<div dir="ltr"><div><div>This looks like you are having the compositor maintain several cursors per seat, and switching them when different tools are used.<br><br></div>That is wrong. The client is responsible for setting the cursor. Any cursor changes by the compositor will only lead to flashing or blinking or other incorrect renderings, in cases where the compositor chooses a cursor that is not equal to the current cursor and also not equal to the cursor the client actually wants. That is why wayland does not set cursors on enter events, and why it should not set the cursor here either.<br><br></div><div>Strong NAK<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Nov 5, 2015 at 8:31 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 8eadf8c..7777291 100644<br>
--- a/src/compositor.c<br>
+++ b/src/compositor.c<br>
@@ -1759,6 +1759,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>
@@ -1766,6 +1767,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 ce084c8..2eaadf4 100644<br>
--- a/src/compositor.h<br>
+++ b/src/compositor.h<br>
@@ -432,6 +432,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>
@@ -531,6 +537,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 6139b31..69806e2 100644<br>
--- a/src/input.c<br>
+++ b/src/input.c<br>
@@ -781,7 +781,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>
@@ -796,6 +802,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>
@@ -933,6 +941,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>
@@ -945,6 +976,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>
@@ -963,6 +997,9 @@ 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_tool1_send_removed(resource);<br>
<br>
@@ -970,6 +1007,48 @@ weston_tablet_tool_destroy(struct weston_tablet_tool *tool)<br>
        free(tool);<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>
@@ -2034,10 +2113,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.4.3<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>