Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qwaylandxdgoutputv1.cpp
Go to the documentation of this file.
1
// Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
// Qt-Security score:critical reason:network-protocol
4
5
#
include
<
QWaylandCompositor
>
6
7
#
include
"qwaylandxdgoutputv1_p.h"
8
#
include
"qwaylandoutput_p.h"
9
10
#
include
<
wayland
-
server
.
h
>
11
12
QT_BEGIN_NAMESPACE
13
/*!
14
* \qmltype XdgOutputV1
15
* \nativetype QWaylandXdgOutputV1
16
* \inqmlmodule QtWayland.Compositor.XdgShell
17
* \brief Represents a display in a compositor.
18
*/
19
20
/*!
21
* \class QWaylandXdgOutputV1
22
* \inmodule QtWaylandCompositor
23
* \brief Represents a display in a compositor.
24
*/
25
26
/*!
27
* \qmltype XdgOutputManagerV1
28
* \nativetype QWaylandXdgOutputManagerV1
29
* \inqmlmodule QtWayland.Compositor.XdgShell
30
* \since 5.14
31
* \brief Provides an extension for describing outputs in a desktop oriented fashion.
32
*
33
* The XdgOutputManagerV1 extension provides a way for a compositor to describe outputs in a way
34
* that is more in line with the concept of an output on desktop oriented systems.
35
*
36
* Some information may not make sense in other applications such as IVI systems.
37
*
38
* Typically the global compositor space on a desktop system is made of a
39
* contiguous or overlapping set of rectangular regions.
40
*
41
* XdgOutputManagerV1 corresponds to the Wayland interface, \c zxdg_output_manager_v1.
42
*
43
* To provide the functionality of the extension in a compositor, create an instance of the
44
* XdgOutputManagerV1 component and add it to the list of extensions supported by the compositor,
45
* and associated each XdgOutputV1 with its WaylandOutput:
46
*
47
* \qml
48
* import QtWayland.Compositor
49
*
50
* WaylandCompositor {
51
* XdgOutputManagerV1 {
52
* WaylandOutput {
53
* id: output1
54
*
55
* position: Qt.point(0, 0)
56
* window: Window {}
57
*
58
* XdgOutputV1 {
59
* name: "WL-1"
60
* logicalPosition: output1.position
61
* logicalSize: Qt.size(output1.geometry.width / output1.scaleFactor,
62
* output1.geometry.height / output1.scaleFactor)
63
* }
64
* }
65
*
66
* WaylandOutput {
67
* id: output2
68
*
69
* position: Qt.point(800, 0)
70
* window: Window {}
71
*
72
* XdgOutputV1 {
73
* name: "WL-2"
74
* logicalPosition: output2.position
75
* logicalSize: Qt.size(output2.geometry.width / output2.scaleFactor,
76
* output2.geometry.height / output2.scaleFactor)
77
* }
78
* }
79
* }
80
* }
81
* \endqml
82
*/
83
84
/*!
85
* \class QWaylandXdgOutputManagerV1
86
* \inmodule QtWaylandCompositor
87
* \since 5.14
88
* \brief Provides an extension for describing outputs in a desktop oriented fashion.
89
*
90
* The QWaylandXdgOutputManagerV1 extension provides a way for a compositor to describe outputs in a way
91
* that is more in line with the concept of an output on desktop oriented systems.
92
*
93
* Some information may not make sense in other applications such as IVI systems.
94
*
95
* QWaylandXdgOutputManagerV1 corresponds to the Wayland interface, \c zxdg_output_manager_v1.
96
*/
97
98
/*!
99
* Constructs a QWaylandXdgOutputManagerV1 object.
100
*/
101
QWaylandXdgOutputManagerV1::QWaylandXdgOutputManagerV1()
102
: QWaylandCompositorExtensionTemplate<QWaylandXdgOutputManagerV1>(*
new
QWaylandXdgOutputManagerV1Private())
103
{
104
}
105
106
/*!
107
* Constructs a QWaylandXdgOutputManagerV1 object for the provided \a compositor.
108
*/
109
QWaylandXdgOutputManagerV1::QWaylandXdgOutputManagerV1(QWaylandCompositor *compositor)
110
: QWaylandCompositorExtensionTemplate<QWaylandXdgOutputManagerV1>(compositor, *
new
QWaylandXdgOutputManagerV1Private())
111
{
112
}
113
114
// QWaylandXdgOutputManagerV1Private
115
116
/*!
117
* Initializes the extension.
118
*/
119
void
QWaylandXdgOutputManagerV1::initialize()
120
{
121
Q_D(QWaylandXdgOutputManagerV1);
122
123
QWaylandCompositorExtensionTemplate::initialize();
124
QWaylandCompositor *compositor =
static_cast
<QWaylandCompositor *>(extensionContainer());
125
if
(!compositor) {
126
qCWarning(qLcWaylandCompositor) <<
"Failed to find QWaylandCompositor when initializing QWaylandXdgOutputManagerV1"
;
127
return
;
128
}
129
d->init(compositor->display(), d->interfaceVersion());
130
}
131
132
/*!
133
* Returns the Wayland interface for QWaylandXdgOutputManagerV1.
134
*/
135
const
wl_interface *QWaylandXdgOutputManagerV1::interface()
136
{
137
return
QWaylandXdgOutputManagerV1Private::interface();
138
}
139
140
// QWaylandXdgOutputManagerV1Private
141
142
void
QWaylandXdgOutputManagerV1Private::registerXdgOutput(QWaylandOutput *output, QWaylandXdgOutputV1 *xdgOutput)
143
{
144
if
(!xdgOutputs.contains(output)) {
145
xdgOutputs[output] = xdgOutput;
146
}
147
}
148
149
void
QWaylandXdgOutputManagerV1Private::unregisterXdgOutput(QWaylandOutput *output)
150
{
151
xdgOutputs.remove(output);
152
}
153
154
QWaylandXdgOutputV1 *QWaylandXdgOutputManagerV1Private::xdgOutput(QWaylandOutput *output)
const
155
{
156
return
xdgOutputs.value(output);
157
}
158
159
void
QWaylandXdgOutputManagerV1Private::zxdg_output_manager_v1_get_xdg_output(Resource *resource,
160
uint32_t id,
161
wl_resource *outputResource)
162
{
163
Q_Q(QWaylandXdgOutputManagerV1);
164
165
// Verify if the associated output exist
166
auto
*output = QWaylandOutput::fromResource(outputResource);
167
if
(!output) {
168
qCWarning(qLcWaylandCompositor,
169
"The client is requesting a QWaylandXdgOutputV1 for a "
170
"QWaylandOutput that doesn't exist"
);
171
wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
"output not found"
);
172
return
;
173
}
174
175
// Do we have a QWaylandXdgOutputV1 for this output?
176
if
(!xdgOutputs.contains(output)) {
177
qCWarning(qLcWaylandCompositor,
178
"The client is requesting a QWaylandXdgOutputV1 that the compositor "
179
"didn't create before"
);
180
wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
181
"compositor didn't create a QWaylandXdgOutputV1 for this zxdg_output_v1 object"
);
182
return
;
183
}
184
185
// Bind QWaylandXdgOutputV1 and initialize
186
auto
*xdgOutput = xdgOutputs[output];
187
auto
*xdgOutputPrivate = QWaylandXdgOutputV1Private::get(xdgOutput);
188
Q_ASSERT(xdgOutputPrivate);
189
xdgOutputPrivate->setManager(q);
190
xdgOutputPrivate->setOutput(output);
191
xdgOutputPrivate->add(resource->client(), id, qMin(resource->version(), QWaylandXdgOutputV1Private::interfaceVersion()));
192
}
193
194
// QWaylandXdgOutputV1
195
196
QWaylandXdgOutputV1::QWaylandXdgOutputV1()
197
: QObject(*
new
QWaylandXdgOutputV1Private)
198
{
199
}
200
201
QWaylandXdgOutputV1::QWaylandXdgOutputV1(QWaylandOutput *output, QWaylandXdgOutputManagerV1 *manager)
202
: QObject(*
new
QWaylandXdgOutputV1Private)
203
{
204
Q_D(QWaylandXdgOutputV1);
205
206
// Set members before emitting changed signals so that handlers will
207
// see both already set and not nullptr, avoiding potential crashes
208
d->manager = manager;
209
d->output = output;
210
211
QWaylandXdgOutputManagerV1Private::get(d->manager)->registerXdgOutput(output,
this
);
212
213
emit managerChanged();
214
emit outputChanged();
215
}
216
217
QWaylandXdgOutputV1::~QWaylandXdgOutputV1()
218
{
219
Q_D(QWaylandXdgOutputV1);
220
221
if
(d->manager)
222
QWaylandXdgOutputManagerV1Private::get(d->manager)->unregisterXdgOutput(d->output);
223
}
224
225
/*!
226
* \qmlproperty XdgOutputManagerV1 XdgOutputV1::manager
227
* \readonly
228
*
229
* This property holds the object that manages this XdgOutputV1.
230
*/
231
/*!
232
* \property QWaylandXdgOutputV1::manager
233
* \readonly
234
* \internal
235
*
236
* This property holds the object that manages this QWaylandXdgOutputV1.
237
*/
238
QWaylandXdgOutputManagerV1 *QWaylandXdgOutputV1::manager()
const
239
{
240
Q_D(
const
QWaylandXdgOutputV1);
241
return
d->manager;
242
}
243
244
/*!
245
* \qmlproperty WaylandOutput XdgOutputV1::output
246
* \readonly
247
*
248
* This property holds the WaylandOutput associated with this XdgOutputV1.
249
*/
250
/*!
251
* \property QWaylandXdgOutputV1::output
252
* \readonly
253
*
254
* This property holds the QWaylandOutput associated with this QWaylandXdgOutputV1.
255
*/
256
QWaylandOutput *QWaylandXdgOutputV1::output()
const
257
{
258
Q_D(
const
QWaylandXdgOutputV1);
259
return
d->output;
260
}
261
262
/*!
263
* \qmlproperty string XdgOutputV1::name
264
*
265
* This property holds the name of this output.
266
*
267
* The naming convention is compositor defined, but limited to alphanumeric
268
* characters and dashes ("-"). Each name is unique and will also remain
269
* consistent across sessions with the same hardware and software configuration.
270
*
271
* Examples of names include "HDMI-A-1", "WL-1", "X11-1" etc...
272
* However don't assume the name reflects the underlying technology.
273
*
274
* Changing this property after initialization doesn't take effect.
275
*/
276
/*!
277
* \property QWaylandXdgOutputV1::name
278
*
279
* This property holds the name of this output.
280
*
281
* The naming convention is compositor defined, but limited to alphanumeric
282
* characters and dashes ("-"). Each name is unique and will also remain
283
* consistent across sessions with the same hardware and software configuration.
284
*
285
* Examples of names include "HDMI-A-1", "WL-1", "X11-1" etc...
286
* However don't assume the name reflects the underlying technology.
287
*
288
* Changing this property after initialization doesn't take effect.
289
*/
290
QString QWaylandXdgOutputV1::name()
const
291
{
292
Q_D(
const
QWaylandXdgOutputV1);
293
return
d->name;
294
}
295
296
void
QWaylandXdgOutputV1::setName(
const
QString &name)
297
{
298
Q_D(QWaylandXdgOutputV1);
299
300
if
(d->name == name)
301
return
;
302
303
// Can't change after clients bound to xdg-output
304
if
(d->initialized) {
305
qCWarning(qLcWaylandCompositor,
"QWaylandXdgOutputV1::name cannot be changed after initialization"
);
306
return
;
307
}
308
309
d->name = name;
310
emit nameChanged();
311
}
312
313
/*!
314
* \qmlproperty string XdgOutputV1::description
315
*
316
* This property holds the description of this output.
317
*
318
* No convention is defined for the description.
319
*
320
* Changing this property after initialization doesn't take effect.
321
*/
322
/*!
323
* \property QWaylandXdgOutputV1::description
324
*
325
* This property holds the description of this output.
326
*
327
* No convention is defined for the description.
328
*
329
* Changing this property after initialization doesn't take effect.
330
*/
331
QString QWaylandXdgOutputV1::description()
const
332
{
333
Q_D(
const
QWaylandXdgOutputV1);
334
return
d->description;
335
}
336
337
void
QWaylandXdgOutputV1::setDescription(
const
QString &description)
338
{
339
Q_D(QWaylandXdgOutputV1);
340
341
if
(d->description == description)
342
return
;
343
344
// Can't change after clients bound to xdg-output
345
if
(d->initialized) {
346
qCWarning(qLcWaylandCompositor,
"QWaylandXdgOutputV1::description cannot be changed after initialization"
);
347
return
;
348
}
349
350
d->description = description;
351
emit descriptionChanged();
352
}
353
354
/*!
355
* \qmlproperty point XdgOutputV1::logicalPosition
356
*
357
* This property holds the coordinates of the output within the global compositor space.
358
*
359
* The default value is 0,0.
360
*/
361
/*!
362
* \property QWaylandXdgOutputV1::logicalPosition
363
*
364
* This property holds the coordinates of the output within the global compositor space.
365
*
366
* The default value is 0,0.
367
*/
368
QPoint QWaylandXdgOutputV1::logicalPosition()
const
369
{
370
Q_D(
const
QWaylandXdgOutputV1);
371
return
d->logicalPos;
372
}
373
374
void
QWaylandXdgOutputV1::setLogicalPosition(
const
QPoint &position)
375
{
376
Q_D(QWaylandXdgOutputV1);
377
378
if
(d->logicalPos == position)
379
return
;
380
381
d->logicalPos = position;
382
if
(d->initialized) {
383
d->sendLogicalPosition(position);
384
d->sendDone();
385
}
386
emit logicalPositionChanged();
387
emit logicalGeometryChanged();
388
}
389
390
/*!
391
* \qmlproperty size XdgOutputV1::logicalSize
392
*
393
* This property holds the size of the output in the global compositor space.
394
*
395
* The default value is -1,-1 which is invalid.
396
*
397
* Please remember that this is the logical size, not the physical size.
398
* For example, for a WaylandOutput mode 3840x2160 and a scale factor 2:
399
* \list
400
* \li A compositor not scaling the surface buffers, will report a logical size of 3840x2160.
401
* \li A compositor automatically scaling the surface buffers, will report a logical size of 1920x1080.
402
* \li A compositor using a fractional scale of 1.5, will report a logical size of 2560x1620.
403
* \endlist
404
*/
405
/*!
406
* \property QWaylandXdgOutputV1::logicalSize
407
*
408
* This property holds the size of the output in the global compositor space.
409
*
410
* The default value is -1,-1 which is invalid.
411
*
412
* Please remember that this is the logical size, not the physical size.
413
* For example, for a WaylandOutput mode 3840x2160 and a scale factor 2:
414
* \list
415
* \li A compositor not scaling the surface buffers, will report a logical size of 3840x2160.
416
* \li A compositor automatically scaling the surface buffers, will report a logical size of 1920x1080.
417
* \li A compositor using a fractional scale of 1.5, will report a logical size of 2560x1620.
418
* \endlist
419
*/
420
QSize QWaylandXdgOutputV1::logicalSize()
const
421
{
422
Q_D(
const
QWaylandXdgOutputV1);
423
return
d->logicalSize;
424
}
425
426
void
QWaylandXdgOutputV1::setLogicalSize(
const
QSize &size)
427
{
428
Q_D(QWaylandXdgOutputV1);
429
430
if
(d->logicalSize == size)
431
return
;
432
433
d->logicalSize = size;
434
if
(d->initialized) {
435
d->sendLogicalSize(size);
436
d->sendDone();
437
}
438
emit logicalSizeChanged();
439
emit logicalGeometryChanged();
440
}
441
442
/*!
443
* \qmlproperty rect XdgOutputV1::logicalGeometry
444
* \readonly
445
*
446
* This property holds the position and size of the output in the global compositor space.
447
* It's the combination of the logical position and logical size.
448
*
449
* \sa XdgOutputV1::logicalPosition
450
* \sa XdgOutputV1::logicalSize
451
*/
452
/*!
453
* \property QWaylandXdgOutputV1::logicalGeometry
454
* \readonly
455
*
456
* This property holds the position and size of the output in the global compositor space.
457
* It's the combination of the logical position and logical size.
458
*
459
* \sa QWaylandXdgOutputV1::logicalPosition
460
* \sa QWaylandXdgOutputV1::logicalSize
461
*/
462
QRect QWaylandXdgOutputV1::logicalGeometry()
const
463
{
464
Q_D(
const
QWaylandXdgOutputV1);
465
return
QRect(d->logicalPos, d->logicalSize);
466
}
467
468
// QWaylandXdgOutputV1Private
469
470
void
QWaylandXdgOutputV1Private::sendLogicalPosition(
const
QPoint &position)
471
{
472
const
auto
values = resourceMap().values();
473
for
(
auto
*resource : values)
474
send_logical_position(resource->handle, position.x(), position.y());
475
}
476
477
void
QWaylandXdgOutputV1Private::sendLogicalSize(
const
QSize &size)
478
{
479
const
auto
values = resourceMap().values();
480
for
(
auto
*resource : values)
481
send_logical_size(resource->handle, size.width(), size.height());
482
}
483
484
void
QWaylandXdgOutputV1Private::maybeSendDone(
const
Resource *resource)
485
{
486
if
(resource->version() < 3)
487
send_done(resource->handle);
488
}
489
490
void
QWaylandXdgOutputV1Private::sendDone()
491
{
492
const
auto
values = resourceMap().values();
493
for
(
auto
*resource : values)
494
maybeSendDone(resource);
495
496
QWaylandOutputPrivate::get(output)->sendDone();
497
}
498
499
void
QWaylandXdgOutputV1Private::setManager(QWaylandXdgOutputManagerV1 *_manager)
500
{
501
Q_Q(QWaylandXdgOutputV1);
502
503
if
(!_manager) {
504
qCWarning(qLcWaylandCompositor,
505
"Cannot associate a null QWaylandXdgOutputManagerV1 to QWaylandXdgOutputV1 %p"
,
this
);
506
return
;
507
}
508
509
if
(manager == _manager)
510
return
;
511
512
if
(manager) {
513
qCWarning(qLcWaylandCompositor,
514
"Cannot associate a different QWaylandXdgOutputManagerV1 to QWaylandXdgOutputV1 %p "
515
"after initialization"
,
this
);
516
return
;
517
}
518
519
manager = _manager;
520
emit q->managerChanged();
521
}
522
523
void
QWaylandXdgOutputV1Private::setOutput(QWaylandOutput *_output)
524
{
525
Q_Q(QWaylandXdgOutputV1);
526
527
if
(!_output) {
528
qCWarning(qLcWaylandCompositor,
529
"Cannot associate a null QWaylandOutput to QWaylandXdgOutputV1 %p"
,
this
);
530
return
;
531
}
532
533
if
(output == _output)
534
return
;
535
536
if
(output) {
537
qCWarning(qLcWaylandCompositor,
538
"Cannot associate a different QWaylandOutput to QWaylandXdgOutputV1 %p "
539
"after initialization"
,
this
);
540
return
;
541
}
542
543
// Assign output above manager, to make both values valid in handlers
544
output = _output;
545
546
if
(!manager) {
547
// Try to find the manager from the output parents
548
for
(
auto
*p = output->parent(); p !=
nullptr
; p = p->parent()) {
549
if
(
auto
*m = qobject_cast<QWaylandXdgOutputManagerV1 *>(p)) {
550
manager = m;
551
emit q->managerChanged();
552
break
;
553
}
554
}
555
}
556
557
emit q->outputChanged();
558
559
// Register the output
560
if
(manager)
561
QWaylandXdgOutputManagerV1Private::get(manager)->registerXdgOutput(output, q);
562
}
563
564
void
QWaylandXdgOutputV1Private::zxdg_output_v1_bind_resource(Resource *resource)
565
{
566
send_logical_position(resource->handle, logicalPos.x(), logicalPos.y());
567
send_logical_size(resource->handle, logicalSize.width(), logicalSize.height());
568
if
(resource->version() >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
569
send_name(resource->handle, name);
570
if
(resource->version() >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION)
571
send_description(resource->handle, description);
572
maybeSendDone(resource);
573
574
QWaylandOutputPrivate *output_d = QWaylandOutputPrivate::get(output);
575
auto
*outputResource = output_d->resourceMap().value(resource->client());
576
if
(outputResource)
577
output_d->maybeSendDone(outputResource);
578
579
initialized =
true
;
580
}
581
582
void
QWaylandXdgOutputV1Private::zxdg_output_v1_destroy(Resource *resource)
583
{
584
wl_resource_destroy(resource->handle);
585
}
586
587
QT_END_NAMESPACE
588
589
#
include
"moc_qwaylandxdgoutputv1.cpp"
qtwayland
src
compositor
extensions
qwaylandxdgoutputv1.cpp
Generated on
for Qt by
1.18.0