Config files and a guide for running Ubuntu 26.04 on a Surface Pro 5 (model 1796, 2017) as a tablet. Everything here fixes a problem I hit on my own machine.
The linux-surface kernel gets the hardware working. It does not make the machine behave like a tablet. After a clean install I had:
- a touchscreen that stopped working after installing a snap
- two-finger touches that zoomed, scrolled and clicked at the same time
- no touch at all after some reboots
- a power button and volume rocker that did nothing
- a boot setup that would pick the wrong kernel after the next kernel update
This repo fixes each of those. Each fix has a doc in docs/ that explains the
cause and shows how to check it yourself.
| Device | Surface Pro 5, model 1796 (2017) |
| OS | Ubuntu 26.04.1 LTS, GNOME 50 on Wayland |
| Kernel | 6.19.8-surface-3 from the linux-surface repo |
| Touch daemon | iptsd 3.1.0 |
| Wi-Fi | Marvell 88W8897 on mwifiex_pcie |
The touchscreen fixes should apply to any Surface that uses IPTS and iptsd
(Pro 4 through Pro 7, Book, Laptop). The button fix is for the ACPI device
MSHW0040. The GRUB hook works on any Ubuntu install where the stock kernel
sorts above the surface one, which is most of them.
If you have a different model, read the docs first and pick what applies.
Install the linux-surface kernel first. See
docs/01-base-install.md. Reboot into it and check
that uname -r contains surface. Then:
git clone https://github.com/Duresa7/surface-pro.git
cd surface-pro
./scripts/check.sh # look before changing anything
sudo ./scripts/install.sh --dry-run # see what would change
sudo ./scripts/install.sh # apply
./scripts/tablet-desktop.sh # desktop settings, run as your own user
sudo rebootAfter the reboot, run ./scripts/check.sh again. It should find no problems.
You can install one part at a time:
sudo ./scripts/install.sh touch # touchscreen only
sudo ./scripts/install.sh grub # boot pinning only
sudo ./scripts/install.sh buttons # power and volume buttons onlyTo remove everything: sudo ./scripts/uninstall.sh.
Touch stops dying after snap installs. The udev rule that ships with
iptsd only matches add events. A snap install re-triggers udev with
change events, the systemd tag is lost, and iptsd gets stopped. Touch
drops to a single-finger mode and the pen stops working. A second rule handles
change events. Details
Two fingers work. The kernel exposes a raw single-touch device next to the
multitouch device that iptsd creates. libinput reads both, so every touch is
counted twice. One finger is fine. Two fingers give a pinch from one device and
extra taps from the other. A udev rule tells libinput to ignore the raw device.
Details
Touch comes up after every boot. The Intel Management Engine is not ready
when iptsd first starts. iptsd asks for a mode switch about 280 ms too
early, the switch fails, and the touch controller gets stuck until the driver
is reloaded. A short delay at boot avoids this. A recovery service reloads the
driver if it still fails. Details
Three-finger swipes register on the first try. iptsd drops a touch that
moves too far between frames. A fast swipe across a 26 cm screen does that. A
small config change raises the limit. Details
Kernel updates do not break boot. GRUB_DEFAULT has to name the surface
kernel by version, because Ubuntu's stock kernel sorts higher and takes entry
0. The name goes stale on the next update and GRUB boots the stock kernel,
which has no touch support. A kernel hook updates the name on every kernel
install or removal. Details
Power button and volume rocker work. The ACPI device MSHW0040 is present
but no driver binds to it at boot, so there are no button input devices. A
small systemd unit asks the kernel to probe it again.
Details
Power button sleeps the machine. A short press suspends instead of opening a menu. Details
| 01 Base install | linux-surface kernel, Secure Boot, Wi-Fi, and packages to skip |
| 02 Touchscreen | The three touch bugs, how to confirm each one, and the gesture tuning |
| 03 Boot and kernel | Why GRUB needs a pin and how the hook keeps it current |
| 04 Buttons and power | MSHW0040, suspend, hibernate, and what the power button can do |
| 05 Tablet experience | Gestures, on-screen keyboards, rotation, and what is not possible |
| Troubleshooting | Symptom, cause, fix |
| Hardware notes | IPTS modes, the HID report descriptor, capability bitmasks |
etc/ files copied to / by install.sh
udev/rules.d/99-iptsd-change.rules keep iptsd alive across udev change events
udev/rules.d/60-iptsd-ignore-raw.rules stop libinput reading every touch twice
systemd/system/iptsd@.service.d/ boot delay, restart, failure escalation
systemd/system/iptsd-recover.service reload the ipts driver to clear a stuck controller
systemd/system/surface-buttons-bind.service
iptsd.d/90-tuning.conf contact detection tuning
kernel/postinst.d/zz-surface-grub-default
scripts/
install.sh safe to re-run, backs up what it replaces, has --dry-run
uninstall.sh removes all of it
check.sh read-only health check
tablet-desktop.sh per-user GNOME settings (do not run with sudo)
Every file under etc/ has a comment at the top that says what it does and
how to undo it.
sudo systemctl start iptsd-recover.serviceThis reloads the ipts driver. It takes about 15 seconds. A plain
systemctl restart iptsd@... does not work once the controller is stuck. It
returns ENODEV. Only a driver reload clears it.
Cameras. The Pro 5 needs IPU3 plus libcamera built from source with tuning files. Kernel 6.19 removed camera detection on this model. The upstream page tracks the current state.
Deep sleep. This hardware has no S3. s2idle is the only sleep state, so
standby uses more battery than an iPad does. That is hardware, not a setting.
Long press for a power menu. systemd's HandlePowerKeyLongPress cannot
fire while GNOME holds its handle-power-key inhibitor lock, and systemd
always honours that kind of lock. GNOME itself has no idea how long you held
the button.
Custom gestures. GNOME's gesture set is fixed. touchegg is not packaged
for Ubuntu 26.04 and only works on X11.
The kernel and the touch daemon come from the linux-surface project. This repo is the set of fixes I needed on top of it.
MIT. See LICENSE.