summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2016-12-02 13:20:47 +0100
committerTimm Bäder <mail@baedert.org>2016-12-07 18:06:37 +0100
commit1aa1676d9dd5910f460bcea0fdde03c041fac6db (patch)
tree29a5b5921a05123c6ba8246115188b03869c611b
parentbe9adea58ebd73686ced99dd9a2a77fd82005c0c (diff)
downloadgtk+-1aa1676d9dd5910f460bcea0fdde03c041fac6db.tar.gz
menu: Replace button-press-handler with gesture
-rw-r--r--gtk/gtkmenu.c88
-rw-r--r--gtk/gtkmenuprivate.h3
2 files changed, 57 insertions, 34 deletions
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 7d2c3c9977..256f5b7276 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -240,10 +240,6 @@ static gboolean gtk_menu_key_press (GtkWidget *widget,
GdkEventKey *event);
static gboolean gtk_menu_scroll (GtkWidget *widget,
GdkEventScroll *event);
-static gboolean gtk_menu_button_press (GtkWidget *widget,
- GdkEventButton *event);
-static gboolean gtk_menu_button_release (GtkWidget *widget,
- GdkEventButton *event);
static gboolean gtk_menu_motion_notify (GtkWidget *widget,
GdkEventMotion *event);
static gboolean gtk_menu_enter_notify (GtkWidget *widget,
@@ -312,6 +308,16 @@ static void gtk_menu_measure (GtkWidget *widget,
int *natural,
int *minimum_baseline,
int *natural_baseline);
+static void gtk_menu_pressed_cb (GtkGestureMultiPress *gesture,
+ int n_press,
+ double x,
+ double y,
+ gpointer user_data);
+static void gtk_menu_released_cb (GtkGestureMultiPress *gesture,
+ int n_press,
+ double x,
+ double y,
+ gpointer user_data);
static const gchar attach_data_key[] = "gtk-menu-attach-data";
@@ -512,8 +518,6 @@ gtk_menu_class_init (GtkMenuClass *class)
widget_class->draw = gtk_menu_draw;
widget_class->scroll_event = gtk_menu_scroll;
widget_class->key_press_event = gtk_menu_key_press;
- widget_class->button_press_event = gtk_menu_button_press;
- widget_class->button_release_event = gtk_menu_button_release;
widget_class->motion_notify_event = gtk_menu_motion_notify;
widget_class->show_all = gtk_menu_show_all;
widget_class->enter_notify_event = gtk_menu_enter_notify;
@@ -1207,6 +1211,13 @@ gtk_menu_init (GtkMenu *menu)
gtk_css_node_set_parent (bottom_arrow_node, widget_node);
gtk_css_node_set_visible (bottom_arrow_node, FALSE);
gtk_css_node_set_state (bottom_arrow_node, gtk_css_node_get_state (widget_node));
+
+ priv->click_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (menu));
+ gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->click_gesture), FALSE);
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->click_gesture), 0);
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->click_gesture), GTK_PHASE_BUBBLE);
+ g_signal_connect (priv->click_gesture, "pressed", G_CALLBACK (gtk_menu_pressed_cb), menu);
+ g_signal_connect (priv->click_gesture, "released", G_CALLBACK (gtk_menu_released_cb), menu);
}
static void
@@ -1278,6 +1289,7 @@ gtk_menu_finalize (GObject *object)
g_clear_object (&priv->top_arrow_gadget);
g_clear_object (&priv->bottom_arrow_gadget);
+ g_clear_object (&priv->click_gesture);
G_OBJECT_CLASS (gtk_menu_parent_class)->finalize (object);
}
@@ -3188,21 +3200,23 @@ pointer_in_menu_window (GtkWidget *widget,
return FALSE;
}
-static gboolean
-gtk_menu_button_press (GtkWidget *widget,
- GdkEventButton *event)
+
+static void
+gtk_menu_pressed_cb (GtkGestureMultiPress *gesture,
+ int n_press,
+ double x,
+ double y,
+ gpointer user_data)
{
+ GtkMenu *menu = user_data;
+ GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+ const GdkEvent *event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
+ const GdkEventButton *button_event = (GdkEventButton *)event;
GdkDevice *source_device;
GtkWidget *event_widget;
- GtkMenu *menu;
-
- if (event->type != GDK_BUTTON_PRESS)
- return FALSE;
-
- source_device = gdk_event_get_source_device ((GdkEvent *) event);
- event_widget = gtk_get_event_widget ((GdkEvent *) event);
- menu = GTK_MENU (widget);
+ source_device = gdk_event_get_source_device (event);
+ event_widget = gtk_get_event_widget ((GdkEvent *)event);
/* 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
@@ -3211,8 +3225,11 @@ gtk_menu_button_press (GtkWidget *widget,
* menu_shell->window.
*/
if (GTK_IS_MENU_SHELL (event_widget) &&
- pointer_in_menu_window (widget, event->x_root, event->y_root))
- return TRUE;
+ pointer_in_menu_window (GTK_WIDGET (menu), button_event->x_root, button_event->y_root))
+ {
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+ return;
+ }
if (GTK_IS_MENU_ITEM (event_widget) &&
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN &&
@@ -3220,42 +3237,45 @@ gtk_menu_button_press (GtkWidget *widget,
!gtk_widget_is_drawable (GTK_MENU_ITEM (event_widget)->priv->submenu))
menu->priv->ignore_button_release = TRUE;
- return GTK_WIDGET_CLASS (gtk_menu_parent_class)->button_press_event (widget, event);
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
}
-static gboolean
-gtk_menu_button_release (GtkWidget *widget,
- GdkEventButton *event)
+static void
+gtk_menu_released_cb (GtkGestureMultiPress *gesture,
+ int n_press,
+ double x,
+ double y,
+ gpointer user_data)
{
- GtkMenuPrivate *priv = GTK_MENU (widget)->priv;
+ GtkMenu *menu = user_data;
+ GtkMenuPrivate *priv = menu->priv;
+ GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+ const GdkEvent *event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
+ const GdkEventButton *button_event = (GdkEventButton *)event;
if (priv->ignore_button_release)
{
priv->ignore_button_release = FALSE;
- return FALSE;
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
+ return;
}
- if (event->type != GDK_BUTTON_RELEASE)
- return FALSE;
-
/* 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))
+ pointer_in_menu_window (GTK_WIDGET (menu), button_event->x_root, button_event->y_root))
{
/* Ugly: make sure menu_shell->button gets reset to 0 when we
* bail out early here so it is in a consistent state for the
* next button_press/button_release in GtkMenuShell.
* See bug #449371.
*/
- if (GTK_MENU_SHELL (widget)->priv->active)
- GTK_MENU_SHELL (widget)->priv->button = 0;
+ if (GTK_MENU_SHELL (menu)->priv->active)
+ GTK_MENU_SHELL (menu)->priv->button = 0;
- return TRUE;
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
-
- return GTK_WIDGET_CLASS (gtk_menu_parent_class)->button_release_event (widget, event);
}
static gboolean
diff --git a/gtk/gtkmenuprivate.h b/gtk/gtkmenuprivate.h
index c61a49e9de..fe089d01e1 100644
--- a/gtk/gtkmenuprivate.h
+++ b/gtk/gtkmenuprivate.h
@@ -28,6 +28,7 @@
#include <gtk/gtkmenu.h>
#include <gtk/gtkcssgadgetprivate.h>
#include <gtk/gtkcssnodeprivate.h>
+#include <gtk/gtkgesturemultipress.h>
G_BEGIN_DECLS
@@ -78,6 +79,8 @@ struct _GtkMenuPrivate
GtkCssGadget *top_arrow_gadget;
GtkCssGadget *bottom_arrow_gadget;
+ GtkGesture *click_gesture;
+
gint scroll_offset;
gint saved_scroll_offset;
gint scroll_step;