mirror of
https://github.com/swaywm/sway.git
synced 2026-05-03 06:46:26 -04:00
Implement pointer constraints v1 protocol
This commit is contained in:
parent
8e32c4a1fb
commit
020edf5b49
7 changed files with 116 additions and 17 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _SWAY_INPUT_CURSOR_H
|
||||
#define _SWAY_INPUT_CURSOR_H
|
||||
#include <stdint.h>
|
||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||
#include "sway/input/seat.h"
|
||||
|
||||
struct sway_cursor {
|
||||
|
|
@ -8,6 +9,9 @@ struct sway_cursor {
|
|||
struct wlr_cursor *cursor;
|
||||
struct wlr_xcursor_manager *xcursor_manager;
|
||||
|
||||
struct wlr_box *mapped_box;
|
||||
bool locked;
|
||||
|
||||
struct wl_client *image_client;
|
||||
|
||||
struct wl_listener motion;
|
||||
|
|
@ -33,4 +37,15 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time);
|
|||
void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec,
|
||||
uint32_t button, enum wlr_button_state state);
|
||||
|
||||
void cursor_handle_constraint_inactive(
|
||||
struct wl_listener *listener,
|
||||
struct wlr_pointer_constraint_v1 *constraint);
|
||||
|
||||
void cursor_handle_constraint_active(
|
||||
struct wl_listener *listener,
|
||||
struct wlr_pointer_constraint_v1_activation *activation);
|
||||
|
||||
void cursor_handle_request_constraint(struct wl_listener *listener,
|
||||
struct wlr_pointer_constraint_v1 *constraint);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_layer_shell.h>
|
||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||
#include <wlr/types/wlr_xdg_shell_v6.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
// TODO WLR: make Xwayland optional
|
||||
|
|
@ -39,6 +40,11 @@ struct sway_server {
|
|||
|
||||
struct wlr_wl_shell *wl_shell;
|
||||
struct wl_listener wl_shell_surface;
|
||||
|
||||
struct wlr_pointer_constraints_v1 *pointer_constraints;
|
||||
struct wl_listener constraint_active;
|
||||
struct wl_listener constraint_inactive;
|
||||
struct wl_listener request_constraint;
|
||||
};
|
||||
|
||||
struct sway_server server;
|
||||
|
|
|
|||
|
|
@ -168,6 +168,8 @@ void view_close(struct sway_view *view);
|
|||
|
||||
void view_damage(struct sway_view *view, bool whole);
|
||||
|
||||
void view_get_layout_box(struct sway_view *view, struct wlr_box *box);
|
||||
|
||||
void view_for_each_surface(struct sway_view *view,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <dev/evdev/input-event-codes.h>
|
||||
#endif
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||
#include <wlr/types/wlr_xcursor_manager.h>
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
|
@ -163,9 +164,11 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time) {
|
|||
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
||||
struct sway_cursor *cursor = wl_container_of(listener, cursor, motion);
|
||||
struct wlr_event_pointer_motion *event = data;
|
||||
wlr_cursor_move(cursor->cursor, event->device,
|
||||
event->delta_x, event->delta_y);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
if (!cursor->locked) {
|
||||
wlr_cursor_move(cursor->cursor, event->device,
|
||||
event->delta_x, event->delta_y);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_cursor_motion_absolute(
|
||||
|
|
@ -173,8 +176,10 @@ static void handle_cursor_motion_absolute(
|
|||
struct sway_cursor *cursor =
|
||||
wl_container_of(listener, cursor, motion_absolute);
|
||||
struct wlr_event_pointer_motion_absolute *event = data;
|
||||
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
if (!cursor->locked) {
|
||||
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch_cursor_button(struct sway_cursor *cursor,
|
||||
|
|
@ -252,17 +257,19 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
|
|||
struct sway_cursor *cursor = wl_container_of(listener, cursor, 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(cursor->cursor, event->device,
|
||||
event->x, event->y);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
} else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) {
|
||||
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, -1);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
} else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) {
|
||||
wlr_cursor_warp_absolute(cursor->cursor, event->device, -1, event->y);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
if (!cursor->locked) {
|
||||
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) &&
|
||||
(event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) {
|
||||
wlr_cursor_warp_absolute(cursor->cursor, event->device,
|
||||
event->x, event->y);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
} else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) {
|
||||
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, -1);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
} else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) {
|
||||
wlr_cursor_warp_absolute(cursor->cursor, event->device, -1, event->y);
|
||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -322,6 +329,60 @@ static void handle_request_set_cursor(struct wl_listener *listener,
|
|||
cursor->image_client = focused_client;
|
||||
}
|
||||
|
||||
void cursor_handle_constraint_inactive(
|
||||
struct wl_listener *listener,
|
||||
struct wlr_pointer_constraint_v1 *constraint) {
|
||||
struct sway_seat *seat = constraint->seat_client->seat->data;
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
|
||||
if (constraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED) {
|
||||
wlr_cursor_map_to_region(cursor->cursor, NULL);
|
||||
free(cursor->mapped_box);
|
||||
cursor->mapped_box = NULL;
|
||||
} else {
|
||||
struct sway_view *view = constraint->surface->data;
|
||||
|
||||
seat->cursor->locked = false;
|
||||
if (constraint->current.cursor_hint.valid) {
|
||||
struct wlr_box view_box;
|
||||
view_get_layout_box(view, &view_box);
|
||||
wlr_cursor_warp(cursor->cursor, NULL,
|
||||
view_box.x + constraint->current.cursor_hint.x,
|
||||
view_box.y + constraint->current.cursor_hint.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cursor_handle_constraint_active(
|
||||
struct wl_listener *listener,
|
||||
struct wlr_pointer_constraint_v1_activation *activation) {
|
||||
struct wlr_box *box = activation->box;
|
||||
struct wlr_pointer_constraint_v1 *constraint = activation->pointer_constraint;
|
||||
struct sway_seat* seat = constraint->seat_client->seat->data;
|
||||
|
||||
if (constraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED) {
|
||||
struct sway_view *view = constraint->surface->data;
|
||||
if (!box) {
|
||||
box = calloc(1, sizeof *box);
|
||||
view_get_layout_box(view, box);
|
||||
} else {
|
||||
struct wlr_box view_box;
|
||||
view_get_layout_box(view, &view_box);
|
||||
box->x += view_box.x;
|
||||
box->y += view_box.y;
|
||||
}
|
||||
seat->cursor->mapped_box = box;
|
||||
wlr_cursor_map_to_region(seat->cursor->cursor, box);
|
||||
} else {
|
||||
seat->cursor->locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
void cursor_handle_request_constraint(struct wl_listener *listener,
|
||||
struct wlr_pointer_constraint_v1 *constraint) {
|
||||
wlr_pointer_constraint_v1_accept(constraint);
|
||||
}
|
||||
|
||||
void sway_cursor_destroy(struct sway_cursor *cursor) {
|
||||
if (!cursor) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -227,6 +227,8 @@ struct sway_seat *seat_create(struct sway_input_manager *input,
|
|||
free(seat);
|
||||
return NULL;
|
||||
}
|
||||
seat->wlr_seat->data = seat;
|
||||
seat->wlr_seat->pointer_constraints = input->server->pointer_constraints;
|
||||
|
||||
seat->cursor = sway_cursor_create(seat);
|
||||
if (!seat->cursor) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <wlr/xwayland.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/layout.h"
|
||||
|
|
@ -120,6 +121,17 @@ bool server_init(struct sway_server *server) {
|
|||
return false;
|
||||
}
|
||||
|
||||
server->pointer_constraints = wlr_pointer_constraints_v1_create(server->wl_display);
|
||||
server->constraint_inactive.notify = (wl_notify_func_t)cursor_handle_constraint_inactive;
|
||||
wl_signal_add(&server->pointer_constraints->events.constraint_inactive,
|
||||
&server->constraint_inactive);
|
||||
server->constraint_active.notify = (wl_notify_func_t)cursor_handle_constraint_active;
|
||||
wl_signal_add(&server->pointer_constraints->events.constraint_active,
|
||||
&server->constraint_active);
|
||||
server->request_constraint.notify = (wl_notify_func_t)cursor_handle_request_constraint;
|
||||
wl_signal_add(&server->pointer_constraints->events.request_constraint,
|
||||
&server->request_constraint);
|
||||
|
||||
input_manager = input_manager_create(server);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ void view_damage(struct sway_view *view, bool whole) {
|
|||
}
|
||||
}
|
||||
|
||||
static void view_get_layout_box(struct sway_view *view, struct wlr_box *box) {
|
||||
void view_get_layout_box(struct sway_view *view, struct wlr_box *box) {
|
||||
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
||||
|
||||
box->x = output->x + view->swayc->x;
|
||||
|
|
@ -219,6 +219,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
|
|||
struct sway_container *cont = container_view_create(focus, view);
|
||||
|
||||
view->surface = wlr_surface;
|
||||
wlr_surface->data = view;
|
||||
view->swayc = cont;
|
||||
|
||||
view_init_subsurfaces(view, wlr_surface);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue