Use packaged Dell XPS touchpad haptics (#5534)

* Configure Dell XPS haptics directly

* Use packaged Dell XPS touchpad haptics service

* fix: keep one Dell haptics migration

* We already have a dedicated Trigger > Hardware menu

* Name for action

* Moved

* Need to make the package available for offline

* Simplify

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
This commit is contained in:
Jacob Mink
2026-05-08 21:07:51 +02:00
committed by GitHub
co-authored by David Heinemeier Hansson
parent 30f9a8da54
commit 1537547f91
9 changed files with 43 additions and 135 deletions
-96
View File
@@ -1,96 +0,0 @@
#!/usr/bin/env python3
# omarchy:summary=Run the Synaptics touchpad haptic feedback daemon
"""Haptic feedback daemon for Synaptics touchpads with Manual Trigger.
Monitors touchpad button press events and sends haptic pulses via HID
feature reports. Required because the kernel's HID haptic subsystem only
supports Auto Trigger with waveform enumeration, not the simpler Manual
Trigger protocol used by these Synaptics touchpads.
"""
import fcntl, glob, os, struct, sys
VENDOR = "06CB"
REPORT_ID = 0x37
INTENSITY = 40 # 0-100
# input_event: struct timeval (16 bytes on 64-bit) + type(H) + code(H) + value(i)
EVENT_FORMAT = "llHHi"
EVENT_SIZE = struct.calcsize(EVENT_FORMAT)
EV_KEY = 0x01
BTN_LEFT = 272
BTN_RIGHT = 273
BTN_MIDDLE = 274
# ioctl: HIDIOCSFEATURE(len) = _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
def HIDIOCSFEATURE(length):
return 0xC0000000 | (length << 16) | (ord("H") << 8) | 0x06
def find_hidraw():
for path in sorted(glob.glob("/sys/class/hidraw/hidraw*")):
uevent = os.path.join(path, "device", "uevent")
try:
with open(uevent) as f:
content = f.read().upper()
if f"0000{VENDOR}" in content:
return os.path.join("/dev", os.path.basename(path))
except OSError:
continue
return None
def find_touchpad_event():
for path in sorted(glob.glob("/sys/class/input/event*/device/name")):
try:
with open(path) as f:
name = f.read().strip().upper()
if VENDOR in name and "TOUCHPAD" in name:
event = path.split("/")[-3]
return os.path.join("/dev/input", event)
except OSError:
continue
return None
def main():
hidraw = find_hidraw()
if not hidraw:
print("No Synaptics haptic touchpad hidraw device found", file=sys.stderr)
sys.exit(1)
event = find_touchpad_event()
if not event:
print("No Synaptics haptic touchpad input device found", file=sys.stderr)
sys.exit(1)
print(f"Haptic touchpad: hidraw={hidraw} input={event} intensity={INTENSITY}", flush=True)
haptic_report = struct.pack("BB", REPORT_ID, INTENSITY)
ioctl_req = HIDIOCSFEATURE(len(haptic_report))
hidraw_fd = os.open(hidraw, os.O_RDWR)
event_fd = os.open(event, os.O_RDONLY)
try:
while True:
data = os.read(event_fd, EVENT_SIZE)
if len(data) < EVENT_SIZE:
continue
_, _, ev_type, code, value = struct.unpack(EVENT_FORMAT, data)
if ev_type == EV_KEY and code in (BTN_LEFT, BTN_RIGHT, BTN_MIDDLE) and value == 1:
try:
fcntl.ioctl(hidraw_fd, ioctl_req, haptic_report)
except OSError:
pass
except KeyboardInterrupt:
pass
finally:
os.close(event_fd)
os.close(hidraw_fd)
if __name__ == "__main__":
main()
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
# omarchy:summary=Match Dell XPS systems with the Synaptics haptic touchpad.
omarchy-hw-match "XPS" && [[ -e /sys/bus/i2c/devices/i2c-VEN_06CB:00 ]]
+17 -1
View File
@@ -233,13 +233,18 @@ show_hardware_menu() {
options="$options\n󰟸 Touchpad" options="$options\n󰟸 Touchpad"
fi fi
if omarchy-hw-dell-xps-haptic-touchpad && omarchy-cmd-present dell-xps-touchpad-haptics; then
options="$options\n󰌌 Touchpad Haptics"
fi
if omarchy-hw-touchscreen; then if omarchy-hw-touchscreen; then
options="$options\n󰆽 Touchscreen" options="$options\n󰆽 Touchscreen"
fi fi
case $(menu "Toggle" "$options") in case $(menu "Toggle" "$options") in
*Laptop*) omarchy-hyprland-monitor-internal toggle ;; *Laptop*) omarchy-hyprland-monitor-internal toggle ;;
*Mirror*) omarchy-hyprland-monitor-internal-mirror toggle;; *Mirror*) omarchy-hyprland-monitor-internal-mirror toggle ;;
*Haptics*) show_hardware_touchpad_haptics_menu ;;
*Touchpad*) omarchy-toggle-touchpad ;; *Touchpad*) omarchy-toggle-touchpad ;;
*Touchscreen*) omarchy-toggle-touchscreen ;; *Touchscreen*) omarchy-toggle-touchscreen ;;
*"Hybrid GPU"*) present_terminal omarchy-toggle-hybrid-gpu ;; *"Hybrid GPU"*) present_terminal omarchy-toggle-hybrid-gpu ;;
@@ -247,6 +252,17 @@ show_hardware_menu() {
esac esac
} }
show_hardware_touchpad_haptics_menu() {
local current=$(dell-xps-touchpad-haptics get)
local selected=$(menu "Touchpad Haptics" "low\nmid\nhigh" "" "$current")
if [[ -n $selected ]]; then
dell-xps-touchpad-haptics set "$selected"
else
back_to show_hardware_menu
fi
}
show_style_menu() { show_style_menu() {
case $(menu "Style" "󰸌 Theme\n󰟵 Unlock\n Font\n Background\n Hyprland\n󱄄 Screensaver\n About") in case $(menu "Style" "󰸌 Theme\n󰟵 Unlock\n Font\n Background\n Hyprland\n󱄄 Screensaver\n About") in
*Theme*) show_theme_menu ;; *Theme*) show_theme_menu ;;
-2
View File
@@ -50,8 +50,6 @@ run_logged $OMARCHY_INSTALL/config/hardware/intel/fred.sh
run_logged $OMARCHY_INSTALL/config/hardware/intel/fix-wifi7-eht.sh run_logged $OMARCHY_INSTALL/config/hardware/intel/fix-wifi7-eht.sh
run_logged $OMARCHY_INSTALL/config/hardware/intel/sof-firmware.sh run_logged $OMARCHY_INSTALL/config/hardware/intel/sof-firmware.sh
run_logged $OMARCHY_INSTALL/config/hardware/dell/fix-xps-haptic-touchpad.sh
run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-asus-ptl-display-backlight.sh run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-asus-ptl-display-backlight.sh
run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-asus-ptl-b9406-display.sh run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-asus-ptl-b9406-display.sh
run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-asus-ptl-b9406-touchpad.sh run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-asus-ptl-b9406-touchpad.sh
@@ -1,36 +0,0 @@
# Fix Dell XPS haptic touchpad.
# The Synaptics haptic touchpad (vendor 06CB) uses the HID Manual Trigger
# protocol, but the kernel's HID haptic subsystem only supports Auto Trigger.
# This sets up a lightweight daemon that monitors touchpad button events and
# sends haptic pulses via HID feature reports on the hidraw device.
# Also disables I2C runtime PM to prevent the haptic engine losing state
# across suspend/resume.
if omarchy-hw-match "XPS" \
&& ls /sys/bus/i2c/devices/i2c-VEN_06CB:00 2>/dev/null; then
# Keep I2C controller power on to prevent haptic engine losing state
sudo tee /etc/udev/rules.d/99-dell-xps-haptic-touchpad.rules << 'EOF'
ACTION=="add", SUBSYSTEM=="pci", KERNEL=="0000:00:19.0", ATTR{power/control}="on"
ACTION=="add", SUBSYSTEM=="platform", KERNEL=="i2c_designware.0", ATTR{power/control}="on"
EOF
sudo udevadm control --reload-rules
# Haptic feedback daemon as a systemd service
sudo tee /etc/systemd/system/dell-xps-haptic-touchpad.service << SVC
[Unit]
Description=Dell XPS haptic touchpad feedback
After=systemd-udev-settle.service
[Service]
Type=simple
ExecStart=$OMARCHY_PATH/bin/omarchy-haptic-touchpad
Restart=on-failure
RestartSec=2
[Install]
WantedBy=multi-user.target
SVC
sudo systemctl daemon-reload
sudo systemctl enable dell-xps-haptic-touchpad.service
fi
+3
View File
@@ -61,6 +61,9 @@ vulkan-asahi
# Surface laptop support packages # Surface laptop support packages
linux-firmware-marvell linux-firmware-marvell
# Dell laptop support packages
dell-xps-touchpad-haptics
# T2 MacBook support packages # T2 MacBook support packages
apple-bcm-firmware apple-bcm-firmware
apple-t2-audio-config apple-t2-audio-config
+1
View File
@@ -7,4 +7,5 @@ run_logged $OMARCHY_INSTALL/packaging/tuis.sh
run_logged $OMARCHY_INSTALL/packaging/npx.sh run_logged $OMARCHY_INSTALL/packaging/npx.sh
run_logged $OMARCHY_INSTALL/packaging/asus-rog.sh run_logged $OMARCHY_INSTALL/packaging/asus-rog.sh
run_logged $OMARCHY_INSTALL/packaging/framework16.sh run_logged $OMARCHY_INSTALL/packaging/framework16.sh
run_logged $OMARCHY_INSTALL/packaging/dell-xps-touchpad-haptics.sh
run_logged $OMARCHY_INSTALL/packaging/surface.sh run_logged $OMARCHY_INSTALL/packaging/surface.sh
+3
View File
@@ -0,0 +1,3 @@
if omarchy-hw-dell-xps-haptic-touchpad; then
omarchy-pkg-add dell-xps-touchpad-haptics
fi
+14
View File
@@ -0,0 +1,14 @@
echo "Move Dell XPS touchpad haptics into the packaged service"
if omarchy-hw-dell-xps-haptic-touchpad; then
sudo systemctl disable --now dell-xps-haptic-touchpad.service 2>/dev/null || true
sudo rm -f /etc/systemd/system/dell-xps-haptic-touchpad.service
sudo rm -f /etc/systemd/system/multi-user.target.wants/dell-xps-haptic-touchpad.service
sudo rm -rf /etc/systemd/system/dell-xps-haptic-touchpad.service.d
sudo rm -f /etc/udev/rules.d/99-dell-xps-haptic-touchpad.rules
sudo rm -f /etc/omarchy-dell-haptic-touchpad.env
sudo systemctl daemon-reload
sudo udevadm control --reload-rules
source "$OMARCHY_PATH/install/packaging/dell-xps-touchpad-haptics.sh"
fi