From: Richard M. Stallman Date: Fri, 14 Apr 1995 18:36:40 +0000 (+0000) Subject: (popup_get_selection): Queue up events that aren't X-Git-Url: https://git.hcoop.net/bpt/emacs.git/commitdiff_plain/aa669defddb849e4ac3f1f3b49a74338495956b7 (popup_get_selection): Queue up events that aren't for the menu, and process them afterward. New arg dpyinfo. (set_frame_menubar): Use inhibit_garbage_collection. [USE_X_TOOLKIT] (xmenu_show): Delete the queue code here. Pass dpyinfo to popup_get_selection. Don't call lw_destroy_all_widgets. [USE_X_TOOLKIT] (xdialog_show): Simplify using popup_get_selection. --- diff --git a/src/xmenu.c b/src/xmenu.c index fd7c9a3cec..224fc7fea6 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1049,12 +1049,25 @@ on the left of the dialog box and all following items on the right.\n\ NOTE: All calls to popup_get_selection() should be protected with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */ + void -popup_get_selection (initial_event) +popup_get_selection (initial_event, dpyinfo) XEvent *initial_event; + struct x_display_info *dpyinfo; { XEvent event; + /* Define a queue to save up for later unreading + all X events that don't pertain to the menu. */ + struct event_queue + { + XEvent event; + struct event_queue *next; + }; + + struct event_queue *queue = NULL; + struct event_queue *queue_tmp; + if (initial_event) event = *initial_event; else @@ -1062,14 +1075,52 @@ popup_get_selection (initial_event) while (1) { + /* Handle expose events for editor frames right away. */ + if (event.type == Expose) + process_expose_from_menu (event); + /* Make sure we don't consider buttons grabbed after menu goes. */ + else if (event.type == ButtonRelease + && dpyinfo->display == event.xbutton.display) + dpyinfo->grabbed &= ~(1 << event.xbutton.button); + + /* Queue all events not for this popup, + except for Expose, which we've already handled. */ + if (event.type != Expose + && (event.xany.display != dpyinfo->display + || ! x_any_window_to_frame (dpyinfo, event.xany.window))) + { + + queue_tmp = (struct event_queue *) malloc (sizeof (struct event_queue)); + + if (queue_tmp != NULL) + { + queue_tmp->event = event; + queue_tmp->next = queue; + queue = queue_tmp; + } + } + XtDispatchEvent (&event); - if (!popup_activated()) + + if (!popup_activated ()) break; XtAppNextEvent (Xt_app_con, &event); } + + /* Unread any events that we got but did not handle. */ + while (queue != NULL) + { + queue_tmp = queue; + XPutBackEvent (queue_tmp->event.xany.display, &queue_tmp->event); + queue = queue_tmp->next; + free ((char *)queue_tmp); + /* Cause these events to get read as soon as we UNBLOCK_INPUT. */ + interrupt_input_pending = 1; + } } /* Detect if a dialog or menu has been posted. */ + int popup_activated () { @@ -1427,10 +1478,11 @@ set_frame_menubar (f, first_time) widget_value *wv, *first_wv, *prev_wv = 0; int i; int id; + int count; - id = frame_vector_add_frame (f); + count = inhibit_garbage_collection (); - BLOCK_INPUT; + id = frame_vector_add_frame (f); wv = malloc_widget_value (); wv->name = "menubar"; @@ -1481,6 +1533,10 @@ set_frame_menubar (f, first_time) f->menu_bar_items_used = menu_items_used; menu_items = Qnil; + unbind_to (count, Qnil); + + BLOCK_INPUT; + if (menubar_widget) { /* Disable resizing (done for Motif!) */ @@ -1615,17 +1671,6 @@ xmenu_show (f, x, y, menubarp, for_click, keymaps, title, error) = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); int submenu_depth = 0; - /* Define a queue to save up for later unreading - all X events that don't pertain to the menu. */ - struct event_queue - { - XEvent event; - struct event_queue *next; - }; - - struct event_queue *queue = NULL; - struct event_queue *queue_tmp; - Position root_x, root_y; int first_pane; @@ -1786,25 +1831,15 @@ xmenu_show (f, x, y, menubarp, for_click, keymaps, title, error) popup_activated_flag = 1; /* Process events that apply to the menu. */ - popup_get_selection ((XEvent *) 0); + popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f)); - pop_down: +#if 0 /* fp turned off the following statement and wrote a comment that it is unnecessary--that the menu has already disappeared. I observer that is not so. -- rms. */ /* Make sure the menu disappears. */ lw_destroy_all_widgets (menu_id); - - /* Unread any events that we got but did not handle. */ - while (queue != NULL) - { - queue_tmp = queue; - XPutBackEvent (FRAME_X_DISPLAY (f), &queue_tmp->event); - queue = queue_tmp->next; - free ((char *)queue_tmp); - /* Cause these events to get read as soon as we UNBLOCK_INPUT. */ - interrupt_input_pending = 1; - } +#endif /* Find the selected item, and its pane, to return the proper value. */ @@ -1896,17 +1931,6 @@ xdialog_show (f, menubarp, keymaps, title, error) widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; - /* Define a queue to save up for later unreading - all X events that don't pertain to the menu. */ - struct event_queue - { - XEvent event; - struct event_queue *next; - }; - - struct event_queue *queue = NULL; - struct event_queue *queue_tmp; - /* Number of elements seen so far, before boundary. */ int left_count = 0; /* 1 means we've seen the boundary between left-hand elts and right-hand. */ @@ -2024,53 +2048,10 @@ xdialog_show (f, menubarp, keymaps, title, error) /* Display the menu. */ lw_pop_up_all_widgets (dialog_id); + popup_activated_flag = 1; /* Process events that apply to the menu. */ - while (1) - { - XEvent event; - - XtAppNextEvent (Xt_app_con, &event); - if (event.type == ButtonRelease) - { - XtDispatchEvent (&event); - break; - } - else if (event.type == Expose) - process_expose_from_menu (event); - XtDispatchEvent (&event); - if (XtWindowToWidget (FRAME_X_DISPLAY (f), event.xany.window) != menu) - { - queue_tmp = (struct event_queue *) malloc (sizeof (struct event_queue)); - - if (queue_tmp != NULL) - { - queue_tmp->event = event; - queue_tmp->next = queue; - queue = queue_tmp; - } - } - } - pop_down: - -#ifdef HAVE_X_WINDOWS - /* State that no mouse buttons are now held. - That is not necessarily true, but the fiction leads to reasonable - results, and it is a pain to ask which are actually held now - or track this in the loop above. */ - FRAME_X_DISPLAY_INFO (f)->grabbed = 0; -#endif - - /* Unread any events that we got but did not handle. */ - while (queue != NULL) - { - queue_tmp = queue; - XPutBackEvent (FRAME_X_DISPLAY (f), &queue_tmp->event); - queue = queue_tmp->next; - free ((char *)queue_tmp); - /* Cause these events to get read as soon as we UNBLOCK_INPUT. */ - interrupt_input_pending = 1; - } + popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f)); /* Find the selected item, and its pane, to return the proper value. */