changeset 11449:fca5a32f7806

(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.
author Richard M. Stallman <rms@gnu.org>
date Fri, 14 Apr 1995 18:36:40 +0000
parents b0a7e8ff84ad
children aee30032f324
files src/xmenu.c
diffstat 1 files changed, 65 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- 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.  */