<div dir="ltr">I don't understand this, it seems very redundant with what you propose to put into the compositor. As far as I can tell, you already require the compositor to hide the cursor when the tool leaves proximity and to choose the last-set cursor when a tool enters proximity.<div><br></div><div>Seems to me your proximity_out handler therefore does not have to do anything, and toytoolkit does not have to remember any cursors. The client, if it wants, can set the cursor on proximity-in. Or not set it. Whatever.<br><div><br></div><div>It this is wrong them I am very confused as to why you had to add so much code to the compositor to manager per-tool cursors. You could instead just reuse the seat cursor, since you seem to have the client setting the cursor on every proximity-in and out.<br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 2, 2016 at 9:28 PM, Peter Hutterer <span dir="ltr"><<a href="mailto:peter.hutterer@who-t.net" target="_blank">peter.hutterer@who-t.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Stephen Chandler Paul <<a href="mailto:thatslyude@gmail.com">thatslyude@gmail.com</a>><br>
<br>
The tablet is given a separate cursor. Most tablet interaction is an absolute<br>
interaction and shouldn't need a cursor at all, but usually the cursor is used<br>
to indicate the type of virtual tool currently assigned.<br>
<br>
Co-authored-by: Peter Hutterer <<a href="mailto:peter.hutterer@who-t.net">peter.hutterer@who-t.net</a>><br>
Signed-off-by: Stephen Chandler Paul <<a href="mailto:thatslyude@gmail.com">thatslyude@gmail.com</a>><br>
Signed-off-by: Peter Hutterer <<a href="mailto:peter.hutterer@who-t.net">peter.hutterer@who-t.net</a>><br>
---<br>
 src/compositor.c |   6 +++<br>
 src/compositor.h |  13 +++++<br>
 src/input.c      | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-<br>
 3 files changed, 175 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/compositor.c b/src/compositor.c<br>
index cbdb14c..f419818 100644<br>
--- a/src/compositor.c<br>
+++ b/src/compositor.c<br>
@@ -1866,6 +1866,7 @@ weston_view_unmap(struct weston_view *view)<br>
                struct weston_pointer *pointer = weston_seat_get_pointer(seat);<br>
                struct weston_keyboard *keyboard =<br>
                        weston_seat_get_keyboard(seat);<br>
+               struct weston_tablet_tool *tool;<br>
<br>
                if (keyboard && keyboard->focus == view->surface)<br>
                        weston_keyboard_set_focus(keyboard, NULL);<br>
@@ -1873,6 +1874,11 @@ weston_view_unmap(struct weston_view *view)<br>
                        weston_pointer_clear_focus(pointer);<br>
                if (touch && touch->focus == view)<br>
                        weston_touch_set_focus(touch, NULL);<br>
+<br>
+               wl_list_for_each(tool, &seat->tablet_tool_list, link) {<br>
+                       if (tool->focus == view)<br>
+                               weston_tablet_tool_set_focus(tool, NULL, 0);<br>
+               }<br>
        }<br>
 }<br>
<br>
diff --git a/src/compositor.h b/src/compositor.h<br>
index 784a70d..7960325 100644<br>
--- a/src/compositor.h<br>
+++ b/src/compositor.h<br>
@@ -470,6 +470,12 @@ struct weston_tablet_tool {<br>
<br>
        int button_count;<br>
        bool tip_is_down;<br>
+<br>
+       int32_t hotspot_x, hotspot_y;<br>
+       struct weston_view *sprite;<br>
+       struct wl_listener sprite_destroy_listener;<br>
+<br>
+       wl_fixed_t x, y;<br>
 };<br>
<br>
 struct weston_tablet {<br>
@@ -580,6 +586,13 @@ void<br>
 weston_tablet_tool_end_grab(struct weston_tablet_tool *tool);<br>
<br>
 void<br>
+weston_tablet_tool_clamp(struct weston_tablet_tool *tool,<br>
+                        wl_fixed_t *fx, wl_fixed_t *fy);<br>
+void<br>
+weston_tablet_tool_cursor_move(struct weston_tablet_tool *tool,<br>
+                              wl_fixed_t x, wl_fixed_t y);<br>
+<br>
+void<br>
 wl_data_device_set_keyboard_focus(struct weston_seat *seat);<br>
<br>
 int<br>
diff --git a/src/input.c b/src/input.c<br>
index 006ab5a..fc74856 100644<br>
--- a/src/input.c<br>
+++ b/src/input.c<br>
@@ -974,7 +974,13 @@ static void<br>
 default_grab_tablet_tool_proximity_out(struct weston_tablet_tool_grab *grab,<br>
                                       uint32_t time)<br>
 {<br>
-       weston_tablet_tool_set_focus(grab->tool, NULL, time);<br>
+       struct weston_tablet_tool *tool = grab->tool;<br>
+<br>
+       weston_tablet_tool_set_focus(tool, NULL, time);<br>
+<br>
+       /* Hide the cursor */<br>
+       if (weston_surface_is_mapped(tool->sprite->surface))<br>
+               weston_surface_unmap(tool->sprite->surface);<br>
 }<br>
<br>
 static void<br>
@@ -989,6 +995,8 @@ default_grab_tablet_tool_motion(struct weston_tablet_tool_grab *grab,<br>
        struct wl_resource *resource;<br>
        struct wl_list *resource_list = &tool->focus_resource_list;<br>
<br>
+       weston_tablet_tool_cursor_move(tool, x, y);<br>
+<br>
        current_view = weston_compositor_pick_view(tool->seat->compositor,<br>
                                                   x, y, &sx, &sy);<br>
        if (current_view != tool->focus)<br>
@@ -1126,6 +1134,29 @@ static struct weston_tablet_tool_grab_interface default_tablet_tool_grab_interfa<br>
        default_grab_tablet_tool_cancel,<br>
 };<br>
<br>
+static void<br>
+tablet_tool_unmap_sprite(struct weston_tablet_tool *tool)<br>
+{<br>
+       if (weston_surface_is_mapped(tool->sprite->surface))<br>
+               weston_surface_unmap(tool->sprite->surface);<br>
+<br>
+       wl_list_remove(&tool->sprite_destroy_listener.link);<br>
+       tool->sprite->surface->configure = NULL;<br>
+       tool->sprite->surface->configure_private = NULL;<br>
+       weston_view_destroy(tool->sprite);<br>
+       tool->sprite = NULL;<br>
+}<br>
+<br>
+static void<br>
+tablet_tool_handle_sprite_destroy(struct wl_listener *listener, void *data)<br>
+{<br>
+       struct weston_tablet_tool *tool =<br>
+               container_of(listener, struct weston_tablet_tool,<br>
+                            sprite_destroy_listener);<br>
+<br>
+       tool->sprite = NULL;<br>
+}<br>
+<br>
 WL_EXPORT struct weston_tablet_tool *<br>
 weston_tablet_tool_create(void)<br>
 {<br>
@@ -1138,6 +1169,9 @@ weston_tablet_tool_create(void)<br>
        wl_list_init(&tool->resource_list);<br>
        wl_list_init(&tool->focus_resource_list);<br>
<br>
+       wl_list_init(&tool->sprite_destroy_listener.link);<br>
+       tool->sprite_destroy_listener.notify = tablet_tool_handle_sprite_destroy;<br>
+<br>
        wl_list_init(&tool->focus_view_listener.link);<br>
        tool->focus_view_listener.notify = tablet_tool_focus_view_destroyed;<br>
<br>
@@ -1156,12 +1190,57 @@ weston_tablet_tool_destroy(struct weston_tablet_tool *tool)<br>
 {<br>
        struct wl_resource *resource, *tmp;<br>
<br>
+       if (tool->sprite)<br>
+               tablet_tool_unmap_sprite(tool);<br>
+<br>
        wl_resource_for_each_safe(resource, tmp, &tool->resource_list)<br>
                zwp_tablet_tool_v1_send_removed(resource);<br>
<br>
        wl_list_remove(&tool->link);<br>
 }<br>
<br>
+WL_EXPORT void<br>
+weston_tablet_tool_clamp(struct weston_tablet_tool *tool,<br>
+                        wl_fixed_t *fx, wl_fixed_t *fy)<br>
+{<br>
+       struct weston_output *output = tool->current_tablet->output;<br>
+       int x, y;<br>
+<br>
+       x = wl_fixed_to_int(*fx);<br>
+       y = wl_fixed_to_int(*fy);<br>
+<br>
+       if (x < output->x)<br>
+               *fx = wl_fixed_from_int(output->x);<br>
+       else if (x >= output->x + output->width)<br>
+               *fx = wl_fixed_from_int(output->x + output->width - 1);<br>
+<br>
+       if (y < output->y)<br>
+               *fy = wl_fixed_from_int(output->y);<br>
+       else if (y >= output->y + output->height)<br>
+               *fy = wl_fixed_from_int(output->y + output->height - 1);<br>
+}<br>
+<br>
+WL_EXPORT void<br>
+weston_tablet_tool_cursor_move(struct weston_tablet_tool *tool,<br>
+                              wl_fixed_t x,<br>
+                              wl_fixed_t y)<br>
+{<br>
+       int32_t ix, iy;<br>
+<br>
+       weston_tablet_tool_clamp(tool, &x, &y);<br>
+       tool->x = x;<br>
+       tool->y = y;<br>
+<br>
+       ix = wl_fixed_to_int(x);<br>
+       iy = wl_fixed_to_int(y);<br>
+<br>
+       if (tool->sprite) {<br>
+               weston_view_set_position(tool->sprite,<br>
+                                        ix - tool->hotspot_x,<br>
+                                        iy - tool->hotspot_y);<br>
+               weston_view_schedule_repaint(tool->sprite);<br>
+       }<br>
+}<br>
<br>
 static void<br>
 seat_send_updated_caps(struct weston_seat *seat)<br>
@@ -2321,10 +2400,86 @@ notify_tablet_added(struct weston_tablet *tablet)<br>
 }<br>
<br>
 static void<br>
+tablet_tool_cursor_surface_configure(struct weston_surface *es,<br>
+                                    int32_t dx, int32_t dy)<br>
+{<br>
+       struct weston_tablet_tool *tool = es->configure_private;<br>
+       int x, y;<br>
+<br>
+       if (es->width == 0)<br>
+               return;<br>
+<br>
+       assert(es == tool->sprite->surface);<br>
+<br>
+       tool->hotspot_x -= dx;<br>
+       tool->hotspot_y -= dy;<br>
+<br>
+       x = wl_fixed_to_int(tool->x) - tool->hotspot_x;<br>
+       y = wl_fixed_to_int(tool->y) - tool->hotspot_y;<br>
+<br>
+       weston_view_set_position(tool->sprite, x, y);<br>
+<br>
+       empty_region(&es->pending.input);<br>
+       empty_region(&es->input);<br>
+<br>
+       if (!weston_surface_is_mapped(es)) {<br>
+               weston_layer_entry_insert(<br>
+                       &es->compositor->cursor_layer.view_list,<br>
+                       &tool->sprite->layer_link);<br>
+               weston_view_update_transform(tool->sprite);<br>
+       }<br>
+}<br>
+<br>
+static void<br>
 tablet_tool_set_cursor(struct wl_client *client, struct wl_resource *resource,<br>
                       uint32_t serial, struct wl_resource *surface_resource,<br>
                       int32_t hotspot_x, int32_t hotspot_y)<br>
 {<br>
+       struct weston_tablet_tool *tool = wl_resource_get_user_data(resource);<br>
+       struct weston_surface *surface = NULL;<br>
+<br>
+       if (surface_resource)<br>
+               surface = wl_resource_get_user_data(surface_resource);<br>
+<br>
+       if (tool->focus == NULL)<br>
+               return;<br>
+<br>
+       /* tablet->focus->surface->resource can be NULL. Surfaces like the<br>
+        * black_surface used in shell.c for fullscreen don't have<br>
+        * a resource, but can still have focus */<br>
+       if (tool->focus->surface->resource == NULL)<br>
+               return;<br>
+<br>
+       if (wl_resource_get_client(tool->focus->surface->resource) != client)<br>
+               return;<br>
+<br>
+       if (tool->focus_serial - serial > UINT32_MAX / 2)<br>
+               return;<br>
+<br>
+       if (surface && tool->sprite && surface != tool->sprite->surface &&<br>
+           surface->configure) {<br>
+               wl_resource_post_error(surface->resource,<br>
+                                      WL_DISPLAY_ERROR_INVALID_OBJECT,<br>
+                                      "surface->configure already set");<br>
+               return;<br>
+       }<br>
+<br>
+       if (tool->sprite)<br>
+               tablet_tool_unmap_sprite(tool);<br>
+<br>
+       if (!surface)<br>
+               return;<br>
+<br>
+       wl_signal_add(&surface->destroy_signal,<br>
+                     &tool->sprite_destroy_listener);<br>
+       surface->configure = tablet_tool_cursor_surface_configure;<br>
+       surface->configure_private = tool;<br>
+       tool->sprite = weston_view_create(surface);<br>
+       tool->hotspot_x = hotspot_x;<br>
+       tool->hotspot_y = hotspot_y;<br>
+<br>
+       if (surface->buffer_ref.buffer)<br>
+               tablet_tool_cursor_surface_configure(surface, 0, 0);<br>
 }<br>
<br>
 static void<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.0<br>
<br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" rel="noreferrer" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</font></span></blockquote></div><br></div>