aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Colascione2014-01-12 17:50:46 -0800
committerDaniel Colascione2014-01-12 17:50:46 -0800
commit7d29a37a5bcd753536311b0aa87bdbb317eed42b (patch)
tree3cfec43ada4c1916016b4074a0c12d12030788c7 /src
parent6137cb82dbe1c5c438df6e8ae95533ebced9ff35 (diff)
parenta787d37a3eb5e28f355a6db750a6e7a75ff18ae0 (diff)
downloademacs-7d29a37a5bcd753536311b0aa87bdbb317eed42b.tar.gz
emacs-7d29a37a5bcd753536311b0aa87bdbb317eed42b.zip
Make GTK+ menus work correctly with the Unity global menu
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog16
-rw-r--r--src/gtkutil.c38
-rw-r--r--src/gtkutil.h2
-rw-r--r--src/xmenu.c2
4 files changed, 44 insertions, 14 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4991d74135b..2929c03329c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,19 @@
12014-01-13 Daniel Colascione <dancol@dancol.org>
2
3 Fix menu item updating in the presence of the Unity global menu
4 GTK+ module.
5
6 * gtkutil.h (xg_have_tear_offs): Add frame parameter
7 * gtkutil.c (xg_have_tear_offs): Count the global menu as a
8 tear-off.
9 (xg_update_menubar,xg_update_menu_item): Call g_object_notify when
10 updating menus; explain why.
11 (xg_update_frame_menubar): Remove the 23px hack: I can't repro the
12 problem it's supposed to solve and it interferes with detecting
13 the presence of a global menu.
14 * xmenu.c (set_frame_menubar): Call xg_have_tear_offs with new
15 parameter.
16
12014-01-11 K. Handa <handa@gnu.org> 172014-01-11 K. Handa <handa@gnu.org>
2 18
3 * composite.c (composition_update_it): Fix indexing of 19 * composite.c (composition_update_it): Fix indexing of
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 21c3f7ddd8b..6e039c7a141 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -2414,9 +2414,12 @@ static int xg_detached_menus;
2414/* Return true if there are detached menus. */ 2414/* Return true if there are detached menus. */
2415 2415
2416bool 2416bool
2417xg_have_tear_offs (void) 2417xg_have_tear_offs (struct frame *f)
2418{ 2418{
2419 return xg_detached_menus > 0; 2419 /* If the frame's menubar height is zero, the menu bar is probably
2420 being redirected outside the window to some kind of global menu;
2421 this situation is the moral equivalent of a tear-off. */
2422 return FRAME_MENUBAR_HEIGHT (f) == 0 || xg_detached_menus > 0;
2420} 2423}
2421 2424
2422/* Callback invoked when a detached menu window is removed. Here we 2425/* Callback invoked when a detached menu window is removed. Here we
@@ -2449,9 +2452,9 @@ tearoff_activate (GtkWidget *widget, gpointer client_data)
2449} 2452}
2450#else /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */ 2453#else /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
2451bool 2454bool
2452xg_have_tear_offs (void) 2455xg_have_tear_offs (struct frame *f)
2453{ 2456{
2454 return false; 2457 return FRAME_MENUBAR_HEIGHT (f) == 0;
2455} 2458}
2456#endif /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */ 2459#endif /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
2457 2460
@@ -2897,7 +2900,13 @@ xg_update_menubar (GtkWidget *menubar,
2897 char *utf8_label = get_utf8_string (val->name); 2900 char *utf8_label = get_utf8_string (val->name);
2898 GtkWidget *submenu = gtk_menu_item_get_submenu (witem); 2901 GtkWidget *submenu = gtk_menu_item_get_submenu (witem);
2899 2902
2903 /* GTK menu items don't notice when their labels have been
2904 changed from underneath them, so we have to explicitly
2905 use g_object_notify to tell listeners (e.g., a GMenuModel
2906 bridge that might be loaded) that the item's label has
2907 changed. */
2900 gtk_label_set_text (wlabel, utf8_label); 2908 gtk_label_set_text (wlabel, utf8_label);
2909 g_object_notify (G_OBJECT (witem), "label");
2901 2910
2902#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW 2911#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
2903 /* If this item has a submenu that has been detached, change 2912 /* If this item has a submenu that has been detached, change
@@ -2934,6 +2943,7 @@ xg_update_menubar (GtkWidget *menubar,
2934 select_cb, deactivate_cb, 2943 select_cb, deactivate_cb,
2935 highlight_cb, 2944 highlight_cb,
2936 0, 0, 0, 0, cl_data, 0); 2945 0, 0, 0, 0, cl_data, 0);
2946
2937 gtk_widget_set_name (w, MENU_ITEM_NAME); 2947 gtk_widget_set_name (w, MENU_ITEM_NAME);
2938 gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), w, pos); 2948 gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), w, pos);
2939 gtk_menu_item_set_submenu (GTK_MENU_ITEM (w), submenu); 2949 gtk_menu_item_set_submenu (GTK_MENU_ITEM (w), submenu);
@@ -2993,6 +3003,7 @@ xg_update_menu_item (widget_value *val,
2993 const char *old_label = 0; 3003 const char *old_label = 0;
2994 const char *old_key = 0; 3004 const char *old_key = 0;
2995 xg_menu_item_cb_data *cb_data; 3005 xg_menu_item_cb_data *cb_data;
3006 bool label_changed = false;
2996 3007
2997 wchild = XG_BIN_CHILD (w); 3008 wchild = XG_BIN_CHILD (w);
2998 utf8_label = get_utf8_string (val->name); 3009 utf8_label = get_utf8_string (val->name);
@@ -3037,15 +3048,20 @@ xg_update_menu_item (widget_value *val,
3037 } 3048 }
3038 } 3049 }
3039 3050
3040
3041 if (wkey) old_key = gtk_label_get_label (wkey); 3051 if (wkey) old_key = gtk_label_get_label (wkey);
3042 if (wlbl) old_label = gtk_label_get_label (wlbl); 3052 if (wlbl) old_label = gtk_label_get_label (wlbl);
3043 3053
3044 if (wkey && utf8_key && (! old_key || strcmp (utf8_key, old_key) != 0)) 3054 if (wkey && utf8_key && (! old_key || strcmp (utf8_key, old_key) != 0))
3045 gtk_label_set_text (wkey, utf8_key); 3055 {
3056 label_changed = true;
3057 gtk_label_set_text (wkey, utf8_key);
3058 }
3046 3059
3047 if (! old_label || strcmp (utf8_label, old_label) != 0) 3060 if (! old_label || strcmp (utf8_label, old_label) != 0)
3048 gtk_label_set_text (wlbl, utf8_label); 3061 {
3062 label_changed = true;
3063 gtk_label_set_text (wlbl, utf8_label);
3064 }
3049 3065
3050 if (utf8_key) g_free (utf8_key); 3066 if (utf8_key) g_free (utf8_key);
3051 if (utf8_label) g_free (utf8_label); 3067 if (utf8_label) g_free (utf8_label);
@@ -3077,6 +3093,9 @@ xg_update_menu_item (widget_value *val,
3077 cb_data->select_id = 0; 3093 cb_data->select_id = 0;
3078 } 3094 }
3079 } 3095 }
3096
3097 if (label_changed) /* See comment in xg_update_menubar. */
3098 g_object_notify (G_OBJECT (w), "label");
3080} 3099}
3081 3100
3082/* Update the toggle menu item W so it corresponds to VAL. */ 3101/* Update the toggle menu item W so it corresponds to VAL. */
@@ -3359,11 +3378,6 @@ xg_update_frame_menubar (struct frame *f)
3359 gtk_widget_show_all (x->menubar_widget); 3378 gtk_widget_show_all (x->menubar_widget);
3360 gtk_widget_get_preferred_size (x->menubar_widget, NULL, &req); 3379 gtk_widget_get_preferred_size (x->menubar_widget, NULL, &req);
3361 3380
3362 /* If menu bar doesn't know its height yet, cheat a little so the frame
3363 doesn't jump so much when resized later in menubar_map_cb. */
3364 if (req.height == 0)
3365 req.height = 23;
3366
3367 if (FRAME_MENUBAR_HEIGHT (f) != req.height) 3381 if (FRAME_MENUBAR_HEIGHT (f) != req.height)
3368 { 3382 {
3369 FRAME_MENUBAR_HEIGHT (f) = req.height; 3383 FRAME_MENUBAR_HEIGHT (f) = req.height;
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 09f0d3fd2a8..12bf461fd69 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -107,7 +107,7 @@ extern void xg_update_frame_menubar (struct frame *f);
107 107
108extern bool xg_event_is_for_menubar (struct frame *, const XEvent *); 108extern bool xg_event_is_for_menubar (struct frame *, const XEvent *);
109 109
110extern bool xg_have_tear_offs (void); 110extern bool xg_have_tear_offs (struct frame *f);
111 111
112extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid); 112extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid);
113 113
diff --git a/src/xmenu.c b/src/xmenu.c
index e7e44d4e47f..6f628527a6d 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -796,7 +796,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
796#ifdef USE_GTK 796#ifdef USE_GTK
797 /* If we have detached menus, we must update deep so detached menus 797 /* If we have detached menus, we must update deep so detached menus
798 also gets updated. */ 798 also gets updated. */
799 deep_p = deep_p || xg_have_tear_offs (); 799 deep_p = deep_p || xg_have_tear_offs (f);
800#endif 800#endif
801 801
802 if (deep_p) 802 if (deep_p)