diff options
Diffstat (limited to 'rootston/desktop.c')
-rw-r--r-- | rootston/desktop.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/rootston/desktop.c b/rootston/desktop.c index e120508d..d469c263 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -15,6 +15,7 @@ #include <wlr/types/wlr_input_inhibitor.h> #include <wlr/types/wlr_layer_shell_v1.h> #include <wlr/types/wlr_output_layout.h> +#include <wlr/types/wlr_pointer_constraints_v1.h> #include <wlr/types/wlr_primary_selection.h> #include <wlr/types/wlr_server_decoration.h> #include <wlr/types/wlr_wl_shell.h> @@ -776,6 +777,53 @@ static void input_inhibit_deactivate(struct wl_listener *listener, void *data) { } } +static void handle_constraint_create( + struct wl_listener *listener, + struct wlr_pointer_constraint_v1 *constraint) { + struct roots_seat* seat = constraint->seat->data; + + double sx, sy; + struct wlr_surface *surface = desktop_surface_at(seat->input->server->desktop, + seat->cursor->cursor->x, seat->cursor->cursor->y, &sx, &sy, NULL); + + if (surface == constraint->surface) { + assert(!seat->cursor->active_constraint); + roots_cursor_constrain(seat->cursor, constraint, sx, sy); + } +} + +static void handle_constraint_destroy( + struct wl_listener *listener, + struct wlr_pointer_constraint_v1 *constraint) { + struct roots_seat* seat = constraint->seat->data; + if (seat->cursor->active_constraint == constraint) { + roots_cursor_constrain(seat->cursor, NULL, NAN, NAN); + if (constraint->current.cursor_hint.valid && seat->cursor->pointer_view) { + double sx = constraint->current.cursor_hint.x; + double sy = constraint->current.cursor_hint.y; + + struct roots_view *view = seat->cursor->pointer_view->view; + + double lx, ly; + if (view->rotation == 0.0) { + lx = sx + view->x; + ly = sy + view->y; + } else { + double c = cos(view->rotation); + double s = sin(view->rotation); + + double center_x = view->width / 2.; + double center_y = view->height / 2.; + + lx = c * (sx - center_x) - s * (sy - center_y) + center_x + view->x; + ly = s * (sx - center_x) + c * (sy - center_y) + center_y + view->y; + } + + wlr_cursor_warp(seat->cursor->cursor, NULL, lx, ly); + } + } +} + struct roots_desktop *desktop_create(struct roots_server *server, struct roots_config *config) { wlr_log(WLR_DEBUG, "Initializing roots desktop"); @@ -906,6 +954,14 @@ struct roots_desktop *desktop_create(struct roots_server *server, &desktop->xdg_toplevel_decoration); desktop->xdg_toplevel_decoration.notify = handle_xdg_toplevel_decoration; + desktop->pointer_constraints = wlr_pointer_constraints_v1_create(server->wl_display); + desktop->constraint_destroy.notify = (wl_notify_func_t)handle_constraint_destroy; + wl_signal_add(&desktop->pointer_constraints->events.constraint_destroy, + &desktop->constraint_destroy); + desktop->constraint_create.notify = (wl_notify_func_t)handle_constraint_create; + wl_signal_add(&desktop->pointer_constraints->events.constraint_create, + &desktop->constraint_create); + return desktop; } |