[gtk+/touchscreens: 28/67] gtk, pah: Hook directly into gtk_main_do_event()
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/touchscreens: 28/67] gtk, pah: Hook directly into gtk_main_do_event()
- Date: Thu, 29 Dec 2011 00:39:23 +0000 (UTC)
commit 3657ba1d5dc56af853aae37cddf751ef3f7df983
Author: Carlos Garnacho <carlosg gnome org>
Date: Sun Nov 6 12:03:22 2011 +0100
gtk,pah: Hook directly into gtk_main_do_event()
Press and hold couldn't reasonably work if nested widgets
handle ::captured-event, once the widget inits press-and-hold,
it'd better also handle possible cancellation on motion and
button release, which isn't guaranteed with ::capture-event.
Also, tentatively start press-and-hold by default on the
grab_widget, and before event capturing happens, this avoids
awkward situations like the scrolled window preventing/delaying
press-and-hold to happen on the child textview for example.
gtk/gtkmain.c | 17 +++++++
gtk/gtkwidget.c | 120 +++++++++++++++++++-----------------------------
gtk/gtkwidgetprivate.h | 7 +++
3 files changed, 72 insertions(+), 72 deletions(-)
---
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index c761d90..670705b 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1644,6 +1644,16 @@ gtk_main_do_event (GdkEvent *event)
case GDK_BUTTON_PRESS:
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
+ if ((event->type == GDK_BUTTON_PRESS) &&
+ event->button.button == 1)
+ {
+ /* Handle press and hold on the grab widget before propagating up,
+ * so a parent capturing events doesn't delay nor prevent a child
+ * from doing the press-and-hold action.
+ */
+ _gtk_widget_press_and_hold_check_start (grab_widget, &event->button);
+ }
+
if (!gtk_propagate_captured_event (grab_widget, event, topmost_widget))
gtk_propagate_event (grab_widget, event);
break;
@@ -1697,6 +1707,13 @@ gtk_main_do_event (GdkEvent *event)
case GDK_BUTTON_RELEASE:
case GDK_PROXIMITY_IN:
case GDK_PROXIMITY_OUT:
+ if ((event->type == GDK_BUTTON_RELEASE) &&
+ event->button.button == 1)
+ _gtk_widget_press_and_hold_check_cancel (grab_widget, &event->button);
+ else if (event->type == GDK_MOTION_NOTIFY)
+ _gtk_widget_press_and_hold_check_threshold (grab_widget,
+ &event->motion);
+
if (!gtk_propagate_captured_event (grab_widget, event, topmost_widget))
gtk_propagate_event (grab_widget, event);
break;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 55f1bd4..21ae6ba 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -545,11 +545,6 @@ typedef struct
GtkWidget *popup;
guint delay_animation_id;
- /* signal handlers */
- guint motion_id;
- guint button_release_id;
- guint grab_notify_id;
-
gint start_x;
gint start_y;
gint current_x;
@@ -665,8 +660,6 @@ static gboolean gtk_widget_real_can_activate_accel (GtkWidget *widg
static void gtk_widget_real_set_has_tooltip (GtkWidget *widget,
gboolean has_tooltip,
gboolean force);
-static gboolean gtk_widget_press_and_hold_start (GtkWidget *widget,
- GdkEventButton *button);
static void gtk_widget_buildable_interface_init (GtkBuildableIface *iface);
static void gtk_widget_buildable_set_name (GtkBuildable *buildable,
const gchar *name);
@@ -728,6 +721,9 @@ static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
gboolean enabled);
static gboolean event_window_is_still_viewable (GdkEvent *event);
+static gboolean gtk_widget_press_and_hold_cancel (GtkWidget *widget);
+
+
/* --- variables --- */
static gpointer gtk_widget_parent_class = NULL;
static guint widget_signals[LAST_SIGNAL] = { 0 };
@@ -6011,15 +6007,6 @@ _gtk_widget_captured_event (GtkWidget *widget,
g_object_ref (widget);
- if ((event->type == GDK_BUTTON_PRESS ||
- event->type == GDK_TOUCH_PRESS) &&
- event->button.button == 1)
- {
- /* Handle press and hold */
- gtk_widget_press_and_hold_start (widget,
- (GdkEventButton *)event);
- }
-
g_signal_emit (widget, widget_signals[CAPTURED_EVENT], 0, event, &return_val);
return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
@@ -6565,6 +6552,14 @@ void
_gtk_widget_grab_notify (GtkWidget *widget,
gboolean was_grabbed)
{
+ PressAndHoldData *data;
+
+ data = g_object_get_qdata (G_OBJECT (widget), quark_press_and_hold);
+
+ if (data && data->device &&
+ gtk_widget_device_is_shadowed (widget, data->device))
+ gtk_widget_press_and_hold_cancel (widget);
+
g_signal_emit (widget, widget_signals[GRAB_NOTIFY], 0, was_grabbed);
}
@@ -6896,15 +6891,6 @@ press_and_hold_data_free (PressAndHoldData *data)
if (data->delay_animation_id)
g_source_remove (data->delay_animation_id);
- if (data->motion_id)
- g_signal_handler_disconnect (data->widget, data->motion_id);
-
- if (data->button_release_id)
- g_signal_handler_disconnect (data->widget, data->button_release_id);
-
- if (data->grab_notify_id)
- g_signal_handler_disconnect (data->widget, data->grab_notify_id);
-
g_slice_free (PressAndHoldData, data);
}
@@ -6955,43 +6941,43 @@ gtk_widget_press_and_hold_cancel (GtkWidget *widget)
return FALSE;
}
-static gboolean
-gtk_widget_press_and_hold_button_release (GtkWidget *widget,
- GdkEvent *_event,
- PressAndHoldData *data)
+gboolean
+_gtk_widget_press_and_hold_check_cancel (GtkWidget *widget,
+ GdkEventButton *event)
{
- if (_event->type != GDK_BUTTON_RELEASE)
+ PressAndHoldData *data;
+
+ if (event->type != GDK_BUTTON_RELEASE)
return FALSE;
- if (data->device == gdk_event_get_device (_event))
- gtk_widget_press_and_hold_cancel (widget);
+ data = gtk_widget_peek_press_and_hold_data (widget);
- return FALSE;
-}
+ if (data &&
+ data->device == gdk_event_get_device ((GdkEvent *) event))
+ {
+ gtk_widget_press_and_hold_cancel (widget);
+ return TRUE;
+ }
-static void
-gtk_widget_press_and_hold_grab_notify (GtkWidget *widget,
- gboolean was_grabbed,
- PressAndHoldData *data)
-{
- if (data->device &&
- gtk_widget_device_is_shadowed (widget, data->device))
- gtk_widget_press_and_hold_cancel (widget);
+ return FALSE;
}
-static gboolean
-gtk_widget_press_and_hold_motion_notify (GtkWidget *widget,
- GdkEvent *_event,
- PressAndHoldData *data)
+gboolean
+_gtk_widget_press_and_hold_check_threshold (GtkWidget *widget,
+ GdkEventMotion *event)
{
- GdkEventMotion *event;
+ PressAndHoldData *data;
GdkDevice *device;
- if (_event->type != GDK_MOTION_NOTIFY)
+ if (event->type != GDK_MOTION_NOTIFY)
+ return FALSE;
+
+ data = gtk_widget_peek_press_and_hold_data (widget);
+
+ if (!data)
return FALSE;
- event = (GdkEventMotion *)_event;
- device = gdk_event_get_device (_event);
+ device = gdk_event_get_device ((GdkEvent *) event);
if (data->device != device)
return FALSE;
@@ -7004,8 +6990,7 @@ gtk_widget_press_and_hold_motion_notify (GtkWidget *widget,
data->current_x, data->current_y))
{
gtk_widget_press_and_hold_cancel (widget);
-
- return FALSE;
+ return TRUE;
}
if (data->popup)
@@ -7149,28 +7134,32 @@ gtk_widget_press_and_hold_query (GtkWidget *widget,
return return_value;
}
-static gboolean
-gtk_widget_press_and_hold_start (GtkWidget *widget,
- GdkEventButton *event)
+gboolean
+_gtk_widget_press_and_hold_check_start (GtkWidget *widget,
+ GdkEventButton *event)
{
PressAndHoldData *data = gtk_widget_peek_press_and_hold_data (widget);
+ if (event->type != GDK_BUTTON_PRESS)
+ return FALSE;
+
/* Press and hold already in process? */
if (data)
return FALSE;
data = gtk_widget_get_press_and_hold_data (widget);
- if (gtk_widget_press_and_hold_query (widget, data->device, event->x, event->y))
+ if (gtk_widget_press_and_hold_query (widget, data->device,
+ event->x, event->y))
{
- gint timeout, begin_ani_timeout;
+ gint timeout, begin_ani_timeout, cursor_size;
GdkScreen *screen;
GdkVisual *visual;
GtkStyleContext *context;
cairo_region_t *region;
- guint cursor_size;
- _gtk_widget_find_at_coords (event->window, event->x, event->y,
+ _gtk_widget_find_at_coords (event->window,
+ event->x, event->y,
&data->start_x, &data->start_y);
data->current_x = data->start_x;
@@ -7211,19 +7200,6 @@ gtk_widget_press_and_hold_start (GtkWidget *widget,
gtk_widget_press_and_hold_begin_animation_timeout,
widget);
- data->motion_id =
- g_signal_connect (widget, "captured-event",
- G_CALLBACK (gtk_widget_press_and_hold_motion_notify),
- data);
- data->button_release_id =
- g_signal_connect (widget, "captured-event",
- G_CALLBACK (gtk_widget_press_and_hold_button_release),
- data);
- data->grab_notify_id =
- g_signal_connect (widget, "grab-notify",
- G_CALLBACK (gtk_widget_press_and_hold_grab_notify),
- data);
-
data->device = gdk_event_get_device ((GdkEvent *) event);
}
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 8716c67..f475e14 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -166,6 +166,13 @@ void _gtk_widget_set_style (GtkWidget *widget,
gboolean _gtk_widget_captured_event (GtkWidget *widget,
GdkEvent *event);
+gboolean _gtk_widget_press_and_hold_check_start (GtkWidget *widget,
+ GdkEventButton *event);
+gboolean _gtk_widget_press_and_hold_check_cancel (GtkWidget *widget,
+ GdkEventButton *event);
+gboolean _gtk_widget_press_and_hold_check_threshold (GtkWidget *widget,
+ GdkEventMotion *event);
+
G_END_DECLS
#endif /* __GTK_WIDGET_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]