[gtk-mac-integration] Bug 703675 - GtkRecentChooserMenu: GtkRecentChooser doesn't work



commit 24ade60fd771ee2424299320424d04ad009aaeb1
Author: John Ralls <jralls ceridwen us>
Date:   Sun Jul 14 16:09:57 2013 -0700

    Bug 703675 - GtkRecentChooserMenu: GtkRecentChooser doesn't work
    
    gtk_recent_chooser_get_current_uri always returns first item in list
    because it doesn't use menu item actions, it uses the menu itself and
    gets the active item.
    
    Work around this by emulating the mouse-tracking in GtkMenu with an
    NSMenuDelegate responding to willHighlightItem, which tells the
    GNSMenuItem to call gtk_menu_set_active to itself.
    
    This requires keeping a reference to the GtkMenuItem on the GNSMenuItem;
    we make it a GWeakRef to avoid a reference loop.
    
    Also release submenus when they're replaced to avoid a leak.

 configure.ac          |    2 +-
 src/GNSMenuDelegate.c |   33 +++++++++++++++++++++++++++++++++
 src/GNSMenuDelegate.h |    5 +++++
 src/GNSMenuItem.c     |   17 +++++++++++++++--
 src/GNSMenuItem.h     |    2 ++
 src/Makefile.am       |    2 ++
 src/cocoa_menu_item.c |   12 +++++++++---
 7 files changed, 67 insertions(+), 6 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1a5cfb9..286242c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,7 +38,7 @@ AM_PROG_CC_C_O
 
 AM_PATH_GLIB_2_0([2.14.0])
 AC_MSG_CHECKING([for GLib >= 2.31.0])
-if $PKG_CONFIG 'glib-2.0 >= 2.31.0'
+if $PKG_CONFIG 'glib-2.0 >= 2.32.0'
 then
     AC_MSG_RESULT(yes)
     AC_DEFINE(HAVE_GLIB_2_31,1,[System has GLib 2.31.0 or newer])
diff --git a/src/GNSMenuDelegate.c b/src/GNSMenuDelegate.c
new file mode 100644
index 0000000..453ed69
--- /dev/null
+++ b/src/GNSMenuDelegate.c
@@ -0,0 +1,33 @@
+/* --- objc-mode --- */
+/* GTK+ Integration with platform-specific application-wide features 
+ * such as the OS X menubar and application delegate concepts.
+ *
+ * Copyright © 2013 John Ralls
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#import "GNSMenuDelegate.h"
+#import "GNSMenuItem.h"
+
+ implementation _GNSMenuDelegate
+-(void) menu: (NSMenu*)theMenu willHighlightItem: (NSMenuItem*)item
+{
+  if ([item respondsToSelector: @selector (willHighlight)])
+    [(_GNSMenuItem*)item willHighlight];
+}
+
+
+ end
diff --git a/src/GNSMenuDelegate.h b/src/GNSMenuDelegate.h
new file mode 100644
index 0000000..08b074f
--- /dev/null
+++ b/src/GNSMenuDelegate.h
@@ -0,0 +1,5 @@
+#import <Cocoa/Cocoa.h>
+#include <gtk/gtk.h>
+
+ interface _GNSMenuDelegate : NSObject {}
+ end
diff --git a/src/GNSMenuItem.c b/src/GNSMenuItem.c
index f7b715a..48ec0d1 100644
--- a/src/GNSMenuItem.c
+++ b/src/GNSMenuItem.c
@@ -39,7 +39,7 @@ idle_call_activate (ClosureData *action)
 
 -(id) initWithTitle: (NSString*) title
            aGClosure: (GClosure*) closure
-          andPointer: (gpointer) ptr
+          andPointer: (gpointer) gtkmenuitem
 {
 
   /* All menu items have the action "activate", which will be handled by this child class
@@ -53,9 +53,10 @@ idle_call_activate (ClosureData *action)
       g_closure_ref (closure);
       g_closure_sink (closure);
       action.closure = closure;
-      action.data = ptr;
+      action.data = NULL;
       accel_closure = NULL;
       notUsed = NO;
+      g_weak_ref_set (&menuItem, GTK_MENU_ITEM (gtkmenuitem));
     }
   return self;
 }
@@ -147,4 +148,16 @@ idle_call_activate (ClosureData *action)
 #endif
 }
 
+-(void) willHighlight
+{
+  NSMenu *theMenu = [self menu];
+  guint index = [theMenu indexOfItem: self];
+  GtkMenuItem *item = g_weak_ref_get (&menuItem);
+  if (item != NULL)
+    {
+      GtkMenu *menu = GTK_MENU (gtk_widget_get_parent (GTK_WIDGET (item)));
+      gtk_menu_set_active (menu, index);
+      g_object_unref (item);
+    }
+}
 @end
diff --git a/src/GNSMenuItem.h b/src/GNSMenuItem.h
index 9f946a8..d0db3dc 100644
--- a/src/GNSMenuItem.h
+++ b/src/GNSMenuItem.h
@@ -51,6 +51,7 @@ typedef struct {
   ClosureData action;
   // The hidden parameter was introduced in 10.5; for earlier OSX
   // versions we need to emulate it.
+  GWeakRef menuItem;
   BOOL notUsed;
 #if !(MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4)
   BOOL hidden;
@@ -93,6 +94,7 @@ typedef struct {
 - (void) unmark;
 - (BOOL) isMarked;
 - (void) removeFromMenu: (NSMenu*) old_menu;
+- (void) willHighlight;
 
 @end
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 7621f80..0a6d27f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,6 +13,8 @@ libgtkmacintegration_la_SOURCES =                     \
        GNSMenuBar.c                                    \
        GNSMenuItem.h                                   \
        GNSMenuItem.c                                   \
+       GNSMenuDelegate.h                               \
+       GNSMenuDelegate.c                               \
        getlabel.h                                      \
        getlabel.c                                      \
        cocoa_menu.h                                    \
diff --git a/src/cocoa_menu_item.c b/src/cocoa_menu_item.c
index 025c409..0643667 100644
--- a/src/cocoa_menu_item.c
+++ b/src/cocoa_menu_item.c
@@ -34,6 +34,7 @@
 #include "getlabel.h"
 #include "gtkosx-image.h"
 #import "GNSMenuBar.h"
+#import "GNSMenuDelegate.h"
 
 //#define DEBUG(format, ...) g_printerr ("%s: " format, G_STRFUNC, ## __VA_ARGS__)
 #define DEBUG(format, ...)
@@ -154,7 +155,11 @@ cocoa_menu_item_update_submenu (_GNSMenuItem *cocoa_item,
   if (cocoa_submenu != nil)
     if ([cocoa_item submenu] != cocoa_submenu)
       //covers no submenu or wrong submenu on cocoa_item)
-      [cocoa_item setSubmenu: cocoa_submenu];
+      {
+       [[[cocoa_item submenu] delegate] release];
+       [[cocoa_item submenu] release];
+       [cocoa_item setSubmenu: cocoa_submenu];
+      }
     else ;
   //Nothing required -- the submenus are already set up correctly
   else if ([cocoa_item hasSubmenu])
@@ -166,12 +171,13 @@ cocoa_menu_item_update_submenu (_GNSMenuItem *cocoa_item,
     {
       const gchar *text = get_menu_label_text (widget, &label);
       NSString *title = [NSString stringWithUTF8String: text ? text : ""];
+      _GNSMenuDelegate *delegate = [[_GNSMenuDelegate alloc] init];
 
       cocoa_submenu = [[[NSMenu alloc] initWithTitle: title] autorelease];
 
+      [cocoa_submenu setDelegate: delegate];
       [cocoa_submenu setAutoenablesItems: NO];
       cocoa_menu_connect (submenu, cocoa_submenu);
-
       /* connect the new nsmenu to the passed-in item (which lives in
          the parent nsmenu)
          (Note: this will release any pre-existing version of this submenu)
@@ -560,7 +566,7 @@ cocoa_menu_item_add_item (NSMenu* cocoa_menu, GtkWidget* menu_item, int index)
 
       cocoa_item = [[_GNSMenuItem alloc]
                    initWithTitle: title
-                   aGClosure: menu_action andPointer: NULL];
+                   aGClosure: menu_action andPointer: menu_item];
 
       DEBUG ("\tan item\n");
     }


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