Skip to content

Instantly share code, notes, and snippets.

@ninlith
Created November 12, 2019 21:45
Show Gist options
  • Save ninlith/a567ef4026cabb37ad36b15ba36d419d to your computer and use it in GitHub Desktop.
Save ninlith/a567ef4026cabb37ad36b15ba36d419d to your computer and use it in GitHub Desktop.
A hackish way to bind extra mouse buttons under Wayland.
#!/usr/bin/env bash
# -*- indent-tabs-mode: nil; tab-width: 4 -*-
#
# An ugly way to bind extra mouse buttons under GNOME/Wayland or otherwise.
#
# Prerequisites:
#
# Effectively unbind extra mouse buttons by modifying udev/hwdb rules:
# 1. Identify scancodes:
# sudo evemu-record /dev/input/by-path/*event-mouse \
# | stdbuf -oL grep --only-matching "MSC_SCAN.*" \
# | awk '{printf $2" 0x"; printf "%x\n", $2}'
# 2. Map buttons as keyboard keys in order to disable their functionality (see
# /usr/include/linux/input-event-codes.h for valid keycodes). For example:
# # /etc/udev/hwdb.d/mouse-unbind.hwdb
# evdev:input:*
# KEYBOARD_KEY_90004=key_n
# KEYBOARD_KEY_90005=key_i
# KEYBOARD_KEY_90006=key_l
# 3. Apply configuration:
# sudo systemd-hwdb update && sudo udevadm trigger
# 4. Verify:
# systemd-hwdb query "evdev:input:*"
#
# Depends: evemu-tools
MOUSE_DEVICE=$(readlink -f /dev/input/by-path/*event-mouse)
KEYBOARD_DEVICE=$(readlink -f /dev/input/by-path/*event-kbd)
EVENT_CODE="MSC_SCAN"
MOUSE_BUTTON_SIDE_DOWN="589828" # 0x90004
MOUSE_BUTTON_SIDE_UP="589829" # 0x90005
MOUSE_BUTTON_SWITCH="589830" # 0x90006
# Invokes GNOME Shell overview.
function overview() {
dbus-send --session --type=method_call --dest=org.gnome.Shell \
/org/gnome/Shell org.gnome.Shell.Eval string:'Main.overview.show();'
}
# Returns 0 if GNOME Shell overview is hidden.
function is_overview_hidden() {
dbus-send --print-reply --session --type=method_call \
--dest=org.gnome.Shell \
/org/gnome/Shell org.gnome.Shell.Eval string:'Main.overview.visible' \
2>/dev/null | grep --quiet "false"
}
function key() {
sudo evemu-event "$KEYBOARD_DEVICE" --sync --type EV_KEY \
--code $1 --value $2;
}
function button() {
sudo evemu-event "$MOUSE_DEVICE" --sync --type EV_KEY \
--code $1 --value $2;
}
while read line; do
if [ -z "${line##*$EVENT_CODE*}" ]; then
read nextline
button=${line##* }
value=${nextline##* }
case "$button$value" in
"$MOUSE_BUTTON_SWITCH""1") # Toggle overview
if is_overview_hidden; then
overview
else
button BTN_LEFT 1
button BTN_LEFT 0
fi
;;
"$MOUSE_BUTTON_SIDE_UP""1") # Move to workspace above
key KEY_LEFTMETA 1
key KEY_PAGEUP 1
key KEY_PAGEUP 0
key KEY_LEFTMETA 0
;;
"$MOUSE_BUTTON_SIDE_DOWN""1") # Move to workspace below
key KEY_LEFTMETA 1
key KEY_PAGEDOWN 1
key KEY_PAGEDOWN 0
key KEY_LEFTMETA 0
;;
esac
fi
done < <(sudo evemu-record "$MOUSE_DEVICE")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment