aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv2014-10-18 18:19:53 +0200
committerJan Djärv2014-10-18 18:19:53 +0200
commit3f4c6d52d345999938bc2d4a53246af4c61ef176 (patch)
tree0103262a2daac51aa88c1cf0d27cacbd8a9192d2 /src
parenta4c80e35cc48376a3e35b11ee41cf3859b93efd5 (diff)
downloademacs-3f4c6d52d345999938bc2d4a53246af4c61ef176.tar.gz
emacs-3f4c6d52d345999938bc2d4a53246af4c61ef176.zip
Handle deprecated Gtk+ stuff for version <= 3.10
* lisp/term/x-win.el (x-gtk-stock-map): Add icon names suggested as replacements to stock names before stock names in a list. Cdr may be a list, each name is tried in turn until one is found. * src/gtkutil.c (XG_TEXT_CANCEL, XG_TEXT_OPEN, XG_TEXT_OK): New defines to handle Gtk versions. (xg_get_file_with_chooser): Use them. (xg_have_tear_offs, tearoff_remove, tearoff_activate): Remove (create_menus): Remove teroff argument and code. Remove call to gtk_menu_set_title. (xg_update_menubar, xg_update_submenu): Remove tearoff code. Adjust args to create_menus. (xg_tool_bar_menu_proxy, xg_tool_bar_detach_callback) (xg_tool_bar_attach_callback, TOOLBAR_TOP_WIDGET): Remove. (xg_pack_tool_bar): Replace TOOLBAR_TOP_WIDGET, remove detach code. (xg_make_tool_item): Remove detach code. (xg_update_tool_bar_sizes): Replace TOOLBAR_TOP_WIDGET. (find_icon_from_name): New function. (update_frame_tool_bar): Remove GtkStockItem code, move to find_icon_from_name. Let stock be a list of icon names to try. Only use gtk_image_new_from_stock on Gtk+ < 3.10. Replace TOOLBAR_TOP_WIDGET. (free_frame_tool_bar, xg_change_toolbar_position ): Replace TOOLBAR_TOP_WIDGET. (xg_initialize): Remove tearoff code. * src/gtkutil.h (xg_have_tear_offs): Remove declaration. * src/xmenu.c (set_frame_menubar): Remove GTK block that calls xg_have_tear_offs. * src/xterm.h (handlebox_widget): Remove.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog31
-rw-r--r--src/gtkutil.c427
-rw-r--r--src/gtkutil.h2
-rw-r--r--src/xmenu.c6
-rw-r--r--src/xterm.h4
5 files changed, 116 insertions, 354 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a28ae469001..9ac2695a0e0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,34 @@
12014-10-18 Jan Djärv <jan.h.d@swipnet.se>
2
3 * xterm.h (handlebox_widget): Remove.
4
5 * xmenu.c (set_frame_menubar): Remove GTK block that calls
6 xg_have_tear_offs.
7
8 * gtkutil.h (xg_have_tear_offs): Remove declaration.
9
10 * gtkutil.c (XG_TEXT_CANCEL, XG_TEXT_OPEN, XG_TEXT_OK): New defines
11 to handle Gtk versions.
12 (xg_get_file_with_chooser): Use them.
13 (xg_have_tear_offs, tearoff_remove, tearoff_activate): Remove
14 (create_menus): Remove teroff argument and code.
15 Remove call to gtk_menu_set_title.
16 (xg_update_menubar, xg_update_submenu): Remove tearoff code. Adjust
17 args to create_menus.
18 (xg_tool_bar_menu_proxy, xg_tool_bar_detach_callback)
19 (xg_tool_bar_attach_callback, TOOLBAR_TOP_WIDGET): Remove.
20 (xg_pack_tool_bar): Replace TOOLBAR_TOP_WIDGET, remove detach code.
21 (xg_make_tool_item): Remove detach code.
22 (xg_update_tool_bar_sizes): Replace TOOLBAR_TOP_WIDGET.
23 (find_icon_from_name): New function.
24 (update_frame_tool_bar): Remove GtkStockItem code, move to
25 find_icon_from_name. Let stock be a list of icon names to try.
26 Only use gtk_image_new_from_stock on Gtk+ < 3.10.
27 Replace TOOLBAR_TOP_WIDGET.
28 (free_frame_tool_bar, xg_change_toolbar_position ): Replace
29 TOOLBAR_TOP_WIDGET.
30 (xg_initialize): Remove tearoff code.
31
12014-10-18 Eli Zaretskii <eliz@gnu.org> 322014-10-18 Eli Zaretskii <eliz@gnu.org>
2 33
3 * xterm.c (x_draw_bar_cursor, x_draw_hollow_cursor): Subtract 1 34 * xterm.c (x_draw_bar_cursor, x_draw_hollow_cursor): Subtract 1
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 445e59c335d..89897f8afa5 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -93,6 +93,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
93#endif 93#endif
94#endif /* HAVE_FREETYPE */ 94#endif /* HAVE_FREETYPE */
95 95
96#if GTK_CHECK_VERSION (3, 10, 0)
97#define XG_TEXT_CANCEL "Cancel"
98#define XG_TEXT_OK "OK"
99#define XG_TEXT_OPEN "Open"
100#else
101#define XG_TEXT_CANCEL GTK_STOCK_CANCEL
102#define XG_TEXT_OK GTK_STOCK_OK
103#define XG_TEXT_OPEN GTK_STOCK_OPEN
104#endif
105
96#ifndef HAVE_GTK3 106#ifndef HAVE_GTK3
97#ifdef USE_GTK_TOOLTIP 107#ifdef USE_GTK_TOOLTIP
98#define gdk_window_get_screen(w) gdk_drawable_get_screen (w) 108#define gdk_window_get_screen(w) gdk_drawable_get_screen (w)
@@ -1774,9 +1784,9 @@ xg_get_file_with_chooser (struct frame *f,
1774 action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; 1784 action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
1775 1785
1776 filewin = gtk_file_chooser_dialog_new (prompt, gwin, action, 1786 filewin = gtk_file_chooser_dialog_new (prompt, gwin, action,
1777 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 1787 XG_TEXT_CANCEL, GTK_RESPONSE_CANCEL,
1778 (mustmatch_p || only_dir_p ? 1788 (mustmatch_p || only_dir_p ?
1779 GTK_STOCK_OPEN : GTK_STOCK_OK), 1789 XG_TEXT_OPEN : XG_TEXT_OK),
1780 GTK_RESPONSE_OK, 1790 GTK_RESPONSE_OK,
1781 NULL); 1791 NULL);
1782 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (filewin), TRUE); 1792 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (filewin), TRUE);
@@ -2356,57 +2366,6 @@ make_menu_item (const char *utf8_label,
2356 return w; 2366 return w;
2357} 2367}
2358 2368
2359#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
2360
2361static int xg_detached_menus;
2362
2363/* Return true if there are detached menus. */
2364
2365bool
2366xg_have_tear_offs (struct frame *f)
2367{
2368 /* If the frame's menubar height is zero, the menu bar is probably
2369 being redirected outside the window to some kind of global menu;
2370 this situation is the moral equivalent of a tear-off. */
2371 return FRAME_MENUBAR_HEIGHT (f) == 0 || xg_detached_menus > 0;
2372}
2373
2374/* Callback invoked when a detached menu window is removed. Here we
2375 decrease the xg_detached_menus count.
2376 WIDGET is the top level window that is removed (the parent of the menu).
2377 CLIENT_DATA is not used. */
2378
2379static void
2380tearoff_remove (GtkWidget *widget, gpointer client_data)
2381{
2382 if (xg_detached_menus > 0) --xg_detached_menus;
2383}
2384
2385/* Callback invoked when a menu is detached. It increases the
2386 xg_detached_menus count.
2387 WIDGET is the GtkTearoffMenuItem.
2388 CLIENT_DATA is not used. */
2389
2390static void
2391tearoff_activate (GtkWidget *widget, gpointer client_data)
2392{
2393 GtkWidget *menu = gtk_widget_get_parent (widget);
2394 if (gtk_menu_get_tearoff_state (GTK_MENU (menu)))
2395 {
2396 ++xg_detached_menus;
2397 g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (widget)),
2398 "destroy",
2399 G_CALLBACK (tearoff_remove), 0);
2400 }
2401}
2402#else /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
2403bool
2404xg_have_tear_offs (struct frame *f)
2405{
2406 return FRAME_MENUBAR_HEIGHT (f) == 0;
2407}
2408#endif /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
2409
2410/* Create a menu item widget, and connect the callbacks. 2369/* Create a menu item widget, and connect the callbacks.
2411 ITEM describes the menu item. 2370 ITEM describes the menu item.
2412 F is the frame the created menu belongs to. 2371 F is the frame the created menu belongs to.
@@ -2477,8 +2436,6 @@ xg_create_one_menuitem (widget_value *item,
2477 HIGHLIGHT_CB is the callback to call when entering/leaving menu items. 2436 HIGHLIGHT_CB is the callback to call when entering/leaving menu items.
2478 If POP_UP_P, create a popup menu. 2437 If POP_UP_P, create a popup menu.
2479 If MENU_BAR_P, create a menu bar. 2438 If MENU_BAR_P, create a menu bar.
2480 If ADD_TEAROFF_P, add a tearoff menu item. Ignored if MENU_BAR_P or
2481 the Gtk+ version used does not have tearoffs.
2482 TOPMENU is the topmost GtkWidget that others shall be placed under. 2439 TOPMENU is the topmost GtkWidget that others shall be placed under.
2483 It may be NULL, in that case we create the appropriate widget 2440 It may be NULL, in that case we create the appropriate widget
2484 (menu bar or menu item depending on POP_UP_P and MENU_BAR_P) 2441 (menu bar or menu item depending on POP_UP_P and MENU_BAR_P)
@@ -2500,7 +2457,6 @@ create_menus (widget_value *data,
2500 GCallback highlight_cb, 2457 GCallback highlight_cb,
2501 bool pop_up_p, 2458 bool pop_up_p,
2502 bool menu_bar_p, 2459 bool menu_bar_p,
2503 bool add_tearoff_p,
2504 GtkWidget *topmenu, 2460 GtkWidget *topmenu,
2505 xg_menu_cb_data *cl_data, 2461 xg_menu_cb_data *cl_data,
2506 const char *name) 2462 const char *name)
@@ -2551,24 +2507,6 @@ create_menus (widget_value *data,
2551 "selection-done", deactivate_cb, 0); 2507 "selection-done", deactivate_cb, 0);
2552 } 2508 }
2553 2509
2554#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
2555 if (! menu_bar_p && add_tearoff_p)
2556 {
2557 // Only add tearoff if menu is empty.
2558 GList *list = gtk_container_get_children (GTK_CONTAINER (wmenu));
2559 if (! list)
2560 {
2561 GtkWidget *tearoff = gtk_tearoff_menu_item_new ();
2562 gtk_menu_shell_append (GTK_MENU_SHELL (wmenu), tearoff);
2563
2564 g_signal_connect (G_OBJECT (tearoff), "activate",
2565 G_CALLBACK (tearoff_activate), 0);
2566 }
2567 else
2568 g_list_free (list);
2569 }
2570#endif
2571
2572 for (item = data; item; item = item->next) 2510 for (item = data; item; item = item->next)
2573 { 2511 {
2574 GtkWidget *w; 2512 GtkWidget *w;
@@ -2582,7 +2520,6 @@ create_menus (widget_value *data,
2582 group = NULL; 2520 group = NULL;
2583 utf8_label = get_utf8_string (item->name); 2521 utf8_label = get_utf8_string (item->name);
2584 2522
2585 gtk_menu_set_title (GTK_MENU (wmenu), utf8_label);
2586 w = gtk_menu_item_new_with_label (utf8_label); 2523 w = gtk_menu_item_new_with_label (utf8_label);
2587 gtk_widget_set_sensitive (w, FALSE); 2524 gtk_widget_set_sensitive (w, FALSE);
2588 if (utf8_label) g_free (utf8_label); 2525 if (utf8_label) g_free (utf8_label);
@@ -2613,7 +2550,6 @@ create_menus (widget_value *data,
2613 highlight_cb, 2550 highlight_cb,
2614 0, 2551 0,
2615 0, 2552 0,
2616 add_tearoff_p,
2617 0, 2553 0,
2618 cl_data, 2554 cl_data,
2619 0); 2555 0);
@@ -2671,7 +2607,6 @@ xg_create_widget (const char *type, const char *name, struct frame *f,
2671 highlight_cb, 2607 highlight_cb,
2672 pop_up_p, 2608 pop_up_p,
2673 menu_bar_p, 2609 menu_bar_p,
2674 menu_bar_p,
2675 0, 2610 0,
2676 0, 2611 0,
2677 name); 2612 name);
@@ -2781,7 +2716,7 @@ xg_update_menubar (GtkWidget *menubar,
2781 { 2716 {
2782 /* Item(s) added. Add all new items in one call. */ 2717 /* Item(s) added. Add all new items in one call. */
2783 create_menus (val, f, select_cb, deactivate_cb, highlight_cb, 2718 create_menus (val, f, select_cb, deactivate_cb, highlight_cb,
2784 0, 1, 0, menubar, cl_data, 0); 2719 0, 1, menubar, cl_data, 0);
2785 2720
2786 /* All updated. */ 2721 /* All updated. */
2787 val = 0; 2722 val = 0;
@@ -2864,14 +2799,6 @@ xg_update_menubar (GtkWidget *menubar,
2864 gtk_label_set_text (wlabel, utf8_label); 2799 gtk_label_set_text (wlabel, utf8_label);
2865 g_object_notify (G_OBJECT (witem), "label"); 2800 g_object_notify (G_OBJECT (witem), "label");
2866 2801
2867#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
2868 /* If this item has a submenu that has been detached, change
2869 the title in the WM decorations also. */
2870 if (submenu && gtk_menu_get_tearoff_state (GTK_MENU (submenu)))
2871 /* Set the title of the detached window. */
2872 gtk_menu_set_title (GTK_MENU (submenu), utf8_label);
2873#endif
2874
2875 if (utf8_label) g_free (utf8_label); 2802 if (utf8_label) g_free (utf8_label);
2876 iter = g_list_next (iter); 2803 iter = g_list_next (iter);
2877 val = val->next; 2804 val = val->next;
@@ -2898,7 +2825,7 @@ xg_update_menubar (GtkWidget *menubar,
2898 GtkWidget *submenu = create_menus (NULL, f, 2825 GtkWidget *submenu = create_menus (NULL, f,
2899 select_cb, deactivate_cb, 2826 select_cb, deactivate_cb,
2900 highlight_cb, 2827 highlight_cb,
2901 0, 0, 0, 0, cl_data, 0); 2828 0, 0, 0, cl_data, 0);
2902 2829
2903 gtk_widget_set_name (w, MENU_ITEM_NAME); 2830 gtk_widget_set_name (w, MENU_ITEM_NAME);
2904 gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), w, pos); 2831 gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), w, pos);
@@ -3106,16 +3033,6 @@ xg_update_submenu (GtkWidget *submenu,
3106 { 3033 {
3107 GtkWidget *w = GTK_WIDGET (iter->data); 3034 GtkWidget *w = GTK_WIDGET (iter->data);
3108 3035
3109#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
3110 /* Skip tearoff items, they have no counterpart in val. */
3111 if (GTK_IS_TEAROFF_MENU_ITEM (w))
3112 {
3113 iter = g_list_next (iter);
3114 if (iter) w = GTK_WIDGET (iter->data);
3115 else break;
3116 }
3117#endif
3118
3119 /* Remember first radio button in a group. If we get a mismatch in 3036 /* Remember first radio button in a group. If we get a mismatch in
3120 a radio group we must rebuild the whole group so that the connections 3037 a radio group we must rebuild the whole group so that the connections
3121 in GTK becomes correct. */ 3038 in GTK becomes correct. */
@@ -3203,7 +3120,6 @@ xg_update_submenu (GtkWidget *submenu,
3203 highlight_cb, 3120 highlight_cb,
3204 0, 3121 0,
3205 0, 3122 0,
3206 1,
3207 submenu, 3123 submenu,
3208 cl_data, 3124 cl_data,
3209 0); 3125 0);
@@ -4188,187 +4104,6 @@ xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage)
4188} 4104}
4189 4105
4190 4106
4191/* This callback is called when a tool item should create a proxy item,
4192 such as for the overflow menu. Also called when the tool bar is detached.
4193 If we don't create a proxy menu item, the detached tool bar will be
4194 blank. */
4195
4196static gboolean
4197xg_tool_bar_menu_proxy (GtkToolItem *toolitem, gpointer user_data)
4198{
4199 GtkButton *wbutton = GTK_BUTTON (XG_BIN_CHILD (XG_BIN_CHILD (toolitem)));
4200 GtkWidget *vb = XG_BIN_CHILD (wbutton);
4201 GtkWidget *c1;
4202 GtkLabel *wlbl = GTK_LABEL (xg_get_tool_bar_widgets (vb, &c1));
4203 GtkImage *wimage = GTK_IMAGE (c1);
4204 GtkWidget *wmenuitem = gtk_image_menu_item_new_with_label
4205 (wlbl ? gtk_label_get_text (wlbl) : "");
4206 GtkWidget *wmenuimage;
4207
4208
4209 if (gtk_button_get_use_stock (wbutton))
4210 wmenuimage = gtk_image_new_from_stock (gtk_button_get_label (wbutton),
4211 GTK_ICON_SIZE_MENU);
4212 else
4213 {
4214 GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (wbutton));
4215 GtkImageType store_type = gtk_image_get_storage_type (wimage);
4216
4217 g_object_set (G_OBJECT (settings), "gtk-menu-images", TRUE, NULL);
4218
4219 if (store_type == GTK_IMAGE_STOCK)
4220 {
4221 gchar *stock_id;
4222 gtk_image_get_stock (wimage, &stock_id, NULL);
4223 wmenuimage = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
4224 }
4225 else if (store_type == GTK_IMAGE_ICON_SET)
4226 {
4227 GtkIconSet *icon_set;
4228 gtk_image_get_icon_set (wimage, &icon_set, NULL);
4229 wmenuimage = gtk_image_new_from_icon_set (icon_set,
4230 GTK_ICON_SIZE_MENU);
4231 }
4232 else if (store_type == GTK_IMAGE_PIXBUF)
4233 {
4234 gint width, height;
4235
4236 if (settings &&
4237 gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
4238 &width, &height))
4239 {
4240 GdkPixbuf *src_pixbuf, *dest_pixbuf;
4241
4242 src_pixbuf = gtk_image_get_pixbuf (wimage);
4243 dest_pixbuf = gdk_pixbuf_scale_simple (src_pixbuf, width, height,
4244 GDK_INTERP_BILINEAR);
4245
4246 wmenuimage = gtk_image_new_from_pixbuf (dest_pixbuf);
4247 }
4248 else
4249 {
4250 fprintf (stderr, "internal error: GTK_IMAGE_PIXBUF failed\n");
4251 emacs_abort ();
4252 }
4253 }
4254 else if (store_type == GTK_IMAGE_ICON_NAME)
4255 {
4256 const gchar *icon_name;
4257 GtkIconSize icon_size;
4258
4259 gtk_image_get_icon_name (wimage, &icon_name, &icon_size);
4260 wmenuimage = gtk_image_new_from_icon_name (icon_name,
4261 GTK_ICON_SIZE_MENU);
4262 }
4263 else
4264 {
4265 fprintf (stderr, "internal error: store_type is %d\n", store_type);
4266 emacs_abort ();
4267 }
4268 }
4269 if (wmenuimage)
4270 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (wmenuitem), wmenuimage);
4271
4272 g_signal_connect (G_OBJECT (wmenuitem),
4273 "activate",
4274 G_CALLBACK (xg_tool_bar_proxy_callback),
4275 user_data);
4276
4277
4278 g_object_set_data (G_OBJECT (wmenuitem), XG_TOOL_BAR_PROXY_BUTTON,
4279 (gpointer) wbutton);
4280 gtk_tool_item_set_proxy_menu_item (toolitem, "Emacs toolbar item", wmenuitem);
4281 gtk_widget_set_sensitive (wmenuitem,
4282 gtk_widget_get_sensitive (GTK_WIDGET (wbutton)));
4283
4284 /* Use enter/leave notify to show help. We use the events
4285 rather than the GtkButton specific signals "enter" and
4286 "leave", so we can have only one callback. The event
4287 will tell us what kind of event it is. */
4288 g_signal_connect (G_OBJECT (wmenuitem),
4289 "enter-notify-event",
4290 G_CALLBACK (xg_tool_bar_proxy_help_callback),
4291 user_data);
4292 g_signal_connect (G_OBJECT (wmenuitem),
4293 "leave-notify-event",
4294 G_CALLBACK (xg_tool_bar_proxy_help_callback),
4295 user_data);
4296
4297 return TRUE;
4298}
4299
4300/* This callback is called when a tool bar is detached. We must set
4301 the height of the tool bar to zero when this happens so frame sizes
4302 are correctly calculated.
4303 WBOX is the handle box widget that enables detach/attach of the tool bar.
4304 W is the tool bar widget.
4305 CLIENT_DATA is a pointer to the frame the tool bar belongs to. */
4306
4307static void
4308xg_tool_bar_detach_callback (GtkHandleBox *wbox,
4309 GtkWidget *w,
4310 gpointer client_data)
4311{
4312 struct frame *f = client_data;
4313
4314 g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar,
4315 NULL);
4316
4317 if (f)
4318 {
4319 GtkRequisition req, req2;
4320
4321 gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req);
4322 gtk_widget_get_preferred_size (w, NULL, &req2);
4323 req.width -= req2.width;
4324 req.height -= req2.height;
4325 if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0)
4326 FRAME_TOOLBAR_TOP_HEIGHT (f) = req.height;
4327 else if (FRAME_TOOLBAR_BOTTOM_HEIGHT (f) != 0)
4328 FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = req.height;
4329 else if (FRAME_TOOLBAR_RIGHT_WIDTH (f) != 0)
4330 FRAME_TOOLBAR_RIGHT_WIDTH (f) = req.width;
4331 else if (FRAME_TOOLBAR_LEFT_WIDTH (f) != 0)
4332 FRAME_TOOLBAR_LEFT_WIDTH (f) = req.width;
4333 xg_height_or_width_changed (f);
4334 }
4335}
4336
4337/* This callback is called when a tool bar is reattached. We must set
4338 the height of the tool bar when this happens so frame sizes
4339 are correctly calculated.
4340 WBOX is the handle box widget that enables detach/attach of the tool bar.
4341 W is the tool bar widget.
4342 CLIENT_DATA is a pointer to the frame the tool bar belongs to. */
4343
4344static void
4345xg_tool_bar_attach_callback (GtkHandleBox *wbox,
4346 GtkWidget *w,
4347 gpointer client_data)
4348{
4349 struct frame *f = client_data;
4350 g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL);
4351
4352 if (f)
4353 {
4354 GtkRequisition req, req2;
4355
4356 gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req);
4357 gtk_widget_get_preferred_size (w, NULL, &req2);
4358 req.width += req2.width;
4359 req.height += req2.height;
4360 if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0)
4361 FRAME_TOOLBAR_TOP_HEIGHT (f) = req.height;
4362 else if (FRAME_TOOLBAR_BOTTOM_HEIGHT (f) != 0)
4363 FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = req.height;
4364 else if (FRAME_TOOLBAR_RIGHT_WIDTH (f) != 0)
4365 FRAME_TOOLBAR_RIGHT_WIDTH (f) = req.width;
4366 else if (FRAME_TOOLBAR_LEFT_WIDTH (f) != 0)
4367 FRAME_TOOLBAR_LEFT_WIDTH (f) = req.width;
4368 xg_height_or_width_changed (f);
4369 }
4370}
4371
4372/* This callback is called when the mouse enters or leaves a tool bar item. 4107/* This callback is called when the mouse enters or leaves a tool bar item.
4373 It is used for displaying and hiding the help text. 4108 It is used for displaying and hiding the help text.
4374 W is the tool bar item, a button. 4109 W is the tool bar item, a button.
@@ -4448,11 +4183,7 @@ xg_tool_bar_item_expose_callback (GtkWidget *w,
4448 gtk_toolbar_set_orientation (GTK_TOOLBAR (w), o) 4183 gtk_toolbar_set_orientation (GTK_TOOLBAR (w), o)
4449#endif 4184#endif
4450 4185
4451#ifdef HAVE_GTK_HANDLE_BOX_NEW
4452#define TOOLBAR_TOP_WIDGET(x) ((x)->handlebox_widget)
4453#else
4454#define TOOLBAR_TOP_WIDGET(x) ((x)->toolbar_widget) 4186#define TOOLBAR_TOP_WIDGET(x) ((x)->toolbar_widget)
4455#endif
4456 4187
4457/* Attach a tool bar to frame F. */ 4188/* Attach a tool bar to frame F. */
4458 4189
@@ -4461,31 +4192,15 @@ xg_pack_tool_bar (struct frame *f, Lisp_Object pos)
4461{ 4192{
4462 struct x_output *x = f->output_data.x; 4193 struct x_output *x = f->output_data.x;
4463 bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright); 4194 bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright);
4464 GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); 4195 GtkWidget *top_widget = x->toolbar_widget;
4465 4196
4466 toolbar_set_orientation (x->toolbar_widget, 4197 toolbar_set_orientation (x->toolbar_widget,
4467 into_hbox 4198 into_hbox
4468 ? GTK_ORIENTATION_VERTICAL 4199 ? GTK_ORIENTATION_VERTICAL
4469 : GTK_ORIENTATION_HORIZONTAL); 4200 : GTK_ORIENTATION_HORIZONTAL);
4470#ifdef HAVE_GTK_HANDLE_BOX_NEW
4471 if (!x->handlebox_widget)
4472 {
4473 top_widget = x->handlebox_widget = gtk_handle_box_new ();
4474 g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached",
4475 G_CALLBACK (xg_tool_bar_detach_callback), f);
4476 g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached",
4477 G_CALLBACK (xg_tool_bar_attach_callback), f);
4478 gtk_container_add (GTK_CONTAINER (x->handlebox_widget),
4479 x->toolbar_widget);
4480 }
4481#endif
4482 4201
4483 if (into_hbox) 4202 if (into_hbox)
4484 { 4203 {
4485#ifdef HAVE_GTK_HANDLE_BOX_NEW
4486 gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (x->handlebox_widget),
4487 GTK_POS_TOP);
4488#endif
4489 gtk_box_pack_start (GTK_BOX (x->hbox_widget), top_widget, 4204 gtk_box_pack_start (GTK_BOX (x->hbox_widget), top_widget,
4490 FALSE, FALSE, 0); 4205 FALSE, FALSE, 0);
4491 4206
@@ -4498,10 +4213,6 @@ xg_pack_tool_bar (struct frame *f, Lisp_Object pos)
4498 else 4213 else
4499 { 4214 {
4500 bool vbox_pos = x->menubar_widget != 0; 4215 bool vbox_pos = x->menubar_widget != 0;
4501#ifdef HAVE_GTK_HANDLE_BOX_NEW
4502 gtk_handle_box_set_handle_position (GTK_HANDLE_BOX (x->handlebox_widget),
4503 GTK_POS_LEFT);
4504#endif
4505 gtk_box_pack_start (GTK_BOX (x->vbox_widget), top_widget, 4216 gtk_box_pack_start (GTK_BOX (x->vbox_widget), top_widget,
4506 FALSE, FALSE, 0); 4217 FALSE, FALSE, 0);
4507 4218
@@ -4654,10 +4365,6 @@ xg_make_tool_item (struct frame *f,
4654 intptr_t ii = i; 4365 intptr_t ii = i;
4655 gpointer gi = (gpointer) ii; 4366 gpointer gi = (gpointer) ii;
4656 4367
4657 g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
4658 G_CALLBACK (xg_tool_bar_menu_proxy),
4659 gi);
4660
4661 g_signal_connect (G_OBJECT (wb), "clicked", 4368 g_signal_connect (G_OBJECT (wb), "clicked",
4662 G_CALLBACK (xg_tool_bar_callback), 4369 G_CALLBACK (xg_tool_bar_callback),
4663 gi); 4370 gi);
@@ -4771,7 +4478,7 @@ xg_update_tool_bar_sizes (struct frame *f)
4771 struct x_output *x = f->output_data.x; 4478 struct x_output *x = f->output_data.x;
4772 GtkRequisition req; 4479 GtkRequisition req;
4773 int nl = 0, nr = 0, nt = 0, nb = 0; 4480 int nl = 0, nr = 0, nt = 0, nb = 0;
4774 GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); 4481 GtkWidget *top_widget = x->toolbar_widget;
4775 4482
4776 gtk_widget_get_preferred_size (GTK_WIDGET (top_widget), NULL, &req); 4483 gtk_widget_get_preferred_size (GTK_WIDGET (top_widget), NULL, &req);
4777 if (x->toolbar_in_hbox) 4484 if (x->toolbar_in_hbox)
@@ -4810,6 +4517,42 @@ xg_update_tool_bar_sizes (struct frame *f)
4810 return 0; 4517 return 0;
4811} 4518}
4812 4519
4520static char *
4521find_icon_from_name (char *name,
4522 GtkIconTheme *icon_theme,
4523 char **icon_name)
4524{
4525#if ! GTK_CHECK_VERSION (3, 10, 0)
4526 GtkStockItem stock_item;
4527#endif
4528
4529 if (name[0] == 'n' && name[1] == ':')
4530 {
4531 *icon_name = name + 2;
4532 name = NULL;
4533
4534 if (! gtk_icon_theme_has_icon (icon_theme, *icon_name))
4535 *icon_name = NULL;
4536 }
4537
4538#if ! GTK_CHECK_VERSION (3, 10, 0)
4539 else if (gtk_stock_lookup (name, &stock_item))
4540 *icon_name = NULL;
4541#endif
4542 else if (gtk_icon_theme_has_icon (icon_theme, name))
4543 {
4544 *icon_name = name;
4545 name = NULL;
4546 }
4547 else
4548 {
4549 name = NULL;
4550 *icon_name = NULL;
4551 }
4552
4553 return name;
4554}
4555
4813 4556
4814/* Update the tool bar for frame F. Add new buttons and remove old. */ 4557/* Update the tool bar for frame F. Add new buttons and remove old. */
4815 4558
@@ -4825,6 +4568,9 @@ update_frame_tool_bar (struct frame *f)
4825 Lisp_Object style; 4568 Lisp_Object style;
4826 bool text_image, horiz; 4569 bool text_image, horiz;
4827 struct xg_frame_tb_info *tbinfo; 4570 struct xg_frame_tb_info *tbinfo;
4571 GdkScreen *screen;
4572 GtkIconTheme *icon_theme;
4573
4828 4574
4829 if (! FRAME_GTK_WIDGET (f)) 4575 if (! FRAME_GTK_WIDGET (f))
4830 return; 4576 return;
@@ -4859,6 +4605,8 @@ update_frame_tool_bar (struct frame *f)
4859 dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar)); 4605 dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar));
4860 4606
4861 style = Ftool_bar_get_system_style (); 4607 style = Ftool_bar_get_system_style ();
4608 screen = gtk_widget_get_screen (GTK_WIDGET (wtoolbar));
4609 icon_theme = gtk_icon_theme_get_for_screen (screen);
4862 4610
4863 /* Are we up to date? */ 4611 /* Are we up to date? */
4864 tbinfo = g_object_get_data (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), 4612 tbinfo = g_object_get_data (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)),
@@ -4895,7 +4643,6 @@ update_frame_tool_bar (struct frame *f)
4895 struct image *img = NULL; 4643 struct image *img = NULL;
4896 Lisp_Object image; 4644 Lisp_Object image;
4897 Lisp_Object stock = Qnil; 4645 Lisp_Object stock = Qnil;
4898 GtkStockItem stock_item;
4899 char *stock_name = NULL; 4646 char *stock_name = NULL;
4900 char *icon_name = NULL; 4647 char *icon_name = NULL;
4901 Lisp_Object rtl; 4648 Lisp_Object rtl;
@@ -4949,32 +4696,28 @@ update_frame_tool_bar (struct frame *f)
4949 if (!NILP (specified_file) && !NILP (Ffboundp (Qx_gtk_map_stock))) 4696 if (!NILP (specified_file) && !NILP (Ffboundp (Qx_gtk_map_stock)))
4950 stock = call1 (Qx_gtk_map_stock, specified_file); 4697 stock = call1 (Qx_gtk_map_stock, specified_file);
4951 4698
4952 if (STRINGP (stock)) 4699 if (CONSP (stock))
4953 { 4700 {
4954 stock_name = SSDATA (stock); 4701 Lisp_Object tem;
4955 if (stock_name[0] == 'n' && stock_name[1] == ':') 4702 for (tem = stock; CONSP (tem); tem = XCDR (tem))
4956 { 4703 if (! NILP (tem) && STRINGP (XCAR (tem)))
4957 GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (wtoolbar)); 4704 {
4958 GtkIconTheme *icon_theme = gtk_icon_theme_get_for_screen (screen); 4705 stock_name = find_icon_from_name (SSDATA (XCAR (tem)),
4959 4706 icon_theme,
4960 icon_name = stock_name + 2; 4707 &icon_name);
4961 stock_name = NULL; 4708 if (stock_name || icon_name) break;
4962 stock = Qnil; 4709 }
4963 4710 }
4964 if (! gtk_icon_theme_has_icon (icon_theme, icon_name)) 4711 else if (STRINGP (stock))
4965 icon_name = NULL; 4712 {
4966 else 4713 stock_name = find_icon_from_name (SSDATA (stock),
4967 icon_size = gtk_toolbar_get_icon_size (wtoolbar); 4714 icon_theme,
4968 } 4715 &icon_name);
4969 else if (gtk_stock_lookup (SSDATA (stock), &stock_item))
4970 icon_size = gtk_toolbar_get_icon_size (wtoolbar);
4971 else
4972 {
4973 stock = Qnil;
4974 stock_name = NULL;
4975 }
4976 } 4716 }
4977 4717
4718 if (stock_name || icon_name)
4719 icon_size = gtk_toolbar_get_icon_size (wtoolbar);
4720
4978 if (stock_name == NULL && icon_name == NULL) 4721 if (stock_name == NULL && icon_name == NULL)
4979 { 4722 {
4980 /* No stock image, or stock item not known. Try regular 4723 /* No stock image, or stock item not known. Try regular
@@ -5035,7 +4778,12 @@ update_frame_tool_bar (struct frame *f)
5035 w = NULL; 4778 w = NULL;
5036 else if (stock_name) 4779 else if (stock_name)
5037 { 4780 {
4781
4782#if GTK_CHECK_VERSION (3, 10, 0)
4783 w = gtk_image_new_from_icon_name (stock_name, icon_size);
4784#else
5038 w = gtk_image_new_from_stock (stock_name, icon_size); 4785 w = gtk_image_new_from_stock (stock_name, icon_size);
4786#endif
5039 g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_STOCK_NAME, 4787 g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_STOCK_NAME,
5040 (gpointer) xstrdup (stock_name), 4788 (gpointer) xstrdup (stock_name),
5041 (GDestroyNotify) xfree); 4789 (GDestroyNotify) xfree);
@@ -5077,7 +4825,7 @@ update_frame_tool_bar (struct frame *f)
5077 { 4825 {
5078 if (! x->toolbar_is_packed) 4826 if (! x->toolbar_is_packed)
5079 xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f)); 4827 xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f));
5080 gtk_widget_show_all (TOOLBAR_TOP_WIDGET (x)); 4828 gtk_widget_show_all (x->toolbar_widget);
5081 if (xg_update_tool_bar_sizes (f)) 4829 if (xg_update_tool_bar_sizes (f))
5082 xg_height_or_width_changed (f); 4830 xg_height_or_width_changed (f);
5083 } 4831 }
@@ -5096,11 +4844,9 @@ free_frame_tool_bar (struct frame *f)
5096 if (x->toolbar_widget) 4844 if (x->toolbar_widget)
5097 { 4845 {
5098 struct xg_frame_tb_info *tbinfo; 4846 struct xg_frame_tb_info *tbinfo;
5099 GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); 4847 GtkWidget *top_widget = x->toolbar_widget;
5100 4848
5101 block_input (); 4849 block_input ();
5102 /* We may have created the toolbar_widget in xg_create_tool_bar, but
5103 not the x->handlebox_widget which is created in xg_pack_tool_bar. */
5104 if (x->toolbar_is_packed) 4850 if (x->toolbar_is_packed)
5105 { 4851 {
5106 if (x->toolbar_in_hbox) 4852 if (x->toolbar_in_hbox)
@@ -5114,7 +4860,7 @@ free_frame_tool_bar (struct frame *f)
5114 gtk_widget_destroy (x->toolbar_widget); 4860 gtk_widget_destroy (x->toolbar_widget);
5115 4861
5116 x->toolbar_widget = 0; 4862 x->toolbar_widget = 0;
5117 TOOLBAR_TOP_WIDGET (x) = 0; 4863 x->toolbar_widget = 0;
5118 x->toolbar_is_packed = false; 4864 x->toolbar_is_packed = false;
5119 FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0; 4865 FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0;
5120 FRAME_TOOLBAR_LEFT_WIDTH (f) = FRAME_TOOLBAR_RIGHT_WIDTH (f) = 0; 4866 FRAME_TOOLBAR_LEFT_WIDTH (f) = FRAME_TOOLBAR_RIGHT_WIDTH (f) = 0;
@@ -5139,7 +4885,7 @@ void
5139xg_change_toolbar_position (struct frame *f, Lisp_Object pos) 4885xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
5140{ 4886{
5141 struct x_output *x = f->output_data.x; 4887 struct x_output *x = f->output_data.x;
5142 GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x); 4888 GtkWidget *top_widget = x->toolbar_widget;
5143 4889
5144 if (! x->toolbar_widget || ! top_widget) 4890 if (! x->toolbar_widget || ! top_widget)
5145 return; 4891 return;
@@ -5183,9 +4929,6 @@ xg_initialize (void)
5183 4929
5184 gdpy_def = NULL; 4930 gdpy_def = NULL;
5185 xg_ignore_gtk_scrollbar = 0; 4931 xg_ignore_gtk_scrollbar = 0;
5186#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
5187 xg_detached_menus = 0;
5188#endif
5189 xg_menu_cb_list.prev = xg_menu_cb_list.next = 4932 xg_menu_cb_list.prev = xg_menu_cb_list.next =
5190 xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0; 4933 xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0;
5191 4934
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 5c7d8b03379..594c7a7382b 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -108,8 +108,6 @@ extern void xg_update_frame_menubar (struct frame *f);
108 108
109extern bool xg_event_is_for_menubar (struct frame *, const XEvent *); 109extern bool xg_event_is_for_menubar (struct frame *, const XEvent *);
110 110
111extern bool xg_have_tear_offs (struct frame *f);
112
113extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid); 111extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid);
114 112
115extern void xg_create_scroll_bar (struct frame *f, 113extern void xg_create_scroll_bar (struct frame *f,
diff --git a/src/xmenu.c b/src/xmenu.c
index e3f1a17fbce..eb783fe5070 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -733,12 +733,6 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
733 f->output_data.x->saved_menu_event->type = 0; 733 f->output_data.x->saved_menu_event->type = 0;
734 } 734 }
735 735
736#ifdef USE_GTK
737 /* If we have detached menus, we must update deep so detached menus
738 also gets updated. */
739 deep_p = deep_p || xg_have_tear_offs (f);
740#endif
741
742 if (deep_p) 736 if (deep_p)
743 { 737 {
744 /* Make a widget-value tree representing the entire menu trees. */ 738 /* Make a widget-value tree representing the entire menu trees. */
diff --git a/src/xterm.h b/src/xterm.h
index ed611f1d19f..0842195f330 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -499,10 +499,6 @@ struct x_output
499 GtkWidget *menubar_widget; 499 GtkWidget *menubar_widget;
500 /* The tool bar in this frame */ 500 /* The tool bar in this frame */
501 GtkWidget *toolbar_widget; 501 GtkWidget *toolbar_widget;
502#ifdef HAVE_GTK_HANDLE_BOX_NEW
503/* The handle box that makes the tool bar detachable. */
504 GtkWidget *handlebox_widget;
505#endif
506 /* True if tool bar is packed into the hbox widget (i.e. vertical). */ 502 /* True if tool bar is packed into the hbox widget (i.e. vertical). */
507 bool_bf toolbar_in_hbox : 1; 503 bool_bf toolbar_in_hbox : 1;
508 bool_bf toolbar_is_packed : 1; 504 bool_bf toolbar_is_packed : 1;