Implement pointer constraints v1 protocol

This commit is contained in:
Las 2018-04-19 18:11:08 +02:00
parent 8e32c4a1fb
commit 020edf5b49
7 changed files with 116 additions and 17 deletions

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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) {

View file

@ -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;
} }

View file

@ -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);