Jun's Blog

Output, activities, memo and etc.

i3: Mouse emulation on keyboard

When I was looking at the ZSA's customizable keyboard: Plank EZ page - mouse emulation the keyboard on the firmware (hardware level), I was inspired. Maybe it's possible to emulate the mouse on the keyboard on the software level?

The way 1: xbindkeys and xdotool: failed

First, what I tried is the way to use the xbindkeys and xdotool.

On Fedora, the installation is like this.

$ sudo dnf install xbindkeys
$ sudo dnf install xdotool

Especially if you want to see the key symbols used in the the xbindkeys, and see the head files /usr/include/X11/keysym.h and /usr/include/X11/keysymdef.h, you can also to install the following RPM package too.

$ sudo dnf install xorg-x11-proto-devel

However the following setting doesn't work. I don't know why. Perhaps the xbindkeys process doesn't run? Also having to logout and login the window manager to update the config is inconvenient.

.xbindkeysrc

$ cat ~/.xbindkeysrc 
# https://askubuntu.com/questions/455762/xbindkeys-wont-work-properly
# Install xbindkeys and xdotool.
# Left click.
# "xset r off; xdotool click --clearmodifiers 1; xset r on"
# "sleep 0.2 & xdotool click --delay 15 1"
"xdotool click 1"
  Alt + n
# Right click.
"xdotool click 3"
  Alt + m
# Direction: down
"xdotool mousemove_relative 0 -1"
  Alt + j
# Direction: up
"xdotool mousemove_relative 0 1"
  Alt + k

Updated: I need to run xbindkeys command as a deamon process. See this document. To reload the change on real time, run xbindkeys --poll-rc. To make the change permanent, set xbindkeys in xprofile or xinitrc file.

The way 2: .config/i3/config and xdotool: ok

The 2nd way is to use the i3 config's keymapping. It's also convenient to update the config by super+shift+r. So, here is the config.

First I set the $mod2 as Alt keys.

.config/i3/config

# Assign modifier keys.
# $ xmodmap -pm
# Mod4: Super
set $mod Mod4
# Mod1: Alt
set $mod2 Mod1

Now here is the remaining part of the config. Mouse click: left, right, mouse direction: up, down, left, right, diagonal, mouse drag & drop are available by this config. One thing I couldn't do is the drag & drop works with the real mouse, trackpad, trackpoint, but doesn't work with the mouse directions emulation on the keyboard.

# Mouse emulation
# click: left, right. direction: up, down, left, right
# ttps://www.reddit.com/r/i3wm/comments/ltjoaa/tip_mouse_emulation_using_hjkl/
# click: left
bindsym $mod2+f exec "xdotool click 1"
# click: drag & drop.
# https://askubuntu.com/questions/725701/is-there-a-way-to-mimic-click-and-drag-using-the-keyboard
bindsym $mod2+s exec "xdotool mousedown 1"
bindsym $mod2+d exec "xdotool mouseup 1"
# click: right
bindsym $mod2+g exec "xdotool click 3"

# diretion: up, down, left, right, diagonal
# The diagonal follows the nethack's one.
# https://nethackwiki.com/wiki/Direction
bindsym $mod2+k exec "xdotool mousemove_relative -- 0 -30"
bindsym $mod2+j exec "xdotool mousemove_relative -- 0 30"
bindsym $mod2+h exec "xdotool mousemove_relative -- -30 0"
bindsym $mod2+l exec "xdotool mousemove_relative -- 30 0"
bindsym $mod2+y exec "xdotool mousemove_relative -- -30 -30"
bindsym $mod2+u exec "xdotool mousemove_relative -- 30 -30"
bindsym $mod2+b exec "xdotool mousemove_relative -- -30 30"
bindsym $mod2+n exec "xdotool mousemove_relative -- 30 30"

# direction: up, down, left, right, diagonal - bigger steps
bindsym $mod2+shift+k exec "xdotool mousemove_relative -- 0 -100"
bindsym $mod2+shift+j exec "xdotool mousemove_relative -- 0 100"
bindsym $mod2+shift+h exec "xdotool mousemove_relative -- -100 0"
bindsym $mod2+shift+l exec "xdotool mousemove_relative -- 100 0"
bindsym $mod2+shift+y exec "xdotool mousemove_relative -- -100 -100"
bindsym $mod2+shift+u exec "xdotool mousemove_relative -- 100 -100"
bindsym $mod2+shift+b exec "xdotool mousemove_relative -- -100 100"
bindsym $mod2+shift+n exec "xdotool mousemove_relative -- 100 100"

# direction: up down left right, diagonal - smaller steps
bindsym $mod2+ctrl+k exec "xdotool mousemove_relative -- 0 -2"
bindsym $mod2+ctrl+j exec "xdotool mousemove_relative -- 0 2"
bindsym $mod2+ctrl+h exec "xdotool mousemove_relative -- -2 0"
bindsym $mod2+ctrl+l exec "xdotool mousemove_relative -- 2 0"
bindsym $mod2+ctrl+y exec "xdotool mousemove_relative -- -2 -2"
bindsym $mod2+ctrl+u exec "xdotool mousemove_relative -- 2 -2"
bindsym $mod2+ctrl+b exec "xdotool mousemove_relative -- -2 2"
bindsym $mod2+ctrl+n exec "xdotool mousemove_relative -- 2 2"