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