diff options
| author | Daniel Colascione | 2014-01-12 17:50:46 -0800 |
|---|---|---|
| committer | Daniel Colascione | 2014-01-12 17:50:46 -0800 |
| commit | 7d29a37a5bcd753536311b0aa87bdbb317eed42b (patch) | |
| tree | 3cfec43ada4c1916016b4074a0c12d12030788c7 /src | |
| parent | 6137cb82dbe1c5c438df6e8ae95533ebced9ff35 (diff) | |
| parent | a787d37a3eb5e28f355a6db750a6e7a75ff18ae0 (diff) | |
| download | emacs-7d29a37a5bcd753536311b0aa87bdbb317eed42b.tar.gz emacs-7d29a37a5bcd753536311b0aa87bdbb317eed42b.zip | |
Make GTK+ menus work correctly with the Unity global menu
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 16 | ||||
| -rw-r--r-- | src/gtkutil.c | 38 | ||||
| -rw-r--r-- | src/gtkutil.h | 2 | ||||
| -rw-r--r-- | src/xmenu.c | 2 |
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 @@ | |||
| 1 | 2014-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 | |||
| 1 | 2014-01-11 K. Handa <handa@gnu.org> | 17 | 2014-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 | ||
| 2416 | bool | 2416 | bool |
| 2417 | xg_have_tear_offs (void) | 2417 | xg_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 */ |
| 2451 | bool | 2454 | bool |
| 2452 | xg_have_tear_offs (void) | 2455 | xg_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 | ||
| 108 | extern bool xg_event_is_for_menubar (struct frame *, const XEvent *); | 108 | extern bool xg_event_is_for_menubar (struct frame *, const XEvent *); |
| 109 | 109 | ||
| 110 | extern bool xg_have_tear_offs (void); | 110 | extern bool xg_have_tear_offs (struct frame *f); |
| 111 | 111 | ||
| 112 | extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid); | 112 | extern 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) |