From 0048e9f4881e31f7dc747df7beb99beffde80089 Mon Sep 17 00:00:00 2001 From: DixiE Date: Fri, 27 May 2022 00:27:43 +0100 Subject: [PATCH 2/2] 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. --- rc/windowing/detection.kak | 2 +- rc/windowing/sway.kak | 51 ++++++++++++++++++++++++++++++++++++++ rc/windowing/wayland.kak | 2 +- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 rc/windowing/sway.kak 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 []: 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 []: 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