summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/elements-systemui.qdoc2
-rw-r--r--doc/manifest.qdoc1
-rw-r--r--examples/applicationmanager/intents/apps/intents.blue/info.yaml8
-rw-r--r--examples/applicationmanager/intents/apps/intents.green/info.yaml4
-rw-r--r--examples/applicationmanager/intents/apps/intents.red/info.yaml6
-rw-r--r--examples/applicationmanager/intents/doc/src/intents.qdoc34
-rw-r--r--examples/applicationmanager/intents/shared/IntentsUIPage.qml2
-rw-r--r--examples/applicationmanager/intents/system-ui.qml17
-rw-r--r--src/intent-client-lib/intentclient.cpp18
-rw-r--r--src/intent-client-lib/intentclient.h2
-rw-r--r--src/intent-client-lib/intentclientrequest.cpp10
-rw-r--r--src/intent-client-lib/intentclientrequest.h1
-rw-r--r--src/intent-client-lib/intentclientsysteminterface.h3
-rw-r--r--src/intent-client-lib/intenthandler.cpp24
-rw-r--r--src/intent-client-lib/intenthandler.h5
-rw-r--r--src/intent-server-lib/intent.h1
-rw-r--r--src/intent-server-lib/intentmodel.cpp2
-rw-r--r--src/launcher-lib/intentclientdbusimplementation.cpp17
-rw-r--r--src/manager-lib/applicationipcinterface.cpp2
-rw-r--r--src/manager-lib/applicationmodel.cpp2
-rw-r--r--src/manager-lib/intentaminterface.cpp222
-rw-r--r--src/manager-lib/intentaminterface.h48
-rw-r--r--src/manager-lib/processstatus.cpp2
-rw-r--r--src/manager-lib/qmlinprocessapplicationinterface.cpp3
-rw-r--r--src/window-lib/windowitem.cpp2
25 files changed, 399 insertions, 39 deletions
diff --git a/doc/elements-systemui.qdoc b/doc/elements-systemui.qdoc
index c82eba0f..b4ad59e2 100644
--- a/doc/elements-systemui.qdoc
+++ b/doc/elements-systemui.qdoc
@@ -51,7 +51,7 @@ item models.
These types are only available for the System UI:
-\annotatedlist system-ui
+\annotatedlist system-ui-instantiable
\section1 Non-Instantiable QML Types
diff --git a/doc/manifest.qdoc b/doc/manifest.qdoc
index 0679943d..a9091963 100644
--- a/doc/manifest.qdoc
+++ b/doc/manifest.qdoc
@@ -256,6 +256,7 @@ The fields used for each item within the \c applications list are as follows:
provided, a default description is used.
\endtable
+\target manifest-intent
The fields used for each item within the \c intents list are as follows:
\table
diff --git a/examples/applicationmanager/intents/apps/intents.blue/info.yaml b/examples/applicationmanager/intents/apps/intents.blue/info.yaml
index 19f252c4..7ce3930e 100644
--- a/examples/applicationmanager/intents/apps/intents.blue/info.yaml
+++ b/examples/applicationmanager/intents/apps/intents.blue/info.yaml
@@ -10,8 +10,16 @@ name:
intents:
- id: rotate-window
+ name:
+ en: Rotate Blue
requiredCapabilities: [ 'call-blue' ]
- id: scale-window
+ name:
+ en: Scale Blue
- id: blink-window
+ name:
+ en: Blink Blue
- id: blue-window-private
+ name:
+ en: Blue Private Intent
visibility: private
diff --git a/examples/applicationmanager/intents/apps/intents.green/info.yaml b/examples/applicationmanager/intents/apps/intents.green/info.yaml
index 97503419..40575f03 100644
--- a/examples/applicationmanager/intents/apps/intents.green/info.yaml
+++ b/examples/applicationmanager/intents/apps/intents.green/info.yaml
@@ -10,4 +10,8 @@ name:
intents:
- id: rotate-window
+ name:
+ en: Rotate Green
- id: scale-window
+ name:
+ en: Scale Green
diff --git a/examples/applicationmanager/intents/apps/intents.red/info.yaml b/examples/applicationmanager/intents/apps/intents.red/info.yaml
index a08392fc..d61ba316 100644
--- a/examples/applicationmanager/intents/apps/intents.red/info.yaml
+++ b/examples/applicationmanager/intents/apps/intents.red/info.yaml
@@ -12,5 +12,11 @@ capabilities: 'call-blue'
intents:
- id: rotate-window
+ name:
+ en: Rotate Red
- id: scale-window
+ name:
+ en: Scale Red
- id: blink-window
+ name:
+ en: Blink Red
diff --git a/examples/applicationmanager/intents/doc/src/intents.qdoc b/examples/applicationmanager/intents/doc/src/intents.qdoc
index f1da854a..958fa483 100644
--- a/examples/applicationmanager/intents/doc/src/intents.qdoc
+++ b/examples/applicationmanager/intents/doc/src/intents.qdoc
@@ -127,7 +127,7 @@ For information on these and other command line options you can run \tt{appman -
look at the \l{Configuration} documentation.
-\section1 Application implementation
+\section1 Application Implementation
All the applications (red, green and blue) are identical and their \c main.qml just
instantiates the shared IntentsApplicationWindow component.
@@ -197,10 +197,36 @@ required capability, while the \b Green doesn't.
\printto
-\section1 System-UI implementation
+\section1 System-UI Implementation
-What is special about the System-UI as compared to the applications, is the \l
-{IntentServer::disambiguationRequest}{disambiguation mechanism} and the accompanying UI.
+Apart from the left side bar that deals with starting and stopping the apps, the System-UI has two
+special features that deal with the intent mechanism:
+
+\list
+ \li Handling Intents in the System-UI and
+ \li Disambiguation of Intent Requests
+\endlist
+
+\section2 Handling Intents in the System-UI
+
+Intents can not only be handled in applications, but also in the System-UI. Since the System-UI is
+always running, we do not need to rely on \c info.yaml manifest files to define the supported
+intents, but instead can declare the needed meta-data directly as properties of the
+IntentServerHandler component. The IntentServerHandler is actually derived from IntentHandler, so
+it works the same way as its application side counter part: it only adds the required properties to
+define all the meta-data (e.g. \c names, \c icon, ...) on top.
+
+\snippet applicationmanager/intents/system-ui.qml IntentServerHandler
+
+The handler callback is nearly the same as the one in the applications. The only noteworthy
+difference here is, that we have access to the \l{IntentRequest::}{requestingApplicationId}
+to identify where the request originated from; for security reasons, this data is not available to
+intent handlers in applications.
+
+\section2 Disambiguation of Intent Requests
+
+The example implements an UI that lets the user choose how to
+\l {IntentServer::disambiguationRequest}{to disambiguate incoming intent requests}.
Registering for the IntentServer's disambiguation requests is done here:
\snippet applicationmanager/intents/system-ui.qml Connection
diff --git a/examples/applicationmanager/intents/shared/IntentsUIPage.qml b/examples/applicationmanager/intents/shared/IntentsUIPage.qml
index 0420a089..010a1501 100644
--- a/examples/applicationmanager/intents/shared/IntentsUIPage.qml
+++ b/examples/applicationmanager/intents/shared/IntentsUIPage.qml
@@ -104,7 +104,7 @@ Rectangle {
Label { text: "Application:" }
ComboBox {
id: cbApplication
- model: [ "<not specified>", "intents.red", "intents.green", "intents.blue" ]
+ model: [ "<not specified>", "intents.red", "intents.green", "intents.blue", ":sysui:" ]
Layout.fillWidth: true
}
Button {
diff --git a/examples/applicationmanager/intents/system-ui.qml b/examples/applicationmanager/intents/system-ui.qml
index e3198f80..f212d3c8 100644
--- a/examples/applicationmanager/intents/system-ui.qml
+++ b/examples/applicationmanager/intents/system-ui.qml
@@ -112,6 +112,23 @@ Item {
request.succeeded ? request.result : request.errorMessage)
})
}
+ RotationAnimation on rotation {
+ id: rotationAnimation
+ running: false
+ duration: 500; from: 0; to: 360
+ }
+ //! [IntentServerHandler]
+ IntentServerHandler {
+ intentIds: "rotate-window"
+ names: { "en": "Rotate System-UI" }
+ visibility: IntentObject.Public
+
+ onRequestReceived: {
+ rotationAnimation.start()
+ request.sendReply({ "wasRequestedBy": request.requestingApplicationId })
+ }
+ }
+ //! [IntentServerHandler]
}
Repeater {
diff --git a/src/intent-client-lib/intentclient.cpp b/src/intent-client-lib/intentclient.cpp
index 89f4b949..449061db 100644
--- a/src/intent-client-lib/intentclient.cpp
+++ b/src/intent-client-lib/intentclient.cpp
@@ -42,9 +42,8 @@
****************************************************************************/
#include <QScopedPointer>
-#include <qqml.h>
-#include <QQmlInfo>
#include <QQmlEngine>
+#include <QQmlInfo>
#include "intentclient.h"
#include "intentclientsysteminterface.h"
@@ -100,16 +99,6 @@ IntentClient *IntentClient::createInstance(IntentClientSystemInterface *systemIn
qCWarning(LogIntents) << "Failed to initialize IntentClient:" << exc.what();
return nullptr;
}
- qmlRegisterSingletonType<IntentClient>("QtApplicationManager", 2, 0, "IntentClient",
- [](QQmlEngine *, QJSEngine *) -> QObject * {
- QQmlEngine::setObjectOwnership(instance(), QQmlEngine::CppOwnership);
- return instance();
- });
-
- qmlRegisterUncreatableType<IntentClientRequest>("QtApplicationManager", 2, 0, "IntentRequest",
- qSL("Cannot create objects of type IntentRequest"));
- qmlRegisterType<IntentHandler>("QtApplicationManager.Application", 2, 0, "IntentHandler");
-
return s_instance = ic.take();
}
@@ -272,14 +261,15 @@ void IntentClient::replyFromSystem(const QUuid &requestId, bool error, const QVa
}
void IntentClient::requestToApplication(const QUuid &requestId, const QString &intentId,
+ const QString &requestingApplicationId,
const QString &applicationId, const QVariantMap &parameters)
{
qCDebug(LogIntents) << "Client: Incoming intent request" << requestId << "to application" << applicationId
<< "for intent" << intentId << "parameters" << parameters;
IntentClientRequest *icr = new IntentClientRequest(IntentClientRequest::Direction::ToApplication,
- QString(), requestId, intentId, applicationId,
- parameters);
+ requestingApplicationId, requestId, intentId,
+ applicationId, parameters);
IntentHandler *handler = m_handlers.value(qMakePair(intentId, applicationId));
if (handler) {
diff --git a/src/intent-client-lib/intentclient.h b/src/intent-client-lib/intentclient.h
index f3ba44c2..54bbf24a 100644
--- a/src/intent-client-lib/intentclient.h
+++ b/src/intent-client-lib/intentclient.h
@@ -92,7 +92,7 @@ private:
bool error, const QString &errorMessage);
void replyFromSystem(const QUuid &requestId, bool error, const QVariantMap &result);
- void requestToApplication(const QUuid &requestId, const QString &intentId,
+ void requestToApplication(const QUuid &requestId, const QString &intentId, const QString &requestingApplicationId,
const QString &applicationId, const QVariantMap &parameters);
private:
diff --git a/src/intent-client-lib/intentclientrequest.cpp b/src/intent-client-lib/intentclientrequest.cpp
index c6cba1cb..e0aad1e7 100644
--- a/src/intent-client-lib/intentclientrequest.cpp
+++ b/src/intent-client-lib/intentclientrequest.cpp
@@ -115,6 +115,16 @@ QT_BEGIN_NAMESPACE_AM
\note Constant, valid on both sent and received requests.
*/
+/*! \qmlproperty string IntentRequest::requestingApplicationId
+ \readonly
+
+ The id of the application which created this intent request. Returns an empty string if called
+ from within an application context - only the server side has access to this information in
+ IntentServerHandler::requestReceived.
+
+ \note Constant, valid on both sent and received requests.
+*/
+
/*! \qmlproperty var IntentRequest::parameters
\readonly
diff --git a/src/intent-client-lib/intentclientrequest.h b/src/intent-client-lib/intentclientrequest.h
index 8d898d32..b11d5648 100644
--- a/src/intent-client-lib/intentclientrequest.h
+++ b/src/intent-client-lib/intentclientrequest.h
@@ -62,6 +62,7 @@ class IntentClientRequest : public QObject
Q_PROPERTY(Direction direction READ direction CONSTANT)
Q_PROPERTY(QString intentId READ intentId CONSTANT)
Q_PROPERTY(QString applicationId READ applicationId CONSTANT)
+ Q_PROPERTY(QString requestingApplicationId READ requestingApplicationId CONSTANT)
Q_PROPERTY(QVariantMap parameters READ parameters CONSTANT)
Q_PROPERTY(bool succeeded READ succeeded NOTIFY replyReceived)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY replyReceived)
diff --git a/src/intent-client-lib/intentclientsysteminterface.h b/src/intent-client-lib/intentclientsysteminterface.h
index 307aae8f..f54675e6 100644
--- a/src/intent-client-lib/intentclientsysteminterface.h
+++ b/src/intent-client-lib/intentclientsysteminterface.h
@@ -74,7 +74,8 @@ signals:
void replyFromSystem(const QUuid &requestId, bool error, const QVariantMap &result);
void requestToApplication(const QUuid &requestId, const QString &intentId,
- const QString &applicationId, const QVariantMap &parameters);
+ const QString &requestingApplicationId, const QString &applicationId,
+ const QVariantMap &parameters);
protected:
IntentClient *m_ic = nullptr;
diff --git a/src/intent-client-lib/intenthandler.cpp b/src/intent-client-lib/intenthandler.cpp
index e8cf146c..2a571403 100644
--- a/src/intent-client-lib/intenthandler.cpp
+++ b/src/intent-client-lib/intenthandler.cpp
@@ -41,6 +41,8 @@
**
****************************************************************************/
+#include <QQmlInfo>
+
#include "intenthandler.h"
#include "intentclient.h"
@@ -48,7 +50,7 @@ QT_BEGIN_NAMESPACE_AM
/*! \qmltype IntentHandler
\inqmlmodule QtApplicationManager.Application
- \ingroup common-instantiatable
+ \ingroup application-instantiatable
\brief A handler for intent requests received by applications.
Any application that has intents listed in its manifest file needs to have a corresponding
@@ -57,6 +59,10 @@ QT_BEGIN_NAMESPACE_AM
instance or have a dedicated IntentHandler instance for every intent id (or any combination of
those).
+ \note For handling intent requests within the system ui, you have to use the derived component
+ IntentServerHandler, which works the same way, but provides all the necessary meta-data
+ from within QML.
+
Here is a fairly standard way to handle an incoming intent request and send out a result or
error message:
@@ -86,8 +92,7 @@ QT_BEGIN_NAMESPACE_AM
Every handler needs to register at least one unique intent id that it will handle. Having
multiple IntentHandlers that are registering the same intent id is not possible.
- \note Any changes to this property after component completion will have no effect. This
- restriction will likely be removed in a future update.
+ \note Any changes to this property after component completion will have no effect.
*/
/*! \qmlsignal IntentHandler::requestReceived(IntentRequest request)
@@ -127,18 +132,25 @@ QStringList IntentHandler::intentIds() const
void IntentHandler::setIntentIds(const QStringList &intentIds)
{
- if (intentIds != m_intentIds) {
- m_intentIds = intentIds;
- emit intentIdsChanged(m_intentIds);
+ if (isComponentCompleted()) {
+ qmlWarning(this) << "Cannot change the intentIds property of an IntentHandler after creation.";
+ return;
}
+ m_intentIds = intentIds;
}
void IntentHandler::componentComplete()
{
IntentClient::instance()->registerHandler(this);
+ m_completed = true;
}
void IntentHandler::classBegin()
{ }
+bool IntentHandler::isComponentCompleted() const
+{
+ return m_completed;
+}
+
QT_END_NAMESPACE_AM
diff --git a/src/intent-client-lib/intenthandler.h b/src/intent-client-lib/intenthandler.h
index 95c73e41..aaf5e031 100644
--- a/src/intent-client-lib/intenthandler.h
+++ b/src/intent-client-lib/intenthandler.h
@@ -60,7 +60,7 @@ class IntentHandler : public QObject, public QQmlParserStatus
Q_CLASSINFO("AM-QmlType", "QtApplicationManager.Application/IntentHandler 2.0")
Q_INTERFACES(QQmlParserStatus)
- Q_PROPERTY(QStringList intentIds READ intentIds WRITE setIntentIds NOTIFY intentIdsChanged)
+ Q_PROPERTY(QStringList intentIds READ intentIds WRITE setIntentIds)
public:
IntentHandler(QObject *parent = nullptr);
@@ -78,10 +78,13 @@ protected:
void componentComplete() override;
void classBegin() override;
+ bool isComponentCompleted() const;
+
private:
Q_DISABLE_COPY(IntentHandler)
QStringList m_intentIds;
+ bool m_completed = false;
};
QT_END_NAMESPACE_AM
diff --git a/src/intent-server-lib/intent.h b/src/intent-server-lib/intent.h
index a8a04d52..a519c425 100644
--- a/src/intent-server-lib/intent.h
+++ b/src/intent-server-lib/intent.h
@@ -114,6 +114,7 @@ private:
QUrl m_icon;
friend class IntentServer;
+ friend class IntentServerHandler;
};
QT_END_NAMESPACE_AM
diff --git a/src/intent-server-lib/intentmodel.cpp b/src/intent-server-lib/intentmodel.cpp
index 4342fc9f..f4b1a76a 100644
--- a/src/intent-server-lib/intentmodel.cpp
+++ b/src/intent-server-lib/intentmodel.cpp
@@ -56,7 +56,7 @@
/*!
\qmltype IntentModel
\inherits QSortFilterProxyModel
- \ingroup system-ui
+ \ingroup system-ui-instantiable
\inqmlmodule QtApplicationManager.SystemUI
\brief A proxy model for the IntentServer singleton.
diff --git a/src/launcher-lib/intentclientdbusimplementation.cpp b/src/launcher-lib/intentclientdbusimplementation.cpp
index 5da608a6..62d9d07c 100644
--- a/src/launcher-lib/intentclientdbusimplementation.cpp
+++ b/src/launcher-lib/intentclientdbusimplementation.cpp
@@ -43,11 +43,15 @@
#include <QDBusConnection>
#include <QDBusPendingReply>
#include <QDBusPendingCallWatcher>
+#include <QQmlEngine>
+#include <qqml.h>
+
#include "launchermain.h"
#include "dbus-utilities.h"
#include "intentclient.h"
#include "intentclientrequest.h"
#include "intentclientdbusimplementation.h"
+#include "intenthandler.h"
#include "intentinterface_interface.h"
@@ -68,6 +72,17 @@ void IntentClientDBusImplementation::initialize(IntentClient *intentClient) Q_DE
{
IntentClientSystemInterface::initialize(intentClient);
+ qmlRegisterSingletonType<IntentClient>("QtApplicationManager", 2, 0, "IntentClient",
+ [](QQmlEngine *, QJSEngine *) -> QObject * {
+ QQmlEngine::setObjectOwnership(IntentClient::instance(), QQmlEngine::CppOwnership);
+ return IntentClient::instance();
+ });
+
+ qmlRegisterUncreatableType<IntentClientRequest>("QtApplicationManager", 2, 0, "IntentRequest",
+ qSL("Cannot create objects of type IntentRequest"));
+ qmlRegisterType<IntentHandler>("QtApplicationManager.Application", 2, 0, "IntentHandler");
+
+
m_dbusInterface = new IoQtApplicationManagerIntentInterfaceInterface(
QString(), qSL("/IntentServer"), QDBusConnection(m_dbusName), intentClient);
@@ -82,7 +97,7 @@ void IntentClientDBusImplementation::initialize(IntentClient *intentClient) Q_DE
connect(m_dbusInterface, &IoQtApplicationManagerIntentInterfaceInterface::requestToApplication,
intentClient, [this](const QString &requestId, const QString &id,
const QString &applicationId, const QVariantMap &parameters) {
- emit requestToApplication(requestId, id, applicationId, convertFromDBusVariant(parameters).toMap());
+ emit requestToApplication(requestId, id, QString(), applicationId, convertFromDBusVariant(parameters).toMap());
});
}
diff --git a/src/manager-lib/applicationipcinterface.cpp b/src/manager-lib/applicationipcinterface.cpp
index a7083461..43a48172 100644
--- a/src/manager-lib/applicationipcinterface.cpp
+++ b/src/manager-lib/applicationipcinterface.cpp
@@ -64,7 +64,7 @@
/*!
\qmltype ApplicationIPCInterface
- \ingroup system-ui
+ \ingroup system-ui-instantiable
\inqmlmodule QtApplicationManager.SystemUI
\brief The definition of an IPC interface between the application manager and applications.
diff --git a/src/manager-lib/applicationmodel.cpp b/src/manager-lib/applicationmodel.cpp
index 4deed932..06434601 100644
--- a/src/manager-lib/applicationmodel.cpp
+++ b/src/manager-lib/applicationmodel.cpp
@@ -57,7 +57,7 @@
/*!
\qmltype ApplicationModel
\inherits QSortFilterProxyModel
- \ingroup system-ui
+ \ingroup system-ui-instantiable
\inqmlmodule QtApplicationManager.SystemUI
\brief A proxy model for the ApplicationManager singleton.
diff --git a/src/manager-lib/intentaminterface.cpp b/src/manager-lib/intentaminterface.cpp
index 52b8e5be..286ff661 100644
--- a/src/manager-lib/intentaminterface.cpp
+++ b/src/manager-lib/intentaminterface.cpp
@@ -56,6 +56,7 @@
#include <QQmlEngine>
#include <QQmlExpression>
#include <QQmlContext>
+#include <QQmlInfo>
#include "error.h"
#include "exception.h"
@@ -291,6 +292,18 @@ QString IntentClientAMImplementation::currentApplicationId(QObject *hint)
void IntentClientAMImplementation::initialize(IntentClient *intentClient) Q_DECL_NOEXCEPT_EXPR(false)
{
IntentClientSystemInterface::initialize(intentClient);
+
+ qmlRegisterSingletonType<IntentClient>("QtApplicationManager", 2, 0, "IntentClient",
+ [](QQmlEngine *, QJSEngine *) -> QObject * {
+ QQmlEngine::setObjectOwnership(IntentClient::instance(), QQmlEngine::CppOwnership);
+ return IntentClient::instance();
+ });
+
+ qmlRegisterUncreatableType<IntentClientRequest>("QtApplicationManager", 2, 0, "IntentRequest",
+ qSL("Cannot create objects of type IntentRequest"));
+ qmlRegisterType<IntentHandler>("QtApplicationManager.Application", 2, 0, "IntentHandler");
+
+ qmlRegisterType<IntentServerHandler>("QtApplicationManager.SystemUI", 2, 0, "IntentServerHandler");
}
void IntentClientAMImplementation::requestToSystem(QPointer<IntentClientRequest> icr)
@@ -422,6 +435,7 @@ void IntentServerInProcessIpcConnection::requestToApplication(IntentServerReques
QMetaObject::invokeMethod(this, [this, irs]() {
auto clientInterface = m_interface->intentClientSystemInterface();
emit clientInterface->requestToApplication(irs->requestId().toString(), irs->intentId(),
+ irs->requestingApplicationId(),
irs->handlingApplicationId(), irs->parameters());
}, Qt::QueuedConnection);
}
@@ -516,16 +530,15 @@ void IntentServerDBusIpcConnection::replyFromApplication(const QString &requestI
convertFromDBusVariant(result).toMap());
}
-
#endif // defined(AM_MULTI_PROCESS)
-QT_END_NAMESPACE_AM
-
// ^^^ IntentServerDBusIpcConnection ^^^
//////////////////////////////////////////////////////////////////////////
// vvv IntentInterfaceAdaptor vvv
+QT_END_NAMESPACE_AM
+
#if defined(AM_MULTI_PROCESS)
IntentInterfaceAdaptor::IntentInterfaceAdaptor(QObject *parent)
@@ -551,5 +564,208 @@ QString IntentInterfaceAdaptor::requestToSystem(const QString &intentId, const Q
#endif // defined(AM_MULTI_PROCESS)
+QT_BEGIN_NAMESPACE_AM
+
// ^^^ IntentInterfaceAdaptor ^^^
//////////////////////////////////////////////////////////////////////////
+// vvv IntentServerHandler vvv
+
+/*! \qmltype IntentServerHandler
+ \inqmlmodule QtApplicationManager.SystemUI
+ \ingroup system-ui-instantiable
+ \brief A handler for intent requests received within the system ui.
+
+ If intents need to be handled from within the system ui, you need to have a corresponding
+ IntentServerHandler instance that is actually able to handle incoming requests. This class gives
+ you the flexibility to handle multiple, different intent ids via a single IntentServerHandler
+ instance or have a dedicated IntentServerHandler instance for every intent id (or any
+ combination of those).
+
+ \note For handling intent requests within an application, you have to use the application side
+ component IntentHandler, which works the same way, but provides all the necessary
+ meta-data in the application's info.yaml manifest file.
+
+ For more information see IntentHandler and the description of the \l{manifest-intent}
+ {meta-data in the manifest documentation}.
+
+ Callbacks connected to the onRequestReceived signal have access to the sender's application ID.
+ Due to security restrictions, this is \b not the case for such handlers implemented in an
+ application context via IntentHandler.
+*/
+
+/*! \qmlproperty url IntentServerHandler::icon
+
+ The intent's icon - see the \l{manifest-intent}{manifest documentation} for more
+ details.
+
+ \note Any changes to this property after component completion will have no effect.
+*/
+/*! \qmlproperty object IntentServerHandler::names
+
+ The intent's name - see the \l{manifest-intent}{manifest documentation} for more
+ details.
+
+ \note Any changes to this property after component completion will have no effect.
+*/
+/*! \qmlproperty list<string> IntentServerHandler::categories
+
+ The intent's categories - see the \l{manifest-intent}{manifest documentation} for more
+ details.
+
+ \note Any changes to this property after component completion will have no effect.
+*/
+/*! \qmlproperty enum IntentServerHandler::visibility
+
+ The intent's visibility - see the \l{manifest-intent}{manifest documentation} for more
+ details.
+ Can be either \c IntentObject.Public or \c IntentObject.Private (the default).
+
+ \note Any changes to this property after component completion will have no effect.
+*/
+/*! \qmlproperty list<string> IntentServerHandler::requiredCapabilities
+
+ The intent's required capabilities - see the \l{manifest-intent}{manifest documentation} for
+ more details.
+
+ \note Any changes to this property after component completion will have no effect.
+*/
+/*! \qmlproperty object IntentServerHandler::parameterMatch
+
+ The intent's parameter requirements - see the \l{manifest-intent}{manifest documentation} for
+ more details.
+
+ \note Any changes to this property after component completion will have no effect.
+*/
+
+IntentServerHandler::IntentServerHandler(QObject *parent)
+ : IntentHandler(parent)
+ , m_intent(new Intent())
+{ }
+
+IntentServerHandler::~IntentServerHandler()
+{
+ IntentServer *is = IntentServer::instance();
+
+ for (const auto &intent : m_registeredIntents)
+ is->removeIntent(intent);
+
+ delete m_intent;
+}
+
+QUrl IntentServerHandler::icon() const
+{
+ return m_intent->icon();
+}
+
+QVariantMap IntentServerHandler::names() const
+{
+ return m_intent->names();
+}
+
+QStringList IntentServerHandler::categories() const
+{
+ return m_intent->categories();
+}
+
+Intent::Visibility IntentServerHandler::visibility() const
+{
+ return m_intent->visibility();
+}
+
+QStringList IntentServerHandler::requiredCapabilities() const
+{
+ return m_intent->requiredCapabilities();
+}
+
+QVariantMap IntentServerHandler::parameterMatch() const
+{
+ return m_intent->parameterMatch();
+}
+
+void IntentServerHandler::setIcon(const QUrl &icon)
+{
+ if (isComponentCompleted()) {
+ qmlWarning(this) << "Cannot change the icon property of an IntentServerHandler after creation.";
+ return;
+ }
+ m_intent->m_icon = icon;
+}
+
+void IntentServerHandler::setNames(const QVariantMap &names)
+{
+ if (isComponentCompleted()) {
+ qmlWarning(this) << "Cannot change the names property of an IntentServerHandler after creation.";
+ return;
+ }
+ m_intent->m_names = names;
+}
+
+void IntentServerHandler::setCategories(const QStringList &categories)
+{
+ if (isComponentCompleted()) {
+ qmlWarning(this) << "Cannot change the categories property of an IntentServerHandler after creation.";
+ return;
+ }
+ m_intent->m_categories = categories;
+}
+
+void IntentServerHandler::setVisibility(Intent::Visibility visibility)
+{
+ if (isComponentCompleted()) {
+ qmlWarning(this) << "Cannot change the visibility property of an IntentServerHandler after creation.";
+ return;
+ }
+ m_intent->m_visibility = visibility;
+}
+
+void IntentServerHandler::setRequiredCapabilities(const QStringList &requiredCapabilities)
+{
+ if (isComponentCompleted()) {
+ qmlWarning(this) << "Cannot change the requiredCapabilities property of an IntentServerHandler after creation.";
+ return;
+ }
+ m_intent->m_requiredCapabilities = requiredCapabilities;
+}
+
+void IntentServerHandler::setParameterMatch(const QVariantMap &parameterMatch)
+{
+ if (isComponentCompleted()) {
+ qmlWarning(this) << "Cannot change the parameterMatch property of an IntentServerHandler after creation.";
+ return;
+ }
+ m_intent->m_parameterMatch = parameterMatch;
+}
+
+void IntentServerHandler::componentComplete()
+{
+ if (QmlInProcessRuntime::determineRuntime(this)) {
+ qmlWarning(this) << "Using IntentServerHandler for handling events in an application "
+ "context does not work. Use IntentHandler instead";
+ return;
+ }
+
+ IntentServer *is = IntentServer::instance();
+ is->addPackage(sysUiId);
+ is->addApplication(sysUiId, sysUiId);
+
+ const auto ids = intentIds();
+ for (const auto &intentId : ids) {
+ // convert from QVariantMap to QMap<QString, QString>
+ QMap<QString, QString> names;
+ const auto qvm_names = m_intent->names();
+ for (auto it = qvm_names.cbegin(); it != qvm_names.cend(); ++it)
+ names.insert(it.key(), it.value().toString());
+
+ auto intent = is->addIntent(intentId, sysUiId, sysUiId, m_intent->requiredCapabilities(),
+ m_intent->visibility(), m_intent->parameterMatch(), names,
+ m_intent->icon(), m_intent->categories());
+ if (intent)
+ m_registeredIntents << intent;
+ else
+ qmlWarning(this) << "IntentServerHandler: could not add intent" << intentId;
+ }
+
+ IntentHandler::componentComplete();
+}
+
+QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/intentaminterface.h b/src/manager-lib/intentaminterface.h
index 49136b13..9f74a2fe 100644
--- a/src/manager-lib/intentaminterface.h
+++ b/src/manager-lib/intentaminterface.h
@@ -48,13 +48,16 @@
#include <QString>
#include <QVariantMap>
#include <QList>
+#include <QUrl>
#if defined(AM_MULTI_PROCESS)
# include <QDBusConnection>
# include <QDBusContext>
#endif
#include <QtAppManCommon/global.h>
#include <QtAppManIntentServer/intentserversysteminterface.h>
+#include <QtAppManIntentServer/intent.h>
#include <QtAppManIntentClient/intentclientsysteminterface.h>
+#include <QtAppManIntentClient/intenthandler.h>
#include <QtAppManApplication/intentinfo.h>
class IntentInterfaceAdaptor;
@@ -195,4 +198,49 @@ private:
#endif // defined(AM_MULTI_PROCESS)
+// server-side IntentHandlers
+class IntentServerHandler : public IntentHandler
+{
+ Q_OBJECT
+ Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/IntentServerHandler 2.0")
+
+ // the following properties cannot be changed after construction (hence, also no 'changed' signal)
+ // these replace the meta-data that's provided through the info.yaml manifests for client-side
+ // handlers
+ Q_PROPERTY(QUrl icon READ icon WRITE setIcon)
+ Q_PROPERTY(QVariantMap names READ names WRITE setNames)
+ Q_PROPERTY(QStringList categories READ categories WRITE setCategories)
+ Q_PROPERTY(QT_PREPEND_NAMESPACE_AM(Intent)::Visibility visibility READ visibility WRITE setVisibility)
+ Q_PROPERTY(QStringList requiredCapabilities READ requiredCapabilities WRITE setRequiredCapabilities)
+ Q_PROPERTY(QVariantMap parameterMatch READ parameterMatch WRITE setParameterMatch)
+
+public:
+ IntentServerHandler(QObject *parent = nullptr);
+ ~IntentServerHandler() override;
+
+ QUrl icon() const;
+ QVariantMap names() const;
+ QStringList categories() const;
+ Intent::Visibility visibility() const;
+ QStringList requiredCapabilities() const;
+ QVariantMap parameterMatch() const;
+
+public slots:
+ void setIcon(const QUrl &icon);
+ void setNames(const QVariantMap &names);
+ void setCategories(const QStringList &categories);
+ void setVisibility(Intent::Visibility visibility);
+ void setRequiredCapabilities(const QStringList &requiredCapabilities);
+ void setParameterMatch(const QVariantMap &parameterMatch);
+
+protected:
+ void componentComplete() override;
+
+private:
+ Q_DISABLE_COPY(IntentServerHandler)
+ Intent *m_intent = nullptr; // DRY: just a container for our otherwise needed members vars
+ QVector<Intent *> m_registeredIntents;
+ bool m_completed = false;
+};
+
QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/processstatus.cpp b/src/manager-lib/processstatus.cpp
index c49f3d6e..c16da4f1 100644
--- a/src/manager-lib/processstatus.cpp
+++ b/src/manager-lib/processstatus.cpp
@@ -56,7 +56,7 @@
/*!
\qmltype ProcessStatus
\inqmlmodule QtApplicationManager.SystemUI
- \ingroup system-ui
+ \ingroup system-ui-instantiable
\brief Provides information about the status of an application process.
ProcessStatus provides information about the process of a given application.
diff --git a/src/manager-lib/qmlinprocessapplicationinterface.cpp b/src/manager-lib/qmlinprocessapplicationinterface.cpp
index caceabe3..feb37ea3 100644
--- a/src/manager-lib/qmlinprocessapplicationinterface.cpp
+++ b/src/manager-lib/qmlinprocessapplicationinterface.cpp
@@ -42,6 +42,7 @@
#include <QQmlEngine>
#include <QQmlExpression>
+#include <QQmlInfo>
#include "logging.h"
#include "qmlinprocessapplicationinterface.h"
@@ -309,7 +310,7 @@ void QmlInProcessApplicationInterfaceExtension::setName(const QString &name)
m_name = name;
resolveObject();
} else {
- qWarning("Cannot change the name property of an ApplicationInterfaceExtension after creation.");
+ qmlWarning(this) << "Cannot change the name property of an ApplicationInterfaceExtension after creation.";
}
}
diff --git a/src/window-lib/windowitem.cpp b/src/window-lib/windowitem.cpp
index 7fb17f69..677360d3 100644
--- a/src/window-lib/windowitem.cpp
+++ b/src/window-lib/windowitem.cpp
@@ -62,7 +62,7 @@
/*!
\qmltype WindowItem
\inqmlmodule QtApplicationManager.SystemUI
- \ingroup system-ui
+ \ingroup system-ui-instantiable
\brief An Item that renders a given WindowObject.
To render a WindowObject inside the System UI, you must specify where and how it should be