diff --git a/src/wayland/wlr_layershell/surface.cpp b/src/wayland/wlr_layershell/surface.cpp index 8349dbfc..c690c0a1 100644 --- a/src/wayland/wlr_layershell/surface.cpp +++ b/src/wayland/wlr_layershell/surface.cpp @@ -173,7 +173,10 @@ LayerSurface::LayerSurface(LayerShellIntegration* shell, QtWaylandClient::QWayla this->bridge->surface = this; } -LayerSurface::~LayerSurface() { this->destroy(); } +LayerSurface::~LayerSurface() { + delete this->bridge; + this->destroy(); +} void LayerSurface::zwlr_layer_surface_v1_configure(quint32 serial, quint32 width, quint32 height) { this->ack_configure(serial); diff --git a/src/wayland/wlr_layershell/wlr_layershell.cpp b/src/wayland/wlr_layershell/wlr_layershell.cpp index 2c80c029..4bb8a3fe 100644 --- a/src/wayland/wlr_layershell/wlr_layershell.cpp +++ b/src/wayland/wlr_layershell/wlr_layershell.cpp @@ -34,7 +34,8 @@ ProxiedWindow* WlrLayershell::retrieveWindow(QObject* oldInstance) { auto* window = old == nullptr ? nullptr : old->disownWindow(); if (window != nullptr) { - this->bridge = LayerSurfaceBridge::init(window, this->computeState()); + this->connectBridge(LayerSurfaceBridge::init(window, this->computeState())); + if (this->bridge) { return window; } else { @@ -48,7 +49,7 @@ ProxiedWindow* WlrLayershell::retrieveWindow(QObject* oldInstance) { ProxiedWindow* WlrLayershell::createQQuickWindow() { auto* window = this->ProxyWindowBase::createQQuickWindow(); - this->bridge = LayerSurfaceBridge::init(window, this->computeState()); + this->connectBridge(LayerSurfaceBridge::init(window, this->computeState())); if (!this->bridge) { qWarning() << "Could not attach Layershell extension to new QQuickWindow. Layer will not " "behave correctly."; @@ -72,6 +73,30 @@ void WlrLayershell::connectWindow() { this->updateAutoExclusion(); } +ProxiedWindow* WlrLayershell::disownWindow(bool keepItemOwnership) { + auto* window = this->ProxyWindowBase::disownWindow(keepItemOwnership); + + if (this->bridge) { + this->connectBridge(nullptr); + } + + return window; +} + +void WlrLayershell::connectBridge(LayerSurfaceBridge* bridge) { + if (this->bridge) { + QObject::disconnect(this->bridge, nullptr, this, nullptr); + } + + this->bridge = bridge; + + if (bridge) { + QObject::connect(this->bridge, &QObject::destroyed, this, &WlrLayershell::onBridgeDestroyed); + } +} + +void WlrLayershell::onBridgeDestroyed() { this->bridge = nullptr; } + bool WlrLayershell::deleteOnInvisible() const { // Qt windows behave weirdly when geometry is modified and setVisible(false) // is subsequently called in the same frame. diff --git a/src/wayland/wlr_layershell/wlr_layershell.hpp b/src/wayland/wlr_layershell/wlr_layershell.hpp index 56dd0605..739f5ff2 100644 --- a/src/wayland/wlr_layershell/wlr_layershell.hpp +++ b/src/wayland/wlr_layershell/wlr_layershell.hpp @@ -122,6 +122,7 @@ public: ProxiedWindow* retrieveWindow(QObject* oldInstance) override; ProxiedWindow* createQQuickWindow() override; void connectWindow() override; + ProxiedWindow* disownWindow(bool keepItemOwnership = false) override; [[nodiscard]] bool deleteOnInvisible() const override; void onPolished() override; @@ -175,10 +176,12 @@ signals: private slots: void updateAutoExclusion(); + void onBridgeDestroyed(); private: [[nodiscard]] LayerSurfaceState computeState() const; + void connectBridge(LayerSurfaceBridge* bridge); void onStateChanged(); bool compositorPicksScreen = true;