82 lines
2.5 KiB
Bash
Executable File
82 lines
2.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
export PATH="$HOME/.local/bin:$PATH"
|
|
|
|
# epochMillis: print the amount of millis since epoch time on the std output stream.
|
|
epochMillis(){
|
|
echo $(($(date +%s%N)/1000000))
|
|
}
|
|
|
|
# queue: array holding the focused window ids in order, the most recent focus is on index 0.
|
|
queue=( )
|
|
queueLimit=8
|
|
|
|
# pushOnQueue: insert a window id on index 0 of the queue. This function also removes the given id if was already present, the queue is an ordered set.
|
|
# arg 1: window id to insert.
|
|
pushOnQueue(){
|
|
if [ "$1" = "0x0" ]
|
|
then
|
|
return
|
|
fi
|
|
newQueue=( "$1" )
|
|
for i in "${queue[@]}"
|
|
do
|
|
if [ "$1" = "$i" ]
|
|
then
|
|
continue
|
|
fi
|
|
newQueue=( ${newQueue[@]:0} "$i" )
|
|
done
|
|
queue=( "${newQueue[@]:0:$queueLimit}" )
|
|
}
|
|
|
|
# markQueue: put i3 marks using the window ids stored on the queue. The windows are marked using "_prevFocusX" where X is a integer corresponding with the index of the element on the queue. The previously focused window (the most recent) is marked using "_prevFocus0". This function also cleans the queue from windows that can't be marked (e.g. windows that have been closed).
|
|
markQueue(){
|
|
queueCopy=( "${queue[@]}" )
|
|
queue=( )
|
|
j=0
|
|
for i in "${queueCopy[@]}"
|
|
do
|
|
i3-msg "unmark _prevFocus$j" 1>/dev/null 2>&1
|
|
if i3-msg "[id=$i] mark --add _prevFocus$j" 2>/dev/null | grep -i "\"success\":true" 1>/dev/null 2>&1
|
|
then
|
|
queue=( ${queue[@]:0} "$i" )
|
|
j=$(($j + 1))
|
|
fi
|
|
done
|
|
}
|
|
|
|
lastTime=$(epochMillis)
|
|
# permanence: period in millis used to determine if a window is worthy to be saved on the queue. This enables i3 window fast navigation without saving unworthy window ids.
|
|
permanence=1000
|
|
|
|
# main loop: read activated window ids continuously.
|
|
xprop -root -spy _NET_ACTIVE_WINDOW |
|
|
while read line
|
|
do
|
|
|
|
currentTime=$(epochMillis)
|
|
period=$(($currentTime-$lastTime))
|
|
lastTime=$currentTime
|
|
|
|
# previousFocus: window id of the previously focused (activated) window.
|
|
previousFocus=$currentFocus
|
|
# currentFocus: window id of the window that has just being activated.
|
|
currentFocus=$(echo "$line" | awk -F' ' '{printf $NF}')
|
|
|
|
# push the previousFocus id to the queue if the time spent on the previous window was greater than permanence. Check also to allow fast switching between two windows.
|
|
if [ $period -gt $permanence -o "$currentFocus" = "${queue[0]}" ]
|
|
then
|
|
pushOnQueue "$previousFocus"
|
|
fi
|
|
|
|
# if the currentFocus is marked as the previous window (_prevFocus0 or queue[0]) then swap the first two elements on the queue to allow switching.
|
|
if [ "${queue[0]}" = "$currentFocus" ]
|
|
then
|
|
queue=( ${queue[1]} ${queue[0]} ${queue[@]:2} )
|
|
fi
|
|
|
|
markQueue
|
|
|
|
done
|