Adapt window recreation to wl_surface as winId and lifetime changes
Returning wl_surface as winId broke widget windows after reconnect. When fetching globals from the new connection new screens are added, this results in QWidget being notified of a screen change. It then refreshes its cached winId which at this point in time will be 0 since the window does not have a new window yet. Then when a widget repainting the backing store will never be flushed because it doesnt find a native parent anymore by going up the parent chain and looking for a widget with non-null winId. Fix this by recreating the wl_surface after fetching the globals but before the initital roundtrip. While at it dont recreate role objects for windows that dont need them. With the changes that also now hidden windows have wl_surfaces we would recreate them along with closed popups. Change-Id: Ib7ed27d1f25df84c85cce4802726178586c19d55 Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
parent
9aa5f633d4
commit
2753bf6b6b
@ -455,18 +455,21 @@ void QWaylandDisplay::reconnect()
|
||||
mActiveWindows.clear();
|
||||
|
||||
const auto windows = QGuiApplication::allWindows();
|
||||
QList<QWaylandWindow *> allPlatformWindows;
|
||||
for (auto window : windows) {
|
||||
if (auto waylandWindow = static_cast<QWaylandWindow *>(window->handle()))
|
||||
if (auto waylandWindow = static_cast<QWaylandWindow *>(window->handle())) {
|
||||
waylandWindow->closeChildPopups();
|
||||
allPlatformWindows.push_back(waylandWindow);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove windows that do not need to be recreated and now closed popups
|
||||
QList<QWaylandWindow *> recreateWindows;
|
||||
for (auto window : std::as_const(windows)) {
|
||||
auto waylandWindow = static_cast<QWaylandWindow*>(window->handle());
|
||||
if (waylandWindow && waylandWindow->wlSurface()) {
|
||||
waylandWindow->reset();
|
||||
recreateWindows.push_back(waylandWindow);
|
||||
for (auto window : std::as_const(allPlatformWindows)) {
|
||||
if (window->subSurfaceWindow() || window->shellSurface()) {
|
||||
recreateWindows.push_back(window);
|
||||
}
|
||||
window->reset();
|
||||
}
|
||||
|
||||
if (mSyncCallback) {
|
||||
@ -480,6 +483,15 @@ void QWaylandDisplay::reconnect()
|
||||
if (!mDisplay)
|
||||
_exit(1);
|
||||
|
||||
connect(
|
||||
this, &QWaylandDisplay::connected, this,
|
||||
[&allPlatformWindows] {
|
||||
for (auto &window : std::as_const(allPlatformWindows)) {
|
||||
window->initializeWlSurface();
|
||||
}
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
|
||||
setupConnection();
|
||||
initialize();
|
||||
|
||||
@ -488,7 +500,8 @@ void QWaylandDisplay::reconnect()
|
||||
initEventThread();
|
||||
|
||||
auto needsRecreate = [](QPlatformWindow *window) {
|
||||
return window && !static_cast<QWaylandWindow *>(window)->wlSurface();
|
||||
auto waylandWindow = static_cast<QWaylandWindow *>(window);
|
||||
return waylandWindow && !waylandWindow->subSurfaceWindow() && !waylandWindow->shellSurface();
|
||||
};
|
||||
auto window = recreateWindows.begin();
|
||||
while (!recreateWindows.isEmpty()) {
|
||||
|
@ -1803,7 +1803,6 @@ void QWaylandWindow::closeChildPopups() {
|
||||
|
||||
void QWaylandWindow::reinit()
|
||||
{
|
||||
initializeWlSurface();
|
||||
if (window()->isVisible()) {
|
||||
initWindow();
|
||||
if (hasPendingUpdateRequest())
|
||||
|
@ -239,6 +239,7 @@ public:
|
||||
|
||||
virtual void reinit();
|
||||
void reset();
|
||||
void initializeWlSurface();
|
||||
|
||||
bool windowEvent(QEvent *event) override;
|
||||
|
||||
@ -340,7 +341,6 @@ protected:
|
||||
private:
|
||||
void setGeometry_helper(const QRect &rect);
|
||||
void initWindow();
|
||||
void initializeWlSurface();
|
||||
bool shouldCreateShellSurface() const;
|
||||
bool shouldCreateSubSurface() const;
|
||||
void resetSurfaceRole();
|
||||
|
Loading…
x
Reference in New Issue
Block a user