diff --git a/include/wlr/types/wlr_relative_pointer_v1.h b/include/wlr/types/wlr_relative_pointer_v1.h index 6f2e0878..292be238 100644 --- a/include/wlr/types/wlr_relative_pointer_v1.h +++ b/include/wlr/types/wlr_relative_pointer_v1.h @@ -15,7 +15,7 @@ /** * This protocol specifies a set of interfaces used for making clients able to * receive relative pointer events not obstructed by barriers (such as the - * monitor edge or other pointer barriers). + * monitor edge or pointer constraints). */ @@ -26,7 +26,7 @@ struct wlr_relative_pointer_manager_v1 { struct wl_global *global; - struct wl_list resources; + struct wl_list resources; // wl_resource_get_link() struct wl_list relative_pointers; struct { @@ -60,6 +60,8 @@ struct wlr_relative_pointer_v1 { struct wl_signal destroy; } events; + struct wl_listener seat_destroy; + void *data; }; @@ -69,7 +71,7 @@ void wlr_relative_pointer_manager_v1_destroy( struct wlr_relative_pointer_manager_v1 *relative_pointer_manager); void wlr_relative_pointer_v1_send_relative_motion( - struct wlr_relative_pointer_v1 *relative_pointer, uint64_t time, + struct wlr_relative_pointer_v1 *relative_pointer, uint64_t time_msec, double dx, double dy, double dx_unaccel, double dy_unaccel); struct wlr_relative_pointer_v1 *wlr_relative_pointer_v1_from_resource( diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 48c48d73..942a3420 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -313,19 +313,6 @@ void wlr_seat_pointer_clear_focus(struct wlr_seat *wlr_seat); void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time, double sx, double sy); -/** - * Send relative motion events to the surface with pointer focus. Coordinates - * for the motion event are relative to current pointer location, both - * accelerated and unaccelerated. Compositors should use - * `wlr_seat_pointer_notify_relative_motion()` to send relative motion events - * to respect relative pointer requests by clients. - * - * Note that the timestamp is 64 bit, split into high 32 bits and low 32 bits. - */ -void wlr_seat_pointer_notify_relative_motion(struct wlr_seat *wlr_seat, - uint64_t time, double dx, double dy, - double dx_unaccel, double dy_unaccel); - /** * Send a button event to the surface with pointer focus. Coordinates for the * button event are surface-local. Returns the serial. Compositors should use diff --git a/rootston/cursor.c b/rootston/cursor.c index ba8d0860..16fb9c70 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -307,7 +307,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, static void notify_relative_motion(struct roots_seat *seat, uint64_t time_msec, double dx, double dy, double dx_unaccel, double dy_unaccel) { - struct wlr_relative_pointer_manager_v1 *relative_pointer_manager = seat->input->server->desktop->relative_pointer_manager; @@ -316,26 +315,15 @@ static void notify_relative_motion(struct roots_seat *seat, uint64_t time_msec, return; } - struct wl_resource *resource; - wl_resource_for_each(resource, &relative_pointer_manager->relative_pointers) { - - struct wlr_relative_pointer_v1 *pointer = - wlr_relative_pointer_v1_from_resource(resource); - if (pointer == NULL || seat->seat != pointer->seat) { + struct wlr_relative_pointer_v1 *pointer; + wl_list_for_each(pointer, &relative_pointer_manager->relative_pointers, link) { + if (seat->seat != pointer->seat) { continue; } wlr_relative_pointer_v1_send_relative_motion(pointer, time_msec, dx, dy, dx_unaccel, dy_unaccel); } - - wl_resource_for_each(resource, &client->pointers) { - if (wlr_seat_client_from_pointer_resource(resource) == NULL) { - continue; - } - wl_pointer_send_frame(resource); - } - } void roots_cursor_handle_motion(struct roots_cursor *cursor, @@ -343,6 +331,7 @@ void roots_cursor_handle_motion(struct roots_cursor *cursor, double dx = event->delta_x; double dy = event->delta_y; + /* TODO send unaccelerated values */ notify_relative_motion(cursor->seat, (uint64_t)event->time_msec * 1000, dx, dy, dx, dy); @@ -388,6 +377,7 @@ void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, double dx = lx - cursor->cursor->x; double dy = ly - cursor->cursor->y; + /* TODO send unaccelerated values */ notify_relative_motion(cursor->seat, (uint64_t)event->time_msec * 1000, dx, dy, dx, dy); diff --git a/types/seat/wlr_seat_pointer.c b/types/seat/wlr_seat_pointer.c index 936ac0dc..594a5b81 100644 --- a/types/seat/wlr_seat_pointer.c +++ b/types/seat/wlr_seat_pointer.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include "types/wlr_seat.h" #include "util/signal.h" diff --git a/types/wlr_relative_pointer_v1.c b/types/wlr_relative_pointer_v1.c index e5568f5f..6f686431 100644 --- a/types/wlr_relative_pointer_v1.c +++ b/types/wlr_relative_pointer_v1.c @@ -19,7 +19,7 @@ static const struct zwp_relative_pointer_v1_interface relative_pointer_v1_impl; * helper functions */ -struct wlr_relative_pointer_v1 *relative_pointer_from_resource(struct wl_resource *resource) { +struct wlr_relative_pointer_v1 *wlr_relative_pointer_v1_from_resource(struct wl_resource *resource) { assert(wl_resource_instance_of(resource, &zwp_relative_pointer_v1_interface, &relative_pointer_v1_impl)); return wl_resource_get_user_data(resource); @@ -37,26 +37,42 @@ static struct wlr_relative_pointer_manager_v1 *relative_pointer_manager_from_res * relative_pointer handler functions */ -static void relative_pointer_v1_handle_resource_destroy(struct wl_resource *resource) { - struct wlr_relative_pointer_v1 *relative_pointer = - relative_pointer_from_resource(resource); +static void relative_pointer_destroy(struct wlr_relative_pointer_v1 *relative_pointer) { wlr_signal_emit_safe(&relative_pointer->events.destroy, relative_pointer); - wl_list_remove(wl_resource_get_link(resource)); + wl_list_remove(&relative_pointer->link); + wl_list_remove(&relative_pointer->seat_destroy.link); free(relative_pointer); } +static void relative_pointer_v1_handle_resource_destroy(struct wl_resource *resource) { + struct wlr_relative_pointer_v1 *relative_pointer = + wlr_relative_pointer_v1_from_resource(resource); + if (relative_pointer == NULL) { + return; + } + relative_pointer_destroy(relative_pointer); +} + static void relative_pointer_v1_handle_destroy(struct wl_client *client, struct wl_resource *resource) { struct wlr_relative_pointer_v1 *relative_pointer = - relative_pointer_from_resource(resource); + wlr_relative_pointer_v1_from_resource(resource); wlr_log(WLR_DEBUG, "relative_pointer_v1 %p released by client %p", relative_pointer, client); wl_resource_destroy(resource); } +static void relative_pointer_handle_seat_destroy(struct wl_listener *listener, + void *data) { + struct wlr_relative_pointer_v1 *relative_pointer = + wl_container_of(listener, relative_pointer, seat_destroy); + + relative_pointer_destroy(relative_pointer); + wl_resource_set_user_data(relative_pointer->resource, NULL); +} /** * relative_pointer_manager handler functions @@ -75,12 +91,10 @@ static void relative_pointer_manager_v1_handle_destroy(struct wl_client *client, client); } - static void relative_pointer_manager_v1_handle_get_relative_pointer(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *pointer) { struct wlr_seat_client *seat_client = wlr_seat_client_from_pointer_resource(pointer); - assert(seat_client->client == client); struct wlr_relative_pointer_v1 *relative_pointer = calloc(1, sizeof(struct wlr_relative_pointer_v1)); @@ -109,7 +123,11 @@ static void relative_pointer_manager_v1_handle_get_relative_pointer(struct wl_cl relative_pointer_manager_from_resource(resource); wl_list_insert(&relative_pointer_manager->relative_pointers, - wl_resource_get_link(relative_pointer_resource)); + &relative_pointer->link); + + wl_signal_add(&relative_pointer->seat->events.destroy, + &relative_pointer->seat_destroy); + relative_pointer->seat_destroy.notify = relative_pointer_handle_seat_destroy; wlr_signal_emit_safe(&relative_pointer_manager->events.new_relative_pointer, relative_pointer); @@ -141,9 +159,9 @@ static void relative_pointer_manager_v1_bind(struct wl_client *wl_client, void * } static void handle_display_destroy(struct wl_listener *listener, void *data) { - struct wlr_relative_pointer_manager_v1 *relative_pointer_manager = - wl_container_of(listener, relative_pointer_manager, display_destroy_listener); - wlr_relative_pointer_manager_v1_destroy(relative_pointer_manager); + struct wlr_relative_pointer_manager_v1 *manager = + wl_container_of(listener, manager, display_destroy_listener); + wlr_relative_pointer_manager_v1_destroy(manager); } @@ -222,13 +240,22 @@ void wlr_relative_pointer_manager_v1_destroy(struct wlr_relative_pointer_manager void wlr_relative_pointer_v1_send_relative_motion(struct wlr_relative_pointer_v1 *relative_pointer, uint64_t time, double dx, double dy, double dx_unaccel, double dy_unaccel) { + struct wlr_seat_client *client = + relative_pointer->seat->pointer_state.focused_client; + + if (client == NULL) { + return; + } zwp_relative_pointer_v1_send_relative_motion(relative_pointer->resource, (uint32_t)(time >> 32), (uint32_t)time, wl_fixed_from_double(dx), wl_fixed_from_double(dy), wl_fixed_from_double(dx_unaccel), wl_fixed_from_double(dy_unaccel)); -} - -struct wlr_relative_pointer_v1 *wlr_relative_pointer_v1_from_resource(struct wl_resource *resource) { - return relative_pointer_from_resource(resource); + struct wl_resource *resource; + wl_resource_for_each(resource, &client->pointers) { + if (wlr_seat_client_from_pointer_resource(resource) == NULL) { + continue; + } + wl_pointer_send_frame(resource); + } }