Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
None
-
5.7.0
-
None
Description
A transient QWidget with Qt::WA_ShowWithoutActivating attribute set request the wl_shell_surface_set_transient without the inactive flag. This results in the Compositor passing keyboard focus to the widget. Depending on the implementation of the widget this can result in the widget just closing again.
To reproduce:
1. Use Plasma/Wayland session
2. Open e.g. kwrite
3. Click File open
4. Try to navigate to a directory using the classic file filter bar
Observe that the autocompletion list for directories always closes directly.
A snippet from WAYLAND_DEBUG of the problematic area:
[3280161.761] wl_keyboard@3.key(69929, 25155703, 14, 1) [snip] [3280166.192] -> wl_compositor@4.create_surface(new id wl_surface@75) [3280166.219] -> wl_shell@5.get_shell_surface(new id wl_shell_surface@67, wl_surface@75) [3280166.243] -> qt_surface_extension@10.get_extended_surface(new id qt_extended_surface@76, wl_surface@75) [3280166.266] -> wl_shell_surface@67.set_title("") [3280166.284] -> wl_shell_surface@67.set_class("qfiledialogtest") [3280166.301] -> wl_shell_surface@67.set_transient(wl_surface@52, 472, 75, 0) [3280166.330] -> wl_surface@75.set_buffer_scale(1) [3280166.343] -> qt_extended_surface@76.set_content_orientation_mask(0) [3280166.357] -> qt_extended_surface@76.set_window_flags(4) [3280166.371] -> wl_shell_surface@67.set_transient(wl_surface@52, 472, 75, 0) [3280166.400] -> wl_surface@75.set_buffer_transform(0) [3280166.413] -> wl_surface@75.commit() [snip] [3280177.303] wl_keyboard@3.leave(69930, wl_surface@52) [snip] [3280177.563] wl_keyboard@3.enter(69932, wl_surface@75, array) [snip] [3280184.402] -> wl_surface@75.attach(nil, 0, 0) [3280184.429] -> wl_surface@75.commit()
We can see from the snippet that on key press a new transient surface is mapped with flag "0" for the surface which currently has keyboard focus. The compositor now passes keyboard focus to that surface, which results in the client to unmap the newly opened surface again.
A git grep of _q_showWithoutActivating and WA_ShowWithoutActivating does not give any results, while there is code specific to that in other qpa plugins:
git grep _q_showWithoutActivating plugins/platforms/cocoa/qcocoawindow.mm: QVariant showWithoutActivating = window()->property("_q_showWithoutActivating"); plugins/platforms/ios/qioswindow.mm: if (!window()->property("_q_showWithoutActivating").toBool()) plugins/platforms/windows/qwindowswindow.cpp: const QVariant showWithoutActivating = window->property("_q_showWithoutActivating"); plugins/platforms/xcb/qxcbwindow.cpp: const QVariant showWithoutActivating = window->property("_q_showWithoutActivating"); widgets/kernel/qwidget.cpp: win->setProperty("_q_showWithoutActivating", QVariant(true));