aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2022-10-16 17:42:17 +0200
committerMichael Stapelberg <stapelberg@users.noreply.github.com>2022-10-16 18:21:08 +0200
commit55d400b17d786cb60ce2af5229c18177d74aa0ba (patch)
treed5a3140c86d5dbe6a5d8b02979cfa5f335ce35bc
parent2ba393f08493c8efedca300dfdbfbfe1cc712f0c (diff)
downloadi3-55d400b17d786cb60ce2af5229c18177d74aa0ba.tar.gz
i3-55d400b17d786cb60ce2af5229c18177d74aa0ba.zip
make tiling drag configurable
fixes https://github.com/i3/i3/issues/5155
-rw-r--r--docs/userguide24
-rw-r--r--etc/config4
-rw-r--r--etc/config.keycodes4
-rw-r--r--include/config_directives.h1
-rw-r--r--include/configuration.h3
-rw-r--r--include/tiling_drag.h10
-rw-r--r--parser-specs/config.spec13
-rw-r--r--release-notes/changes/1-tiling-drag1
-rw-r--r--src/click.c11
-rw-r--r--src/config.c2
-rw-r--r--src/config_directives.c14
-rw-r--r--testcases/t/201-config-parser.t1
12 files changed, 85 insertions, 3 deletions
diff --git a/docs/userguide b/docs/userguide
index 7b233844..b8f75b37 100644
--- a/docs/userguide
+++ b/docs/userguide
@@ -196,6 +196,7 @@ provided by the i3 https://github.com/i3/i3/blob/next/etc/config.keycodes[defaul
Floating windows are always on top of tiling windows.
+[[tiling_drag]]
=== Moving tiling containers with the mouse
Since i3 4.21, it's possible to drag tiling containers using the mouse. The
@@ -1402,6 +1403,29 @@ fullscreen toggle
bindsym Mod1+F fullscreen toggle
-------------------
+[[config_tiling_drag]]
+=== Tiling drag
+
+You can configure how to initiate the tiling drag feature (see <<tiling_drag>>).
+
+*Syntax*:
+--------------------------------
+tiling_drag off
+tiling_drag modifier|titlebar [modifier|titlebar]
+--------------------------------
+
+*Examples*:
+--------------------------------
+# Only initiate a tiling drag when the modifier is held:
+tiling_drag modifier
+
+# Initiate a tiling drag on either titlebar click or held modifier:
+tiling_drag modifier titlebar
+
+# Disable tiling drag altogether
+tiling_drag off
+--------------------------------
+
== Configuring i3bar
The bar at the bottom of your monitor is drawn by a separate process called
diff --git a/etc/config b/etc/config
index 51902f08..40076ca9 100644
--- a/etc/config
+++ b/etc/config
@@ -49,6 +49,10 @@ set $right semicolon
# use Mouse+Mod1 to drag floating windows to their wanted position
floating_modifier Mod1
+# move tiling windows via drag & drop by left-clicking into the title bar,
+# or left-clicking anywhere into the window while holding the floating modifier.
+tiling_drag modifier titlebar
+
# start a terminal
bindsym Mod1+Return exec i3-sensible-terminal
diff --git a/etc/config.keycodes b/etc/config.keycodes
index 11a7d46f..7bc5d60a 100644
--- a/etc/config.keycodes
+++ b/etc/config.keycodes
@@ -43,6 +43,10 @@ bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOU
# Use Mouse+$mod to drag floating windows to their wanted position
floating_modifier $mod
+# move tiling windows via drag & drop by left-clicking into the title bar,
+# or left-clicking anywhere into the window while holding the floating modifier.
+tiling_drag modifier titlebar
+
# start a terminal
bindcode $mod+36 exec i3-sensible-terminal
diff --git a/include/config_directives.h b/include/config_directives.h
index e0057097..015154d5 100644
--- a/include/config_directives.h
+++ b/include/config_directives.h
@@ -65,6 +65,7 @@ CFGFUN(assign, const char *workspace, bool is_number);
CFGFUN(no_focus);
CFGFUN(ipc_socket, const char *path);
CFGFUN(ipc_kill_timeout, const long timeout_ms);
+CFGFUN(tiling_drag, const char *value);
CFGFUN(restart_state, const char *path);
CFGFUN(popup_during_fullscreen, const char *value);
CFGFUN(color, const char *colorclass, const char *border, const char *background, const char *text, const char *indicator, const char *child_border);
diff --git a/include/configuration.h b/include/configuration.h
index 843e156f..63d504de 100644
--- a/include/configuration.h
+++ b/include/configuration.h
@@ -14,6 +14,7 @@
#include "queue.h"
#include "i3.h"
+#include "tiling_drag.h"
typedef struct IncludedFile IncludedFile;
typedef struct Config Config;
@@ -265,6 +266,8 @@ struct Config {
/* The number of currently parsed barconfigs */
int number_barconfigs;
+
+ tiling_drag_t tiling_drag;
};
/**
diff --git a/include/tiling_drag.h b/include/tiling_drag.h
index ac9679b2..d78744c9 100644
--- a/include/tiling_drag.h
+++ b/include/tiling_drag.h
@@ -10,6 +10,16 @@
#pragma once
/**
+ * Tiling drag initiation modes.
+ */
+typedef enum {
+ TILING_DRAG_OFF = 0,
+ TILING_DRAG_MODIFIER = 1,
+ TILING_DRAG_TITLEBAR = 2,
+ TILING_DRAG_MODIFIER_OR_TITLEBAR = 3
+} tiling_drag_t;
+
+/**
* Initiates a mouse drag operation on a tiled window.
*
*/
diff --git a/parser-specs/config.spec b/parser-specs/config.spec
index 617ed130..dfe8008d 100644
--- a/parser-specs/config.spec
+++ b/parser-specs/config.spec
@@ -53,6 +53,7 @@ state INITIAL:
'ipc_kill_timeout' -> IPC_KILL_TIMEOUT
'restart_state' -> RESTART_STATE
'popup_during_fullscreen' -> POPUP_DURING_FULLSCREEN
+ 'tiling_drag' -> TILING_DRAG
exectype = 'exec_always', 'exec' -> EXEC
colorclass = 'client.background'
-> COLOR_SINGLE
@@ -330,6 +331,18 @@ state POPUP_DURING_FULLSCREEN:
value = 'ignore', 'leave_fullscreen', 'smart'
-> call cfg_popup_during_fullscreen($value)
+state TILING_DRAG_MODE:
+ value = 'modifier', 'titlebar'
+ ->
+ end
+ -> call cfg_tiling_drag($value)
+
+state TILING_DRAG:
+ off = '0', 'no', 'false', 'off', 'disable', 'inactive'
+ -> call cfg_tiling_drag($off)
+ value = 'modifier', 'titlebar'
+ -> TILING_DRAG_MODE
+
# client.background <hexcolor>
state COLOR_SINGLE:
color = word
diff --git a/release-notes/changes/1-tiling-drag b/release-notes/changes/1-tiling-drag
new file mode 100644
index 00000000..bc16308b
--- /dev/null
+++ b/release-notes/changes/1-tiling-drag
@@ -0,0 +1 @@
+tiling drag is now configurable, and defaults to “modifier” for existing configs
diff --git a/src/click.c b/src/click.c
index 5b0cc2e8..6f1cb5c2 100644
--- a/src/click.c
+++ b/src/click.c
@@ -228,7 +228,9 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo
}
/* 2: floating modifier pressed, initiate a drag */
- if (mod_pressed && event->detail == XCB_BUTTON_INDEX_1 && !floatingcon) {
+ if (mod_pressed && is_left_click && !floatingcon &&
+ (config.tiling_drag == TILING_DRAG_MODIFIER ||
+ config.tiling_drag == TILING_DRAG_MODIFIER_OR_TITLEBAR)) {
const bool use_threshold = !mod_pressed;
tiling_drag(con, event, use_threshold);
allow_replay_pointer(event->time);
@@ -305,8 +307,11 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo
return;
}
- /* 8: floating modifier pressed, initiate a drag */
- if ((mod_pressed || dest == CLICK_DECORATION) && event->detail == XCB_BUTTON_INDEX_1) {
+ /* 8: floating modifier pressed, or click in titlebar, initiate a drag */
+ if (is_left_click &&
+ ((config.tiling_drag == TILING_DRAG_TITLEBAR && dest == CLICK_DECORATION) ||
+ (config.tiling_drag == TILING_DRAG_MODIFIER_OR_TITLEBAR &&
+ (mod_pressed || dest == CLICK_DECORATION)))) {
allow_replay_pointer(event->time);
const bool use_threshold = !mod_pressed;
tiling_drag(con, event, use_threshold);
diff --git a/src/config.c b/src/config.c
index f3fd9476..236d682b 100644
--- a/src/config.c
+++ b/src/config.c
@@ -222,6 +222,8 @@ bool load_configuration(const char *override_configpath, config_load_t load_type
config.focus_wrapping = FOCUS_WRAPPING_ON;
+ config.tiling_drag = TILING_DRAG_MODIFIER;
+
FREE(current_configpath);
current_configpath = get_config_path(override_configpath, true);
if (current_configpath == NULL) {
diff --git a/src/config_directives.c b/src/config_directives.c
index a611da27..39fe7410 100644
--- a/src/config_directives.c
+++ b/src/config_directives.c
@@ -560,6 +560,20 @@ CFGFUN(ipc_kill_timeout, const long timeout_ms) {
ipc_set_kill_timeout(timeout_ms / 1000.0);
}
+CFGFUN(tiling_drag, const char *value) {
+ if (strcmp(value, "modifier") == 0) {
+ config.tiling_drag = TILING_DRAG_MODIFIER;
+ } else if (strcmp(value, "titlebar") == 0) {
+ config.tiling_drag = TILING_DRAG_TITLEBAR;
+ } else if (strcmp(value, "modifier,titlebar") == 0 ||
+ strcmp(value, "titlebar,modifier") == 0) {
+ /* Switch the above to strtok() or similar if we ever grow more options */
+ config.tiling_drag = TILING_DRAG_MODIFIER_OR_TITLEBAR;
+ } else {
+ config.tiling_drag = TILING_DRAG_OFF;
+ }
+}
+
/*******************************************************************************
* Bar configuration (i3bar)
******************************************************************************/
diff --git a/testcases/t/201-config-parser.t b/testcases/t/201-config-parser.t
index 3a21a8a0..11efdf84 100644
--- a/testcases/t/201-config-parser.t
+++ b/testcases/t/201-config-parser.t
@@ -549,6 +549,7 @@ my $expected_all_tokens = "ERROR: CONFIG: Expected one of these tokens: <end>, '
ipc_kill_timeout
restart_state
popup_during_fullscreen
+ tiling_drag
exec_always
exec
client.background