]> git.eshelyaron.com Git - emacs.git/commitdiff
Adapt code from AquaEmacs to handle occasional blank menus.
authorJan Djärv <jan.h.d@swipnet.se>
Sun, 18 Dec 2011 14:50:19 +0000 (15:50 +0100)
committerJan Djärv <jan.h.d@swipnet.se>
Sun, 18 Dec 2011 14:50:19 +0000 (15:50 +0100)
* nsmenu.m (trackingMenu): New variable.
(NSMenuDidBeginTrackingNotification): Declare if OSX < 10.5 and
NS_IMPL_COCOA.
(trackingNotification): New method (from AquaEmacs).
(menuNeedsUpdate): Expand comment and return if trackingMenu is 0,
from AquaEmacs.
(syms_of_nsmenu): Set trackingMenu to 1 if not NS_IMPL_COCOA.

* nsterm.m (ns_term_init): Subscribe for notifications
NSMenuDidBeginTrackingNotification and NSMenuDidEndTrackingNotification
to method trackingNotification in EmacsMenu.

Fixes: debbugs:7030
src/ChangeLog
src/nsmenu.m
src/nsterm.m

index 610079fe321a7234056c18c00d1f24ed4616c26d..14eb35bdc1cef5a1ce29118e6e487b89c9a4ba77 100644 (file)
@@ -1,5 +1,17 @@
 2011-12-18  Jan Djärv  <jan.h.d@swipnet.se>
 
+       * nsterm.m (ns_term_init): Subscribe for notifications
+       NSMenuDidBeginTrackingNotification and NSMenuDidEndTrackingNotification
+       to method trackingNotification in EmacsMenu.
+
+       * nsmenu.m (trackingMenu): New variable.
+       (NSMenuDidBeginTrackingNotification): Declare if OSX < 10.5 and
+       NS_IMPL_COCOA.
+       (trackingNotification): New method (from AquaEmacs).
+       (menuNeedsUpdate): Expand comment and return if trackingMenu is 0,
+       from AquaEmacs (Bug#7030).
+       (syms_of_nsmenu): Set trackingMenu to 1 if not NS_IMPL_COCOA.
+
        * nsselect.m (CUT_BUFFER_SUPPORT): Remove define.
        (symbol_to_nsstring): Fix indentation.
        (ns_symbol_to_pb): New function.
index 951282910acace5fd732f03f15a30927c42ac561..d599cdb6ce5d477f42b210c9cb4c82860630498e 100644 (file)
@@ -74,6 +74,10 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
 static int popup_activated_flag;
 static NSModalSession popupSession;
 
+/* Nonzero means we are tracking and updating menus.  */
+static int trackingMenu;
+
+
 /* NOTE: toolbar implementation is at end,
   following complete menu implementation. */
 
@@ -543,21 +547,44 @@ set_frame_menubar (struct frame *f, int first_time, int deep_p)
   frame = f;
 }
 
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+extern NSString *NSMenuDidBeginTrackingNotification;
+#endif
+#endif
+
+#ifdef NS_IMPL_COCOA
+-(void)trackingNotification:(NSNotification *)notification
+{
+  /* Update menu in menuNeedsUpdate only while tracking menus.  */
+  trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
+                  ? 1 : 0);
+}
+#endif
 
 /* delegate method called when a submenu is being opened: run a 'deep' call
    to set_frame_menubar */
 - (void)menuNeedsUpdate: (NSMenu *)menu
 {
-  NSEvent *event;
   if (!FRAME_LIVE_P (frame))
     return;
-  event = [[FRAME_NS_VIEW (frame) window] currentEvent];
-  /* HACK: Cocoa/Carbon will request update on every keystroke
+
+  /* Cocoa/Carbon will request update on every keystroke
      via IsMenuKeyEvent -> CheckMenusForKeyEvent.  These are not needed
      since key equivalents are handled through emacs.
-     On Leopard, even keystroke events generate SystemDefined events, but
-     their subtype is 8. */
-  if ([event type] != NSSystemDefined || [event subtype] == 8
+     On Leopard, even keystroke events generate SystemDefined event.
+     Third-party applications that enhance mouse / trackpad
+     interaction, or also VNC/Remote Desktop will send events
+     of type AppDefined rather than SysDefined.
+     Menus will fail to show up if they haven't been initialized.
+     AppDefined events may lack timing data.
+
+     Thus, we rely on the didBeginTrackingNotification notification
+     as above to indicate the need for updates.
+     From 10.6 on, we could also use -[NSMenu propertiesToUpdate]: In the
+     key press case, NSMenuPropertyItemImage (e.g.) won't be set.
+  */
+  if (trackingMenu == 0
       /* Also, don't try this if from an event picked up asynchronously,
          as lots of lisp evaluation happens in ns_update_menubar. */
       || handling_signal != 0)
@@ -1795,6 +1822,11 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
 void
 syms_of_nsmenu (void)
 {
+#ifndef NS_IMPL_COCOA
+  /* Don't know how to keep track of this in Next/Open/Gnustep.  Always
+     update menus there.  */
+  trackingMenu = 1;
+#endif
   defsubr (&Sx_popup_dialog);
   defsubr (&Sns_reset_menu);
   defsubr (&Smenu_or_popup_active_p);
index 1d64594306539349ee0be9b6758c44295a1e05ad..055959bf2ac67f0afa26832976b4ffabdd190f62 100644 (file)
@@ -4203,6 +4203,15 @@ ns_term_init (Lisp_Object display_name)
     [NSApp setServicesMenu: svcsMenu];
     /* Needed at least on Cocoa, to get dock menu to show windows */
     [NSApp setWindowsMenu: [[NSMenu alloc] init]];
+
+    [[NSNotificationCenter defaultCenter]
+      addObserver: mainMenu
+         selector: @selector (trackingNotification:)
+             name: NSMenuDidBeginTrackingNotification object: mainMenu];
+    [[NSNotificationCenter defaultCenter]
+      addObserver: mainMenu
+         selector: @selector (trackingNotification:)
+             name: NSMenuDidEndTrackingNotification object: mainMenu];
   }
 #endif /* MAC OS X menu setup */