# HG changeset patch # User Jan D # Date 1279101953 -7200 # Node ID 60266cf487b0f0161ecdc9babc2eaa82b1875ff3 # Parent 269057771f8cea04285273a17839b043d0983ae6 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*. diff -r 269057771f8c -r 60266cf487b0 src/ChangeLog --- 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 + + * 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 * w32fns.c (x_set_foreground_color): Fix setting the cursor color diff -r 269057771f8c -r 60266cf487b0 src/gtkutil.c --- 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; +} + /*********************************************************************** diff -r 269057771f8c -r 60266cf487b0 src/gtkutil.h --- 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)); diff -r 269057771f8c -r 60266cf487b0 src/xfns.c --- 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; diff -r 269057771f8c -r 60266cf487b0 src/xmenu.c --- 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; diff -r 269057771f8c -r 60266cf487b0 src/xterm.c --- 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 diff -r 269057771f8c -r 60266cf487b0 src/xterm.h --- 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)