From 13c5d7c7a9e0b3eccc769caede634661f5ad6261 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 25 Feb 2024 16:13:24 -0800 Subject: [PATCH] fix(wayland): layershell windows are recreated if attach fails Usually this happens if the namespace changes --- src/core/proxywindow.cpp | 19 +++++++++++-------- src/core/proxywindow.hpp | 1 + src/wayland/CMakeLists.txt | 1 - src/wayland/waylandlayershell.cpp | 30 ++++++++++++++++++++++++++---- src/wayland/waylandlayershell.hpp | 3 +++ 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/core/proxywindow.cpp b/src/core/proxywindow.cpp index af360fa8..b8dc617a 100644 --- a/src/core/proxywindow.cpp +++ b/src/core/proxywindow.cpp @@ -28,14 +28,7 @@ ProxyWindowBase::~ProxyWindowBase() { } void ProxyWindowBase::onReload(QObject* oldInstance) { - auto* old = qobject_cast(oldInstance); - - if (old == nullptr || old->window == nullptr) { - this->window = new QQuickWindow(); - } else { - this->window = old->disownWindow(); - } - + this->window = this->createWindow(oldInstance); this->setupWindow(); Reloadable::reloadRecursive(this->mContentItem, oldInstance); @@ -52,6 +45,16 @@ void ProxyWindowBase::onReload(QObject* oldInstance) { this->window->setVisible(this->mVisible); } +QQuickWindow* ProxyWindowBase::createWindow(QObject* oldInstance) { + auto* old = qobject_cast(oldInstance); + + if (old == nullptr || old->window == nullptr) { + return new QQuickWindow(); + } else { + return old->disownWindow(); + } +} + void ProxyWindowBase::setupWindow() { // clang-format off QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged); diff --git a/src/core/proxywindow.hpp b/src/core/proxywindow.hpp index 4abd675e..c6d81a9c 100644 --- a/src/core/proxywindow.hpp +++ b/src/core/proxywindow.hpp @@ -55,6 +55,7 @@ public: void onReload(QObject* oldInstance) override; + virtual QQuickWindow* createWindow(QObject* oldInstance); virtual void setupWindow(); // Disown the backing window and delete all its children. diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 8d95ac71..89cac236 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -13,7 +13,6 @@ pkg_check_modules(wayland REQUIRED IMPORTED_TARGET wayland-client wayland-protoc find_package(Qt6 REQUIRED COMPONENTS WaylandClient) target_link_libraries(quickshell-wayland PRIVATE ${QT_DEPS} wayland-client) -message(STATUS Qt6::WaylandClient) # wayland protocols diff --git a/src/wayland/waylandlayershell.cpp b/src/wayland/waylandlayershell.cpp index 7fa52066..ef4c317c 100644 --- a/src/wayland/waylandlayershell.cpp +++ b/src/wayland/waylandlayershell.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,31 @@ WaylandLayershell::WaylandLayershell(QObject* parent) : ProxyWindowBase(parent) , ext(new LayershellWindowExtension(this)) {} +QQuickWindow* WaylandLayershell::createWindow(QObject* oldInstance) { + auto* old = qobject_cast(oldInstance); + QQuickWindow* window = nullptr; + + if (old == nullptr || old->window == nullptr) { + window = new QQuickWindow(); + } else { + window = old->disownWindow(); + + if (this->ext->attach(window)) { + return window; + } else { + window->deleteLater(); + window = new QQuickWindow(); + } + } + + if (!this->ext->attach(window)) { + qWarning() << "Could not attach Layershell extension to new QQUickWindow. Layer will not " + "behave correctly."; + } + + return window; +} + void WaylandLayershell::setupWindow() { this->ProxyWindowBase::setupWindow(); @@ -32,10 +58,6 @@ void WaylandLayershell::setupWindow() { QObject::connect(this, &WaylandLayershell::anchorsChanged, this, &WaylandLayershell::updateAutoExclusion); QObject::connect(this, &WaylandLayershell::marginsChanged, this, &WaylandLayershell::updateAutoExclusion); // clang-format on - - if (!this->ext->attach(this->window)) { - // todo: discard window - } } void WaylandLayershell::setWidth(qint32 width) { diff --git a/src/wayland/waylandlayershell.hpp b/src/wayland/waylandlayershell.hpp index 9c5ad144..e33992b1 100644 --- a/src/wayland/waylandlayershell.hpp +++ b/src/wayland/waylandlayershell.hpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include @@ -30,6 +32,7 @@ class WaylandLayershell: public ProxyWindowBase { public: explicit WaylandLayershell(QObject* parent = nullptr); + QQuickWindow* createWindow(QObject* oldInstance) override; void setupWindow() override; void setWidth(qint32 width) override;