From e48af446070cf99613a0d0aa5d1ee455bd40b6e9 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Wed, 17 Jul 2024 20:54:29 -0700 Subject: [PATCH] core/window: add QsWindow attached object to contained Items --- src/core/proxywindow.cpp | 6 ++++++ src/core/proxywindow.hpp | 15 +++++++++++++++ src/core/windowinterface.cpp | 30 +++++++++++++++++++++++++++++- src/core/windowinterface.hpp | 25 +++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/core/proxywindow.cpp b/src/core/proxywindow.cpp index fc78f168..8f8ab0dc 100644 --- a/src/core/proxywindow.cpp +++ b/src/core/proxywindow.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "generation.hpp" @@ -123,6 +124,8 @@ void ProxyWindowBase::connectWindow() { generation->registerIncubationController(this->window->incubationController()); } + this->window->setProperty("__qs_proxywindow", QVariant::fromValue(this)); + // clang-format off QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged); QObject::connect(this->window, &QWindow::xChanged, this, &ProxyWindowBase::xChanged); @@ -344,3 +347,6 @@ QQmlListProperty ProxyWindowBase::data() { void ProxyWindowBase::onWidthChanged() { this->mContentItem->setWidth(this->width()); } void ProxyWindowBase::onHeightChanged() { this->mContentItem->setHeight(this->height()); } + +QObject* ProxyWindowAttached::window() const { return this->mWindow; } +QQuickItem* ProxyWindowAttached::contentItem() const { return this->mWindow->contentItem(); } diff --git a/src/core/proxywindow.hpp b/src/core/proxywindow.hpp index 1c62f029..ce8228fe 100644 --- a/src/core/proxywindow.hpp +++ b/src/core/proxywindow.hpp @@ -136,3 +136,18 @@ private: void polishItems(); void updateMask(); }; + +class ProxyWindowAttached: public QsWindowAttached { + Q_OBJECT; + +public: + explicit ProxyWindowAttached(ProxyWindowBase* window) + : QsWindowAttached(window) + , mWindow(window) {} + + [[nodiscard]] QObject* window() const override; + [[nodiscard]] QQuickItem* contentItem() const override; + +private: + ProxyWindowBase* mWindow; +}; diff --git a/src/core/windowinterface.cpp b/src/core/windowinterface.cpp index a29bd599..48f6f2ae 100644 --- a/src/core/windowinterface.cpp +++ b/src/core/windowinterface.cpp @@ -1 +1,29 @@ -#include "windowinterface.hpp" // NOLINT +#include "windowinterface.hpp" + +#include +#include +#include + +#include "proxywindow.hpp" + +QsWindowAttached* WindowInterface::qmlAttachedProperties(QObject* object) { + auto* item = qobject_cast(object); + if (!item) return nullptr; + auto* window = item->window(); + if (!window) return nullptr; + auto* proxy = window->property("__qs_proxywindow").value(); + if (!proxy) return nullptr; + + auto v = proxy->property("__qs_window_attached"); + if (auto* attached = v.value()) { + return attached; + } + + auto* attached = new ProxyWindowAttached(proxy); + + if (attached) { + proxy->setProperty("__qs_window_attached", QVariant::fromValue(attached)); + } + + return attached; +} diff --git a/src/core/windowinterface.hpp b/src/core/windowinterface.hpp index ec50dfd8..ac72a791 100644 --- a/src/core/windowinterface.hpp +++ b/src/core/windowinterface.hpp @@ -13,7 +13,15 @@ #include "reload.hpp" class ProxyWindowBase; +class QsWindowAttached; +///! Base class of Quickshell windows +/// Base class of Quickshell windows +/// ### Attached properties +/// `QSWindow` can be used as an attached object of anything that subclasses @@QtQuick.Item$. +/// It provides the following properties +/// - `window` - the `QSWindow` object. +/// - `contentItem` - the `contentItem` property of the window. class WindowInterface: public Reloadable { Q_OBJECT; // clang-format off @@ -101,6 +109,7 @@ class WindowInterface: public Reloadable { Q_CLASSINFO("DefaultProperty", "data"); QML_NAMED_ELEMENT(QSWindow); QML_UNCREATABLE("uncreatable base class"); + QML_ATTACHED(QsWindowAttached); public: explicit WindowInterface(QObject* parent = nullptr): Reloadable(parent) {} @@ -131,6 +140,8 @@ public: [[nodiscard]] virtual QQmlListProperty data() = 0; + static QsWindowAttached* qmlAttachedProperties(QObject* object); + signals: void windowConnected(); void visibleChanged(); @@ -142,3 +153,17 @@ signals: void colorChanged(); void maskChanged(); }; + +class QsWindowAttached: public QObject { + Q_OBJECT; + Q_PROPERTY(QObject* window READ window CONSTANT); + Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT); + QML_ANONYMOUS; + +public: + [[nodiscard]] virtual QObject* window() const = 0; + [[nodiscard]] virtual QQuickItem* contentItem() const = 0; + +protected: + explicit QsWindowAttached(QObject* parent): QObject(parent) {} +};