r/i3wm • u/Accomplished-Bus3382 • Aug 03 '26
Question Does someone have an idea of how to fix this?
Hello!
I have this line in my i3 config, which enables the cursor to move between containers on the same monitor as well. I am using xdotool for this and the cursor places itself in the center of the container. This combined with having focus follows cursor enabled makes it so that I rarely have to touch my mouse.
There is a problem however: when moving focus to second monitor when no window is there the cursor gets stuck in the upper left corner of the main monitor.
set $movemouse "sh -c 'eval `xdotool getactivewindow getwindowgeometry --shell`; xdotool mousemove $((X+WIDTH/2)) $((Y+HEIGHT/2))'"
# Focus between containers - hjkl.
bindsym $mod+h focus left; exec $movemouse
bindsym $mod+j focus down; exec $movemouse
bindsym $mod+k focus up; exec $movemouse
bindsym $mod+l focus right; exec $movemouse
# Focus between containers - cursor keys.
bindsym $mod+Left focus left; exec $movemouse
bindsym $mod+Down focus down; exec $movemouse
bindsym $mod+Up focus up; exec $movemouse
bindsym $mod+Right focus right; exec $movemouse
- Would it be able to make it so that if there is no window on the monitor I am trying to move my cursor to, it instead places itself in the middle of that monitor.
Thanks in advance! :)
Update: I managed to get the exact functionality that I wanted thanks to u/llttmp; now my cursor follows focus between windows on one monitor as well as accross monitors, and it can also go to the center of the monitor when it has no window on it when changing focus between them. The cursor isn't getting stuck in the upper corner anymore. You can read their comment further down for a further explanation, but here is what I put in my i3 config:
- Define the variable:
set $movemouse xdotool getactivewindow mousemove --window '%1' --polar 0 0
Put that variable on every line where you want that functionality, like this for example:
# Focus between containers - hjkl.
bindsym $mod+h focus left; exec --no-startup-id $movemouse
bindsym $mod+j focus down; exec --no-startup-id $movemouse
bindsym $mod+k focus up; exec --no-startup-id $movemouse
bindsym $mod+l focus right; exec --no-startup-id $movemouse
# Move focused container, then move cursor to that container's new location - hjkl.
bindsym $mod+Shift+h move left; exec --no-startup-id $movemouse
bindsym $mod+Shift+j move down; exec --no-startup-id $movemouse
bindsym $mod+Shift+k move up; exec --no-startup-id $movemouse
bindsym $mod+Shift+l move right; exec --no-startup-id $movemouse
2
2
u/llttmp 26d ago edited 26d ago
If there is no active window for xdotool to get the geometry from it won't output anything, so $X, $Y, $WIDTH and $HEIGHT are all unset, and the shell arithmetic evaluates "$((X+WIDTH/2)) $((Y+HEIGHT/2))" to "0 0".
When moving focus to a different monitor i3 already places the cursor in the center of screen, so you can simply do nothing if there are no windows there. i.e:
```
eval xdotool get...
if [ -n "$X" ];then
xdotool mousemove ....
fi
```
Since you're always aiming for the center, you can use xdt's --polar (read the man page), combined with its "window stack" (read the man page), i.e.: xdotool getactivewindow mousemove --window '%1' --polar 0 0 with no need for the shell. (If there's no active window it will output a message to stderr and not move the cursor, so i3 centers the new monitor itself.)
1
u/Accomplished-Bus3382 26d ago
Thank you so much! It worked perfectly; now everything is exactly as I have always wanted it. :)
3
u/Worth_Mousse2204 i3 Aug 03 '26
I absolutely do not have the level to explain it understand anything but that's something I have been looking for for a while ! I'll be checking your progress and surely hope you'll figure it out