358 lines
12 KiB
Diff
358 lines
12 KiB
Diff
From 2a2e870c139e2130b00d582546616269bca27458 Mon Sep 17 00:00:00 2001
|
|
From: Carlos Garnacho <carlosg@gnome.org>
|
|
Date: Fri, 4 Sep 2020 17:11:36 +0200
|
|
Subject: [PATCH] clutter: Backport of ::touch-mode
|
|
|
|
In upstream/master this is a ClutterSeat readonly property. Add it to
|
|
ClutterDeviceManager here, the mechanism and triggering is the same
|
|
though.
|
|
---
|
|
clutter/clutter/clutter-device-manager.c | 24 +++
|
|
clutter/clutter/clutter-device-manager.h | 2 +
|
|
.../evdev/clutter-device-manager-evdev.c | 179 ++++++++++++++++++
|
|
3 files changed, 205 insertions(+)
|
|
|
|
diff --git a/clutter/clutter/clutter-device-manager.c b/clutter/clutter/clutter-device-manager.c
|
|
index c676384..e1cc455 100644
|
|
--- a/clutter/clutter/clutter-device-manager.c
|
|
+++ b/clutter/clutter/clutter-device-manager.c
|
|
@@ -62,6 +62,7 @@ enum
|
|
PROP_0,
|
|
|
|
PROP_BACKEND,
|
|
+ PROP_TOUCH_MODE,
|
|
|
|
PROP_LAST
|
|
};
|
|
@@ -108,6 +109,7 @@ clutter_device_manager_set_property (GObject *gobject,
|
|
priv->backend = g_value_get_object (value);
|
|
break;
|
|
|
|
+ case PROP_TOUCH_MODE:
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
}
|
|
@@ -127,6 +129,10 @@ clutter_device_manager_get_property (GObject *gobject,
|
|
g_value_set_object (value, priv->backend);
|
|
break;
|
|
|
|
+ case PROP_TOUCH_MODE:
|
|
+ g_value_set_boolean (value, FALSE);
|
|
+ break;
|
|
+
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
}
|
|
@@ -143,6 +149,12 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
|
P_("The ClutterBackend of the device manager"),
|
|
CLUTTER_TYPE_BACKEND,
|
|
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
+ obj_props[PROP_TOUCH_MODE] =
|
|
+ g_param_spec_boolean ("touch-mode",
|
|
+ P_("Touch mode"),
|
|
+ P_("Touch mode"),
|
|
+ FALSE,
|
|
+ CLUTTER_PARAM_READABLE);
|
|
|
|
gobject_class->set_property = clutter_device_manager_set_property;
|
|
gobject_class->get_property = clutter_device_manager_get_property;
|
|
@@ -579,3 +591,15 @@ clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_man
|
|
|
|
*settings = device_manager->priv->kbd_a11y_settings;
|
|
}
|
|
+
|
|
+gboolean
|
|
+clutter_device_manager_get_touch_mode (ClutterDeviceManager *device_manager)
|
|
+{
|
|
+ gboolean touch_mode;
|
|
+
|
|
+ g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), FALSE);
|
|
+
|
|
+ g_object_get (G_OBJECT (device_manager), "touch-mode", &touch_mode, NULL);
|
|
+
|
|
+ return touch_mode;
|
|
+}
|
|
diff --git a/clutter/clutter/clutter-device-manager.h b/clutter/clutter/clutter-device-manager.h
|
|
index 1cbf030..a4a6271 100644
|
|
--- a/clutter/clutter/clutter-device-manager.h
|
|
+++ b/clutter/clutter/clutter-device-manager.h
|
|
@@ -155,6 +155,8 @@ void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *devic
|
|
CLUTTER_EXPORT
|
|
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
|
ClutterKbdA11ySettings *settings);
|
|
+CLUTTER_EXPORT
|
|
+gboolean clutter_device_manager_get_touch_mode (ClutterDeviceManager *device_manager);
|
|
|
|
G_END_DECLS
|
|
|
|
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c
|
|
index 84b0aad..78b5b64 100644
|
|
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
|
|
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
|
|
@@ -108,6 +108,19 @@ struct _ClutterDeviceManagerEvdevPrivate
|
|
|
|
gint device_id_next;
|
|
GList *free_device_ids;
|
|
+
|
|
+ guint tablet_mode_switch_state : 1;
|
|
+ guint has_touchscreen : 1;
|
|
+ guint has_tablet_switch : 1;
|
|
+ guint has_pointer : 1;
|
|
+ guint touch_mode : 1;
|
|
+};
|
|
+
|
|
+enum
|
|
+{
|
|
+ PROP_0,
|
|
+ PROP_TOUCH_MODE,
|
|
+ N_PROPS
|
|
};
|
|
|
|
static void clutter_device_manager_evdev_event_extender_init (ClutterEventExtenderInterface *iface);
|
|
@@ -765,6 +778,34 @@ clutter_event_source_free (ClutterEventSource *source)
|
|
g_source_unref (g_source);
|
|
}
|
|
|
|
+static void
|
|
+update_touch_mode (ClutterDeviceManagerEvdev *manager_evdev)
|
|
+{
|
|
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
|
+ gboolean touch_mode;
|
|
+
|
|
+ /* No touch mode if we don't have a touchscreen, easy */
|
|
+ if (!priv->has_touchscreen)
|
|
+ touch_mode = FALSE;
|
|
+ /* If we have a tablet mode switch, honor it being unset */
|
|
+ else if (priv->has_tablet_switch && !priv->tablet_mode_switch_state)
|
|
+ touch_mode = FALSE;
|
|
+ /* If tablet mode is enabled, go for it */
|
|
+ else if (priv->has_tablet_switch && priv->tablet_mode_switch_state)
|
|
+ touch_mode = TRUE;
|
|
+ /* If there is no tablet mode switch (eg. kiosk machines),
|
|
+ * assume touch-mode is mutually exclusive with pointers.
|
|
+ */
|
|
+ else
|
|
+ touch_mode = !priv->has_pointer;
|
|
+
|
|
+ if (priv->touch_mode != touch_mode)
|
|
+ {
|
|
+ priv->touch_mode = touch_mode;
|
|
+ g_object_notify (G_OBJECT (manager_evdev), "touch-mode");
|
|
+ }
|
|
+}
|
|
+
|
|
static void
|
|
evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
|
|
struct libinput_device *libinput_device)
|
|
@@ -942,19 +983,81 @@ flush_event_queue (void)
|
|
}
|
|
}
|
|
|
|
+static gboolean
|
|
+has_touchscreen (ClutterDeviceManagerEvdev *manager_evdev)
|
|
+{
|
|
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
|
+ GSList *l;
|
|
+
|
|
+ for (l = priv->devices; l; l = l->next)
|
|
+ {
|
|
+ ClutterInputDeviceType device_type;
|
|
+
|
|
+ device_type = clutter_input_device_get_device_type (l->data);
|
|
+
|
|
+ if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+device_type_is_pointer (ClutterInputDeviceType device_type)
|
|
+{
|
|
+ return (device_type == CLUTTER_POINTER_DEVICE ||
|
|
+ device_type == CLUTTER_TOUCHPAD_DEVICE);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+has_pointer (ClutterDeviceManagerEvdev *manager_evdev)
|
|
+{
|
|
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
|
+ GSList *l;
|
|
+
|
|
+ for (l = priv->devices; l; l = l->next)
|
|
+ {
|
|
+ ClutterInputDeviceType device_type;
|
|
+
|
|
+ device_type = clutter_input_device_get_device_type (l->data);
|
|
+
|
|
+ if (device_type_is_pointer (device_type))
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
static gboolean
|
|
process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
|
|
struct libinput_event *event)
|
|
{
|
|
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
|
ClutterInputDevice *device;
|
|
struct libinput_device *libinput_device;
|
|
gboolean handled = TRUE;
|
|
+ gboolean check_touch_mode;
|
|
|
|
switch (libinput_event_get_type (event))
|
|
{
|
|
case LIBINPUT_EVENT_DEVICE_ADDED:
|
|
libinput_device = libinput_event_get_device (event);
|
|
|
|
+ priv->has_touchscreen |=
|
|
+ libinput_device_has_capability (libinput_device, LIBINPUT_DEVICE_CAP_TOUCH);
|
|
+ priv->has_pointer |=
|
|
+ libinput_device_has_capability (libinput_device, LIBINPUT_DEVICE_CAP_POINTER);
|
|
+ check_touch_mode = priv->has_touchscreen | priv->has_pointer;
|
|
+
|
|
+ if (libinput_device_has_capability (libinput_device,
|
|
+ LIBINPUT_DEVICE_CAP_SWITCH) &&
|
|
+ libinput_device_switch_has_switch (libinput_device,
|
|
+ LIBINPUT_SWITCH_TABLET_MODE))
|
|
+ {
|
|
+ priv->has_tablet_switch = TRUE;
|
|
+ check_touch_mode = TRUE;
|
|
+ }
|
|
+
|
|
evdev_add_device (manager_evdev, libinput_device);
|
|
break;
|
|
|
|
@@ -966,7 +1069,17 @@ process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
|
|
|
|
libinput_device = libinput_event_get_device (event);
|
|
|
|
+ check_touch_mode =
|
|
+ libinput_device_has_capability (libinput_device, LIBINPUT_DEVICE_CAP_TOUCH);
|
|
device = libinput_device_get_user_data (libinput_device);
|
|
+ if (check_touch_mode)
|
|
+ priv->has_touchscreen = has_touchscreen (manager_evdev);
|
|
+ if (device_type_is_pointer (clutter_input_device_get_device_type (device)))
|
|
+ {
|
|
+ priv->has_pointer = has_pointer (manager_evdev);
|
|
+ check_touch_mode = TRUE;
|
|
+ }
|
|
+
|
|
evdev_remove_device (manager_evdev,
|
|
CLUTTER_INPUT_DEVICE_EVDEV (device));
|
|
break;
|
|
@@ -975,6 +1088,9 @@ process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
|
|
handled = FALSE;
|
|
}
|
|
|
|
+ if (check_touch_mode)
|
|
+ update_touch_mode (manager_evdev);
|
|
+
|
|
return handled;
|
|
}
|
|
|
|
@@ -1752,6 +1868,23 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
|
notify_pad_ring (device, time, number, source, group, mode, angle);
|
|
break;
|
|
}
|
|
+ case LIBINPUT_EVENT_SWITCH_TOGGLE:
|
|
+ {
|
|
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
|
+ struct libinput_event_switch *switch_event =
|
|
+ libinput_event_get_switch_event (event);
|
|
+ enum libinput_switch sw =
|
|
+ libinput_event_switch_get_switch (switch_event);
|
|
+ enum libinput_switch_state state =
|
|
+ libinput_event_switch_get_switch_state (switch_event);
|
|
+
|
|
+ if (sw == LIBINPUT_SWITCH_TABLET_MODE)
|
|
+ {
|
|
+ priv->tablet_mode_switch_state = (state == LIBINPUT_SWITCH_STATE_ON);
|
|
+ update_touch_mode (manager_evdev);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
default:
|
|
handled = FALSE;
|
|
}
|
|
@@ -1967,6 +2100,10 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
|
|
|
|
source = clutter_event_source_new (manager_evdev);
|
|
priv->event_source = source;
|
|
+
|
|
+ priv->has_touchscreen = has_touchscreen (manager_evdev);
|
|
+ priv->has_pointer = has_pointer (manager_evdev);
|
|
+ update_touch_mode (manager_evdev);
|
|
}
|
|
|
|
static void
|
|
@@ -2001,6 +2138,43 @@ clutter_device_manager_evdev_dispose (GObject *object)
|
|
G_OBJECT_CLASS (clutter_device_manager_evdev_parent_class)->dispose (object);
|
|
}
|
|
|
|
+static void
|
|
+clutter_device_manager_evdev_set_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ switch (prop_id)
|
|
+ {
|
|
+ case PROP_TOUCH_MODE:
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+clutter_device_manager_evdev_get_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ ClutterDeviceManagerEvdev *manager_evdev;
|
|
+ ClutterDeviceManagerEvdevPrivate *priv;
|
|
+
|
|
+ manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (object);
|
|
+ priv = manager_evdev->priv;
|
|
+
|
|
+ switch (prop_id)
|
|
+ {
|
|
+ case PROP_TOUCH_MODE:
|
|
+ g_value_set_boolean (value, priv->touch_mode);
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
static void
|
|
clutter_device_manager_evdev_finalize (GObject *object)
|
|
{
|
|
@@ -2036,6 +2210,8 @@ clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
|
|
gobject_class->constructed = clutter_device_manager_evdev_constructed;
|
|
gobject_class->finalize = clutter_device_manager_evdev_finalize;
|
|
gobject_class->dispose = clutter_device_manager_evdev_dispose;
|
|
+ gobject_class->set_property = clutter_device_manager_evdev_set_property;
|
|
+ gobject_class->get_property = clutter_device_manager_evdev_get_property;
|
|
|
|
manager_class = CLUTTER_DEVICE_MANAGER_CLASS (klass);
|
|
manager_class->add_device = clutter_device_manager_evdev_add_device;
|
|
@@ -2047,6 +2223,9 @@ clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
|
|
manager_class->get_supported_virtual_device_types = clutter_device_manager_evdev_get_supported_virtual_device_types;
|
|
manager_class->compress_motion = clutter_device_manager_evdev_compress_motion;
|
|
manager_class->apply_kbd_a11y_settings = clutter_device_manager_evdev_apply_kbd_a11y_settings;
|
|
+
|
|
+ g_object_class_override_property (gobject_class, PROP_TOUCH_MODE,
|
|
+ "touch-mode");
|
|
}
|
|
|
|
static void
|
|
--
|
|
2.29.2
|
|
|