# HG changeset patch # User Richard M. Stallman # Date 797884600 0 # Node ID fca5a32f7806bb5f8a76d2f80b7cfee633f12512 # Parent b0a7e8ff84ad442ffc474a004aa80a10a472427d (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 -r b0a7e8ff84ad -r fca5a32f7806 src/xmenu.c --- a/src/xmenu.c Fri Apr 14 18:33:44 1995 +0000 +++ b/src/xmenu.c Fri Apr 14 18:36:40 1995 +0000 @@ -1049,12 +1049,25 @@ 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 @@ 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,11 +1478,12 @@ widget_value *wv, *first_wv, *prev_wv = 0; int i; int id; + int count; + + count = inhibit_garbage_collection (); id = frame_vector_add_frame (f); - BLOCK_INPUT; - wv = malloc_widget_value (); wv->name = "menubar"; wv->value = 0; @@ -1481,6 +1533,10 @@ 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 @@ = (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 @@ 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 @@ 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 @@ /* 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. */