summaryrefslogtreecommitdiff
path: root/src/xmenu.c
diff options
context:
space:
mode:
authorJan Djärv <jan.h.d@swipnet.se>2004-11-13 20:18:21 +0000
committerJan Djärv <jan.h.d@swipnet.se>2004-11-13 20:18:21 +0000
commitaf89e8710242b29ea53a150143df30207382891f (patch)
tree16436b4ad25d09f4801636e921654652b6800b23 /src/xmenu.c
parent3b8370e18bc4b13ec80f9a8c196381aa0a8383ff (diff)
downloademacs-af89e8710242b29ea53a150143df30207382891f.tar.gz
* xmenu.c (unuse_menu_items, pop_down_menu): Arg is of type
Lisp_Object. (popup_get_selection): Move unwind protect ... (create_and_show_popup_menu, create_and_show_dialog): ... to here. Move destroy of widget to pop_down_menu. (popup_widget_loop): Move unwind protect ... (create_and_show_popup_menu, create_and_show_dialog): ... to here. Move destroy of widget to pop_down_menu. (pop_down_menu): BLOCK_INPUT and destroy widget/window. (xmenu_show): record unwind pop_down_menu. Move XMenuDestroy, x_mouse_leave and grabbed = 0 to pop_down_menu.
Diffstat (limited to 'src/xmenu.c')
-rw-r--r--src/xmenu.c185
1 files changed, 105 insertions, 80 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index 3b813927281..c8c40a47256 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -288,7 +288,7 @@ finish_menu_items ()
static Lisp_Object
unuse_menu_items (dummy)
- int dummy;
+ Lisp_Object dummy;
{
return menu_items_inuse = Qnil;
}
@@ -1173,14 +1173,6 @@ x_menu_wait_for_event (void *data)
#ifdef USE_X_TOOLKIT
-static Lisp_Object
-pop_down_menu (dummy)
- int dummy;
-{
- popup_activated_flag = 0;
- return Qnil;
-}
-
/* Loop in Xt until the menu pulldown or dialog popup has been
popped down (deactivated). This is used for x-popup-menu
and x-popup-dialog; it is not used for the menu bar.
@@ -1200,9 +1192,6 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
{
XEvent event;
- int specpdl_count = SPECPDL_INDEX ();
- record_unwind_protect (pop_down_menu, Qnil);
-
while (popup_activated_flag)
{
if (initial_event)
@@ -1252,8 +1241,6 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
x_dispatch_event (&event, event.xany.display);
}
-
- unbind_to (specpdl_count, Qnil);
}
#endif /* USE_X_TOOLKIT */
@@ -1261,30 +1248,12 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
#ifdef USE_GTK
/* Loop util popup_activated_flag is set to zero in a callback.
Used for popup menus and dialogs. */
-static GtkWidget *current_menu;
-
-static Lisp_Object
-pop_down_menu (dummy)
- int dummy;
-{
- if (current_menu)
- {
- gtk_widget_unmap (current_menu);
- current_menu = 0;
- popup_activated_flag = 0;
- }
- return Qnil;
-}
static void
popup_widget_loop (do_timers, widget)
int do_timers;
GtkWidget *widget;
{
- int specpdl_count = SPECPDL_INDEX ();
- current_menu = widget;
- record_unwind_protect (pop_down_menu, Qnil);
-
++popup_activated_flag;
/* Process events in the Gtk event loop until done. */
@@ -1293,8 +1262,6 @@ popup_widget_loop (do_timers, widget)
if (do_timers) x_menu_wait_for_event (0);
gtk_main_iteration ();
}
-
- unbind_to (specpdl_count, Qnil);
}
#endif
@@ -2443,6 +2410,23 @@ popup_selection_callback (widget, client_data)
if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
}
+static GtkWidget *current_menu;
+
+static Lisp_Object
+pop_down_menu (dummy)
+ Lisp_Object dummy;
+{
+ popup_activated_flag = 0;
+ if (current_menu)
+ {
+ BLOCK_INPUT;
+ gtk_widget_destroy (current_menu);
+ UNBLOCK_INPUT;
+ current_menu = 0;
+ }
+ return Qnil;
+}
+
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
menu pops down.
menu_item_selection will be set to the selection. */
@@ -2458,6 +2442,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
GtkWidget *menu;
GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */
struct next_popup_x_y popup_x_y;
+ int specpdl_count = SPECPDL_INDEX ();
xg_crazy_callback_abort = 1;
menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
@@ -2488,13 +2473,16 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
gtk_widget_show_all (menu);
gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0);
+ current_menu = menu;
+ record_unwind_protect (pop_down_menu, Qnil);
+
/* 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 (1, 0);
+ popup_widget_loop (1, menu);
- gtk_widget_destroy (menu);
+ unbind_to (specpdl_count, Qnil);
/* Must reset this manually because the button release event is not passed
to Emacs event loop. */
@@ -2522,6 +2510,24 @@ popup_selection_callback (widget, id, client_data)
menu_item_selection = (Lisp_Object *) client_data;
}
+/* ARG is the LWLIB ID of the dialog box, represented
+ as a Lisp object as (HIGHPART . LOWPART). */
+
+static Lisp_Object
+pop_down_menu (arg)
+ Lisp_Object arg;
+{
+ LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
+ | XINT (XCDR (arg)));
+
+ BLOCK_INPUT;
+ lw_destroy_all_widgets (id);
+ UNBLOCK_INPUT;
+ popup_activated_flag = 0;
+
+ return Qnil;
+}
+
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
menu pops down.
menu_item_selection will be set to the selection. */
@@ -2578,15 +2584,19 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
/* Display the menu. */
lw_popup_menu (menu, (XEvent *) &dummy);
popup_activated_flag = 1;
+
+ {
+ int fact = 4 * sizeof (LWLIB_ID);
+ int specpdl_count = SPECPDL_INDEX ();
+ record_unwind_protect (pop_down_menu,
+ Fcons (make_number (menu_id >> (fact)),
+ make_number (menu_id & ~(-1 << (fact)))));
- /* Process events that apply to the menu. */
- popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 0);
+ /* Process events that apply to the menu. */
+ popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 0);
- /* fp turned off the following statement and wrote a comment
- that it is unnecessary--that the menu has already disappeared.
- Nowadays the menu disappears ok, all right, but
- we need to delete the widgets or multiple ones will pile up. */
- lw_destroy_all_widgets (menu_id);
+ unbind_to (specpdl_count, Qnil);
+ }
}
#endif /* not USE_GTK */
@@ -2897,13 +2907,17 @@ create_and_show_dialog (f, first_wv)
if (menu)
{
+ int specpdl_count = SPECPDL_INDEX ();
+ current_menu = menu;
+ record_unwind_protect (pop_down_menu, Qnil);
+
/* Display the menu. */
gtk_widget_show_all (menu);
/* Process events that apply to the menu. */
popup_widget_loop (1, menu);
- gtk_widget_destroy (menu);
+ unbind_to (specpdl_count, Qnil);
}
}
@@ -2926,23 +2940,6 @@ dialog_selection_callback (widget, id, client_data)
}
-/* ARG is the LWLIB ID of the dialog box, represented
- as a Lisp object as (HIGHPART . LOWPART). */
-
-Lisp_Object
-xdialog_show_unwind (arg)
- Lisp_Object arg;
-{
- LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
- | XINT (XCDR (arg)));
- BLOCK_INPUT;
- lw_destroy_all_widgets (id);
- UNBLOCK_INPUT;
- popup_activated_flag = 0;
- return Qnil;
-}
-
-
/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
dialog pops down.
menu_item_selection will be set to the selection. */
@@ -2970,7 +2967,7 @@ create_and_show_dialog (f, first_wv)
int fact = 4 * sizeof (LWLIB_ID);
/* xdialog_show_unwind is responsible for popping the dialog box down. */
- record_unwind_protect (xdialog_show_unwind,
+ record_unwind_protect (pop_down_menu,
Fcons (make_number (dialog_id >> (fact)),
make_number (dialog_id & ~(-1 << (fact)))));
@@ -3203,6 +3200,43 @@ menu_help_callback (help_string, pane, item)
Qnil, menu_object, make_number (item), 1);
}
+static XMenu *current_menu;
+
+static Lisp_Object
+pop_down_menu (frame)
+ Lisp_Object frame;
+{
+ struct frame *f = XFRAME (frame);
+
+ BLOCK_INPUT;
+ if (current_menu)
+ {
+#ifndef MSDOS
+ XUngrabPointer (FRAME_X_DISPLAY (f), CurrentTime);
+ XUngrabKeyboard (FRAME_X_DISPLAY (f), CurrentTime);
+#endif
+ XMenuDestroy (FRAME_X_DISPLAY (f), current_menu);
+ current_menu = 0;
+ }
+
+#ifdef HAVE_X_WINDOWS
+ /* Assume the mouse has moved out of the X window.
+ If it has actually moved in, we will get an EnterNotify. */
+ x_mouse_leave (FRAME_X_DISPLAY_INFO (f));
+
+ /* State that no mouse buttons are now held.
+ (The oldXMenu code doesn't track this info for us.)
+ That is not necessarily true, but the fiction leads to reasonable
+ results, and it is a pain to ask which are actually held now. */
+ FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
+
+#endif /* HAVE_X_WINDOWS */
+
+ UNBLOCK_INPUT;
+
+ return Qnil;
+}
+
static Lisp_Object
xmenu_show (f, x, y, for_click, keymaps, title, error)
@@ -3216,7 +3250,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
Window root;
XMenu *menu;
int pane, selidx, lpane, status;
- Lisp_Object entry, pane_prefix;
+ Lisp_Object entry, pane_prefix, frame;
char *datap;
int ulx, uly, width, height;
int dispwidth, dispheight;
@@ -3224,6 +3258,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
int maxwidth;
int dummy_int;
unsigned int dummy_uint;
+ int specpdl_count = SPECPDL_INDEX ();
*error = 0;
if (menu_items_n_panes == 0)
@@ -3416,20 +3451,17 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
#ifndef MSDOS
XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
#endif
+
+ XSETFRAME (frame, f);
+ record_unwind_protect (pop_down_menu, frame);
/* Help display under X won't work because XMenuActivate contains
a loop that doesn't give Emacs a chance to process it. */
menu_help_frame = f;
+ current_menu = menu;
status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx,
- x, y, ButtonReleaseMask, &datap,
- menu_help_callback);
-
-
-#ifdef HAVE_X_WINDOWS
- /* Assume the mouse has moved out of the X window.
- If it has actually moved in, we will get an EnterNotify. */
- x_mouse_leave (FRAME_X_DISPLAY_INFO (f));
-#endif
+ x, y, ButtonReleaseMask, &datap,
+ menu_help_callback);
switch (status)
{
@@ -3480,15 +3512,8 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
entry = Qnil;
break;
}
- XMenuDestroy (FRAME_X_DISPLAY (f), menu);
-#ifdef HAVE_X_WINDOWS
- /* State that no mouse buttons are now held.
- (The oldXMenu code doesn't track this info for us.)
- That is not necessarily true, but the fiction leads to reasonable
- results, and it is a pain to ask which are actually held now. */
- FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
-#endif
+ unbind_to (specpdl_count, Qnil);
return entry;
}