summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Griebl <robert.griebl@qt.io>2023-09-25 21:44:43 +0200
committerRobert Griebl <robert.griebl@qt.io>2023-11-06 15:17:37 +0100
commitca4215d582b87686cf9aafe0f51c9c98db96bb8c (patch)
treeffb61926782f1cd9447cac06265d1dcb26593c7a
parent25e73aae0935c87e69d89371d2018f8bbfa1e3f6 (diff)
Add an ApplicationManagerWindow attached object
This makes it easier to always reach your AMW instance, especially now in multi-process mode, where Window.window will NOT be the AMW anymore. The attached object is modelled after the Window attached one, so activeFocusItem was added to both AMW and AMWAttached. Also fixed the most obvious of the non-implemented in-process AMW properties. This needs a follow-up commit to completely fix that though. Change-Id: Icac9bfb2994ca6250f0056e142bd59c8ef4b469a Task-number: QTBUG-103266 Reviewed-by: Bernd Weimer <bernd.weimer@qt.io>
-rw-r--r--qmltypes/QtApplicationManager/Application/plugins.qmltypes4
-rw-r--r--src/application-main-lib/applicationmain.cpp4
-rw-r--r--src/application-main-lib/waylandapplicationmanagerwindowimpl.cpp40
-rw-r--r--src/application-main-lib/waylandapplicationmanagerwindowimpl.h11
-rw-r--r--src/manager-lib/inprocesssurfaceitem.cpp11
-rw-r--r--src/manager-lib/inprocesssurfaceitem.h8
-rw-r--r--src/manager-lib/qmlinprocapplicationmanagerwindowimpl.cpp143
-rw-r--r--src/manager-lib/qmlinprocapplicationmanagerwindowimpl.h40
-rw-r--r--src/shared-main-lib/applicationmanagerwindow.cpp89
-rw-r--r--src/shared-main-lib/applicationmanagerwindow.h58
-rw-r--r--src/shared-main-lib/applicationmanagerwindowimpl.cpp40
-rw-r--r--src/shared-main-lib/applicationmanagerwindowimpl.h32
-rw-r--r--src/window-lib/windowmanager.cpp4
13 files changed, 457 insertions, 27 deletions
diff --git a/qmltypes/QtApplicationManager/Application/plugins.qmltypes b/qmltypes/QtApplicationManager/Application/plugins.qmltypes
index 452854c1..3c4af941 100644
--- a/qmltypes/QtApplicationManager/Application/plugins.qmltypes
+++ b/qmltypes/QtApplicationManager/Application/plugins.qmltypes
@@ -36,6 +36,7 @@ Module {
Property { name: "visible"; type: "bool"; isFinal: true }
Property { name: "active"; type: "bool"; isReadonly: true; isFinal: true }
Property { name: "opacity"; type: "double"; isFinal: true }
+ Property { name: "activeFocusItem"; type: "QQuickItem"; isPointer: true; isReadonly: true; isFinal: true }
Property { name: "data"; type: "QQmlListProperty<QObject>"; isReadonly: true; isFinal: true }
Signal {
name: "dataChanged"
@@ -80,6 +81,9 @@ Module {
name: "activeChanged"
}
Signal {
+ name: "activeFocusItemChanged"
+ }
+ Signal {
name: "windowPropertyChanged"
Parameter { name: "name"; type: "QString" }
Parameter { name: "value"; type: "QVariant" }
diff --git a/src/application-main-lib/applicationmain.cpp b/src/application-main-lib/applicationmain.cpp
index 32907aa0..a5d6beff 100644
--- a/src/application-main-lib/applicationmain.cpp
+++ b/src/application-main-lib/applicationmain.cpp
@@ -53,6 +53,10 @@ ApplicationMain::ApplicationMain(int &argc, char **argv) noexcept
WaylandApplicationManagerWindowImpl::setFactory([this](ApplicationManagerWindow *window) {
return new WaylandApplicationManagerWindowImpl(window, this);
});
+ WaylandApplicationManagerWindowAttachedImpl::setFactory([](ApplicationManagerWindowAttached *windowAttached,
+ QQuickItem *attacheeItem) {
+ return new WaylandApplicationManagerWindowAttachedImpl(windowAttached, attacheeItem);
+ });
}
ApplicationMain::~ApplicationMain()
diff --git a/src/application-main-lib/waylandapplicationmanagerwindowimpl.cpp b/src/application-main-lib/waylandapplicationmanagerwindowimpl.cpp
index 1d26432b..c1510062 100644
--- a/src/application-main-lib/waylandapplicationmanagerwindowimpl.cpp
+++ b/src/application-main-lib/waylandapplicationmanagerwindowimpl.cpp
@@ -24,18 +24,21 @@ class AMQuickWindowQmlImpl : public QQuickWindowQmlImpl
{
Q_OBJECT
public:
- AMQuickWindowQmlImpl(QWindow *parent)
- : QQuickWindowQmlImpl(parent)
+ AMQuickWindowQmlImpl(ApplicationManagerWindow *amwindow)
+ : QQuickWindowQmlImpl(nullptr)
+ , m_amwindow(amwindow)
{ }
using QQuickWindowQmlImpl::classBegin;
using QQuickWindowQmlImpl::componentComplete;
+
+ ApplicationManagerWindow *m_amwindow;
};
WaylandApplicationManagerWindowImpl::WaylandApplicationManagerWindowImpl(ApplicationManagerWindow *window,
ApplicationMain *applicationMain)
: ApplicationManagerWindowImpl(window)
, m_applicationMain(applicationMain)
- , m_qwindow(new AMQuickWindowQmlImpl(nullptr))
+ , m_qwindow(new AMQuickWindowQmlImpl(window))
{
QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::windowTitleChanged,
window, &ApplicationManagerWindow::titleChanged);
@@ -63,6 +66,8 @@ WaylandApplicationManagerWindowImpl::WaylandApplicationManagerWindowImpl(Applica
window, &ApplicationManagerWindow::colorChanged);
QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::activeChanged,
window, &ApplicationManagerWindow::activeChanged);
+ QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::activeFocusItemChanged,
+ window, &ApplicationManagerWindow::activeFocusItemChanged);
}
WaylandApplicationManagerWindowImpl::~WaylandApplicationManagerWindowImpl()
@@ -296,6 +301,35 @@ bool WaylandApplicationManagerWindowImpl::isActive() const
return m_qwindow->isActive();
}
+QQuickItem *WaylandApplicationManagerWindowImpl::activeFocusItem() const
+{
+ return m_qwindow->activeFocusItem();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// WaylandApplicationManagerWindowAttachedImpl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+WaylandApplicationManagerWindowAttachedImpl::WaylandApplicationManagerWindowAttachedImpl(ApplicationManagerWindowAttached *windowAttached, QQuickItem *attacheeItem)
+ : ApplicationManagerWindowAttachedImpl(windowAttached, attacheeItem)
+{ }
+
+ApplicationManagerWindow *WaylandApplicationManagerWindowAttachedImpl::findApplicationManagerWindow()
+{
+ if (!attacheeItem())
+ return nullptr;
+
+ QObject::connect(attacheeItem(), &QQuickItem::windowChanged,
+ amWindowAttached(), [this](QQuickWindow *newWin) {
+ auto *quickWindow = qobject_cast<AMQuickWindowQmlImpl *>(newWin);
+ onWindowChanged(quickWindow ? quickWindow->m_amwindow : nullptr);
+ });
+ auto *quickWindow = qobject_cast<AMQuickWindowQmlImpl *>(attacheeItem()->window());
+ return quickWindow ? quickWindow->m_amwindow : nullptr;
+}
+
QT_END_NAMESPACE_AM
#include "waylandapplicationmanagerwindowimpl.moc"
diff --git a/src/application-main-lib/waylandapplicationmanagerwindowimpl.h b/src/application-main-lib/waylandapplicationmanagerwindowimpl.h
index d41e868a..3bcbddc5 100644
--- a/src/application-main-lib/waylandapplicationmanagerwindowimpl.h
+++ b/src/application-main-lib/waylandapplicationmanagerwindowimpl.h
@@ -56,6 +56,7 @@ public:
QColor color() const override;
void setColor(const QColor &c) override;
bool isActive() const override;
+ QQuickItem *activeFocusItem() const override;
bool setWindowProperty(const QString &name, const QVariant &value) override;
QVariant windowProperty(const QString &name) const override;
@@ -70,5 +71,15 @@ private:
AMQuickWindowQmlImpl *m_qwindow = nullptr;
};
+
+class WaylandApplicationManagerWindowAttachedImpl : public ApplicationManagerWindowAttachedImpl
+{
+public:
+ WaylandApplicationManagerWindowAttachedImpl(ApplicationManagerWindowAttached *windowAttached,
+ QQuickItem *attacheeItem);
+
+ ApplicationManagerWindow *findApplicationManagerWindow() override;
+};
+
QT_END_NAMESPACE_AM
// We mean it. Dummy comment since syncqt needs this also for completely private Qt modules.
diff --git a/src/manager-lib/inprocesssurfaceitem.cpp b/src/manager-lib/inprocesssurfaceitem.cpp
index e18f7ec6..81fb6a25 100644
--- a/src/manager-lib/inprocesssurfaceitem.cpp
+++ b/src/manager-lib/inprocesssurfaceitem.cpp
@@ -4,6 +4,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "inprocesssurfaceitem.h"
+#include "applicationmanagerwindow.h"
#include <QQmlEngine>
#include <QSGSimpleRectNode>
@@ -132,6 +133,16 @@ void InProcessSurfaceItem::close()
emit closeRequested();
}
+ApplicationManagerWindow *InProcessSurfaceItem::applicationManagerWindow()
+{
+ return m_amWindow.data();
+}
+
+void InProcessSurfaceItem::setApplicationManagerWindow(ApplicationManagerWindow *win)
+{
+ m_amWindow = win;
+}
+
QT_END_NAMESPACE_AM
#include "moc_inprocesssurfaceitem.cpp"
diff --git a/src/manager-lib/inprocesssurfaceitem.h b/src/manager-lib/inprocesssurfaceitem.h
index 6600dd8d..03ee0e9d 100644
--- a/src/manager-lib/inprocesssurfaceitem.h
+++ b/src/manager-lib/inprocesssurfaceitem.h
@@ -16,6 +16,8 @@
QT_BEGIN_NAMESPACE_AM
+class ApplicationManagerWindow;
+
/*
* Item exposed to the System UI
*/
@@ -44,8 +46,8 @@ public:
void close();
- QObject *inProcessApplicationManagerWindow() { return m_inProcessAppManWindow.data(); }
- void setInProcessApplicationManagerWindow(QObject* win) { m_inProcessAppManWindow = win; }
+ ApplicationManagerWindow *applicationManagerWindow();
+ void setApplicationManagerWindow(ApplicationManagerWindow *win);
signals:
void visibleClientSideChanged();
@@ -64,7 +66,7 @@ private:
QObject m_windowProperties;
bool m_visibleClientSide = true;
QColor m_color;
- QPointer<QObject> m_inProcessAppManWindow;
+ QPointer<ApplicationManagerWindow> m_amWindow;
};
QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/qmlinprocapplicationmanagerwindowimpl.cpp b/src/manager-lib/qmlinprocapplicationmanagerwindowimpl.cpp
index 046c4195..3467d9e3 100644
--- a/src/manager-lib/qmlinprocapplicationmanagerwindowimpl.cpp
+++ b/src/manager-lib/qmlinprocapplicationmanagerwindowimpl.cpp
@@ -3,6 +3,9 @@
// Copyright (C) 2018 Pelagicore AG
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QQuickWindow>
+#include <QtQuick/private/qquickitem_p.h>
+
#include "logging.h"
#include "applicationmanagerwindow.h"
#include "qmlinprocapplicationmanagerwindowimpl.h"
@@ -10,7 +13,6 @@
#include "qmlinprocruntime.h"
#include <private/qqmlcomponentattached_p.h>
-#include <QtQuick/private/qquickitem_p.h>
QT_BEGIN_NAMESPACE_AM
@@ -20,7 +22,7 @@ QmlInProcApplicationManagerWindowImpl::QmlInProcApplicationManagerWindowImpl(App
: ApplicationManagerWindowImpl(window)
, m_surfaceItem(new InProcessSurfaceItem)
{
- m_surfaceItem->setInProcessApplicationManagerWindow(window);
+ m_surfaceItem->setApplicationManagerWindow(window);
m_surfaceItem->setColor(QColorConstants::White);
QObject::connect(m_surfaceItem.data(), &QQuickItem::widthChanged,
@@ -34,6 +36,47 @@ QmlInProcApplicationManagerWindowImpl::QmlInProcApplicationManagerWindowImpl(App
QObject::connect(m_surfaceItem.data(), &InProcessSurfaceItem::closeRequested,
window, &ApplicationManagerWindow::close);
+
+ if (m_surfaceItem->window())
+ connectActiveFocusItem();
+ QObject::connect(m_surfaceItem.data(), &InProcessSurfaceItem::windowChanged,
+ window, [this]() { connectActiveFocusItem(); });
+}
+void QmlInProcApplicationManagerWindowImpl::connectActiveFocusItem()
+{
+ QObject::disconnect(m_activeFocusItemConnection);
+
+ if (m_surfaceItem->window()) {
+ // We can only track the AFI of our Window directly, but we keep a pointer to the AFI,
+ // if it is a child of our InProcessSurfaceItem
+
+ m_activeFocusItemConnection = QObject::connect(m_surfaceItem->window(), &QQuickWindow::activeFocusItemChanged,
+ amWindow(), [this]() {
+ auto *afi = m_surfaceItem->window() ? m_surfaceItem->window()->activeFocusItem()
+ : nullptr;
+ if (afi) {
+ bool found = false;
+ QQuickItem *p = afi->parentItem();
+ while (p) {
+ if (p == m_surfaceItem) {
+ found = true;
+ break;
+ }
+ p = p->parentItem();
+ }
+ if (!found)
+ afi = nullptr;
+ }
+ if (afi != m_activeFocusItem) {
+ bool activeChanged = (bool(afi) != bool(m_activeFocusItem));
+ m_activeFocusItem = afi;
+
+ if (activeChanged)
+ emit amWindow()->activeChanged();
+ emit amWindow()->activeFocusItemChanged();
+ }
+ });
+ }
}
QmlInProcApplicationManagerWindowImpl::~QmlInProcApplicationManagerWindowImpl()
@@ -168,22 +211,21 @@ void QmlInProcApplicationManagerWindowImpl::findParentWindow(QObject *object)
auto surfaceItem = qobject_cast<InProcessSurfaceItem *>(object);
if (surfaceItem) {
- setParentWindow(static_cast<ApplicationManagerWindow *>(surfaceItem->inProcessApplicationManagerWindow()));
+ setParentWindow(surfaceItem->applicationManagerWindow());
} else {
- auto inProcessAppWindow = qobject_cast<ApplicationManagerWindow *>(object);
- if (inProcessAppWindow)
- setParentWindow(inProcessAppWindow);
+ if (auto window = qobject_cast<ApplicationManagerWindow *>(object))
+ setParentWindow(window);
else
findParentWindow(object->parent());
}
}
-void QmlInProcApplicationManagerWindowImpl::setParentWindow(ApplicationManagerWindow *inProcessAppWindow)
+void QmlInProcApplicationManagerWindowImpl::setParentWindow(ApplicationManagerWindow *newParentWindow)
{
if (m_parentWindow && m_parentVisibleConnection)
QObject::disconnect(m_parentVisibleConnection);
- m_parentWindow = inProcessAppWindow;
+ m_parentWindow = newParentWindow;
if (m_parentWindow) {
m_parentVisibleConnection = QObject::connect(
@@ -223,7 +265,7 @@ int QmlInProcApplicationManagerWindowImpl::width() const
void QmlInProcApplicationManagerWindowImpl::setWidth(int w)
{
- m_surfaceItem->setWidth(w);
+ m_surfaceItem->setWidth(qBound(m_minimumWidth, w, m_maximumWidth));
}
int QmlInProcApplicationManagerWindowImpl::height() const
@@ -233,38 +275,58 @@ int QmlInProcApplicationManagerWindowImpl::height() const
void QmlInProcApplicationManagerWindowImpl::setHeight(int h)
{
- m_surfaceItem->setHeight(h);
+ m_surfaceItem->setHeight(qBound(m_minimumHeight, h, m_maximumHeight));
}
void QmlInProcApplicationManagerWindowImpl::setMinimumWidth(int minw)
{
+ if ((minw < 0) || (minw > WindowSizeMax))
+ return;
+
if (m_minimumWidth != minw) {
m_minimumWidth = minw;
emit amWindow()->minimumWidthChanged();
+ if (width() < minw)
+ setWidth(minw);
}
}
void QmlInProcApplicationManagerWindowImpl::setMinimumHeight(int minh)
{
+ if ((minh < 0) || (minh > WindowSizeMax))
+ return;
+
if (m_minimumHeight != minh) {
m_minimumHeight = minh;
emit amWindow()->minimumHeightChanged();
+ if (height() < minh)
+ setHeight(minh);
}
}
void QmlInProcApplicationManagerWindowImpl::setMaximumWidth(int maxw)
{
+ if ((maxw < 0) || (maxw > WindowSizeMax))
+ return;
+
if (m_maximumWidth != maxw) {
m_maximumWidth = maxw;
emit amWindow()->maximumWidthChanged();
+ if (width() > maxw)
+ setWidth(maxw);
}
}
void QmlInProcApplicationManagerWindowImpl::setMaximumHeight(int maxh)
{
+ if ((maxh < 0) || (maxh > WindowSizeMax))
+ return;
+
if (m_maximumHeight != maxh) {
m_maximumHeight = maxh;
emit amWindow()->maximumHeightChanged();
+ if (height() > maxh)
+ setHeight(maxh);
}
}
@@ -303,4 +365,65 @@ void QmlInProcApplicationManagerWindowImpl::setColor(const QColor &c)
}
}
+bool QmlInProcApplicationManagerWindowImpl::isActive() const
+{
+ return (m_activeFocusItem);
+}
+
+QQuickItem *QmlInProcApplicationManagerWindowImpl::activeFocusItem() const
+{
+ return m_activeFocusItem;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ApplicationManagerWindowAttached
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+QmlInProcApplicationManagerWindowAttachedImpl::QmlInProcApplicationManagerWindowAttachedImpl(ApplicationManagerWindowAttached *windowAttached, QQuickItem *attacheeItem)
+ : ApplicationManagerWindowAttachedImpl(windowAttached, attacheeItem)
+{ }
+
+ApplicationManagerWindow *QmlInProcApplicationManagerWindowAttachedImpl::findApplicationManagerWindow()
+{
+ if (!attacheeItem())
+ return nullptr;
+
+ auto ipsurface = findInProcessSurfaceItem();
+ return ipsurface ? ipsurface->applicationManagerWindow() : nullptr;
+}
+
+InProcessSurfaceItem *QmlInProcApplicationManagerWindowAttachedImpl::findInProcessSurfaceItem()
+{
+ // Connect to all parent items' parentChanged() signals, up to root or an InProcessSurfaceItem.
+ // If one of them changes, disconnect all parentChanged connections, then find the new
+ // InProcessSurfaceItem and re-connect.
+
+ for (const auto &connection : std::as_const(m_parentChangeConnections))
+ QObject::disconnect(connection);
+
+ InProcessSurfaceItem *ipsurface = nullptr;
+ QQuickItem *p = attacheeItem();
+ while (p && !ipsurface) {
+ ipsurface = qobject_cast<InProcessSurfaceItem *>(p);
+ if (!ipsurface) {
+ m_parentChangeConnections << QObject::connect(p, &QQuickItem::parentChanged,
+ amWindowAttached(), [this]() { onParentChanged(); });
+ }
+ p = p->parentItem();
+ }
+ return ipsurface;
+}
+
+void QmlInProcApplicationManagerWindowAttachedImpl::onParentChanged()
+{
+ InProcessSurfaceItem *ipsurface = findInProcessSurfaceItem();
+
+ if (!amWindowAttached()->window()
+ || (ipsurface != amWindowAttached()->window()->backingObject())) {
+ onWindowChanged(ipsurface ? ipsurface->applicationManagerWindow() : nullptr);
+ }
+}
+
QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/qmlinprocapplicationmanagerwindowimpl.h b/src/manager-lib/qmlinprocapplicationmanagerwindowimpl.h
index 92c24fac..509db596 100644
--- a/src/manager-lib/qmlinprocapplicationmanagerwindowimpl.h
+++ b/src/manager-lib/qmlinprocapplicationmanagerwindowimpl.h
@@ -58,7 +58,8 @@ public:
void setOpacity(qreal opactity) override;
QColor color() const override;
void setColor(const QColor &c) override;
- bool isActive() const override { return m_active; }
+ bool isActive() const override;
+ QQuickItem *activeFocusItem() const override;
bool setWindowProperty(const QString &name, const QVariant &value) override;
QVariant windowProperty(const QString &name) const override;
@@ -72,7 +73,8 @@ private:
void notifyRuntimeAboutSurface();
void determineRuntime();
void findParentWindow(QObject *object);
- void setParentWindow(ApplicationManagerWindow *inProcessAppWindow);
+ void setParentWindow(ApplicationManagerWindow *newParentWindow);
+ void connectActiveFocusItem();
static QVector<QmlInProcApplicationManagerWindowImpl *> s_inCompleteWindows;
@@ -81,19 +83,37 @@ private:
QVector<QQmlComponentAttached *> m_attachedCompleteHandlers;
ApplicationManagerWindow *m_parentWindow = nullptr;
QMetaObject::Connection m_parentVisibleConnection;
+ QMetaObject::Connection m_activeFocusItemConnection;
private:
QString m_title;
- int m_x;
- int m_y;
- int m_minimumWidth;
- int m_minimumHeight;
- int m_maximumWidth;
- int m_maximumHeight;
- bool m_active;
- qreal m_opacity;
+ int m_x = 0;
+ int m_y = 0;
+ int m_minimumWidth = 0;
+ int m_minimumHeight = 0;
+ static const int WindowSizeMax = (1 << 24) - 1; // same as QWINDOWSIZE_MAX
+ int m_maximumWidth = WindowSizeMax;
+ int m_maximumHeight = WindowSizeMax;
+ qreal m_opacity = 1;
+ QQuickItem *m_activeFocusItem = nullptr;
friend class QmlInProcRuntime; // for setting the m_runtime member
};
+
+class QmlInProcApplicationManagerWindowAttachedImpl : public ApplicationManagerWindowAttachedImpl
+{
+public:
+ QmlInProcApplicationManagerWindowAttachedImpl(ApplicationManagerWindowAttached *windowAttached,
+ QQuickItem *attacheeItem);
+
+ ApplicationManagerWindow *findApplicationManagerWindow() override;
+
+private:
+ void onParentChanged();
+ InProcessSurfaceItem *findInProcessSurfaceItem();
+
+ QVector<QMetaObject::Connection> m_parentChangeConnections;
+};
+
QT_END_NAMESPACE_AM
diff --git a/src/shared-main-lib/applicationmanagerwindow.cpp b/src/shared-main-lib/applicationmanagerwindow.cpp
index fd364fb0..b4ee0b44 100644
--- a/src/shared-main-lib/applicationmanagerwindow.cpp
+++ b/src/shared-main-lib/applicationmanagerwindow.cpp
@@ -80,6 +80,11 @@ ApplicationManagerWindow::~ApplicationManagerWindow()
setVisible(false);
}
+ApplicationManagerWindowAttached *ApplicationManagerWindow::qmlAttachedProperties(QObject *object)
+{
+ return new ApplicationManagerWindowAttached(object);
+}
+
QQmlListProperty<QObject> ApplicationManagerWindow::data()
{
return QQmlListProperty<QObject>(this, nullptr,
@@ -350,6 +355,90 @@ bool ApplicationManagerWindow::isActive() const
return m_impl->isActive();
}
+QQuickItem *ApplicationManagerWindow::activeFocusItem() const
+{
+ return m_impl->activeFocusItem();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ApplicationManagerWindowAttached
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ApplicationManagerWindowAttached::ApplicationManagerWindowAttached(QObject *attachee)
+ : QObject(attachee)
+{
+ if (auto *attacheeItem = qobject_cast<QQuickItem*>(attachee)) {
+ m_impl.reset(ApplicationManagerWindowAttachedImpl::create(this, attacheeItem));
+
+ if (auto *amwindow = m_impl->findApplicationManagerWindow())
+ reconnect(amwindow);
+ }
+}
+
+
+void ApplicationManagerWindowAttached::reconnect(ApplicationManagerWindow *newWin)
+{
+ if (newWin == m_amwindow)
+ return;
+
+ if (m_amwindow)
+ QObject::disconnect(m_amwindow, nullptr, this, nullptr);
+
+ m_amwindow = newWin;
+ emit windowChanged();
+ emit backingObjectChanged();
+ emit contentItemChanged();
+
+ if (m_amwindow) {
+ QObject::connect(m_amwindow, &ApplicationManagerWindow::activeChanged,
+ this, &ApplicationManagerWindowAttached::activeChanged);
+ QObject::connect(m_amwindow, &ApplicationManagerWindow::activeFocusItemChanged,
+ this, &ApplicationManagerWindowAttached::activeFocusItemChanged);
+ QObject::connect(m_amwindow, &ApplicationManagerWindow::widthChanged,
+ this, &ApplicationManagerWindowAttached::widthChanged);
+ QObject::connect(m_amwindow, &ApplicationManagerWindow::heightChanged,
+ this, &ApplicationManagerWindowAttached::heightChanged);
+ }
+}
+
+ApplicationManagerWindow *ApplicationManagerWindowAttached::window() const
+{
+ return m_amwindow.get();
+}
+
+QObject *ApplicationManagerWindowAttached::backingObject() const
+{
+ return m_amwindow ? m_amwindow->backingObject() : nullptr;
+}
+
+bool ApplicationManagerWindowAttached::isActive() const
+{
+ return m_amwindow ? m_amwindow->isActive() : false;
+}
+
+QQuickItem *ApplicationManagerWindowAttached::activeFocusItem() const
+{
+ return m_amwindow ? m_amwindow->activeFocusItem() : nullptr;
+}
+
+QQuickItem *ApplicationManagerWindowAttached::contentItem() const
+{
+ return m_amwindow ? m_amwindow->contentItem() : nullptr;
+}
+
+int ApplicationManagerWindowAttached::width() const
+{
+ return m_amwindow ? m_amwindow->height() : 0;
+}
+
+int ApplicationManagerWindowAttached::height() const
+{
+ return m_amwindow ? m_amwindow->height() : 0;
+}
+
+
QT_END_NAMESPACE_AM
#include "moc_applicationmanagerwindow.cpp"
diff --git a/src/shared-main-lib/applicationmanagerwindow.h b/src/shared-main-lib/applicationmanagerwindow.h
index ea6ebb87..a41f7d05 100644
--- a/src/shared-main-lib/applicationmanagerwindow.h
+++ b/src/shared-main-lib/applicationmanagerwindow.h
@@ -10,6 +10,7 @@
#include <QtGui/QColor>
#include <QtQml/QQmlParserStatus>
#include <QtQml/QQmlListProperty>
+#include <QtQml/QQmlEngine>
#include <QtAppManCommon/global.h>
@@ -19,6 +20,8 @@ QT_FORWARD_DECLARE_CLASS(QQuickItem)
QT_BEGIN_NAMESPACE_AM
class ApplicationManagerWindowImpl;
+class ApplicationManagerWindowAttached;
+class ApplicationManagerWindowAttachedImpl;
class ApplicationManagerWindow : public QObject, public QQmlParserStatus
@@ -26,10 +29,11 @@ class ApplicationManagerWindow : public QObject, public QQmlParserStatus
Q_OBJECT
Q_CLASSINFO("AM-QmlType", "QtApplicationManager.Application/ApplicationManagerWindow 2.0")
Q_INTERFACES(QQmlParserStatus)
+ QML_ATTACHED(ApplicationManagerWindowAttached)
Q_PROPERTY(bool inProcess READ isInProcess CONSTANT FINAL)
Q_PROPERTY(QObject *backingObject READ backingObject CONSTANT FINAL)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL)
- Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT FINAL)
+ Q_PROPERTY(QQuickItem *contentItem READ contentItem CONSTANT FINAL)
// QWindow properties
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL)
@@ -48,6 +52,7 @@ class ApplicationManagerWindow : public QObject, public QQmlParserStatus
//Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged FINAL)
//Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation WRITE reportContentOrientationChange NOTIFY contentOrientationChanged FINAL)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
+ Q_PROPERTY(QQuickItem *activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged FINAL)
Q_PROPERTY(QQmlListProperty<QObject> data READ data NOTIFY dataChanged FINAL)
@@ -57,6 +62,8 @@ public:
explicit ApplicationManagerWindow(QObject *parent = nullptr);
~ApplicationManagerWindow() override;
+ static ApplicationManagerWindowAttached *qmlAttachedProperties(QObject *object);
+
bool isInProcess() const;
QObject *backingObject() const;
@@ -106,6 +113,8 @@ public:
Q_SIGNAL void colorChanged();
bool isActive() const;
Q_SIGNAL void activeChanged();
+ QQuickItem *activeFocusItem() const;
+ Q_SIGNAL void activeFocusItemChanged();
Q_INVOKABLE bool setWindowProperty(const QString &name, const QVariant &value);
Q_INVOKABLE QVariant windowProperty(const QString &name) const;
@@ -134,6 +143,53 @@ private:
static qsizetype data_count(QQmlListProperty<QObject> *property);
static QObject *data_at(QQmlListProperty<QObject> *property, qsizetype index);
static void data_clear(QQmlListProperty<QObject> *property);
+
+ Q_DISABLE_COPY_MOVE(ApplicationManagerWindow)
};
+class ApplicationManagerWindowAttached : public QObject
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ Q_PROPERTY(ApplicationManagerWindow *window READ window NOTIFY windowChanged FINAL)
+ Q_PROPERTY(QObject *backingObject READ backingObject NOTIFY backingObjectChanged FINAL)
+// Q_PROPERTY(QWindow::Visibility visibility READ visibility NOTIFY visibilityChanged FINAL)
+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged FINAL)
+ Q_PROPERTY(QQuickItem *activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged FINAL)
+ Q_PROPERTY(QQuickItem *contentItem READ contentItem NOTIFY contentItemChanged FINAL)
+ Q_PROPERTY(int width READ width NOTIFY widthChanged FINAL)
+ Q_PROPERTY(int height READ height NOTIFY heightChanged FINAL)
+
+public:
+ explicit ApplicationManagerWindowAttached(QObject *attachee);
+
+ ApplicationManagerWindow *window() const;
+ Q_SIGNAL void windowChanged();
+ QObject *backingObject() const;
+ Q_SIGNAL void backingObjectChanged();
+// QWindow::Visibility visibility() const;
+// Q_SIGNAL void visibilityChanged();
+ bool isActive() const;
+ Q_SIGNAL void activeChanged();
+ QQuickItem *activeFocusItem() const;
+ Q_SIGNAL void activeFocusItemChanged();
+ QQuickItem *contentItem() const;
+ Q_SIGNAL void contentItemChanged();
+ int width() const;
+ Q_SIGNAL void widthChanged();
+ int height() const;
+ Q_SIGNAL void heightChanged();
+
+ QQuickItem *attachee();
+ void reconnect(ApplicationManagerWindow *newWin); // callback for implementation
+
+protected:
+ std::unique_ptr<ApplicationManagerWindowAttachedImpl> m_impl;
+ QPointer<ApplicationManagerWindow> m_amwindow;
+
+private:
+ Q_DISABLE_COPY_MOVE(ApplicationManagerWindowAttached)
+};
+
+
QT_END_NAMESPACE_AM
diff --git a/src/shared-main-lib/applicationmanagerwindowimpl.cpp b/src/shared-main-lib/applicationmanagerwindowimpl.cpp
index f5583ed2..70e0211d 100644
--- a/src/shared-main-lib/applicationmanagerwindowimpl.cpp
+++ b/src/shared-main-lib/applicationmanagerwindowimpl.cpp
@@ -27,4 +27,44 @@ ApplicationManagerWindow *ApplicationManagerWindowImpl::amWindow()
return m_amwindow;
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ApplicationManagerWindowAttachedImpl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+std::function<ApplicationManagerWindowAttachedImpl *(ApplicationManagerWindowAttached *, QQuickItem *)> ApplicationManagerWindowAttachedImpl::s_factory;
+
+ApplicationManagerWindowAttachedImpl::ApplicationManagerWindowAttachedImpl(ApplicationManagerWindowAttached *windowAttached,
+ QQuickItem *attacheeItem)
+ : m_amWindowAttached(windowAttached)
+ , m_attacheeItem(attacheeItem)
+{ }
+
+void ApplicationManagerWindowAttachedImpl::setFactory(const std::function<ApplicationManagerWindowAttachedImpl *(ApplicationManagerWindowAttached *, QQuickItem *)> &factory)
+{
+ s_factory = factory;
+}
+
+ApplicationManagerWindowAttachedImpl *ApplicationManagerWindowAttachedImpl::create(ApplicationManagerWindowAttached *windowAttached, QQuickItem *attacheeItem)
+{
+ return s_factory ? s_factory(windowAttached, attacheeItem) : nullptr;
+}
+
+ApplicationManagerWindowAttached *ApplicationManagerWindowAttachedImpl::amWindowAttached() const
+{
+ return m_amWindowAttached;
+}
+
+QQuickItem *ApplicationManagerWindowAttachedImpl::attacheeItem() const
+{
+ return m_attacheeItem;
+}
+
+void ApplicationManagerWindowAttachedImpl::onWindowChanged(ApplicationManagerWindow *newWin)
+{
+ m_amWindowAttached->reconnect(newWin);
+}
+
+
QT_END_NAMESPACE_AM
diff --git a/src/shared-main-lib/applicationmanagerwindowimpl.h b/src/shared-main-lib/applicationmanagerwindowimpl.h
index 224218e8..a4e56c75 100644
--- a/src/shared-main-lib/applicationmanagerwindowimpl.h
+++ b/src/shared-main-lib/applicationmanagerwindowimpl.h
@@ -8,10 +8,12 @@
#include <QtAppManCommon/global.h>
QT_FORWARD_DECLARE_CLASS(QQuickItem)
+QT_FORWARD_DECLARE_CLASS(QQuickWindow)
QT_BEGIN_NAMESPACE_AM
class ApplicationManagerWindow;
+class ApplicationManagerWindowAttached;
class ApplicationManagerWindowImpl
@@ -59,6 +61,7 @@ public:
virtual void setColor(const QColor &c) = 0;
virtual bool isActive() const = 0;
+ virtual QQuickItem *activeFocusItem() const = 0;
virtual bool setWindowProperty(const QString &name, const QVariant &value) = 0;
virtual QVariant windowProperty(const QString &name) const = 0;
@@ -79,4 +82,33 @@ private:
Q_DISABLE_COPY_MOVE(ApplicationManagerWindowImpl)
};
+
+class ApplicationManagerWindowAttachedImpl
+{
+public:
+ static void setFactory(const std::function<ApplicationManagerWindowAttachedImpl *(ApplicationManagerWindowAttached *, QQuickItem *)> &factory);
+
+ static ApplicationManagerWindowAttachedImpl *create(ApplicationManagerWindowAttached *window,
+ QQuickItem *attacheeItem);
+
+ virtual ~ApplicationManagerWindowAttachedImpl() = default;
+
+ ApplicationManagerWindowAttached *amWindowAttached() const;
+ QQuickItem *attacheeItem() const;
+
+ virtual ApplicationManagerWindow *findApplicationManagerWindow() = 0;
+ void onWindowChanged(ApplicationManagerWindow *newWin);
+
+protected:
+ ApplicationManagerWindowAttachedImpl(ApplicationManagerWindowAttached *windowAttached,
+ QQuickItem *attacheeItem);
+
+private:
+ ApplicationManagerWindowAttached *m_amWindowAttached;
+ QQuickItem *m_attacheeItem;
+
+ static std::function<ApplicationManagerWindowAttachedImpl *(ApplicationManagerWindowAttached *, QQuickItem *)> s_factory;
+ Q_DISABLE_COPY_MOVE(ApplicationManagerWindowAttachedImpl)
+};
+
QT_END_NAMESPACE_AM
diff --git a/src/window-lib/windowmanager.cpp b/src/window-lib/windowmanager.cpp
index 5911da01..7c4beee2 100644
--- a/src/window-lib/windowmanager.cpp
+++ b/src/window-lib/windowmanager.cpp
@@ -229,6 +229,10 @@ WindowManager *WindowManager::createInstance(QQmlEngine *qmlEngine, const QStrin
ApplicationManagerWindowImpl::setFactory([](ApplicationManagerWindow *window) {
return new QmlInProcApplicationManagerWindowImpl(window);
});
+ ApplicationManagerWindowAttachedImpl::setFactory([](ApplicationManagerWindowAttached *windowAttached,
+ QQuickItem *attacheeItem) {
+ return new QmlInProcApplicationManagerWindowAttachedImpl(windowAttached, attacheeItem);
+ });
SystemFrameTimerImpl::setFactory([](FrameTimer *frameTimer) {
return new SystemFrameTimerImpl(frameTimer);
});