aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Müller <ulm@gentoo.org>2016-07-13 22:13:42 +0200
committerUlrich Müller <ulm@gentoo.org>2016-07-13 22:13:42 +0200
commit2c73e513ba90e484a2755cfd2797af18f7aead7b (patch)
treee047cf928d7fc32e7ad4f682e32f447dbc47d002 /emacs/24.5
parentRemove 24.3 patchset. (diff)
downloademacs-patches-2c73e513ba90e484a2755cfd2797af18f7aead7b.tar.gz
emacs-patches-2c73e513ba90e484a2755cfd2797af18f7aead7b.tar.bz2
emacs-patches-2c73e513ba90e484a2755cfd2797af18f7aead7b.zip
Fix icons in toolbar with GTK+ 3.20.6, bug 588704.emacs-24.5-patches-2
Diffstat (limited to 'emacs/24.5')
-rw-r--r--emacs/24.5/06_all_gtk-toolbar.patch922
1 files changed, 922 insertions, 0 deletions
diff --git a/emacs/24.5/06_all_gtk-toolbar.patch b/emacs/24.5/06_all_gtk-toolbar.patch
new file mode 100644
index 0000000..d3cc5d6
--- /dev/null
+++ b/emacs/24.5/06_all_gtk-toolbar.patch
@@ -0,0 +1,922 @@
+Fix icons in toolbar with GTK+ 3.20.6.
+https://bugs.gentoo.org/588704
+https://bugs.archlinux.org/task/48862
+
+This comprises the following commits from upstream git, backported
+to Emacs 24.5:
+
+commit 4e94689452f3a895a52e67787b795596c2390462
+Author: Paul Eggert <eggert@cs.ucla.edu>
+Date: Sat Oct 18 12:07:17 2014 -0700
+
+ * gtkutil.c: Remove no-longer-used code.
+
+commit 6e5ff6166647e6af30beff38f67f2bca86cf9786
+Author: Jan Djärv <jan.h.d@swipnet.se>
+Date: Sat Oct 18 18:26:47 2014 +0200
+
+ * cus-start.el (x-gtk-whole-detached-tool-bar): Remove.
+
+commit ac225d22f68af9531bc25d6ab83c11797105b5bc
+Author: Jan Djärv <jan.h.d@swipnet.se>
+Date: Sat Oct 18 18:25:24 2014 +0200
+
+ * xfns.c (syms_of_xfns): Remove x-gtk-whole-detached-tool-bar.
+
+commit 3f4c6d52d345999938bc2d4a53246af4c61ef176
+Author: Jan Djärv <jan.h.d@swipnet.se>
+Date: Sat Oct 18 18:19:53 2014 +0200
+
+ Handle deprecated Gtk+ stuff for version <= 3.10
+
+--- emacs-24.5-orig/lisp/cus-start.el
++++ emacs-24.5/lisp/cus-start.el
+@@ -519,7 +519,6 @@
+ (x-gtk-use-old-file-dialog menu boolean "22.1")
+ (x-gtk-show-hidden-files menu boolean "22.1")
+ (x-gtk-file-dialog-help-text menu boolean "22.1")
+- (x-gtk-whole-detached-tool-bar x boolean "22.1")
+ (x-gtk-use-system-tooltips tooltip boolean "23.3")
+ ;; xterm.c
+ (x-use-underline-position-properties display boolean "22.1")
+--- emacs-24.5-orig/lisp/term/x-win.el
++++ emacs-24.5/lisp/term/x-win.el
+@@ -1475,47 +1475,47 @@
+ (mapcar (lambda (arg)
+ (cons (purecopy (car arg)) (purecopy (cdr arg))))
+ '(
+- ("etc/images/new" . "gtk-new")
+- ("etc/images/open" . "gtk-open")
++ ("etc/images/new" . ("document-new" "gtk-new"))
++ ("etc/images/open" . ("document-open" "gtk-open"))
+ ("etc/images/diropen" . "n:system-file-manager")
+- ("etc/images/close" . "gtk-close")
+- ("etc/images/save" . "gtk-save")
+- ("etc/images/saveas" . "gtk-save-as")
+- ("etc/images/undo" . "gtk-undo")
+- ("etc/images/cut" . "gtk-cut")
+- ("etc/images/copy" . "gtk-copy")
+- ("etc/images/paste" . "gtk-paste")
+- ("etc/images/search" . "gtk-find")
+- ("etc/images/print" . "gtk-print")
+- ("etc/images/preferences" . "gtk-preferences")
+- ("etc/images/help" . "gtk-help")
+- ("etc/images/left-arrow" . "gtk-go-back")
+- ("etc/images/right-arrow" . "gtk-go-forward")
+- ("etc/images/home" . "gtk-home")
+- ("etc/images/jump-to" . "gtk-jump-to")
++ ("etc/images/close" . ("window-close" "gtk-close"))
++ ("etc/images/save" . ("document-save" "gtk-save"))
++ ("etc/images/saveas" . ("document-save-as" "gtk-save-as"))
++ ("etc/images/undo" . ("edit-undo" "gtk-undo"))
++ ("etc/images/cut" . ("edit-cut" "gtk-cut"))
++ ("etc/images/copy" . ("edit-copy" "gtk-copy"))
++ ("etc/images/paste" . ("edit-paste" "gtk-paste"))
++ ("etc/images/search" . ("edit-find" "gtk-find"))
++ ("etc/images/print" . ("document-print" "gtk-print"))
++ ("etc/images/preferences" . ("preferences-system" "gtk-preferences"))
++ ("etc/images/help" . ("help-browser" "gtk-help"))
++ ("etc/images/left-arrow" . ("go-previous" "gtk-go-back"))
++ ("etc/images/right-arrow" . ("go-next" "gtk-go-forward"))
++ ("etc/images/home" . ("go-home" "gtk-home"))
++ ("etc/images/jump-to" . ("go-jump" "gtk-jump-to"))
+ ("etc/images/index" . "gtk-index")
+- ("etc/images/search" . "gtk-find")
+- ("etc/images/exit" . "gtk-quit")
++ ("etc/images/exit" . ("application-exit" "gtk-quit"))
+ ("etc/images/cancel" . "gtk-cancel")
+- ("etc/images/info" . "gtk-info")
++ ("etc/images/info" . ("dialog-information" "gtk-info"))
+ ("etc/images/bookmark_add" . "n:bookmark_add")
+ ;; Used in Gnus and/or MH-E:
+ ("etc/images/attach" . "gtk-attach")
+ ("etc/images/connect" . "gtk-connect")
+ ("etc/images/contact" . "gtk-contact")
+- ("etc/images/delete" . "gtk-delete")
+- ("etc/images/describe" . "gtk-properties")
++ ("etc/images/delete" . ("edit-delete" "gtk-delete"))
++ ("etc/images/describe" . ("ocument-properties" "gtk-properties"))
+ ("etc/images/disconnect" . "gtk-disconnect")
+ ;; ("etc/images/exit" . "gtk-exit")
+ ("etc/images/lock-broken" . "gtk-lock_broken")
+ ("etc/images/lock-ok" . "gtk-lock_ok")
+ ("etc/images/lock" . "gtk-lock")
+ ("etc/images/next-page" . "gtk-next-page")
+- ("etc/images/refresh" . "gtk-refresh")
+- ("etc/images/sort-ascending" . "gtk-sort-ascending")
++ ("etc/images/refresh" . ("view-refresh" "gtk-refresh"))
++ ("etc/images/sort-ascending" . ("view-sort-ascending" "gtk-sort-ascending"))
+ ("etc/images/sort-column-ascending" . "gtk-sort-column-ascending")
+ ("etc/images/sort-criteria" . "gtk-sort-criteria")
+- ("etc/images/sort-descending" . "gtk-sort-descending")
++ ("etc/images/sort-descending" . ("view-sort-descending"
++ "gtk-sort-descending"))
+ ("etc/images/sort-row-ascending" . "gtk-sort-row-ascending")
+ ("images/gnus/toggle-subscription" . "gtk-task-recurring")
+ ("images/mail/compose" . "gtk-mail-compose")
+@@ -1532,8 +1532,8 @@
+ ("images/mail/spam" . "gtk-spam")
+ ;; Used for GDB Graphical Interface
+ ("images/gud/break" . "gtk-no")
+- ("images/gud/recstart" . "gtk-media-record")
+- ("images/gud/recstop" . "gtk-media-stop")
++ ("images/gud/recstart" . ("media-record" "gtk-media-record"))
++ ("images/gud/recstop" . ("media-playback-stop" "gtk-media-stop"))
+ ;; No themed versions available:
+ ;; mail/preview (combining stock_mail and stock_zoom)
+ ;; mail/save (combining stock_mail, stock_save and stock_convert)
+@@ -1542,9 +1542,12 @@
+ Emacs must be compiled with the Gtk+ toolkit for this to have any effect.
+ A value that begins with n: denotes a named icon instead of a stock icon."
+ :version "22.2"
+- :type '(choice (repeat (choice symbol
+- (cons (string :tag "Emacs icon")
+- (string :tag "Stock/named")))))
++ :type '(choice (repeat
++ (choice symbol
++ (cons (string :tag "Emacs icon")
++ (choice (group (string :tag "Named")
++ (string :tag "Stock"))
++ (string :tag "Stock/named"))))))
+ :group 'x)
+
+ (defcustom icon-map-list '(x-gtk-stock-map)
+--- emacs-24.5-orig/src/gtkutil.c
++++ emacs-24.5/src/gtkutil.c
+@@ -92,6 +92,16 @@
+ #endif
+ #endif /* HAVE_FREETYPE */
+
++#if GTK_CHECK_VERSION (3, 10, 0)
++#define XG_TEXT_CANCEL "Cancel"
++#define XG_TEXT_OK "OK"
++#define XG_TEXT_OPEN "Open"
++#else
++#define XG_TEXT_CANCEL GTK_STOCK_CANCEL
++#define XG_TEXT_OK GTK_STOCK_OK
++#define XG_TEXT_OPEN GTK_STOCK_OPEN
++#endif
++
+ #ifndef HAVE_GTK3
+ #ifdef USE_GTK_TOOLTIP
+ #define gdk_window_get_screen(w) gdk_drawable_get_screen (w)
+@@ -1826,9 +1836,9 @@
+ action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
+
+ filewin = gtk_file_chooser_dialog_new (prompt, gwin, action,
+- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
++ XG_TEXT_CANCEL, GTK_RESPONSE_CANCEL,
+ (mustmatch_p || only_dir_p ?
+- GTK_STOCK_OPEN : GTK_STOCK_OK),
++ XG_TEXT_OPEN : XG_TEXT_OK),
+ GTK_RESPONSE_OK,
+ NULL);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (filewin), TRUE);
+@@ -2408,57 +2418,6 @@
+ return w;
+ }
+
+-#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
+-
+-static int xg_detached_menus;
+-
+-/* Return true if there are detached menus. */
+-
+-bool
+-xg_have_tear_offs (struct frame *f)
+-{
+- /* 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
+- decrease the xg_detached_menus count.
+- WIDGET is the top level window that is removed (the parent of the menu).
+- CLIENT_DATA is not used. */
+-
+-static void
+-tearoff_remove (GtkWidget *widget, gpointer client_data)
+-{
+- if (xg_detached_menus > 0) --xg_detached_menus;
+-}
+-
+-/* Callback invoked when a menu is detached. It increases the
+- xg_detached_menus count.
+- WIDGET is the GtkTearoffMenuItem.
+- CLIENT_DATA is not used. */
+-
+-static void
+-tearoff_activate (GtkWidget *widget, gpointer client_data)
+-{
+- GtkWidget *menu = gtk_widget_get_parent (widget);
+- if (gtk_menu_get_tearoff_state (GTK_MENU (menu)))
+- {
+- ++xg_detached_menus;
+- g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (widget)),
+- "destroy",
+- G_CALLBACK (tearoff_remove), 0);
+- }
+-}
+-#else /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
+-bool
+-xg_have_tear_offs (struct frame *f)
+-{
+- return FRAME_MENUBAR_HEIGHT (f) == 0;
+-}
+-#endif /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
+-
+ /* Create a menu item widget, and connect the callbacks.
+ ITEM describes the menu item.
+ F is the frame the created menu belongs to.
+@@ -2529,8 +2488,6 @@
+ HIGHLIGHT_CB is the callback to call when entering/leaving menu items.
+ If POP_UP_P, create a popup menu.
+ If MENU_BAR_P, create a menu bar.
+- If ADD_TEAROFF_P, add a tearoff menu item. Ignored if MENU_BAR_P or
+- the Gtk+ version used does not have tearoffs.
+ TOPMENU is the topmost GtkWidget that others shall be placed under.
+ It may be NULL, in that case we create the appropriate widget
+ (menu bar or menu item depending on POP_UP_P and MENU_BAR_P)
+@@ -2552,7 +2509,6 @@
+ GCallback highlight_cb,
+ bool pop_up_p,
+ bool menu_bar_p,
+- bool add_tearoff_p,
+ GtkWidget *topmenu,
+ xg_menu_cb_data *cl_data,
+ const char *name)
+@@ -2603,17 +2559,6 @@
+ "selection-done", deactivate_cb, 0);
+ }
+
+-#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
+- if (! menu_bar_p && add_tearoff_p)
+- {
+- GtkWidget *tearoff = gtk_tearoff_menu_item_new ();
+- gtk_menu_shell_append (GTK_MENU_SHELL (wmenu), tearoff);
+-
+- g_signal_connect (G_OBJECT (tearoff), "activate",
+- G_CALLBACK (tearoff_activate), 0);
+- }
+-#endif
+-
+ for (item = data; item; item = item->next)
+ {
+ GtkWidget *w;
+@@ -2627,7 +2572,6 @@
+ group = NULL;
+ utf8_label = get_utf8_string (item->name);
+
+- gtk_menu_set_title (GTK_MENU (wmenu), utf8_label);
+ w = gtk_menu_item_new_with_label (utf8_label);
+ gtk_widget_set_sensitive (w, FALSE);
+ if (utf8_label) g_free (utf8_label);
+@@ -2658,7 +2602,6 @@
+ highlight_cb,
+ 0,
+ 0,
+- add_tearoff_p,
+ 0,
+ cl_data,
+ 0);
+@@ -2716,7 +2659,6 @@
+ highlight_cb,
+ pop_up_p,
+ menu_bar_p,
+- menu_bar_p,
+ 0,
+ 0,
+ name);
+@@ -2826,7 +2768,7 @@
+ {
+ /* Item(s) added. Add all new items in one call. */
+ create_menus (val, f, select_cb, deactivate_cb, highlight_cb,
+- 0, 1, 0, menubar, cl_data, 0);
++ 0, 1, menubar, cl_data, 0);
+
+ /* All updated. */
+ val = 0;
+@@ -2899,7 +2841,6 @@
+ is up to date when leaving the minibuffer. */
+ GtkLabel *wlabel = GTK_LABEL (XG_BIN_CHILD (witem));
+ 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
+@@ -2909,14 +2850,6 @@
+ 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
+- the title in the WM decorations also. */
+- if (submenu && gtk_menu_get_tearoff_state (GTK_MENU (submenu)))
+- /* Set the title of the detached window. */
+- gtk_menu_set_title (GTK_MENU (submenu), utf8_label);
+-#endif
+-
+ if (utf8_label) g_free (utf8_label);
+ iter = g_list_next (iter);
+ val = val->next;
+@@ -2943,7 +2876,7 @@
+ GtkWidget *submenu = create_menus (NULL, f,
+ select_cb, deactivate_cb,
+ highlight_cb,
+- 0, 0, 0, 0, cl_data, 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);
+@@ -3140,7 +3073,6 @@
+ GList *list = 0;
+ GList *iter;
+ widget_value *cur;
+- bool has_tearoff_p = 0;
+ GList *first_radio = 0;
+
+ if (submenu)
+@@ -3152,17 +3084,6 @@
+ {
+ GtkWidget *w = GTK_WIDGET (iter->data);
+
+-#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
+- /* Skip tearoff items, they have no counterpart in val. */
+- if (GTK_IS_TEAROFF_MENU_ITEM (w))
+- {
+- has_tearoff_p = 1;
+- iter = g_list_next (iter);
+- if (iter) w = GTK_WIDGET (iter->data);
+- else break;
+- }
+-#endif
+-
+ /* Remember first radio button in a group. If we get a mismatch in
+ a radio group we must rebuild the whole group so that the connections
+ in GTK becomes correct. */
+@@ -3250,7 +3171,6 @@
+ highlight_cb,
+ 0,
+ 0,
+- ! has_tearoff_p,
+ submenu,
+ cl_data,
+ 0);
+@@ -3908,9 +3828,6 @@
+ get them. */
+ #define XG_TOOL_BAR_LAST_MODIFIER "emacs-tool-bar-modifier"
+
+-/* The key for storing the button widget in its proxy menu item. */
+-#define XG_TOOL_BAR_PROXY_BUTTON "emacs-tool-bar-proxy-button"
+-
+ /* The key for the data we put in the GtkImage widgets. The data is
+ the stock name used by Emacs. We use this to see if we need to update
+ the GtkImage with a new image. */
+@@ -3983,41 +3900,6 @@
+ x_focus_frame (f);
+ }
+
+-/* Callback function invoked when a tool bar item is pressed in a detached
+- tool bar or the overflow drop down menu.
+- We just call xg_tool_bar_callback.
+- W is the menu item widget that got pressed,
+- CLIENT_DATA is an integer that is the index of the button in the
+- tool bar. 0 is the first button. */
+-
+-static void
+-xg_tool_bar_proxy_callback (GtkWidget *w, gpointer client_data)
+-{
+- GtkWidget *wbutton = GTK_WIDGET (g_object_get_data (G_OBJECT (w),
+- XG_TOOL_BAR_PROXY_BUTTON));
+- xg_tool_bar_callback (wbutton, client_data);
+-}
+-
+-
+-static gboolean
+-xg_tool_bar_help_callback (GtkWidget *w,
+- GdkEventCrossing *event,
+- gpointer client_data);
+-
+-/* This callback is called when a help is to be shown for an item in
+- the detached tool bar when the detached tool bar it is not expanded. */
+-
+-static gboolean
+-xg_tool_bar_proxy_help_callback (GtkWidget *w,
+- GdkEventCrossing *event,
+- gpointer client_data)
+-{
+- GtkWidget *wbutton = GTK_WIDGET (g_object_get_data (G_OBJECT (w),
+- XG_TOOL_BAR_PROXY_BUTTON));
+-
+- return xg_tool_bar_help_callback (wbutton, event, client_data);
+-}
+-
+ static GtkWidget *
+ xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage)
+ {
+@@ -4031,187 +3913,6 @@
+ }
+
+
+-/* This callback is called when a tool item should create a proxy item,
+- such as for the overflow menu. Also called when the tool bar is detached.
+- If we don't create a proxy menu item, the detached tool bar will be
+- blank. */
+-
+-static gboolean
+-xg_tool_bar_menu_proxy (GtkToolItem *toolitem, gpointer user_data)
+-{
+- GtkButton *wbutton = GTK_BUTTON (XG_BIN_CHILD (XG_BIN_CHILD (toolitem)));
+- GtkWidget *vb = XG_BIN_CHILD (wbutton);
+- GtkWidget *c1;
+- GtkLabel *wlbl = GTK_LABEL (xg_get_tool_bar_widgets (vb, &c1));
+- GtkImage *wimage = GTK_IMAGE (c1);
+- GtkWidget *wmenuitem = gtk_image_menu_item_new_with_label
+- (wlbl ? gtk_label_get_text (wlbl) : "");
+- GtkWidget *wmenuimage;
+-
+-
+- if (gtk_button_get_use_stock (wbutton))
+- wmenuimage = gtk_image_new_from_stock (gtk_button_get_label (wbutton),
+- GTK_ICON_SIZE_MENU);
+- else
+- {
+- GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (wbutton));
+- GtkImageType store_type = gtk_image_get_storage_type (wimage);
+-
+- g_object_set (G_OBJECT (settings), "gtk-menu-images", TRUE, NULL);
+-
+- if (store_type == GTK_IMAGE_STOCK)
+- {
+- gchar *stock_id;
+- gtk_image_get_stock (wimage, &stock_id, NULL);
+- wmenuimage = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+- }
+- else if (store_type == GTK_IMAGE_ICON_SET)
+- {
+- GtkIconSet *icon_set;
+- gtk_image_get_icon_set (wimage, &icon_set, NULL);
+- wmenuimage = gtk_image_new_from_icon_set (icon_set,
+- GTK_ICON_SIZE_MENU);
+- }
+- else if (store_type == GTK_IMAGE_PIXBUF)
+- {
+- gint width, height;
+-
+- if (settings &&
+- gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
+- &width, &height))
+- {
+- GdkPixbuf *src_pixbuf, *dest_pixbuf;
+-
+- src_pixbuf = gtk_image_get_pixbuf (wimage);
+- dest_pixbuf = gdk_pixbuf_scale_simple (src_pixbuf, width, height,
+- GDK_INTERP_BILINEAR);
+-
+- wmenuimage = gtk_image_new_from_pixbuf (dest_pixbuf);
+- }
+- else
+- {
+- fprintf (stderr, "internal error: GTK_IMAGE_PIXBUF failed\n");
+- emacs_abort ();
+- }
+- }
+- else if (store_type == GTK_IMAGE_ICON_NAME)
+- {
+- const gchar *icon_name;
+- GtkIconSize icon_size;
+-
+- gtk_image_get_icon_name (wimage, &icon_name, &icon_size);
+- wmenuimage = gtk_image_new_from_icon_name (icon_name,
+- GTK_ICON_SIZE_MENU);
+- }
+- else
+- {
+- fprintf (stderr, "internal error: store_type is %d\n", store_type);
+- emacs_abort ();
+- }
+- }
+- if (wmenuimage)
+- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (wmenuitem), wmenuimage);
+-
+- g_signal_connect (G_OBJECT (wmenuitem),
+- "activate",
+- G_CALLBACK (xg_tool_bar_proxy_callback),
+- user_data);
+-
+-
+- g_object_set_data (G_OBJECT (wmenuitem), XG_TOOL_BAR_PROXY_BUTTON,
+- (gpointer) wbutton);
+- gtk_tool_item_set_proxy_menu_item (toolitem, "Emacs toolbar item", wmenuitem);
+- gtk_widget_set_sensitive (wmenuitem,
+- gtk_widget_get_sensitive (GTK_WIDGET (wbutton)));
+-
+- /* Use enter/leave notify to show help. We use the events
+- rather than the GtkButton specific signals "enter" and
+- "leave", so we can have only one callback. The event
+- will tell us what kind of event it is. */
+- g_signal_connect (G_OBJECT (wmenuitem),
+- "enter-notify-event",
+- G_CALLBACK (xg_tool_bar_proxy_help_callback),
+- user_data);
+- g_signal_connect (G_OBJECT (wmenuitem),
+- "leave-notify-event",
+- G_CALLBACK (xg_tool_bar_proxy_help_callback),
+- user_data);
+-
+- return TRUE;
+-}
+-
+-/* This callback is called when a tool bar is detached. We must set
+- the height of the tool bar to zero when this happens so frame sizes
+- are correctly calculated.
+- WBOX is the handle box widget that enables detach/attach of the tool bar.
+- W is the tool bar widget.
+- CLIENT_DATA is a pointer to the frame the tool bar belongs to. */
+-
+-static void
+-xg_tool_bar_detach_callback (GtkHandleBox *wbox,
+- GtkWidget *w,
+- gpointer client_data)
+-{
+- struct frame *f = client_data;
+-
+- g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar,
+- NULL);
+-
+- if (f)
+- {
+- GtkRequisition req, req2;
+-
+- gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req);
+- gtk_widget_get_preferred_size (w, NULL, &req2);
+- req.width -= req2.width;
+- req.height -= req2.height;
+- if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0)
+- FRAME_TOOLBAR_TOP_HEIGHT (f) = req.height;
+- else if (FRAME_TOOLBAR_BOTTOM_HEIGHT (f) != 0)
+- FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = req.height;
+- else if (FRAME_TOOLBAR_RIGHT_WIDTH (f) != 0)
+- FRAME_TOOLBAR_RIGHT_WIDTH (f) = req.width;
+- else if (FRAME_TOOLBAR_LEFT_WIDTH (f) != 0)
+- FRAME_TOOLBAR_LEFT_WIDTH (f) = req.width;
+- xg_height_or_width_changed (f);
+- }
+-}
+-
+-/* This callback is called when a tool bar is reattached. We must set
+- the height of the tool bar when this happens so frame sizes
+- are correctly calculated.
+- WBOX is the handle box widget that enables detach/attach of the tool bar.
+- W is the tool bar widget.
+- CLIENT_DATA is a pointer to the frame the tool bar belongs to. */
+-
+-static void
+-xg_tool_bar_attach_callback (GtkHandleBox *wbox,
+- GtkWidget *w,
+- gpointer client_data)
+-{
+- struct frame *f = client_data;
+- g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL);
+-
+- if (f)
+- {
+- GtkRequisition req, req2;
+-
+- gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req);
+- gtk_widget_get_preferred_size (w, NULL, &req2);
+- req.width += req2.width;
+- req.height += req2.height;
+- if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0)
+- FRAME_TOOLBAR_TOP_HEIGHT (f) = req.height;
+- else if (FRAME_TOOLBAR_BOTTOM_HEIGHT (f) != 0)
+- FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = req.height;
+- else if (FRAME_TOOLBAR_RIGHT_WIDTH (f) != 0)
+- FRAME_TOOLBAR_RIGHT_WIDTH (f) = req.width;
+- else if (FRAME_TOOLBAR_LEFT_WIDTH (f) != 0)
+- FRAME_TOOLBAR_LEFT_WIDTH (f) = req.width;
+- xg_height_or_width_changed (f);
+- }
+-}
+-
+ /* This callback is called when the mouse enters or leaves a tool bar item.
+ It is used for displaying and hiding the help text.
+ W is the tool bar item, a button.
+@@ -4291,12 +3992,6 @@
+ gtk_toolbar_set_orientation (GTK_TOOLBAR (w), o)
+ #endif
+
+-#ifdef HAVE_GTK_HANDLE_BOX_NEW
+-#define TOOLBAR_TOP_WIDGET(x) ((x)->handlebox_widget)
+-#else
+-#define TOOLBAR_TOP_WIDGET(x) ((x)->toolbar_widget)
+-#endif
+-
+ /* Attach a tool bar to frame F. */
+
+ static void
+@@ -4304,31 +3999,15 @@
+ {
+ struct x_output *x = f->output_data.x;
+ bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright);
+- GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x);
++ GtkWidget *top_widget = x->toolbar_widget;
+
+ toolbar_set_orientation (x->toolbar_widget,
+ into_hbox
+ ? GTK_ORIENTATION_VERTICAL
+ : GTK_ORIENTATION_HORIZONTAL);
+-#ifdef HAVE_GTK_HANDLE_BOX_NEW
+- if (!x->handlebox_widget)
+- {
+- top_widget = x->handlebox_widget = gtk_handle_box_new ();
+- g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached",
+- G_CALLBACK (xg_tool_bar_detach_callback), f);
+- g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached",
+- G_CALLBACK (xg_tool_bar_attach_callback), f);
+- gtk_container_add (GTK_CONTAINER (x->handlebox_widget),
+- x->toolbar_widget);
+- }
+-#endif
+
+ if (into_hbox)
+ {
+-#ifdef HAVE_GTK_HANDLE_BOX_NEW
+- gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (x->handlebox_widget),
+- GTK_POS_TOP);
+-#endif
+ gtk_box_pack_start (GTK_BOX (x->hbox_widget), top_widget,
+ FALSE, FALSE, 0);
+
+@@ -4341,10 +4020,6 @@
+ else
+ {
+ bool vbox_pos = x->menubar_widget != 0;
+-#ifdef HAVE_GTK_HANDLE_BOX_NEW
+- gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (x->handlebox_widget),
+- GTK_POS_LEFT);
+-#endif
+ gtk_box_pack_start (GTK_BOX (x->vbox_widget), top_widget,
+ FALSE, FALSE, 0);
+
+@@ -4497,10 +4172,6 @@
+ intptr_t ii = i;
+ gpointer gi = (gpointer) ii;
+
+- g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
+- G_CALLBACK (xg_tool_bar_menu_proxy),
+- gi);
+-
+ g_signal_connect (G_OBJECT (wb), "clicked",
+ G_CALLBACK (xg_tool_bar_callback),
+ gi);
+@@ -4614,7 +4285,7 @@
+ struct x_output *x = f->output_data.x;
+ GtkRequisition req;
+ int nl = 0, nr = 0, nt = 0, nb = 0;
+- GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x);
++ GtkWidget *top_widget = x->toolbar_widget;
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (top_widget), NULL, &req);
+ if (x->toolbar_in_hbox)
+@@ -4653,6 +4324,42 @@
+ return 0;
+ }
+
++static char *
++find_icon_from_name (char *name,
++ GtkIconTheme *icon_theme,
++ char **icon_name)
++{
++#if ! GTK_CHECK_VERSION (3, 10, 0)
++ GtkStockItem stock_item;
++#endif
++
++ if (name[0] == 'n' && name[1] == ':')
++ {
++ *icon_name = name + 2;
++ name = NULL;
++
++ if (! gtk_icon_theme_has_icon (icon_theme, *icon_name))
++ *icon_name = NULL;
++ }
++
++#if ! GTK_CHECK_VERSION (3, 10, 0)
++ else if (gtk_stock_lookup (name, &stock_item))
++ *icon_name = NULL;
++#endif
++ else if (gtk_icon_theme_has_icon (icon_theme, name))
++ {
++ *icon_name = name;
++ name = NULL;
++ }
++ else
++ {
++ name = NULL;
++ *icon_name = NULL;
++ }
++
++ return name;
++}
++
+
+ /* Update the tool bar for frame F. Add new buttons and remove old. */
+
+@@ -4668,6 +4375,9 @@
+ Lisp_Object style;
+ bool text_image, horiz;
+ struct xg_frame_tb_info *tbinfo;
++ GdkScreen *screen;
++ GtkIconTheme *icon_theme;
++
+
+ if (! FRAME_GTK_WIDGET (f))
+ return;
+@@ -4702,6 +4412,8 @@
+ dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar));
+
+ style = Ftool_bar_get_system_style ();
++ screen = gtk_widget_get_screen (GTK_WIDGET (wtoolbar));
++ icon_theme = gtk_icon_theme_get_for_screen (screen);
+
+ /* Are we up to date? */
+ tbinfo = g_object_get_data (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)),
+@@ -4738,7 +4450,6 @@
+ struct image *img = NULL;
+ Lisp_Object image;
+ Lisp_Object stock = Qnil;
+- GtkStockItem stock_item;
+ char *stock_name = NULL;
+ char *icon_name = NULL;
+ Lisp_Object rtl;
+@@ -4792,32 +4503,28 @@
+ if (!NILP (specified_file) && !NILP (Ffboundp (Qx_gtk_map_stock)))
+ stock = call1 (Qx_gtk_map_stock, specified_file);
+
+- if (STRINGP (stock))
++ if (CONSP (stock))
+ {
+- stock_name = SSDATA (stock);
+- if (stock_name[0] == 'n' && stock_name[1] == ':')
+- {
+- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (wtoolbar));
+- GtkIconTheme *icon_theme = gtk_icon_theme_get_for_screen (screen);
+-
+- icon_name = stock_name + 2;
+- stock_name = NULL;
+- stock = Qnil;
+-
+- if (! gtk_icon_theme_has_icon (icon_theme, icon_name))
+- icon_name = NULL;
+- else
+- icon_size = gtk_toolbar_get_icon_size (wtoolbar);
+- }
+- else if (gtk_stock_lookup (SSDATA (stock), &stock_item))
+- icon_size = gtk_toolbar_get_icon_size (wtoolbar);
+- else
+- {
+- stock = Qnil;
+- stock_name = NULL;
+- }
++ Lisp_Object tem;
++ for (tem = stock; CONSP (tem); tem = XCDR (tem))
++ if (! NILP (tem) && STRINGP (XCAR (tem)))
++ {
++ stock_name = find_icon_from_name (SSDATA (XCAR (tem)),
++ icon_theme,
++ &icon_name);
++ if (stock_name || icon_name) break;
++ }
++ }
++ else if (STRINGP (stock))
++ {
++ stock_name = find_icon_from_name (SSDATA (stock),
++ icon_theme,
++ &icon_name);
+ }
+
++ if (stock_name || icon_name)
++ icon_size = gtk_toolbar_get_icon_size (wtoolbar);
++
+ if (stock_name == NULL && icon_name == NULL)
+ {
+ /* No stock image, or stock item not known. Try regular
+@@ -4878,7 +4585,12 @@
+ w = NULL;
+ else if (stock_name)
+ {
++
++#if GTK_CHECK_VERSION (3, 10, 0)
++ w = gtk_image_new_from_icon_name (stock_name, icon_size);
++#else
+ w = gtk_image_new_from_stock (stock_name, icon_size);
++#endif
+ g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_STOCK_NAME,
+ (gpointer) xstrdup (stock_name),
+ (GDestroyNotify) xfree);
+@@ -4920,7 +4632,7 @@
+ {
+ if (! x->toolbar_is_packed)
+ xg_pack_tool_bar (f, f->tool_bar_position);
+- gtk_widget_show_all (TOOLBAR_TOP_WIDGET (x));
++ gtk_widget_show_all (x->toolbar_widget);
+ if (xg_update_tool_bar_sizes (f))
+ xg_height_or_width_changed (f);
+ }
+@@ -4939,11 +4651,9 @@
+ if (x->toolbar_widget)
+ {
+ struct xg_frame_tb_info *tbinfo;
+- GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x);
++ GtkWidget *top_widget = x->toolbar_widget;
+
+ block_input ();
+- /* We may have created the toolbar_widget in xg_create_tool_bar, but
+- not the x->handlebox_widget which is created in xg_pack_tool_bar. */
+ if (x->toolbar_is_packed)
+ {
+ if (x->toolbar_in_hbox)
+@@ -4957,7 +4667,7 @@
+ gtk_widget_destroy (x->toolbar_widget);
+
+ x->toolbar_widget = 0;
+- TOOLBAR_TOP_WIDGET (x) = 0;
++ x->toolbar_widget = 0;
+ x->toolbar_is_packed = false;
+ FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0;
+ FRAME_TOOLBAR_LEFT_WIDTH (f) = FRAME_TOOLBAR_RIGHT_WIDTH (f) = 0;
+@@ -4982,7 +4692,7 @@
+ xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
+ {
+ struct x_output *x = f->output_data.x;
+- GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x);
++ GtkWidget *top_widget = x->toolbar_widget;
+
+ if (! x->toolbar_widget || ! top_widget)
+ return;
+@@ -5026,9 +4736,6 @@
+
+ gdpy_def = NULL;
+ xg_ignore_gtk_scrollbar = 0;
+-#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
+- xg_detached_menus = 0;
+-#endif
+ xg_menu_cb_list.prev = xg_menu_cb_list.next =
+ xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0;
+
+--- emacs-24.5-orig/src/gtkutil.h
++++ emacs-24.5/src/gtkutil.h
+@@ -107,8 +107,6 @@
+
+ extern bool xg_event_is_for_menubar (struct frame *, const XEvent *);
+
+-extern bool xg_have_tear_offs (struct frame *f);
+-
+ extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid);
+
+ extern void xg_create_scroll_bar (struct frame *f,
+--- emacs-24.5-orig/src/xfns.c
++++ emacs-24.5/src/xfns.c
+@@ -6221,12 +6221,6 @@
+ to turn the additional text off. */);
+ x_gtk_file_dialog_help_text = 1;
+
+- DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", x_gtk_whole_detached_tool_bar,
+- doc: /* If non-nil, a detached tool bar is shown in full.
+-The default is to just show an arrow and pressing on that arrow shows
+-the tool bar buttons. */);
+- x_gtk_whole_detached_tool_bar = 0;
+-
+ DEFVAR_BOOL ("x-gtk-use-system-tooltips", x_gtk_use_system_tooltips,
+ doc: /* If non-nil with a Gtk+ built Emacs, the Gtk+ tooltip is used.
+ Otherwise use Emacs own tooltip implementation.
+--- emacs-24.5-orig/src/xmenu.c
++++ emacs-24.5/src/xmenu.c
+@@ -793,12 +793,6 @@
+ f->output_data.x->saved_menu_event->type = 0;
+ }
+
+-#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 (f);
+-#endif
+-
+ if (deep_p)
+ {
+ /* Make a widget-value tree representing the entire menu trees. */
+--- emacs-24.5-orig/src/xterm.h
++++ emacs-24.5/src/xterm.h
+@@ -491,10 +491,6 @@
+ GtkWidget *menubar_widget;
+ /* The tool bar in this frame */
+ GtkWidget *toolbar_widget;
+-#ifdef HAVE_GTK_HANDLE_BOX_NEW
+-/* The handle box that makes the tool bar detachable. */
+- GtkWidget *handlebox_widget;
+-#endif
+ /* True if tool bar is packed into the hbox widget (i.e. vertical). */
+ bool_bf toolbar_in_hbox : 1;
+ bool_bf toolbar_is_packed : 1;