summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2021-05-11 12:44:34 +0200
committerPaul Olav Tvete <paul.tvete@qt.io>2021-08-13 14:34:56 +0200
commitea929b6fa5a90602e6f1fb597e3edfed9e6de3a7 (patch)
treef43077aca5e1c42f5688378d0902ef8e3c4cb7e3 /examples
parent12401c6f116f26e38182c90dc6920e4610f0e90d (diff)
doc: Expand documentation of Pure QML example
Add details about what customizations are specific to this example. Task-number: QTBUG-91674 Change-Id: Icf2dd4fb2bcbd230bbadbb01e5a57f481ad178eb Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/wayland/pure-qml/doc/src/pure-qml.qdoc101
-rw-r--r--examples/wayland/pure-qml/qml/Chrome.qml28
-rw-r--r--examples/wayland/pure-qml/qml/CompositorScreen.qml6
-rw-r--r--examples/wayland/pure-qml/qml/Keyboard.qml2
-rw-r--r--examples/wayland/pure-qml/qml/main.qml4
5 files changed, 126 insertions, 15 deletions
diff --git a/examples/wayland/pure-qml/doc/src/pure-qml.qdoc b/examples/wayland/pure-qml/doc/src/pure-qml.qdoc
index 06a938bed..90aa9d1d5 100644
--- a/examples/wayland/pure-qml/doc/src/pure-qml.qdoc
+++ b/examples/wayland/pure-qml/doc/src/pure-qml.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -31,6 +31,101 @@
\brief Pure QML is an example that demonstrates how to write a Wayland compositor in pure QML.
\ingroup qtwaylandcompositor-examples
- Pure QML is a small desktop-style Wayland compositor example that demonstrates the power and ease
- of the Qt Wayland Compositor QML APIs.
+ \section1 Introduction
+
+ Pure QML is a small desktop-style Wayland compositor example that demonstrates the power and
+ ease of the \l{Qt Wayland Compositor} QML APIs.
+
+ The Pure QML example is similar to the
+ \l{Qt Wayland Compositor Examples - Minimal QML}{Minimal QML example}, in that it is a
+ full-blown Wayland compositor, implemented only using QML code.
+
+ \section1 Initializing the Compositor
+
+ Like the \l{Qt Wayland Compositor Examples - Minimal QML}{Minimal QML example}, Pure QML
+ supports the main \l{Shell Extensions - Qt Wayland Compositor}{shell extensions} that are
+ supported by Qt.
+
+ \snippet pure-qml/qml/main.qml shell extensions
+
+ These are instantiated as children of the \l{WaylandCompositor} which automatically adds
+ them to the list of supported interfaces which is broadcasted to clients from the server.
+
+ When a connected client creates a surface and binds it to one of the shell extensions, the
+ corresponding signal is emitted. This then calls a method inside our custom \l WaylandOutput
+ class, which appends the \l ShellSurface to a \l{ListModel}.
+
+ \snippet pure-qml/qml/CompositorScreen.qml handleShellSurface
+
+ This model is used as the source for a \l Repeater which creates
+ \l{ShellSurfaceItem}{ShellSurfaceItems} inside the compositor's \l WaylandOutput. This adds a
+ view of the surface in the Qt Quick scene. Since it is a \l{ShellSurfaceItem}, it also has
+ certain interaction options for the user of the compositor, depending on which shell extension
+ is in use.
+
+ \snippet pure-qml/qml/CompositorScreen.qml repeater
+
+ \section1 Keyboard
+
+ In addition to the basic windowing system functions, the Pure QML compositor also supports an
+ optional on-screen keyboard running in-process. This uses the \l{Qt Virtual Keyboard} module,
+ and will be enabled if the module is available.
+
+ \snippet pure-qml/qml/Keyboard.qml keyboard
+
+ The code is simple. We instantiate an \l InputPanel in the bottom of the output, and make sure
+ it is visible if and only if it is currently active.
+
+ \snippet pure-qml/qml/CompositorScreen.qml keyboard
+
+ The keyboard is then added to the \l WaylandOutput using a \l Loader element. The \l Loader is
+ used here to avoid having a hard dependency on the \l{Qt Virtual Keyboard} module. If loading
+ fails, then the compositor will continue operating normally, but without support for an
+ on-screen keyboard.
+
+ Finally, we need a way for the compositor to communicate the text input to its clients. This
+ is done via a \c{text-input} extension. The Pure QML example only supports the
+ \c{qt_text_input_method_unstable_v1} protocol.
+
+ \snippet pure-qml/qml/main.qml text input
+
+ The extension is added to the compositor by instantiating the \l QtTextInputMethodManager as
+ a child of the \l{WaylandCompositor}.
+
+ In order for the on-screen keyboard to work, this protocol must also be supported by the client.
+ Therefore, the \l QtTextInputMethodManager is most useful if the clients are also Qt
+ applications.
+
+ \note Qt also supports \l{TextInputManager}, which is an implementation of the
+ \c{text_input_unstable_v2} protocol.
+
+ \section1 Transitions
+
+ In addition to the basic functionality, the Pure QML example also demonstrates animated
+ transitions between states.
+
+ The first of these is the \e{activation} transition. This is only supported on the \l{XdgShell},
+ since this is the only shell extension which has an \l{XdgTopLevel::activated}{activated} state.
+
+ \snippet pure-qml/qml/Chrome.qml activation
+
+ When a client window becomes activated under the \l XdgShell protocol, we trigger an animation
+ which makes the window "pop out" for 200 ms.
+
+ The Pure QML compositor also supports a \e{destruction} animation. This triggers whenever the
+ window closes and surface is destroyed, whether this was because the client gracefully closed
+ its window, or even if it crashes.
+
+ \snippet pure-qml/qml/Chrome.qml destruction
+
+ To ensure that the content exists for the duration of the animation, we start by locking the
+ buffer. This means the final frame rendered by the client will remain in memory until we are
+ done with it.
+
+ Again, we trigger an animation on the scale of the item. The animation in question imitates
+ turning off the power on a CRT screen, giving a visual clue to the user that the window is
+ closing, and didn't just vanish into thin air.
+
+ Any sort of animated effect may be used for state changes such as these, with the full range
+ of Qt Quick at your disposal.
*/
diff --git a/examples/wayland/pure-qml/qml/Chrome.qml b/examples/wayland/pure-qml/qml/Chrome.qml
index d9ff038c0..201fa5241 100644
--- a/examples/wayland/pure-qml/qml/Chrome.qml
+++ b/examples/wayland/pure-qml/qml/Chrome.qml
@@ -58,11 +58,25 @@ ShellSurfaceItem {
signal destroyAnimationFinished
+ // ![destruction]
onSurfaceDestroyed: {
bufferLocked = true;
destroyAnimation.start();
}
+ SequentialAnimation {
+ id: destroyAnimation
+
+ ParallelAnimation {
+ NumberAnimation { target: scaleTransform; property: "yScale"; to: 2/height; duration: 150 }
+ NumberAnimation { target: scaleTransform; property: "xScale"; to: 0.4; duration: 150 }
+ NumberAnimation { target: chrome; property: "opacity"; to: chrome.isChild ? 0 : 1; duration: 150 }
+ }
+ NumberAnimation { target: scaleTransform; property: "xScale"; to: 0; duration: 150 }
+ ScriptAction { script: destroyAnimationFinished() }
+ }
+ // ![destruction]
+
transform: [
Scale {
id: scaleTransform
@@ -71,6 +85,7 @@ ShellSurfaceItem {
}
]
+ // ![activation]
Connections {
target: shellSurface.toplevel !== undefined ? shellSurface.toplevel : null
@@ -85,18 +100,6 @@ ShellSurfaceItem {
}
SequentialAnimation {
- id: destroyAnimation
-
- ParallelAnimation {
- NumberAnimation { target: scaleTransform; property: "yScale"; to: 2/height; duration: 150 }
- NumberAnimation { target: scaleTransform; property: "xScale"; to: 0.4; duration: 150 }
- NumberAnimation { target: chrome; property: "opacity"; to: chrome.isChild ? 0 : 1; duration: 150 }
- }
- NumberAnimation { target: scaleTransform; property: "xScale"; to: 0; duration: 150 }
- ScriptAction { script: destroyAnimationFinished() }
- }
-
- SequentialAnimation {
id: receivedFocusAnimation
ParallelAnimation {
@@ -108,4 +111,5 @@ ShellSurfaceItem {
NumberAnimation { target: scaleTransform; property: "xScale"; to: 1; duration: 100; easing.type: Easing.InOutQuad }
}
}
+ // ![activation]
}
diff --git a/examples/wayland/pure-qml/qml/CompositorScreen.qml b/examples/wayland/pure-qml/qml/CompositorScreen.qml
index 79dee6a2f..ba61f2053 100644
--- a/examples/wayland/pure-qml/qml/CompositorScreen.qml
+++ b/examples/wayland/pure-qml/qml/CompositorScreen.qml
@@ -58,9 +58,11 @@ WaylandOutput {
property ListModel shellSurfaces: ListModel {}
property bool isNestedCompositor: Qt.platform.pluginName.startsWith("wayland") || Qt.platform.pluginName === "xcb"
+ // ![handleShellSurface]
function handleShellSurface(shellSurface) {
shellSurfaces.append({shellSurface: shellSurface});
}
+ // ![handleShellSurface]
// During development, it can be useful to start the compositor inside X11 or
// another Wayland compositor. In such cases, set sizeFollowsWindow to true to
@@ -91,6 +93,7 @@ WaylandOutput {
source: "qrc:/images/background.jpg"
smooth: true
+ // ![repeater]
Repeater {
model: output.shellSurfaces
// Chrome displays a shell surface on the screen (See Chrome.qml)
@@ -99,13 +102,16 @@ WaylandOutput {
onDestroyAnimationFinished: output.shellSurfaces.remove(index)
}
}
+ // ![repeater]
}
// Virtual Keyboard
+ // ![keyboard]
Loader {
anchors.fill: parent
source: "Keyboard.qml"
}
+ // ![keyboard]
// Draws the mouse cursor for a given Wayland seat
WaylandCursorItem {
diff --git a/examples/wayland/pure-qml/qml/Keyboard.qml b/examples/wayland/pure-qml/qml/Keyboard.qml
index 9f336e942..aedc6e620 100644
--- a/examples/wayland/pure-qml/qml/Keyboard.qml
+++ b/examples/wayland/pure-qml/qml/Keyboard.qml
@@ -48,6 +48,7 @@
**
****************************************************************************/
+// ![keyboard]
import QtQuick
import QtQuick.VirtualKeyboard
@@ -57,4 +58,5 @@ InputPanel {
anchors.left: parent.left
anchors.right: parent.right
}
+// ![keyboard]
diff --git a/examples/wayland/pure-qml/qml/main.qml b/examples/wayland/pure-qml/qml/main.qml
index dffb81b3e..5a0f324ec 100644
--- a/examples/wayland/pure-qml/qml/main.qml
+++ b/examples/wayland/pure-qml/qml/main.qml
@@ -59,6 +59,7 @@ WaylandCompositor {
CompositorScreen { id: screen; compositor: waylandCompositor }
+ // ![shell extensions]
// Shell surface extension. Needed to provide a window concept for Wayland clients.
// I.e. requests and events for maximization, minimization, resizing, closing etc.
XdgShell {
@@ -74,7 +75,10 @@ WaylandCompositor {
WlShell {
onWlShellSurfaceCreated: screen.handleShellSurface(shellSurface)
}
+ // ![shell extensions]
// Extension for Input Method (QT_IM_MODULE) support at compositor-side
+ // ![text input]
QtTextInputMethodManager {}
+ // ![text input]
}