From 56464253c02276c386243a844bc781859002d6f1 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 31 Jul 2012 13:21:08 +0300 Subject: [PATCH] compositor: rework touch focus In the wl_seat conversion, struct wl_touch got fields for the focused surface and the client resource for the input device being focused. However, the conversion was incomplete: the old fields weston_seat::touch_focus* we still used by the event dispatching code, but the new code never set them. Therefore no touch events were ever sent. From weston_seat, remove the fields touch_focus, touch_focus_listener, touch_focus_resource, and touch_focus_resource_listener. They are replaced by the corresponding fields and listeners from struct wl_touch. While doing this, fix touch_set_focus(). If touch_set_focus() was called first with surface A, and then with surface B, without being called with NULL in between, it would corrupt the destroy_signal list. It was equivalent of calling wl_signal_add() for different signal sources with the same listener without removing in between. Now, touch_set_focus() first removes focus and listeners, and then attempts to assign focus if requested. If the target client has not subscribed for touch events, the touch focus will now be NULL. Before this patch, the touch focus was left to the previous surface. NOTE: this patch depends on the patch "server: add lose_touch_focus()" for Wayland. Signed-off-by: Pekka Paalanen --- src/compositor.c | 62 ++++++++++++++++---------------------------------------- src/compositor.h | 4 ---- 2 files changed, 18 insertions(+), 48 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 97efcaf..aee68bf 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -2061,32 +2061,19 @@ notify_keyboard_focus_out(struct wl_seat *seat) } static void -lose_touch_focus_resource(struct wl_listener *listener, void *data) -{ - struct weston_seat *seat = container_of(listener, struct weston_seat, - touch_focus_resource_listener); - - seat->touch_focus_resource = NULL; -} - -static void -lose_touch_focus(struct wl_listener *listener, void *data) -{ - struct weston_seat *seat = container_of(listener, struct weston_seat, - touch_focus_listener); - - seat->touch_focus = NULL; -} - -static void touch_set_focus(struct weston_seat *ws, struct wl_surface *surface) { struct wl_seat *seat = &ws->seat; struct wl_resource *resource; - if (ws->touch_focus == surface) + if (seat->touch->focus == surface) return; + if (seat->touch->focus_resource) + wl_list_remove(&seat->touch->focus_listener.link); + seat->touch->focus = NULL; + seat->touch->focus_resource = NULL; + if (surface) { resource = find_resource_for_client(&seat->touch->resource_list, @@ -2096,23 +2083,10 @@ touch_set_focus(struct weston_seat *ws, struct wl_surface *surface) return; } - ws->touch_focus_resource_listener.notify = - lose_touch_focus_resource; - wl_signal_add(&resource->destroy_signal, - &ws->touch_focus_resource_listener); - ws->touch_focus_listener.notify = lose_touch_focus; - wl_signal_add(&surface->resource.destroy_signal, - &ws->touch_focus_listener); - seat->touch->focus = surface; seat->touch->focus_resource = resource; - } else { - if (seat->touch->focus) - wl_list_remove(&ws->touch_focus_listener.link); - if (seat->touch->focus_resource) - wl_list_remove(&ws->touch_focus_resource_listener.link); - seat->touch->focus = NULL; - seat->touch->focus_resource = NULL; + wl_signal_add(&resource->destroy_signal, + &seat->touch->focus_listener); } } @@ -2146,33 +2120,33 @@ notify_touch(struct wl_seat *seat, uint32_t time, int touch_id, if (ws->num_tp == 1) { es = weston_compositor_pick_surface(ec, x, y, &sx, &sy); touch_set_focus(ws, &es->surface); - } else if (ws->touch_focus) { - es = (struct weston_surface *) ws->touch_focus; + } else if (seat->touch->focus) { + es = (struct weston_surface *)seat->touch->focus; weston_surface_from_global_fixed(es, x, y, &sx, &sy); } - if (ws->touch_focus_resource && ws->touch_focus) - wl_touch_send_down(ws->touch_focus_resource, + if (seat->touch->focus_resource && seat->touch->focus) + wl_touch_send_down(seat->touch->focus_resource, serial, time, - &ws->touch_focus->resource, + &seat->touch->focus->resource, touch_id, sx, sy); break; case WL_TOUCH_MOTION: - es = (struct weston_surface *) ws->touch_focus; + es = (struct weston_surface *)seat->touch->focus; if (!es) break; weston_surface_from_global_fixed(es, x, y, &sx, &sy); - if (ws->touch_focus_resource) - wl_touch_send_motion(ws->touch_focus_resource, + if (seat->touch->focus_resource) + wl_touch_send_motion(seat->touch->focus_resource, time, touch_id, sx, sy); break; case WL_TOUCH_UP: weston_compositor_idle_release(ec); ws->num_tp--; - if (ws->touch_focus_resource) - wl_touch_send_up(ws->touch_focus_resource, + if (seat->touch->focus_resource) + wl_touch_send_up(seat->touch->focus_resource, serial, time, touch_id); if (ws->num_tp == 0) touch_set_focus(ws, NULL); diff --git a/src/compositor.h b/src/compositor.h index 7112796..899fa42 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -224,10 +224,6 @@ struct weston_seat { struct wl_listener saved_kbd_focus_listener; uint32_t num_tp; - struct wl_surface *touch_focus; - struct wl_listener touch_focus_listener; - struct wl_resource *touch_focus_resource; - struct wl_listener touch_focus_resource_listener; struct wl_listener new_drag_icon_listener; -- 2.7.4