From 8b74450b398dbe9afa38fdad5e5b9335a2ac1d0b Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 20 Sep 2017 07:32:28 -0400 Subject: wlr_seat: pointer events --- examples/compositor.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/compositor.c b/examples/compositor.c index 63041615..7595c729 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include "wlr/types/wlr_compositor.h" @@ -27,6 +28,7 @@ #include #include "config.h" #include "shared.h" +#include // TODO: move to common header? int os_create_anonymous_file(off_t size); @@ -58,6 +60,8 @@ struct sample_state { struct wl_listener cursor_axis; struct wl_listener new_xdg_surface_v6; + + struct wlr_xdg_surface_v6 *focused_surface; }; struct example_xdg_surface_v6 { @@ -76,6 +80,25 @@ struct example_xdg_surface_v6 { struct wl_listener request_show_window_menu_listener; }; +static void example_set_focused_surface(struct sample_state *sample, + struct wlr_xdg_surface_v6 *surface) { + if (sample->focused_surface == surface) { + return; + } + + // set activated state of the xdg surfaces + struct wlr_xdg_surface_v6 *xdg_surface; + struct wlr_xdg_client_v6 *xdg_client; + wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { + wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { + wlr_xdg_toplevel_v6_set_activated(xdg_surface, + xdg_surface == surface); + } + } + + sample->focused_surface = surface; +} + /* * Convert timespec to milliseconds */ @@ -307,12 +330,53 @@ static void handle_keyboard_bound(struct wl_listener *listener, void *data) { } } +static struct wlr_xdg_surface_v6 *example_xdg_surface_at( + struct sample_state *sample, int lx, int ly) { + struct wlr_xdg_surface_v6 *xdg_surface; + struct wlr_xdg_client_v6 *xdg_client; + wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { + wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { + struct example_xdg_surface_v6 *esurface = xdg_surface->data; + + if (sample->cursor->x >= esurface->position.lx && + sample->cursor->y >= esurface->position.ly && + sample->cursor->x <= esurface->position.lx + + xdg_surface->geometry->width && + sample->cursor->y <= esurface->position.ly + + xdg_surface->geometry->height) { + return xdg_surface; + } + } + } + + return NULL; +} + static void handle_cursor_motion(struct wl_listener *listener, void *data) { struct sample_state *sample = wl_container_of(listener, sample, cursor_motion); struct wlr_event_pointer_motion *event = data; + wlr_cursor_move(sample->cursor, event->device, event->delta_x, event->delta_y); + + struct wlr_xdg_surface_v6 *surface = + example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y); + + if (surface) { + struct example_xdg_surface_v6 *esurface = surface->data; + + int32_t sx = sample->cursor->x - esurface->position.lx; + int32_t sy = sample->cursor->y - esurface->position.ly; + + // TODO z-order + wlr_seat_pointer_enter(sample->wl_seat, surface->surface, + sx, sy); + wlr_seat_pointer_send_motion(sample->wl_seat, event->time_sec, + sx, sy); + } else { + wlr_seat_pointer_clear_focus(sample->wl_seat); + } } static void handle_cursor_motion_absolute(struct wl_listener *listener, @@ -323,6 +387,8 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, wlr_cursor_warp_absolute(sample->cursor, event->device, event->x_mm, event->y_mm); + + // TODO move pointer } static void handle_cursor_axis(struct wl_listener *listener, void *data) { @@ -333,10 +399,17 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) { } static void handle_cursor_button(struct wl_listener *listener, void *data) { - //struct sample_state *sample = - //wl_container_of(listener, sample, cursor_button); - //struct wlr_event_pointer_button *event = data; - wlr_log(L_DEBUG, "TODO: handle cursor button"); + struct sample_state *sample = + wl_container_of(listener, sample, cursor_button); + struct wlr_event_pointer_button *event = data; + + struct wlr_xdg_surface_v6 *surface = + example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y); + + example_set_focused_surface(sample, surface); + + wlr_seat_pointer_send_button(sample->wl_seat, event->time_sec, + event->button, event->state); } static void handle_input_add(struct compositor_state *state, @@ -462,6 +535,7 @@ int main(int argc, char *argv[]) { wlr_gamma_control_manager_create(compositor.display); state.wl_seat = wlr_seat_create(compositor.display, "seat0"); + assert(state.wl_seat); state.keyboard_bound.notify = handle_keyboard_bound; wl_signal_add(&state.wl_seat->events.keyboard_bound, &state.keyboard_bound); wlr_seat_set_capabilities(state.wl_seat, WL_SEAT_CAPABILITY_KEYBOARD -- cgit v1.2.3 From 7a3edf6e6218b79e47541a0d5ebed64e094055b4 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 21 Sep 2017 11:38:04 -0400 Subject: use double for cursor coordinates --- examples/compositor.c | 4 ++-- include/wlr/types/wlr_cursor.h | 2 +- include/wlr/types/wlr_seat.h | 4 ++-- types/wlr_seat.c | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'examples') diff --git a/examples/compositor.c b/examples/compositor.c index 7595c729..24013c52 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -366,8 +366,8 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) { if (surface) { struct example_xdg_surface_v6 *esurface = surface->data; - int32_t sx = sample->cursor->x - esurface->position.lx; - int32_t sy = sample->cursor->y - esurface->position.ly; + double sx = sample->cursor->x - esurface->position.lx; + double sy = sample->cursor->y - esurface->position.ly; // TODO z-order wlr_seat_pointer_enter(sample->wl_seat, surface->surface, diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 5fc0ec76..88390e0d 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -11,7 +11,7 @@ struct wlr_cursor_state; struct wlr_cursor { struct wlr_cursor_state *state; - int x, y; + double x, y; struct { struct wl_signal motion; diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 2993d693..221e4489 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -88,7 +88,7 @@ bool wlr_seat_pointer_surface_has_focus(struct wlr_seat *wlr_seat, * surface that was entered. Coordinates for the enter event are surface-local. */ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, - struct wlr_surface *surface, int32_t sx, int32_t sy); + struct wlr_surface *surface, double sx, double sy); /** * Clear the focused surface for the pointer and leave all entered surfaces. @@ -100,7 +100,7 @@ void wlr_seat_pointer_clear_focus(struct wlr_seat *wlr_seat); * motion event are surface-local. */ void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time, - int32_t sx, int32_t sy); + double sx, double sy); /** * Send a button event to the surface with pointer focus. Coordinates for the diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 2a0a1dcd..411c1182 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -261,7 +261,7 @@ static void handle_pointer_focus_resource_destroyed( } void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, - struct wlr_surface *surface, int32_t sx, int32_t sy) { + struct wlr_surface *surface, double sx, double sy) { assert(wlr_seat); if (wlr_seat->pointer_state.focused_surface == surface) { @@ -293,7 +293,7 @@ void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat, if (handle) { uint32_t serial = wl_display_next_serial(wlr_seat->display); wl_pointer_send_enter(handle->pointer, serial, surface->resource, - wl_fixed_from_int(sx), wl_fixed_from_int(sy)); + wl_fixed_from_double(sx), wl_fixed_from_double(sy)); wl_pointer_send_frame(handle->pointer); } @@ -326,14 +326,14 @@ 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, - int32_t sx, int32_t sy) { + double sx, double sy) { if (!wlr_seat->pointer_state.focused_handle) { // nobody to send the event to return; } wl_pointer_send_motion(wlr_seat->pointer_state.focused_handle->pointer, - time, wl_fixed_from_int(sx), wl_fixed_from_int(sy)); + time, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); wl_pointer_send_frame(wlr_seat->pointer_state.focused_handle->pointer); } -- cgit v1.2.3 From 675a71dce789eb6aa3ba7e38ba137c9e4c6a5f07 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 21 Sep 2017 13:48:46 -0400 Subject: compositor.c: determine xdg position by window geom --- examples/compositor.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/compositor.c b/examples/compositor.c index 24013c52..7c4bed09 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -67,6 +67,7 @@ struct sample_state { struct example_xdg_surface_v6 { struct wlr_xdg_surface_v6 *surface; + // position of the wlr_surface in the layout struct { int lx; int ly; @@ -338,11 +339,14 @@ static struct wlr_xdg_surface_v6 *example_xdg_surface_at( wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { struct example_xdg_surface_v6 *esurface = xdg_surface->data; - if (sample->cursor->x >= esurface->position.lx && - sample->cursor->y >= esurface->position.ly && - sample->cursor->x <= esurface->position.lx + + double window_x = esurface->position.lx + xdg_surface->geometry->x; + double window_y = esurface->position.ly + xdg_surface->geometry->y; + + if (sample->cursor->x >= window_x && + sample->cursor->y >= window_y && + sample->cursor->x <= window_x + xdg_surface->geometry->width && - sample->cursor->y <= esurface->position.ly + + sample->cursor->y <= window_y + xdg_surface->geometry->height) { return xdg_surface; } -- cgit v1.2.3 From 91323a9b9b8f81bf5073894088574e0b98b9746e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 21 Sep 2017 14:05:14 -0400 Subject: compositor.c: add guards for unconfigured surfaces --- examples/compositor.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/compositor.c b/examples/compositor.c index 7c4bed09..02544b93 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -92,6 +92,10 @@ static void example_set_focused_surface(struct sample_state *sample, struct wlr_xdg_client_v6 *xdg_client; wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { + if (!xdg_surface->configured || + xdg_surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + continue; + } wlr_xdg_toplevel_v6_set_activated(xdg_surface, xdg_surface == surface); } @@ -246,11 +250,13 @@ static void handle_output_frame(struct output_state *output, struct wlr_xdg_client_v6 *xdg_client; wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { - if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_NONE) { + if (!xdg_surface->configured) { continue; } struct example_xdg_surface_v6 *esurface = xdg_surface->data; + assert(esurface); + int width = xdg_surface->surface->current.buffer_width; int height = xdg_surface->surface->current.buffer_height; @@ -337,6 +343,10 @@ static struct wlr_xdg_surface_v6 *example_xdg_surface_at( struct wlr_xdg_client_v6 *xdg_client; wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { + if (!xdg_surface->configured) { + continue; + } + struct example_xdg_surface_v6 *esurface = xdg_surface->data; double window_x = esurface->position.lx + xdg_surface->geometry->x; -- cgit v1.2.3 From 446adda1a3ad55b21522b9e81fd192c4a63510e7 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 21 Sep 2017 17:51:31 -0400 Subject: compositor.c: implement cursor motion absolute --- examples/compositor.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'examples') diff --git a/examples/compositor.c b/examples/compositor.c index 02544b93..fa5f3286 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -366,14 +366,8 @@ static struct wlr_xdg_surface_v6 *example_xdg_surface_at( return NULL; } -static void handle_cursor_motion(struct wl_listener *listener, void *data) { - struct sample_state *sample = - wl_container_of(listener, sample, cursor_motion); - struct wlr_event_pointer_motion *event = data; - - wlr_cursor_move(sample->cursor, event->device, event->delta_x, - event->delta_y); - +static void update_pointer_position(struct sample_state *sample, + uint32_t time_sec) { struct wlr_xdg_surface_v6 *surface = example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y); @@ -386,23 +380,34 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) { // TODO z-order wlr_seat_pointer_enter(sample->wl_seat, surface->surface, sx, sy); - wlr_seat_pointer_send_motion(sample->wl_seat, event->time_sec, + wlr_seat_pointer_send_motion(sample->wl_seat, time_sec, sx, sy); } else { wlr_seat_pointer_clear_focus(sample->wl_seat); } } +static void handle_cursor_motion(struct wl_listener *listener, void *data) { + struct sample_state *sample = + wl_container_of(listener, sample, cursor_motion); + struct wlr_event_pointer_motion *event = data; + + wlr_cursor_move(sample->cursor, event->device, event->delta_x, + event->delta_y); + + update_pointer_position(sample, event->time_sec); +} + static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { struct sample_state *sample = wl_container_of(listener, sample, cursor_motion_absolute); struct wlr_event_pointer_motion_absolute *event = data; - wlr_cursor_warp_absolute(sample->cursor, event->device, event->x_mm, - event->y_mm); + wlr_cursor_warp_absolute(sample->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); - // TODO move pointer + update_pointer_position(sample, event->time_sec); } static void handle_cursor_axis(struct wl_listener *listener, void *data) { -- cgit v1.2.3 From d558745633e83b47e08f362f44164f3965dac2f7 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 21 Sep 2017 18:30:04 -0400 Subject: Handle tablet motion in example compositor --- examples/compositor.c | 37 +++++++++++++++++++++++++++++++++++++ include/wlr/types/wlr_seat.h | 2 +- types/wlr_seat.c | 2 +- 3 files changed, 39 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/compositor.c b/examples/compositor.c index fa5f3286..085cbb0e 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -7,6 +7,8 @@ #include #include #include +// TODO: BSD et al +#include #include #include #include @@ -59,6 +61,10 @@ struct sample_state { struct wl_listener cursor_button; struct wl_listener cursor_axis; + struct wl_listener tool_axis; + struct wl_listener tool_tip; + struct wl_listener tool_button; + struct wl_listener new_xdg_surface_v6; struct wlr_xdg_surface_v6 *focused_surface; @@ -431,6 +437,31 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { event->button, event->state); } +static void handle_tool_axis(struct wl_listener *listener, void *data) { + struct sample_state *sample = + wl_container_of(listener, sample, tool_axis); + struct wlr_event_tablet_tool_axis *event = data; + if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && + (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { + wlr_cursor_warp_absolute(sample->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + update_pointer_position(sample, event->time_sec); + } +} + +static void handle_tool_tip(struct wl_listener *listener, void *data) { + struct sample_state *sample = + wl_container_of(listener, sample, tool_tip); + struct wlr_event_tablet_tool_tip *event = data; + + struct wlr_xdg_surface_v6 *surface = + example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y); + example_set_focused_surface(sample, surface); + + wlr_seat_pointer_send_button(sample->wl_seat, event->time_sec, + BTN_MOUSE, event->state); +} + static void handle_input_add(struct compositor_state *state, struct wlr_input_device *device) { struct sample_state *sample = state->data; @@ -528,6 +559,12 @@ int main(int argc, char *argv[]) { wl_signal_add(&state.cursor->events.axis, &state.cursor_axis); state.cursor_axis.notify = handle_cursor_axis; + wl_signal_add(&state.cursor->events.tablet_tool_axis, &state.tool_axis); + state.tool_axis.notify = handle_tool_axis; + + wl_signal_add(&state.cursor->events.tablet_tool_tip, &state.tool_tip); + state.tool_tip.notify = handle_tool_tip; + compositor_init(&compositor); state.renderer = wlr_gles2_renderer_create(compositor.backend); diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 221e4489..4b433ccb 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -107,6 +107,6 @@ void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time, * button event are surface-local. */ void wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time, - uint32_t button, enum wlr_button_state state); + uint32_t button, uint32_t state); #endif diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 411c1182..9a254b35 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -338,7 +338,7 @@ void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time, } void wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time, - uint32_t button, enum wlr_button_state state) { + uint32_t button, uint32_t state) { if (!wlr_seat->pointer_state.focused_handle) { // nobody to send the event to return; -- cgit v1.2.3