implement input_inhibit protocol, needed for swaylock

this is in "it appears to work" state, though I blindly copy-pasted a little
more code than I'm happy with, so might benefit from a review
This commit is contained in:
Daniel Barlow 2021-08-21 17:12:02 +01:00
parent 65f5bf189d
commit 39b1d92f9b
7 changed files with 212 additions and 8 deletions

View file

@ -5,6 +5,7 @@
#include <wlr/types/wlr_data_control_v1.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_input_inhibitor.h>
#include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_screencopy_v1.h>
#include "config/rcxml.h"
@ -78,6 +79,81 @@ drop_permissions(void)
}
}
static void seat_clear_touch_points(struct seat *seat,
struct wl_client *active_client){
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
struct wlr_touch_point *point;
wl_list_for_each(point, &seat->seat->touch_state.touch_points, link) {
if (point->client->client != active_client) {
wlr_seat_touch_point_clear_focus(seat->seat,
now.tv_nsec / 1000, point->touch_id);
}
}
}
static void seat_inhibit_input(struct seat *seat, struct wl_client *active_client)
{
seat->active_client_while_inhibited = active_client;
if(seat->focused_layer &&
(wl_resource_get_client(seat->focused_layer->resource) !=
active_client))
{
wlr_log(WLR_INFO, "defocus layer");
seat_set_focus_layer(seat, NULL); /* ? */
}
struct wlr_surface * previous_kb_surface = seat->seat->keyboard_state.focused_surface;
if (previous_kb_surface &&
wl_resource_get_client(previous_kb_surface->resource) != active_client) {
wlr_log(WLR_INFO, "defocus surface");
seat_focus_surface(seat, NULL); /* keyboard focus */
}
struct wlr_seat_client * previous_ptr_client = seat->seat->pointer_state.focused_client;
if (previous_ptr_client &&
(previous_ptr_client->client != active_client)) {
wlr_log(WLR_INFO, "defocus ptr");
wlr_seat_pointer_clear_focus(seat->seat);
}
seat_clear_touch_points(seat, active_client);
}
static void seat_disinhibit_input(struct seat *seat)
{
seat->active_client_while_inhibited = NULL;
// Triggers a refocus of the topmost surface layer if necessary
// TODO: Make layer surface focus per-output based on cursor position
/*
struct roots_output *output;
wl_list_for_each(output, &seat->input->server->desktop->outputs, link) {
arrange_layers(output);
*/
}
static void handle_input_inhibit(struct wl_listener *listener, void *data) {
wlr_log(WLR_INFO, "activate input inhibit");
struct server *server = wl_container_of(
listener, server, input_inhibit_activate);
seat_inhibit_input(&server->seat,
server->input_inhibit->active_client);
}
static void handle_input_disinhibit(struct wl_listener *listener, void *data) {
wlr_log(WLR_INFO, "deactivate input inhibit");
struct server *server = wl_container_of(
listener, server, input_inhibit_deactivate);
seat_disinhibit_input(&server->seat);
}
void
server_init(struct server *server)
{
@ -203,6 +279,19 @@ server_init(struct server *server)
wlr_data_control_manager_v1_create(server->wl_display);
wlr_gamma_control_manager_v1_create(server->wl_display);
// struct wlr_input_inhibit_manager *input_inhibit_mgr = NULL;
server->input_inhibit = wlr_input_inhibit_manager_create(server->wl_display);
if (!server->input_inhibit) {
wlr_log(WLR_ERROR, "unable to create the input inhibit manager");
exit(EXIT_FAILURE);
}
wl_signal_add(&server->input_inhibit->events.activate, &server->input_inhibit_activate);
server->input_inhibit_activate.notify = handle_input_inhibit;
wl_signal_add(&server->input_inhibit->events.deactivate, &server->input_inhibit_deactivate);
server->input_inhibit_deactivate.notify = handle_input_disinhibit;
server->foreign_toplevel_manager =
wlr_foreign_toplevel_manager_v1_create(server->wl_display);