+2003-11-02 Jan Dj\e,Ad\e(Brv <jan.h.d@swipnet.se>
+
+ * gtkutil.h: Declare xg_have_tear_offs, remove xg_keep_popup
+ and xg_did_tearoff.
+
+ * gtkutil.c: Remove variable xg_did_tearoff.
+ (xg_have_tear_offs): New function.
+ (tearoff_remove): Just decrease xg_detached_menus.
+ (tearoff_activate): Increase xg_detached_menus and call
+ tearoff_remove when tearoff is removed.
+ (xg_keep_popup): Removed function.
+ (create_menus): Give add_tearoff_p as argument to recursive
+ call to create_menus.
+ (xg_create_widget): Use variables instead of multiple
+ strcmp. Tell create_menus to create tear off only for
+ menu bar menus.
+ (xg_update_menubar): Change title for a detached menu also.
+ (xg_modify_menubar_widgets): Always call xg_update_menubar, regardless
+ of deep_p.
+ (xg_initialize): Initialize xg_detached_menus, remove
+ initialization of xg_did_tearoff.
+
+ * xmenu.c (set_frame_menubar): For GTK, set deep_p if
+ xg_have_tear_offs returns non-zero.
+ (create_and_show_popup_menu): Remove setting of xg_did_tearoff and
+ call to xg_keep_popup.
+
2003-11-01 Andrew Choi <akochoi@shaw.ca>
* macterm.c (XTread_socket): Handle menubar selection and grow
return 0;
}
-GtkWidget *xg_did_tearoff;
+static int xg_detached_menus;
+
+/* Returns non-zero if there are detached menus. */
+int
+xg_have_tear_offs ()
+{
+ return xg_detached_menus > 0;
+}
/* Callback invoked when a detached menu window is removed. Here we
- delete the popup menu.
+ decrease the xg_detached_menus count.
WIDGET is the top level window that is removed (the parent of the menu).
- EVENT is the event that triggers the window removal.
- CLIENT_DATA points to the menu that is detached.
-
- Returns TRUE to tell GTK to stop processing this event. */
-static gboolean
-tearoff_remove (widget, event, client_data)
+ CLIENT_DATA is not used. */
+static void
+tearoff_remove (widget, client_data)
GtkWidget *widget;
- GdkEvent *event;
gpointer client_data;
{
- gtk_widget_destroy (GTK_WIDGET (client_data));
- return TRUE;
+ if (xg_detached_menus > 0) --xg_detached_menus;
}
-/* Callback invoked when a menu is detached. It sets the xg_did_tearoff
- variable.
+/* 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
gpointer client_data;
{
GtkWidget *menu = gtk_widget_get_parent (widget);
- if (! gtk_menu_get_tearoff_state (GTK_MENU (menu)))
- return;
-
- xg_did_tearoff = menu;
+ 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);
+ }
}
-/* If a detach of a popup menu is done, this function should be called
- to keep the menu around until the detached window is removed.
- MENU is the top level menu for the popup,
- SUBMENU is the menu that got detached (that is MENU or a
- submenu of MENU), see the xg_did_tearoff variable. */
-void
-xg_keep_popup (menu, submenu)
- GtkWidget *menu;
- GtkWidget *submenu;
-{
- GtkWidget *p;
-
- /* Find the top widget for the detached menu. */
- p = gtk_widget_get_toplevel (submenu);
-
- /* Delay destroying the menu until the detached menu is removed. */
- g_signal_connect (G_OBJECT (p), "unmap_event",
- G_CALLBACK (tearoff_remove), menu);
-}
/* Create a menu item widget, and connect the callbacks.
ITEM decribes the menu item.
highlight_cb,
0,
0,
- 1,
+ add_tearoff_p,
0,
cl_data,
0);
GCallback highlight_cb;
{
GtkWidget *w = 0;
+ int menu_bar_p = strcmp (type, "menubar") == 0;
+ int pop_up_p = strcmp (type, "popup") == 0;
+
if (strcmp (type, "dialog") == 0)
{
w = create_dialog (val, select_cb, deactivate_cb);
if (w)
gtk_widget_set_name (w, "emacs-dialog");
}
- else if (strcmp (type, "menubar") == 0 || strcmp (type, "popup") == 0)
+ else if (menu_bar_p || pop_up_p)
{
w = create_menus (val->contents,
f,
select_cb,
deactivate_cb,
highlight_cb,
- strcmp (type, "popup") == 0,
- strcmp (type, "menubar") == 0,
- 1,
+ pop_up_p,
+ menu_bar_p,
+ menu_bar_p,
0,
0,
name);
/* Set the cursor to an arrow for popup menus when they are mapped.
This is done by default for menu bar menus. */
- if (strcmp (type, "popup") == 0)
+ if (pop_up_p)
{
/* Must realize so the GdkWindow inside the widget is created. */
gtk_widget_realize (w);
is up to date when leaving the minibuffer. */
GtkLabel *wlabel = GTK_LABEL (gtk_bin_get_child (GTK_BIN (witem)));
char *utf8_label = get_utf8_string (val->name);
+ GtkWidget *submenu = gtk_menu_item_get_submenu (witem);
gtk_label_set_text (wlabel, utf8_label);
+ /* 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);
+
iter = g_list_next (iter);
val = val->next;
++pos;
cl_data = (xg_menu_cb_data*) g_object_get_data (G_OBJECT (menubar),
XG_FRAME_DATA);
- if (! deep_p)
- {
- widget_value *cur = val->contents;
- xg_update_menubar (menubar, f, &list, list, 0, cur,
- select_cb, highlight_cb, cl_data);
- }
- else
+ xg_update_menubar (menubar, f, &list, list, 0, val->contents,
+ select_cb, highlight_cb, cl_data);
+
+ if (deep_p);
{
widget_value *cur;
/* Update all sub menus.
- We must keep the submenu names (GTK menu item widgets) since the
+ We must keep the submenus (GTK menu item widgets) since the
X Window in the XEvent that activates the menu are those widgets. */
/* Update cl_data, menu_item things in F may have changed. */
newly created sub menu under witem. */
if (newsub != sub)
gtk_menu_item_set_submenu (witem, newsub);
-
}
}
{
xg_ignore_gtk_scrollbar = 0;
xg_left_ptr_cursor = 0;
- xg_did_tearoff = 0;
-
+ xg_detached_menus = 0;
xg_menu_cb_list.prev = xg_menu_cb_list.next =
xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0;
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 ();
+#endif
+
if (deep_p)
{
/* Make a widget-value tree representing the entire menu trees. */
xg_crazy_callback_abort = 1;
if (menubar_widget)
{
- /* The third arg is DEEP_P, which says to consider the entire
+ /* The fourth arg is DEEP_P, which says to consider the entire
menu trees we supply, rather than just the menu bar item names. */
xg_modify_menubar_widgets (menubar_widget,
f,
gtk_widget_show_all (menu);
gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0);
- xg_did_tearoff = 0;
/* Set this to one. popup_widget_loop increases it by one, so it becomes
two. show_help_echo uses this to detect popup menus. */
popup_activated_flag = 1;
/* Process events that apply to the menu. */
popup_widget_loop ();
- if (xg_did_tearoff)
- xg_keep_popup (menu, xg_did_tearoff);
- else
- gtk_widget_destroy (menu);
+ gtk_widget_destroy (menu);
/* Must reset this manually because the button release event is not passed
to Emacs event loop. */