# HG changeset patch # User Jan Dj¸«£rv # Date 1100377101 0 # Node ID 6c24ca598cb18bdc270947dccc1df1fd05799c47 # Parent 8cb4d5028bf550bd6aacd2c9b3c316e86f650c78 * 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. diff -r 8cb4d5028bf5 -r 6c24ca598cb1 src/ChangeLog --- a/src/ChangeLog Sat Nov 13 01:42:56 2004 +0000 +++ b/src/ChangeLog Sat Nov 13 20:18:21 2004 +0000 @@ -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 -r 8cb4d5028bf5 -r 6c24ca598cb1 src/xmenu.c --- a/src/xmenu.c Sat Nov 13 01:42:56 2004 +0000 +++ b/src/xmenu.c Sat Nov 13 20:18:21 2004 +0000 @@ -288,7 +288,7 @@ static Lisp_Object unuse_menu_items (dummy) - int dummy; + Lisp_Object dummy; { return menu_items_inuse = Qnil; } @@ -1173,14 +1173,6 @@ #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 @@ { 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 @@ x_dispatch_event (&event, event.xany.display); } - - unbind_to (specpdl_count, Qnil); } #endif /* USE_X_TOOLKIT */ @@ -1261,30 +1248,12 @@ #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 @@ if (do_timers) x_menu_wait_for_event (0); gtk_main_iteration (); } - - unbind_to (specpdl_count, Qnil); } #endif @@ -2443,6 +2410,23 @@ 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 @@ 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 @@ 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); - - gtk_widget_destroy (menu); + popup_widget_loop (1, 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 @@ 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 @@ /* Display the menu. */ lw_popup_menu (menu, (XEvent *) &dummy); popup_activated_flag = 1; - - /* 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); + + { + 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); + + unbind_to (specpdl_count, Qnil); + } } #endif /* not USE_GTK */ @@ -2897,13 +2907,17 @@ 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 @@ } -/* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ #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 @@ 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; }