summaryrefslogtreecommitdiffstats
path: root/examples/wayland/pure-qml/doc/src/pure-qml.qdoc
blob: b083c5d6d4b862e2bca88f89d6c8e75ef4821423 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \title Qt Wayland Compositor Examples - Pure QML
    \example pure-qml
    \brief Pure QML is an example that demonstrates how to write a Wayland compositor in pure QML.
    \ingroup qtwaylandcompositor-examples

    \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} 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.
*/