diff options
author | Daniel d'Andrada <daniel.dandrada@luxoft.com> | 2018-07-10 14:40:25 +0200 |
---|---|---|
committer | Robert Griebl <robert.griebl@pelagicore.com> | 2018-07-11 11:57:12 +0000 |
commit | ba2a7ede9e1689c03099cd0ef619bc18cda29ef4 (patch) | |
tree | 043a0d1581988a56b5fd9956814defa774f3a031 /examples/applicationmanager/minidesk | |
parent | c414cb25d0cc2f7ce33e21e15ff52bc14d6421ad (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')
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 Binary files differnew file mode 100644 index 00000000..adb840ce --- /dev/null +++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.png 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 Binary files differnew file mode 100644 index 00000000..3f8caa42 --- /dev/null +++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.png 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 Binary files differnew file mode 100644 index 00000000..0a16982a --- /dev/null +++ b/examples/applicationmanager/minidesk/doc/images/minidesk.png 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", {}); + } +} |