124 lines
4.9 KiB
Diff
124 lines
4.9 KiB
Diff
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
|
|
index 02169e77..a1f3befe 100644
|
|
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
|
|
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
|
|
@@ -423,8 +423,10 @@ void QWaylandDisplay::reconnect()
|
|
m_eventThread->wait();
|
|
m_frameEventQueueThread->wait();
|
|
|
|
- qDeleteAll(mWaitingScreens);
|
|
- mWaitingScreens.clear();
|
|
+ for (auto *screen : std::exchange(mWaitingScreens, {})) {
|
|
+ forgetScreenForSurfaces(screen);
|
|
+ delete screen;
|
|
+ }
|
|
|
|
while (!mScreens.isEmpty()) {
|
|
auto screen = mScreens.takeLast();
|
|
@@ -603,6 +605,22 @@ QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const
|
|
return nullptr;
|
|
}
|
|
|
|
+void QWaylandDisplay::registerSurface(QWaylandSurface *surface)
|
|
+{
|
|
+ mSurfaces.append(surface);
|
|
+}
|
|
+
|
|
+void QWaylandDisplay::unregisterSurface(QWaylandSurface *surface)
|
|
+{
|
|
+ mSurfaces.removeOne(surface);
|
|
+}
|
|
+
|
|
+void QWaylandDisplay::forgetScreenForSurfaces(QWaylandScreen *screen)
|
|
+{
|
|
+ for (auto *surface : std::as_const(mSurfaces))
|
|
+ surface->m_screens.removeAll(screen);
|
|
+}
|
|
+
|
|
void QWaylandDisplay::handleScreenInitialized(QWaylandScreen *screen)
|
|
{
|
|
if (!mWaitingScreens.removeOne(screen))
|
|
@@ -823,6 +841,7 @@ void QWaylandDisplay::registry_global_remove(uint32_t id)
|
|
for (auto *screen : mWaitingScreens) {
|
|
if (screen->outputId() == id) {
|
|
mWaitingScreens.removeOne(screen);
|
|
+ forgetScreenForSurfaces(screen);
|
|
delete screen;
|
|
break;
|
|
}
|
|
@@ -831,6 +850,7 @@ void QWaylandDisplay::registry_global_remove(uint32_t id)
|
|
for (QWaylandScreen *screen : std::as_const(mScreens)) {
|
|
if (screen->outputId() == id) {
|
|
mScreens.removeOne(screen);
|
|
+ forgetScreenForSurfaces(screen);
|
|
// If this is the last screen, we have to add a fake screen, or Qt will break.
|
|
ensureScreen();
|
|
QWindowSystemInterface::handleScreenRemoved(screen);
|
|
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay_p.h b/src/plugins/platforms/wayland/qwaylanddisplay_p.h
|
|
index 29952886..0baa378f 100644
|
|
--- a/src/plugins/platforms/wayland/qwaylanddisplay_p.h
|
|
+++ b/src/plugins/platforms/wayland/qwaylanddisplay_p.h
|
|
@@ -116,6 +116,9 @@ public:
|
|
QPlatformPlaceholderScreen *placeholderScreen() const { return mPlaceholderScreen; }
|
|
void ensureScreen();
|
|
|
|
+ void registerSurface(QWaylandSurface *surface);
|
|
+ void unregisterSurface(QWaylandSurface *surface);
|
|
+
|
|
QWaylandScreen *screenForOutput(struct wl_output *output) const;
|
|
void handleScreenInitialized(QWaylandScreen *screen);
|
|
|
|
@@ -289,6 +292,7 @@ private:
|
|
void checkWaylandError();
|
|
void reconnect();
|
|
void setupConnection();
|
|
+ void forgetScreenForSurfaces(QWaylandScreen *screen);
|
|
void handleWaylandSync();
|
|
void requestWaylandSync();
|
|
|
|
@@ -311,6 +315,7 @@ private:
|
|
QList<QWaylandScreen *> mScreens;
|
|
QPlatformPlaceholderScreen *mPlaceholderScreen = nullptr;
|
|
QList<QWaylandInputDevice *> mInputDevices;
|
|
+ QList<QWaylandSurface *> mSurfaces;
|
|
QList<Listener> mRegistryListeners;
|
|
QWaylandIntegration *mWaylandIntegration = nullptr;
|
|
#if QT_CONFIG(cursor)
|
|
diff --git a/src/plugins/platforms/wayland/qwaylandsurface.cpp b/src/plugins/platforms/wayland/qwaylandsurface.cpp
|
|
index 274fdda8..b37e9265 100644
|
|
--- a/src/plugins/platforms/wayland/qwaylandsurface.cpp
|
|
+++ b/src/plugins/platforms/wayland/qwaylandsurface.cpp
|
|
@@ -13,13 +13,16 @@ namespace QtWaylandClient {
|
|
|
|
QWaylandSurface::QWaylandSurface(QWaylandDisplay *display)
|
|
: wl_surface(display->createSurface(this))
|
|
+ , m_display(display)
|
|
{
|
|
+ display->registerSurface(this);
|
|
connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandSurface::handleScreenRemoved);
|
|
connect(qApp, &QGuiApplication::screenAdded, this, &QWaylandSurface::screensChanged);
|
|
}
|
|
|
|
QWaylandSurface::~QWaylandSurface()
|
|
{
|
|
+ m_display->unregisterSurface(this);
|
|
destroy();
|
|
}
|
|
|
|
diff --git a/src/plugins/platforms/wayland/qwaylandsurface_p.h b/src/plugins/platforms/wayland/qwaylandsurface_p.h
|
|
index 41860297..ddb63b04 100644
|
|
--- a/src/plugins/platforms/wayland/qwaylandsurface_p.h
|
|
+++ b/src/plugins/platforms/wayland/qwaylandsurface_p.h
|
|
@@ -57,10 +57,12 @@ protected:
|
|
|
|
QList<QWaylandScreen *> m_screens; //As seen by wl_surface.enter/leave events. Chronological order.
|
|
QWaylandWindow *m_window = nullptr;
|
|
+ QWaylandDisplay *m_display = nullptr;
|
|
std::optional<int32_t> m_preferredBufferScale;
|
|
std::optional<wl_output_transform> m_preferredBufferTransform;
|
|
|
|
friend class QWaylandWindow; // TODO: shouldn't need to be friends
|
|
+ friend class QWaylandDisplay;
|
|
};
|
|
|
|
} // namespace QtWaylandClient
|