summaryrefslogtreecommitdiffstats
path: root/examples/applicationmanager/minidesk
diff options
context:
space:
mode:
authorDaniel d'Andrada <daniel.dandrada@luxoft.com>2018-07-10 14:40:25 +0200
committerRobert Griebl <robert.griebl@pelagicore.com>2018-07-11 11:57:12 +0000
commitba2a7ede9e1689c03099cd0ef619bc18cda29ef4 (patch)
tree043a0d1581988a56b5fd9956814defa774f3a031 /examples/applicationmanager/minidesk
parentc414cb25d0cc2f7ce33e21e15ff52bc14d6421ad (diff)
Fix installation of the examples
- Only the project files and wrapper scripts were being installed - They were being put directly into Qt's example dir. They should be grouped into a applicationmanager subdirectory there, similarly to what other modules do. Task-number: AUTOSUITE-591 Change-Id: I1da6b28a8fe2e9210ad109309d30dfc1ad0d1e99 Reviewed-by: Robert Griebl <robert.griebl@pelagicore.com>
Diffstat (limited to 'examples/applicationmanager/minidesk')
-rw-r--r--examples/applicationmanager/minidesk/am-config.yaml37
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml101
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.pngbin0 -> 5138 bytes
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml9
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml94
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.pngbin0 -> 5597 bytes
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml9
-rw-r--r--examples/applicationmanager/minidesk/doc/images/minidesk.pngbin0 -> 96692 bytes
-rw-r--r--examples/applicationmanager/minidesk/doc/src/minidesk.qdoc256
-rw-r--r--examples/applicationmanager/minidesk/minidesk.pro27
-rw-r--r--examples/applicationmanager/minidesk/minidesk.qmlproject17
-rw-r--r--examples/applicationmanager/minidesk/system-ui/Readme.qml91
-rw-r--r--examples/applicationmanager/minidesk/system-ui/main.qml238
13 files changed, 879 insertions, 0 deletions
diff --git a/examples/applicationmanager/minidesk/am-config.yaml b/examples/applicationmanager/minidesk/am-config.yaml
new file mode 100644
index 00000000..269e20c7
--- /dev/null
+++ b/examples/applicationmanager/minidesk/am-config.yaml
@@ -0,0 +1,37 @@
+formatVersion: 1
+formatType: am-configuration
+---
+installationLocations:
+- id: "internal-0"
+ installationPath: "/tmp/minidesk/apps"
+ documentPath: "/tmp/minidesk/docs"
+ mountPoint: "/tmp"
+ isDefault: true
+
+applications:
+ builtinAppsManifestDir: "${CONFIG_PWD}/apps"
+ installedAppsManifestDir: "/tmp/minidesk/manifests"
+ appImageMountDir: "/tmp/minidesk/image-mounts"
+ database: "/tmp/minidesk/apps.db"
+
+logging:
+ rules:
+ - "*=false"
+ - "qt.*=false"
+ - "am.*=false"
+ - "qml*=true"
+ - "*.warning=true"
+ - "*.critical=true"
+
+ui:
+ fullscreen: no
+ mainQml: "${CONFIG_PWD}/system-ui/main.qml"
+
+systemProperties:
+ protected:
+ light: on
+
+# development setup:
+flags:
+ noSecurity: yes
+ noUiWatchdog: yes
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml
new file mode 100644
index 00000000..76ab5dc0
--- /dev/null
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtApplicationManager 1.0
+
+ApplicationManagerWindow {
+ id: root
+ color: "peachpuff"
+
+ Rectangle {
+ anchors.centerIn: parent
+ width: 180; height: 180; radius: width/4
+ color: "peru"
+
+ Image {
+ source: ApplicationInterface.icon
+ anchors.centerIn: parent
+ }
+
+ RotationAnimation on rotation {
+ id: rotation
+ from: 0; to: 360; loops: Animation.Infinite; duration: 4000
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (rotation.paused) {
+ rotation.resume();
+ } else {
+ rotation.pause();
+ root.setWindowProperty("rotation", parent.rotation);
+ }
+ popUp.visible = rotation.paused;
+ }
+ }
+ }
+
+ ApplicationManagerWindow {
+ id: popUp
+ visible: false
+ color: "lightcoral"
+
+ Text {
+ anchors.centerIn: parent
+ text: "App1 paused!"
+ }
+
+ Component.onCompleted: setWindowProperty("type", "pop-up");
+ }
+}
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.png b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.png
new file mode 100644
index 00000000..adb840ce
--- /dev/null
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.png
Binary files differ
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml
new file mode 100644
index 00000000..953e852f
--- /dev/null
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml
@@ -0,0 +1,9 @@
+formatVersion: 1
+formatType: am-application
+---
+id: 'tld.minidesk.app1'
+icon: 'icon.png'
+code: 'app1.qml'
+runtime: 'qml'
+name:
+ en: 'App1'
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml
new file mode 100644
index 00000000..88b1f745
--- /dev/null
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtApplicationManager 1.0
+
+ApplicationManagerWindow {
+ color: ApplicationInterface.systemProperties.light ? "peachpuff" : "black"
+
+ Image {
+ anchors.centerIn: parent
+ source: ApplicationInterface.icon
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ var notification = ApplicationInterface.createNotification();
+ notification.summary = "Let there be light!"
+ notification.show();
+ }
+ }
+ }
+
+ onWindowPropertyChanged: console.log("App2: onWindowPropertyChanged - " + name + ": " + value);
+
+ Connections {
+ target: ApplicationInterface
+ onOpenDocument: console.log("App2: onOpenDocument - " + documentUrl);
+ onQuit: target.acknowledgeQuit();
+ }
+
+ ApplicationInterfaceExtension {
+ id: extension
+ name: "tld.minidesk.interface"
+
+ onReadyChanged: console.log("App2: circumference function returned: "
+ + object.circumference(2.0, "plate") + ", it used pi = " + object.pi);
+ }
+
+ Connections {
+ target: extension.object
+ onComputed: console.log("App2: " + what + " has been computed");
+ onPiChanged: console.log("App2: pi changed: " + target.pi);
+ }
+}
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.png b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.png
new file mode 100644
index 00000000..3f8caa42
--- /dev/null
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.png
Binary files differ
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml
new file mode 100644
index 00000000..65759aa8
--- /dev/null
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml
@@ -0,0 +1,9 @@
+formatVersion: 1
+formatType: am-application
+---
+id: 'tld.minidesk.app2'
+icon: 'icon.png'
+code: 'app2.qml'
+runtime: 'qml'
+name:
+ en: 'App2'
diff --git a/examples/applicationmanager/minidesk/doc/images/minidesk.png b/examples/applicationmanager/minidesk/doc/images/minidesk.png
new file mode 100644
index 00000000..0a16982a
--- /dev/null
+++ b/examples/applicationmanager/minidesk/doc/images/minidesk.png
Binary files differ
diff --git a/examples/applicationmanager/minidesk/doc/src/minidesk.qdoc b/examples/applicationmanager/minidesk/doc/src/minidesk.qdoc
new file mode 100644
index 00000000..ad85c36e
--- /dev/null
+++ b/examples/applicationmanager/minidesk/doc/src/minidesk.qdoc
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:FDL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+
+\example minidesk
+\title Desktop System-UI Example
+\image minidesk.png Screenshot
+\brief Minimal Desktop System-UI in pure QML
+\ingroup applicationmanager-examples
+
+\section1 Introduction
+
+The \e {Desktop System-UI Example} showcases the application-manager API in a simple fashion. The
+focus is on the concepts, less on elegance or completeness, for instance no error checking is done.
+Some features will only print debug messages without further functionality. A classic desktop with
+server-side window decorations is emulated.
+
+The following features are supported:
+\list
+\li Start applications by clicking an icon on the top left
+\li Stop applications by clicking on the top/left window decoration rectangle
+\li Raise applications by clicking on the decoration
+\li Drag windows by pressing on the window decoration and moving
+\li System-UI sends 'propA' change when an app is started
+\li System-UI and App2 react on window property changes with a debug message
+\li App1 animation can be stopped and restarted by a click
+\li App1 sends 'rotation' property to System-UI on stop
+\li App1 shows a pop-up on the System-UI while it is paused
+\li App2 will make use of an IPC extension when it is started
+\li App2 logs the document URL it has been started with
+\li App2 triggers a notification in the System-UI when the bulb icon is clicked
+\li A separate (\"wayland\") process started outside of appman will be shown as App1
+\endlist
+
+\note The example can be run in single- and multi-process mode. In the following, multi-process is
+assumed and corresponding terminology is used. The terms \e client and \e application, respectively
+\e server and \e {System-UI} are used interchangeably. The System-UI comprises compositing and
+generic inter-process communication (IPC).
+
+\section2 Invocation
+The example can be started from within the minidesk folder with:
+\badcode
+path/to/bin/appman -c am-config.yaml -r
+\endcode
+
+\note The application-manager attempts to register a \c freedesktop.org compliant notification
+server. DBus errors might occur if it conflicts with the server running on the host desktop
+environment. In this case, a private session bus needs to be started by adding the
+\c --start-session-dbus option:
+\badcode
+path/to/bin/appman -c am-config.yaml -r --start-session-dbus
+\endcode
+
+\section1 Walkthrough
+
+\section2 System-UI Window
+
+\quotefromfile minidesk/system-ui/main.qml
+\skipto import Qt
+\printuntil text:
+\printline }
+\dots
+
+The \l{QtApplicationManager} module has to be imported to be able to access the application-manager
+APIs. The System-UI window has a fixed size and linen background color. Instead of a \l{Rectangle},
+the root element could as well be a \l{Window}. On top of the background the
+\l{minidesk/system-ui/Readme.qml}{Readme} element is shown that displays a usage how-to. At the
+bottom left there is a textual indication for whether the application-manager runs in single- or
+multi-process mode.
+
+\section2 Launcher
+
+\printto System-UI chrome for applications
+
+A \l{Repeater} provides the application icons arranged in a \l{Column} on the top-left corner of
+the System-UI. This is achieved by using the \l{ApplicationManager} element as the model. Amongst
+others, it provides the \c icon role which is used as the \l{Image} source URL. The \c icon URL is
+defined in the \l{Manifest Definition}{info.yaml} file of the application. To indicate that an
+application has been launched, the opacity of the corresponding application's icon is decreased
+through a binding to the \c isRunning role.
+
+Clicking on an application icon will launch the corresponding application through a call to
+\l {ApplicationManager::startApplication()}{ApplicationManager.startApplication()}. The first
+argument, \c applicationId, is provided by the ApplicationManager model (e.g. "tld.minidesk.app1"
+for the first application). Both applications will be started with the (optional) document URL
+"documentUrl". Subsequent clicks on an already launched icon will still call
+\l{ApplicationManager::}{startApplication()}, but will be silently ignored. The content of the
+\c appContainter will be set below in the \c onWindowReady handler. The content is provided by the
+two applications in an \l{ApplicationManagerWindow} root element.
+
+\section2 Application Windows in the System-UI
+
+\printto System-UI for a pop-up and notification
+
+This second \l{Repeater} provides the window chrome for the actual applications in its delegate.
+The model is the same as for the first \l{Repeater}, essentially the \l{ApplicationManager}
+element. The chrome consists of:
+\list
+\li A fixed size window \l{Rectangle} with a "tan" color. The default location depends on the
+ \c model.index, hence each application has a different location.
+\li The name of the application, prefixed with "Decoration" on the top horizontal center. The name
+ is also provided by the \l{ApplicationManager} model and read from the application's
+ \l{Manifest Definition}{info.yaml} file.
+\li A \l{MouseArea} for dragging the window and setting the z-order. The \l{MouseArea} fills the
+ entire window, though the application container is placed on top of it and hence it will not
+ handle dragging. Simply increasing the z-order on each click is only done to keep the code to
+ a minimum.
+\li A small chocolate-colored \l Rectangle on the top left corner for closing the window chrome and
+ stopping the actual application (see
+ \l{ApplicationManager::stopApplication()}{stopApplication()}).
+\li A container \l{Item} where the actual application will be placed in. The \c appContainer is
+ exposed, so it can later be referenced to place the actual application window in it.
+\endlist
+
+\section2 Pop-ups
+
+Two approaches are implemented to display pop-ups in the System-UI:
+\list
+\li Through a window rendered by the client application
+\li Through the notification API provided by the application-manager
+\endlist
+This is the corresponding System-UI code:
+\printto Handler for WindowManager signals
+
+\section3 Client Application Rendering
+The \c popUpContainer \l{Item} provides a System-UI recipient for the pop-up rendered
+by App1. App1 instantiates another \l{ApplicationManagerWindow} for the pop-up within its
+\l{ApplicationManagerWindow} root element, as shown here:
+\quotefromfile minidesk/apps/tld.minidesk.app1/app1.qml
+\skipto Rectangle
+\skipto ApplicationManagerWindow
+\printuntil Component.onCompleted
+\printline }
+The \l{ApplicationManagerWindow::setWindowProperty}{ApplicationManagerWindow.setWindowProperty()}
+method is used to set a freely selectable shared property. Here we choose \c{type: "pop-up"} to
+indicate that the window is supposed to be shown as a pop-up. In the \c onWindowReady handler below
+the System-UI checks for this property and handles the window appropriately as a pop-up.
+
+\section3 Notification API Usage
+
+An alternative to the above approach is to use the application-manager's \l{Notification} API on
+the application (client) side and the \l{NotificationManager} API on the System-UI (server) side.
+The following code is invoked when the \e bulb icon of App2 is clicked:
+
+\quotefromfile minidesk/apps/tld.minidesk.app2/app2.qml
+\skipto var notification
+\printuntil notification.show();
+
+App2 creates a new \l{Notification} element, sets its \l{Notification::summary}{summary} property
+and calls \l{Notification::show()}{show()} on it. This call will increase the
+\l{NotificationManager::count}{NotificationManager.count} on the System-UI side, and subsequently
+the \l{Text} element's text property will be set to the \c summary string of the first
+notification. Presenting the first notification only is a simplification to keep the code short.
+
+\section2 WindowManager Signal Handler
+
+\quotefromfile minidesk/system-ui/main.qml
+\skipto Handler for WindowManager signals
+\printto IPC extension
+This is the vital part of the System-UI, where the window surfaces of the applications are mapped
+to items in the System-UI. The \l {WindowManager::windowReady}{onWindowReady} handler is invoked
+when a new application window is shown (visibility set to true). The \c index parameter references
+into the \l{WindowManager} model, which holds the window surfaces. The first line translates this
+index to the application index of the \l{ApplicationManager} model and assigns it to \c appIndex.
+
+Only the "pop-up" ApplicationManagerWindow of App1 has the user-defined \c type property set. All
+other windows don't have the \c type property. In the latter case, the application's \c window
+passed to \c onWindowReady is re-parented to the System-UI's \c winChrome. Also the size of the
+window is set to fill the entire \c appContainer.
+
+There is a special treatment for an invalid \c appIndex for demonstration purposes: it is assumed
+that the window surface is from an external application that follows the Wayland protocol. For
+example a Qt application could be started on the command line as follows:
+
+\badcode
+QT_WAYLAND_DISABLE_WINDOWDECORATION=1 ./qtapp -platform wayland
+\endcode
+
+This application will then be shown inside the App1 container.
+\c QT_WAYLAND_DISABLE_WINDOWDECORATION is set to disable client side window decorations, since they
+are provided by the System-UI. Note, that an application started in this way, can just as well be
+closed only from the command line.
+
+Pop-ups (windows with type "pop-up") are re-parented to their respective \c popUpContainer.
+
+The \c onWindowClosing handler determines if the window is a top-level application window. If so,
+the applications's \c winChrome is set to invisible and the corresponding application icon is set
+to fully opaque to indicate that the application is not running. The \c onWindowLost handler calls
+\l{WindowManager::releaseWindow()}{WindowManager.releaseWindow()} to free all resources associated
+with the \c window.
+
+
+\section2 IPC Extension
+The following snippet demonstrates how the \l{ApplicationIPCInterface} can be used to define an IPC
+extension. The IPC interface has to be defined in the System-UI, for instance:
+\printuntil Component.onCompleted
+\printline }
+
+Here, a property \c pi is defined, as well as a signal \c computed and a function \c circumference.
+After registering this interface with
+\l{ApplicationIPCManager::registerInterface()}{ApplicationIPCManager.registerInterface()}, it can
+be used from the application processes.
+
+On the application side, the \l{ApplicationInterfaceExtension} type has to be used. Here is how
+App2 makes use of this interface extension:
+
+\quotefromfile minidesk/apps/tld.minidesk.app2/app2.qml
+\skipto ApplicationInterfaceExtension
+\printuntil onPiChanged
+\printline }
+
+The interface is used here immediately when it becomes ready. It can, of course, be accessed from
+elsewhere, too. The \l{ApplicationInterfaceExtension::name}{ApplicationInterfaceExtension.name} has
+to match the name it was registered with in
+\l{ApplicationIPCManager::registerInterface()}{ApplicationIPCManager.registerInterface()}.
+
+\section2 Application Termination
+When an application is stopped from the System-UI through
+\l{ApplicationManager::stopApplication()}{ApplicationManager.stopApplication()}, it will be sent
+the \l{ApplicationInterface::quit()}{ApplicationInterface.quit()} signal. The application can do
+some clean-up and must subsequently confirm with
+\l{ApplicationInterface::acknowledgeQuit()}{ApplicationInterface.acknowledgeQuit()}, like App2 does:
+\quotefromfile minidesk/apps/tld.minidesk.app2/app2.qml
+\skipto Connections
+\printuntil onQuit
+\printline }
+
+Note that App1 is not well-behaved: it does not acknowledge the \c quit signal and will hence simply
+be terminated by the application-manager.
+
+*/
diff --git a/examples/applicationmanager/minidesk/minidesk.pro b/examples/applicationmanager/minidesk/minidesk.pro
new file mode 100644
index 00000000..d12a6917
--- /dev/null
+++ b/examples/applicationmanager/minidesk/minidesk.pro
@@ -0,0 +1,27 @@
+TEMPLATE = app
+CONFIG += am-systemui
+
+OTHER_FILES += \
+ am-config.yaml \
+ minidesk.qmlproject \
+ doc/src/*.qdoc \
+ doc/images/*.png \
+ system-ui/*.qml \
+ apps/tld.minidesk.app1/*.yaml \
+ apps/tld.minidesk.app1/*.qml \
+ apps/tld.minidesk.app1/*.png \
+ apps/tld.minidesk.app2/*.yaml \
+ apps/tld.minidesk.app2/*.qml \
+ apps/tld.minidesk.app2/*.png \
+
+target.path = $$[QT_INSTALL_EXAMPLES]/applicationmanager/minidesk
+INSTALLS += target
+
+AM_COPY_DIRECTORIES += apps system-ui
+AM_COPY_FILES += am-config.yaml
+
+AM_DEFAULT_ARGS=-c am-config.yaml --start-session-dbus --verbose
+
+example_sources.path = $$target.path
+example_sources.files = $$AM_COPY_FILES $$AM_COPY_DIRECTORIES doc
+INSTALLS += example_sources
diff --git a/examples/applicationmanager/minidesk/minidesk.qmlproject b/examples/applicationmanager/minidesk/minidesk.qmlproject
new file mode 100644
index 00000000..5ce6345e
--- /dev/null
+++ b/examples/applicationmanager/minidesk/minidesk.qmlproject
@@ -0,0 +1,17 @@
+import QmlProject 1.1
+
+Project {
+ mainFile: "system-ui/main.qml"
+
+ QmlFiles {
+ directory: "."
+ }
+ ImageFiles {
+ directory: "apps"
+ }
+ Files {
+ directory: "."
+ filter: "*.yaml"
+ }
+}
+
diff --git a/examples/applicationmanager/minidesk/system-ui/Readme.qml b/examples/applicationmanager/minidesk/system-ui/Readme.qml
new file mode 100644
index 00000000..01144436
--- /dev/null
+++ b/examples/applicationmanager/minidesk/system-ui/Readme.qml
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+import QtQuick 2.4
+
+Item {
+ anchors.fill: parent
+
+ Column {
+ width: paragraph.implicitWidth
+ height: heading.implicitHeight + paragraph.implicitHeight + 80
+ anchors.centerIn: parent
+ spacing: 10
+
+ Text {
+ id: heading
+ color: "cornflowerblue"
+ font { pixelSize: 20; weight: Font.Bold }
+ text: "Minimal Desktop System-UI in pure QML"
+ }
+
+ Text {
+ id: paragraph
+ color: "grey"
+ font.pixelSize: 16
+ text: "The following features are supported:\n" +
+ "\u2022 Start applications by clicking an icon on the top left\n" +
+ "\u2022 Stop applications by clicking on the top/left window decoration rectangle\n" +
+ "\u2022 Raise applications by clicking on the decoration\n" +
+ "\u2022 Drag windows by pressing on the window decoration and moving\n" +
+ "\u2022 System-UI sends 'propA' change when an app is started\n" +
+ "\u2022 System-UI and App2 react on window property changes with a debug message\n" +
+ "\u2022 App1 animation can be stopped and restarted by a click\n" +
+ "\u2022 App1 sends 'rotation' property to System-UI on stop\n" +
+ "\u2022 App1 shows a pop-up on the System-UI while it is paused\n" +
+ "\u2022 App2 will make use of an IPC extension when it is started\n" +
+ "\u2022 App2 logs the document URL it has been started with\n" +
+ "\u2022 App2 triggers a notification in the System-UI when the bulb icon is clicked\n" +
+ "\u2022 A separate (\"wayland\") process started outside of appman will be shown as App1"
+ }
+ }
+}
diff --git a/examples/applicationmanager/minidesk/system-ui/main.qml b/examples/applicationmanager/minidesk/system-ui/main.qml
new file mode 100644
index 00000000..1ba08ddc
--- /dev/null
+++ b/examples/applicationmanager/minidesk/system-ui/main.qml
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:BSD-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: BSD-3-Clause
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtApplicationManager 1.0
+
+Rectangle {
+ width: 1024
+ height: 640
+ color: "linen"
+
+ Readme {}
+
+ Text {
+ anchors.bottom: parent.bottom
+ text: (ApplicationManager.singleProcess ? "Single" : "Multi") + "-Process Mode"
+ }
+
+ // Application launcher panel
+ Column {
+ id: launcher
+ Repeater {
+ id: menuItems
+ model: ApplicationManager
+
+ Image {
+ source: icon
+ opacity: isRunning ? 0.3 : 1.0
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: application.start();
+ }
+ }
+ }
+ }
+
+ // System-UI chrome for applications
+ Repeater {
+ model: ListModel { id: topLevelWindowsModel }
+
+ delegate: Rectangle {
+ id: winChrome
+
+ width: 400; height: 320
+ z: model.index
+ color: "tan"
+
+ property bool manuallyClosed: false
+
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: "Decoration: " + model.window.application.name("en")
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ drag.target: parent
+ onPressed: topLevelWindowsModel.move(model.index, topLevelWindowsModel.count-1, 1);
+ }
+
+ Rectangle {
+ width: 25; height: 25
+ color: "chocolate"
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ winChrome.manuallyClosed = true;
+ model.window.application.stop();
+ }
+ }
+ }
+
+ WindowItem {
+ anchors.fill: parent
+ anchors.margins: 3
+ anchors.topMargin: 25
+ window: model.window
+ }
+
+ Component.onCompleted: {
+ winChrome.x = 300 + model.index * 50;
+ winChrome.y = 10 + model.index * 30;
+ }
+
+ states: [
+ State {
+ name: "open"
+ when: model.window && model.window.contentState === WindowObject.SurfaceWithContent && !manuallyClosed
+ PropertyChanges {
+ target: winChrome
+ opacity: 1
+ scale: 1
+ visible: true
+ }
+ }
+ ]
+
+ opacity: 0.25
+ scale: 0.50
+ visible: false
+
+ transitions: [
+ Transition {
+ to: "open"
+ NumberAnimation { target: winChrome; properties: "opacity,scale"; duration: 500; easing.type: Easing.OutQuad}
+ },
+ Transition {
+ from: "open"
+ SequentialAnimation {
+ PropertyAction { target: winChrome; property: "visible"; value: true } // we wanna see the window during the closing animation
+ NumberAnimation { target: winChrome; properties: "opacity,scale"; duration: 500; easing.type: Easing.InQuad}
+ ScriptAction { script: {
+ if (model.window.contentState === WindowObject.NoSurface)
+ topLevelWindowsModel.remove(model.index, 1);
+ } }
+ }
+ }
+ ]
+ }
+ }
+
+ // System-UI for pop-ups
+ Repeater {
+ model: ListModel { id: popupsModel }
+ delegate: WindowItem {
+ z: 100 + model.index
+ width: 200; height: 60
+ anchors.centerIn: parent
+ window: model.window
+ Connections {
+ target: model.window
+ onContentStateChanged: {
+ if (model.window.contentState === WindowObject.NoSurface)
+ popupsModel.remove(model.index, 1);
+ }
+ }
+ Rectangle {
+ width: 25
+ height: 25
+ anchors.horizontalCenter: parent.right
+ anchors.verticalCenter: parent.top
+ color: "chocolate"
+ Text { text: "X"; anchors.centerIn: parent }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: model.window.close()
+ }
+ }
+ }
+ }
+
+ // System-UI for a notification
+ Text {
+ z: 30001
+ font.pixelSize: 46
+ anchors.centerIn: parent
+ text: NotificationManager.count > 0 ? NotificationManager.get(0).summary : ""
+ }
+
+ // Handler for WindowManager signals
+ Connections {
+ target: WindowManager
+ onWindowAdded: {
+ // separate windows by their type, adding them to their respective model
+ var model = window.windowProperty("type") === "pop-up" ? popupsModel : topLevelWindowsModel;
+ model.append({"window":window});
+ }
+ }
+
+ // IPC extension
+ ApplicationIPCInterface {
+ id: extension
+
+ property double pi
+ signal computed(string what)
+ readonly property var _decltype_circumference: { "double": [ "double", "string" ] }
+ function circumference(radius, thing) {
+ console.log("SystemUI: circumference(" + radius + ", \"" + thing + "\") has been called");
+ pi = 3.14;
+ var circ = 2 * pi * radius;
+ computed("circumference for " + thing);
+ return circ;
+ }
+
+ Component.onCompleted: ApplicationIPCManager.registerInterface(extension, "tld.minidesk.interface", {});
+ }
+}