[PATCH wayland 06/10] Add cursor object representing the visible pointer
Kristian Høgsberg
krh at bitplanet.net
Wed Jul 25 06:36:52 PDT 2012
On Wed, Jul 25, 2012 at 6:45 AM, Ander Conselvan de Oliveira
<conselvan2 at gmail.com> wrote:
> On 07/23/2012 09:54 PM, Daniel Stone wrote:
>>
>> The wl_cursor object represents a visible on-screen cursor, with
>> co-ordinates and a surface image. Add hooks for compositors to be able
>> to discover new cursors and be informed when they change, and have the
>> core implementation track the location.
>
>
> I like the idea of having wl_cursor with position and hotspot but there is a
> few problems with the implementation.
>
> First, the drag icon should not replace the pointer cursor but be a surface
> displayed under it. And if we just make that a separate cursor, the whole
> saved cursor logic can be dropped.
>
> Also, having to emit the cursor update signal on every single grab is
> leading to a lot of code duplication. Is there a reason it can't be done
> inside notify_* in weston? The drag cursor would be updated on the drag grab
> though, since it would be a separate cursor.
>
> And maybe the cursor.update_signal is not necessary. If all the cursor are
> in a list, they could be updated on weston_output_repaint() before redoing
> the surface list.
Yeah, I agree with those points. I didn't read the patch closely yet,
but the saved cursor stuff didn't look right. We never save the
cursor, we always rely on the client to set the right cursor. If the
compositor has to change the cursor during a grab (moving a window,
dnd etc) we take away pointer focus, and when we give it back, the
client will set a new cursor in response.
Kristian
> Cheers,
> Ander
>
>
>
>
>> Signed-off-by: Daniel Stone <daniel at fooishbar.org>
>> ---
>> src/data-device.c | 30 +++++++++++++++++-----
>> src/wayland-server.c | 69
>> +++++++++++++++++++++++++++++++++++++++++++++++---
>> src/wayland-server.h | 27 ++++++++++++++++++--
>> 3 files changed, 115 insertions(+), 11 deletions(-)
>>
>> diff --git a/src/data-device.c b/src/data-device.c
>> index 82020af..c19e14f 100644
>> --- a/src/data-device.c
>> +++ b/src/data-device.c
>> @@ -212,6 +212,12 @@ drag_grab_focus(struct wl_pointer_grab *grab,
>> &seat->drag_focus_listener);
>> seat->drag_focus_resource = resource;
>> grab->focus = surface;
>> +
>> + seat->pointer->cursor.icon = seat->drag_cursor.icon;
>> + seat->pointer->cursor.x = seat->pointer->x;
>> + seat->pointer->cursor.y = seat->pointer->y;
>> + wl_signal_emit(&seat->pointer->cursor.update_signal,
>> + &seat->pointer->cursor);
>> }
>>
>> static void
>> @@ -223,6 +229,11 @@ drag_grab_motion(struct wl_pointer_grab *grab,
>> if (seat->drag_focus_resource)
>> wl_data_device_send_motion(seat->drag_focus_resource,
>> time, x, y);
>> +
>> + seat->pointer->cursor.x = seat->pointer->x;
>> + seat->pointer->cursor.y = seat->pointer->y;
>> + wl_signal_emit(&seat->pointer->cursor.update_signal,
>> + &seat->pointer->cursor);
>> }
>>
>> static void
>> @@ -231,14 +242,15 @@ data_device_end_drag_grab(struct wl_seat *seat)
>> struct wl_resource *surface_resource;
>> struct wl_surface_interface *implementation;
>>
>> - if (seat->drag_surface) {
>> - surface_resource = &seat->drag_surface->resource;
>> + if (seat->drag_cursor.icon) {
>> + surface_resource = &seat->drag_cursor.icon->resource;
>> implementation = (struct wl_surface_interface *)
>> surface_resource->object.implementation;
>>
>> implementation->attach(surface_resource->client,
>> surface_resource, NULL, 0, 0);
>> wl_list_remove(&seat->drag_icon_listener.link);
>> + seat->drag_cursor.icon = NULL;
>> }
>>
>> drag_grab_focus(&seat->drag_grab, NULL,
>> @@ -247,7 +259,7 @@ data_device_end_drag_grab(struct wl_seat *seat)
>> wl_pointer_end_grab(seat->pointer);
>>
>> seat->drag_data_source = NULL;
>> - seat->drag_surface = NULL;
>> + seat->drag_cursor.icon = NULL;
>> seat->drag_client = NULL;
>> }
>>
>> @@ -292,7 +304,12 @@ destroy_data_device_icon(struct wl_listener
>> *listener, void *data)
>> struct wl_seat *seat = container_of(listener, struct wl_seat,
>> drag_icon_listener);
>>
>> - seat->drag_surface = NULL;
>> + if (seat->pointer->cursor.icon == seat->drag_cursor.icon) {
>> + seat->pointer->cursor.icon = NULL;
>> + wl_signal_emit(&seat->pointer->cursor.update_signal,
>> + &seat->pointer->cursor);
>> + }
>> + seat->drag_cursor.icon = NULL;
>> }
>>
>> static void
>> @@ -322,11 +339,12 @@ data_device_start_drag(struct wl_client *client,
>> struct wl_resource *resource,
>> }
>>
>> if (icon_resource) {
>> - seat->drag_surface = icon_resource->data;
>> + seat->drag_cursor.icon = icon_resource->data;
>> + seat->drag_cursor.hotspot_x = 0;
>> + seat->drag_cursor.hotspot_y = 0;
>> seat->drag_icon_listener.notify =
>> destroy_data_device_icon;
>> wl_signal_add(&icon_resource->destroy_signal,
>> &seat->drag_icon_listener);
>> - wl_signal_emit(&seat->drag_icon_signal, icon_resource);
>> }
>>
>> wl_pointer_set_focus(seat->pointer, NULL,
>> diff --git a/src/wayland-server.c b/src/wayland-server.c
>> index 88e8433..f9d2522 100644
>> --- a/src/wayland-server.c
>> +++ b/src/wayland-server.c
>> @@ -519,6 +519,13 @@ default_grab_focus(struct wl_pointer_grab *grab,
>> return;
>>
>> wl_pointer_set_focus(pointer, surface, x, y);
>> +
>> + pointer->cursor.icon = pointer->saved_cursor.icon;
>> + pointer->cursor.hotspot_x = pointer->saved_cursor.hotspot_x;
>> + pointer->cursor.hotspot_y = pointer->saved_cursor.hotspot_y;
>> + pointer->cursor.x = pointer->x;
>> + pointer->cursor.y = pointer->y;
>> + wl_signal_emit(&pointer->cursor.update_signal, &pointer->cursor);
>> }
>>
>> static void
>> @@ -526,10 +533,15 @@ default_grab_motion(struct wl_pointer_grab *grab,
>> uint32_t time, wl_fixed_t x, wl_fixed_t y)
>> {
>> struct wl_resource *resource;
>> + struct wl_pointer *pointer = grab->pointer;
>>
>> - resource = grab->pointer->focus_resource;
>> + resource = pointer->focus_resource;
>> if (resource)
>> wl_pointer_send_motion(resource, time, x, y);
>> +
>> + pointer->cursor.x = pointer->x;
>> + pointer->cursor.y = pointer->y;
>> + wl_signal_emit(&pointer->cursor.update_signal, &pointer->cursor);
>> }
>>
>> static void
>> @@ -627,6 +639,47 @@ static const struct wl_keyboard_grab_interface
>> default_grab_modifiers,
>> };
>>
>> +static void
>> +saved_cursor_destroy_listener(struct wl_listener *listener, void *data)
>> +{
>> + struct wl_pointer *pointer =
>> + container_of(listener, struct wl_pointer, icon_listener);
>> +
>> + if (pointer->cursor.icon == pointer->saved_cursor.icon) {
>> + pointer->cursor.icon = NULL;
>> + wl_signal_emit(&pointer->cursor.update_signal,
>> + &pointer->cursor);
>> + }
>> +
>> + pointer->saved_cursor.icon = NULL;
>> +}
>> +
>> +WL_EXPORT void
>> +wl_pointer_set_cursor_icon(struct wl_pointer *pointer,
>> + struct wl_surface *cursor,
>> + int32_t hotspot_x,
>> + int32_t hotspot_y)
>> +{
>> + if (pointer->saved_cursor.icon)
>> + wl_list_remove(&pointer->icon_listener.link);
>> +
>> + pointer->saved_cursor.icon = cursor;
>> + if (cursor)
>> + wl_signal_add(&cursor->resource.destroy_signal,
>> + &pointer->icon_listener);
>> + pointer->saved_cursor.hotspot_x = hotspot_x;
>> + pointer->saved_cursor.hotspot_y = hotspot_y;
>> +
>> + /* Grabs will set their own cursor. */
>> + if (pointer->grab != &pointer->default_grab)
>> + return;
>> +
>> + pointer->cursor.icon = pointer->saved_cursor.icon;
>> + pointer->cursor.hotspot_x = pointer->saved_cursor.hotspot_x;
>> + pointer->cursor.hotspot_y = pointer->saved_cursor.hotspot_y;
>> + wl_signal_emit(&pointer->cursor.update_signal, &pointer->cursor);
>> +}
>> +
>> WL_EXPORT void
>> wl_pointer_init(struct wl_pointer *pointer)
>> {
>> @@ -638,6 +691,10 @@ wl_pointer_init(struct wl_pointer *pointer)
>> pointer->grab = &pointer->default_grab;
>> wl_signal_init(&pointer->focus_signal);
>>
>> + pointer->icon_listener.notify = saved_cursor_destroy_listener;
>> + wl_signal_init(&pointer->cursor.update_signal);
>> + wl_signal_init(&pointer->cursor.destroy_signal);
>> +
>> /* FIXME: Pick better co-ords. */
>> pointer->x = wl_fixed_from_int(100);
>> pointer->y = wl_fixed_from_int(100);
>> @@ -649,6 +706,10 @@ wl_pointer_release(struct wl_pointer *pointer)
>> /* XXX: What about pointer->resource_list? */
>> if (pointer->focus_resource)
>> wl_list_remove(&pointer->focus_listener.link);
>> + if (pointer->saved_cursor.icon)
>> + wl_list_remove(&pointer->icon_listener.link);
>> + wl_signal_emit(&pointer->cursor.destroy_signal,
>> + &pointer->cursor);
>> }
>>
>> WL_EXPORT void
>> @@ -700,7 +761,7 @@ wl_seat_init(struct wl_seat *seat)
>> wl_list_init(&seat->base_resource_list);
>> wl_signal_init(&seat->selection_signal);
>> wl_list_init(&seat->drag_resource_list);
>> - wl_signal_init(&seat->drag_icon_signal);
>> + wl_signal_init(&seat->cursor_signal);
>> }
>>
>> WL_EXPORT void
>> @@ -742,8 +803,10 @@ wl_seat_set_pointer(struct wl_seat *seat, struct
>> wl_pointer *pointer)
>> return;
>>
>> seat->pointer = pointer;
>> - if (pointer)
>> + if (pointer) {
>> pointer->seat = seat;
>> + wl_signal_emit(&seat->cursor_signal, &pointer->cursor);
>> + }
>>
>> seat_send_updated_caps(seat);
>> }
>> diff --git a/src/wayland-server.h b/src/wayland-server.h
>> index f092145..f7a0957 100644
>> --- a/src/wayland-server.h
>> +++ b/src/wayland-server.h
>> @@ -239,6 +239,19 @@ struct wl_data_source {
>> void (*cancel)(struct wl_data_source *source);
>> };
>>
>> +struct wl_cursor {
>> + struct wl_signal update_signal;
>> + struct wl_signal destroy_signal;
>> +
>> + struct wl_surface *icon;
>> +
>> + wl_fixed_t x;
>> + wl_fixed_t y;
>> +
>> + int32_t hotspot_x;
>> + int32_t hotspot_y;
>> +};
>> +
>> struct wl_pointer {
>> struct wl_seat *seat;
>>
>> @@ -260,6 +273,10 @@ struct wl_pointer {
>> struct wl_surface *current;
>> wl_fixed_t current_x, current_y;
>>
>> + struct wl_cursor cursor;
>> + struct wl_cursor saved_cursor;
>> + struct wl_listener icon_listener;
>> +
>> uint32_t button_count;
>> };
>>
>> @@ -307,6 +324,8 @@ struct wl_seat {
>> struct wl_keyboard *keyboard;
>> struct wl_touch *touch;
>>
>> + struct wl_signal cursor_signal;
>> +
>> uint32_t selection_serial;
>> struct wl_data_source *selection_data_source;
>> struct wl_listener selection_data_source_listener;
>> @@ -320,9 +339,8 @@ struct wl_seat {
>> struct wl_resource *drag_focus_resource;
>> struct wl_listener drag_focus_listener;
>> struct wl_pointer_grab drag_grab;
>> - struct wl_surface *drag_surface;
>> + struct wl_cursor drag_cursor;
>> struct wl_listener drag_icon_listener;
>> - struct wl_signal drag_icon_signal;
>> };
>>
>> /*
>> @@ -389,6 +407,11 @@ wl_pointer_start_grab(struct wl_pointer *pointer,
>> struct wl_pointer_grab *grab);
>> void
>> wl_pointer_end_grab(struct wl_pointer *pointer);
>> +void
>> +wl_pointer_set_cursor_icon(struct wl_pointer *pointer,
>> + struct wl_surface *cursor,
>> + wl_fixed_t hotspot_x,
>> + wl_fixed_t hotspot_y);
>>
>> void
>> wl_keyboard_init(struct wl_keyboard *keyboard);
>>
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list