changeset 109327:60266cf487b0

Fix menus as per bug 6499 and 6608. * gtkutil.c (xg_event_is_for_menubar): New function (Bug#6499). * gtkutil.h (xg_event_is_for_menubar): Declare. * xfns.c (x_menubar_window_to_frame): Take XEvent as second parameter instead of Window. Call xg_event_is_for_menubar when USE_GTK (Bug#6499). * xmenu.c (x_activate_menubar): Revert previous fix for Bug#6499, i.e. don't put back ButtonRelease (Bug#6608). * xterm.c (handle_one_xevent): Pass event to x_menubar_window_to_frame. * xterm.h (x_menubar_window_to_frame): Second parameter is XEvent*.
author Jan D <jan.h.d@swipnet.se>
date Wed, 14 Jul 2010 12:05:53 +0200
parents 269057771f8c
children 548603211765
files src/ChangeLog src/gtkutil.c src/gtkutil.h src/xfns.c src/xmenu.c src/xterm.c src/xterm.h
diffstat 7 files changed, 61 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Jul 14 10:40:52 2010 +0300
+++ b/src/ChangeLog	Wed Jul 14 12:05:53 2010 +0200
@@ -1,3 +1,20 @@
+2010-07-14  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* xterm.h (x_menubar_window_to_frame): Second parameter is XEvent*.
+
+	* xterm.c (handle_one_xevent): Pass event to x_menubar_window_to_frame.
+
+	* xmenu.c (x_activate_menubar): Revert previous fix for Bug#6499,
+	i.e. don't put back ButtonRelease (Bug#6608).
+
+	* xfns.c (x_menubar_window_to_frame): Take XEvent as second parameter
+	instead of Window.  Call xg_event_is_for_menubar when
+	USE_GTK (Bug#6499).
+
+	* gtkutil.h (xg_event_is_for_menubar): Declare.
+
+	* gtkutil.c (xg_event_is_for_menubar): New function (Bug#6499).
+
 2010-07-14  Eli Zaretskii  <eliz@gnu.org>
 
 	* w32fns.c (x_set_foreground_color): Fix setting the cursor color
--- a/src/gtkutil.c	Wed Jul 14 10:40:52 2010 +0300
+++ b/src/gtkutil.c	Wed Jul 14 12:05:53 2010 +0200
@@ -2990,6 +2990,38 @@
     }
 }
 
+int
+xg_event_is_for_menubar (FRAME_PTR f, XEvent *event)
+{
+  struct x_output *x = f->output_data.x;
+
+  if (! x->menubar_widget) return 0;
+
+  if (! (event->xbutton.x >= 0
+         && event->xbutton.x < FRAME_PIXEL_WIDTH (f)
+         && event->xbutton.y >= 0
+         && event->xbutton.y < f->output_data.x->menubar_height
+         && event->xbutton.same_screen))
+    return 0;
+
+  GList *list = gtk_container_get_children (GTK_CONTAINER (x->menubar_widget));
+  if (! list) return 0;
+  GList *iter;
+  GdkRectangle rec;
+  rec.x = event->xbutton.x;
+  rec.y = event->xbutton.y;
+  rec.width = 1;
+  rec.height = 1;
+  for (iter = list ; iter; iter = g_list_next (iter))
+    {
+      GtkWidget *w = GTK_WIDGET (iter->data);
+      if (GTK_WIDGET_MAPPED (w) && gtk_widget_intersect (w, &rec, NULL))
+        break;
+    }
+  g_list_free (list);
+  return iter == 0 ? 0 : 1;
+}
+
 
 
 /***********************************************************************
--- a/src/gtkutil.h	Wed Jul 14 10:40:52 2010 +0300
+++ b/src/gtkutil.h	Wed Jul 14 12:05:53 2010 +0200
@@ -154,6 +154,8 @@
 
 extern int xg_update_frame_menubar P_ ((FRAME_PTR f));
 
+extern int xg_event_is_for_menubar P_ ((FRAME_PTR f, XEvent *event));
+
 extern int xg_have_tear_offs P_ ((void));
 
 extern int xg_get_scroll_id_for_window P_ ((Display *dpy, Window wid));
--- a/src/xfns.c	Wed Jul 14 10:40:52 2010 +0300
+++ b/src/xfns.c	Wed Jul 14 12:05:53 2010 +0200
@@ -404,10 +404,11 @@
 /* Likewise, but consider only the menu bar widget.  */
 
 struct frame *
-x_menubar_window_to_frame (dpyinfo, wdesc)
+x_menubar_window_to_frame (dpyinfo, event)
      struct x_display_info *dpyinfo;
-     int wdesc;
+     XEvent *event;
 {
+  Window wdesc = event->xany.window;
   Lisp_Object tail, frame;
   struct frame *f;
   struct x_output *x;
@@ -423,21 +424,11 @@
       if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
 	continue;
       x = f->output_data.x;
+#ifdef USE_GTK
+      if (x->menubar_widget && xg_event_is_for_menubar (f, event))
+        return f;
+#else
       /* Match if the window is this frame's menubar.  */
-#ifdef USE_GTK
-      if (x->menubar_widget)
-        {
-          GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
-
-	  /* This gives false positives, but the rectangle check in xterm.c
-	     where this is called takes care of that.  */
-          if (gwdesc != 0
-              && (gwdesc == x->menubar_widget
-                  || gtk_widget_is_ancestor (x->menubar_widget, gwdesc)
-		  || gtk_widget_is_ancestor (gwdesc, x->menubar_widget)))
-            return f;
-        }
-#else
       if (x->menubar_widget
 	  && lw_window_is_in_menubar (wdesc, x->menubar_widget))
 	return f;
--- a/src/xmenu.c	Wed Jul 14 10:40:52 2010 +0300
+++ b/src/xmenu.c	Wed Jul 14 12:05:53 2010 +0200
@@ -684,14 +684,6 @@
   set_frame_menubar (f, 0, 1);
   BLOCK_INPUT;
 #ifdef USE_GTK
-  /* If we click outside any menu item, the menu bar still grabs.
-     So we send Press and the Release.  If outside, grab is released.
-     If on a menu item, it is popped up normally.
-     PutBack is like a stack, so we put back in reverse order.  */
-  f->output_data.x->saved_menu_event->type = ButtonRelease;
-  XPutBackEvent (f->output_data.x->display_info->display,
-                 f->output_data.x->saved_menu_event);
-  f->output_data.x->saved_menu_event->type = ButtonPress;
   XPutBackEvent (f->output_data.x->display_info->display,
                  f->output_data.x->saved_menu_event);
   popup_activated_flag = 1;
--- a/src/xterm.c	Wed Jul 14 10:40:52 2010 +0300
+++ b/src/xterm.c	Wed Jul 14 12:05:53 2010 +0200
@@ -6951,7 +6951,7 @@
 	  f->mouse_moved = 0;
 
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
-        f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
+        f = x_menubar_window_to_frame (dpyinfo, &event);
         /* For a down-event in the menu bar,
            don't pass it to Xt right now.
            Instead, save it away
--- a/src/xterm.h	Wed Jul 14 10:40:52 2010 +0300
+++ b/src/xterm.h	Wed Jul 14 12:05:53 2010 +0200
@@ -383,7 +383,8 @@
 extern struct frame *x_window_to_frame P_ ((struct x_display_info *, int));
 
 extern struct frame *x_any_window_to_frame P_ ((struct x_display_info *, int));
-extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *, int));
+extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *,
+                                                    XEvent *));
 extern struct frame *x_top_window_to_frame P_ ((struct x_display_info *, int));
 
 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)