The 'Missing Menu' Problem in Raspberry Pi OS Bookworm

If you are searching for the raspberry pi touchscreen calibration menu preferences calibrate touchscreen option, you have likely hit a wall. In older versions of Raspberry Pi OS (Buster and Bullseye), you could simply navigate to Preferences > Calibrate Touchscreen in the desktop menu. This launched an X11-based tool called xinput_calibrator.

As of 2026, Raspberry Pi OS Bookworm uses the Wayland display server (via the Wayfire or labwc compositors) by default. X11 tools like xinput_calibrator cannot interact with Wayland input devices. Consequently, the Raspberry Pi Foundation removed the GUI menu entry entirely. To calibrate a touchscreen today, you must bypass the missing GUI and apply a calibration matrix directly to the kernel's input subsystem using libinput and udev rules.

Safety & Hardware Warning: Never force a 5V GPIO signal into a 3.3V SPI touch controller (like the XPT2046) without a logic level shifter. While this guide focuses on USB/HDMI touchscreens, mixing voltage domains on the Pi 5 GPIO header will permanently destroy the SoC.

Decision Tree: Which Calibration Method to Use

Not all touchscreens calibrate the same way. Use this decision table to identify your exact hardware and terminate on the correct configuration method.

If Your Screen Interface Is...And The Touch Controller Is...Then Use This MethodConcrete Pick / Value
DSI (Ribbon Cable)FT6236 (Capacitive)Auto-calibrated by firmwareNo action required
HDMI + USB-AILITEK / eGalax (HID)libinput udev matrixENV{LIBINPUT_CALIBRATION_MATRIX}
SPI (GPIO Header)XPT2046 (Resistive)Device Tree Overlaydtoverlay=ads7846,penirq=25

Hardware Spec Sheet & Pin Mapping

This guide targets the most common calibration offender: third-party HDMI+USB resistive screens. The code and steps below are validated on the following exact hardware stack:

  • Compute Board: Raspberry Pi 5 (8GB variant)
  • OS: Raspberry Pi OS Bookworm (64-bit, Wayland desktop)
  • Display: Waveshare 7" HDMI LCD (C) - Resistive USB Touch
  • Storage: 32GB Samsung EVO Plus microSD (A2 rated)

Interface Pin Mapping

Unlike SPI screens that map to specific GPIO pins, USB/HDMI touchscreens rely on the Pi's high-speed peripheral buses. Ensure you are using the correct ports to avoid bandwidth bottlenecks.

Pi 5 PortCableScreen PortFunction
HDMI0 (Micro-HDMI)Micro-HDMI to HDMIHDMI INVideo Signal (Up to 4K60)
USB 3.0 (Blue, Type-A)USB-A to Micro-USBMicro-USB (Touch)HID Touch Data (Must be Data-rated cable)
5V/GND (GPIO 2/6)Jumper Wires (Optional)VCC/GND PinsBacklight Power (if USB power is insufficient)

Step-by-Step: Calibrating via libinput udev Rules

Since the GUI is gone, we apply the calibration matrix at the udev level. This ensures the calibration is applied the moment the kernel detects the USB HID device, long before the Wayland compositor starts.

  1. Identify your touch device vendor and product ID.
    Open a terminal and run lsusb. Look for your touch controller (e.g., ID 0eef:0001 D-WAV Scientific Co., Ltd eGalax TouchScreen). Note the four-digit vendor and product IDs.
  2. Create a custom udev rule.
    Run sudo nano /etc/udev/rules.d/99-touchscreen-calibration.rules.
  3. Paste the calibration matrix rule.
    Replace 0eef and 0001 with your actual IDs. The matrix format is a b c d e f representing a 3x2 transformation matrix. Start with the identity matrix (no transformation) and adjust if rotated.
    ACTION=="add|change", KERNEL=="event*", ATTRS{idVendor}=="0eef", ATTRS{idProduct}=="0001", ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0"
  4. Reload udev and trigger the rule.
    Run sudo udevadm control --reload-rules && sudo udevadm trigger.
  5. Generate the actual matrix values.
    Since Wayland lacks a native GUI calibrator out-of-the-box, install wf-calibrator (if using Wayfire) or use the Python diagnostic script below to map raw coordinates to screen pixels, then calculate the 6-value matrix using the libinput calibration math formula.

Python Diagnostic Script: Verifying Touch Coordinates

To verify your calibration or gather raw data to build your matrix, you need to read the HID events directly from the kernel. This Python script uses the evdev library to intercept raw touch coordinates. It includes robust error handling for permission and device-binding failures.

Prerequisite: Install the library via sudo apt install python3-evdev and ensure your user is in the input group (sudo usermod -aG input $USER).

#!/usr/bin/env python3
"""
Touchscreen Diagnostic & Calibration Verifier
Target: Raspberry Pi 5 (Bookworm 64-bit, Wayland)
Reads raw ABS_X and ABS_Y events to verify libinput calibration.
"""
import sys
import os
import evdev
from evdev import InputDevice, ecodes

def find_touchscreen():
    """Iterate through /dev/input/event* to find a device with ABS_X/ABS_Y."""
    devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
    for device in devices:
        caps = device.capabilities()
        if ecodes.EV_ABS in caps:
            abs_caps = caps[ecodes.EV_ABS]
            abs_codes = [i[0] for i in abs_caps]
            if ecodes.ABS_X in abs_codes and ecodes.ABS_Y in abs_codes:
                return device
    return None

def main():
    try:
        ts = find_touchscreen()
        if not ts:
            print('ERROR: No touchscreen device found with ABS_X/ABS_Y capabilities.')
            print('Check if the USB cable is data-rated and the kernel bound the hid-multitouch driver.')
            sys.exit(1)

        print(f'Successfully bound to: {ts.name} at {ts.path}')
        print('Tap the screen. Press Ctrl+C to exit.\n')

        for event in ts.read_loop():
            if event.type == ecodes.EV_ABS:
                if event.code == ecodes.ABS_X:
                    print(f'Raw X: {event.value:05d} | ', end='')
                elif event.code == ecodes.ABS_Y:
                    print(f'Raw Y: {event.value:05d}')

    except PermissionError:
        print('FATAL: Permission denied reading /dev/input/event*.')
        print('FIX: Run \'sudo usermod -aG input $USER\' and reboot, or run this script with sudo.')
        sys.exit(1)
    except FileNotFoundError as e:
        print(f'FATAL: Device node missing. {e}')
        sys.exit(1)
    except KeyboardInterrupt:
        print('\nDiagnostic interrupted by user. Exiting cleanly.')
        sys.exit(0)

if __name__ == '__main__':
    main()

Troubleshooting: Exact Error Strings & Ranked Causes

When calibration fails, the system rarely gives a helpful GUI popup. Here are the exact terminal error strings you will encounter, ranked by probability, with their fixes.

The First Three Things to Check When It Fails:
1. Verify the USB cable is data-capable, not a charge-only cable (run lsusb; if the touch device isn't listed, it's a bad cable).
2. Confirm your session type by running echo $XDG_SESSION_TYPE. If it says wayland, X11 tools will silently fail.
3. Run libinput list-devices to ensure the kernel actually handed the device off to libinput.

Error String: "Error: No calibratable devices found."

Context: This occurs when you attempt to run the legacy xinput_calibrator command on a modern Bookworm installation.

  1. Cause 1 (90% probability): You are on Wayland, but xinput_calibrator only queries the X11 input server. Fix: Use the libinput udev method detailed above.
  2. Cause 2 (8% probability): The touch controller is bound to the hid-multitouch kernel driver, but X11 is looking for an evdev driver. Fix: Force X11 to use evdev via xorg.conf.d (only if you explicitly reverted to X11).
  3. Cause 3 (2% probability): The USB port is suspended for power saving. Fix: Add usbcore.autosuspend=-1 to /boot/firmware/cmdline.txt.

Error String: "libinput bug: device calibration failed"

Context: This appears in journalctl -u wayfire or labwc logs when your udev rule contains an invalid matrix.

  1. Cause 1: The matrix string does not contain exactly 6 space-separated floating-point numbers. Fix: Correct the syntax in 99-touchscreen-calibration.rules.
  2. Cause 2: The matrix values are mathematically impossible (e.g., all zeros), resulting in a non-invertible transformation. Fix: Reset to the identity matrix 1 0 0 0 1 0 and recalculate.

Extending and Simplifying the Build

Manual matrix calibration on Wayland is a necessary evil for cheap third-party screens, but it is not the only path forward. Here is how to alter your project scope based on your tolerance for configuration.

How to Simplify the Build:
If you are building a commercial kiosk or a permanent home-automation dashboard and want to eliminate calibration debugging entirely, abandon third-party HDMI+USB screens. Purchase the Official Raspberry Pi 7" Touch Display (Part # SC0512). Because it uses the DSI ribbon cable and an Atmel capacitive controller, the Pi firmware applies the calibration matrix automatically at boot. You will never need to write a udev rule.

How to Extend the Build:
Resistive touchscreens suffer from poor edge-of-screen accuracy, making it difficult to hit window close buttons or swipe-down menu preferences. To extend the usability of your current hardware without recalibrating, add an Adafruit Rotary Trinkey (USB-C) or a standard I2C rotary encoder mapped to keyboard arrows via evmapy. This allows you to handle menu navigation and scrolling mechanically, reserving the touchscreen strictly for large, center-screen button taps where the calibration matrix is most accurate.