|
- #!/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
|