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
qwaylandscreen.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
include
"qwaylandscreen_p.h"
6
7
#
include
"qwaylanddisplay_p.h"
8
#
include
"qwaylandintegration_p.h"
9
#
include
"qwaylandcursor_p.h"
10
#
include
"qwaylandwindow_p.h"
11
12
#
include
<
QtGui
/
QGuiApplication
>
13
14
#
include
<
qpa
/
qwindowsysteminterface
.
h
>
15
#
include
<
qpa
/
qplatformwindow
.
h
>
16
17
QT_BEGIN_NAMESPACE
18
19
namespace
QtWaylandClient
{
20
21
QWaylandXdgOutputManagerV1
::
QWaylandXdgOutputManagerV1
(
QWaylandDisplay
*
display
,
uint
id
,
uint
version
)
22
:
QtWayland
::
zxdg_output_manager_v1
(
display
->
wl_registry
(),
id
,
qMin
(3u,
version
))
23
{
24
}
25
26
QWaylandXdgOutputManagerV1
::~
QWaylandXdgOutputManagerV1
()
27
{
28
destroy
();
29
}
30
31
QWaylandScreen
::
QWaylandScreen
(
QWaylandDisplay
*
waylandDisplay
,
int
version
,
uint32_t
id
)
32
:
QtWayland
::
wl_output
(
waylandDisplay
->
wl_registry
(),
id
,
qMin
(
version
, 4))
33
,
m_outputId
(
id
)
34
,
mWaylandDisplay
(
waylandDisplay
)
35
,
mOutputName
(
QStringLiteral
(
"Screen%1"
).
arg
(
id
))
36
{
37
if
(
auto
*
xdgOutputManager
=
waylandDisplay
->
xdgOutputManager
())
38
initXdgOutput
(
xdgOutputManager
);
39
40
if
(
version
<
WL_OUTPUT_DONE_SINCE_VERSION
) {
41
qCWarning
(
lcQpaWayland
) <<
"wl_output done event not supported by compositor,"
42
<<
"QScreen may not work correctly"
;
43
mWaylandDisplay
->
forceRoundTrip
();
// Give the compositor a chance to send geometry etc.
44
mProcessedEvents
|=
OutputDoneEvent
;
// Fake the done event
45
maybeInitialize
();
46
}
47
}
48
49
QWaylandScreen
::~
QWaylandScreen
()
50
{
51
if
(
zxdg_output_v1
::
isInitialized
())
52
zxdg_output_v1
::
destroy
();
53
if
(
wl_output
::
version
() >=
WL_OUTPUT_RELEASE_SINCE_VERSION
)
54
wl_output
::
release
();
55
else
56
wl_output_destroy
(
wl_output
::
object
());
57
}
58
59
uint
QWaylandScreen
::
requiredEvents
()
const
60
{
61
uint
ret
=
OutputDoneEvent
;
62
63
if
(
mWaylandDisplay
->
xdgOutputManager
()) {
64
if
(
mWaylandDisplay
->
xdgOutputManager
()->
version
() >=
ZXDG_OUTPUT_V1_NAME_SINCE_VERSION
)
65
ret
|=
XdgOutputNameEvent
;
66
67
// For objects version 3 onwards, zxdg_output_v1.done is deprecated.
68
if
(
mWaylandDisplay
->
xdgOutputManager
()->
version
() < 3)
69
ret
|=
XdgOutputDoneEvent
;
70
}
71
return
ret
;
72
}
73
74
void
QWaylandScreen
::
maybeInitialize
()
75
{
76
Q_ASSERT
(!
mInitialized
);
77
78
const
uint
requiredEvents
=
this
->
requiredEvents
();
79
if
((
mProcessedEvents
&
requiredEvents
) !=
requiredEvents
)
80
return
;
81
82
mInitialized
=
true
;
83
mWaylandDisplay
->
handleScreenInitialized
(
this
);
84
85
updateOutputProperties
();
86
if
(
zxdg_output_v1
::
isInitialized
())
87
updateXdgOutputProperties
();
88
}
89
90
void
QWaylandScreen
::
initXdgOutput
(
QWaylandXdgOutputManagerV1
*
xdgOutputManager
)
91
{
92
Q_ASSERT
(
xdgOutputManager
);
93
if
(
zxdg_output_v1
::
isInitialized
())
94
return
;
95
96
zxdg_output_v1
::
init
(
xdgOutputManager
->
get_xdg_output
(
wl_output
::
object
()));
97
}
98
99
QWaylandDisplay
*
QWaylandScreen
::
display
()
const
100
{
101
return
mWaylandDisplay
;
102
}
103
104
QString
QWaylandScreen
::
manufacturer
()
const
105
{
106
return
mManufacturer
;
107
}
108
109
QString
QWaylandScreen
::
model
()
const
110
{
111
return
mModel
;
112
}
113
114
QRect
QWaylandScreen
::
geometry
()
const
115
{
116
if
(
zxdg_output_v1
::
isInitialized
()) {
117
118
// Workaround for Gnome bug
119
// https://gitlab.gnome.org/GNOME/mutter/-/issues/2631
120
// which sends an incorrect xdg geometry
121
const
bool
xdgGeometryIsBogus
=
mScale
> 1 &&
mXdgGeometry
.
size
() ==
mGeometry
.
size
();
122
123
if
(!
xdgGeometryIsBogus
) {
124
return
mXdgGeometry
;
125
}
126
}
127
// Scale geometry for QScreen. This makes window and screen
128
// geometry be in the same coordinate system.
129
return
QRect
(
mGeometry
.
topLeft
(),
mGeometry
.
size
() /
mScale
);
130
}
131
132
int
QWaylandScreen
::
depth
()
const
133
{
134
return
mDepth
;
135
}
136
137
QImage
::
Format
QWaylandScreen
::
format
()
const
138
{
139
return
mFormat
;
140
}
141
142
QSizeF
QWaylandScreen
::
physicalSize
()
const
143
{
144
if
(
mPhysicalSize
.
isEmpty
())
145
return
QPlatformScreen
::
physicalSize
();
146
else
147
return
mPhysicalSize
;
148
}
149
150
QDpi
QWaylandScreen
::
logicalDpi
()
const
151
{
152
static
bool
physicalDpi
=
qEnvironmentVariable
(
"QT_WAYLAND_FORCE_DPI"
) ==
QStringLiteral
(
"physical"
);
153
if
(
physicalDpi
)
154
return
QPlatformScreen
::
logicalDpi
();
155
156
static
int
forceDpi
=
qgetenv
(
"QT_WAYLAND_FORCE_DPI"
).
toInt
();
157
if
(
forceDpi
)
158
return
QDpi
(
forceDpi
,
forceDpi
);
159
160
return
QDpi
(96, 96);
161
}
162
163
QList
<
QPlatformScreen
*>
QWaylandScreen
::
virtualSiblings
()
const
164
{
165
QList
<
QPlatformScreen
*>
list
;
166
const
QList
<
QWaylandScreen
*>
screens
=
mWaylandDisplay
->
screens
();
167
auto
*
placeholder
=
mWaylandDisplay
->
placeholderScreen
();
168
169
list
.
reserve
(
screens
.
size
() + (
placeholder
? 1 : 0));
170
171
for
(
QWaylandScreen
*
screen
:
std
::
as_const
(
screens
)) {
172
if
(
screen
->
screen
())
173
list
<<
screen
;
174
}
175
176
if
(
placeholder
)
177
list
<<
placeholder
;
178
179
return
list
;
180
}
181
182
Qt
::
ScreenOrientation
QWaylandScreen
::
orientation
()
const
183
{
184
return
m_orientation
;
185
}
186
187
int
QWaylandScreen
::
scale
()
const
188
{
189
return
mScale
;
190
}
191
192
qreal
QWaylandScreen
::
devicePixelRatio
()
const
193
{
194
return
qreal
(
mScale
);
195
}
196
197
qreal
QWaylandScreen
::
refreshRate
()
const
198
{
199
return
mRefreshRate
/ 1000.f;
200
}
201
202
#
if
QT_CONFIG
(
cursor
)
203
QPlatformCursor
*
QWaylandScreen
::
cursor
()
const
204
{
205
return
mWaylandDisplay
->
waylandCursor
();
206
}
207
#
endif
// QT_CONFIG(cursor)
208
209
QPlatformScreen
::
SubpixelAntialiasingType
QWaylandScreen
::
subpixelAntialiasingTypeHint
()
const
210
{
211
QPlatformScreen
::
SubpixelAntialiasingType
type
=
QPlatformScreen
::
subpixelAntialiasingTypeHint
();
212
if
(
type
==
QPlatformScreen
::
Subpixel_None
) {
213
switch
(
mSubpixel
) {
214
case
wl_output
::
subpixel_unknown
:
215
case
wl_output
::
subpixel_none
:
216
type
=
QPlatformScreen
::
Subpixel_None
;
217
break
;
218
case
wl_output
::
subpixel_horizontal_rgb
:
219
type
=
QPlatformScreen
::
Subpixel_RGB
;
220
break
;
221
case
wl_output
::
subpixel_horizontal_bgr
:
222
type
=
QPlatformScreen
::
Subpixel_BGR
;
223
break
;
224
case
wl_output
::
subpixel_vertical_rgb
:
225
type
=
QPlatformScreen
::
Subpixel_VRGB
;
226
break
;
227
case
wl_output
::
subpixel_vertical_bgr
:
228
type
=
QPlatformScreen
::
Subpixel_VBGR
;
229
break
;
230
}
231
}
232
return
type
;
233
}
234
235
QWaylandScreen
*
QWaylandScreen
::
waylandScreenFromWindow
(
QWindow
*
window
)
236
{
237
QPlatformScreen
*
platformScreen
=
QPlatformScreen
::
platformScreenForWindow
(
window
);
238
if
(
platformScreen
->
isPlaceholder
())
239
return
nullptr
;
240
return
static_cast
<
QWaylandScreen
*>(
platformScreen
);
241
}
242
243
QWaylandScreen
*
QWaylandScreen
::
fromWlOutput
(::
wl_output
*
output
)
244
{
245
if
(
auto
*
o
=
QtWayland
::
wl_output
::
fromObject
(
output
))
246
return
static_cast
<
QWaylandScreen
*>(
o
);
247
return
nullptr
;
248
}
249
250
Qt
::
ScreenOrientation
QWaylandScreen
::
toScreenOrientation
(
int
wlTransform
,
251
Qt
::
ScreenOrientation
fallback
)
const
252
{
253
auto
orientation
=
fallback
;
254
bool
isPortrait
=
mGeometry
.
height
() >
mGeometry
.
width
();
255
switch
(
wlTransform
) {
256
case
WL_OUTPUT_TRANSFORM_NORMAL
:
257
orientation
=
isPortrait
?
Qt
::
PortraitOrientation
:
Qt
::
LandscapeOrientation
;
258
break
;
259
case
WL_OUTPUT_TRANSFORM_90
:
260
orientation
=
isPortrait
?
Qt
::
InvertedLandscapeOrientation
:
Qt
::
PortraitOrientation
;
261
break
;
262
case
WL_OUTPUT_TRANSFORM_180
:
263
orientation
=
isPortrait
?
Qt
::
InvertedPortraitOrientation
:
Qt
::
InvertedLandscapeOrientation
;
264
break
;
265
case
WL_OUTPUT_TRANSFORM_270
:
266
orientation
=
isPortrait
?
Qt
::
LandscapeOrientation
:
Qt
::
InvertedPortraitOrientation
;
267
break
;
268
// Ignore these ones, at least for now
269
case
WL_OUTPUT_TRANSFORM_FLIPPED
:
270
case
WL_OUTPUT_TRANSFORM_FLIPPED_90
:
271
case
WL_OUTPUT_TRANSFORM_FLIPPED_180
:
272
case
WL_OUTPUT_TRANSFORM_FLIPPED_270
:
273
break
;
274
}
275
276
return
orientation
;
277
}
278
279
void
QWaylandScreen
::
output_mode
(
uint32_t
flags
,
int
width
,
int
height
,
int
refresh
)
280
{
281
if
(!(
flags
&
WL_OUTPUT_MODE_CURRENT
))
282
return
;
283
284
QSize
size
(
width
,
height
);
285
if
(
size
!=
mGeometry
.
size
())
286
mGeometry
.
setSize
(
size
);
287
288
if
(
refresh
!=
mRefreshRate
)
289
mRefreshRate
=
refresh
;
290
}
291
292
void
QWaylandScreen
::
output_geometry
(
int32_t
x
,
int32_t
y
,
293
int32_t
width
,
int32_t
height
,
294
int
subpixel
,
295
const
QString
&
make
,
296
const
QString
&
model
,
297
int32_t
transform
)
298
{
299
mManufacturer
=
make
;
300
mModel
=
model
;
301
302
mSubpixel
=
subpixel
;
303
mTransform
=
transform
;
304
305
mPhysicalSize
=
QSize
(
width
,
height
);
306
mGeometry
.
moveTopLeft
(
QPoint
(
x
,
y
));
307
}
308
309
void
QWaylandScreen
::
output_scale
(
int32_t
factor
)
310
{
311
mScale
=
factor
;
312
}
313
314
void
QWaylandScreen
::
output_done
()
315
{
316
mProcessedEvents
|=
OutputDoneEvent
;
317
318
if
(
mInitialized
) {
319
updateOutputProperties
();
320
if
(
zxdg_output_v1
::
isInitialized
())
321
updateXdgOutputProperties
();
322
}
else
{
323
maybeInitialize
();
324
}
325
}
326
327
void
QWaylandScreen
::
output_name
(
const
QString
&
name
)
328
{
329
if
(
Q_UNLIKELY
(
mInitialized
)) {
330
qCWarning
(
lcQpaWayland
) <<
"wl_output.name received after output has been initialized, this is most likely a bug in the compositor"
;
331
return
;
332
}
333
334
if
(
Q_UNLIKELY
(
mProcessedEvents
&
OutputNameEvent
)) {
335
qCWarning
(
lcQpaWayland
) <<
"wl_output.name received more than once, this is most likely a bug in the compositor"
;
336
return
;
337
}
338
339
if
(!
name
.
isEmpty
())
340
mOutputName
=
name
;
341
342
mProcessedEvents
|=
OutputNameEvent
;
343
}
344
345
void
QWaylandScreen
::
updateOutputProperties
()
346
{
347
Q_ASSERT
(
mInitialized
);
348
349
if
(
mTransform
>= 0) {
350
auto
newOrientation
=
toScreenOrientation
(
mTransform
,
m_orientation
);
351
if
(
m_orientation
!=
newOrientation
) {
352
m_orientation
=
newOrientation
;
353
QWindowSystemInterface
::
handleScreenOrientationChange
(
screen
(),
m_orientation
);
354
}
355
mTransform
= -1;
356
}
357
358
QWindowSystemInterface
::
handleScreenRefreshRateChange
(
screen
(),
refreshRate
());
359
360
if
(!
zxdg_output_v1
::
isInitialized
())
361
QWindowSystemInterface
::
handleScreenGeometryChange
(
screen
(),
geometry
(),
availableGeometry
());
362
}
363
364
365
void
QWaylandScreen
::
zxdg_output_v1_logical_position
(
int32_t
x
,
int32_t
y
)
366
{
367
mXdgGeometry
.
moveTopLeft
(
QPoint
(
x
,
y
));
368
}
369
370
void
QWaylandScreen
::
zxdg_output_v1_logical_size
(
int32_t
width
,
int32_t
height
)
371
{
372
mXdgGeometry
.
setSize
(
QSize
(
width
,
height
));
373
}
374
375
void
QWaylandScreen
::
zxdg_output_v1_done
()
376
{
377
if
(
Q_UNLIKELY
(
mWaylandDisplay
->
xdgOutputManager
()->
version
() >= 3))
378
qCWarning
(
lcQpaWayland
) <<
"zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor"
;
379
380
mProcessedEvents
|=
XdgOutputDoneEvent
;
381
if
(
mInitialized
)
382
updateXdgOutputProperties
();
383
else
384
maybeInitialize
();
385
}
386
387
void
QWaylandScreen
::
zxdg_output_v1_name
(
const
QString
&
name
)
388
{
389
if
(
Q_UNLIKELY
(
mInitialized
))
390
qCWarning
(
lcQpaWayland
) <<
"zxdg_output_v1.name received after output has been initialized, this is most likely a bug in the compositor"
;
391
392
if
(
Q_UNLIKELY
(
mProcessedEvents
&
XdgOutputNameEvent
)) {
393
qCWarning
(
lcQpaWayland
) <<
"zxdg_output_v1.name received more than once, this is most likely a bug in the compositor"
;
394
return
;
395
}
396
397
// This event is deprecated, instead clients should use wl_output.name.
398
if
(!(
mProcessedEvents
&
OutputNameEvent
)) {
399
if
(!
name
.
isEmpty
())
400
mOutputName
=
name
;
401
}
402
403
mProcessedEvents
|=
XdgOutputNameEvent
;
404
}
405
406
void
QWaylandScreen
::
updateXdgOutputProperties
()
407
{
408
Q_ASSERT
(
mInitialized
);
409
Q_ASSERT
(
zxdg_output_v1
::
isInitialized
());
410
QWindowSystemInterface
::
handleScreenGeometryChange
(
screen
(),
geometry
(),
availableGeometry
());
411
}
412
413
}
// namespace QtWaylandClient
414
415
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qrandomaccessasyncfile_darwin.mm:17
QtWaylandClient
Definition
qwaylandclientextension.h:16
qtbase
src
plugins
platforms
wayland
qwaylandscreen.cpp
Generated on
for Qt by
1.16.1