summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Olbrich <m.olbrich@pengutronix.de>2022-08-09 14:01:29 +0200
committerMarius Vlad <marius.vlad@collabora.com>2022-11-21 13:54:48 +0200
commitcf1ca2c300769e274892b8d51bcdbc079d45ee87 (patch)
tree67d9d66bb9d3c0990ad32127e370d962e8dc7ac4
parentd23a69272f544ee428ebbb597da09a82e084132c (diff)
downloadweston-cf1ca2c300769e274892b8d51bcdbc079d45ee87.tar.gz
input: send touch frame event after up event
Currently the frame event gets lost: The touch focus is removed in the 'up' event. So the focus is gone when the frame event arrives so it is never sent to the clients. To avoid this, keep the touch focus until the frame is handled. Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> (cherry picked from commit 5448580111b5ff992ce2603cb6e99b9f54db7ad8) This has undergone a change to avoid an ABI break, so rather than hooking up a pending_touch boolean in weston_touch, keep a local list of weston_touch_devices and have a pending_touch with each device to check upon. Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
-rw-r--r--libweston/input.c63
1 files changed, 61 insertions, 2 deletions
diff --git a/libweston/input.c b/libweston/input.c
index 6cbb8db0..235cf023 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -75,6 +75,15 @@ struct border {
enum motion_direction blocking_dir;
};
+struct pending_touch {
+ struct weston_touch_device *touch_device;
+ bool pending_focus_touch_reset;
+
+ struct wl_list touch_link;
+};
+
+static struct wl_list pending_touch_list;
+
static void
maybe_warp_confined_pointer(struct weston_pointer_constraint *constraint);
@@ -143,6 +152,7 @@ weston_touch_create_touch_device(struct weston_touch *touch,
const struct weston_touch_device_ops *ops)
{
struct weston_touch_device *device;
+ struct pending_touch *pt;
assert(syspath);
if (ops) {
@@ -164,20 +174,55 @@ weston_touch_create_touch_device(struct weston_touch *touch,
return NULL;
}
+ pt = zalloc(sizeof(*pt));
+ if (!pt) {
+ free(device);
+ return NULL;
+ }
+
+
device->backend_data = backend_data;
device->ops = ops;
+ pt->touch_device = device;
+ pt->pending_focus_touch_reset = false;
+
device->aggregate = touch;
wl_list_insert(touch->device_list.prev, &device->link);
+ wl_list_insert(&pending_touch_list, &pt->touch_link);
return device;
}
+static struct pending_touch *
+weston_touch_get_pending(struct weston_touch_device *dev)
+{
+ struct pending_touch *pt_iter = NULL;
+ struct pending_touch *pt = NULL;
+
+ wl_list_for_each(pt_iter, &pending_touch_list, touch_link) {
+ if (pt_iter->touch_device == dev) {
+ pt = pt_iter;
+ break;
+ }
+ }
+
+ return pt;
+}
+
/** Destroy the touch device. */
WL_EXPORT void
weston_touch_device_destroy(struct weston_touch_device *device)
{
+ struct pending_touch *pt = NULL;
+
wl_list_remove(&device->link);
+ pt = weston_touch_get_pending(device);
+
+ assert(pt);
+ wl_list_remove(&pt->touch_link);
+ free(pt);
+
wl_signal_emit(&device->destroy_signal, device);
free(device->syspath);
free(device);
@@ -2388,6 +2433,7 @@ process_touch_normal(struct weston_touch_device *device,
struct weston_touch_grab *grab = device->aggregate->grab;
struct weston_compositor *ec = device->aggregate->seat->compositor;
struct weston_view *ev;
+ struct pending_touch *pt = NULL;
wl_fixed_t sx, sy;
wl_fixed_t x = wl_fixed_from_double(double_x);
wl_fixed_t y = wl_fixed_from_double(double_y);
@@ -2438,8 +2484,9 @@ process_touch_normal(struct weston_touch_device *device,
break;
case WL_TOUCH_UP:
grab->interface->up(grab, time, touch_id);
- if (touch->num_tp == 0)
- weston_touch_set_focus(touch, NULL);
+ pt = weston_touch_get_pending(device);
+ assert(pt);
+ pt->pending_focus_touch_reset = true;
break;
}
}
@@ -2628,12 +2675,22 @@ WL_EXPORT void
notify_touch_frame(struct weston_touch_device *device)
{
struct weston_touch_grab *grab;
+ struct pending_touch *pt;
switch (weston_touch_device_get_mode(device)) {
case WESTON_TOUCH_MODE_NORMAL:
case WESTON_TOUCH_MODE_PREP_CALIB:
grab = device->aggregate->grab;
grab->interface->frame(grab);
+
+ pt = weston_touch_get_pending(device);
+ assert(pt);
+
+ if (pt->pending_focus_touch_reset) {
+ if (grab->touch->num_tp == 0)
+ weston_touch_set_focus(grab->touch, NULL);
+ pt->pending_focus_touch_reset = false;
+ }
break;
case WESTON_TOUCH_MODE_CALIB:
case WESTON_TOUCH_MODE_PREP_NORMAL:
@@ -5059,6 +5116,8 @@ bind_input_timestamps_manager(struct wl_client *client, void *data,
int
weston_input_init(struct weston_compositor *compositor)
{
+ wl_list_init(&pending_touch_list);
+
if (!wl_global_create(compositor->wl_display,
&zwp_relative_pointer_manager_v1_interface, 1,
compositor, bind_relative_pointer_manager))