summaryrefslogtreecommitdiff
path: root/src/gtkutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkutil.c')
-rw-r--r--src/gtkutil.c105
1 files changed, 71 insertions, 34 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 9f2b652525f..95ac04b8ff0 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1,6 +1,6 @@
/* Functions for creating and updating GTK widgets.
-Copyright (C) 2003-2012 Free Software Foundation, Inc.
+Copyright (C) 2003-2013 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -2416,6 +2416,8 @@ make_menu_item (const char *utf8_label,
return w;
}
+#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
+
static int xg_detached_menus;
/* Return true if there are detached menus. */
@@ -2454,7 +2456,13 @@ tearoff_activate (GtkWidget *widget, gpointer client_data)
G_CALLBACK (tearoff_remove), 0);
}
}
-
+#else /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
+bool
+xg_have_tear_offs (void)
+{
+ return false;
+}
+#endif /* ! HAVE_GTK_TEAROFF_MENU_ITEM_NEW */
/* Create a menu item widget, and connect the callbacks.
ITEM describes the menu item.
@@ -2526,7 +2534,8 @@ xg_create_one_menuitem (widget_value *item,
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.
+ 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)
@@ -2599,6 +2608,7 @@ create_menus (widget_value *data,
"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 ();
@@ -2607,6 +2617,7 @@ create_menus (widget_value *data,
g_signal_connect (G_OBJECT (tearoff), "activate",
G_CALLBACK (tearoff_activate), 0);
}
+#endif
for (item = data; item; item = item->next)
{
@@ -2897,11 +2908,13 @@ xg_update_menubar (GtkWidget *menubar,
gtk_label_set_text (wlabel, utf8_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);
@@ -3129,7 +3142,8 @@ xg_update_submenu (GtkWidget *submenu,
{
GtkWidget *w = GTK_WIDGET (iter->data);
- /* Skip tearoff items, they have no counterpart in val. */
+#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;
@@ -3137,6 +3151,7 @@ xg_update_submenu (GtkWidget *submenu,
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
@@ -4138,7 +4153,7 @@ xg_tool_bar_detach_callback (GtkHandleBox *wbox,
if (f)
{
GtkRequisition req, req2;
- FRAME_X_OUTPUT (f)->toolbar_detached = 1;
+
gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req);
gtk_widget_get_preferred_size (w, NULL, &req2);
req.width -= req2.width;
@@ -4173,7 +4188,7 @@ xg_tool_bar_attach_callback (GtkHandleBox *wbox,
if (f)
{
GtkRequisition req, req2;
- FRAME_X_OUTPUT (f)->toolbar_detached = 0;
+
gtk_widget_get_preferred_size (GTK_WIDGET (wbox), NULL, &req);
gtk_widget_get_preferred_size (w, NULL, &req2);
req.width += req2.width;
@@ -4269,6 +4284,12 @@ xg_tool_bar_item_expose_callback (GtkWidget *w,
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
@@ -4276,14 +4297,16 @@ xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos)
{
struct x_output *x = f->output_data.x;
bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright);
+ GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x);
toolbar_set_orientation (x->toolbar_widget,
into_hbox
? GTK_ORIENTATION_VERTICAL
: GTK_ORIENTATION_HORIZONTAL);
+#ifdef HAVE_GTK_HANDLE_BOX_NEW
if (!x->handlebox_widget)
{
- x->handlebox_widget = gtk_handle_box_new ();
+ 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",
@@ -4291,34 +4314,40 @@ xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos)
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);
- gtk_box_pack_start (GTK_BOX (x->hbox_widget), x->handlebox_widget,
+#endif
+ gtk_box_pack_start (GTK_BOX (x->hbox_widget), top_widget,
FALSE, FALSE, 0);
if (EQ (pos, Qleft))
gtk_box_reorder_child (GTK_BOX (x->hbox_widget),
- x->handlebox_widget,
+ top_widget,
0);
- x->toolbar_in_hbox = 1;
+ x->toolbar_in_hbox = true;
}
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);
- gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->handlebox_widget,
+#endif
+ gtk_box_pack_start (GTK_BOX (x->vbox_widget), top_widget,
FALSE, FALSE, 0);
if (EQ (pos, Qtop))
gtk_box_reorder_child (GTK_BOX (x->vbox_widget),
- x->handlebox_widget,
+ top_widget,
vbox_pos);
- x->toolbar_in_hbox = 0;
+ x->toolbar_in_hbox = false;
}
+ x->toolbar_is_packed = true;
}
/* Create a tool bar for frame F. */
@@ -4347,7 +4376,6 @@ xg_create_tool_bar (FRAME_PTR f)
}
x->toolbar_widget = gtk_toolbar_new ();
- x->toolbar_detached = 0;
gtk_widget_set_name (x->toolbar_widget, "emacs-toolbar");
@@ -4562,13 +4590,14 @@ xg_update_tool_bar_sizes (FRAME_PTR f)
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);
- gtk_widget_get_preferred_size (GTK_WIDGET (x->handlebox_widget), NULL, &req);
+ gtk_widget_get_preferred_size (GTK_WIDGET (top_widget), NULL, &req);
if (x->toolbar_in_hbox)
{
int pos;
gtk_container_child_get (GTK_CONTAINER (x->hbox_widget),
- x->handlebox_widget,
+ top_widget,
"position", &pos, NULL);
if (pos == 0) nl = req.width;
else nr = req.width;
@@ -4577,7 +4606,7 @@ xg_update_tool_bar_sizes (FRAME_PTR f)
{
int pos;
gtk_container_child_get (GTK_CONTAINER (x->vbox_widget),
- x->handlebox_widget,
+ top_widget,
"position", &pos, NULL);
if (pos == 0 || (pos == 1 && x->menubar_widget)) nt = req.height;
else nb = req.height;
@@ -4612,7 +4641,6 @@ update_frame_tool_bar (FRAME_PTR f)
GtkToolbar *wtoolbar;
GtkToolItem *ti;
GtkTextDirection dir;
- bool pack_tool_bar = x->handlebox_widget == NULL;
Lisp_Object style;
bool text_image, horiz;
struct xg_frame_tb_info *tbinfo;
@@ -4866,9 +4894,9 @@ update_frame_tool_bar (FRAME_PTR f)
if (f->n_tool_bar_items != 0)
{
- if (pack_tool_bar)
+ if (! x->toolbar_is_packed)
xg_pack_tool_bar (f, f->tool_bar_position);
- gtk_widget_show_all (GTK_WIDGET (x->handlebox_widget));
+ gtk_widget_show_all (TOOLBAR_TOP_WIDGET (x));
if (xg_update_tool_bar_sizes (f))
xg_height_or_width_changed (f);
}
@@ -4887,24 +4915,26 @@ free_frame_tool_bar (FRAME_PTR f)
if (x->toolbar_widget)
{
struct xg_frame_tb_info *tbinfo;
- bool is_packed = x->handlebox_widget != 0;
+ GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x);
+
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 (is_packed)
+ if (x->toolbar_is_packed)
{
if (x->toolbar_in_hbox)
gtk_container_remove (GTK_CONTAINER (x->hbox_widget),
- x->handlebox_widget);
+ top_widget);
else
gtk_container_remove (GTK_CONTAINER (x->vbox_widget),
- x->handlebox_widget);
+ top_widget);
}
else
gtk_widget_destroy (x->toolbar_widget);
x->toolbar_widget = 0;
- x->handlebox_widget = 0;
+ TOOLBAR_TOP_WIDGET (x) = 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;
@@ -4928,20 +4958,25 @@ void
xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos)
{
struct x_output *x = f->output_data.x;
+ GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x);
- if (! x->toolbar_widget || ! x->handlebox_widget)
+ if (! x->toolbar_widget || ! top_widget)
return;
block_input ();
- g_object_ref (x->handlebox_widget);
- if (x->toolbar_in_hbox)
- gtk_container_remove (GTK_CONTAINER (x->hbox_widget),
- x->handlebox_widget);
- else
- gtk_container_remove (GTK_CONTAINER (x->vbox_widget),
- x->handlebox_widget);
+ g_object_ref (top_widget);
+ if (x->toolbar_is_packed)
+ {
+ if (x->toolbar_in_hbox)
+ gtk_container_remove (GTK_CONTAINER (x->hbox_widget),
+ top_widget);
+ else
+ gtk_container_remove (GTK_CONTAINER (x->vbox_widget),
+ top_widget);
+ }
+
xg_pack_tool_bar (f, pos);
- g_object_unref (x->handlebox_widget);
+ g_object_unref (top_widget);
if (xg_update_tool_bar_sizes (f))
xg_height_or_width_changed (f);
@@ -4967,7 +5002,9 @@ xg_initialize (void)
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;