iwichmann iwichmann - 1 month ago 13
Linux Question

Embedded Qt Mouse Pointer Not Showing Up

I've got a bit of an interesting problem here. There are plenty of threads I've found where people are working to hide or get rid of a cursor on an embedded Qt GUI...but I'm trying to get a cursor to show up on an embedded Qt GUI.

I inherited a project that was 'finished' some time ago, and the person who did the most work on the project has moved on. Fast forward to today and there is a need to add a cursor to this functional touchscreen GUI. The system OS is Yocto Linux, and it is running a Qt 5.4 application on a framebuffer.

I've scoured the Qt code and there is nothing there that would hide a cursor. I've added in the appropriate QT_QPA_FB_HIDECURSOR=0 environment variable to my Qt startup script. I've experimented with adding a QCursor obejct to the GUI. Unfortunately none of these things are working. Using the QCusor I am sometimes able to get a cursor up on the screen, but isn't tied to the touch input (the cursor shows up at the position I programatically move it to, but it stays there when I interact with the GUI).

My touch input events are tied into Qt (via QT_QPA_GENERIC_PLUGINS=evdevtouch and QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event9:rotate=180), but for some reason that touch input cannot be tied to a cursor.

At this point I've spent a few days messing around with environment variables and startup script modifications, but nothing I've done has got the result I'm looking for.

Does anybody out there have some ideas on where to look for solutions to this problem?

Thanks!
Ian

Answer

So, now 3 months later I think my team and I just came up with a passable solution to this problem.

The path towards the solution started with the Qt Documentation on "Using libinput". The documentation boils down to a few important statements:

Parameters like the device node name can be set in the environment variables QT_QPA_EVDEV_MOUSE_PARAMETERS, QT_QPA_EVDEV_KEYBOARD_PARAMETERS and QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS


The mouse cursor shows up whenever QT_QPA_EGLFS_HIDECURSOR (for eglfs) or QT_QPA_FB_HIDECURSOR (for linuxfb) is not set and Qt's libudev-based device discovery reports that at least one mouse is available. When libudev support is not present, the mouse cursor always show up unless explicitly disabled via the environment variable.


The evdevtablet plugin provides basic support for Wacom and similar, pen-based tablets. It generates QTabletEvent events only. To enable it, pass QT_QPA_GENERIC_PLUGINS=evdevtablet in the environment or, alternatively, pass -plugin evdevtablet argument on the command-line. The plugin can take a device node parameter, for example QT_QPA_GENERIC_PLUGINS=evdevtablet:/dev/event1, in case the Qt's automatic device discovery (based either on libudev or a walkthrough of /dev/input/event*) is not functional or misbehaving.


So, in my system I have the device nodes: event0, event1, event2, event3, event4, event5, mice, and mouse0. Because I'm trying to get the mouse working, I made the assumption that I'd have to use the mouse0 node. This lead to me setting these environment variables:

QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/mouse0

Much to my frustration these environment variables led to nothing. After some time my team and I figured out how to get debug output from Qt source on our system:

  • Modifying source code in the qtbase directory under our yocto build (roughly /yocto/poky/build/tmp/work/temp build directory/qtbase
  • Copying qtbase/plugins/generic/libqevdevmouseplugin.so to my hardware (roughly /usr/lib/qt5/plugins/generic)
  • Running Qt from the command line

We quickly discovered that the input events coming from mouse0 and mice were basically garbage data. On our system we did set up EVDEV in the kernel, so the mouse input was also tied to the device node event0. When we tried setting the Qt mouse parameter to event0 we started to see debug output that looked like real data.

QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/event0

However, the problem of no-mouse-pointer still remained. After a while we looked back at the Qt Documentation, specifically at the 2nd paragraph listed above. As a last ditch attempt we tried adding in the QT_QPA_FB_HIDECURSOR environment variable...

QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/event0
QT_QPA_FB_HIDECURSOR=0

And...voila! After countless hours of debugging and reading documentation, we finally got a mouse pointer.

I think the main crux of our issue was misinterpreting the Qt Documentation.

The mouse cursor shows up whenever ... QT_QPA_FB_HIDECURSOR (for linuxfb) is not set

By "not set", Qt means explicitly defined as FALSE...not simply "not set" at all.

This solution will work for us, but it does leave at least one thing to be desired. Along the way I stumbled across this thread answer on the Unix StackEx which points to the Kernel documentation of input/input.txt. In section "3.2.2 mousedev" you can see the line:

Each 'mouse' device is assigned to a single mouse or digitizer, except the last one - 'mice'. This single character device is shared by all mice and digitizers, and even if none are connected, the device is present. This is useful for hotplugging USB mice, so that programs can open the device even when no mice are present.

What this means for us is that while we can use event0 (which goes away when we unplug the mouse) for our mouse input event handling, we won't be able to support hot plugging without making some kernel/Qt-source modifications or figuring out how to get mice working as a Qt mouse input parameter.

So, the question of "why does event0 work and not mouse0/mice" still stands...but for now we've got a solution we can live with.

Comments