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
|
#ifndef _SWAY_INPUT_CURSOR_H
|
||||||
#define _SWAY_INPUT_CURSOR_H
|
#define _SWAY_INPUT_CURSOR_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||||
#include "sway/input/seat.h"
|
#include "sway/input/seat.h"
|
||||||
|
|
||||||
struct sway_cursor {
|
struct sway_cursor {
|
||||||
|
|
@ -8,6 +9,9 @@ struct sway_cursor {
|
||||||
struct wlr_cursor *cursor;
|
struct wlr_cursor *cursor;
|
||||||
struct wlr_xcursor_manager *xcursor_manager;
|
struct wlr_xcursor_manager *xcursor_manager;
|
||||||
|
|
||||||
|
struct wlr_box *mapped_box;
|
||||||
|
bool locked;
|
||||||
|
|
||||||
struct wl_client *image_client;
|
struct wl_client *image_client;
|
||||||
|
|
||||||
struct wl_listener motion;
|
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,
|
void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec,
|
||||||
uint32_t button, enum wlr_button_state state);
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
#include <wlr/types/wlr_data_device.h>
|
#include <wlr/types/wlr_data_device.h>
|
||||||
#include <wlr/types/wlr_layer_shell.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/types/wlr_xdg_shell_v6.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
// TODO WLR: make Xwayland optional
|
// TODO WLR: make Xwayland optional
|
||||||
|
|
@ -39,6 +40,11 @@ struct sway_server {
|
||||||
|
|
||||||
struct wlr_wl_shell *wl_shell;
|
struct wlr_wl_shell *wl_shell;
|
||||||
struct wl_listener wl_shell_surface;
|
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;
|
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_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,
|
void view_for_each_surface(struct sway_view *view,
|
||||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <dev/evdev/input-event-codes.h>
|
#include <dev/evdev/input-event-codes.h>
|
||||||
#endif
|
#endif
|
||||||
#include <wlr/types/wlr_cursor.h>
|
#include <wlr/types/wlr_cursor.h>
|
||||||
|
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||||
#include <wlr/types/wlr_xcursor_manager.h>
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
@ -163,19 +164,23 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time) {
|
||||||
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
||||||
struct sway_cursor *cursor = wl_container_of(listener, cursor, motion);
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, motion);
|
||||||
struct wlr_event_pointer_motion *event = data;
|
struct wlr_event_pointer_motion *event = data;
|
||||||
|
if (!cursor->locked) {
|
||||||
wlr_cursor_move(cursor->cursor, event->device,
|
wlr_cursor_move(cursor->cursor, event->device,
|
||||||
event->delta_x, event->delta_y);
|
event->delta_x, event->delta_y);
|
||||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_cursor_motion_absolute(
|
static void handle_cursor_motion_absolute(
|
||||||
struct wl_listener *listener, void *data) {
|
struct wl_listener *listener, void *data) {
|
||||||
struct sway_cursor *cursor =
|
struct sway_cursor *cursor =
|
||||||
wl_container_of(listener, cursor, motion_absolute);
|
wl_container_of(listener, cursor, motion_absolute);
|
||||||
struct wlr_event_pointer_motion_absolute *event = data;
|
struct wlr_event_pointer_motion_absolute *event = data;
|
||||||
|
if (!cursor->locked) {
|
||||||
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
|
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
|
||||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dispatch_cursor_button(struct sway_cursor *cursor,
|
void dispatch_cursor_button(struct sway_cursor *cursor,
|
||||||
uint32_t time_msec, uint32_t button, enum wlr_button_state state) {
|
uint32_t time_msec, uint32_t button, enum wlr_button_state state) {
|
||||||
|
|
@ -252,6 +257,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
|
||||||
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis);
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis);
|
||||||
struct wlr_event_tablet_tool_axis *event = data;
|
struct wlr_event_tablet_tool_axis *event = data;
|
||||||
|
|
||||||
|
if (!cursor->locked) {
|
||||||
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) &&
|
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) &&
|
||||||
(event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) {
|
(event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) {
|
||||||
wlr_cursor_warp_absolute(cursor->cursor, event->device,
|
wlr_cursor_warp_absolute(cursor->cursor, event->device,
|
||||||
|
|
@ -265,6 +271,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
|
||||||
cursor_send_pointer_motion(cursor, event->time_msec);
|
cursor_send_pointer_motion(cursor, event->time_msec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_tool_tip(struct wl_listener *listener, void *data) {
|
static void handle_tool_tip(struct wl_listener *listener, void *data) {
|
||||||
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip);
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip);
|
||||||
|
|
@ -322,6 +329,60 @@ static void handle_request_set_cursor(struct wl_listener *listener,
|
||||||
cursor->image_client = focused_client;
|
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) {
|
void sway_cursor_destroy(struct sway_cursor *cursor) {
|
||||||
if (!cursor) {
|
if (!cursor) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,8 @@ struct sway_seat *seat_create(struct sway_input_manager *input,
|
||||||
free(seat);
|
free(seat);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
seat->wlr_seat->data = seat;
|
||||||
|
seat->wlr_seat->pointer_constraints = input->server->pointer_constraints;
|
||||||
|
|
||||||
seat->cursor = sway_cursor_create(seat);
|
seat->cursor = sway_cursor_create(seat);
|
||||||
if (!seat->cursor) {
|
if (!seat->cursor) {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include <wlr/xwayland.h>
|
#include <wlr/xwayland.h>
|
||||||
#include "sway/commands.h"
|
#include "sway/commands.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
|
#include "sway/input/cursor.h"
|
||||||
#include "sway/input/input-manager.h"
|
#include "sway/input/input-manager.h"
|
||||||
#include "sway/server.h"
|
#include "sway/server.h"
|
||||||
#include "sway/tree/layout.h"
|
#include "sway/tree/layout.h"
|
||||||
|
|
@ -120,6 +121,17 @@ bool server_init(struct sway_server *server) {
|
||||||
return false;
|
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);
|
input_manager = input_manager_create(server);
|
||||||
return true;
|
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);
|
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
||||||
|
|
||||||
box->x = output->x + view->swayc->x;
|
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);
|
struct sway_container *cont = container_view_create(focus, view);
|
||||||
|
|
||||||
view->surface = wlr_surface;
|
view->surface = wlr_surface;
|
||||||
|
wlr_surface->data = view;
|
||||||
view->swayc = cont;
|
view->swayc = cont;
|
||||||
|
|
||||||
view_init_subsurfaces(view, wlr_surface);
|
view_init_subsurfaces(view, wlr_surface);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue