diff options
Diffstat (limited to 'examples/applicationmanager/minidesk/doc/src/minidesk.qdoc')
-rw-r--r-- | examples/applicationmanager/minidesk/doc/src/minidesk.qdoc | 256 |
1 files changed, 256 insertions, 0 deletions
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. + +*/ |