diff --git a/src/wayland/wlr_layershell.cpp b/src/wayland/wlr_layershell.cpp index 1ce7b7fc..9b4f32f2 100644 --- a/src/wayland/wlr_layershell.cpp +++ b/src/wayland/wlr_layershell.cpp @@ -18,7 +18,7 @@ WlrLayershell::WlrLayershell(QObject* parent) : ProxyWindowBase(parent) , ext(new LayershellWindowExtension(this)) {} -QQuickWindow* WlrLayershell::retrieveWindow(QObject* oldInstance) { +ProxiedWindow* WlrLayershell::retrieveWindow(QObject* oldInstance) { auto* old = qobject_cast(oldInstance); auto* window = old == nullptr ? nullptr : old->disownWindow(); @@ -33,8 +33,8 @@ QQuickWindow* WlrLayershell::retrieveWindow(QObject* oldInstance) { return this->createQQuickWindow(); } -QQuickWindow* WlrLayershell::createQQuickWindow() { - auto* window = new QQuickWindow(); +ProxiedWindow* WlrLayershell::createQQuickWindow() { + auto* window = this->ProxyWindowBase::createQQuickWindow(); if (!this->ext->attach(window)) { qWarning() << "Could not attach Layershell extension to new QQuickWindow. Layer will not " diff --git a/src/wayland/wlr_layershell.hpp b/src/wayland/wlr_layershell.hpp index e7a1a077..f6f6988a 100644 --- a/src/wayland/wlr_layershell.hpp +++ b/src/wayland/wlr_layershell.hpp @@ -64,8 +64,8 @@ class WlrLayershell: public ProxyWindowBase { public: explicit WlrLayershell(QObject* parent = nullptr); - QQuickWindow* retrieveWindow(QObject* oldInstance) override; - QQuickWindow* createQQuickWindow() override; + ProxiedWindow* retrieveWindow(QObject* oldInstance) override; + ProxiedWindow* createQQuickWindow() override; void connectWindow() override; [[nodiscard]] bool deleteOnInvisible() const override; diff --git a/src/window/proxywindow.cpp b/src/window/proxywindow.cpp index 426b4057..2a1f51d9 100644 --- a/src/window/proxywindow.cpp +++ b/src/window/proxywindow.cpp @@ -1,6 +1,7 @@ #include "proxywindow.hpp" #include +#include #include #include #include @@ -80,7 +81,7 @@ void ProxyWindowBase::onReload(QObject* oldInstance) { void ProxyWindowBase::postCompleteWindow() { this->setVisible(this->mVisible); } -QQuickWindow* ProxyWindowBase::createQQuickWindow() { return new QQuickWindow(); } +ProxiedWindow* ProxyWindowBase::createQQuickWindow() { return new ProxiedWindow(); } void ProxyWindowBase::createWindow() { if (this->window != nullptr) return; @@ -102,7 +103,7 @@ void ProxyWindowBase::deleteWindow(bool keepItemOwnership) { } } -QQuickWindow* ProxyWindowBase::disownWindow(bool keepItemOwnership) { +ProxiedWindow* ProxyWindowBase::disownWindow(bool keepItemOwnership) { if (this->window == nullptr) return nullptr; QObject::disconnect(this->window, nullptr, this, nullptr); @@ -116,7 +117,7 @@ QQuickWindow* ProxyWindowBase::disownWindow(bool keepItemOwnership) { return window; } -QQuickWindow* ProxyWindowBase::retrieveWindow(QObject* oldInstance) { +ProxiedWindow* ProxyWindowBase::retrieveWindow(QObject* oldInstance) { auto* old = qobject_cast(oldInstance); return old == nullptr ? nullptr : old->disownWindow(); } @@ -136,6 +137,7 @@ void ProxyWindowBase::connectWindow() { QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyWindowBase::heightChanged); QObject::connect(this->window, &QWindow::screenChanged, this, &ProxyWindowBase::screenChanged); QObject::connect(this->window, &QQuickWindow::colorChanged, this, &ProxyWindowBase::colorChanged); + QObject::connect(this->window, &ProxiedWindow::exposed, this, &ProxyWindowBase::onWindowExposeEvent); // clang-format on } @@ -215,7 +217,9 @@ void ProxyWindowBase::polishItems() { // This hack manually polishes the item tree right before showing the window so it will // always be created with the correct size. QQuickWindowPrivate::get(this->window)->polishItems(); +} +void ProxyWindowBase::onWindowExposeEvent() { if (!this->ranLints) { qs::debug::lintItemTree(this->mContentItem); this->ranLints = true; @@ -368,3 +372,8 @@ void ProxyWindowBase::onHeightChanged() { this->mContentItem->setHeight(this->he QObject* ProxyWindowAttached::window() const { return this->mWindow; } QQuickItem* ProxyWindowAttached::contentItem() const { return this->mWindow->contentItem(); } + +void ProxiedWindow::exposeEvent(QExposeEvent* event) { + this->QQuickWindow::exposeEvent(event); + emit this->exposed(); +} diff --git a/src/window/proxywindow.hpp b/src/window/proxywindow.hpp index 8ab8bfd0..769dad03 100644 --- a/src/window/proxywindow.hpp +++ b/src/window/proxywindow.hpp @@ -11,12 +11,15 @@ #include #include #include +#include #include "../core/qmlscreen.hpp" #include "../core/region.hpp" #include "../core/reload.hpp" #include "windowinterface.hpp" +class ProxiedWindow; + // Proxy to an actual window exposing a limited property set with the ability to // transfer it to a new window. @@ -60,10 +63,10 @@ public: void deleteWindow(bool keepItemOwnership = false); // Disown the backing window and delete all its children. - virtual QQuickWindow* disownWindow(bool keepItemOwnership = false); + virtual ProxiedWindow* disownWindow(bool keepItemOwnership = false); - virtual QQuickWindow* retrieveWindow(QObject* oldInstance); - virtual QQuickWindow* createQQuickWindow(); + virtual ProxiedWindow* retrieveWindow(QObject* oldInstance); + virtual ProxiedWindow* createQQuickWindow(); virtual void connectWindow(); virtual void completeWindow(); virtual void postCompleteWindow(); @@ -119,6 +122,7 @@ protected slots: void onMaskChanged(); void onMaskDestroyed(); void onScreenDestroyed(); + void onWindowExposeEvent(); protected: bool mVisible = true; @@ -127,7 +131,7 @@ protected: QScreen* mScreen = nullptr; QColor mColor = Qt::white; PendingRegion* mMask = nullptr; - QQuickWindow* window = nullptr; + ProxiedWindow* window = nullptr; QQuickItem* mContentItem = nullptr; bool reloadComplete = false; bool ranLints = false; @@ -151,3 +155,16 @@ public: private: ProxyWindowBase* mWindow; }; + +class ProxiedWindow: public QQuickWindow { + Q_OBJECT; + +public: + explicit ProxiedWindow(QWindow* parent = nullptr): QQuickWindow(parent) {} + +signals: + void exposed(); + +protected: + void exposeEvent(QExposeEvent* event) override; +};