Skip to content

QQuickItem: Guard against cycles in nextPrevItemInTabFocusChain

Fixes https://bugs.kde.org/show_bug.cgi?id=370676 (kscreenlocker_greet hang when pressing Tab key) and https://bugreports.qt.io/browse/QTBUG-87190 (upstream bug).

Original commit info

Change was approved at https://codereview.qt-project.org/c/qt/qtdeclarative/+/409500. Original description:

nextPrevItemInTabFocusChain already had a check to prevent running into cycles, it would however only detect if we reached the original item. If our cycle instead would loop between reachable items without ever returning to the initial one, as in the diagram below, then we would never terminate the loop.

            /-->other item<---next item
initial-item           \          ^
                        \         |
			 --->different item

To prevent this from happening, we keep track of all items we've seen so far. One last complications arises due to the fact that we do visit the parent twice under some cicrcumstances, but we already have the skip variable to indicate that case – we simply skip the duplicate check if it is set to true.

Pick-to: 6.2 6.3
Fixes: QTBUG-87190
Change-Id: I1449a7ebf8f325f00c296e8a8db4360faf1049e4
Reviewed-by: Volker Hilsheimer volker.hilsheimer@qt.io

(cherry picked from commit e74bcf75)

Testing performed

I tested to verify that this patch builds on Qt 5 and fixes the bug. My concern is that the qduplicatetracker_p.h header is different between Qt 5 and 6, but it seems to build and run fine in practice. I did not ensure that there are no hidden semantic differences in this header.

  • sudo pacman -R qt5-virtualkeyboard to make the hang happen
  • Recompile the qt5-declarative package with this change using makepkg, and install it
  • Super+L to lock the screen, then press Tab without password prompt visible

kscreenlocker_greet did not hang. Additionally the tab key seems to work fine in Application Launcher and the lock screen.

Note that when kscreenlocker_greet's password prompt is hidden, Tab still behaves oddly (the first Tab does nothing, the second tab shows the UI but the password prompt is unresponsive, the third tab underlines my username and the fourth focuses the password prompt). kscreenlocker_greet with prompt hidden should be fixed to eat Tab keypresses, and show the prompt and highlight the password prompt.

  • sudo pacman -S qt5-declarative (unpatched version)
  • Super+L to lock the screen, then press Tab without password prompt visible

kscreenlocker_greet hangs, does not respond to SIGTERM from TTY2, must use SIGKILL.

Operating System: Arch Linux
KDE Plasma Version: 5.24.5
KDE Frameworks Version: 5.93.0
Qt Version: 5.15.3
Kernel Version: 5.17.4-zen1-1-zen (64-bit)
Graphics Platform: X11
Processors: 12 × AMD Ryzen 5 5600X 6-Core Processor
Memory: 15.6 GiB of RAM
Graphics Processor: NVIDIA GeForce GT 730/PCIe/SSE2

BUG: 370676

Merge request reports