]> code.delx.au - gnu-emacs/commitdiff
* xmenu.c (unuse_menu_items, pop_down_menu): Arg is of type
authorJan Djärv <jan.h.d@swipnet.se>
Sat, 13 Nov 2004 20:18:21 +0000 (20:18 +0000)
committerJan Djärv <jan.h.d@swipnet.se>
Sat, 13 Nov 2004 20:18:21 +0000 (20:18 +0000)
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
src/xmenu.c

index 65505cb7c6c0dc3c746c84adec27699c1999cb3b..390ade23e10a7b860f98ba08e5d7df9168c085a1 100644 (file)
@@ -1,3 +1,17 @@
+2004-11-13  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
+
+       * 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  <storm@cua.dk>
 
        * xdisp.c (make_cursor_line_fully_visible_p): New variable.
index 3b81392728132ccf5b5ac47828be46d995cda9b5..c8c40a472562ef2c67128d2bb5249c67dd934d0a 100644 (file)
@@ -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;
 }