]> git.eshelyaron.com Git - emacs.git/commitdiff
Add no-accept-focus and frame-list-z-order to NS port
authorAlan Third <alan@idiocy.org>
Thu, 20 Apr 2017 14:25:56 +0000 (15:25 +0100)
committerAlan Third <alan@idiocy.org>
Fri, 21 Apr 2017 19:44:35 +0000 (20:44 +0100)
* lisp/frame.el (frame-list-z-order): Add NS.
* src/nsfns.m: Add x_set_no_accept_focus to handler struct.
(Fx_create_frame): Handle no-accept-focus parameter.
(ns_window_is_ancestor):
(Fns_frame_list_z_order): New functions.
* src/nsterm.m (x_set_no_accept_focus): New function.
(initFrameFromEmacs): Use EmacsWindow instead of EmacsFSWindow for
non-fullscreen windows.
(EmacsWindow:canBecomeKeyWindow): New function.

lisp/frame.el
src/nsfns.m
src/nsterm.h
src/nsterm.m

index e632b5943fc945d8bee8e7a47df6f3845a5c048c..cec262499d106be7cfc6962f9245161dec2863b5 100644 (file)
@@ -1500,6 +1500,7 @@ keys and their meanings."
 
 (declare-function x-frame-list-z-order "xfns.c" (&optional display))
 (declare-function w32-frame-list-z-order "w32fns.c" (&optional display))
+(declare-function ns-frame-list-z-order "nsfns.m" (&optional display))
 
 (defun frame-list-z-order (&optional display)
   "Return list of Emacs' frames, in Z (stacking) order.
@@ -1517,10 +1518,13 @@ Return nil if DISPLAY contains no Emacs frame."
      ((eq frame-type 'x)
       (x-frame-list-z-order display))
      ((eq frame-type 'w32)
-      (w32-frame-list-z-order display)))))
+      (w32-frame-list-z-order display))
+     ((eq frame-type 'ns)
+      (ns-frame-list-z-order display)))))
 
 (declare-function x-frame-restack "xfns.c" (frame1 frame2 &optional above))
 (declare-function w32-frame-restack "w32fns.c" (frame1 frame2 &optional above))
+(declare-function ns-frame-restack "nsfns.m" (frame1 frame2 &optional above))
 
 (defun frame-restack (frame1 frame2 &optional above)
   "Restack FRAME1 below FRAME2.
index f1a5df8f27e37a6db1484024f1cb30934ce7b212..3a37df95759891c769f098bc77ee3ff10a3f924d 100644 (file)
@@ -973,14 +973,14 @@ frame_parm_handler ns_frame_parm_handlers[] =
   0, /* x_set_tool_bar_position */
   0, /* x_set_inhibit_double_buffering */
 #ifdef NS_IMPL_COCOA
-  x_set_undecorated, /* x_set_undecorated */
+  x_set_undecorated,
 #else
   0, /*x_set_undecorated */
 #endif
-  x_set_parent_frame, /* x_set_parent_frame */
+  x_set_parent_frame,
   0, /* x_set_skip_taskbar */
   0, /* x_set_no_focus_on_map */
-  0, /* x_set_no_accept_focus */
+  x_set_no_accept_focus,
   x_set_z_group, /* x_set_z_group */
   0, /* x_set_override_redirect */
 };
@@ -1287,6 +1287,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
   store_frame_param (f, Qparent_frame, parent_frame);
 
   x_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL);
+  x_default_parameter (f, parms, Qno_accept_focus, Qnil,
+                       NULL, NULL, RES_TYPE_BOOLEAN);
 
   /* The resources controlling the menu-bar and tool-bar are
      processed specially at startup, and reflected in the mode
@@ -1428,6 +1430,58 @@ x_focus_frame (struct frame *f, bool noactivate)
     }
 }
 
+static BOOL
+ns_window_is_ancestor (NSWindow *win, NSWindow *candidate)
+/* Test whether CANDIDATE is an ancestor window of WIN. */
+{
+  if (candidate == NULL)
+    return NO;
+  else if (win == candidate)
+    return YES;
+  else
+    return ns_window_is_ancestor(win, [candidate parentWindow]);
+}
+
+DEFUN ("ns-frame-list-z-order", Fns_frame_list_z_order,
+       Sns_frame_list_z_order, 0, 1, 0,
+       doc: /* Return list of Emacs' frames, in Z (stacking) order.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be either a frame or a display name (a string).  If
+omitted or nil, that stands for the selected frame's display.  Return
+nil if TERMINAL contains no Emacs frame.
+
+As a special case, if TERMINAL is non-nil and specifies a live frame,
+return the child frames of that frame in Z (stacking) order.
+
+Frames are listed from topmost (first) to bottommost (last).  */)
+  (Lisp_Object terminal)
+{
+  NSArray *list = [NSApp orderedWindows];
+  Lisp_Object frames = Qnil;
+
+  if (FRAMEP (terminal) && FRAME_LIVE_P (XFRAME (terminal)))
+    {
+      /* Filter LIST to just those that are ancestors of TERMINAL. */
+      NSWindow *win = [FRAME_NS_VIEW (XFRAME (terminal)) window];
+
+      NSPredicate *ancestor_pred =
+        [NSPredicate predicateWithBlock:^BOOL(id candidate, NSDictionary *bind) {
+            return ns_window_is_ancestor (win, [(NSWindow *)candidate parentWindow]);
+          }];
+
+      list = [[NSApp orderedWindows] filteredArrayUsingPredicate: ancestor_pred];
+    }
+
+  for (NSWindow *win in [list reverseObjectEnumerator])
+    {
+      Lisp_Object frame;
+      XSETFRAME (frame, ((EmacsView *)[win delegate])->emacsframe);
+      frames = Fcons(frame, frames);
+    }
+
+  return frames;
+}
+
 DEFUN ("ns-frame-restack", Fns_frame_restack, Sns_frame_restack, 2, 3, 0,
        doc: /* Restack FRAME1 below FRAME2.
 This means that if both frames are visible and the display areas of
@@ -3188,6 +3242,7 @@ be used as the image of the icon representing the frame.  */);
   defsubr (&Sns_display_monitor_attributes_list);
   defsubr (&Sns_frame_geometry);
   defsubr (&Sns_frame_edges);
+  defsubr (&Sns_frame_list_z_order);
   defsubr (&Sns_frame_restack);
   defsubr (&Sx_display_mm_width);
   defsubr (&Sx_display_mm_height);
index 2f8c4269b0bd8dd5272b1550977df2857cdc2918..9285178d190ca73e649ce73cf038adccfc499603 100644 (file)
@@ -1212,6 +1212,8 @@ extern void x_set_undecorated (struct frame *f, Lisp_Object new_value,
                                Lisp_Object old_value);
 extern void x_set_parent_frame (struct frame *f, Lisp_Object new_value,
                                 Lisp_Object old_value);
+extern void x_set_no_accept_focus (struct frame *f, Lisp_Object new_value,
+                                   Lisp_Object old_value);
 extern void x_set_z_group (struct frame *f, Lisp_Object new_value,
                            Lisp_Object old_value);
 extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
index c53957f93381100c05779ce21a5f896b53426819..4e88297bc04cfa174d51e7c09efc516a91c48ca2 100644 (file)
@@ -1912,6 +1912,21 @@ x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
     }
 }
 
+void
+x_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
+/*  Set frame F's `no-accept-focus' parameter which, if non-nil, hints
+ * that F's window-system window does not want to receive input focus
+ * via mouse clicks or by moving the mouse into it.
+ *
+ * If non-nil, this may have the unwanted side-effect that a user cannot
+ * scroll a non-selected frame with the mouse.
+ *
+ * Some window managers may not honor this parameter. */
+{
+  if (!EQ (new_value, old_value))
+    FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value);
+}
+
 void
 x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 /* Set frame F's `z-group' parameter.  If `above', F's window-system
@@ -6900,7 +6915,7 @@ not_in_argv (NSString *arg)
   maximizing_resize = NO;
 #endif
 
-  win = [[EmacsFSWindow alloc]
+  win = [[EmacsWindow alloc]
             initWithContentRect: r
                       styleMask: (FRAME_UNDECORATED (f)
                                   ? NSWindowStyleMaskBorderless
@@ -8130,6 +8145,11 @@ not_in_argv (NSString *arg)
 
   [super setFrameTopLeftPoint:point];
 }
+
+- (BOOL)canBecomeKeyWindow
+{
+  return !FRAME_NO_ACCEPT_FOCUS (((EmacsView *)[self delegate])->emacsframe);
+}
 @end /* EmacsWindow */