static void gtk_gesture_multi_press_class_init (GtkGestureMultiPressClass *klass) { GtkEventControllerClass *controller_class = GTK_EVENT_CONTROLLER_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkGestureClass *gesture_class = GTK_GESTURE_CLASS (klass); object_class->finalize = gtk_gesture_multi_press_finalize; gesture_class->check = gtk_gesture_multi_press_check; gesture_class->begin = gtk_gesture_multi_press_begin; gesture_class->update = gtk_gesture_multi_press_update; gesture_class->end = gtk_gesture_multi_press_end; gesture_class->cancel = gtk_gesture_multi_press_cancel; controller_class->reset = gtk_gesture_multi_press_reset; /** * GtkGestureMultiPress::pressed: * @gesture: the object which received the signal * @n_press: how many touch/button presses happened with this one * @x: The X coordinate, in widget allocation coordinates * @y: The Y coordinate, in widget allocation coordinates * * This signal is emitted whenever a button or touch press happens. * * Since: 3.14 */ signals[PRESSED] = g_signal_new (I_("pressed"), G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkGestureMultiPressClass, pressed), NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_DOUBLE); /** * GtkGestureMultiPress::released: * @gesture: the object which received the signal * @n_press: number of press that is paired with this release * @x: The X coordinate, in widget allocation coordinates * @y: The Y coordinate, in widget allocation coordinates * * This signal is emitted when a button or touch is released. @n_press * will report the number of press that is paired to this event, note * that #GtkGestureMultiPress::stopped may have been emitted between the * press and its release, @n_press will only start over at the next press. * * Since: 3.14 */ signals[RELEASED] = g_signal_new (I_("released"), G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkGestureMultiPressClass, released), NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_DOUBLE); /** * GtkGestureMultiPress::stopped: * @gesture: the object which received the signal * * This signal is emitted whenever any time/distance threshold has * been exceeded. * * Since: 3.14 */ signals[STOPPED] = g_signal_new (I_("stopped"), G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkGestureMultiPressClass, stopped), NULL, NULL, NULL, G_TYPE_NONE, 0); }
static void gtk_gesture_single_class_init (GtkGestureSingleClass *klass) { GtkEventControllerClass *controller_class = GTK_EVENT_CONTROLLER_CLASS (klass); GtkGestureClass *gesture_class = GTK_GESTURE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = gtk_gesture_single_get_property; object_class->set_property = gtk_gesture_single_set_property; controller_class->handle_event = gtk_gesture_single_handle_event; gesture_class->cancel = gtk_gesture_single_cancel; /** * GtkGestureSingle:touch-only: * * Whether the gesture handles only touch events. * * Since: 3.14 */ g_object_class_install_property (object_class, PROP_TOUCH_ONLY, g_param_spec_boolean ("touch-only", P_("Handle only touch events"), P_("Whether the gesture handles" " only touch events"), FALSE, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); /** * GtkGestureSingle:exclusive: * * Whether the gesture is exclusive. Exclusive gestures only listen to pointer * and pointer emulated events. * * Since: 3.14 */ g_object_class_install_property (object_class, PROP_EXCLUSIVE, g_param_spec_boolean ("exclusive", P_("Whether the gesture is exclusive"), P_("Whether the gesture is exclusive"), FALSE, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); /** * GtkGestureSingle:button: * * Mouse button number to listen to, or 0 to listen for any button. * * Since: 3.14 */ g_object_class_install_property (object_class, PROP_BUTTON, g_param_spec_uint ("button", P_("Button number"), P_("Button number to listen to"), 0, G_MAXUINT, GDK_BUTTON_PRIMARY, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); }
static void gtk_gesture_multi_press_reset (GtkEventController *controller) { _gtk_gesture_multi_press_stop (GTK_GESTURE_MULTI_PRESS (controller)); GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_multi_press_parent_class)->reset (controller); }
static gboolean gtk_gesture_single_handle_event (GtkEventController *controller, const GdkEvent *event) { GdkEventSequence *sequence = NULL; GtkGestureSinglePrivate *priv; GdkDevice *source_device; GdkInputSource source; guint button = 0, i; gboolean retval, test_touchscreen = FALSE; source_device = gdk_event_get_source_device (event); if (!source_device) return FALSE; priv = gtk_gesture_single_get_instance_private (GTK_GESTURE_SINGLE (controller)); source = gdk_device_get_source (source_device); if (source != GDK_SOURCE_TOUCHSCREEN) test_touchscreen = gtk_simulate_touchscreen (); switch (event->type) { case GDK_TOUCH_BEGIN: case GDK_TOUCH_END: case GDK_TOUCH_UPDATE: if (priv->exclusive && !event->touch.emulating_pointer) return FALSE; sequence = event->touch.sequence; button = 1; break; case GDK_BUTTON_PRESS: case GDK_BUTTON_RELEASE: if (priv->touch_only && !test_touchscreen && source != GDK_SOURCE_TOUCHSCREEN) return FALSE; button = event->button.button; break; case GDK_MOTION_NOTIFY: if (!gtk_gesture_handles_sequence (GTK_GESTURE (controller), sequence)) return FALSE; if (priv->touch_only && !test_touchscreen && source != GDK_SOURCE_TOUCHSCREEN) return FALSE; if (priv->current_button > 0 && priv->current_button <= 5 && (event->motion.state & (GDK_BUTTON1_MASK << (priv->current_button - 1)))) button = priv->current_button; else if (priv->current_button == 0) { /* No current button, find out from the mask */ for (i = 0; i < 3; i++) { if ((event->motion.state & (GDK_BUTTON1_MASK << i)) == 0) continue; button = i + 1; break; } } break; case GDK_TOUCH_CANCEL: case GDK_GRAB_BROKEN: return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller, event); break; default: return FALSE; } if (button == 0 || (priv->button != 0 && priv->button != button) || (priv->current_button != 0 && priv->current_button != button)) { if (gtk_gesture_is_active (GTK_GESTURE (controller))) gtk_event_controller_reset (controller); return FALSE; } if (event->type == GDK_BUTTON_PRESS || event->type == GDK_TOUCH_BEGIN || event->type == GDK_MOTION_NOTIFY || event->type == GDK_TOUCH_UPDATE) { if (!gtk_gesture_is_active (GTK_GESTURE (controller))) priv->current_sequence = sequence; priv->current_button = button; } retval = GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller, event); if (sequence == priv->current_sequence && (event->type == GDK_BUTTON_RELEASE || event->type == GDK_TOUCH_END)) priv->current_button = 0; else if (priv->current_sequence == sequence && !gtk_gesture_handles_sequence (GTK_GESTURE (controller), sequence)) { if (button == priv->current_button && event->type == GDK_BUTTON_PRESS) priv->current_button = 0; else if (sequence == priv->current_sequence && event->type == GDK_TOUCH_BEGIN) priv->current_sequence = NULL; } return retval; }