HW cursor is not reactivated after a VT Switch
Dear community,
I am currently working on a HW cursor problem, that appears in a custom distribution using XServer and QT5. As the title describes the XServer uses the HW cursor which is not visible after the following actions:
- Switch from one fullscreen QT window to another and back (the second one uses QML widgets and shader)
- Switch to another VT and back (STRG-ALT-F*)
- Cursor is not visible on the QT window and movement does not reactivate it
Used software versions:
- XServer 1.20.8
- QT 5.12.3
XServer configuration:
./configure --prefix=/usr --disable-silent-rules --enable-screensaver --disable-dri --disable-linux-apm --disable-linux-acpi --disable-input-thread --disable-systemd-logind --without-systemd-daemon --disable-xcsecurity --disable-xdm-auth-1 --disable-xf86bigfont --disable-xnest --disable-xwayland --disable-xwin --with-log-dir=/var/log --with-module-dir=/usr/lib/xorg/modules --with-xkb-output=/var/cache/xkb --with-xkb-path=/usr/share/X11/xkb --with-sha1=libcrypto --disable-int10-module --disable-vbe --disable-vgahw --enable-libunwind --with-systemd-daemon --enable-xephyr --enable-kdrive --enable-glamor --disable-xvfb
QT configuration:
./configure -confirm-license -opensource -prefix <folder>/qt5/_/usr -archdatadir <folder>/qt5/_/usr/lib/qt5 -bindir <folder>/qt5/_/usr/bin -datadir <folder>/qt5/_/usr/share/qt5 -docdir <folder>/qt5/_/usr/share/doc/qt5 -headerdir <folder>/qt5/_/usr/include/qt5 -sysconfdir /etc/xdg -hostprefix <folder>/qt5/_/usr -hostdatadir <folder>/qt5/_/usr/share/qt5 -alsa -force-pkg-config -make libs -make tools -nomake tests -no-rpath -reduce-relocations -shared -use-gold-linker -recheck-all -ccache -no-pch -verbose -no-strip -qpa xcb -no-directfb -no-eglfs -no-kms -no-linuxfb -dbus-linked -fontconfig -glib -iconv -no-cups -no-dbus -no-evdev -no-harfbuzz -no-icu -no-libinput -no-libudev -no-sm -zlib -opengl desktop -openssl-linked -qt-pcre -skip qtactiveqt -skip qtscript -skip qtxmlpatterns -skip qtdoc -skip qtrepotools -skip qtqa -skip qtlocation -skip qtsensors -skip qtsystems -skip qtfeedback -skip qtdocgallery -skip qtpim -skip qtconnectivity -skip qtwayland -skip qt3d -skip qtserialbus -skip qtserialport -skip qtmacextras -skip qtwinextras -skip qtandroidextras -skip qtwebsockets -skip qtwebchannel -skip qtwebengine -skip qtcanvas3d -skip qtwebview -skip qtpurchasing -skip qtcharts -skip qtdatavis3d -skip qtvirtualkeyboard -skip qtgamepad -skip qtscxml -skip qtnetworkauth -skip qtwebglplugin -xcb -xcb-xlib -xkbcommon
Used hardware:
- Lenovo T590
State of issue analysis: I've seen that during a VT switch the cursor handle is saved from ScreenPriv->CurrentCursor into ScreenPriv->SavedCursor (xf86CursorPriv.h) and recovered the other way around when switching back. This is caused by a call to xf86CursorEnableDisableFBAccess (xf86CursorRD.c). But the window switch (action 1.) leads to the following call chain which in case sets ScreenPriv->CurrentCursor to NullCursor. As a consequence the cursor handle can neither be saved nor restored during the VT switch.
Backtrace:
0: /usr/bin/Xorg (xf86CursorSetCursor+0x208) [0x8c23b30e1f8]
1: /usr/bin/Xorg (miPointerUpdateSprite+0x168) [0x8c23b3ce558]
2: /usr/bin/Xorg (miPointerSetCursorPosition+0x120) [0x8c23b3ce7c0]
3: /usr/bin/Xorg (AnimCurSetCursorPosition+0x63) [0x8c23b361d23]
4: /usr/bin/Xorg (InitializeSprite+0x176) [0x8c23b299516]
5: /usr/bin/Xorg (AttachDevice+0x21e) [0x8c23b28733e]
6: /usr/bin/Xorg (ActivateKeyboardGrab+0x180) [0x8c23b29fc80]
7: /usr/bin/Xorg (ActivatePassiveGrab+0x8e) [0x8c23b29b46e]
8: /usr/bin/Xorg (CheckPassiveGrabsOnWindow+0x14a) [0x8c23b29b8ca]
9: /usr/bin/Xorg (CheckDeviceGrabs+0x22c) [0x8c23b29c93c]
10: /usr/bin/Xorg (ProcessDeviceEvent+0x49d) [0x8c23b37419d]
11: /usr/bin/Xorg (ProcessOtherEvent+0x2eb) [0x8c23b3744fb]
12: /usr/bin/Xorg (XkbHandleActions+0x1c6) [0x8c23b39d256]
13: /usr/bin/Xorg (AccessXFilterPressEvent+0x21b) [0x8c23b3969fb]
14: /usr/bin/Xorg (mieqProcessDeviceEvent+0x19b) [0x8c23b3c555b]
15: /usr/bin/Xorg (mieqProcessInputEvents+0xa1) [0x8c23b3c56c1]
16: /usr/bin/Xorg (ProcessInputEvents+0x18) [0x8c23b2cc6e8]
17: /usr/bin/Xorg (Dispatch+0xa7) [0x8c23b28f057]
18: /usr/bin/Xorg (dix_main+0x376) [0x8c23b293386]
19: /lib/libc.so.6 (__libc_start_main+0xeb) [0x7583f17be08b]
20: /usr/bin/Xorg (_start+0x2a) [0x8c23b27d1fa]
If the cursor could not be restored with that "backup mechanism" I would assume that it is at least reactivated when the mouse is moved again (like it can be observed from major distributions e.g. Ubuntu) with a call like this:
Backtrace:
0: /usr/bin/Xorg (xf86CursorSetCursor+0x232) [0x4725e275172]
1: /usr/bin/Xorg (miPointerUpdateSprite+0x1ce) [0x4725e3354ee]
2: /usr/bin/Xorg (miPointerDisplayCursor+0xa6) [0x4725e3357f6]
3: /usr/bin/Xorg (CursorDisplayCursor+0x1a3) [0x4725e283ea3]
4: /usr/bin/Xorg (AnimCurDisplayCursor+0xb6) [0x4725e2c9196]
5: /usr/bin/Xorg (ChangeToCursor+0x5e) [0x4725e1ff3ce]
6: /usr/bin/Xorg (WindowHasNewCursor+0x4f) [0x4725e2008ff]
7: /usr/bin/Xorg (ChangeWindowAttributes+0xd1d) [0x4725e223f4d]
8: /usr/bin/Xorg (ProcChangeWindowAttributes+0x9c) [0x4725e1f019c]
9: /usr/bin/Xorg (Dispatch+0x2fe) [0x4725e1f61fe]
10: /usr/bin/Xorg (dix_main+0x376) [0x4725e1fa2d6]
11: /lib/libc.so.6 (__libc_start_main+0xeb) [0x74c222d1e08b]
12: /usr/bin/Xorg (_start+0x2a) [0x4725e1e414a]
But this is neither the case. Only an additional connection (another application) to the XServer socket for example triggers a reactivation.
Questions:
- Which XServer layer/mechanism causes the cursor reactivation when moving? (e.g. ProcChangeWindowAttributes)
- Is it possible to enforce this cursor reactivation (in my case after a VT switch) e.g. with a XLib/xcb call?
- I found some documentation on ramdac. Is there more documentation available that explains the overall cursor handling?
Thanks for any hint or documentation recommendation.
Best regards