// 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 \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 \section1 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 \section1 The Manifest The \l{Manifest Definition} has all the information you need to produce a minimal \c info.yaml file. Finding 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. The application manager automatically detects when a manifest has changed and updates the cache accordingly, but you can also force a rebuild of this database by calling \c{appman --clear-cache}. \note Dynamically adding, updating, or removing individual applications is supported via the PackageManager interface. \section1 CMake Integration The Application Manager CMake integration provides two functions to add applications to the build system: \list 1 \li \c{qt_am_create_builtin_package} for builtin packages \li \c{qt_am_create_installable_package} for dynamically installable packages \endlist \section2 Builtin Packages Builtin packages are applications that are built into the System UI and are always available. They are defined in the System UI's am-config.yaml file using the \c applications/builtinAppsManifestDir. The \c{qt_am_create_builtin_package} function is mainly used to provide a good QtCreator integration, as it provides a Run Target for every application added this way. This makes it easier to start, stop, debug and profile applications. In addition this function manages installable files: it copies them to the build directory when necessary and also provides a CMake install target. A simple builtin application could look like this: \code qt_am_create_builtin_package(myapp FILES apps/myapp/info.yaml apps/myapp/icon.png apps/myapp/main.qml ) \endcode See the \l {System UI Example: "Hello World!"}{Hello World!} example for a complete example. \section2 Installable Packages Installable packages are applications that can be installed into the System UI at runtime. Similar to built-in packages, the \c{qt_am_create_installable_package} function is used to provide run targets in QtCreator, but it also adds additional targets to create installable packages which can be installed into the System UI at runtime. A simple installable application could look like this: \code qt_am_create_installable_package(myapp OUTPUT_DIRECTORY apps/myapp FILES apps/myapp/info.yaml apps/myapp/icon.png apps/myapp/main.qml ) \endcode See the \l {Package Installation Example}} for a complete example. \section2 Using the QML script compiler in Applications The QML script compiler is a tool that compiles QML files into binary files and makes the code more efficient. It is used behind the scenes if you are using the \l{qt_add_qml_module} function to specify a QML module. Such a module can also be used in applications by doing the following modifications: Build the module using \l{qt_add_qml_module} and add it as dependency to the application: \code qt_add_qml_module(mymodule URI com.example.mymodule VERSION 1.0 QML_FILES MyItem.qml ) qt_am_create_builtin_package(myapp FILES apps/myapp/info.yaml apps/myapp/icon.png apps/myapp/main.qml DEPENDENCIES mymodule ) Load the module library file instead of the application's QML file in the info.yaml file: \code runtimeParameters: resources: [ "libmymodule.so" ] \endcode \note This works for installable packages in a similar fashion. See the \l {Application Features Example} for a complete example of a builtin package and the \l {Package Installation Example} for a complete example of an installable package. */