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
qwaylandoutput.cpp
Go to the documentation of this file.
1
// Copyright (C) 2017-2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2
// Copyright (C) 2017 Klarälvdalens Datakonsult AB (KDAB).
3
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
// Qt-Security score:critical reason:network-protocol
5
6
#
include
"qwaylandoutput.h"
7
#
include
"qwaylandoutput_p.h"
8
9
#
include
<
QtWaylandCompositor
/
QWaylandCompositor
>
10
#
include
<
QtWaylandCompositor
/
QWaylandView
>
11
12
#
include
<
QtWaylandCompositor
/
private
/
qwaylandsurface_p
.
h
>
13
#
include
<
QtWaylandCompositor
/
private
/
qwaylandcompositor_p
.
h
>
14
#
include
<
QtWaylandCompositor
/
private
/
qwaylandview_p
.
h
>
15
#
include
<
QtWaylandCompositor
/
private
/
qwaylandutils_p
.
h
>
16
17
#
include
<
QtCore
/
QCoreApplication
>
18
#
include
<
QtCore
/
QtMath
>
19
#
include
<
QtGui
/
QWindow
>
20
#
include
<
QtGui
/
QExposeEvent
>
21
#
include
<
QtGui
/
QScreen
>
22
#
include
<
private
/
qobject_p
.
h
>
23
24
QT_BEGIN_NAMESPACE
25
26
static
QtWaylandServer
::
wl_output
::
subpixel
toWlSubpixel
(
const
QWaylandOutput::Subpixel &value)
27
{
28
switch
(value) {
29
case
QWaylandOutput::SubpixelUnknown:
30
return
QtWaylandServer::wl_output::subpixel_unknown;
31
case
QWaylandOutput::SubpixelNone:
32
return
QtWaylandServer::wl_output::subpixel_none;
33
case
QWaylandOutput::SubpixelHorizontalRgb:
34
return
QtWaylandServer::wl_output::subpixel_horizontal_rgb;
35
case
QWaylandOutput::SubpixelHorizontalBgr:
36
return
QtWaylandServer::wl_output::subpixel_horizontal_bgr;
37
case
QWaylandOutput::SubpixelVerticalRgb:
38
return
QtWaylandServer::wl_output::subpixel_vertical_rgb;
39
case
QWaylandOutput::SubpixelVerticalBgr:
40
return
QtWaylandServer::wl_output::subpixel_vertical_bgr;
41
default
:
42
break
;
43
}
44
45
return
QtWaylandServer::wl_output::subpixel_unknown;
46
}
47
48
static
QtWaylandServer
::
wl_output
::
transform
toWlTransform
(
const
QWaylandOutput::Transform &value)
49
{
50
switch
(value) {
51
case
QWaylandOutput::Transform90:
52
return
QtWaylandServer::wl_output::transform_90;
53
case
QWaylandOutput::Transform180:
54
return
QtWaylandServer::wl_output::transform_180;
55
case
QWaylandOutput::Transform270:
56
return
QtWaylandServer::wl_output::transform_270;
57
case
QWaylandOutput::TransformFlipped:
58
return
QtWaylandServer::wl_output::transform_flipped;
59
case
QWaylandOutput::TransformFlipped90:
60
return
QtWaylandServer::wl_output::transform_flipped_90;
61
case
QWaylandOutput::TransformFlipped180:
62
return
QtWaylandServer::wl_output::transform_flipped_180;
63
case
QWaylandOutput::TransformFlipped270:
64
return
QtWaylandServer::wl_output::transform_flipped_270;
65
default
:
66
break
;
67
}
68
69
return
QtWaylandServer::wl_output::transform_normal;
70
}
71
72
QWaylandOutputPrivate::QWaylandOutputPrivate()
73
{
74
}
75
76
QWaylandOutputPrivate::~QWaylandOutputPrivate()
77
{
78
}
79
80
void
QWaylandOutputPrivate::output_bind_resource(Resource *resource)
81
{
82
sendGeometry(resource);
83
84
for
(
const
QWaylandOutputMode &mode : std::as_const(modes))
85
sendMode(resource, mode);
86
87
maybeSendScale(resource, scaleFactor);
88
maybeSendDone(resource);
89
}
90
91
void
QWaylandOutputPrivate::_q_handleMaybeWindowPixelSizeChanged()
92
{
93
if
(!window)
94
return
;
95
96
const
QSize pixelSize = window->size() * window->devicePixelRatio();
97
98
if
(pixelSize != windowPixelSize) {
99
windowPixelSize = pixelSize;
100
handleWindowPixelSizeChanged();
101
}
102
}
103
104
void
QWaylandOutputPrivate::_q_handleWindowDestroyed()
105
{
106
Q_Q(QWaylandOutput);
107
window =
nullptr
;
108
emit q->windowChanged();
109
emit q->windowDestroyed();
110
}
111
112
void
QWaylandOutputPrivate::sendGeometry(
const
Resource *resource)
113
{
114
send_geometry(resource->handle,
115
position.x(), position.y(),
116
physicalSize.width(), physicalSize.height(),
117
toWlSubpixel(subpixel), manufacturer, model,
118
toWlTransform(transform));
119
}
120
121
void
QWaylandOutputPrivate::sendGeometryInfo()
122
{
123
const
auto
resources = resourceMap().values();
124
for
(
const
Resource *resource : resources) {
125
sendGeometry(resource);
126
maybeSendDone(resource);
127
}
128
}
129
130
void
QWaylandOutputPrivate::sendMode(
const
Resource *resource,
const
QWaylandOutputMode &mode)
131
{
132
quint32 flags = 0;
133
if
(currentMode == modes.indexOf(mode))
134
flags |= QtWaylandServer::wl_output::mode_current;
135
if
(preferredMode == modes.indexOf(mode))
136
flags |= QtWaylandServer::wl_output::mode_preferred;
137
138
send_mode(resource->handle, flags,
139
mode.size().width(), mode.size().height(),
140
mode.refreshRate());
141
}
142
143
void
QWaylandOutputPrivate::sendModesInfo()
144
{
145
const
auto
resources = resourceMap().values();
146
for
(
const
Resource *resource : resources) {
147
for
(
const
QWaylandOutputMode &mode : std::as_const(modes))
148
sendMode(resource, mode);
149
maybeSendDone(resource);
150
}
151
}
152
153
void
QWaylandOutputPrivate::maybeSendDone(
const
Resource *resource)
154
{
155
if
(resource->version() >= 2)
156
send_done(resource->handle);
157
}
158
159
void
QWaylandOutputPrivate::sendDone()
160
{
161
const
auto
values = resourceMap().values();
162
for
(
auto
*resource : values)
163
maybeSendDone(resource);
164
}
165
166
void
QWaylandOutputPrivate::handleWindowPixelSizeChanged()
167
{
168
Q_Q(QWaylandOutput);
169
Q_ASSERT(window);
170
if
(sizeFollowsWindow && currentMode < modes.size()) {
171
if
(currentMode >= 0) {
172
QWaylandOutputMode &mode = modes[currentMode];
173
mode.setSize(windowPixelSize);
174
emit q->geometryChanged();
175
if
(!availableGeometry.isValid())
176
emit q->availableGeometryChanged();
177
sendModesInfo();
178
}
else
{
179
// We didn't add a mode during the initialization because the window
180
// size was invalid, let's add it now
181
int
mHzRefreshRate = qFloor(window->screen()->refreshRate() * 1000);
182
QWaylandOutputMode mode(windowPixelSize, mHzRefreshRate);
183
if
(mode.isValid()) {
184
modes.clear();
185
q->addMode(mode,
true
);
186
q->setCurrentMode(mode);
187
}
188
}
189
}
190
}
191
192
void
QWaylandOutputPrivate::addView(QWaylandView *view, QWaylandSurface *surface)
193
{
194
for
(
int
i = 0; i < surfaceViews.size(); i++) {
195
if
(surface == surfaceViews.at(i).surface) {
196
if
(!surfaceViews.at(i).views.contains(view)) {
197
surfaceViews[i].views.append(view);
198
}
199
return
;
200
}
201
}
202
203
surfaceViews.append(QWaylandSurfaceViewMapper(surface,view));
204
}
205
206
void
QWaylandOutputPrivate::removeView(QWaylandView *view, QWaylandSurface *surface)
207
{
208
Q_Q(QWaylandOutput);
209
for
(
int
i = 0; i < surfaceViews.size(); i++) {
210
if
(surface == surfaceViews.at(i).surface) {
211
bool
removed = surfaceViews[i].views.removeOne(view);
212
if
(removed && surfaceViews.at(i).views.isEmpty()) {
213
if
(surfaceViews.at(i).has_entered)
214
q->surfaceLeave(surface);
215
surfaceViews.remove(i);
216
}
217
return
;
218
}
219
}
220
qWarning(
"%s Could not find view %p for surface %p to remove. Possible invalid state"
, Q_FUNC_INFO, view, surface);
221
}
222
223
QWaylandOutput::QWaylandOutput()
224
: QWaylandObject(*
new
QWaylandOutputPrivate())
225
{
226
}
227
228
/*!
229
\qmltype WaylandOutput
230
\nativetype QWaylandOutput
231
\inqmlmodule QtWayland.Compositor
232
\since 5.8
233
\brief Provides access to a displayable area managed by the compositor.
234
235
The WaylandOutput manages a rectangular area within bounds of the compositor's
236
geometry, to use it for displaying client content. This could, for instance, be
237
a screen managed by the WaylandCompositor.
238
239
The type corresponds to the \c wl_output interface in the Wayland protocol.
240
241
\note If the compositor has multiple Wayland outputs, the \l Qt::AA_ShareOpenGLContexts
242
attribute must be set before the \l QGuiApplication object is constructed.
243
*/
244
245
/*!
246
\class QWaylandOutput
247
\inmodule QtWaylandCompositor
248
\since 5.8
249
\brief The QWaylandOutput class represents a displayable area managed by the compositor.
250
251
The QWaylandOutput manages a rectangular area within bounds of the compositor's
252
geometry, to use it for displaying client content. This could, for instance, be
253
a screen managed by the WaylandCompositor.
254
255
The class corresponds to the \c wl_output interface in the Wayland protocol.
256
*/
257
258
/*!
259
* Constructs a QWaylandOutput in \a compositor and with the specified \a window. The
260
* \l{QWaylandCompositor::create()}{create()} function must be called on the
261
* \a compositor before constructing a QWaylandOutput for it.
262
*
263
* The QWaylandOutput object is initialized later, in reaction to an event.
264
* At this point it is added as an output for the \a compositor. If it is the
265
* first QWaylandOutput object created for this \a compositor, it becomes the
266
* \l{QWaylandCompositor::defaultOutput()}{default output}.
267
*/
268
QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window)
269
: QWaylandObject(*
new
QWaylandOutputPrivate())
270
{
271
Q_D(QWaylandOutput);
272
d->compositor = compositor;
273
d->window = window;
274
QWaylandCompositorPrivate::get(compositor)->addPolishObject(
this
);
275
}
276
277
/*!
278
* Destroys the QWaylandOutput.
279
*/
280
QWaylandOutput::~QWaylandOutput()
281
{
282
Q_D(QWaylandOutput);
283
284
const
auto
surfaceViews = d->surfaceViews;
// intentional copy
285
for
(
const
QWaylandSurfaceViewMapper &surfacemapper : surfaceViews) {
286
for
(QWaylandView *view : surfacemapper.views) {
287
if
(view->output() ==
this
)
288
view->setOutput(
nullptr
);
289
}
290
}
291
292
if
(d->compositor)
293
QWaylandCompositorPrivate::get(d->compositor)->removeOutput(
this
);
294
}
295
296
/*!
297
* \internal
298
*/
299
void
QWaylandOutput::initialize()
300
{
301
Q_D(QWaylandOutput);
302
303
Q_ASSERT(!d->initialized);
304
Q_ASSERT(d->compositor);
305
Q_ASSERT(d->compositor->isCreated());
306
307
if
(!d->window && d->sizeFollowsWindow) {
308
qWarning(
"Setting QWaylandOutput::sizeFollowsWindow without a window has no effect"
);
309
}
310
311
// Replace modes with one that follows the window size and refresh rate,
312
// but only if window size is valid
313
if
(d->window && d->sizeFollowsWindow) {
314
QWaylandOutputMode mode(d->window->size() * d->window->devicePixelRatio(),
315
qFloor(d->window->screen()->refreshRate() * 1000));
316
if
(mode.isValid()) {
317
d->modes.clear();
318
addMode(mode,
true
);
319
setCurrentMode(mode);
320
}
321
}
322
323
QWaylandCompositorPrivate::get(d->compositor)->addOutput(
this
);
324
325
if
(d->window) {
326
QObjectPrivate::connect(d->window, &QWindow::widthChanged, d, &QWaylandOutputPrivate::_q_handleMaybeWindowPixelSizeChanged);
327
QObjectPrivate::connect(d->window, &QWindow::heightChanged, d, &QWaylandOutputPrivate::_q_handleMaybeWindowPixelSizeChanged);
328
QObjectPrivate::connect(d->window, &QWindow::screenChanged, d, &QWaylandOutputPrivate::_q_handleMaybeWindowPixelSizeChanged);
329
QObjectPrivate::connect(d->window, &QObject::destroyed, d, &QWaylandOutputPrivate::_q_handleWindowDestroyed);
330
}
331
332
d->init(d->compositor->display(), 2);
333
334
d->initialized =
true
;
335
}
336
337
/*!
338
* Returns the QWaylandOutput corresponding to \a resource.
339
*/
340
QWaylandOutput *QWaylandOutput::fromResource(wl_resource *resource)
341
{
342
if
(
auto
p = QtWayland::fromResource<QWaylandOutputPrivate *>(resource))
343
return
p->q_func();
344
return
nullptr
;
345
}
346
347
/*!
348
* \internal
349
*/
350
struct
::wl_resource *QWaylandOutput::resourceForClient(QWaylandClient *client)
const
351
{
352
Q_D(
const
QWaylandOutput);
353
QWaylandOutputPrivate::Resource *r = d->resourceMap().value(client->client());
354
if
(r)
355
return
r->handle;
356
357
return
nullptr
;
358
}
359
360
/*!
361
* Schedules a QEvent::UpdateRequest to be delivered to the QWaylandOutput's \l{window()}{window}.
362
*
363
* \sa QWindow::requestUpdate()
364
*/
365
void
QWaylandOutput::update()
366
{
367
Q_D(QWaylandOutput);
368
if
(!d->window)
369
return
;
370
d->window->requestUpdate();
371
}
372
373
/*!
374
* \qmlproperty WaylandCompositor QtWayland.Compositor::WaylandOutput::compositor
375
*
376
* This property holds the compositor displaying content on this WaylandOutput.
377
*
378
* \note This property can be set only once, before the WaylandOutput component
379
* is completed.
380
*/
381
382
/*!
383
* \property QWaylandOutput::compositor
384
*
385
* This property holds the compositor displaying content on this QWaylandOutput.
386
*
387
* \note This property can be set only once, before the QWaylandOutput has been
388
* initialized.
389
*/
390
391
/*!
392
* Returns the compositor for this QWaylandOutput.
393
*/
394
QWaylandCompositor *QWaylandOutput::compositor()
const
395
{
396
return
d_func()->compositor;
397
}
398
399
/*!
400
* \internal
401
*/
402
void
QWaylandOutput::setCompositor(QWaylandCompositor *compositor)
403
{
404
Q_D(QWaylandOutput);
405
406
if
(d->compositor == compositor)
407
return
;
408
409
if
(d->initialized) {
410
qWarning(
"Setting QWaylandCompositor %p on QWaylandOutput %p is not supported after QWaylandOutput has been initialized\n"
, compositor,
this
);
411
return
;
412
}
413
if
(d->compositor && d->compositor != compositor) {
414
qWarning(
"Possible initialization error. Moving QWaylandOutput %p between compositor instances.\n"
,
this
);
415
}
416
417
d->compositor = compositor;
418
419
QWaylandCompositorPrivate::get(compositor)->addPolishObject(
this
);
420
}
421
422
/*!
423
* \qmlproperty string QtWayland.Compositor::WaylandOutput::manufacturer
424
*
425
* This property holds a textual description of the manufacturer of the display
426
* managed by this WaylandOutput.
427
*/
428
429
/*!
430
* \property QWaylandOutput::manufacturer
431
*
432
* This property holds a textual description of the manufacturer of the display
433
* managed by this QWaylandOutput.
434
*/
435
QString QWaylandOutput::manufacturer()
const
436
{
437
return
d_func()->manufacturer;
438
}
439
440
void
QWaylandOutput::setManufacturer(
const
QString &manufacturer)
441
{
442
Q_D(QWaylandOutput);
443
444
if
(d->manufacturer == manufacturer)
445
return
;
446
447
d->manufacturer = manufacturer;
448
d->sendGeometryInfo();
449
Q_EMIT manufacturerChanged();
450
}
451
452
/*!
453
* \qmlproperty string QtWayland.Compositor::WaylandOutput::model
454
*
455
* This property holds a textual description of the model of the display
456
* managed by this WaylandOutput.
457
*/
458
459
/*!
460
* \property QWaylandOutput::model
461
*
462
* This property holds a textual description of the model of the display
463
* managed by this QWaylandOutput.
464
*/
465
QString QWaylandOutput::model()
const
466
{
467
return
d_func()->model;
468
}
469
470
void
QWaylandOutput::setModel(
const
QString &model)
471
{
472
Q_D(QWaylandOutput);
473
474
if
(d->model == model)
475
return
;
476
477
d->model = model;
478
d->sendGeometryInfo();
479
Q_EMIT modelChanged();
480
}
481
482
/*!
483
* \qmlproperty point QtWayland.Compositor::WaylandOutput::position
484
*
485
* This property holds the position of this WaylandOutput in the compositor's coordinate system.
486
*/
487
488
/*!
489
* \property QWaylandOutput::position
490
*
491
* This property holds the position of this QWaylandOutput in the compositor's coordinate system.
492
*/
493
QPoint QWaylandOutput::position()
const
494
{
495
return
d_func()->position;
496
}
497
498
void
QWaylandOutput::setPosition(
const
QPoint &pt)
499
{
500
Q_D(QWaylandOutput);
501
if
(d->position == pt)
502
return
;
503
504
d->position = pt;
505
506
d->sendGeometryInfo();
507
508
Q_EMIT positionChanged();
509
Q_EMIT geometryChanged();
510
}
511
512
/*!
513
* Returns the list of modes.
514
*/
515
QList<QWaylandOutputMode> QWaylandOutput::modes()
const
516
{
517
Q_D(
const
QWaylandOutput);
518
return
d->modes.toList();
519
}
520
521
/*!
522
* Adds the mode \a mode to the output and mark it as preferred
523
* if \a preferred is \c true.
524
* Please note there can only be one preferred mode.
525
*/
526
void
QWaylandOutput::addMode(
const
QWaylandOutputMode &mode,
bool
preferred)
527
{
528
Q_D(QWaylandOutput);
529
530
if
(!mode.isValid()) {
531
qWarning(
"Cannot add an invalid mode"
);
532
return
;
533
}
534
535
int
index = d->modes.indexOf(mode);
536
if
(index < 0) {
537
d->modes.append(mode);
538
index = d->modes.size() - 1;
539
}
540
541
if
(preferred)
542
d->preferredMode = index;
543
544
emit modeAdded();
545
}
546
547
/*!
548
* Returns the output's size in pixels and refresh rate in mHz.
549
* If the current mode is not set it will return an invalid mode.
550
*
551
* \sa QWaylandOutput::modes
552
* \sa QWaylandOutputMode
553
*/
554
QWaylandOutputMode QWaylandOutput::currentMode()
const
555
{
556
Q_D(
const
QWaylandOutput);
557
558
return
d->modes.value(d->currentMode);
559
}
560
561
/*!
562
* Sets the current mode.
563
* The mode \a mode must have been previously added.
564
*
565
* \sa QWaylandOutput::modes
566
* \sa QWaylandOutputMode
567
*/
568
void
QWaylandOutput::setCurrentMode(
const
QWaylandOutputMode &mode)
569
{
570
Q_D(QWaylandOutput);
571
572
int
index = d->modes.indexOf(mode);
573
if
(index < 0) {
574
qWarning(
"Cannot set an unknown QWaylandOutput mode as current"
);
575
return
;
576
}
577
578
d->currentMode = index;
579
580
Q_EMIT currentModeChanged();
581
Q_EMIT geometryChanged();
582
if
(!d->availableGeometry.isValid())
583
emit availableGeometryChanged();
584
585
d->sendModesInfo();
586
}
587
588
/*!
589
* \qmlproperty rect QtWayland.Compositor::WaylandOutput::geometry
590
*
591
* This property holds the geometry of the WaylandOutput.
592
*/
593
594
/*!
595
* \property QWaylandOutput::geometry
596
*
597
* This property holds the geometry of the QWaylandOutput.
598
*
599
* \sa QWaylandOutput::currentMode
600
*/
601
QRect QWaylandOutput::geometry()
const
602
{
603
Q_D(
const
QWaylandOutput);
604
return
QRect(d->position, currentMode().size());
605
}
606
607
/*!
608
* \qmlproperty rect QtWayland.Compositor::WaylandOutput::availableGeometry
609
*
610
* This property holds the geometry of the WaylandOutput available for displaying content.
611
* The available geometry is in output coordinates space, starts from 0,0 and it's as big
612
* as the output by default.
613
*
614
* \sa QWaylandOutput::geometry
615
*/
616
617
/*!
618
* \property QWaylandOutput::availableGeometry
619
*
620
* This property holds the geometry of the QWaylandOutput available for displaying content.
621
* The available geometry is in output coordinates space, starts from 0,0 and it's as big
622
* as the output by default.
623
*
624
* \sa QWaylandOutput::currentMode, QWaylandOutput::geometry
625
*/
626
QRect QWaylandOutput::availableGeometry()
const
627
{
628
Q_D(
const
QWaylandOutput);
629
630
if
(!d->availableGeometry.isValid())
631
return
QRect(QPoint(0, 0), currentMode().size());
632
633
return
d->availableGeometry;
634
}
635
636
void
QWaylandOutput::setAvailableGeometry(
const
QRect &availableGeometry)
637
{
638
Q_D(QWaylandOutput);
639
if
(d->availableGeometry == availableGeometry)
640
return
;
641
642
if
(availableGeometry.topLeft().x() < 0 || availableGeometry.topLeft().y() < 0)
643
qWarning(
"Available geometry should be a portion of the output"
);
644
645
d->availableGeometry = availableGeometry;
646
647
Q_EMIT availableGeometryChanged();
648
}
649
650
/*!
651
* \qmlproperty size QtWayland.Compositor::WaylandOutput::physicalSize
652
*
653
* This property holds the physical size of the WaylandOutput in millimeters.
654
*
655
* \sa QWaylandOutput::geometry
656
*/
657
658
/*!
659
* \property QWaylandOutput::physicalSize
660
*
661
* This property holds the physical size of the QWaylandOutput in millimeters.
662
*
663
* \sa QWaylandOutput::geometry, QWaylandOutput::currentMode
664
*/
665
QSize QWaylandOutput::physicalSize()
const
666
{
667
return
d_func()->physicalSize;
668
}
669
670
void
QWaylandOutput::setPhysicalSize(
const
QSize &size)
671
{
672
Q_D(QWaylandOutput);
673
if
(d->physicalSize == size)
674
return
;
675
676
d->physicalSize = size;
677
678
d->sendGeometryInfo();
679
680
Q_EMIT physicalSizeChanged();
681
}
682
683
/*!
684
* \enum QWaylandOutput::Subpixel
685
*
686
* This enum type is used to specify the subpixel arrangement of a QWaylandOutput.
687
*
688
* \value SubpixelUnknown The subpixel arrangement is not set.
689
* \value SubpixelNone There are no subpixels.
690
* \value SubpixelHorizontalRgb The subpixels are arranged horizontally in red, green, blue order.
691
* \value SubpixelHorizontalBgr The subpixels are arranged horizontally in blue, green, red order.
692
* \value SubpixelVerticalRgb The subpixels are arranged vertically in red, green, blue order.
693
* \value SubpixelVerticalBgr The subpixels are arranged vertically in blue, green, red order.
694
*
695
* \sa QWaylandOutput::subpixel
696
*/
697
698
/*!
699
* \qmlproperty enum QtWayland.Compositor::WaylandOutput::subpixel
700
*
701
* This property holds the subpixel arrangement of this WaylandOutput.
702
*
703
* \list
704
* \li WaylandOutput.SubpixelUnknown The subpixel arrangement is not set.
705
* \li WaylandOutput.SubpixelNone There are no subpixels.
706
* \li WaylandOutput.SubpixelHorizontalRgb The subpixels are arranged horizontally in red, green, blue order.
707
* \li WaylandOutput.SubpixelHorizontalBgr The subpixels are arranged horizontally in blue, green, red order.
708
* \li WaylandOutput.SubpixelVerticalRgb The subpixels are arranged vertically in red, green, blue order.
709
* \li WaylandOutput.SubpixelVerticalBgr The subpixels are arranged vertically in blue, green, red order.
710
* \endlist
711
*
712
* The default is WaylandOutput.SubpixelUnknown.
713
*/
714
715
/*!
716
* \property QWaylandOutput::subpixel
717
*
718
* This property holds the subpixel arrangement of this QWaylandOutput. The default is
719
* QWaylandOutput::SubpixelUnknown.
720
*/
721
QWaylandOutput::Subpixel QWaylandOutput::subpixel()
const
722
{
723
return
d_func()->subpixel;
724
}
725
726
void
QWaylandOutput::setSubpixel(
const
Subpixel &subpixel)
727
{
728
Q_D(QWaylandOutput);
729
if
(d->subpixel == subpixel)
730
return
;
731
732
d->subpixel = subpixel;
733
734
d->sendGeometryInfo();
735
736
Q_EMIT subpixelChanged();
737
}
738
739
/*! \enum QWaylandOutput::Transform
740
*
741
* This enum type is used to specify the orientation of a QWaylandOutput.
742
*
743
* \value TransformNormal The orientation is normal.
744
* \value Transform90 The orientation is rotated 90 degrees.
745
* \value Transform180 The orientation is rotated 180 degrees.
746
* \value Transform270 The orientation is rotated 270 degrees.
747
* \value TransformFlipped The orientation is mirrored.
748
* \value TransformFlipped90 The orientation is mirrored, and rotated 90 degrees.
749
* \value TransformFlipped180 The orientation is mirrored, and rotated 180 degrees.
750
* \value TransformFlipped270 The orientation is mirrored, and rotated 270 degrees.
751
*
752
* \sa QWaylandOutput::transform
753
*/
754
755
/*!
756
* \qmlproperty enum QtWayland.Compositor::WaylandOutput::transform
757
*
758
* This property holds the transformation that the QWaylandCompositor applies to a surface
759
* to compensate for the orientation of the QWaylandOutput.
760
*
761
* \list
762
* \li WaylandOutput.TransformNormal The orientation is normal.
763
* \li WaylandOutput.Transform90 The orientation is rotated 90 degrees.
764
* \li WaylandOutput.Transform180 The orientation is rotated 180 degrees.
765
* \li WaylandOutput.Transform270 The orientation is rotated 270 degrees.
766
* \li WaylandOutput.TransformFlipped The orientation is mirrored.
767
* \li WaylandOutput.TransformFlipped90 The orientation is mirrored, then rotated 90 degrees.
768
* \li WaylandOutput.TransformFlipped180 The orientation is mirrored, then rotated 180 degrees.
769
* \li WaylandOutput.TransformFlipped270 The orientation is mirrored, then rotated 270 degrees.
770
* \endlist
771
*
772
* The default is WaylandOutput.TransformNormal.
773
*/
774
775
/*!
776
* \property QWaylandOutput::transform
777
*
778
* This property holds the transformation that the QWaylandCompositor applies to a surface
779
* to compensate for the orientation of the QWaylandOutput.
780
*
781
* The default is QWaylandOutput::TransformNormal.
782
*/
783
QWaylandOutput::Transform QWaylandOutput::transform()
const
784
{
785
return
d_func()->transform;
786
}
787
788
void
QWaylandOutput::setTransform(
const
Transform &transform)
789
{
790
Q_D(QWaylandOutput);
791
if
(d->transform == transform)
792
return
;
793
794
d->transform = transform;
795
796
d->sendGeometryInfo();
797
798
Q_EMIT transformChanged();
799
}
800
801
/*!
802
* \qmlproperty int QtWayland.Compositor::WaylandOutput::scaleFactor
803
*
804
* This property holds the factor by which the WaylandCompositor scales surface buffers
805
* before they are displayed. It is used on high density output devices where unscaled content
806
* would be too small to be practical. The client can in turn set the scale factor of its
807
* buffer to match the output if it prefers to provide high resolution content that is
808
* suitable for the output device.
809
*
810
* The default is 1 (no scaling).
811
*/
812
813
/*!
814
* \property QWaylandOutput::scaleFactor
815
*
816
* This property holds the factor by which the QWaylandCompositor scales surface buffers
817
* before they are displayed. This is used on high density output devices where unscaled content
818
* would be too small to be practical. The client can in turn set the scale factor of its
819
* buffer to match the output if it prefers to provide high resolution content that is
820
* suitable for the output device.
821
*
822
* The default is 1 (no scaling).
823
*/
824
int
QWaylandOutput::scaleFactor()
const
825
{
826
return
d_func()->scaleFactor;
827
}
828
829
void
QWaylandOutputPrivate::maybeSendScale(
const
Resource *resource,
830
int
scale)
831
{
832
if
(resource->version() >= 2)
833
send_scale(resource->handle, scale);
834
}
835
836
void
QWaylandOutput::setScaleFactor(
int
scale)
837
{
838
Q_D(QWaylandOutput);
839
if
(d->scaleFactor == scale)
840
return
;
841
842
d->scaleFactor = scale;
843
844
const
auto
resMap = d->resourceMap();
845
for
(QWaylandOutputPrivate::Resource *resource : resMap) {
846
d->maybeSendScale(resource, scale);
847
d->maybeSendDone(resource);
848
}
849
850
Q_EMIT scaleFactorChanged();
851
}
852
853
/*!
854
* \qmlproperty bool QtWayland.Compositor::WaylandOutput::sizeFollowsWindow
855
* \default false
856
*
857
* This property controls whether the size of the WaylandOutput matches the
858
* size of its window.
859
*
860
* If this property is true, all modes previously added are replaced by a
861
* mode that matches window size and screen refresh rate. It is especially
862
* useful in a nested compositor setup during development.
863
*/
864
865
/*!
866
* \property QWaylandOutput::sizeFollowsWindow
867
*
868
* This property controls whether the size of the QWaylandOutput matches the
869
* size of its window.
870
*
871
* If this property is true, all modes previously added are replaced by a
872
* mode that matches window size and screen refresh rate.
873
*
874
* The default is false.
875
*/
876
bool
QWaylandOutput::sizeFollowsWindow()
const
877
{
878
return
d_func()->sizeFollowsWindow;
879
}
880
881
void
QWaylandOutput::setSizeFollowsWindow(
bool
follow)
882
{
883
Q_D(QWaylandOutput);
884
885
if
(follow != d->sizeFollowsWindow) {
886
d->sizeFollowsWindow = follow;
887
Q_EMIT sizeFollowsWindowChanged();
888
}
889
}
890
891
/*!
892
* \qmlproperty Window QtWayland.Compositor::WaylandOutput::window
893
*
894
* This property holds the Window for this WaylandOutput.
895
*
896
* \note This property can be set only once, before the WaylandOutput
897
* component is completed.
898
*/
899
900
/*!
901
* \property QWaylandOutput::window
902
*
903
* This property holds the QWindow for this QWaylandOutput.
904
*/
905
QWindow *QWaylandOutput::window()
const
906
{
907
return
d_func()->window;
908
}
909
910
void
QWaylandOutput::setWindow(QWindow *window)
911
{
912
Q_D(QWaylandOutput);
913
if
(d->window == window)
914
return
;
915
if
(d->initialized) {
916
qWarning(
"Setting QWindow %p on QWaylandOutput %p is not supported after QWaylandOutput has been initialized\n"
, window,
this
);
917
return
;
918
}
919
d->window = window;
920
emit windowChanged();
921
}
922
923
/*!
924
* Informs QWaylandOutput that a frame has started.
925
*/
926
void
QWaylandOutput::frameStarted()
927
{
928
Q_D(QWaylandOutput);
929
930
d->canSendFrameCallbacks =
true
;
931
932
for
(
const
QWaylandSurfaceViewMapper &surfacemapper : std::as_const(d->surfaceViews)) {
933
if
(QWaylandView *primaryView = surfacemapper.maybePrimaryView()) {
934
if
(Q_LIKELY(!QWaylandViewPrivate::get(primaryView)->independentFrameCallback))
935
surfacemapper.surface->frameStarted();
936
}
937
}
938
}
939
940
/*!
941
* Sends pending frame callbacks.
942
*/
943
void
QWaylandOutput::sendFrameCallbacks()
944
{
945
Q_D(QWaylandOutput);
946
947
if
(Q_UNLIKELY(!d->canSendFrameCallbacks))
948
return
;
949
950
d->canSendFrameCallbacks =
false
;
951
952
for
(
int
i = 0; i < d->surfaceViews.size(); i++) {
953
const
QWaylandSurfaceViewMapper &surfacemapper = d->surfaceViews.at(i);
954
if
(surfacemapper.surface && surfacemapper.surface->hasContent()) {
955
if
(!surfacemapper.has_entered) {
956
surfaceEnter(surfacemapper.surface);
957
d->surfaceViews[i].has_entered =
true
;
958
}
959
if
(
auto
primaryView = surfacemapper.maybePrimaryView()) {
960
if
(!QWaylandViewPrivate::get(primaryView)->independentFrameCallback)
961
surfacemapper.surface->sendFrameCallbacks();
962
}
963
}
964
}
965
wl_display_flush_clients(d->compositor->display());
966
}
967
968
/*!
969
* \internal
970
*/
971
void
QWaylandOutput::surfaceEnter(QWaylandSurface *surface)
972
{
973
if
(!surface)
974
return
;
975
976
auto
clientResource = resourceForClient(surface->client());
977
if
(clientResource)
978
QWaylandSurfacePrivate::get(surface)->send_enter(clientResource);
979
}
980
981
/*!
982
* \internal
983
*/
984
void
QWaylandOutput::surfaceLeave(QWaylandSurface *surface)
985
{
986
if
(!surface || !surface->client())
987
return
;
988
989
auto
*clientResource = resourceForClient(surface->client());
990
if
(clientResource)
991
QWaylandSurfacePrivate::get(surface)->send_leave(clientResource);
992
}
993
994
/*!
995
* \internal
996
*/
997
bool
QWaylandOutput::event(QEvent *event)
998
{
999
if
(event->type() == QEvent::Polish)
1000
initialize();
1001
return
QObject::event(event);
1002
}
1003
1004
QT_END_NAMESPACE
1005
1006
#
include
"moc_qwaylandoutput.cpp"
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
toWlTransform
static QtWaylandServer::wl_output::transform toWlTransform(const QWaylandOutput::Transform &value)
Definition
qwaylandoutput.cpp:48
toWlSubpixel
static QT_BEGIN_NAMESPACE QtWaylandServer::wl_output::subpixel toWlSubpixel(const QWaylandOutput::Subpixel &value)
Definition
qwaylandoutput.cpp:26
qtwayland
src
compositor
compositor_api
qwaylandoutput.cpp
Generated on
for Qt by
1.18.0