Sherief, FYI

Touchpad Jitters

Ever since I got my latest laptop (a 2022 Razer Blade 15 Advanced) I’ve noticed that sometimes the mouse cursor would become jumpy, not tracking finger motion correctly, and when that happens some gestures like two-finger scrolling and three-finger-tap for middle-click would fail - I guess because the jumpy cursor interferes with the state machine for the gesture recognition. It’s very annoying, and more so since I’m very sensitive to pointer ballistics.

This didn’t happen with an external mouse, so I ruled out a system-wide issue, and would go away after a reboot. A reboot is however very disruptive, and I started trying to think of ways to avoid that. The closest thing I could think of to rebooting was to disable, then re-enable, the device in question.

I started at Hardware Component Guidelines for Precision Trackpads - Device Connectivity, and it mentioned two methods for precision trackpads to be connected: I2C, or USB. Most devices whose datasheets I’ve seen were I2C (or SPI) devices and a USB protocol chip would be more money on the Bill of Materials, so I made the educated guess to start looking at I2C devices. Expanding the Human Interface Devices node showed one “I2C HID Device”:

I2C Device in Device Manager

Looking at the device, it’s enumerated via ACPI (so almost definitely built-in) and the vendor is ELAN:

I2C device info

That seemed to be it - disabled the device, touchpad stopped working. I waited till the issue manifested again, which I noticed would happen when I close the lid of my laptop sometimes, and tried disabling and re-enabling the device and voila, once re-enabled the touchpad was responding perfectly. So at this point the reboot requirement, and all the disruption it entails, has been worked-around.

I started googling the issue, and found a few bugs - one bug against VoodoI2C and another filed against libinput with the promising title Razer Blade 15 2021 Touchpad jump after wake. The behavior described is near-identical and a comment mentions this occuring on Windows 11, so probably not a Linux-specific issue (I run Windows 10). From some code spelunking, it looks like sending I2C_HID_POWER_ON after a wake breaks the ELAN touchpad controller according to this Linux kernel code comment. On Linux a vendor-specific “quirk” flag is added to the I2C code, and on Windows the corresponding part would be hidi2c.sys - ideally, it should include code to detect the ELAN controllers and apply the quirk. I reported the issue, but as of the time of writing no progress has happened and the Microsoft I2C driver is still broken for this touchpad family.

The first few months I kept my laptop on a desk 99% of the time, so this wasn’t a big deal, but more recently I’ve been carrying it around and opening the lid to find a jittery touchpad and having to do the Device Manager song-and-dance to fix it got really old really fast, and with no fixes from Microsoft on the horizon I decided to see what can be done about it. Patching the driver was a no-go, as loading unsigned drivers is fragile and higher friction than the trip to Device Manager - so I decided to automate the device disable / enable on resume.

The first part that was needed is a way to enable / disable a device via its hardware path - I used the SetupDi*() driver installer family of functions to do that, and ended up with a SetDeviceState() function. Then I’d Create a window and register it to receive suspend / resume events via RegisterSuspendResumeNotification(). A simple WindowProc() that listens for WM_POWERBROADCAST with a wParam of PBT_APMRESUMEAUTOMATIC to detect a wake-from-sleep, then it would use SetDeviceState() to disable and re-enable the touchpad. The whole program is ~250 lines of my own code, and another ~250 lines for a utility function to check whether the user is an administrator as the SetupDi*() family of API calls understandably require elevated privileges.

Adding the resulting binary as a scheduled task with elevated privileges to launch on every reboot has solved my issue - finally I can just close the lid, carry my laptop somewhere else, then re-open the lid. A basic ask for a laptop I’d say, but one that is unfortunately a bit too far out of reach for the hardware and software supply chains involved in this case.