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 Date: Sat Oct 18 12:07:17 2014 -0700 * gtkutil.c: Remove no-longer-used code. commit 6e5ff6166647e6af30beff38f67f2bca86cf9786 Author: Jan Djärv 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 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 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;