core/window: add QsWindow attached object to contained Items

This commit is contained in:
outfoxxed 2024-07-17 20:54:29 -07:00
parent d1c33d48cd
commit e48af44607
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
4 changed files with 75 additions and 1 deletions

View file

@ -11,6 +11,7 @@
#include <qregion.h> #include <qregion.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <qtypes.h> #include <qtypes.h>
#include <qvariant.h>
#include <qwindow.h> #include <qwindow.h>
#include "generation.hpp" #include "generation.hpp"
@ -123,6 +124,8 @@ void ProxyWindowBase::connectWindow() {
generation->registerIncubationController(this->window->incubationController()); generation->registerIncubationController(this->window->incubationController());
} }
this->window->setProperty("__qs_proxywindow", QVariant::fromValue(this));
// clang-format off // clang-format off
QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged); QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged);
QObject::connect(this->window, &QWindow::xChanged, this, &ProxyWindowBase::xChanged); QObject::connect(this->window, &QWindow::xChanged, this, &ProxyWindowBase::xChanged);
@ -344,3 +347,6 @@ QQmlListProperty<QObject> ProxyWindowBase::data() {
void ProxyWindowBase::onWidthChanged() { this->mContentItem->setWidth(this->width()); } void ProxyWindowBase::onWidthChanged() { this->mContentItem->setWidth(this->width()); }
void ProxyWindowBase::onHeightChanged() { this->mContentItem->setHeight(this->height()); } void ProxyWindowBase::onHeightChanged() { this->mContentItem->setHeight(this->height()); }
QObject* ProxyWindowAttached::window() const { return this->mWindow; }
QQuickItem* ProxyWindowAttached::contentItem() const { return this->mWindow->contentItem(); }

View file

@ -136,3 +136,18 @@ private:
void polishItems(); void polishItems();
void updateMask(); 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;
};

View file

@ -1 +1,29 @@
#include "windowinterface.hpp" // NOLINT #include "windowinterface.hpp"
#include <qobject.h>
#include <qquickitem.h>
#include <qvariant.h>
#include "proxywindow.hpp"
QsWindowAttached* WindowInterface::qmlAttachedProperties(QObject* object) {
auto* item = qobject_cast<QQuickItem*>(object);
if (!item) return nullptr;
auto* window = item->window();
if (!window) return nullptr;
auto* proxy = window->property("__qs_proxywindow").value<ProxyWindowBase*>();
if (!proxy) return nullptr;
auto v = proxy->property("__qs_window_attached");
if (auto* attached = v.value<QsWindowAttached*>()) {
return attached;
}
auto* attached = new ProxyWindowAttached(proxy);
if (attached) {
proxy->setProperty("__qs_window_attached", QVariant::fromValue(attached));
}
return attached;
}

View file

@ -13,7 +13,15 @@
#include "reload.hpp" #include "reload.hpp"
class ProxyWindowBase; 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 { class WindowInterface: public Reloadable {
Q_OBJECT; Q_OBJECT;
// clang-format off // clang-format off
@ -101,6 +109,7 @@ class WindowInterface: public Reloadable {
Q_CLASSINFO("DefaultProperty", "data"); Q_CLASSINFO("DefaultProperty", "data");
QML_NAMED_ELEMENT(QSWindow); QML_NAMED_ELEMENT(QSWindow);
QML_UNCREATABLE("uncreatable base class"); QML_UNCREATABLE("uncreatable base class");
QML_ATTACHED(QsWindowAttached);
public: public:
explicit WindowInterface(QObject* parent = nullptr): Reloadable(parent) {} explicit WindowInterface(QObject* parent = nullptr): Reloadable(parent) {}
@ -131,6 +140,8 @@ public:
[[nodiscard]] virtual QQmlListProperty<QObject> data() = 0; [[nodiscard]] virtual QQmlListProperty<QObject> data() = 0;
static QsWindowAttached* qmlAttachedProperties(QObject* object);
signals: signals:
void windowConnected(); void windowConnected();
void visibleChanged(); void visibleChanged();
@ -142,3 +153,17 @@ signals:
void colorChanged(); void colorChanged();
void maskChanged(); 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) {}
};