From 055b191a670e0c38ed3f387de8d2641bd28734a4 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Wed, 27 Mar 2024 01:37:45 -0700 Subject: [PATCH] core/window: add windowTransform and backingWindowVisible properties --- src/core/floatingwindow.cpp | 5 +++++ src/core/floatingwindow.hpp | 1 + src/core/proxywindow.cpp | 11 +++++++++-- src/core/proxywindow.hpp | 4 ++++ src/core/windowinterface.hpp | 18 +++++++++++++++++- src/wayland/wlr_layershell.cpp | 5 +++++ src/wayland/wlr_layershell.hpp | 1 + 7 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/core/floatingwindow.cpp b/src/core/floatingwindow.cpp index 4503440..1a6eb6b 100644 --- a/src/core/floatingwindow.cpp +++ b/src/core/floatingwindow.cpp @@ -29,9 +29,11 @@ FloatingWindowInterface::FloatingWindowInterface(QObject* parent) // clang-format off QObject::connect(this->window, &ProxyWindowBase::windowConnected, this, &FloatingWindowInterface::windowConnected); QObject::connect(this->window, &ProxyWindowBase::visibleChanged, this, &FloatingWindowInterface::visibleChanged); + QObject::connect(this->window, &ProxyWindowBase::backerVisibilityChanged, this, &FloatingWindowInterface::backingWindowVisibleChanged); QObject::connect(this->window, &ProxyWindowBase::heightChanged, this, &FloatingWindowInterface::heightChanged); QObject::connect(this->window, &ProxyWindowBase::widthChanged, this, &FloatingWindowInterface::widthChanged); QObject::connect(this->window, &ProxyWindowBase::screenChanged, this, &FloatingWindowInterface::screenChanged); + QObject::connect(this->window, &ProxyWindowBase::windowTransformChanged, this, &FloatingWindowInterface::windowTransformChanged); QObject::connect(this->window, &ProxyWindowBase::colorChanged, this, &FloatingWindowInterface::colorChanged); QObject::connect(this->window, &ProxyWindowBase::maskChanged, this, &FloatingWindowInterface::maskChanged); // clang-format on @@ -47,6 +49,9 @@ void FloatingWindowInterface::onReload(QObject* oldInstance) { QQmlListProperty FloatingWindowInterface::data() { return this->window->data(); } ProxyWindowBase* FloatingWindowInterface::proxyWindow() const { return this->window; } QQuickItem* FloatingWindowInterface::contentItem() const { return this->window->contentItem(); } +bool FloatingWindowInterface::isBackingWindowVisible() const { + return this->window->isVisibleDirect(); +} // NOLINTBEGIN #define proxyPair(type, get, set) \ diff --git a/src/core/floatingwindow.hpp b/src/core/floatingwindow.hpp index 5f03277..93b5723 100644 --- a/src/core/floatingwindow.hpp +++ b/src/core/floatingwindow.hpp @@ -32,6 +32,7 @@ public: // NOLINTBEGIN [[nodiscard]] bool isVisible() const override; + [[nodiscard]] bool isBackingWindowVisible() const override; void setVisible(bool visible) override; [[nodiscard]] qint32 width() const override; diff --git a/src/core/proxywindow.cpp b/src/core/proxywindow.cpp index 06ee9ec..bc15c58 100644 --- a/src/core/proxywindow.cpp +++ b/src/core/proxywindow.cpp @@ -30,6 +30,12 @@ ProxyWindowBase::ProxyWindowBase(QObject* parent) QObject::connect(this, &ProxyWindowBase::maskChanged, this, &ProxyWindowBase::onMaskChanged); QObject::connect(this, &ProxyWindowBase::widthChanged, this, &ProxyWindowBase::onMaskChanged); QObject::connect(this, &ProxyWindowBase::heightChanged, this, &ProxyWindowBase::onMaskChanged); + + QObject::connect(this, &ProxyWindowBase::xChanged, this, &ProxyWindowBase::windowTransformChanged); + QObject::connect(this, &ProxyWindowBase::yChanged, this, &ProxyWindowBase::windowTransformChanged); + QObject::connect(this, &ProxyWindowBase::widthChanged, this, &ProxyWindowBase::windowTransformChanged); + QObject::connect(this, &ProxyWindowBase::heightChanged, this, &ProxyWindowBase::windowTransformChanged); + QObject::connect(this, &ProxyWindowBase::backerVisibilityChanged, this, &ProxyWindowBase::windowTransformChanged); // clang-format on } @@ -171,14 +177,15 @@ void ProxyWindowBase::setVisibleDirect(bool visible) { emit this->backerVisibilityChanged(); } else { if (this->window != nullptr) { - this->window->setVisible(false); emit this->backerVisibilityChanged(); + this->window->setVisible(false); this->deleteWindow(); } } } else if (this->window != nullptr) { + if (!visible) emit this->backerVisibilityChanged(); this->window->setVisible(visible); - emit this->backerVisibilityChanged(); + if (visible) emit this->backerVisibilityChanged(); } } diff --git a/src/core/proxywindow.hpp b/src/core/proxywindow.hpp index 64314ee..f2c75b6 100644 --- a/src/core/proxywindow.hpp +++ b/src/core/proxywindow.hpp @@ -42,6 +42,8 @@ class ProxyWindowBase: public Reloadable { Q_PROPERTY(QuickshellScreenInfo* screen READ screen WRITE setScreen NOTIFY screenChanged); Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged); Q_PROPERTY(PendingRegion* mask READ mask WRITE setMask NOTIFY maskChanged); + Q_PROPERTY(QObject* windowTransform READ windowTransform NOTIFY windowTransformChanged); + Q_PROPERTY(bool backingWindowVisible READ isVisibleDirect NOTIFY backerVisibilityChanged); Q_PROPERTY(QQmlListProperty data READ data); Q_CLASSINFO("DefaultProperty", "data"); @@ -94,6 +96,8 @@ public: [[nodiscard]] PendingRegion* mask() const; virtual void setMask(PendingRegion* mask); + [[nodiscard]] QObject* windowTransform() const { return nullptr; } // NOLINT + [[nodiscard]] QQmlListProperty data(); signals: diff --git a/src/core/windowinterface.hpp b/src/core/windowinterface.hpp index f32e427..ec50dfd 100644 --- a/src/core/windowinterface.hpp +++ b/src/core/windowinterface.hpp @@ -18,14 +18,25 @@ class WindowInterface: public Reloadable { Q_OBJECT; // clang-format off Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT); - /// If the window is shown or hidden. Defaults to true. + /// If the window should be shown or hidden. Defaults to true. Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged); + /// If the window is currently shown. You should generally prefer [visible](#prop.visible). + /// + /// This property is useful for ensuring windows spawn in a specific order, and you should + /// not use it in place of [visible](#prop.visible). + Q_PROPERTY(bool backingWindowVisible READ isBackingWindowVisible NOTIFY backingWindowVisibleChanged); Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged); Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged); /// The screen that the window currently occupies. /// /// This may be modified to move the window to the given screen. Q_PROPERTY(QuickshellScreenInfo* screen READ screen WRITE setScreen NOTIFY screenChanged); + /// Opaque property that will receive an update when factors that affect the window's position + /// and transform changed. + /// + /// This property is intended to be used to force a binding update, + /// along with map[To|From]Item (which is not reactive). + Q_PROPERTY(QObject* windowTransform READ windowTransform NOTIFY windowTransformChanged); /// The background color of the window. Defaults to white. /// /// > [!WARNING] This seems to behave weirdly when using transparent colors on some systems. @@ -98,6 +109,7 @@ public: [[nodiscard]] virtual QQuickItem* contentItem() const = 0; [[nodiscard]] virtual bool isVisible() const = 0; + [[nodiscard]] virtual bool isBackingWindowVisible() const = 0; virtual void setVisible(bool visible) = 0; [[nodiscard]] virtual qint32 width() const = 0; @@ -109,6 +121,8 @@ public: [[nodiscard]] virtual QuickshellScreenInfo* screen() const = 0; virtual void setScreen(QuickshellScreenInfo* screen) = 0; + [[nodiscard]] QObject* windowTransform() const { return nullptr; } // NOLINT + [[nodiscard]] virtual QColor color() const = 0; virtual void setColor(QColor color) = 0; @@ -120,9 +134,11 @@ public: signals: void windowConnected(); void visibleChanged(); + void backingWindowVisibleChanged(); void widthChanged(); void heightChanged(); void screenChanged(); + void windowTransformChanged(); void colorChanged(); void maskChanged(); }; diff --git a/src/wayland/wlr_layershell.cpp b/src/wayland/wlr_layershell.cpp index 5d7f674..945706f 100644 --- a/src/wayland/wlr_layershell.cpp +++ b/src/wayland/wlr_layershell.cpp @@ -177,9 +177,11 @@ WaylandPanelInterface::WaylandPanelInterface(QObject* parent) // clang-format off QObject::connect(this->layer, &ProxyWindowBase::windowConnected, this, &WaylandPanelInterface::windowConnected); QObject::connect(this->layer, &ProxyWindowBase::visibleChanged, this, &WaylandPanelInterface::visibleChanged); + QObject::connect(this->layer, &ProxyWindowBase::backerVisibilityChanged, this, &WaylandPanelInterface::backingWindowVisibleChanged); QObject::connect(this->layer, &ProxyWindowBase::heightChanged, this, &WaylandPanelInterface::heightChanged); QObject::connect(this->layer, &ProxyWindowBase::widthChanged, this, &WaylandPanelInterface::widthChanged); QObject::connect(this->layer, &ProxyWindowBase::screenChanged, this, &WaylandPanelInterface::screenChanged); + QObject::connect(this->layer, &ProxyWindowBase::windowTransformChanged, this, &WaylandPanelInterface::windowTransformChanged); QObject::connect(this->layer, &ProxyWindowBase::colorChanged, this, &WaylandPanelInterface::colorChanged); QObject::connect(this->layer, &ProxyWindowBase::maskChanged, this, &WaylandPanelInterface::maskChanged); @@ -201,6 +203,9 @@ void WaylandPanelInterface::onReload(QObject* oldInstance) { QQmlListProperty WaylandPanelInterface::data() { return this->layer->data(); } ProxyWindowBase* WaylandPanelInterface::proxyWindow() const { return this->layer; } QQuickItem* WaylandPanelInterface::contentItem() const { return this->layer->contentItem(); } +bool WaylandPanelInterface::isBackingWindowVisible() const { + return this->layer->isVisibleDirect(); +} // NOLINTBEGIN #define proxyPair(type, get, set) \ diff --git a/src/wayland/wlr_layershell.hpp b/src/wayland/wlr_layershell.hpp index b9e733f..4a176bd 100644 --- a/src/wayland/wlr_layershell.hpp +++ b/src/wayland/wlr_layershell.hpp @@ -128,6 +128,7 @@ public: // NOLINTBEGIN [[nodiscard]] bool isVisible() const override; + [[nodiscard]] bool isBackingWindowVisible() const override; void setVisible(bool visible) override; [[nodiscard]] qint32 width() const override;