This commit is contained in:
llyyr 2026-06-03 04:01:09 -04:00 committed by GitHub
commit 2c2a39384e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 0 deletions

View file

@ -147,4 +147,5 @@ const char *get_mouse_button_name(uint32_t button);
void handle_request_set_cursor_shape(struct wl_listener *listener, void *data);
void handle_pointer_warp(struct wl_listener *listener, void *data);
#endif

View file

@ -81,6 +81,9 @@ struct sway_server {
struct wlr_pointer_constraints_v1 *pointer_constraints;
struct wl_listener pointer_constraint;
struct wlr_pointer_warp_v1 *pointer_warp_v1;
struct wl_listener pointer_warp;
struct wlr_xdg_output_manager_v1 *xdg_output_manager_v1;
struct wlr_output_manager_v1 *output_manager_v1;

View file

@ -9,6 +9,7 @@
#include <wlr/types/wlr_cursor_shape_v1.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_relative_pointer_v1.h>
#include <wlr/types/wlr_pointer_warp_v1.h>
#include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_tablet_v2.h>
#include <wlr/types/wlr_tablet_pad.h>
@ -1415,3 +1416,43 @@ void handle_request_set_cursor_shape(struct wl_listener *listener, void *data) {
cursor_set_image(seat->cursor, wlr_cursor_shape_v1_name(event->shape), focused_client);
}
void handle_pointer_warp(struct wl_listener *listener, void *data) {
const struct wlr_pointer_warp_v1_event_warp *event = data;
struct sway_seat *seat = event->seat_client->seat->data;
struct sway_cursor *cursor = seat->cursor;
struct wl_client *focused_client = NULL;
struct wlr_surface *focused_surface =
cursor->seat->wlr_seat->pointer_state.focused_surface;
if (focused_surface != NULL) {
focused_client = wl_resource_get_client(focused_surface->resource);
}
if (focused_client == NULL || event->seat_client->client != focused_client) {
sway_log(SWAY_DEBUG, "denying request to warp cursor from unfocused client");
return;
}
struct wlr_box surface_box = {
.width = event->surface->current.width,
.height = event->surface->current.height,
};
if (!wlr_box_contains_point(&surface_box, event->x, event->y)) {
sway_log(SWAY_DEBUG, "denying request to warp cursor out of surface");
return;
}
struct sway_view *view = view_from_wlr_surface(event->surface);
if (view == NULL) {
return;
}
struct sway_container *con = view->container;
double lx = event->x + con->pending.content_x - view->geometry.x;
double ly = event->y + con->pending.content_y - view->geometry.y;
wlr_cursor_warp(cursor->cursor, NULL, lx, ly);
wlr_seat_pointer_warp(event->seat_client->seat, event->x, event->y);
cursor_rebase(cursor);
}

View file

@ -33,6 +33,7 @@
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_output_power_management_v1.h>
#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_pointer_warp_v1.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_relative_pointer_v1.h>
@ -426,6 +427,14 @@ bool server_init(struct sway_server *server) {
wl_signal_add(&server->pointer_constraints->events.new_constraint,
&server->pointer_constraint);
server->pointer_warp_v1 = wlr_pointer_warp_v1_create(server->wl_display, 1);
if (!server->pointer_warp_v1) {
sway_log(SWAY_ERROR, "Failed to create pointer warp");
return false;
}
server->pointer_warp.notify = handle_pointer_warp;
wl_signal_add(&server->pointer_warp_v1->events.warp, &server->pointer_warp);
if (!wlr_presentation_create(server->wl_display, server->backend, SWAY_PRESENTATION_VERSION)) {
sway_log(SWAY_ERROR, "Failed to create presentation");
return false;
@ -724,6 +733,7 @@ void server_fini(struct sway_server *server) {
wl_list_remove(&server->server_decoration.link);
wl_list_remove(&server->xdg_decoration.link);
wl_list_remove(&server->pointer_constraint.link);
wl_list_remove(&server->pointer_warp.link);
wl_list_remove(&server->output_manager_apply.link);
wl_list_remove(&server->output_manager_test.link);
wl_list_remove(&server->output_power_manager_set_mode.link);