]> git.eshelyaron.com Git - emacs.git/commitdiff
Make GTK+ menus work correctly with Unity global menu
authorDaniel Colascione <dancol@dancol.org>
Mon, 13 Jan 2014 01:40:35 +0000 (17:40 -0800)
committerDaniel Colascione <dancol@dancol.org>
Mon, 13 Jan 2014 01:40:35 +0000 (17:40 -0800)
src/ChangeLog
src/gtkutil.c
src/gtkutil.h
src/xmenu.c

index 8df6e31521dda4534186dd5b2a47307a3bc77a6c..d39377f4ef324aa9ab36b3b51bbb2c84ae708b39 100644 (file)
@@ -1,3 +1,16 @@
+2014-01-13  Daniel Colascione  <dancol@dancol.org>
+
+       Fix menu item updating in the presence of the Unity global menu
+       GTK+ module.
+
+       * gtkutil.h (xg_have_tear_offs): Add frame parameter
+       * gtkutil.c (xg_have_tear_offs): Count the global menu as a
+       tear-off.
+       (xg_update_menubar,xg_update_menu_item): Call g_object_notify when
+       updating menus; explain why.
+       * xmenu.c (set_frame_menubar): Call xg_have_tear_offs with new
+       parameter.
+
 2014-01-07  Paul Eggert  <eggert@cs.ucla.edu>
 
        Fix misdisplay of interlaced GIFs with libgif5 (Bug#16372).
index 21c3f7ddd8b2e61d8606d04b0194f253ebecd8a6..6e039c7a1411ae151a5e585ba5f31ee34f12c787 100644 (file)
@@ -2414,9 +2414,12 @@ static int xg_detached_menus;
 /* Return true if there are detached menus.  */
 
 bool
-xg_have_tear_offs (void)
+xg_have_tear_offs (struct frame *f)
 {
-  return xg_detached_menus > 0;
+  /* If the frame's menubar height is zero, the menu bar is probably
+     being redirected outside the window to some kind of global menu;
+     this situation is the moral equivalent of a tear-off.  */
+  return FRAME_MENUBAR_HEIGHT (f) == 0 || xg_detached_menus > 0;
 }
 
 /* Callback invoked when a detached menu window is removed.  Here we
@@ -2449,9 +2452,9 @@ tearoff_activate (GtkWidget *widget, gpointer client_data)
 }
 #else /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
 bool
-xg_have_tear_offs (void)
+xg_have_tear_offs (struct frame *f)
 {
-  return false;
+  return FRAME_MENUBAR_HEIGHT (f) == 0;
 }
 #endif /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
 
@@ -2897,7 +2900,13 @@ xg_update_menubar (GtkWidget *menubar,
           char *utf8_label = get_utf8_string (val->name);
           GtkWidget *submenu = gtk_menu_item_get_submenu (witem);
 
+          /* GTK menu items don't notice when their labels have been
+             changed from underneath them, so we have to explicitly
+             use g_object_notify to tell listeners (e.g., a GMenuModel
+             bridge that might be loaded) that the item's label has
+             changed.  */
           gtk_label_set_text (wlabel, utf8_label);
+          g_object_notify (G_OBJECT (witem), "label");
 
 #ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
           /* If this item has a submenu that has been detached, change
@@ -2934,6 +2943,7 @@ xg_update_menubar (GtkWidget *menubar,
                                              select_cb, deactivate_cb,
                                              highlight_cb,
                                              0, 0, 0, 0, cl_data, 0);
+
           gtk_widget_set_name (w, MENU_ITEM_NAME);
           gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), w, pos);
           gtk_menu_item_set_submenu (GTK_MENU_ITEM (w), submenu);
@@ -2993,6 +3003,7 @@ xg_update_menu_item (widget_value *val,
   const char *old_label = 0;
   const char *old_key = 0;
   xg_menu_item_cb_data *cb_data;
+  bool label_changed = false;
 
   wchild = XG_BIN_CHILD (w);
   utf8_label = get_utf8_string (val->name);
@@ -3037,15 +3048,20 @@ xg_update_menu_item (widget_value *val,
         }
     }
 
-
   if (wkey) old_key = gtk_label_get_label (wkey);
   if (wlbl) old_label = gtk_label_get_label (wlbl);
 
   if (wkey && utf8_key && (! old_key || strcmp (utf8_key, old_key) != 0))
-    gtk_label_set_text (wkey, utf8_key);
+    {
+      label_changed = true;
+      gtk_label_set_text (wkey, utf8_key);
+    }
 
   if (! old_label || strcmp (utf8_label, old_label) != 0)
-    gtk_label_set_text (wlbl, utf8_label);
+    {
+      label_changed = true;
+      gtk_label_set_text (wlbl, utf8_label);
+    }
 
   if (utf8_key) g_free (utf8_key);
   if (utf8_label) g_free (utf8_label);
@@ -3077,6 +3093,9 @@ xg_update_menu_item (widget_value *val,
           cb_data->select_id = 0;
         }
     }
+
+  if (label_changed) /* See comment in xg_update_menubar.  */
+    g_object_notify (G_OBJECT (w), "label");
 }
 
 /* Update the toggle menu item W so it corresponds to VAL.  */
@@ -3359,11 +3378,6 @@ xg_update_frame_menubar (struct frame *f)
   gtk_widget_show_all (x->menubar_widget);
   gtk_widget_get_preferred_size (x->menubar_widget, NULL, &req);
 
-  /* If menu bar doesn't know its height yet, cheat a little so the frame
-     doesn't jump so much when resized later in menubar_map_cb.  */
-  if (req.height == 0)
-    req.height = 23;
-
   if (FRAME_MENUBAR_HEIGHT (f) != req.height)
     {
       FRAME_MENUBAR_HEIGHT (f) = req.height;
index 09f0d3fd2a84d32214f421f088fd5c9ea144aa13..12bf461fd69f19e04e1a0faacce239e129c690cf 100644 (file)
@@ -107,7 +107,7 @@ extern void xg_update_frame_menubar (struct frame *f);
 
 extern bool xg_event_is_for_menubar (struct frame *, const XEvent *);
 
-extern bool xg_have_tear_offs (void);
+extern bool xg_have_tear_offs (struct frame *f);
 
 extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid);
 
index e7e44d4e47f235c496857fe04efd7d4dfbb95786..6f628527a6de9f5daec4ec19332ef3e685bd6e87 100644 (file)
@@ -796,7 +796,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
 #ifdef USE_GTK
   /* If we have detached menus, we must update deep so detached menus
      also gets updated.  */
-  deep_p = deep_p || xg_have_tear_offs ();
+  deep_p = deep_p || xg_have_tear_offs (f);
 #endif
 
   if (deep_p)