mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
add pointer constraints
This commit is contained in:
parent
bd1e6f3728
commit
f5072151a9
5 changed files with 127 additions and 9 deletions
|
|
@ -23,7 +23,9 @@
|
||||||
#include <wlr/types/wlr_output_damage.h>
|
#include <wlr/types/wlr_output_damage.h>
|
||||||
#include <wlr/types/wlr_output_management_v1.h>
|
#include <wlr/types/wlr_output_management_v1.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
|
#include <wlr/types/wlr_relative_pointer_v1.h>
|
||||||
#include <wlr/types/wlr_pointer.h>
|
#include <wlr/types/wlr_pointer.h>
|
||||||
|
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||||
#include <wlr/types/wlr_seat.h>
|
#include <wlr/types/wlr_seat.h>
|
||||||
#include <wlr/types/wlr_server_decoration.h>
|
#include <wlr/types/wlr_server_decoration.h>
|
||||||
#include <wlr/types/wlr_xcursor_manager.h>
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
|
|
@ -72,6 +74,7 @@ struct seat {
|
||||||
struct wlr_cursor *cursor;
|
struct wlr_cursor *cursor;
|
||||||
struct wlr_xcursor_manager *xcursor_manager;
|
struct wlr_xcursor_manager *xcursor_manager;
|
||||||
struct wlr_drag_icon *drag_icon;
|
struct wlr_drag_icon *drag_icon;
|
||||||
|
struct wlr_pointer_constraint_v1 *current_constraint;
|
||||||
|
|
||||||
/* if set, views cannot receive focus */
|
/* if set, views cannot receive focus */
|
||||||
struct wlr_layer_surface_v1 *focused_layer;
|
struct wlr_layer_surface_v1 *focused_layer;
|
||||||
|
|
@ -96,6 +99,7 @@ struct seat {
|
||||||
struct wl_listener request_start_drag;
|
struct wl_listener request_start_drag;
|
||||||
struct wl_listener start_drag;
|
struct wl_listener start_drag;
|
||||||
struct wl_listener destroy_drag;
|
struct wl_listener destroy_drag;
|
||||||
|
struct wl_listener constraint_commit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct server {
|
struct server {
|
||||||
|
|
@ -143,6 +147,10 @@ struct server {
|
||||||
|
|
||||||
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
|
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
|
||||||
|
|
||||||
|
struct wlr_relative_pointer_manager_v1 *relative_pointer_manager;
|
||||||
|
struct wlr_pointer_constraints_v1 *constraints;
|
||||||
|
struct wl_listener new_constraint;
|
||||||
|
|
||||||
/* Set when in cycle (alt-tab) mode */
|
/* Set when in cycle (alt-tab) mode */
|
||||||
struct view *cycle_view;
|
struct view *cycle_view;
|
||||||
|
|
||||||
|
|
@ -312,6 +320,12 @@ struct xdg_popup {
|
||||||
struct wl_listener new_popup;
|
struct wl_listener new_popup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct constraint {
|
||||||
|
struct seat *seat;
|
||||||
|
struct wlr_pointer_constraint_v1 *constraint;
|
||||||
|
struct wl_listener destroy;
|
||||||
|
};
|
||||||
|
|
||||||
void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup);
|
void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup);
|
||||||
|
|
||||||
void xdg_toplevel_decoration(struct wl_listener *listener, void *data);
|
void xdg_toplevel_decoration(struct wl_listener *listener, void *data);
|
||||||
|
|
@ -435,4 +449,8 @@ void osd_update(struct server *server);
|
||||||
bool input_inhibit_blocks_surface(struct seat *seat,
|
bool input_inhibit_blocks_surface(struct seat *seat,
|
||||||
struct wl_resource *resource);
|
struct wl_resource *resource);
|
||||||
|
|
||||||
|
void create_constraint(struct wl_listener *listener, void *data);
|
||||||
|
void constrain_cursor(struct server *server, struct wlr_pointer_constraint_v1
|
||||||
|
*constraint);
|
||||||
|
|
||||||
#endif /* __LABWC_H */
|
#endif /* __LABWC_H */
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ wayland_scanner_server = generator(
|
||||||
|
|
||||||
server_protocols = [
|
server_protocols = [
|
||||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||||
|
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
||||||
['wlr-layer-shell-unstable-v1.xml'],
|
['wlr-layer-shell-unstable-v1.xml'],
|
||||||
['wlr-input-inhibitor-unstable-v1.xml'],
|
['wlr-input-inhibitor-unstable-v1.xml'],
|
||||||
]
|
]
|
||||||
|
|
|
||||||
101
src/cursor.c
101
src/cursor.c
|
|
@ -236,6 +236,81 @@ start_drag(struct wl_listener *listener, void *data)
|
||||||
wl_signal_add(&seat->drag_icon->events.destroy, &seat->destroy_drag);
|
wl_signal_add(&seat->drag_icon->events.destroy, &seat->destroy_drag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_constraint_commit(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct seat *seat = wl_container_of(listener, seat, constraint_commit);
|
||||||
|
struct wlr_pointer_constraint_v1 *constraint = seat->current_constraint;
|
||||||
|
assert(constraint->surface = data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
destroy_constraint(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct constraint *constraint = wl_container_of(listener, constraint,
|
||||||
|
destroy);
|
||||||
|
struct wlr_pointer_constraint_v1 *wlr_constraint = data;
|
||||||
|
struct seat *seat = constraint->seat;
|
||||||
|
|
||||||
|
wl_list_remove(&constraint->destroy.link);
|
||||||
|
if (seat->current_constraint == wlr_constraint) {
|
||||||
|
if (seat->constraint_commit.link.next != NULL) {
|
||||||
|
wl_list_remove(&seat->constraint_commit.link);
|
||||||
|
}
|
||||||
|
wl_list_init(&seat->constraint_commit.link);
|
||||||
|
seat->current_constraint = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
create_constraint(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct wlr_pointer_constraint_v1 *wlr_constraint = data;
|
||||||
|
struct server *server = wl_container_of(listener, server,
|
||||||
|
new_constraint);
|
||||||
|
struct view *view;
|
||||||
|
struct constraint *constraint = calloc(1, sizeof(struct constraint));
|
||||||
|
|
||||||
|
constraint->constraint = wlr_constraint;
|
||||||
|
constraint->seat = &server->seat;
|
||||||
|
constraint->destroy.notify = destroy_constraint;
|
||||||
|
wl_signal_add(&wlr_constraint->events.destroy, &constraint->destroy);
|
||||||
|
|
||||||
|
view = desktop_focused_view(server);
|
||||||
|
if (view->surface == wlr_constraint->surface) {
|
||||||
|
constrain_cursor(server, wlr_constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constrain_cursor(struct server *server, struct wlr_pointer_constraint_v1
|
||||||
|
*constraint)
|
||||||
|
{
|
||||||
|
struct seat *seat = &server->seat;
|
||||||
|
if (seat->current_constraint == constraint) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_list_remove(&seat->constraint_commit.link);
|
||||||
|
if (seat->current_constraint) {
|
||||||
|
wlr_pointer_constraint_v1_send_deactivated(
|
||||||
|
seat->current_constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
seat->current_constraint = constraint;
|
||||||
|
|
||||||
|
if (constraint == NULL) {
|
||||||
|
wl_list_init(&seat->constraint_commit.link);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_pointer_constraint_v1_send_activated(constraint);
|
||||||
|
seat->constraint_commit.notify = handle_constraint_commit;
|
||||||
|
wl_signal_add(&constraint->surface->events.commit,
|
||||||
|
&seat->constraint_commit);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cursor_motion(struct wl_listener *listener, void *data)
|
cursor_motion(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -244,17 +319,25 @@ cursor_motion(struct wl_listener *listener, void *data)
|
||||||
* _relative_ pointer motion event (i.e. a delta)
|
* _relative_ pointer motion event (i.e. a delta)
|
||||||
*/
|
*/
|
||||||
struct seat *seat = wl_container_of(listener, seat, cursor_motion);
|
struct seat *seat = wl_container_of(listener, seat, cursor_motion);
|
||||||
|
struct server *server = seat->server;
|
||||||
struct wlr_event_pointer_motion *event = data;
|
struct wlr_event_pointer_motion *event = data;
|
||||||
|
|
||||||
/*
|
wlr_relative_pointer_manager_v1_send_relative_motion(
|
||||||
* The cursor doesn't move unless we tell it to. The cursor
|
server->relative_pointer_manager,
|
||||||
* automatically handles constraining the motion to the output layout,
|
seat->seat, (uint64_t)event->time_msec * 1000,
|
||||||
* as well as any special configuration applied for the specific input
|
event->delta_x, event->delta_y, event->unaccel_dx,
|
||||||
* device which generated the event. You can pass NULL for the device
|
event->unaccel_dy);
|
||||||
* if you want to move the cursor around without any input.
|
if (!seat->current_constraint) {
|
||||||
*/
|
/*
|
||||||
wlr_cursor_move(seat->cursor, event->device, event->delta_x,
|
* The cursor doesn't move unless we tell it to. The cursor
|
||||||
event->delta_y);
|
* automatically handles constraining the motion to the output layout,
|
||||||
|
* as well as any special configuration applied for the specific input
|
||||||
|
* device which generated the event. You can pass NULL for the device
|
||||||
|
* if you want to move the cursor around without any input.
|
||||||
|
*/
|
||||||
|
wlr_cursor_move(seat->cursor, event->device, event->delta_x,
|
||||||
|
event->delta_y);
|
||||||
|
}
|
||||||
process_cursor_motion(seat->server, event->time_msec);
|
process_cursor_motion(seat->server, event->time_msec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,7 @@ seat_init(struct server *server)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_list_init(&seat->constraint_commit.link);
|
||||||
wl_list_init(&seat->inputs);
|
wl_list_init(&seat->inputs);
|
||||||
seat->new_input.notify = new_input_notify;
|
seat->new_input.notify = new_input_notify;
|
||||||
wl_signal_add(&server->backend->events.new_input, &seat->new_input);
|
wl_signal_add(&server->backend->events.new_input, &seat->new_input);
|
||||||
|
|
@ -242,6 +243,12 @@ seat_focus_surface(struct seat *seat, struct wlr_surface *surface)
|
||||||
struct wlr_keyboard *kb = &seat->keyboard_group->keyboard;
|
struct wlr_keyboard *kb = &seat->keyboard_group->keyboard;
|
||||||
wlr_seat_keyboard_notify_enter(seat->seat, surface, kb->keycodes,
|
wlr_seat_keyboard_notify_enter(seat->seat, surface, kb->keycodes,
|
||||||
kb->num_keycodes, &kb->modifiers);
|
kb->num_keycodes, &kb->modifiers);
|
||||||
|
|
||||||
|
struct server *server = seat->server;
|
||||||
|
struct wlr_pointer_constraint_v1 *constraint =
|
||||||
|
wlr_pointer_constraints_v1_constraint_for_surface(server->constraints,
|
||||||
|
surface, seat->seat);
|
||||||
|
constrain_cursor(server, constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,15 @@ server_init(struct server *server)
|
||||||
wlr_data_control_manager_v1_create(server->wl_display);
|
wlr_data_control_manager_v1_create(server->wl_display);
|
||||||
wlr_gamma_control_manager_v1_create(server->wl_display);
|
wlr_gamma_control_manager_v1_create(server->wl_display);
|
||||||
|
|
||||||
|
server->relative_pointer_manager = wlr_relative_pointer_manager_v1_create(
|
||||||
|
server->wl_display);
|
||||||
|
server->constraints = wlr_pointer_constraints_v1_create(
|
||||||
|
server->wl_display);
|
||||||
|
|
||||||
|
server->new_constraint.notify = create_constraint;
|
||||||
|
wl_signal_add(&server->constraints->events.new_constraint,
|
||||||
|
&server->new_constraint);
|
||||||
|
|
||||||
server->input_inhibit =
|
server->input_inhibit =
|
||||||
wlr_input_inhibit_manager_create(server->wl_display);
|
wlr_input_inhibit_manager_create(server->wl_display);
|
||||||
if (!server->input_inhibit) {
|
if (!server->input_inhibit) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue