diff options
author | Michael Natterer <mitch@imendio.com> | 2007-03-29 15:47:49 +0000 |
---|---|---|
committer | Michael Natterer <mitch@src.gnome.org> | 2007-03-29 15:47:49 +0000 |
commit | edb9f10aadbddd8a6d7ad652b02a5d9fa9227b6d (patch) | |
tree | 6ac8245aca28a68b2da572d1d2f5f60d5fc7e6b9 /gtk/gtkmenu.c | |
parent | bec19a3f73aae747bee8c35da243e66e2178c9ab (diff) | |
download | gtk+-edb9f10aadbddd8a6d7ad652b02a5d9fa9227b6d.tar.gz |
Don't close menus on clicks on their border area (bug #423761). (modified
2007-03-29 Michael Natterer <mitch@imendio.com>
Don't close menus on clicks on their border area (bug #423761).
(modified patch from maemo-gtk).
* gtk/gtkmenu.c (gtk_menu_button_press)
(gtk_menu_button_release): bail out early if the click was on the
menu's border (not on any item and not outside the window).
(pointer_in_menu_window): new utility function which checks if
passed root coords are inside the menu_shell or one of its
parent shells.
svn path=/trunk/; revision=17571
Diffstat (limited to 'gtk/gtkmenu.c')
-rw-r--r-- | gtk/gtkmenu.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 93214ac438..92eb569bd7 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -2579,17 +2579,56 @@ gtk_menu_button_scroll (GtkMenu *menu, } static gboolean +pointer_in_menu_window (GtkWidget *widget, + gdouble x_root, + gdouble y_root) +{ + GtkMenu *menu = GTK_MENU (widget); + + if (GTK_WIDGET_MAPPED (menu->toplevel)) + { + GtkMenuShell *menu_shell; + gint window_x, window_y; + + gdk_window_get_position (menu->toplevel->window, &window_x, &window_y); + + if (x_root >= window_x && x_root < window_x + widget->allocation.width && + y_root >= window_y && y_root < window_y + widget->allocation.height) + return TRUE; + + menu_shell = GTK_MENU_SHELL (widget); + + if (GTK_IS_MENU (menu_shell->parent_menu_shell)) + return pointer_in_menu_window (menu_shell->parent_menu_shell, + x_root, y_root); + } + + return FALSE; +} + +static gboolean gtk_menu_button_press (GtkWidget *widget, GdkEventButton *event) { if (event->type != GDK_BUTTON_PRESS) return FALSE; - /* Don't pop down the menu for presses over scroll arrows + /* Don't pass down to menu shell for presses over scroll arrows */ if (gtk_menu_button_scroll (GTK_MENU (widget), event)) return TRUE; + /* Don't pass down to menu shell if a non-menuitem part of the menu + * was clicked. The check for the event_widget being a GtkMenuShell + * works because we have the pointer grabbed on menu_shell->window + * with owner_events=TRUE, so all events that are either outside + * the menu or on its border are delivered relative to + * menu_shell->window. + */ + if (GTK_IS_MENU_SHELL (gtk_get_event_widget ((GdkEvent *) event)) && + pointer_in_menu_window (widget, event->x_root, event->y_root)) + return TRUE; + return GTK_WIDGET_CLASS (gtk_menu_parent_class)->button_press_event (widget, event); } @@ -2608,11 +2647,18 @@ gtk_menu_button_release (GtkWidget *widget, if (event->type != GDK_BUTTON_RELEASE) return FALSE; - /* Don't pop down the menu for releases over scroll arrows + /* Don't pass down to menu shell for releases over scroll arrows */ if (gtk_menu_button_scroll (GTK_MENU (widget), event)) return TRUE; + /* Don't pass down to menu shell if a non-menuitem part of the menu + * was clicked (see comment in button_press()). + */ + if (GTK_IS_MENU_SHELL (gtk_get_event_widget ((GdkEvent *) event)) && + pointer_in_menu_window (widget, event->x_root, event->y_root)) + return TRUE; + return GTK_WIDGET_CLASS (gtk_menu_parent_class)->button_release_event (widget, event); } |