树莓派QML全屏应用触摸穿透问题求助(Qt 5.9.1 + VNC环境)
Hey there, I get exactly what you're dealing with—your Qt 5.9.1 QML app runs fullscreen on the RPi's touchscreen but doesn't show up over VNC (which you're okay with), but the real pain is touch events leaking through to the desktop behind, causing accidental app launches or folder edits. And you don't want to go through the hassle of recompiling Qt. Let's fix this with some practical workarounds that don't require touching Qt's source code:
Option 1: Lock Your App to the Top with Window Manager Tools
The Raspberry Pi's default LXDE desktop uses a window manager that lets you pin your app to the absolute top and block input from reaching the desktop below.
- First, make sure your QML Window has the right flags to stay on top and run fullscreen:
Window { // Your existing properties... flags: Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.WindowFullscreen } - Next, install
wmctrlif you don't have it already:sudo apt install wmctrl - After launching your app, run this command to lock it as the topmost window and prevent input leakage:
If you don't know your app's window title, runwmctrl -r "Your App Window Title" -b add,above,stickywmctrl -lto list all open windows and grab the correct name or window ID. This forces your app to stay above all other windows and stops the desktop from receiving any stray touch events.
Option 2: Force Qt to Grab Input Exclusively
You can tweak Qt's input handling at runtime—either via environment variables or QML code—to make your app hoard all touch/mouse events.
Method A: Use an Environment Variable on Launch
Add this environment variable when starting your app to disable X11's MIT Shared Memory extension, which can sometimes cause input to leak:
export QT_X11_NO_MITSHM=1 ./your-qt-app-binary
This makes Qt take direct control of input devices, cutting off the desktop's access.
Method B: Grab Input Directly in QML
Add code to your main Window to actively grab all mouse and touch events when the app is visible:
Window { id: mainWindow // Your existing properties... Component.onCompleted: { mainWindow.grabMouse() mainWindow.grabTouchPoints() } onVisibleChanged: { if (visible) { mainWindow.grabMouse() mainWindow.grabTouchPoints() } else { mainWindow.releaseMouse() mainWindow.releaseTouchPoints() } } }
This ensures that as long as your app is fullscreen and visible, all touch events go straight to it—none slip through to the desktop behind.
Option 3: Temporarily Disable Desktop Touch Input
If the above options don't work, you can take a more direct approach: temporarily disable the touchscreen for the desktop while your app runs, then re-enable it when the app closes.
First, find your touchscreen's device ID with this command:
xinput listLook for a device name like
FT5406 memory based driver(common on RPis) and note the ID listed afterid=.Create a simple launch script to handle disabling/enabling:
#!/bin/bash # Replace "Touchscreen Device Name" with your actual device name from xinput list TOUCH_ID=$(xinput list | grep "Touchscreen Device Name" | awk '{print $6}' | sed 's/id=//') # Disable touch input for the desktop xinput disable $TOUCH_ID # Launch your Qt app ./your-qt-app-binary # Re-enable touch input once the app closes xinput enable $TOUCH_IDThis gives your app exclusive control of the touchscreen while it's running—no way for the desktop to get any touch events.
Quick Notes
- For Option 1, if your app has no window title, use
wmctrl -a $(wmctrl -l | grep "your-app-binary-name" | awk '{print $1}')to target it by process instead. - The
grabMouse()andgrabTouchPoints()functions used in Option 2 are fully supported in Qt 5.9.1, so no version compatibility issues here. - Option 3 relies on X11, which is used by the default LXDE desktop on Raspberry Pi, so it will work out of the box.
Give these options a try—they should all fix your touch leakage problem without needing to recompile Qt. Pick the one that fits your workflow best!
内容的提问来源于stack exchange,提问作者Serkan

