summaryrefslogtreecommitdiff
path: root/gtk/gtkmenu.c
diff options
context:
space:
mode:
authorMichael Natterer <mitch@imendio.com>2007-03-29 15:47:49 +0000
committerMichael Natterer <mitch@src.gnome.org>2007-03-29 15:47:49 +0000
commitedb9f10aadbddd8a6d7ad652b02a5d9fa9227b6d (patch)
tree6ac8245aca28a68b2da572d1d2f5f60d5fc7e6b9 /gtk/gtkmenu.c
parentbec19a3f73aae747bee8c35da243e66e2178c9ab (diff)
downloadgtk+-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.c50
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);
}