[wayland] Ensure our own windows don't have flag Qt::X11BypassWindowManagerHint
The QtWayland QPA plugin does not create windows with X11BypassWindowManagerHint which means that KWin's internal windows are not shown at all. Even worse in QtQuick it can result in a freeze due to blocking wait for a frame rendered which can just never happen. As windows could be created by e.g. scripts or look and feel packages we cannot ensure that the flag will never be set in source code. Thus we use ApplicationWayland::notify to filter for Show events and check whether the window to be shown is bypassing window manager hits. If it is, we unset the flag, destroy the window and show a new one.
This commit is contained in:
parent
cdf5ef113a
commit
f81655b7f5
1 changed files with 11 additions and 1 deletions
|
@ -237,13 +237,23 @@ void ApplicationWayland::createX11Connection()
|
|||
|
||||
bool ApplicationWayland::notify(QObject *o, QEvent *e)
|
||||
{
|
||||
if (qobject_cast< QWindow* >(o)) {
|
||||
if (QWindow *w = qobject_cast< QWindow* >(o)) {
|
||||
if (e->type() == QEvent::Expose) {
|
||||
// ensure all Wayland events both on client and server side are dispatched
|
||||
// otherwise it is possible that Qt starts rendering and blocks the main gui thread
|
||||
// as it waits for the callback of the last frame
|
||||
waylandServer()->dispatch();
|
||||
}
|
||||
if (e->type() == QEvent::Show) {
|
||||
// on QtWayland windows with X11BypassWindowManagerHint are not shown, thus we need to remove it
|
||||
// as the flag is interpreted only before the PlatformWindow is created we need to destroy the window first
|
||||
if (w->flags() & Qt::X11BypassWindowManagerHint) {
|
||||
w->setFlags(w->flags() & ~Qt::X11BypassWindowManagerHint);
|
||||
w->destroy();
|
||||
w->show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Application::notify(o, e);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue