Skip to content

Jok0ne/zo-reddot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zo-reddot — disable ThinkPad TrackPoint motion, keep the buttons

zo-reddot — disable ThinkPad TrackPoint motion, keep the buttons on Linux

Dead pointer. Live buttons. Works on Wayland + X11. No BIOS toggle, no xinput gymnastics, no dotfile religion.

GPL-3.0 License Linux Python 3.7+ Wayland | X11 systemd stable

Problem · Install · How it works · Config · Hardware · Troubleshooting · Design


The problem

On modern Linux ThinkPads — Yoga 370, T470, X270, X1 Carbon Gen 5 and most of the 2017-onward Elantech-digitizer lineup — the three TrackPoint buttons below the spacebar share an input device with the red dot (pointing stick) itself. Disable the pointer (BIOS toggle, inhibited=1, xinput disable) and you lose the buttons too. On Wayland, the classic Coordinate Transformation Matrix escape hatch is gone.

Every forum answer, every Stack Overflow thread, every dotfile gist ignores this. Here's the receipt:

Approach Works? Problem
echo 1 > /sys/class/input/inputN/inhibited Disables the whole device, buttons included
BIOS "TrackPoint = Disabled" Same — EC turns off the device entirely
xinput set-prop "Device Enabled" 0 X11 only, also kills the device
libinput AttrTrackpointMultiplier / udev POINTINGSTICK_SENSITIVITY Ignored on many Elantech devices
xinput set-prop "Coordinate Transformation Matrix" 0 0 0 0 0 0 0 0 1 X11 only — useless under Wayland
ZO-REDdot Works on Wayland + X11, keeps buttons

The only fix that actually works is to grab the device at the kernel boundary and drop the X/Y motion while re-emitting the button events through a fresh uinput pointer. 30 lines of Python. That's it.

Install

git clone https://github.com/Jok0ne/zo-reddot.git
cd zo-reddot
./install.sh

The installer:

  • installs python3-evdev (supports dnf / apt-get / pacman),
  • copies zo-reddot.py to /usr/local/bin/ and the unit to /etc/systemd/system/,
  • enables and starts zo-reddot.service.

Root is required — exclusive grab on an input device and writing to /dev/uinput are privileged operations.

Verify

systemctl status zo-reddot
journalctl -u zo-reddot -f

Expected log line:

zo-reddot: grabbed + uinput up — buttons only, motion dropped

Nudge the red dot: nothing. Click any of the three buttons under the spacebar: normal left / middle / right click.

How it works

  ┌────────────────────────┐
  │    TrackPoint device   │  /dev/input/event4
  │   (Elantech ISA PS/2)  │  emits:  BTN_LEFT/RIGHT/MIDDLE  +  EV_REL(X,Y)
  └────────────┬───────────┘
               │  device.grab() — exclusive read
               ▼
  ┌────────────────────────┐
  │       zo-reddot        │  forward:  BTN_LEFT/RIGHT/MIDDLE
  │     event  filter      │  drop:     EV_REL X/Y, scroll emulation
  └────────────┬───────────┘
               │  UInput.write_event() + syn()
               ▼
  ┌────────────────────────┐
  │ "TrackPoint Buttons    │  new /dev/input/eventN
  │  Only" (uinput device) │  advertises only BTN_LEFT/RIGHT/MIDDLE
  └────────────┬───────────┘
               │
               ▼
  ┌────────────────────────┐
  │    libinput +          │  buttons integrate normally,
  │    Wayland / X11       │  no pointer motion
  └────────────────────────┘

libinput and the desktop environment see the new uinput device as a normal button-only pointer and integrate it automatically. The pointing-stick itself has no visible consumer anymore, so nudging it does nothing.

Service survives reboots. Uninstall releases the device cleanly and restores the original behaviour.

Configuration

The service matches the input device by exact name. Default:

TRACKPOINT_NAME=ETPS/2 Elantech TrackPoint

If your device has a different name — find it with cat /proc/bus/input/devices or sudo libinput list-devices — set TRACKPOINT_NAME in /etc/systemd/system/zo-reddot.service:

Environment=TRACKPOINT_NAME=TPPS/2 Elan TrackPoint

Then:

sudo systemctl daemon-reload
sudo systemctl restart zo-reddot

Uninstall

./install.sh uninstall

Stops and disables the service, removes the script and unit file. Original TrackPoint behaviour (pointer + buttons) is back immediately.

Hardware

DeviceDigitizerTested onStatus
ThinkPad Yoga 370 Elantech 056a:50b0 Fedora 42, Plasma 6 Wayland
T470 / T470s / T470p Elantech likely
X270 / L470 Elantech likely
X1 Carbon Gen 5 / X1 Yoga Gen 2 Elantech likely

If you run it successfully on other hardware, a PR adding to this list is welcome.

What this does not touch

  • Touchpad — separate input device.
  • External USB / Bluetooth mice.
  • Keyboard.
  • Plasma / GNOME pointer-speed settings on every other pointer.

Troubleshooting

The service is active but the TrackPoint still moves the cursor

libinput may have cached the original device. Log out and back in, or force a full config reload:

qdbus-qt6 org.kde.KWin /KWin reconfigure

If it still moves, verify the daemon grabbed the right device:

journalctl -u zo-reddot -n 20

You should see grabbing /dev/input/eventN (<device name>). If no input device named '…' found appears instead, your TrackPoint has a different name — set TRACKPOINT_NAME as described in Configuration.

I have a different TrackPoint brand (Synaptics, IBM, ALPS)

Find the exact device name:

cat /proc/bus/input/devices | grep -iE "trackpoint|pointing"

Then set TRACKPOINT_NAME in the unit file. Common values:

  • TPPS/2 Elan TrackPoint
  • TPPS/2 IBM TrackPoint
  • Synaptics TM2334-004
  • AlpsPS/2 ALPS DualPoint Stick
GNOME / Cinnamon / XFCE / Sway support

ZO-REDdot operates at the kernel/uinput layer, below every desktop environment and display server. Anything that speaks libinput or evdev sees the buttons-only device and treats it as a normal button pointer. No desktop-specific configuration needed.

The service enters restart loop

The daemon exits with code 1 if it can't find the matching device. In a restart loop, this usually means the TRACKPOINT_NAME is wrong or the device was renamed after a kernel update. Disable auto-restart temporarily to debug:

sudo systemctl stop zo-reddot
sudo /usr/bin/python3 /usr/local/bin/zo-reddot.py

Read the stderr output, correct the env var, and restart.

Design notes

Why not interception-tools or the C trackpoint-filter?

Both work. ZO-REDdot exists because:

  • Zero compilation. One Python file, done.
  • Readable source — ~30 lines you can audit before running as root.
  • Single dependency (python3-evdev) that every distro packages.
  • One process, one syscall loop — no cascading dependency services.

If you need maximum efficiency, a compiled C equivalent saves ~15 MB of Python RSS. For a background daemon on a modern laptop, that tradeoff is usually fine.

Why run as root?

EVIOCGRAB (exclusive device grab) and writing to /dev/uinput both require CAP_SYS_ADMIN or explicit input-group access plus uaccess. We could drop to a dedicated user with those capabilities, but root + SupplementaryGroups=input is clearer and the attack surface is ~30 lines of code.

Why intercept instead of transform?

X11's Coordinate Transformation Matrix zeros out motion at the server level and leaves buttons alone — elegant, but bound to X11. Wayland has no equivalent primitive exposed to userspace. Kernel-level grab + uinput re-emit works on both, with the same latency as any other input device.

License

GPL-3.0-or-later — see LICENSE.

Copyright © 2026 Zerone. If you redistribute this — modified or not — recipients must keep the same freedoms you received: attribution preserved, source available, changes released under the same terms.

SPDX-License-Identifier: GPL-3.0-or-later

About

Disable the ThinkPad TrackPoint red dot (pointing stick) while keeping the three buttons alive on Linux — Wayland + X11, libinput-compatible, one systemd service. Works on Yoga 370, T470, X270, X1 Carbon Gen 5 and other Elantech devices.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors