2014-05-27 23:15:40 +00:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2019-11-27 13:33:43 +00:00
|
|
|
#define GTK_COMPILATION
|
2017-08-28 23:11:45 +00:00
|
|
|
#include "gdk/gdkeventsprivate.h"
|
|
|
|
|
2014-06-03 11:17:13 +00:00
|
|
|
typedef struct {
|
|
|
|
GtkWidget *widget;
|
|
|
|
gint x;
|
|
|
|
gint y;
|
|
|
|
guint state;
|
|
|
|
guint pressed : 1;
|
|
|
|
} PointState;
|
|
|
|
|
|
|
|
static PointState mouse_state;
|
|
|
|
static PointState touch_state[10]; /* touchpoint 0 gets pointer emulation,
|
|
|
|
* use it first in tests for consistency.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define EVENT_SEQUENCE(point) (GdkEventSequence*) ((point) - touch_state + 1)
|
|
|
|
|
2020-02-09 15:54:26 +00:00
|
|
|
static void
|
|
|
|
inject_event (GdkEvent *event)
|
|
|
|
{
|
|
|
|
gboolean handled;
|
|
|
|
|
Restructure the GdkEvent type hierarchy
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
2020-04-16 16:23:36 +00:00
|
|
|
g_signal_emit_by_name (event->surface, "event", event, &handled);
|
2020-02-09 15:54:26 +00:00
|
|
|
}
|
|
|
|
|
2014-06-03 11:17:13 +00:00
|
|
|
static void
|
|
|
|
point_press (PointState *point,
|
|
|
|
GtkWidget *widget,
|
|
|
|
guint button)
|
2014-05-27 23:15:40 +00:00
|
|
|
{
|
|
|
|
GdkDisplay *display;
|
|
|
|
GdkDevice *device;
|
2016-02-13 05:41:29 +00:00
|
|
|
GdkSeat *seat;
|
2019-05-20 00:38:08 +00:00
|
|
|
GdkSurface *surface;
|
2014-06-03 11:17:13 +00:00
|
|
|
GdkEvent *ev;
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
display = gtk_widget_get_display (widget);
|
2016-02-13 05:41:29 +00:00
|
|
|
seat = gdk_display_get_default_seat (display);
|
|
|
|
device = gdk_seat_get_pointer (seat);
|
2019-05-20 00:38:08 +00:00
|
|
|
surface = gtk_native_get_surface (gtk_widget_get_native (widget));
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2014-06-03 11:17:13 +00:00
|
|
|
if (point == &mouse_state)
|
|
|
|
{
|
Restructure the GdkEvent type hierarchy
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
2020-04-16 16:23:36 +00:00
|
|
|
ev = gdk_button_event_new (GDK_BUTTON_PRESS,
|
2020-02-15 15:12:41 +00:00
|
|
|
surface,
|
|
|
|
device,
|
|
|
|
device,
|
|
|
|
NULL,
|
|
|
|
GDK_CURRENT_TIME,
|
|
|
|
point->x,
|
|
|
|
point->y,
|
|
|
|
button,
|
|
|
|
point->state);
|
2014-06-03 11:17:13 +00:00
|
|
|
|
|
|
|
point->state |= GDK_BUTTON1_MASK << (button - 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Restructure the GdkEvent type hierarchy
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
2020-04-16 16:23:36 +00:00
|
|
|
ev = gdk_touch_event_new (GDK_TOUCH_BEGIN,
|
2020-02-15 15:12:41 +00:00
|
|
|
EVENT_SEQUENCE (point),
|
|
|
|
surface,
|
|
|
|
device,
|
|
|
|
device,
|
|
|
|
GDK_CURRENT_TIME,
|
|
|
|
point->state,
|
|
|
|
point->x,
|
|
|
|
point->y,
|
|
|
|
point == &touch_state[0]);
|
2014-06-03 11:17:13 +00:00
|
|
|
}
|
|
|
|
|
2020-02-09 15:54:26 +00:00
|
|
|
inject_event (ev);
|
2014-06-03 11:17:13 +00:00
|
|
|
|
2018-05-29 19:53:44 +00:00
|
|
|
g_object_unref (ev);
|
2014-06-03 11:17:13 +00:00
|
|
|
|
|
|
|
point->widget = widget;
|
|
|
|
}
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2014-06-03 11:17:13 +00:00
|
|
|
static void
|
|
|
|
point_update (PointState *point,
|
|
|
|
GtkWidget *widget,
|
|
|
|
gdouble x,
|
|
|
|
gdouble y)
|
|
|
|
{
|
|
|
|
GdkDisplay *display;
|
|
|
|
GdkDevice *device;
|
2016-02-13 05:41:29 +00:00
|
|
|
GdkSeat *seat;
|
2019-05-20 00:38:08 +00:00
|
|
|
GdkSurface *surface;
|
2014-06-03 11:17:13 +00:00
|
|
|
GdkEvent *ev;
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2014-06-03 11:17:13 +00:00
|
|
|
display = gtk_widget_get_display (widget);
|
2016-02-13 05:41:29 +00:00
|
|
|
seat = gdk_display_get_default_seat (display);
|
|
|
|
device = gdk_seat_get_pointer (seat);
|
2019-05-20 00:38:08 +00:00
|
|
|
surface = gtk_native_get_surface (gtk_widget_get_native (widget));
|
2014-06-03 11:17:13 +00:00
|
|
|
|
2014-06-04 11:35:16 +00:00
|
|
|
point->x = x;
|
|
|
|
point->y = y;
|
|
|
|
|
2014-06-03 11:17:13 +00:00
|
|
|
if (point == &mouse_state)
|
|
|
|
{
|
Restructure the GdkEvent type hierarchy
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
2020-04-16 16:23:36 +00:00
|
|
|
ev = gdk_motion_event_new (surface,
|
2020-02-15 15:12:41 +00:00
|
|
|
device,
|
|
|
|
device,
|
|
|
|
NULL,
|
|
|
|
GDK_CURRENT_TIME,
|
|
|
|
point->state,
|
|
|
|
point->x,
|
|
|
|
point->y);
|
2014-06-03 11:17:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!point->widget || widget != point->widget)
|
|
|
|
return;
|
|
|
|
|
Restructure the GdkEvent type hierarchy
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
2020-04-16 16:23:36 +00:00
|
|
|
ev = gdk_touch_event_new (GDK_TOUCH_UPDATE,
|
2020-02-15 15:12:41 +00:00
|
|
|
EVENT_SEQUENCE (point),
|
|
|
|
surface,
|
|
|
|
device,
|
|
|
|
device,
|
|
|
|
GDK_CURRENT_TIME,
|
|
|
|
point->state,
|
|
|
|
point->x,
|
|
|
|
point->y,
|
|
|
|
point == &touch_state[0]);
|
2014-06-03 11:17:13 +00:00
|
|
|
}
|
|
|
|
|
2020-02-09 15:54:26 +00:00
|
|
|
inject_event (ev);
|
2014-06-03 11:17:13 +00:00
|
|
|
|
2018-05-29 19:53:44 +00:00
|
|
|
g_object_unref (ev);
|
2014-06-03 11:17:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
point_release (PointState *point,
|
|
|
|
guint button)
|
|
|
|
{
|
|
|
|
GdkDisplay *display;
|
|
|
|
GdkDevice *device;
|
2016-02-13 05:41:29 +00:00
|
|
|
GdkSeat *seat;
|
2019-05-20 00:38:08 +00:00
|
|
|
GdkSurface *surface;
|
2014-06-03 11:17:13 +00:00
|
|
|
GdkEvent *ev;
|
|
|
|
|
|
|
|
if (point->widget == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
display = gtk_widget_get_display (point->widget);
|
2016-02-13 05:41:29 +00:00
|
|
|
seat = gdk_display_get_default_seat (display);
|
|
|
|
device = gdk_seat_get_pointer (seat);
|
2019-05-20 00:38:08 +00:00
|
|
|
surface = gtk_native_get_surface (gtk_widget_get_native (point->widget));
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2014-06-03 11:17:13 +00:00
|
|
|
if (!point->widget)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (point == &mouse_state)
|
|
|
|
{
|
|
|
|
if ((point->state & (GDK_BUTTON1_MASK << (button - 1))) == 0)
|
|
|
|
return;
|
|
|
|
|
Restructure the GdkEvent type hierarchy
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
2020-04-16 16:23:36 +00:00
|
|
|
ev = gdk_button_event_new (GDK_BUTTON_RELEASE,
|
2020-02-15 15:12:41 +00:00
|
|
|
surface,
|
|
|
|
device,
|
|
|
|
device,
|
|
|
|
NULL,
|
|
|
|
GDK_CURRENT_TIME,
|
|
|
|
point->x,
|
|
|
|
point->y,
|
|
|
|
button,
|
|
|
|
point->state);
|
2014-06-03 11:17:13 +00:00
|
|
|
|
|
|
|
point->state &= ~(GDK_BUTTON1_MASK << (button - 1));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Restructure the GdkEvent type hierarchy
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
2020-04-16 16:23:36 +00:00
|
|
|
ev = gdk_touch_event_new (GDK_TOUCH_END,
|
2020-02-15 15:12:41 +00:00
|
|
|
EVENT_SEQUENCE (point),
|
|
|
|
surface,
|
|
|
|
device,
|
|
|
|
device,
|
|
|
|
GDK_CURRENT_TIME,
|
|
|
|
point->state,
|
|
|
|
point->x,
|
|
|
|
point->y,
|
|
|
|
point == &touch_state[0]);
|
2014-06-03 11:17:13 +00:00
|
|
|
}
|
|
|
|
|
2020-02-09 15:54:26 +00:00
|
|
|
inject_event (ev);
|
2014-06-03 11:17:13 +00:00
|
|
|
|
2018-05-29 19:53:44 +00:00
|
|
|
g_object_unref (ev);
|
2014-05-27 23:15:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const gchar *
|
|
|
|
phase_nick (GtkPropagationPhase phase)
|
|
|
|
{
|
|
|
|
GTypeClass *class;
|
|
|
|
GEnumValue *value;
|
|
|
|
|
|
|
|
class = g_type_class_ref (GTK_TYPE_PROPAGATION_PHASE);
|
|
|
|
value = g_enum_get_value ((GEnumClass*)class, phase);
|
|
|
|
g_type_class_unref (class);
|
|
|
|
|
|
|
|
return value->value_nick;
|
|
|
|
}
|
|
|
|
|
2014-05-31 16:12:10 +00:00
|
|
|
static const gchar *
|
|
|
|
state_nick (GtkEventSequenceState state)
|
|
|
|
{
|
|
|
|
GTypeClass *class;
|
|
|
|
GEnumValue *value;
|
|
|
|
|
|
|
|
class = g_type_class_ref (GTK_TYPE_EVENT_SEQUENCE_STATE);
|
|
|
|
value = g_enum_get_value ((GEnumClass*)class, state);
|
|
|
|
g_type_class_unref (class);
|
|
|
|
|
|
|
|
return value->value_nick;
|
|
|
|
}
|
|
|
|
|
2014-05-27 23:15:40 +00:00
|
|
|
typedef struct {
|
2018-10-12 15:35:44 +00:00
|
|
|
GtkEventController *controller;
|
2014-05-27 23:15:40 +00:00
|
|
|
GString *str;
|
|
|
|
gboolean exit;
|
|
|
|
} LegacyData;
|
|
|
|
|
|
|
|
static gboolean
|
2018-10-12 15:35:44 +00:00
|
|
|
legacy_cb (GtkEventControllerLegacy *c, GdkEvent *button, gpointer data)
|
2014-05-27 23:15:40 +00:00
|
|
|
{
|
2018-01-16 04:56:14 +00:00
|
|
|
if (gdk_event_get_event_type (button) == GDK_BUTTON_PRESS)
|
|
|
|
{
|
|
|
|
LegacyData *ld = data;
|
2018-10-12 15:35:44 +00:00
|
|
|
GtkWidget *w;
|
|
|
|
|
|
|
|
w = gtk_event_controller_get_widget (ld->controller);
|
2018-01-16 04:56:14 +00:00
|
|
|
|
|
|
|
if (ld->str->len > 0)
|
|
|
|
g_string_append (ld->str, ", ");
|
|
|
|
g_string_append_printf (ld->str, "legacy %s", gtk_widget_get_name (w));
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2018-01-16 04:56:14 +00:00
|
|
|
return ld->exit;
|
|
|
|
}
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2018-01-16 04:56:14 +00:00
|
|
|
return GDK_EVENT_PROPAGATE;
|
2014-05-27 23:15:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GString *str;
|
|
|
|
GtkEventSequenceState state;
|
|
|
|
} GestureData;
|
|
|
|
|
|
|
|
static void
|
|
|
|
press_cb (GtkGesture *g, gint n_press, gdouble x, gdouble y, gpointer data)
|
|
|
|
{
|
|
|
|
GtkEventController *c = GTK_EVENT_CONTROLLER (g);
|
2014-06-04 11:35:16 +00:00
|
|
|
GdkEventSequence *sequence;
|
2014-05-27 23:15:40 +00:00
|
|
|
GtkPropagationPhase phase;
|
|
|
|
GestureData *gd = data;
|
2014-05-31 16:48:00 +00:00
|
|
|
const gchar *name;
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2014-05-31 16:48:00 +00:00
|
|
|
name = g_object_get_data (G_OBJECT (g), "name");
|
2014-05-27 23:15:40 +00:00
|
|
|
phase = gtk_event_controller_get_propagation_phase (c);
|
|
|
|
|
|
|
|
if (gd->str->len > 0)
|
|
|
|
g_string_append (gd->str, ", ");
|
2014-05-31 16:48:00 +00:00
|
|
|
g_string_append_printf (gd->str, "%s %s", phase_nick (phase), name);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2014-06-04 11:35:16 +00:00
|
|
|
sequence = gtk_gesture_get_last_updated_sequence (g);
|
|
|
|
|
|
|
|
if (sequence)
|
|
|
|
g_string_append_printf (gd->str, " (%x)", GPOINTER_TO_UINT (sequence));
|
|
|
|
|
2014-05-27 23:15:40 +00:00
|
|
|
if (gd->state != GTK_EVENT_SEQUENCE_NONE)
|
|
|
|
gtk_gesture_set_state (g, gd->state);
|
|
|
|
}
|
|
|
|
|
2014-05-31 16:12:10 +00:00
|
|
|
static void
|
|
|
|
cancel_cb (GtkGesture *g, GdkEventSequence *sequence, gpointer data)
|
|
|
|
{
|
|
|
|
GestureData *gd = data;
|
2014-05-31 16:48:00 +00:00
|
|
|
const gchar *name;
|
|
|
|
|
|
|
|
name = g_object_get_data (G_OBJECT (g), "name");
|
2014-05-31 16:12:10 +00:00
|
|
|
|
|
|
|
if (gd->str->len > 0)
|
|
|
|
g_string_append (gd->str, ", ");
|
2014-05-31 16:48:00 +00:00
|
|
|
g_string_append_printf (gd->str, "%s cancelled", name);
|
2014-05-31 16:12:10 +00:00
|
|
|
}
|
|
|
|
|
2014-06-04 11:35:16 +00:00
|
|
|
static void
|
|
|
|
begin_cb (GtkGesture *g, GdkEventSequence *sequence, gpointer data)
|
|
|
|
{
|
|
|
|
GestureData *gd = data;
|
|
|
|
const gchar *name;
|
|
|
|
|
|
|
|
name = g_object_get_data (G_OBJECT (g), "name");
|
|
|
|
|
|
|
|
if (gd->str->len > 0)
|
|
|
|
g_string_append (gd->str, ", ");
|
|
|
|
g_string_append_printf (gd->str, "%s began", name);
|
|
|
|
|
|
|
|
if (gd->state != GTK_EVENT_SEQUENCE_NONE)
|
|
|
|
gtk_gesture_set_state (g, gd->state);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
end_cb (GtkGesture *g, GdkEventSequence *sequence, gpointer data)
|
|
|
|
{
|
|
|
|
GestureData *gd = data;
|
|
|
|
const gchar *name;
|
|
|
|
|
|
|
|
name = g_object_get_data (G_OBJECT (g), "name");
|
|
|
|
|
|
|
|
if (gd->str->len > 0)
|
|
|
|
g_string_append (gd->str, ", ");
|
|
|
|
g_string_append_printf (gd->str, "%s ended", name);
|
|
|
|
}
|
|
|
|
|
2014-06-03 14:11:24 +00:00
|
|
|
static void
|
|
|
|
update_cb (GtkGesture *g, GdkEventSequence *sequence, gpointer data)
|
|
|
|
{
|
|
|
|
GestureData *gd = data;
|
|
|
|
const gchar *name;
|
|
|
|
|
|
|
|
name = g_object_get_data (G_OBJECT (g), "name");
|
|
|
|
|
|
|
|
if (gd->str->len > 0)
|
|
|
|
g_string_append (gd->str, ", ");
|
|
|
|
g_string_append_printf (gd->str, "%s updated", name);
|
|
|
|
}
|
|
|
|
|
2014-05-31 16:12:10 +00:00
|
|
|
static void
|
|
|
|
state_changed_cb (GtkGesture *g, GdkEventSequence *sequence, GtkEventSequenceState state, gpointer data)
|
|
|
|
{
|
|
|
|
GestureData *gd = data;
|
2014-05-31 16:48:00 +00:00
|
|
|
const gchar *name;
|
|
|
|
|
|
|
|
name = g_object_get_data (G_OBJECT (g), "name");
|
2014-05-31 16:12:10 +00:00
|
|
|
|
|
|
|
if (gd->str->len > 0)
|
|
|
|
g_string_append (gd->str, ", ");
|
2014-05-31 16:48:00 +00:00
|
|
|
g_string_append_printf (gd->str, "%s state %s", name, state_nick (state));
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
if (sequence != NULL)
|
|
|
|
g_string_append_printf (gd->str, " (%x)", GPOINTER_TO_UINT (sequence));
|
2014-05-31 16:12:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-27 23:15:40 +00:00
|
|
|
static GtkGesture *
|
2014-05-31 16:48:00 +00:00
|
|
|
add_gesture (GtkWidget *w, const gchar *name, GtkPropagationPhase phase, GString *str, GtkEventSequenceState state)
|
2014-05-27 23:15:40 +00:00
|
|
|
{
|
|
|
|
GtkGesture *g;
|
|
|
|
GestureData *data;
|
|
|
|
|
|
|
|
data = g_new (GestureData, 1);
|
|
|
|
data->str = str;
|
|
|
|
data->state = state;
|
|
|
|
|
2019-05-29 17:10:46 +00:00
|
|
|
g = gtk_gesture_click_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (g), FALSE);
|
|
|
|
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (g), 1);
|
|
|
|
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (g), phase);
|
2018-03-09 05:14:59 +00:00
|
|
|
gtk_widget_add_controller (w, GTK_EVENT_CONTROLLER (g));
|
2014-05-31 16:48:00 +00:00
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (g), "name", (gpointer)name);
|
|
|
|
|
2014-05-27 23:15:40 +00:00
|
|
|
g_signal_connect (g, "pressed", G_CALLBACK (press_cb), data);
|
2014-05-31 16:12:10 +00:00
|
|
|
g_signal_connect (g, "cancel", G_CALLBACK (cancel_cb), data);
|
2014-06-03 14:11:24 +00:00
|
|
|
g_signal_connect (g, "update", G_CALLBACK (update_cb), data);
|
2014-05-31 16:12:10 +00:00
|
|
|
g_signal_connect (g, "sequence-state-changed", G_CALLBACK (state_changed_cb), data);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
2014-06-04 11:35:16 +00:00
|
|
|
static GtkGesture *
|
|
|
|
add_mt_gesture (GtkWidget *w, const gchar *name, GtkPropagationPhase phase, GString *str, GtkEventSequenceState state)
|
|
|
|
{
|
|
|
|
GtkGesture *g;
|
|
|
|
GestureData *data;
|
|
|
|
|
|
|
|
data = g_new (GestureData, 1);
|
|
|
|
data->str = str;
|
|
|
|
data->state = state;
|
|
|
|
|
2018-03-08 22:36:41 +00:00
|
|
|
g = gtk_gesture_rotate_new ();
|
2014-06-04 11:35:16 +00:00
|
|
|
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (g), phase);
|
2018-03-08 22:36:41 +00:00
|
|
|
gtk_widget_add_controller (w, GTK_EVENT_CONTROLLER (g));
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (g), "name", (gpointer)name);
|
|
|
|
|
|
|
|
g_signal_connect (g, "begin", G_CALLBACK (begin_cb), data);
|
|
|
|
g_signal_connect (g, "update", G_CALLBACK (update_cb), data);
|
|
|
|
g_signal_connect (g, "end", G_CALLBACK (end_cb), data);
|
|
|
|
g_signal_connect (g, "sequence-state-changed", G_CALLBACK (state_changed_cb), data);
|
|
|
|
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
2014-05-27 23:15:40 +00:00
|
|
|
static void
|
|
|
|
add_legacy (GtkWidget *w, GString *str, gboolean exit)
|
|
|
|
{
|
|
|
|
LegacyData *data;
|
|
|
|
|
|
|
|
data = g_new (LegacyData, 1);
|
2018-10-12 15:35:44 +00:00
|
|
|
data->controller = gtk_event_controller_legacy_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
data->str = str;
|
|
|
|
data->exit = exit;
|
2018-10-12 15:35:44 +00:00
|
|
|
|
2018-10-15 15:29:32 +00:00
|
|
|
gtk_event_controller_set_propagation_phase (data->controller, GTK_PHASE_BUBBLE);
|
2018-10-12 15:35:44 +00:00
|
|
|
gtk_widget_add_controller (w, data->controller);
|
|
|
|
g_signal_connect (data->controller, "event", G_CALLBACK (legacy_cb), data);
|
2014-05-27 23:15:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_phases (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
2014-05-31 16:48:00 +00:00
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
2017-07-19 18:57:04 +00:00
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
2014-05-31 16:54:36 +00:00
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c2, "
|
|
|
|
"bubble c3, "
|
|
|
|
"bubble b3, "
|
|
|
|
"bubble a3");
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-05-27 23:15:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_mixed (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
2018-10-15 15:29:32 +00:00
|
|
|
add_legacy (A, str, GDK_EVENT_PROPAGATE);
|
|
|
|
add_legacy (B, str, GDK_EVENT_PROPAGATE);
|
|
|
|
add_legacy (C, str, GDK_EVENT_PROPAGATE);
|
|
|
|
|
2014-05-31 16:48:00 +00:00
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
2017-07-19 18:57:04 +00:00
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
2014-05-31 16:54:36 +00:00
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c2, "
|
|
|
|
"bubble c3, "
|
2017-10-12 12:22:04 +00:00
|
|
|
"legacy C, "
|
2014-05-31 16:54:36 +00:00
|
|
|
"bubble b3, "
|
2017-10-12 12:22:04 +00:00
|
|
|
"legacy B, "
|
|
|
|
"bubble a3, "
|
|
|
|
"legacy A");
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-05-27 23:15:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_early_exit (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
2018-10-15 15:29:32 +00:00
|
|
|
add_legacy (A, str, GDK_EVENT_PROPAGATE);
|
|
|
|
add_legacy (B, str, GDK_EVENT_STOP);
|
|
|
|
add_legacy (C, str, GDK_EVENT_PROPAGATE);
|
|
|
|
|
2014-05-31 16:48:00 +00:00
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
2017-07-19 18:57:04 +00:00
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
2014-05-31 16:54:36 +00:00
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c2, "
|
|
|
|
"bubble c3, "
|
2017-10-12 12:22:04 +00:00
|
|
|
"legacy C, "
|
|
|
|
"bubble b3, "
|
2014-05-31 16:54:36 +00:00
|
|
|
"legacy B");
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-05-27 23:15:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-05-31 22:46:43 +00:00
|
|
|
test_claim_capture (void)
|
2014-05-27 23:15:40 +00:00
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-05-27 23:15:40 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
2014-05-31 16:48:00 +00:00
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
2017-07-19 18:57:04 +00:00
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-05-31 16:48:00 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
2014-05-31 16:54:36 +00:00
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"c1 state claimed");
|
2014-05-31 16:48:00 +00:00
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-05-31 16:48:00 +00:00
|
|
|
}
|
|
|
|
|
2014-05-31 22:46:43 +00:00
|
|
|
static void
|
|
|
|
test_claim_target (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-05-31 22:46:43 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-05-31 22:46:43 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-05-31 22:46:43 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-05-31 22:46:43 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-05-31 22:46:43 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-05-31 22:46:43 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c2, "
|
|
|
|
"c2 state claimed");
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-05-31 22:46:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_claim_bubble (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-05-31 22:46:43 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-05-31 22:46:43 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-05-31 22:46:43 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-05-31 22:46:43 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-05-31 22:46:43 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_gesture (C, "c3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-05-31 22:46:43 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c2, "
|
|
|
|
"bubble c3, "
|
|
|
|
"bubble b3, "
|
|
|
|
"c3 cancelled, "
|
|
|
|
"c2 cancelled, "
|
|
|
|
"c1 cancelled, "
|
|
|
|
"b3 state claimed"
|
|
|
|
);
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-05-31 22:46:43 +00:00
|
|
|
}
|
|
|
|
|
2014-06-03 12:15:14 +00:00
|
|
|
static void
|
|
|
|
test_early_claim_capture (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GtkGesture *g;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-06-03 12:15:14 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-06-03 12:15:14 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-06-03 12:15:14 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-06-03 12:15:14 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-06-03 12:15:14 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
g = add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-06-03 12:15:14 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"b1 state claimed");
|
|
|
|
|
|
|
|
/* Reset the string */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
|
|
|
|
gtk_gesture_set_state (g, GTK_EVENT_SEQUENCE_DENIED);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture c1, "
|
|
|
|
"c1 state claimed, "
|
|
|
|
"b1 state denied");
|
|
|
|
|
|
|
|
point_release (&mouse_state, 1);
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-06-03 12:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_late_claim_capture (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GtkGesture *g;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-06-03 12:15:14 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-06-03 12:15:14 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-06-03 12:15:14 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-06-03 12:15:14 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-06-03 12:15:14 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
g = add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-06-03 12:15:14 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c2, "
|
|
|
|
"c2 state claimed");
|
|
|
|
|
|
|
|
/* Reset the string */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
|
|
|
|
gtk_gesture_set_state (g, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c2 cancelled, "
|
|
|
|
"c1 cancelled, "
|
|
|
|
"b1 state claimed");
|
|
|
|
|
|
|
|
point_release (&mouse_state, 1);
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-06-03 12:15:14 +00:00
|
|
|
}
|
|
|
|
|
2014-05-31 16:48:00 +00:00
|
|
|
static void
|
|
|
|
test_group (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
|
|
|
GtkGesture *g1, *g2;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-05-31 16:48:00 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-05-31 16:48:00 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-05-31 16:48:00 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-05-31 16:48:00 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-05-31 16:48:00 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
g1 = add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
g2 = add_gesture (C, "c3", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
gtk_gesture_group (g1, g2);
|
|
|
|
add_gesture (A, "a3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b3", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c4", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
2014-05-31 16:54:36 +00:00
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c3, "
|
|
|
|
"c3 state claimed, "
|
2014-06-01 19:44:55 +00:00
|
|
|
"c2 state claimed, "
|
2014-05-31 16:54:36 +00:00
|
|
|
"target c2");
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-05-27 23:15:40 +00:00
|
|
|
}
|
|
|
|
|
2014-06-03 13:09:16 +00:00
|
|
|
static void
|
|
|
|
test_gestures_outside_grab (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C, *D;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-06-03 13:09:16 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-06-03 13:09:16 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-06-03 13:09:16 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-06-03 13:09:16 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-06-03 13:09:16 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
D = gtk_window_new ();
|
2014-06-03 13:09:16 +00:00
|
|
|
gtk_widget_show (D);
|
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_gesture (B, "b2", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a2", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-06-03 13:09:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c2, "
|
|
|
|
"c2 state claimed");
|
|
|
|
|
|
|
|
/* Set a grab on another window */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
gtk_grab_add (D);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c1 cancelled, "
|
|
|
|
"c2 cancelled, "
|
|
|
|
"b1 cancelled, "
|
|
|
|
"a1 cancelled");
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
|
|
|
gtk_window_destroy (D);
|
2014-06-03 13:09:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_gestures_inside_grab (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-06-03 13:09:16 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-06-03 13:09:16 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-06-03 13:09:16 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-06-03 13:09:16 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-06-03 13:09:16 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (C, "c2", GTK_PHASE_TARGET, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_gesture (B, "b2", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (A, "a2", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&mouse_state, A, 1);
|
2014-06-03 13:09:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture a1, "
|
|
|
|
"capture b1, "
|
|
|
|
"capture c1, "
|
|
|
|
"target c2, "
|
|
|
|
"c2 state claimed");
|
|
|
|
|
|
|
|
/* Set a grab on B */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
gtk_grab_add (B);
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"a1 cancelled");
|
|
|
|
|
|
|
|
/* Update with the grab under effect */
|
|
|
|
g_string_erase (str, 0, str->len);
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&mouse_state, A, allocation.x, allocation.y);
|
2014-06-03 13:09:16 +00:00
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"b1 updated, "
|
|
|
|
"c1 updated, "
|
|
|
|
"c2 updated");
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-06-03 13:09:16 +00:00
|
|
|
}
|
|
|
|
|
2014-06-04 11:35:16 +00:00
|
|
|
static void
|
|
|
|
test_multitouch_on_single (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-06-04 11:35:16 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-06-04 11:35:16 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-06-04 11:35:16 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_NONE);
|
|
|
|
add_gesture (B, "b1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
2017-07-19 18:57:04 +00:00
|
|
|
|
2014-06-04 11:35:16 +00:00
|
|
|
/* First touch down */
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[0], A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&touch_state[0], A, 1);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture a1 (1), "
|
|
|
|
"capture b1 (1), "
|
|
|
|
"b1 state claimed (1)");
|
|
|
|
|
|
|
|
/* Second touch down */
|
|
|
|
g_string_erase (str, 0, str->len);
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[1], A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&touch_state[1], A, 1);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"a1 state denied (2), "
|
|
|
|
"b1 state denied (2)");
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-06-04 11:35:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_multitouch_activation (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-06-04 11:35:16 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-06-04 11:35:16 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-06-04 11:35:16 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
add_mt_gesture (C, "c1", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
/* First touch down */
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[0], A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&touch_state[0], A, 1);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==, "");
|
|
|
|
|
|
|
|
/* Second touch down */
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[1], A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&touch_state[1], A, 1);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c1 began, "
|
|
|
|
"c1 state claimed (2), "
|
2017-10-12 12:25:53 +00:00
|
|
|
"c1 state claimed (1)");
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
/* First touch up */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
point_release (&touch_state[0], 1);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c1 ended");
|
|
|
|
|
|
|
|
/* A third touch down triggering again action */
|
|
|
|
g_string_erase (str, 0, str->len);
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[2], A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&touch_state[2], A, 1);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c1 began, "
|
|
|
|
"c1 state claimed (3)");
|
|
|
|
|
|
|
|
/* One touch up, gesture is finished again */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
point_release (&touch_state[2], 1);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c1 ended");
|
|
|
|
|
|
|
|
/* Another touch up, gesture remains inactive */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
point_release (&touch_state[1], 1);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==, "");
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-06-04 11:35:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_multitouch_interaction (void)
|
|
|
|
{
|
|
|
|
GtkWidget *A, *B, *C;
|
|
|
|
GtkGesture *g;
|
|
|
|
GString *str;
|
2017-07-19 18:57:04 +00:00
|
|
|
GtkAllocation allocation;
|
2014-06-04 11:35:16 +00:00
|
|
|
|
2020-02-14 19:55:36 +00:00
|
|
|
A = gtk_window_new ();
|
2014-06-04 11:35:16 +00:00
|
|
|
gtk_widget_set_name (A, "A");
|
|
|
|
B = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
|
gtk_widget_set_name (B, "B");
|
2017-08-02 15:58:17 +00:00
|
|
|
C = gtk_image_new ();
|
2014-06-04 11:35:16 +00:00
|
|
|
gtk_widget_set_hexpand (C, TRUE);
|
|
|
|
gtk_widget_set_vexpand (C, TRUE);
|
|
|
|
gtk_widget_set_name (C, "C");
|
|
|
|
|
2020-05-09 12:26:52 +00:00
|
|
|
gtk_box_append (GTK_BOX (A), B);
|
|
|
|
gtk_box_append (GTK_BOX (B), C);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
2017-01-19 09:02:04 +00:00
|
|
|
gtk_widget_show (A);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
str = g_string_new ("");
|
|
|
|
|
|
|
|
g = add_gesture (A, "a1", GTK_PHASE_CAPTURE, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
|
|
|
add_mt_gesture (C, "c1", GTK_PHASE_BUBBLE, str, GTK_EVENT_SEQUENCE_CLAIMED);
|
2020-02-10 15:24:03 +00:00
|
|
|
gtk_widget_get_allocation (B, &allocation);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
/* First touch down, a1 claims the sequence */
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[0], A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&touch_state[0], A, 1);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"capture a1 (1), "
|
|
|
|
"a1 state claimed (1)");
|
|
|
|
|
|
|
|
/* Second touch down, a1 denies and c1 takes over */
|
|
|
|
g_string_erase (str, 0, str->len);
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[1], A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&touch_state[1], A, 1);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
/* Denying sequences in touch-excess situation is a responsibility of the caller */
|
|
|
|
gtk_gesture_set_state (g, GTK_EVENT_SEQUENCE_DENIED);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"a1 state denied (2), "
|
|
|
|
"c1 began, "
|
2017-10-12 12:25:53 +00:00
|
|
|
"c1 state claimed (1), "
|
2014-06-04 11:35:16 +00:00
|
|
|
"c1 state claimed (2), "
|
|
|
|
"a1 state denied (1)");
|
|
|
|
|
|
|
|
/* Move first point, only c1 should update */
|
|
|
|
g_string_erase (str, 0, str->len);
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[0], A, allocation.x, allocation.y);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c1 updated");
|
|
|
|
|
|
|
|
/* First touch up */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
point_release (&touch_state[0], 1);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c1 ended");
|
|
|
|
|
|
|
|
/* A third touch down triggering again action on c1 */
|
|
|
|
g_string_erase (str, 0, str->len);
|
2020-02-10 15:24:03 +00:00
|
|
|
point_update (&touch_state[2], A, allocation.x, allocation.y);
|
2017-07-19 18:57:04 +00:00
|
|
|
point_press (&touch_state[2], A, 1);
|
2014-06-04 11:35:16 +00:00
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"a1 state denied (3), "
|
|
|
|
"c1 began, "
|
|
|
|
"c1 state claimed (3)");
|
|
|
|
|
|
|
|
/* One touch up, gesture is finished again */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
point_release (&touch_state[2], 1);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==,
|
|
|
|
"c1 ended");
|
|
|
|
|
|
|
|
/* Another touch up, gesture remains inactive */
|
|
|
|
g_string_erase (str, 0, str->len);
|
|
|
|
point_release (&touch_state[1], 1);
|
|
|
|
|
|
|
|
g_assert_cmpstr (str->str, ==, "");
|
|
|
|
|
|
|
|
g_string_free (str, TRUE);
|
|
|
|
|
2020-05-09 14:33:02 +00:00
|
|
|
gtk_window_destroy (A);
|
2014-06-04 11:35:16 +00:00
|
|
|
}
|
|
|
|
|
2014-05-27 23:15:40 +00:00
|
|
|
int
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
{
|
|
|
|
gtk_test_init (&argc, &argv);
|
|
|
|
|
|
|
|
g_test_add_func ("/gestures/propagation/phases", test_phases);
|
|
|
|
g_test_add_func ("/gestures/propagation/mixed", test_mixed);
|
|
|
|
g_test_add_func ("/gestures/propagation/early-exit", test_early_exit);
|
2014-06-03 18:22:55 +00:00
|
|
|
g_test_add_func ("/gestures/claim/capture", test_claim_capture);
|
|
|
|
g_test_add_func ("/gestures/claim/target", test_claim_target);
|
|
|
|
g_test_add_func ("/gestures/claim/bubble", test_claim_bubble);
|
|
|
|
g_test_add_func ("/gestures/claim/early-capture", test_early_claim_capture);
|
|
|
|
g_test_add_func ("/gestures/claim/late-capture", test_late_claim_capture);
|
|
|
|
g_test_add_func ("/gestures/group", test_group);
|
|
|
|
g_test_add_func ("/gestures/grabs/gestures-outside-grab", test_gestures_outside_grab);
|
|
|
|
g_test_add_func ("/gestures/grabs/gestures-inside-grab", test_gestures_inside_grab);
|
2014-06-04 11:35:16 +00:00
|
|
|
g_test_add_func ("/gestures/multitouch/gesture-single", test_multitouch_on_single);
|
|
|
|
g_test_add_func ("/gestures/multitouch/multitouch-activation", test_multitouch_activation);
|
|
|
|
g_test_add_func ("/gestures/multitouch/interaction", test_multitouch_interaction);
|
2014-05-27 23:15:40 +00:00
|
|
|
|
|
|
|
return g_test_run ();
|
|
|
|
}
|