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.
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. 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. On Tue, Feb 2, 2016 at 9:28 PM, Peter Hutterer <peter.hutte...@who-t.net> wrote: > From: Stephen Chandler Paul <thatsly...@gmail.com> > > The tablet is given a separate cursor. Most tablet interaction is an > absolute > interaction and shouldn't need a cursor at all, but usually the cursor is > used > to indicate the type of virtual tool currently assigned. > > 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.c | 6 +++ > src/compositor.h | 13 +++++ > src/input.c | 157 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 3 files changed, 175 insertions(+), 1 deletion(-) > > diff --git a/src/compositor.c b/src/compositor.c > index cbdb14c..f419818 100644 > --- a/src/compositor.c > +++ b/src/compositor.c > @@ -1866,6 +1866,7 @@ weston_view_unmap(struct weston_view *view) > struct weston_pointer *pointer = > weston_seat_get_pointer(seat); > struct weston_keyboard *keyboard = > weston_seat_get_keyboard(seat); > + struct weston_tablet_tool *tool; > > if (keyboard && keyboard->focus == view->surface) > weston_keyboard_set_focus(keyboard, NULL); > @@ -1873,6 +1874,11 @@ weston_view_unmap(struct weston_view *view) > weston_pointer_clear_focus(pointer); > if (touch && touch->focus == view) > weston_touch_set_focus(touch, NULL); > + > + wl_list_for_each(tool, &seat->tablet_tool_list, link) { > + if (tool->focus == view) > + weston_tablet_tool_set_focus(tool, NULL, > 0); > + } > } > } > > diff --git a/src/compositor.h b/src/compositor.h > index 784a70d..7960325 100644 > --- a/src/compositor.h > +++ b/src/compositor.h > @@ -470,6 +470,12 @@ struct weston_tablet_tool { > > int button_count; > bool tip_is_down; > + > + int32_t hotspot_x, hotspot_y; > + struct weston_view *sprite; > + struct wl_listener sprite_destroy_listener; > + > + wl_fixed_t x, y; > }; > > struct weston_tablet { > @@ -580,6 +586,13 @@ void > weston_tablet_tool_end_grab(struct weston_tablet_tool *tool); > > void > +weston_tablet_tool_clamp(struct weston_tablet_tool *tool, > + wl_fixed_t *fx, wl_fixed_t *fy); > +void > +weston_tablet_tool_cursor_move(struct weston_tablet_tool *tool, > + wl_fixed_t x, wl_fixed_t y); > + > +void > wl_data_device_set_keyboard_focus(struct weston_seat *seat); > > int > diff --git a/src/input.c b/src/input.c > index 006ab5a..fc74856 100644 > --- a/src/input.c > +++ b/src/input.c > @@ -974,7 +974,13 @@ static void > default_grab_tablet_tool_proximity_out(struct weston_tablet_tool_grab > *grab, > uint32_t time) > { > - weston_tablet_tool_set_focus(grab->tool, NULL, time); > + struct weston_tablet_tool *tool = grab->tool; > + > + weston_tablet_tool_set_focus(tool, NULL, time); > + > + /* Hide the cursor */ > + if (weston_surface_is_mapped(tool->sprite->surface)) > + weston_surface_unmap(tool->sprite->surface); > } > > static void > @@ -989,6 +995,8 @@ default_grab_tablet_tool_motion(struct > weston_tablet_tool_grab *grab, > struct wl_resource *resource; > struct wl_list *resource_list = &tool->focus_resource_list; > > + weston_tablet_tool_cursor_move(tool, x, y); > + > current_view = weston_compositor_pick_view(tool->seat->compositor, > x, y, &sx, &sy); > if (current_view != tool->focus) > @@ -1126,6 +1134,29 @@ static struct weston_tablet_tool_grab_interface > default_tablet_tool_grab_interfa > default_grab_tablet_tool_cancel, > }; > > +static void > +tablet_tool_unmap_sprite(struct weston_tablet_tool *tool) > +{ > + if (weston_surface_is_mapped(tool->sprite->surface)) > + weston_surface_unmap(tool->sprite->surface); > + > + wl_list_remove(&tool->sprite_destroy_listener.link); > + tool->sprite->surface->configure = NULL; > + tool->sprite->surface->configure_private = NULL; > + weston_view_destroy(tool->sprite); > + tool->sprite = NULL; > +} > + > +static void > +tablet_tool_handle_sprite_destroy(struct wl_listener *listener, void > *data) > +{ > + struct weston_tablet_tool *tool = > + container_of(listener, struct weston_tablet_tool, > + sprite_destroy_listener); > + > + tool->sprite = NULL; > +} > + > WL_EXPORT struct weston_tablet_tool * > weston_tablet_tool_create(void) > { > @@ -1138,6 +1169,9 @@ weston_tablet_tool_create(void) > wl_list_init(&tool->resource_list); > wl_list_init(&tool->focus_resource_list); > > + wl_list_init(&tool->sprite_destroy_listener.link); > + tool->sprite_destroy_listener.notify = > tablet_tool_handle_sprite_destroy; > + > wl_list_init(&tool->focus_view_listener.link); > tool->focus_view_listener.notify = > tablet_tool_focus_view_destroyed; > > @@ -1156,12 +1190,57 @@ weston_tablet_tool_destroy(struct > weston_tablet_tool *tool) > { > struct wl_resource *resource, *tmp; > > + if (tool->sprite) > + tablet_tool_unmap_sprite(tool); > + > wl_resource_for_each_safe(resource, tmp, &tool->resource_list) > zwp_tablet_tool_v1_send_removed(resource); > > wl_list_remove(&tool->link); > } > > +WL_EXPORT void > +weston_tablet_tool_clamp(struct weston_tablet_tool *tool, > + wl_fixed_t *fx, wl_fixed_t *fy) > +{ > + struct weston_output *output = tool->current_tablet->output; > + int x, y; > + > + x = wl_fixed_to_int(*fx); > + y = wl_fixed_to_int(*fy); > + > + if (x < output->x) > + *fx = wl_fixed_from_int(output->x); > + else if (x >= output->x + output->width) > + *fx = wl_fixed_from_int(output->x + output->width - 1); > + > + if (y < output->y) > + *fy = wl_fixed_from_int(output->y); > + else if (y >= output->y + output->height) > + *fy = wl_fixed_from_int(output->y + output->height - 1); > +} > + > +WL_EXPORT void > +weston_tablet_tool_cursor_move(struct weston_tablet_tool *tool, > + wl_fixed_t x, > + wl_fixed_t y) > +{ > + int32_t ix, iy; > + > + weston_tablet_tool_clamp(tool, &x, &y); > + tool->x = x; > + tool->y = y; > + > + ix = wl_fixed_to_int(x); > + iy = wl_fixed_to_int(y); > + > + if (tool->sprite) { > + weston_view_set_position(tool->sprite, > + ix - tool->hotspot_x, > + iy - tool->hotspot_y); > + weston_view_schedule_repaint(tool->sprite); > + } > +} > > static void > seat_send_updated_caps(struct weston_seat *seat) > @@ -2321,10 +2400,86 @@ notify_tablet_added(struct weston_tablet *tablet) > } > > static void > +tablet_tool_cursor_surface_configure(struct weston_surface *es, > + int32_t dx, int32_t dy) > +{ > + struct weston_tablet_tool *tool = es->configure_private; > + int x, y; > + > + if (es->width == 0) > + return; > + > + assert(es == tool->sprite->surface); > + > + tool->hotspot_x -= dx; > + tool->hotspot_y -= dy; > + > + x = wl_fixed_to_int(tool->x) - tool->hotspot_x; > + y = wl_fixed_to_int(tool->y) - tool->hotspot_y; > + > + weston_view_set_position(tool->sprite, x, y); > + > + empty_region(&es->pending.input); > + empty_region(&es->input); > + > + if (!weston_surface_is_mapped(es)) { > + weston_layer_entry_insert( > + &es->compositor->cursor_layer.view_list, > + &tool->sprite->layer_link); > + weston_view_update_transform(tool->sprite); > + } > +} > + > +static void > tablet_tool_set_cursor(struct wl_client *client, struct wl_resource > *resource, > uint32_t serial, struct wl_resource > *surface_resource, > int32_t hotspot_x, int32_t hotspot_y) > { > + struct weston_tablet_tool *tool = > wl_resource_get_user_data(resource); > + struct weston_surface *surface = NULL; > + > + if (surface_resource) > + surface = wl_resource_get_user_data(surface_resource); > + > + if (tool->focus == NULL) > + return; > + > + /* tablet->focus->surface->resource can be NULL. Surfaces like the > + * black_surface used in shell.c for fullscreen don't have > + * a resource, but can still have focus */ > + if (tool->focus->surface->resource == NULL) > + return; > + > + if (wl_resource_get_client(tool->focus->surface->resource) != > client) > + return; > + > + if (tool->focus_serial - serial > UINT32_MAX / 2) > + return; > + > + if (surface && tool->sprite && surface != tool->sprite->surface && > + surface->configure) { > + wl_resource_post_error(surface->resource, > + WL_DISPLAY_ERROR_INVALID_OBJECT, > + "surface->configure already set"); > + return; > + } > + > + if (tool->sprite) > + tablet_tool_unmap_sprite(tool); > + > + if (!surface) > + return; > + > + wl_signal_add(&surface->destroy_signal, > + &tool->sprite_destroy_listener); > + surface->configure = tablet_tool_cursor_surface_configure; > + surface->configure_private = tool; > + tool->sprite = weston_view_create(surface); > + tool->hotspot_x = hotspot_x; > + tool->hotspot_y = hotspot_y; > + > + if (surface->buffer_ref.buffer) > + tablet_tool_cursor_surface_configure(surface, 0, 0); > } > > static void > -- > 2.5.0 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel >
_______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel