aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Michael Weiser <michael.weiser@gmx.de>2020-03-12 22:10:04 +0100
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2020-05-13 21:22:16 -0400
commit0f11aa037ad8765abf66e0c90052f9e4c37d56db (patch)
treee78523c566a1a96d53098bfc7c1d1f104043d373
parentImplement pointer simulation if client hasn't bound to touch (diff)
downloadsway-0f11aa037ad8765abf66e0c90052f9e4c37d56db.tar.gz
sway-0f11aa037ad8765abf66e0c90052f9e4c37d56db.tar.zst
sway-0f11aa037ad8765abf66e0c90052f9e4c37d56db.zip
commands: Add per-view shortcuts_inhibitor command
Add a separate per-view shortcuts_inhibitor command that can be used with criteria to override the per-seat defaults. This allows to e.g. disable shortcuts inhibiting globally but enable it for specific, known-good virtualization and remote desktop software or, alternatively, to blacklist that one slightly broken piece of software that just doesn't seem to get it right but insists on trying. Add a flag to sway_view and handling logic in the input manager that respects that flag if configured but falls back to per-seat config otherwise. Add the actual command but with just enable and disable subcommands since there's no value in duplicating the per-seat activate/deactivate/toggle logic here. Split the inhibitor retrieval helper in two so we can use the backend half in the command to retrieve inhibitors for a specific surface and not just the currently focused one. Extend the manual page with documentation of the command and references to its per-seat sibling and usefulness with criteria. Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/input/seat.h8
-rw-r--r--include/sway/tree/view.h2
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/shortcuts_inhibitor.c49
-rw-r--r--sway/input/input-manager.c22
-rw-r--r--sway/input/seat.c16
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.scd11
-rw-r--r--sway/tree/view.c1
10 files changed, 103 insertions, 9 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index 3fde0893..4a2f8c20 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -164,6 +164,7 @@ sway_cmd cmd_resize;
164sway_cmd cmd_scratchpad; 164sway_cmd cmd_scratchpad;
165sway_cmd cmd_seamless_mouse; 165sway_cmd cmd_seamless_mouse;
166sway_cmd cmd_set; 166sway_cmd cmd_set;
167sway_cmd cmd_shortcuts_inhibitor;
167sway_cmd cmd_show_marks; 168sway_cmd cmd_show_marks;
168sway_cmd cmd_smart_borders; 169sway_cmd cmd_smart_borders;
169sway_cmd cmd_smart_gaps; 170sway_cmd cmd_smart_gaps;
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index fa232aa2..6a46fa91 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -295,6 +295,14 @@ void seatop_render(struct sway_seat *seat, struct sway_output *output,
295bool seatop_allows_set_cursor(struct sway_seat *seat); 295bool seatop_allows_set_cursor(struct sway_seat *seat);
296 296
297/** 297/**
298 * Returns the keyboard shortcuts inhibitor that applies to the given surface
299 * or NULL if none exists.
300 */
301struct sway_keyboard_shortcuts_inhibitor *
302keyboard_shortcuts_inhibitor_get_for_surface(const struct sway_seat *seat,
303 const struct wlr_surface *surface);
304
305/**
298 * Returns the keyboard shortcuts inhibitor that applies to the currently 306 * Returns the keyboard shortcuts inhibitor that applies to the currently
299 * focused surface of a seat or NULL if none exists. 307 * focused surface of a seat or NULL if none exists.
300 */ 308 */
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 4d3532d2..9230f456 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -110,6 +110,8 @@ struct sway_view {
110 struct wl_listener surface_new_subsurface; 110 struct wl_listener surface_new_subsurface;
111 111
112 int max_render_time; // In milliseconds 112 int max_render_time; // In milliseconds
113
114 enum seat_config_shortcuts_inhibit shortcuts_inhibit;
113}; 115};
114 116
115struct sway_xdg_shell_view { 117struct sway_xdg_shell_view {
diff --git a/sway/commands.c b/sway/commands.c
index 6a56ff5a..afe05b26 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -127,6 +127,7 @@ static struct cmd_handler command_handlers[] = {
127 { "rename", cmd_rename }, 127 { "rename", cmd_rename },
128 { "resize", cmd_resize }, 128 { "resize", cmd_resize },
129 { "scratchpad", cmd_scratchpad }, 129 { "scratchpad", cmd_scratchpad },
130 { "shortcuts_inhibitor", cmd_shortcuts_inhibitor },
130 { "split", cmd_split }, 131 { "split", cmd_split },
131 { "splith", cmd_splith }, 132 { "splith", cmd_splith },
132 { "splitt", cmd_splitt }, 133 { "splitt", cmd_splitt },
diff --git a/sway/commands/shortcuts_inhibitor.c b/sway/commands/shortcuts_inhibitor.c
new file mode 100644
index 00000000..ffa1a5c9
--- /dev/null
+++ b/sway/commands/shortcuts_inhibitor.c
@@ -0,0 +1,49 @@
1#include <string.h>
2#include "log.h"
3#include "sway/commands.h"
4#include "sway/config.h"
5#include "sway/input/seat.h"
6#include "sway/tree/container.h"
7#include "sway/tree/view.h"
8
9struct cmd_results *cmd_shortcuts_inhibitor(int argc, char **argv) {
10 struct cmd_results *error = NULL;
11 if ((error = checkarg(argc, "shortcuts_inhibitor", EXPECTED_EQUAL_TO, 1))) {
12 return error;
13 }
14
15 struct sway_container *con = config->handler_context.container;
16 if (!con || !con->view) {
17 return cmd_results_new(CMD_INVALID,
18 "Only views can have shortcuts inhibitors");
19 }
20
21 struct sway_view *view = con->view;
22 if (strcmp(argv[0], "enable") == 0) {
23 view->shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
24 } else if (strcmp(argv[0], "disable") == 0) {
25 view->shortcuts_inhibit = SHORTCUTS_INHIBIT_DISABLE;
26
27 struct sway_seat *seat = NULL;
28 wl_list_for_each(seat, &server.input->seats, link) {
29 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
30 keyboard_shortcuts_inhibitor_get_for_surface(
31 seat, view->surface);
32 if (!sway_inhibitor) {
33 continue;
34 }
35
36 wlr_keyboard_shortcuts_inhibitor_v1_deactivate(
37 sway_inhibitor->inhibitor);
38 sway_log(SWAY_DEBUG, "Deactivated keyboard shortcuts "
39 "inhibitor for seat %s on view",
40 seat->wlr_seat->name);
41
42 }
43 } else {
44 return cmd_results_new(CMD_INVALID,
45 "Expected `shortcuts_inhibitor enable|disable`");
46 }
47
48 return cmd_results_new(CMD_SUCCESS, NULL);
49}
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index 243f860b..dc07cbf0 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -15,6 +15,7 @@
15#include "sway/input/cursor.h" 15#include "sway/input/cursor.h"
16#include "sway/ipc-server.h" 16#include "sway/ipc-server.h"
17#include "sway/server.h" 17#include "sway/server.h"
18#include "sway/tree/view.h"
18#include "stringop.h" 19#include "stringop.h"
19#include "list.h" 20#include "list.h"
20#include "log.h" 21#include "log.h"
@@ -333,12 +334,25 @@ static void handle_keyboard_shortcuts_inhibit_new_inhibitor(
333 struct sway_seat *seat = inhibitor->seat->data; 334 struct sway_seat *seat = inhibitor->seat->data;
334 wl_list_insert(&seat->keyboard_shortcuts_inhibitors, &sway_inhibitor->link); 335 wl_list_insert(&seat->keyboard_shortcuts_inhibitors, &sway_inhibitor->link);
335 336
336 struct seat_config *config = seat_get_config(seat); 337 // per-view, seat-agnostic config via criteria
337 if (!config) { 338 struct sway_view *view = view_from_wlr_surface(inhibitor->surface);
338 config = seat_get_config_by_name("*"); 339 enum seat_config_shortcuts_inhibit inhibit = SHORTCUTS_INHIBIT_DEFAULT;
340 if (view) {
341 inhibit = view->shortcuts_inhibit;
339 } 342 }
340 343
341 if (config && config->shortcuts_inhibit == SHORTCUTS_INHIBIT_DISABLE) { 344 if (inhibit == SHORTCUTS_INHIBIT_DEFAULT) {
345 struct seat_config *config = seat_get_config(seat);
346 if (!config) {
347 config = seat_get_config_by_name("*");
348 }
349
350 if (config) {
351 inhibit = config->shortcuts_inhibit;
352 }
353 }
354
355 if (inhibit == SHORTCUTS_INHIBIT_DISABLE) {
342 /** 356 /**
343 * Here we deny to honour the inhibitor by never sending the 357 * Here we deny to honour the inhibitor by never sending the
344 * activate signal. We can not, however, destroy the inhibitor 358 * activate signal. We can not, however, destroy the inhibitor
diff --git a/sway/input/seat.c b/sway/input/seat.c
index aa46940d..a4e06c57 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1499,16 +1499,22 @@ bool seatop_allows_set_cursor(struct sway_seat *seat) {
1499} 1499}
1500 1500
1501struct sway_keyboard_shortcuts_inhibitor * 1501struct sway_keyboard_shortcuts_inhibitor *
1502keyboard_shortcuts_inhibitor_get_for_focused_surface( 1502keyboard_shortcuts_inhibitor_get_for_surface(
1503 const struct sway_seat *seat) { 1503 const struct sway_seat *seat,
1504 struct wlr_surface *focused_surface = 1504 const struct wlr_surface *surface) {
1505 seat->wlr_seat->keyboard_state.focused_surface;
1506 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = NULL; 1505 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = NULL;
1507 wl_list_for_each(sway_inhibitor, &seat->keyboard_shortcuts_inhibitors, link) { 1506 wl_list_for_each(sway_inhibitor, &seat->keyboard_shortcuts_inhibitors, link) {
1508 if (sway_inhibitor->inhibitor->surface == focused_surface) { 1507 if (sway_inhibitor->inhibitor->surface == surface) {
1509 return sway_inhibitor; 1508 return sway_inhibitor;
1510 } 1509 }
1511 } 1510 }
1512 1511
1513 return NULL; 1512 return NULL;
1514} 1513}
1514
1515struct sway_keyboard_shortcuts_inhibitor *
1516keyboard_shortcuts_inhibitor_get_for_focused_surface(
1517 const struct sway_seat *seat) {
1518 return keyboard_shortcuts_inhibitor_get_for_surface(seat,
1519 seat->wlr_seat->keyboard_state.focused_surface);
1520}
diff --git a/sway/meson.build b/sway/meson.build
index 226e6458..d71846a4 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -99,6 +99,7 @@ sway_sources = files(
99 'commands/seat/xcursor_theme.c', 99 'commands/seat/xcursor_theme.c',
100 'commands/set.c', 100 'commands/set.c',
101 'commands/show_marks.c', 101 'commands/show_marks.c',
102 'commands/shortcuts_inhibitor.c',
102 'commands/smart_borders.c', 103 'commands/smart_borders.c',
103 'commands/smart_gaps.c', 104 'commands/smart_gaps.c',
104 'commands/split.c', 105 'commands/split.c',
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index febf749f..9e42d897 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -304,6 +304,17 @@ set|plus|minus <amount>
304 Shows a window from the scratchpad. Repeatedly using this command will 304 Shows a window from the scratchpad. Repeatedly using this command will
305 cycle through the windows in the scratchpad. 305 cycle through the windows in the scratchpad.
306 306
307*shortcuts inhibitor* enable|disable
308 Enables or disables the ability of clients to inhibit keyboard
309 shortcuts for a view. This is primarily useful for virtualization and
310 remote desktop software. It affects either the currently focused view
311 or a set of views selected by criteria. Subcommand _disable_
312 additionally deactivates any active inhibitors for the given view(s).
313 Criteria are particularly useful with the *for_window* command to
314 configure a class of views differently from the per-seat defaults
315 established by the *seat* subcommand of the same name. See
316 *sway-input*(5) for more ways to affect inhibitors.
317
307*split* vertical|v|horizontal|h|toggle|t 318*split* vertical|v|horizontal|h|toggle|t
308 Splits the current container, vertically or horizontally. When _toggle_ is 319 Splits the current container, vertically or horizontally. When _toggle_ is
309 specified, the current container is split opposite to the parent 320 specified, the current container is split opposite to the parent
diff --git a/sway/tree/view.c b/sway/tree/view.c
index de1e936a..2b4b6c09 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -36,6 +36,7 @@ void view_init(struct sway_view *view, enum sway_view_type type,
36 view->impl = impl; 36 view->impl = impl;
37 view->executed_criteria = create_list(); 37 view->executed_criteria = create_list();
38 view->allow_request_urgent = true; 38 view->allow_request_urgent = true;
39 view->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT;
39 wl_signal_init(&view->events.unmap); 40 wl_signal_init(&view->events.unmap);
40} 41}
41 42