summaryrefslogtreecommitdiff
path: root/gtk/gtkmenu.c
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2004-12-22 16:52:23 +0000
committerSøren Sandmann Pedersen <ssp@src.gnome.org>2004-12-22 16:52:23 +0000
commit03413577a1ee364109a181c5c7711c2b118a703b (patch)
treecf415c25d5ff14092b159f726a621f0ffa08f1ff /gtk/gtkmenu.c
parent5ec1648473815ab4d09ab1151f22c55d59c1cc8c (diff)
downloadgdk-pixbuf-03413577a1ee364109a181c5c7711c2b118a703b.tar.gz
Bug #147497, make menu items activate immediately when you release the
Wed Dec 22 11:35:41 2004 Søren Sandmann <sandmann@redhat.com> Bug #147497, make menu items activate immediately when you release the button. * gtk/gtkmenu.c (gtk_menu_enter_notify, menu_motion_notify): Make items activate immediately. * gtk/gtkmenu.c (definitely_within_item): New function * gtk/gtkmenu.c (check_threshold): New function
Diffstat (limited to 'gtk/gtkmenu.c')
-rw-r--r--gtk/gtkmenu.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 71048e84a..7266bb756 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -76,6 +76,8 @@ struct _GtkMenuAttachData
struct _GtkMenuPrivate
{
+ gboolean seen_item_enter;
+
gboolean have_position;
gint x;
gint y;
@@ -1278,6 +1280,7 @@ gtk_menu_popup (GtkMenu *menu,
GtkWidget *parent;
GdkEvent *current_event;
GtkMenuShell *menu_shell;
+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
g_return_if_fail (GTK_IS_MENU (menu));
@@ -1285,6 +1288,8 @@ gtk_menu_popup (GtkMenu *menu,
menu_shell = GTK_MENU_SHELL (menu);
menu_shell->parent_menu_shell = parent_menu_shell;
+
+ priv->seen_item_enter = FALSE;
/* Find the last viewable ancestor, and make an X grab on it
*/
@@ -2718,12 +2723,42 @@ gtk_menu_key_press (GtkWidget *widget,
}
static gboolean
+check_threshold (GtkWidget *widget,
+ int start_x, int start_y,
+ int x, int y)
+{
+#define THRESHOLD 8
+
+ return
+ ABS (start_x - x) > THRESHOLD ||
+ ABS (start_y - y) > THRESHOLD;
+}
+
+static gboolean
+definitely_within_item (GtkWidget *widget,
+ int x,
+ int y)
+{
+ GdkWindow *window = GTK_MENU_ITEM (widget)->event_window;
+ int w, h;
+
+ gdk_drawable_get_size (window, &w, &h);
+
+ return
+ check_threshold (widget, 0, 0, x, y) &&
+ check_threshold (widget, w - 1, 0, x, y) &&
+ check_threshold (widget, w - 1, h - 1, x, y) &&
+ check_threshold (widget, 0, h - 1, x, y);
+}
+
+static gboolean
gtk_menu_motion_notify (GtkWidget *widget,
GdkEventMotion *event)
{
GtkWidget *menu_item;
GtkMenu *menu;
GtkMenuShell *menu_shell;
+ GtkMenuPrivate *priv;
gboolean need_enter;
@@ -2746,6 +2781,11 @@ gtk_menu_motion_notify (GtkWidget *widget,
menu_shell = GTK_MENU_SHELL (menu_item->parent);
menu = GTK_MENU (menu_shell);
+
+ priv = gtk_menu_get_private (GTK_MENU (widget));
+
+ if (definitely_within_item (menu_item, event->x, event->y))
+ menu_shell->activate_time = 0;
need_enter = (menu->navigation_region != NULL || menu_shell->ignore_enter);
@@ -2993,6 +3033,42 @@ gtk_menu_enter_notify (GtkWidget *widget,
if (!menu_shell->ignore_enter)
gtk_menu_handle_scrolling (GTK_MENU (widget), TRUE);
}
+
+ if (menu_item && GTK_IS_MENU_ITEM (menu_item))
+ {
+ GtkWidget *menu = menu_item->parent;
+
+ if (menu && GTK_IS_MENU (menu))
+ {
+ GtkMenuPrivate *priv = gtk_menu_get_private (GTK_MENU (menu));
+ GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu);
+
+ if (priv->seen_item_enter)
+ {
+ /* This is the second enter we see for an item
+ * on this menu. This means a release should always
+ * mean activate.
+ */
+ menu_shell->activate_time = 0;
+ }
+ else if ((event->detail != GDK_NOTIFY_NONLINEAR &&
+ event->detail != GDK_NOTIFY_NONLINEAR_VIRTUAL))
+ {
+ if (definitely_within_item (menu_item, event->x, event->y))
+ {
+ /* This is an actual user-enter (ie. not a pop-under)
+ * In this case, the user must either have entered
+ * sufficiently far enough into the item, or he must move
+ * far enough away from the enter point. (see
+ * gtk_menu_motion_notify())
+ */
+ menu_shell->activate_time = 0;
+ }
+ }
+
+ priv->seen_item_enter = TRUE;
+ }
+ }
/* If this is a faked enter (see gtk_menu_motion_notify), 'widget'
* will not correspond to the event widget's parent. Check to see