From af89e8710242b29ea53a150143df30207382891f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Sat, 13 Nov 2004 20:18:21 +0000 Subject: [PATCH] * 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. --- src/ChangeLog | 14 ++++ src/xmenu.c | 185 ++++++++++++++++++++++++++++---------------------- 2 files changed, 119 insertions(+), 80 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 65505cb7c6c..390ade23e10 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2004-11-13 Jan Dj,Ad(Brv + + * 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. + 2004-11-13 Kim F. Storm * xdisp.c (make_cursor_line_fully_visible_p): New variable. 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; } -- 2.39.2