emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r112188: * nsmenu.m (ns_update_menuba


From: Jan D.
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r112188: * nsmenu.m (ns_update_menubar): Correct NSTRACE.
Date: Sat, 30 Mar 2013 10:57:27 +0100
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 112188
fixes bug: http://debbugs.gnu.org/12698
committer: Jan D. <address@hidden>
branch nick: trunk
timestamp: Sat 2013-03-30 10:57:27 +0100
message:
  * nsmenu.m (ns_update_menubar): Correct NSTRACE.
  (x_activate_menubar): Update the menu with title that matches
  ns_get_pending_menu_title, and call
  ns_check_pending_openmenu.
  (menuWillOpen:): New method.
  (menuNeedsUpdate:): Add check for ! COCOA || OSX < 10.5 (Bug#12698).
  
  * nsterm.h (ns_get_pending_menu_title, ns_check_menu_open)
  (ns_check_pending_open_menu): Declare.
  
  * nsterm.m (menu_will_open_state, menu_mouse_point)
  (menu_pending_title): New varaibles.
  (ns_get_pending_menu_title, ns_check_menu_open)
  (ns_check_pending_open_menu): New functions.
modified:
  src/ChangeLog
  src/nsmenu.m
  src/nsterm.h
  src/nsterm.m
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-03-29 15:50:21 +0000
+++ b/src/ChangeLog     2013-03-30 09:57:27 +0000
@@ -1,3 +1,20 @@
+2013-03-30  Jan Djärv  <address@hidden>
+
+       * nsterm.h (ns_get_pending_menu_title, ns_check_menu_open)
+       (ns_check_pending_open_menu): Declare.
+
+       * nsmenu.m (ns_update_menubar): Correct NSTRACE.
+       (x_activate_menubar): Update the menu with title that matches
+       ns_get_pending_menu_title, and call
+       ns_check_pending_openmenu (Bug#12698).
+       (menuWillOpen:): New method.
+       (menuNeedsUpdate:): Add check for ! COCOA || OSX < 10.5 (Bug#12698).
+
+       * nsterm.m (menu_will_open_state, menu_mouse_point)
+       (menu_pending_title): New varaibles.
+       (ns_get_pending_menu_title, ns_check_menu_open)
+       (ns_check_pending_open_menu): New functions.
+
 2013-03-29  Dmitry Antipov  <address@hidden>
 
        * indent.c (current_column_bol_cache): Remove leftover which is not

=== modified file 'src/nsmenu.m'
--- a/src/nsmenu.m      2013-03-28 14:04:49 +0000
+++ b/src/nsmenu.m      2013-03-30 09:57:27 +0000
@@ -88,14 +88,6 @@
    ========================================================================== 
*/
 
 
-/* FIXME: not currently used, but should normalize with other terms. */
-void
-x_activate_menubar (struct frame *f)
-{
-    fprintf (stderr, "XXX: Received x_activate_menubar event.\n");
-}
-
-
 /* Supposed to discard menubar and free storage.  Since we share the
    menubar among frames and update its context for the focused window,
    there is nothing to do here. */
@@ -138,7 +130,7 @@
   long t;
 #endif
 
-  NSTRACE (set_frame_menubar);
+  NSTRACE (ns_update_menubar);
 
   if (f != SELECTED_FRAME ())
       return;
@@ -512,6 +504,29 @@
   ns_update_menubar (f, deep_p, nil);
 }
 
+void
+x_activate_menubar (struct frame *f)
+{
+  NSArray *a = [[NSApp mainMenu] itemArray];
+  /* Update each submenu separatly so ns_update_menubar don't reset
+     the delegate.  */
+  int i = 0;
+  while (i < [a count])
+    {
+      EmacsMenu *menu = (EmacsMenu *)[[a objectAtIndex:i] submenu];
+      const char *title = [[menu title] UTF8String];
+      if (strcmp (title, ns_get_pending_menu_title ()) == 0)
+        {
+          ns_update_menubar (f, true, menu);
+          break;
+        }
+      ++i;
+    }
+  ns_check_pending_open_menu ();
+}
+
+
+
 
 /* ==========================================================================
 
@@ -564,6 +579,14 @@
   trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
                   ? 1 : 0);
 }
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+- (void)menuWillOpen:(NSMenu *)menu
+{
+  ns_check_menu_open (menu);
+}
+#endif
+
 #endif
 
 /* delegate method called when a submenu is being opened: run a 'deep' call
@@ -591,7 +614,12 @@
   if (trackingMenu == 0)
     return;
 /*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog 
(@"address@hidden", event); */
-  ns_update_menubar (frame, 1, self);
+#if ! defined(NS_IMPL_COCOA) || \
+  MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+  /* Don't know how to do this for anything other than OSX >= 10.5
+     This is wrong, as it might run Lisp code in the event loop.  */
+  ns_update_menubar (frame, true, self);
+#endif
 }
 
 

=== modified file 'src/nsterm.h'
--- a/src/nsterm.h      2013-03-16 13:52:12 +0000
+++ b/src/nsterm.h      2013-03-30 09:57:27 +0000
@@ -792,6 +792,9 @@
 extern NSColor *ns_lookup_indexed_color (unsigned long idx, struct frame *f);
 extern unsigned long ns_index_color (NSColor *color, struct frame *f);
 extern void ns_free_indexed_color (unsigned long idx, struct frame *f);
+extern const char *ns_get_pending_menu_title ();
+extern void ns_check_menu_open (NSMenu *menu);
+extern void ns_check_pending_open_menu ();
 #endif
 
 /* C access to ObjC functionality */

=== modified file 'src/nsterm.m'
--- a/src/nsterm.m      2013-03-28 14:04:49 +0000
+++ b/src/nsterm.m      2013-03-30 09:57:27 +0000
@@ -228,6 +228,25 @@
   NULL, 0, 0
 };
 
+/*
+ * State for pending menu activation:
+ * MENU_NONE     Normal state
+ * MENU_PENDING  A menu has been clicked on, but has been canceled so we can
+ *               run lisp to update the menu.
+ * MENU_OPENING  Menu is up to date, and the click event is redone so the menu
+ *               will open.
+ */
+#define MENU_NONE 0
+#define MENU_PENDING 1
+#define MENU_OPENING 2
+static int menu_will_open_state = MENU_NONE;
+
+/* Saved position for menu click.  */
+static CGPoint menu_mouse_point;
+
+/* Title for the menu to open.  */
+static char *menu_pending_title = 0;
+
 /* Convert modifiers in a NeXTstep event to emacs style modifiers.  */
 #define NS_FUNCTION_KEY_MASK 0x800000
 #define NSLeftControlKeyMask    (0x000001 | NSControlKeyMask)
@@ -3388,6 +3407,77 @@
 }
 #endif
 
+const char *
+ns_get_pending_menu_title ()
+{
+  return menu_pending_title;
+}
+
+/* Check if menu open should be cancelled or continued as normal.  */
+void
+ns_check_menu_open (NSMenu *menu)
+{
+  /* GNUStep and OSX <= 10.4 does not have cancelTracking.  */
+#if defined(NS_IMPL_COCOA) && \
+  MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+
+  /* Click in menu bar? */
+  NSArray *a = [[NSApp mainMenu] itemArray];
+  int i;
+  BOOL found = NO;
+  for (i = 0; ! found && i < [a count]; i++)
+    found = menu == [[a objectAtIndex:i] submenu];
+  if (found)
+    {
+      if (menu_will_open_state == MENU_NONE && emacs_event)
+        {
+          NSEvent *theEvent = [NSApp currentEvent];
+          struct frame *emacsframe = SELECTED_FRAME ();
+
+          [menu cancelTracking];
+          menu_will_open_state = MENU_PENDING;
+          emacs_event->kind = MENU_BAR_ACTIVATE_EVENT;
+          EV_TRAILER (theEvent);
+
+          CGEventRef ourEvent = CGEventCreate (NULL);
+          menu_mouse_point = CGEventGetLocation (ourEvent);
+          CFRelease (ourEvent);
+          xfree (menu_pending_title);
+          menu_pending_title = xstrdup ([[menu title] UTF8String]);
+        }
+      else if (menu_will_open_state == MENU_OPENING)
+        {
+          menu_will_open_state = MENU_NONE;
+        }
+    }
+#endif
+}
+
+/* Redo saved menu click if state is MENU_PENDING.  */
+void
+ns_check_pending_open_menu ()
+{
+#ifdef NS_IMPL_COCOA
+  if (menu_will_open_state == MENU_PENDING)
+    {
+      CGEventSourceRef source
+        = CGEventSourceCreate (kCGEventSourceStateHIDSystemState);
+
+      CGEventRef event = CGEventCreateMouseEvent (source,
+                                                  kCGEventLeftMouseDown,
+                                                  menu_mouse_point,
+                                                  kCGMouseButtonLeft);
+      CGEventSetType (event, kCGEventLeftMouseDown);
+      CGEventPost (kCGHIDEventTap, event);
+      CFRelease (event);
+      CFRelease (source);
+
+      menu_will_open_state = MENU_OPENING;
+    }
+#endif
+}
+
+
 static int
 ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
 /* --------------------------------------------------------------------------


reply via email to

[Prev in Thread] Current Thread [Next in Thread]