Should yabai handle apps that steal focus? I have my ugly workaround for that. #2521
PromethiumL
started this conversation in
General
Replies: 1 comment
-
Workaround (Proof of Concept)Here's my script named #!/bin/bash
# We first check if the current space or the target space has a matched app.
# If so, we compute the destination space and focus it multiple times.
# Otherwise, use yabai as usual.
YES=0
NO=1
COMBO_COUNT=4
# The temp file keeps the latest destination space.
tmpfile=/tmp/yabai-focus-space-dest.txt
if ! [ -f $tmpfile ]; then
touch $tmpfile
fi
needs_special_treatment() {
local prev_or_next=$1
local src_space=$(get_cur_space)
if [ "$src_space" = 'null' ]; then return $NO; fi
if $(match_app $src_space); then return $YES; fi
local dest_space=$(get_dest_space $src_space $prev_or_next)
echo "src_space: $src_space, dest_space: $dest_space"
if $(match_app $dest_space); then return $YES; fi
return $NO
}
match_app(){
local space=$1
patterns='["Google Chrome", "Visual Studio Code"]'
local count=$(yabai -m query --windows --space $space | jq --argjson patterns "$patterns" \
'map(select(.app | IN($patterns[]))) | length')
if [ $count -gt 0 ]; then
return $YES
fi
return $NO
}
get_cur_space() {
yabai -m query --spaces has-focus,index | jq '[.[] | select(."has-focus")] | first | .index'
}
get_dest_space() {
local cur_space="$1"
local prev_or_next="$2"
num_spaces=$(yabai -m query --spaces index | jq 'length')
[ "$prev_or_next" = "prev" ] && delta=-1 || delta=1
# NOTE: uncomment the alternative line if you want to cycle between spaces
# local dest_space=$((($cur_space + $num_spaces - 1 + $delta) % $num_spaces + 1))
local dest_space=$(($cur_space + $delta))
[ $dest_space -lt 1 ] && dest_space=1
[ $dest_space -gt $num_spaces ] && dest_space=$num_spaces
echo $dest_space
}
focus_combo() {
local dest_space=$(cat $tmpfile)
echo "focusing multiple times: $dest_space"
for i in $(seq $COMBO_COUNT); do
echo "focusing $dest_space"
yabai -m space --focus $dest_space
done
}
prev_or_next=$1
if [ "$prev_or_next" != "prev" ] && [ "$prev_or_next" != "next" ]; then
echo "Error: Argument must be 'prev' or 'next'."
exit 1
fi
if ! needs_special_treatment $prev_or_next; then
yabai -m space --focus $prev_or_next
exit 0
fi
dest_space=$(get_dest_space $(get_cur_space) $prev_or_next)
echo "dest_space: $dest_space"
echo -n $dest_space > $tmpfile
focus_combo in my
Performance / LimitationThis is just a proof of concept so I didn't try optimization. I'm not sure if this is the canonic way to handle this (probably not :) )
On average my wrapper script takes 0.08s to 0.1s, which is roughly 5-10x slower than the original yabai. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I am suffering from specific apps (esp Chrome) which often steal focus when any workspace change involves two windows on two displays. (See #1736 and similar issues).
Problem Demonstration (Without yabai)
The problem is app-specific, and Chrome is probably the most annoying one as it makes yabai unusable.
Steps to reproduce: Have two displays [A] [B] where [A] is on the left. [A] is my primary monitor.
Case 1: when the focus is shifted from another app (or empty) to Chrome on the right (Similar to #1736):
(Safari doesn't have this behavior)
Case 2: when the one of the two windows of the same application is closed
When two windows are visible, closing either one would result in the other to be focused. I'm not sure but it looks like an intended behavior of macos. Tested on Chrome, Safari, iTerm2 and so on. Finder is the only counterexample.
Case 3: when one of the two windows is closed while the other is on an invisible workspace
Thoughts
Behaviors like Chrome (case 1) and MS Word really prevented yabai from achieving my user task.
Is there any possible mechanism that yabai can have (say if SIP is partially disabled) to prevent certain apps from stealing the focus?
As a workaround, I made a bash script to run yabai multiple times if the current window or the target space windows match my app list, but it's very ugly since the performance isn't optimal.
Beta Was this translation helpful? Give feedback.
All reactions