summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDixiE <git@notdixie.co.uk>2022-05-27 00:27:43 +0100
committerDixiE <git@notdixie.co.uk>2022-06-02 10:57:28 +0100
commit0048e9f4881e31f7dc747df7beb99beffde80089 (patch)
tree82cd9be4ec2ed7921105f1507cb010c35b64b439
parente1fd534637837f63e9d10281b674d80756622976 (diff)
Support `focus` Within Sway WM
While Wayland offers nothing general to help us support `focus` on all window managers, WM-specific implementations are generally possible. Sway is a tiling window manager that mimics i3, and has a reasonably powerful CLI that can help us achieve this. In addition to supporting `focus` for Sway, this change paves the way for additional WM-specific Wayland functionality by adding a detection step to wayland.kak, in a similar fashion to detection.kak.
-rw-r--r--rc/windowing/detection.kak2
-rw-r--r--rc/windowing/sway.kak51
-rw-r--r--rc/windowing/wayland.kak2
3 files changed, 53 insertions, 2 deletions
diff --git a/rc/windowing/detection.kak b/rc/windowing/detection.kak
index 3dc046ea..c47ca0a3 100644
--- a/rc/windowing/detection.kak
+++ b/rc/windowing/detection.kak
@@ -23,7 +23,7 @@ declare-option -docstring \
"Ordered list of windowing modules to try and load. An empty list disables
both automatic module loading and environment detection, enabling complete
manual control of the module loading." \
-str-list windowing_modules 'tmux' 'screen' 'kitty' 'iterm' 'wayland' 'x11'
+str-list windowing_modules 'tmux' 'screen' 'kitty' 'iterm' 'sway' 'wayland' 'x11'
hook -group windowing global KakBegin .* %{
diff --git a/rc/windowing/sway.kak b/rc/windowing/sway.kak
new file mode 100644
index 00000000..dc0c5830
--- /dev/null
+++ b/rc/windowing/sway.kak
@@ -0,0 +1,51 @@
+provide-module sway %{
+
+# Ensure we're actually in Sway
+evaluate-commands %sh{
+ [ -z "${kak_opt_windowing_modules}" ] ||
+ [ -n "$SWAYSOCK" ] ||
+ echo 'fail SWAYSOCK is not set'
+}
+
+require-module 'wayland'
+
+define-command sway-focus-pid -hidden %{
+ evaluate-commands %sh{
+ pid=$kak_client_pid
+
+ # Try to focus a window with the current PID, walking up the tree of
+ # parent processes until the focus eventually succeeds
+ while ! swaymsg [pid=$pid] focus > /dev/null 2> /dev/null ; do
+ # Replace the current PID with its parent PID
+ pid=$(ps -p $pid -o ppid=)
+
+ # If we couldn't get a PPID for some reason, or it's 1 or less, we
+ # should just fail.
+ if [ -z $pid ] || [ $pid -le 1 ]; then
+ echo "fail Can't find PID for Sway window to focus"
+ break
+ fi
+ done
+ }
+}
+
+define-command sway-focus -params ..1 -docstring '
+sway-focus [<kakoune_client>]: focus a given client''s window.
+If no client is passed, then the current client is used' \
+%{
+ # Quick branch to make sure we're calling sway-focus-pid from the client
+ # the user wants to focus on.
+ evaluate-commands %sh{
+ if [ $# -eq 1 ]; then
+ printf "evaluate-commands -client '%s' sway-focus-pid" "$1"
+ else
+ echo sway-focus-pid
+ fi
+ }
+}
+complete-command sway-focus client
+
+unalias global focus
+alias global focus sway-focus
+
+}
diff --git a/rc/windowing/wayland.kak b/rc/windowing/wayland.kak
index dd3632d9..1f595a33 100644
--- a/rc/windowing/wayland.kak
+++ b/rc/windowing/wayland.kak
@@ -49,7 +49,7 @@ define-command wayland-focus -params ..1 -docstring '
wayland-focus [<kakoune_client>]: focus a given client''s window
If no client is passed, then the current client is used' \
%{
- fail There is no way to focus another window on Wayland
+ fail 'Focusing specific windows in most Wayland window managers is unsupported'
}
complete-command wayland-focus client