Skip to content

Instantly share code, notes, and snippets.

@Zauberfisch
Last active March 18, 2024 04:08
Show Gist options
  • Save Zauberfisch/f27716f9078072c596b1dec442fe8475 to your computer and use it in GitHub Desktop.
Save Zauberfisch/f27716f9078072c596b1dec442fe8475 to your computer and use it in GitHub Desktop.
i3 Window Manager - disable focus wrapping / cycling

i3 Window Manager - disable focus wrapping / cycling

Switching window focus ($mod+Up / $mod+Right / $mod+Down / $mod+Left) in i3 cycles through all windows on a workspace, meaning when you hit one edge of the screen, it will start again on the other side.

I was looking for a way to disable that, but was unable to find a way to change this via configuration. Therefore I have created the following script.

Place i3-focus-nowrap.sh somewhere within your path (eg /usr/local/bin) or use an absolute reference in the keybindings below. And replace the keybindings in your .i3 config (eg ~/.i3/config)

so change:

# change focus
bindsym $mod+j focus left
bindsym $mod+k focus down
bindsym $mod+l focus up
bindsym $mod+odiaeresis focus right

# alternatively, you can use the cursor keys:
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right

to:

# change focus
bindsym $mod+j exec i3-focus-nowrap.sh left
bindsym $mod+k exec i3-focus-nowrap.sh down
bindsym $mod+l exec i3-focus-nowrap.sh up
bindsym $mod+odiaeresis exec i3-focus-nowrap.sh right

# alternatively, you can use the cursor keys:
bindsym $mod+Left exec i3-focus-nowrap.sh left
bindsym $mod+Down exec i3-focus-nowrap.sh down
bindsym $mod+Up exec i3-focus-nowrap.sh up
bindsym $mod+Right exec i3-focus-nowrap.sh right

My configuration has 6px gaps around windows + 19px status bar at the bottom, if you have a different configuration adjust gapWidth in i3-focus-nowrap.sh

Dependencies

  • jq (to parse json)
#!/bin/sh
gapWidthTop=6
gapWidthRight=6
gapWidthBottom=25
gapWidthLeft=6
tree=`i3-msg -t get_tree`
screenWidth=`echo "$tree" | jq .rect.width`
screenHeight=`echo "$tree" | jq .rect.height`
edgeTop=$gapWidthTop
edgeRight=$(( $screenWidth - $gapWidthRight ))
edgeBottom=$(( $screenHeight - $gapWidthBottom ))
edgeLeft=$gapWidthLeft
currentWindow=`echo "$tree" | jq -r ".. | select(.focused? and .focused == true).rect"`
width=`echo "$currentWindow" | jq .width`
height=`echo "$currentWindow" | jq .height`
offsetTop=`echo "$currentWindow" | jq .y`
offsetLeft=`echo "$currentWindow" | jq .x`
offsetRight=$(( $offsetLeft + $width ))
offsetBottom=$(( $offsetTop + $height ))
if [[ "$1" == "up" && "$offsetTop" -gt "$edgeTop" ]] || [[ "$1" == "right" && "$offsetRight" -lt "$edgeRight" ]] || [[ "$1" == "down" && "$offsetBottom" -lt "$edgeBottom" ]] || [[ "$1" == "left" && "$offsetLeft" -gt "$edgeLeft" ]]
then
i3-msg focus $1
fi
@bcremer
Copy link

bcremer commented Aug 20, 2018

This scripts are obsolete since i3wm version 4.15:

introduce a “focus_wrapping” option (subsumes “force_focus_wrapping”)

See:

@DovieW
Copy link

DovieW commented Mar 18, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment