aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/pointer_constraint.c51
-rw-r--r--sway/config/seat.c1
-rw-r--r--sway/input/cursor.c5
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.scd5
6 files changed, 64 insertions, 0 deletions
diff --git a/sway/commands.c b/sway/commands.c
index dd994fa1..425897fb 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -81,6 +81,7 @@ static struct cmd_handler handlers[] = {
{ "no_focus", cmd_no_focus },
{ "output", cmd_output },
{ "popup_during_fullscreen", cmd_popup_during_fullscreen },
+ { "pointer_constraint", cmd_pointer_constraint },
{ "seat", cmd_seat },
{ "set", cmd_set },
{ "show_marks", cmd_show_marks },
diff --git a/sway/commands/pointer_constraint.c b/sway/commands/pointer_constraint.c
new file mode 100644
index 00000000..2dda0776
--- /dev/null
+++ b/sway/commands/pointer_constraint.c
@@ -0,0 +1,51 @@
+#include <string.h>
+#include <wlr/types/wlr_pointer_constraints_v1.h>
+#include "sway/commands.h"
+#include "sway/config.h"
+#include "sway/input/cursor.h"
+#include "sway/input/seat.h"
+
+enum operation {
+ OP_ENABLE,
+ OP_DISABLE,
+ OP_ESCAPE,
+};
+
+// pointer_constraint [enable|disable|escape]
+struct cmd_results *cmd_pointer_constraint(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "pointer_constraint", EXPECTED_EQUAL_TO, 1))) {
+ return error;
+ }
+
+ enum operation op;
+ if (strcmp(argv[0], "enable") == 0) {
+ op = OP_ENABLE;
+ } else if (strcmp(argv[0], "disable") == 0) {
+ op = OP_DISABLE;
+ } else if (strcmp(argv[0], "escape") == 0) {
+ op = OP_ESCAPE;
+ } else {
+ return cmd_results_new(CMD_FAILURE, "Expected enable|disable|escape");
+ }
+
+ if (op == OP_ESCAPE && config->reading) {
+ return cmd_results_new(CMD_FAILURE, "Can only escape at runtime.");
+ }
+
+ struct sway_cursor *cursor = config->handler_context.seat->cursor;
+ struct seat_config *seat_config = seat_get_config(cursor->seat);
+ switch (op) {
+ case OP_ENABLE:
+ seat_config->allow_constrain = true;
+ break;
+ case OP_DISABLE:
+ seat_config->allow_constrain = false;
+ /* fallthrough */
+ case OP_ESCAPE:
+ sway_cursor_constrain(cursor, NULL);
+ break;
+ }
+
+ return cmd_results_new(CMD_SUCCESS, NULL);
+}
diff --git a/sway/config/seat.c b/sway/config/seat.c
index 92dc42e3..541c4f99 100644
--- a/sway/config/seat.c
+++ b/sway/config/seat.c
@@ -26,6 +26,7 @@ struct seat_config *new_seat_config(const char* name) {
return NULL;
}
seat->hide_cursor_timeout = -1;
+ seat->allow_constrain = true;
return seat;
}
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 78e2f695..14c62970 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -1454,6 +1454,11 @@ void handle_pointer_constraint(struct wl_listener *listener, void *data) {
void sway_cursor_constrain(struct sway_cursor *cursor,
struct wlr_pointer_constraint_v1 *constraint) {
+ struct seat_config *config = seat_get_config(cursor->seat);
+ if (!config->allow_constrain) {
+ return;
+ }
+
if (cursor->active_constraint == constraint) {
return;
}
diff --git a/sway/meson.build b/sway/meson.build
index 94d5abdb..b3837e21 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -75,6 +75,7 @@ sway_sources = files(
'commands/nop.c',
'commands/output.c',
'commands/popup_during_fullscreen.c',
+ 'commands/pointer_constraint.c',
'commands/reload.c',
'commands/rename.c',
'commands/resize.c',
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 55de3c9c..e04c5fbf 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -539,6 +539,11 @@ The default colors are:
\* may be used in lieu of a specific output name to configure all outputs.
A list of output names may be obtained via *swaymsg -t get_outputs*.
+*pointer_constraint* enable|disable|escape
+ Enables or disables the ability for clients to capture the cursor (enabled
+ by default). This is primarily useful for video games. The "escape" command
+ can be used at runtime to escape from a captured client.
+
*popup_during_fullscreen* smart|ignore|leave_fullscreen
Determines what to do when a fullscreen view opens a dialog.
If _smart_ (the default), the dialog will be displayed. If _ignore_, the