aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-04-03 17:03:29 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-04-04 18:47:48 -0400
commitb7e779491232b825f6edc0b199e7564e93f1e332 (patch)
tree00457213fa57ec07692bb093392a83203e0e9960 /sway/input/seat.c
parentAdd input inhibitor to input manager (diff)
downloadsway-b7e779491232b825f6edc0b199e7564e93f1e332.tar.gz
sway-b7e779491232b825f6edc0b199e7564e93f1e332.tar.zst
sway-b7e779491232b825f6edc0b199e7564e93f1e332.zip
Implement input-inhibit in sway, swaylock
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c68
1 files changed, 61 insertions, 7 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 318fa9f6..0e26dde4 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1,5 +1,7 @@
1#define _XOPEN_SOURCE 700 1#define _XOPEN_SOURCE 700
2#define _POSIX_C_SOURCE 199309L
2#include <assert.h> 3#include <assert.h>
4#include <time.h>
3#include <wlr/types/wlr_cursor.h> 5#include <wlr/types/wlr_cursor.h>
4#include <wlr/types/wlr_output_layout.h> 6#include <wlr/types/wlr_output_layout.h>
5#include <wlr/types/wlr_xcursor_manager.h> 7#include <wlr/types/wlr_xcursor_manager.h>
@@ -9,6 +11,7 @@
9#include "sway/input/input-manager.h" 11#include "sway/input/input-manager.h"
10#include "sway/input/keyboard.h" 12#include "sway/input/keyboard.h"
11#include "sway/ipc-server.h" 13#include "sway/ipc-server.h"
14#include "sway/layers.h"
12#include "sway/output.h" 15#include "sway/output.h"
13#include "sway/tree/container.h" 16#include "sway/tree/container.h"
14#include "sway/tree/view.h" 17#include "sway/tree/view.h"
@@ -350,6 +353,11 @@ void seat_configure_xcursor(struct sway_seat *seat) {
350 seat->cursor->cursor->y); 353 seat->cursor->cursor->y);
351} 354}
352 355
356bool seat_allow_input(struct sway_seat *seat, struct wlr_surface *surface) {
357 struct wl_client *client = wl_resource_get_client(surface->resource);
358 return !seat->exclusive_client || seat->exclusive_client == client;
359}
360
353void seat_set_focus_warp(struct sway_seat *seat, 361void seat_set_focus_warp(struct sway_seat *seat,
354 struct sway_container *container, bool warp) { 362 struct sway_container *container, bool warp) {
355 if (seat->focused_layer) { 363 if (seat->focused_layer) {
@@ -371,6 +379,12 @@ void seat_set_focus_warp(struct sway_seat *seat,
371 wl_list_remove(&seat_con->link); 379 wl_list_remove(&seat_con->link);
372 wl_list_insert(&seat->focus_stack, &seat_con->link); 380 wl_list_insert(&seat->focus_stack, &seat_con->link);
373 381
382 if (container->type == C_VIEW && !seat_allow_input(
383 seat, container->sway_view->surface)) {
384 wlr_log(L_DEBUG, "Refusing to set focus, input is inhibited");
385 return;
386 }
387
374 if (container->type == C_VIEW) { 388 if (container->type == C_VIEW) {
375 seat_send_focus(seat, container); 389 seat_send_focus(seat, container);
376 } 390 }
@@ -426,13 +440,13 @@ void seat_set_focus_layer(struct sway_seat *seat,
426 struct wlr_layer_surface *layer) { 440 struct wlr_layer_surface *layer) {
427 if (!layer && seat->focused_layer) { 441 if (!layer && seat->focused_layer) {
428 seat->focused_layer = NULL; 442 seat->focused_layer = NULL;
429 struct sway_container *c = seat_get_focus(seat); 443 struct sway_container *previous = seat_get_focus(seat);
430 if (c) { 444 if (previous) {
431 wlr_log(L_DEBUG, "Returning focus to %p %s '%s'", c, 445 wlr_log(L_DEBUG, "Returning focus to %p %s '%s'", previous,
432 container_type_to_str(c->type), c->name); 446 container_type_to_str(previous->type), previous->name);
433 // Hack to get seat to re-focus the return value of get_focus 447 // Hack to get seat to re-focus the return value of get_focus
434 seat_set_focus(seat, c->parent); 448 seat_set_focus(seat, previous->parent);
435 seat_set_focus(seat, c); 449 seat_set_focus(seat, previous);
436 } 450 }
437 return; 451 return;
438 } else if (!layer || seat->focused_layer == layer) { 452 } else if (!layer || seat->focused_layer == layer) {
@@ -462,7 +476,47 @@ void seat_set_focus_layer(struct sway_seat *seat,
462 476
463void seat_set_exclusive_client(struct sway_seat *seat, 477void seat_set_exclusive_client(struct sway_seat *seat,
464 struct wl_client *client) { 478 struct wl_client *client) {
465 // TODO 479 if (!client) {
480 seat->exclusive_client = client;
481 // Triggers a refocus of the topmost surface layer if necessary
482 // TODO: Make layer surface focus per-output based on cursor position
483 for (int i = 0; i < root_container.children->length; ++i) {
484 struct sway_container *output = root_container.children->items[i];
485 if (!sway_assert(output->type == C_OUTPUT,
486 "root container has non-output child")) {
487 continue;
488 }
489 arrange_layers(output->sway_output);
490 }
491 return;
492 }
493 if (seat->focused_layer) {
494 if (wl_resource_get_client(seat->focused_layer->resource) != client) {
495 seat_set_focus_layer(seat, NULL);
496 }
497 }
498 if (seat->has_focus) {
499 struct sway_container *focus = seat_get_focus(seat);
500 if (focus->type == C_VIEW && wl_resource_get_client(
501 focus->sway_view->surface->resource) != client) {
502 seat_set_focus(seat, NULL);
503 }
504 }
505 if (seat->wlr_seat->pointer_state.focused_client) {
506 if (seat->wlr_seat->pointer_state.focused_client->client != client) {
507 wlr_seat_pointer_clear_focus(seat->wlr_seat);
508 }
509 }
510 struct timespec now;
511 clock_gettime(CLOCK_MONOTONIC, &now);
512 struct wlr_touch_point *point;
513 wl_list_for_each(point, &seat->wlr_seat->touch_state.touch_points, link) {
514 if (point->client->client != client) {
515 wlr_seat_touch_point_clear_focus(seat->wlr_seat,
516 now.tv_nsec / 1000, point->touch_id);
517 }
518 }
519 seat->exclusive_client = client;
466} 520}
467 521
468struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, 522struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,