1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2019 Luxoft Sweden AB
// Copyright (C) 2018 Pelagicore AG
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page howto-apps.html
\ingroup qtappman
\ingroup qtappman-highlights
\title Writing Applications
\brief Discusses writing an application to run as a client within the application manager.
Writing an application to run as a client within the application manager is similar to writing a
stand-alone QML application, except for these three additional tasks or limitations:
\list 1
\li If you write a QML application, make your QML scene's root element an
ApplicationManagerWindow; or derive your own custom root item from it.
\li Provide a valid \l{Manifest definition}{info.yaml} file.
\li Restart the application manager to make it aware of your application.
\endlist
\section2 The Root Element
It's recommended to use either an ApplicationManagerWindow or a QtObject as the root of your QML
application. This is especially important if you require similar behavior in single-process and
multi-process mode. If you use a QtObject, any visible base elements should still be
\l{ApplicationManagerWindow}{ApplicationManagerWindows}. Nevertheless, other root elements are
supported for convenience, as well.
Here are a few things to consider:
\list
\li Only \l{ApplicationManagerWindow}{ApplicationManagerWindows} support window properties
that are shared between the System UI and the client applications.
\li In multi-process mode, \l Window root elements always get a decoration (unless you set
QT_WAYLAND_DISABLE_WINDOWDECORATION) and are invisible by default. QQuick
\l{Item}{Items} are wrapped inside a \l Window representing a Wayland client window.
\li In single-process mode \l Window root elements appear parallel to instead of inside the
System UI.
\endlist
\section2 The Manifest and Updating the Database
The \l{Manifest Definition} has all the information you need to produce a minimal \c info.yaml
file.
Finding and and parsing \c info.yaml files recursively, for potentially hundreds of applications
can be a very time consuming task and would severely slow down the application manager's startup.
Therefore, all manifest files are cached in a binary database. To notify the application manager
about changes to an \c info.yaml file, you have to force a rebuild of this database by calling
\c{appman --recreate-database}.
\note Dynamically adding, updating, or removing individual applications is supported via the
ApplicationInstaller interface.
\section2 qmake Integration
To install applications into a System UI using the \l{Installer}{Installer Sub-System}, the
application needs to be packaged first. This can be done using the \l{Packager} utility. To better
integrate the packaging into your usual developer workflow you can also use the qmake integration
provided.
The integration adds an additional \c{package} target to the Makefile. You can create a new
application in one of two ways:
\list
\li Call \c{make package} on the command line.
\li Add \c{make package} as an additional build step in QtCreator.
\endlist
\section3 Simple QML Applications
For simple QML-only applications, create a qmake project file which defines an install step for all
the needed files. The actual install location doesn't matter in this case, because it is used as a
temporary path when the package is being created.
\code
TEMPLATE = aux
FILES += info.yaml \
icon.png \
Main.qml
app.files = $$FILES
app.path = /apps/com.example.application
INSTALLS += app
\endcode
In addition add the following two lines to provide the install location to the packaging step and
to load the qmake integration.
\code
AM_PACKAGE_DIR = $$app.path
load(am-app)
\endcode
\section3 Complex Applications
For complex applications, where you need to deploy a C++ based QML plugin in addition to your QML
content, you must split your app into multiple folders and project files. One folder for the QML
part, another one for the C++ plugin, and a \c SUBDIRS project to glue them together.
The packaging integration is done in the \c SUBDIRS project and this process expects that the other
project files provide install targets to a shared install location. In this case, the QML part
installs its files in \c{/apps/com.example.application}, while the C++ plugin installs in
\c{/apps/com.example.application/imports/com/example/application}.
In the \c SUBDIRS project you need to define the \c AM_MANIFEST variable and set it to the location
of your \c info.yaml file. Then, define the shared install location as \c AM_PACKAGE_DIR:
\code
AM_MANIFEST = $$PWD/app/info.yaml
AM_PACKAGE_DIR = /apps/com.example.application
load(am-app)
\endcode
\section3 Package Multiple Applications
If your repository provides multiple applications, like the
\l{http://code.qt.io/cgit/qt-apps/qt-auto-extra-apps.git/}{Qt Auto Extra Apps Repository}, you can
use qmake's am-package feature to provide a repository-wide \c{package} step.
Add a \c{.qmake.conf} file with the following content to your repository, which is loaded
automatically by qmake:
\code
CONFIG += am-package
\endcode
*/
|