From: Stephen Chandler Paul <thatsly...@gmail.com>

Closely modelled after the pointer focus handling

Co-authored-by: Peter Hutterer <peter.hutte...@who-t.net>
Signed-off-by: Stephen Chandler Paul <thatsly...@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
---
 src/compositor.h | 10 ++++++
 src/input.c      | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+)

diff --git a/src/compositor.h b/src/compositor.h
index 3c67ffe..c1f3cc4 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -408,8 +408,14 @@ struct weston_touch {
 struct weston_tablet_tool {
        struct weston_seat *seat;
        enum zwp_tablet_tool_v1_type type;
+       struct weston_tablet *current_tablet;
 
        struct wl_list resource_list;
+       struct wl_list focus_resource_list;
+       struct weston_view *focus;
+       struct wl_listener focus_view_listener;
+       struct wl_listener focus_resource_listener;
+       uint32_t focus_serial;
 
        struct wl_list link;
 
@@ -515,6 +521,10 @@ struct weston_tablet_tool *
 weston_tablet_tool_create(void);
 void
 weston_tablet_tool_destroy(struct weston_tablet_tool *tool);
+void
+weston_tablet_tool_set_focus(struct weston_tablet_tool *tool,
+                            struct weston_view *view,
+                            uint32_t time);
 
 void
 wl_data_device_set_keyboard_focus(struct weston_seat *seat);
diff --git a/src/input.c b/src/input.c
index 0b43fd8..f835cf4 100644
--- a/src/input.c
+++ b/src/input.c
@@ -215,6 +215,26 @@ touch_focus_resource_destroyed(struct wl_listener 
*listener, void *data)
 }
 
 static void
+tablet_tool_focus_view_destroyed(struct wl_listener *listener, void *data)
+{
+       struct weston_tablet_tool *tool =
+               container_of(listener, struct weston_tablet_tool,
+                            focus_view_listener);
+
+       weston_tablet_tool_set_focus(tool, NULL, 0);
+}
+
+static void
+tablet_tool_focus_resource_destroyed(struct wl_listener *listener, void *data)
+{
+       struct weston_tablet_tool *tool =
+               container_of(listener, struct weston_tablet_tool,
+                            focus_resource_listener);
+
+       weston_tablet_tool_set_focus(tool, NULL, 0);
+}
+
+static void
 move_resources(struct wl_list *destination, struct wl_list *source)
 {
        wl_list_insert_list(destination, source);
@@ -607,6 +627,16 @@ find_resource_for_surface(struct wl_list *list, struct 
weston_surface *surface)
        return wl_resource_find_for_client(list, 
wl_resource_get_client(surface->resource));
 }
 
+static struct wl_resource *
+find_resource_for_view(struct wl_list *list, struct weston_view *view)
+{
+       if (!view)
+               return NULL;
+
+       return find_resource_for_surface(list,
+                                        view->surface);
+}
+
 static void
 default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
                                uint32_t serial, uint32_t mods_depressed,
@@ -853,6 +883,61 @@ weston_tablet_destroy(struct weston_tablet *tablet)
        wl_list_remove(&tablet->link);
 }
 
+WL_EXPORT void
+weston_tablet_tool_set_focus(struct weston_tablet_tool *tool,
+                            struct weston_view *view,
+                            uint32_t time)
+{
+       struct wl_list *focus_resource_list;
+       struct wl_resource *resource;
+       struct weston_seat *seat = tool->seat;
+
+       focus_resource_list = &tool->focus_resource_list;
+       if (tool->focus && !wl_list_empty(focus_resource_list)) {
+               wl_resource_for_each(resource, focus_resource_list) {
+                       zwp_tablet_tool_v1_send_proximity_out(resource);
+                       zwp_tablet_tool_v1_send_frame(resource, time);
+               }
+
+               move_resources(&tool->resource_list, focus_resource_list);
+       }
+
+       if (find_resource_for_view(&tool->resource_list, view)) {
+               struct wl_client *surface_client =
+                       wl_resource_get_client(view->surface->resource);
+
+               move_resources_for_client(focus_resource_list,
+                                         &tool->resource_list,
+                                         surface_client);
+
+               tool->focus_serial = 
wl_display_next_serial(seat->compositor->wl_display);
+               wl_resource_for_each(resource, focus_resource_list) {
+                       struct wl_resource *tr;
+
+                       tr = 
wl_resource_find_for_client(&tool->current_tablet->resource_list,
+                                                        surface_client);
+
+                       zwp_tablet_tool_v1_send_proximity_in(resource, 
tool->focus_serial,
+                                                          tr, 
view->surface->resource);
+                       zwp_tablet_tool_v1_send_frame(resource, time);
+               }
+       }
+
+       wl_list_remove(&tool->focus_view_listener.link);
+       wl_list_init(&tool->focus_view_listener.link);
+       wl_list_remove(&tool->focus_resource_listener.link);
+       wl_list_init(&tool->focus_resource_listener.link);
+
+       if (view)
+               wl_signal_add(&view->destroy_signal,
+                             &tool->focus_view_listener);
+       if (view && view->surface->resource)
+               wl_resource_add_destroy_listener(view->surface->resource,
+                                                
&tool->focus_resource_listener);
+       tool->focus = view;
+       tool->focus_view_listener.notify = tablet_tool_focus_view_destroyed;
+}
+
 WL_EXPORT struct weston_tablet_tool *
 weston_tablet_tool_create(void)
 {
@@ -863,6 +948,13 @@ weston_tablet_tool_create(void)
                return NULL;
 
        wl_list_init(&tool->resource_list);
+       wl_list_init(&tool->focus_resource_list);
+
+       wl_list_init(&tool->focus_view_listener.link);
+       tool->focus_view_listener.notify = tablet_tool_focus_view_destroyed;
+
+       wl_list_init(&tool->focus_resource_listener.link);
+       tool->focus_resource_listener.notify = 
tablet_tool_focus_resource_destroyed;
 
        return tool;
 }
-- 
2.5.0

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to