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.
This commit is contained in:
DixiE 2022-05-27 00:27:43 +01:00
parent e1fd534637
commit 0048e9f488
3 changed files with 53 additions and 2 deletions

View File

@ -23,7 +23,7 @@ declare-option -docstring \
"Ordered list of windowing modules to try and load. An empty list disables "Ordered list of windowing modules to try and load. An empty list disables
both automatic module loading and environment detection, enabling complete both automatic module loading and environment detection, enabling complete
manual control of the module loading." \ 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 .* %{ hook -group windowing global KakBegin .* %{

51
rc/windowing/sway.kak Normal file
View File

@ -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
}

View File

@ -49,7 +49,7 @@ define-command wayland-focus -params ..1 -docstring '
wayland-focus [<kakoune_client>]: focus a given client''s window wayland-focus [<kakoune_client>]: focus a given client''s window
If no client is passed, then the current client is used' \ 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 complete-command wayland-focus client