aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h7
-rw-r--r--sway/commands/seat.c1
-rw-r--r--sway/commands/seat/shortcuts_inhibitor.c96
-rw-r--r--sway/config/seat.c5
-rw-r--r--sway/input/input-manager.c20
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway-input.5.scd19
8 files changed, 150 insertions, 0 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index bbbdfc80..3fde0893 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -288,6 +288,7 @@ sway_cmd seat_cmd_idle_inhibit;
288sway_cmd seat_cmd_idle_wake; 288sway_cmd seat_cmd_idle_wake;
289sway_cmd seat_cmd_keyboard_grouping; 289sway_cmd seat_cmd_keyboard_grouping;
290sway_cmd seat_cmd_pointer_constraint; 290sway_cmd seat_cmd_pointer_constraint;
291sway_cmd seat_cmd_shortcuts_inhibitor;
291sway_cmd seat_cmd_xcursor_theme; 292sway_cmd seat_cmd_xcursor_theme;
292 293
293sway_cmd cmd_ipc_cmd; 294sway_cmd cmd_ipc_cmd;
diff --git a/include/sway/config.h b/include/sway/config.h
index fdd65efd..359f9604 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -177,6 +177,12 @@ enum seat_config_allow_constrain {
177 CONSTRAIN_DISABLE 177 CONSTRAIN_DISABLE
178}; 178};
179 179
180enum seat_config_shortcuts_inhibit {
181 SHORTCUTS_INHIBIT_DEFAULT, // the default is currently enabled
182 SHORTCUTS_INHIBIT_ENABLE,
183 SHORTCUTS_INHIBIT_DISABLE
184};
185
180enum seat_keyboard_grouping { 186enum seat_keyboard_grouping {
181 KEYBOARD_GROUP_DEFAULT, // the default is currently smart 187 KEYBOARD_GROUP_DEFAULT, // the default is currently smart
182 KEYBOARD_GROUP_NONE, 188 KEYBOARD_GROUP_NONE,
@@ -201,6 +207,7 @@ struct seat_config {
201 list_t *attachments; // list of seat_attachment configs 207 list_t *attachments; // list of seat_attachment configs
202 int hide_cursor_timeout; 208 int hide_cursor_timeout;
203 enum seat_config_allow_constrain allow_constrain; 209 enum seat_config_allow_constrain allow_constrain;
210 enum seat_config_shortcuts_inhibit shortcuts_inhibit;
204 enum seat_keyboard_grouping keyboard_grouping; 211 enum seat_keyboard_grouping keyboard_grouping;
205 uint32_t idle_inhibit_sources, idle_wake_sources; 212 uint32_t idle_inhibit_sources, idle_wake_sources;
206 struct { 213 struct {
diff --git a/sway/commands/seat.c b/sway/commands/seat.c
index eba28cac..84c6ba53 100644
--- a/sway/commands/seat.c
+++ b/sway/commands/seat.c
@@ -22,6 +22,7 @@ static struct cmd_handler seat_handlers[] = {
22 { "idle_wake", seat_cmd_idle_wake }, 22 { "idle_wake", seat_cmd_idle_wake },
23 { "keyboard_grouping", seat_cmd_keyboard_grouping }, 23 { "keyboard_grouping", seat_cmd_keyboard_grouping },
24 { "pointer_constraint", seat_cmd_pointer_constraint }, 24 { "pointer_constraint", seat_cmd_pointer_constraint },
25 { "shortcuts_inhibitor", seat_cmd_shortcuts_inhibitor },
25 { "xcursor_theme", seat_cmd_xcursor_theme }, 26 { "xcursor_theme", seat_cmd_xcursor_theme },
26}; 27};
27 28
diff --git a/sway/commands/seat/shortcuts_inhibitor.c b/sway/commands/seat/shortcuts_inhibitor.c
new file mode 100644
index 00000000..7c7f99cf
--- /dev/null
+++ b/sway/commands/seat/shortcuts_inhibitor.c
@@ -0,0 +1,96 @@
1#include "log.h"
2#include "sway/commands.h"
3#include "sway/input/seat.h"
4#include "sway/input/input-manager.h"
5#include "util.h"
6
7static struct cmd_results *handle_action(struct seat_config *sc,
8 struct sway_seat *seat, const char *action) {
9 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = NULL;
10 if (strcmp(action, "disable") == 0) {
11 sc->shortcuts_inhibit = SHORTCUTS_INHIBIT_DISABLE;
12
13 wl_list_for_each(sway_inhibitor,
14 &seat->keyboard_shortcuts_inhibitors, link) {
15 wlr_keyboard_shortcuts_inhibitor_v1_deactivate(
16 sway_inhibitor->inhibitor);
17 }
18
19 sway_log(SWAY_DEBUG, "Deactivated all keyboard shortcuts inhibitors");
20 } else {
21 sway_inhibitor = keyboard_shortcuts_inhibitor_get_for_focused_surface(seat);
22 if (!sway_inhibitor) {
23 return cmd_results_new(CMD_FAILURE,
24 "No inhibitor found for focused surface");
25 }
26
27 struct wlr_keyboard_shortcuts_inhibitor_v1 *inhibitor =
28 sway_inhibitor->inhibitor;
29 bool inhibit;
30 if (strcmp(action, "activate") == 0) {
31 inhibit = true;
32 } else if (strcmp(action, "deactivate") == 0) {
33 inhibit = false;
34 } else if (strcmp(action, "toggle") == 0) {
35 inhibit = !inhibitor->active;
36 } else {
37 return cmd_results_new(CMD_INVALID, "Expected enable|"
38 "disable|activate|deactivate|toggle");
39 }
40
41 if (inhibit) {
42 wlr_keyboard_shortcuts_inhibitor_v1_activate(inhibitor);
43 } else {
44 wlr_keyboard_shortcuts_inhibitor_v1_deactivate(inhibitor);
45 }
46
47 sway_log(SWAY_DEBUG, "%sctivated keyboard shortcuts inhibitor",
48 inhibit ? "A" : "Dea");
49 }
50
51 return cmd_results_new(CMD_SUCCESS, NULL);
52}
53
54// shortcuts_inhibitor [enable|disable|activate|deactivate|toggle]
55struct cmd_results *seat_cmd_shortcuts_inhibitor(int argc, char **argv) {
56 struct cmd_results *error =
57 checkarg(argc, "shortcuts_inhibitor", EXPECTED_EQUAL_TO, 1);
58 if (error) {
59 return error;
60 }
61
62 struct seat_config *sc = config->handler_context.seat_config;
63 if (!sc) {
64 return cmd_results_new(CMD_FAILURE, "No seat defined");
65 }
66
67 if (strcmp(argv[0], "enable") == 0) {
68 sc->shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
69 // at runtime disable is an action that also deactivates all active
70 // inhibitors handled in handle_action()
71 } else if (strcmp(argv[0], "disable") == 0 && !config->active) {
72 sc->shortcuts_inhibit = SHORTCUTS_INHIBIT_DISABLE;
73 } else if (!config->active) {
74 return cmd_results_new(CMD_INVALID, "only enable and disable "
75 "can be used in the config");
76 } else {
77 if (strcmp(sc->name, "*") != 0) {
78 struct sway_seat *seat = input_manager_get_seat(sc->name, false);
79 if (!seat) {
80 return cmd_results_new(CMD_FAILURE,
81 "Seat %s does not exist", sc->name);
82 }
83 error = handle_action(sc, seat, argv[0]);
84 } else {
85 struct sway_seat *seat = NULL;
86 wl_list_for_each(seat, &server.input->seats, link) {
87 error = handle_action(sc, seat, argv[0]);
88 if (error && error->status != CMD_SUCCESS) {
89 break;
90 }
91 }
92 }
93 }
94
95 return error ? error : cmd_results_new(CMD_SUCCESS, NULL);
96}
diff --git a/sway/config/seat.c b/sway/config/seat.c
index 6c916727..e2702de5 100644
--- a/sway/config/seat.c
+++ b/sway/config/seat.c
@@ -30,6 +30,7 @@ struct seat_config *new_seat_config(const char* name) {
30 } 30 }
31 seat->hide_cursor_timeout = -1; 31 seat->hide_cursor_timeout = -1;
32 seat->allow_constrain = CONSTRAIN_DEFAULT; 32 seat->allow_constrain = CONSTRAIN_DEFAULT;
33 seat->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT;
33 seat->keyboard_grouping = KEYBOARD_GROUP_DEFAULT; 34 seat->keyboard_grouping = KEYBOARD_GROUP_DEFAULT;
34 seat->xcursor_theme.name = NULL; 35 seat->xcursor_theme.name = NULL;
35 seat->xcursor_theme.size = 24; 36 seat->xcursor_theme.size = 24;
@@ -154,6 +155,10 @@ void merge_seat_config(struct seat_config *dest, struct seat_config *source) {
154 dest->allow_constrain = source->allow_constrain; 155 dest->allow_constrain = source->allow_constrain;
155 } 156 }
156 157
158 if (source->shortcuts_inhibit != SHORTCUTS_INHIBIT_DEFAULT) {
159 dest->shortcuts_inhibit = source->shortcuts_inhibit;
160 }
161
157 if (source->keyboard_grouping != KEYBOARD_GROUP_DEFAULT) { 162 if (source->keyboard_grouping != KEYBOARD_GROUP_DEFAULT) {
158 dest->keyboard_grouping = source->keyboard_grouping; 163 dest->keyboard_grouping = source->keyboard_grouping;
159 } 164 }
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index af0f5afa..124d57dc 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -333,6 +333,26 @@ static void handle_keyboard_shortcuts_inhibit_new_inhibitor(
333 struct sway_seat *seat = inhibitor->seat->data; 333 struct sway_seat *seat = inhibitor->seat->data;
334 wl_list_insert(&seat->keyboard_shortcuts_inhibitors, &sway_inhibitor->link); 334 wl_list_insert(&seat->keyboard_shortcuts_inhibitors, &sway_inhibitor->link);
335 335
336 struct seat_config *config = seat_get_config(seat);
337 if (!config) {
338 config = seat_get_config_by_name("*");
339 }
340
341 if (config && config->shortcuts_inhibit == SHORTCUTS_INHIBIT_DISABLE) {
342 /**
343 * Here we deny to honour the inhibitor by never sending the
344 * activate signal. We can not, however, destroy the inhibitor
345 * because the protocol doesn't allow for it. So it will linger
346 * until the client removes it im- or explicitly. But at least
347 * it can only be one inhibitor per surface and seat at a time.
348 *
349 * We also want to allow the user to activate the inhibitor
350 * manually later which is why we do this check here where the
351 * inhibitor is already attached to its seat and ready for use.
352 */
353 return;
354 }
355
336 wlr_keyboard_shortcuts_inhibitor_v1_activate(inhibitor); 356 wlr_keyboard_shortcuts_inhibitor_v1_activate(inhibitor);
337} 357}
338 358
diff --git a/sway/meson.build b/sway/meson.build
index 6fdc4a7d..8a549108 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -94,6 +94,7 @@ sway_sources = files(
94 'commands/seat/idle.c', 94 'commands/seat/idle.c',
95 'commands/seat/keyboard_grouping.c', 95 'commands/seat/keyboard_grouping.c',
96 'commands/seat/pointer_constraint.c', 96 'commands/seat/pointer_constraint.c',
97 'commands/seat/shortcuts_inhibitor.c',
97 'commands/seat/xcursor_theme.c', 98 'commands/seat/xcursor_theme.c',
98 'commands/set.c', 99 'commands/set.c',
99 'commands/show_marks.c', 100 'commands/show_marks.c',
diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd
index 9edd9381..c0584241 100644
--- a/sway/sway-input.5.scd
+++ b/sway/sway-input.5.scd
@@ -243,6 +243,25 @@ correct seat.
243 by default) for the seat. This is primarily useful for video games. The 243 by default) for the seat. This is primarily useful for video games. The
244 "escape" command can be used at runtime to escape from a captured client. 244 "escape" command can be used at runtime to escape from a captured client.
245 245
246*seat* <name> shortcuts_inhibitor enable|disable|activate|deactivate|toggle
247 Enables or disables the ability of clients to inhibit keyboard
248 shortcuts for the seat. This is primarily useful for virtualization and
249 remote desktop software. Subcommands _enable_ and _disable_ affect
250 whether future inhibitors are honoured by default, i.e. activated
251 automatically, the default being _enable_. When used at runtime,
252 _disable_ also disables any currently active inhibitors. _activate_,
253 _deactivate_ and _toggle_ are only useable at runtime and change the
254 state of a potentially existing inhibitor on the currently focused
255 window. This can be used with the current seat alias (_-_) to affect
256 only the currently focused window of the current seat. Subcommand
257 _deactivate_ is particularly useful in an _--inhibited_ *bindsym* to
258 escape a state where shortcuts are inhibited and the client becomes
259 uncooperative. It is worth noting that whether disabled or deactivated
260 inhibitors are removed is entirely up to the client. Depending on the
261 client it may therefore be possible to (re-)activate them later. Any
262 visual indication that an inhibitor is present is currently left to the
263 client as well.
264
246*seat* <name> xcursor_theme <theme> [<size>] 265*seat* <name> xcursor_theme <theme> [<size>]
247 Override the system default XCursor theme. The default seat's 266 Override the system default XCursor theme. The default seat's
248 (_seat0_) theme is also used as the default cursor theme in 267 (_seat0_) theme is also used as the default cursor theme in