Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylandxdgdecorationv1.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:critical reason:network-protocol
4
6
7#include <QtWaylandCompositor/QWaylandXdgToplevel>
8#include <QtWaylandCompositor/private/qwaylandxdgshell_p.h>
9
10#include <QtWaylandCompositor/QWaylandCompositor>
11#include <QtCore/QObject>
12
14
15/*!
16 \qmltype XdgDecorationManagerV1
17 \nativetype QWaylandXdgDecorationManagerV1
18 \inqmlmodule QtWayland.Compositor.XdgShell
19 \since 5.12
20 \brief Provides an extension for negotiation of server-side and client-side window decorations.
21
22 The XdgDecorationManagerV1 extension provides a way for a compositor to announce support for
23 server-side window decorations, and for xdg-shell clients to communicate whether they prefer
24 client-side or server-side decorations.
25
26 XdgDecorationManagerV1 corresponds to the Wayland interface, \c zxdg_decoration_manager_v1.
27
28 To provide the functionality of the extension in a compositor, create an instance of the
29 XdgDecorationManagerV1 component and add it to the list of extensions supported by the compositor:
30
31 \code
32 import QtWayland.Compositor
33
34 WaylandCompositor {
35 // Xdg decoration manager assumes xdg-shell is being used
36 XdgShell {
37 onToplevelCreated: // ...
38 }
39 XdgDecorationManagerV1 {
40 // Provide a hint to clients that support the extension they should use server-side
41 // decorations.
42 preferredMode: XdgToplevel.ServerSideDecoration
43 }
44 }
45 \endcode
46
47 \sa QWaylandXdgToplevel::decorationMode, {Server Side Decoration Compositor}
48*/
49
50/*!
51 \class QWaylandXdgDecorationManagerV1
52 \inmodule QtWaylandCompositor
53 \since 5.12
54 \brief Provides an extension for negotiation of server-side and client-side window decorations.
55
56 The QWaylandXdgDecorationManagerV1 extension provides a way for a compositor to announce support
57 for server-side window decorations, and for xdg-shell clients to communicate whether they prefer
58 client-side or server-side decorations.
59
60 QWaylandXdgDecorationManagerV1 corresponds to the Wayland interface, \c zxdg_decoration_manager_v1.
61
62 \sa QWaylandXdgToplevel::decorationMode
63*/
64
65/*!
66 Constructs a QWaylandXdgDecorationManagerV1 object.
67*/
68QWaylandXdgDecorationManagerV1::QWaylandXdgDecorationManagerV1()
69 : QWaylandCompositorExtensionTemplate<QWaylandXdgDecorationManagerV1>(*new QWaylandXdgDecorationManagerV1Private)
70{
71}
72
73/*!
74 Initializes the extension.
75*/
76void QWaylandXdgDecorationManagerV1::initialize()
77{
78 Q_D(QWaylandXdgDecorationManagerV1);
79
80 QWaylandCompositorExtensionTemplate::initialize();
81 QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
82 if (!compositor) {
83 qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandXdgDecorationV1";
84 return;
85 }
86 d->init(compositor->display(), 1);
87}
88
89/*!
90 \qmlproperty enumeration XdgDecorationManagerV1::preferredMode
91
92 This property holds the decoration mode the compositor prefers. Possible values are:
93
94 \value XdgToplevel.ClientSideDecoration The client should draw window decorations (default).
95 \value XdgToplevel.ServerSideDecoration The compositor should draw window decorations.
96
97 This is the mode used for clients that don't indicate a preference for server-side or
98 client-side decorations.
99*/
100/*!
101 \property QWaylandXdgDecorationManagerV1::preferredMode
102
103 This property holds the decoration mode the compositor prefers.
104
105 This is the mode used for clients that don't indicate a preference for server-side or
106 client-side decorations.
107*/
108QWaylandXdgToplevel::DecorationMode QWaylandXdgDecorationManagerV1::preferredMode() const
109{
110 Q_D(const QWaylandXdgDecorationManagerV1);
111 return d->m_preferredMode;
112}
113
114void QWaylandXdgDecorationManagerV1::setPreferredMode(QWaylandXdgToplevel::DecorationMode preferredMode)
115{
116 Q_D(QWaylandXdgDecorationManagerV1);
117 if (d->m_preferredMode == preferredMode)
118 return;
119
120 d->m_preferredMode = preferredMode;
121 emit preferredModeChanged();
122}
123
124/*!
125 Returns the Wayland interface for the QWaylandXdgDecorationManagerV1.
126*/
127const wl_interface *QWaylandXdgDecorationManagerV1::interface()
128{
129 return QWaylandXdgDecorationManagerV1Private::interface();
130}
131
132void QWaylandXdgDecorationManagerV1Private::zxdg_decoration_manager_v1_get_toplevel_decoration(
133 Resource *resource, uint id, wl_resource *toplevelResource)
134{
135 Q_Q(QWaylandXdgDecorationManagerV1);
136
137 auto *toplevel = QWaylandXdgToplevel::fromResource(toplevelResource);
138 if (!toplevel) {
139 qWarning() << "Couldn't find toplevel for decoration";
140 return;
141 }
142
143 //TODO: verify that the xdg surface is unconfigured, and post protocol error/warning
144
145 auto *toplevelPrivate = QWaylandXdgToplevelPrivate::get(toplevel);
146
147 if (toplevelPrivate->m_decoration) {
148 qWarning() << "zxdg_decoration_manager_v1.get_toplevel_decoration:"
149 << toplevel << "already has a decoration object, ignoring";
150 //TODO: protocol error as well?
151 return;
152 }
153
154 new QWaylandXdgToplevelDecorationV1(toplevel, q, resource->client(), id);
155}
156
157QWaylandXdgToplevelDecorationV1::QWaylandXdgToplevelDecorationV1(QWaylandXdgToplevel *toplevel,
158 QWaylandXdgDecorationManagerV1 *manager,
159 wl_client *client, int id)
160 : QtWaylandServer::zxdg_toplevel_decoration_v1(client, id, /*version*/ 1)
161 , m_toplevel(toplevel)
162 , m_manager(manager)
163{
164 Q_ASSERT(toplevel);
165 auto *toplevelPrivate = QWaylandXdgToplevelPrivate::get(toplevel);
166 Q_ASSERT(!toplevelPrivate->m_decoration);
167 toplevelPrivate->m_decoration = this;
168 sendConfigure(manager->preferredMode());
169}
170
171QWaylandXdgToplevelDecorationV1::~QWaylandXdgToplevelDecorationV1()
172{
173 QWaylandXdgToplevelPrivate::get(m_toplevel)->m_decoration = nullptr;
174}
175
176void QWaylandXdgToplevelDecorationV1::sendConfigure(QWaylandXdgToplevelDecorationV1::DecorationMode mode)
177{
178 if (configuredMode() == mode)
179 return;
180
181 switch (mode) {
182 case DecorationMode::ClientSideDecoration:
183 send_configure(mode_client_side);
184 break;
185 case DecorationMode::ServerSideDecoration:
186 send_configure(mode_server_side);
187 break;
188 default:
189 qWarning() << "Illegal mode in QWaylandXdgToplevelDecorationV1::sendConfigure" << mode;
190 break;
191 }
192
193 m_configuredMode = mode;
194 emit m_toplevel->decorationModeChanged();
195}
196
197void QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_destroy_resource(Resource *resource)
198{
199 Q_UNUSED(resource);
200 delete this;
201}
202
203void QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_destroy(Resource *resource)
204{
205 wl_resource_destroy(resource->handle);
206}
207
208void QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_set_mode(Resource *resource, uint32_t mode)
209{
210 Q_UNUSED(resource);
211 m_clientPreferredMode = mode;
212 handleClientPreferredModeChanged();
213}
214
215void QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_unset_mode(Resource *resource)
216{
217 Q_UNUSED(resource);
218 m_clientPreferredMode = 0;
219 handleClientPreferredModeChanged();
220}
221
222void QWaylandXdgToplevelDecorationV1::handleClientPreferredModeChanged()
223{
224 if (m_clientPreferredMode != m_configuredMode) {
225 if (m_clientPreferredMode == 0)
226 sendConfigure(m_manager->preferredMode());
227 else
228 sendConfigure(DecorationMode(m_clientPreferredMode));
229 }
230}
231
232QT_END_NAMESPACE
233
234#include "moc_qwaylandxdgdecorationv1.cpp"
Combined button and popup list for selecting options.