Coverage Report

Created: 2026-10-14 08:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/kernel/qscreen.cpp
Line
Count
Source
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 "qscreen.h"
6
#include "qscreen_p.h"
7
#include "qpixmap.h"
8
#include "qguiapplication_p.h"
9
#include <qpa/qplatformscreen.h>
10
#include <qpa/qplatformscreen_p.h>
11
12
#include <QtCore/QDebug>
13
#include <QtCore/private/qobject_p.h>
14
#include "qhighdpiscaling_p.h"
15
16
QT_BEGIN_NAMESPACE
17
18
/*!
19
    \class QScreen
20
    \since 5.0
21
    \brief The QScreen class is used to query screen properties.
22
    \inmodule QtGui
23
24
    A note on logical vs physical dots per inch: physical DPI is based on the
25
    actual physical pixel sizes when available, and is useful for print preview
26
    and other cases where it's desirable to know the exact physical dimensions
27
    of screen displayed contents.
28
29
    Logical dots per inch are used to convert font and user interface elements
30
    from point sizes to pixel sizes, and might be different from the physical
31
    dots per inch. The logical dots per inch are sometimes user-settable in the
32
    desktop environment's settings panel, to let the user globally control UI
33
    and font sizes in different applications.
34
35
    \note Both physical and logical DPI are expressed in device-independent dots.
36
    Multiply by QScreen::devicePixelRatio() to get device-dependent density.
37
38
    To obtain a QScreen object, use QGuiApplication::primaryScreen() for the
39
    primary screen, or QGuiApplication::screens() to get a list of all screens.
40
41
    \sa QGuiApplication::primaryScreen()
42
    \sa QGuiApplication::screens()
43
44
    \inmodule QtGui
45
*/
46
47
QScreen::QScreen(QPlatformScreen *platformScreen)
48
0
    : QObject(*new QScreenPrivate(), nullptr)
49
0
{
50
0
    Q_D(QScreen);
51
52
0
    d->platformScreen = platformScreen;
53
0
    platformScreen->d_func()->screen = this;
54
55
0
    d->orientation = platformScreen->orientation();
56
0
    d->logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
57
0
    d->refreshRate = platformScreen->refreshRate();
58
    // safeguard ourselves against buggy platform behavior...
59
0
    if (d->refreshRate < 1.0)
60
0
        d->refreshRate = 60.0;
61
62
0
    d->updateGeometry();
63
0
    d->updatePrimaryOrientation(); // derived from the geometry
64
0
}
65
66
void QScreenPrivate::updateGeometry()
67
0
{
68
0
    geometry = QHighDpi::fromNativeGlobalPosition(platformScreen->geometry(), platformScreen);
69
0
    availableGeometry = QHighDpi::fromNativeGlobalPosition(platformScreen->availableGeometry(), platformScreen);
70
0
}
71
72
/*!
73
    Destroys the screen.
74
75
    \internal
76
 */
77
QScreen::~QScreen()
78
0
{
79
0
    Q_ASSERT_X(!QGuiApplicationPrivate::screen_list.contains(this), "QScreen",
80
0
        "QScreens should be removed via QWindowSystemInterface::handleScreenRemoved()");
81
0
}
82
83
/*!
84
  Get the platform screen handle.
85
86
  \sa {Qt Platform Abstraction}{Qt Platform Abstraction (QPA)}
87
*/
88
QPlatformScreen *QScreen::handle() const
89
0
{
90
0
    Q_D(const QScreen);
91
0
    return d->platformScreen;
92
0
}
93
94
/*!
95
  \property QScreen::name
96
  \brief a user presentable string representing the screen
97
98
  For example, on X11 these correspond to the XRandr screen names,
99
  typically "VGA1", "HDMI1", etc.
100
101
  \note The user presentable string is not guaranteed to match the
102
  result of any native APIs, and should not be used to uniquely identify
103
  a screen.
104
*/
105
QString QScreen::name() const
106
0
{
107
0
    Q_D(const QScreen);
108
0
    return d->platformScreen->name();
109
0
}
110
111
/*!
112
  \property QScreen::manufacturer
113
  \brief the manufacturer of the screen
114
115
  \since 5.9
116
*/
117
QString QScreen::manufacturer() const
118
0
{
119
0
    Q_D(const QScreen);
120
0
    return d->platformScreen->manufacturer();
121
0
}
122
123
/*!
124
  \property QScreen::model
125
  \brief the model of the screen
126
127
  \since 5.9
128
*/
129
QString QScreen::model() const
130
0
{
131
0
    Q_D(const QScreen);
132
0
    return d->platformScreen->model();
133
0
}
134
135
/*!
136
  \property QScreen::serialNumber
137
  \brief the serial number of the screen
138
139
  \since 5.9
140
*/
141
QString QScreen::serialNumber() const
142
0
{
143
0
    Q_D(const QScreen);
144
0
    return d->platformScreen->serialNumber();
145
0
}
146
147
/*!
148
  \property QScreen::depth
149
  \brief the color depth of the screen
150
*/
151
int QScreen::depth() const
152
0
{
153
0
    Q_D(const QScreen);
154
0
    return d->platformScreen->depth();
155
0
}
156
157
/*!
158
  \property QScreen::size
159
  \brief the pixel resolution of the screen
160
*/
161
QSize QScreen::size() const
162
0
{
163
0
    Q_D(const QScreen);
164
0
    return d->geometry.size();
165
0
}
166
167
/*!
168
  \property QScreen::physicalDotsPerInchX
169
  \brief the number of physical dots or pixels per inch in the horizontal direction
170
171
  This value represents the actual horizontal pixel density on the screen's display.
172
  Depending on what information the underlying system provides the value might not be
173
  entirely accurate.
174
175
  \note Physical DPI is expressed in device-independent dots. Multiply by QScreen::devicePixelRatio()
176
  to get device-dependent density.
177
178
  \sa physicalDotsPerInchY()
179
*/
180
qreal QScreen::physicalDotsPerInchX() const
181
0
{
182
0
    return size().width() / physicalSize().width() * qreal(25.4);
183
0
}
184
185
/*!
186
  \property QScreen::physicalDotsPerInchY
187
  \brief the number of physical dots or pixels per inch in the vertical direction
188
189
  This value represents the actual vertical pixel density on the screen's display.
190
  Depending on what information the underlying system provides the value might not be
191
  entirely accurate.
192
193
  \note Physical DPI is expressed in device-independent dots. Multiply by QScreen::devicePixelRatio()
194
  to get device-dependent density.
195
196
  \sa physicalDotsPerInchX()
197
*/
198
qreal QScreen::physicalDotsPerInchY() const
199
0
{
200
0
    return size().height() / physicalSize().height() * qreal(25.4);
201
0
}
202
203
/*!
204
  \property QScreen::physicalDotsPerInch
205
  \brief the number of physical dots or pixels per inch
206
207
  This value represents the pixel density on the screen's display.
208
  Depending on what information the underlying system provides the value might not be
209
  entirely accurate.
210
211
  This is a convenience property that's simply the average of the physicalDotsPerInchX
212
  and physicalDotsPerInchY properties.
213
214
  \note Physical DPI is expressed in device-independent dots. Multiply by QScreen::devicePixelRatio()
215
  to get device-dependent density.
216
217
  \sa physicalDotsPerInchX()
218
  \sa physicalDotsPerInchY()
219
*/
220
qreal QScreen::physicalDotsPerInch() const
221
0
{
222
0
    QSize sz = size();
223
0
    QSizeF psz = physicalSize();
224
0
    return ((sz.height() / psz.height()) + (sz.width() / psz.width())) * qreal(25.4 * 0.5);
225
0
}
226
227
/*!
228
  \property QScreen::logicalDotsPerInchX
229
  \brief the number of logical dots or pixels per inch in the horizontal direction
230
231
  This value is used to convert font point sizes to pixel sizes.
232
233
  \sa logicalDotsPerInchY()
234
*/
235
qreal QScreen::logicalDotsPerInchX() const
236
0
{
237
0
    Q_D(const QScreen);
238
0
    if (QHighDpiScaling::isActive())
239
0
        return QHighDpiScaling::logicalDpi(this).first;
240
0
    return d->logicalDpi.first;
241
0
}
242
243
/*!
244
  \property QScreen::logicalDotsPerInchY
245
  \brief the number of logical dots or pixels per inch in the vertical direction
246
247
  This value is used to convert font point sizes to pixel sizes.
248
249
  \sa logicalDotsPerInchX()
250
*/
251
qreal QScreen::logicalDotsPerInchY() const
252
0
{
253
0
    Q_D(const QScreen);
254
0
    if (QHighDpiScaling::isActive())
255
0
        return QHighDpiScaling::logicalDpi(this).second;
256
0
    return d->logicalDpi.second;
257
0
}
258
259
/*!
260
  \property QScreen::logicalDotsPerInch
261
  \brief the number of logical dots or pixels per inch
262
263
  This value can be used to convert font point sizes to pixel sizes.
264
265
  This is a convenience property that's simply the average of the logicalDotsPerInchX
266
  and logicalDotsPerInchY properties.
267
268
  \sa logicalDotsPerInchX()
269
  \sa logicalDotsPerInchY()
270
*/
271
qreal QScreen::logicalDotsPerInch() const
272
0
{
273
0
    Q_D(const QScreen);
274
0
    QDpi dpi = QHighDpiScaling::isActive() ? QHighDpiScaling::logicalDpi(this) : d->logicalDpi;
275
0
    return (dpi.first + dpi.second) * qreal(0.5);
276
0
}
277
278
/*!
279
    \property QScreen::devicePixelRatio
280
    \brief the screen's ratio between physical pixels and device-independent pixels
281
    \since 5.5
282
283
    Returns the ratio between physical pixels and device-independent pixels for the screen.
284
285
    This function may return a value that differs from QWindow::devicePixelRatio(),
286
    for instance on Wayland when using fractional scaling, or if window properties
287
    that affect surface resolution are set. Prefer using QWindow::devicePixelRatio().
288
289
    \note On some platforms the devicePixelRatio of a window and the screen it is on can
290
    be different. Use this function only when you don't know which window you are targeting.
291
    If you do know the target window, use QWindow::devicePixelRatio() instead.
292
293
    \sa QWindow::devicePixelRatio(), QGuiApplication::devicePixelRatio()
294
*/
295
qreal QScreen::devicePixelRatio() const
296
0
{
297
0
    Q_D(const QScreen);
298
0
    return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor(this);
299
0
}
300
301
/*!
302
  \property QScreen::physicalSize
303
  \brief the screen's physical size (in millimeters)
304
305
  The physical size represents the actual physical dimensions of the
306
  screen's display.
307
308
  Depending on what information the underlying system provides the value
309
  might not be entirely accurate.
310
*/
311
QSizeF QScreen::physicalSize() const
312
0
{
313
0
    Q_D(const QScreen);
314
0
    return d->platformScreen->physicalSize();
315
0
}
316
317
/*!
318
  \property QScreen::availableSize
319
  \brief the screen's available size in pixels
320
321
  The available size is the size excluding window manager reserved areas
322
  such as task bars and system menus.
323
*/
324
QSize QScreen::availableSize() const
325
0
{
326
0
    Q_D(const QScreen);
327
0
    return d->availableGeometry.size();
328
0
}
329
330
/*!
331
  \property QScreen::geometry
332
  \brief the screen's geometry in pixels
333
334
  As an example this might return QRect(0, 0, 1280, 1024), or in a
335
  virtual desktop setting QRect(1280, 0, 1280, 1024).
336
*/
337
QRect QScreen::geometry() const
338
0
{
339
0
    Q_D(const QScreen);
340
0
    return d->geometry;
341
0
}
342
343
/*!
344
  \property QScreen::availableGeometry
345
  \brief the screen's available geometry in pixels
346
347
  The available geometry is the geometry excluding window manager reserved areas
348
  such as task bars and system menus.
349
350
  Note, on X11 this will return the true available geometry only on systems with one monitor and
351
  if window manager has set _NET_WORKAREA atom. In all other cases this is equal to geometry().
352
  This is a limitation in X11 window manager specification.
353
*/
354
QRect QScreen::availableGeometry() const
355
0
{
356
0
    Q_D(const QScreen);
357
0
    return d->availableGeometry;
358
0
}
359
360
/*!
361
  Get the screen's virtual siblings.
362
363
  The virtual siblings are the screen instances sharing the same virtual desktop.
364
  They share a common coordinate system, and windows can freely be moved or
365
  positioned across them without having to be re-created.
366
*/
367
QList<QScreen *> QScreen::virtualSiblings() const
368
0
{
369
0
    Q_D(const QScreen);
370
0
    const QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings();
371
0
    QList<QScreen *> screens;
372
0
    screens.reserve(platformScreens.size());
373
0
    for (QPlatformScreen *platformScreen : platformScreens) {
374
        // Only consider platform screens that have been added
375
0
        if (auto *knownScreen = platformScreen->screen())
376
0
            screens << knownScreen;
377
0
    }
378
0
    return screens;
379
0
}
380
381
/*!
382
    \property QScreen::virtualSize
383
    \brief the pixel size of the virtual desktop to which this screen belongs
384
385
  Returns the pixel size of the virtual desktop corresponding to this screen.
386
387
  This is the combined size of the virtual siblings' individual geometries.
388
389
  \sa virtualSiblings()
390
*/
391
QSize QScreen::virtualSize() const
392
0
{
393
0
    return virtualGeometry().size();
394
0
}
395
396
/*!
397
    \property QScreen::virtualGeometry
398
    \brief the pixel geometry of the virtual desktop to which this screen belongs
399
400
  Returns the pixel geometry of the virtual desktop corresponding to this screen.
401
402
  This is the union of the virtual siblings' individual geometries.
403
404
  \sa virtualSiblings()
405
*/
406
QRect QScreen::virtualGeometry() const
407
0
{
408
0
    QRect result;
409
0
    const auto screens = virtualSiblings();
410
0
    for (QScreen *screen : screens)
411
0
        result |= screen->geometry();
412
0
    return result;
413
0
}
414
415
/*!
416
    \property QScreen::availableVirtualSize
417
    \brief the available size of the virtual desktop to which this screen belongs
418
419
  Returns the available pixel size of the virtual desktop corresponding to this screen.
420
421
  This is the combined size of the virtual siblings' individual available geometries.
422
423
  \sa availableSize(), virtualSiblings()
424
*/
425
QSize QScreen::availableVirtualSize() const
426
0
{
427
0
    return availableVirtualGeometry().size();
428
0
}
429
430
/*!
431
    \property QScreen::availableVirtualGeometry
432
    \brief the available geometry of the virtual desktop to which this screen belongs
433
434
  Returns the available geometry of the virtual desktop corresponding to this screen.
435
436
  This is the union of the virtual siblings' individual available geometries.
437
438
  \sa availableGeometry(), virtualSiblings()
439
*/
440
QRect QScreen::availableVirtualGeometry() const
441
0
{
442
0
    QRect result;
443
0
    const auto screens = virtualSiblings();
444
0
    for (QScreen *screen : screens)
445
0
        result |= screen->availableGeometry();
446
0
    return result;
447
0
}
448
449
/*!
450
    \property QScreen::orientation
451
    \brief the screen orientation
452
453
    The \c orientation property tells the orientation of the screen from the
454
    window system perspective.
455
456
    Most mobile devices and tablet computers contain accelerometer sensors.
457
    The Qt Sensors module provides the ability to read this sensor directly.
458
    However, the windowing system may rotate the entire screen automatically
459
    based on how it is being held; in that case, this \c orientation property
460
    will change.
461
462
    \sa primaryOrientation(), QWindow::contentOrientation()
463
*/
464
Qt::ScreenOrientation QScreen::orientation() const
465
0
{
466
0
    Q_D(const QScreen);
467
0
    return d->orientation;
468
0
}
469
470
/*!
471
  \property QScreen::refreshRate
472
  \brief the approximate vertical refresh rate of the screen in Hz
473
474
  \warning Avoid using the screen's refresh rate to drive animations via a
475
  timer such as QChronoTimer. Instead use QWindow::requestUpdate().
476
477
  \sa QWindow::requestUpdate()
478
*/
479
qreal QScreen::refreshRate() const
480
0
{
481
0
    Q_D(const QScreen);
482
0
    return d->refreshRate;
483
0
}
484
485
/*!
486
    \property QScreen::primaryOrientation
487
    \brief the primary screen orientation
488
489
    The primary screen orientation is Qt::LandscapeOrientation
490
    if the screen geometry's width is greater than or equal to its
491
    height, or Qt::PortraitOrientation otherwise. This property might
492
    change when the screen orientation was changed (i.e. when the
493
    display is rotated).
494
    The behavior is however platform dependent and can often be specified in
495
    an application manifest file.
496
497
*/
498
Qt::ScreenOrientation QScreen::primaryOrientation() const
499
0
{
500
0
    Q_D(const QScreen);
501
0
    return d->primaryOrientation;
502
0
}
503
504
/*!
505
    \property QScreen::nativeOrientation
506
    \brief the native screen orientation
507
    \since 5.2
508
509
    The native orientation of the screen is the orientation where the logo
510
    sticker of the device appears the right way up, or Qt::PrimaryOrientation
511
    if the platform does not support this functionality.
512
513
    The native orientation is a property of the hardware, and does not change.
514
*/
515
Qt::ScreenOrientation QScreen::nativeOrientation() const
516
0
{
517
0
    Q_D(const QScreen);
518
0
    return d->platformScreen->nativeOrientation();
519
0
}
520
521
/*!
522
    Convenience function to compute the angle of rotation to get from
523
    rotation \a a to rotation \a b.
524
525
    The result will be 0, 90, 180, or 270.
526
527
    Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
528
*/
529
int QScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b) const
530
0
{
531
0
    if (a == Qt::PrimaryOrientation)
532
0
        a = primaryOrientation();
533
534
0
    if (b == Qt::PrimaryOrientation)
535
0
        b = primaryOrientation();
536
537
0
    return QPlatformScreen::angleBetween(a, b);
538
0
}
539
540
/*!
541
    Convenience function to compute a transform that maps from the coordinate system
542
    defined by orientation \a a into the coordinate system defined by orientation
543
    \a b and target dimensions \a target.
544
545
    Example, \a a is Qt::Landscape, \a b is Qt::Portrait, and \a target is QRect(0, 0, w, h)
546
    the resulting transform will be such that the point QPoint(0, 0) is mapped to QPoint(0, w),
547
    and QPoint(h, w) is mapped to QPoint(0, h). Thus, the landscape coordinate system QRect(0, 0, h, w)
548
    is mapped (with a 90 degree rotation) into the portrait coordinate system QRect(0, 0, w, h).
549
550
    Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
551
*/
552
QTransform QScreen::transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target) const
553
0
{
554
0
    if (a == Qt::PrimaryOrientation)
555
0
        a = primaryOrientation();
556
557
0
    if (b == Qt::PrimaryOrientation)
558
0
        b = primaryOrientation();
559
560
0
    return QPlatformScreen::transformBetween(a, b, target);
561
0
}
562
563
/*!
564
    Maps the rect between two screen orientations.
565
566
    This will flip the x and y dimensions of the rectangle \a{rect} if the orientation \a{a} is
567
    Qt::PortraitOrientation or Qt::InvertedPortraitOrientation and orientation \a{b} is
568
    Qt::LandscapeOrientation or Qt::InvertedLandscapeOrientation, or vice versa.
569
570
    Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
571
*/
572
QRect QScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect) const
573
0
{
574
0
    if (a == Qt::PrimaryOrientation)
575
0
        a = primaryOrientation();
576
577
0
    if (b == Qt::PrimaryOrientation)
578
0
        b = primaryOrientation();
579
580
0
    return QPlatformScreen::mapBetween(a, b, rect);
581
0
}
582
583
/*!
584
    Convenience function that returns \c true if \a o is either portrait or inverted portrait;
585
    otherwise returns \c false.
586
587
    Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
588
*/
589
bool QScreen::isPortrait(Qt::ScreenOrientation o) const
590
0
{
591
0
    return o == Qt::PortraitOrientation || o == Qt::InvertedPortraitOrientation
592
0
        || (o == Qt::PrimaryOrientation && primaryOrientation() == Qt::PortraitOrientation);
593
0
}
594
595
/*!
596
    Convenience function that returns \c true if \a o is either landscape or inverted landscape;
597
    otherwise returns \c false.
598
599
    Qt::PrimaryOrientation is interpreted as the screen's primaryOrientation().
600
*/
601
bool QScreen::isLandscape(Qt::ScreenOrientation o) const
602
0
{
603
0
    return o == Qt::LandscapeOrientation || o == Qt::InvertedLandscapeOrientation
604
0
        || (o == Qt::PrimaryOrientation && primaryOrientation() == Qt::LandscapeOrientation);
605
0
}
606
607
/*!
608
    \fn void QScreen::orientationChanged(Qt::ScreenOrientation orientation)
609
610
    This signal is emitted when the orientation of the screen
611
    changes with \a orientation as an argument.
612
613
    \sa orientation()
614
*/
615
616
/*!
617
    \fn void QScreen::primaryOrientationChanged(Qt::ScreenOrientation orientation)
618
619
    This signal is emitted when the primary orientation of the screen
620
    changes with \a orientation as an argument.
621
622
    \sa primaryOrientation()
623
*/
624
625
void QScreenPrivate::updatePrimaryOrientation()
626
0
{
627
0
    primaryOrientation = geometry.width() >= geometry.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
628
0
}
629
630
/*!
631
    Returns the screen at \a point within the set of \l QScreen::virtualSiblings(),
632
    or \c nullptr if outside of any screen.
633
634
    The \a point is in relation to the virtualGeometry() of each set of virtual
635
    siblings.
636
637
    \since 5.15
638
*/
639
QScreen *QScreen::virtualSiblingAt(QPoint point)
640
0
{
641
0
    const auto &siblings = virtualSiblings();
642
0
    for (QScreen *sibling : siblings) {
643
0
        if (sibling->geometry().contains(point))
644
0
            return sibling;
645
0
    }
646
0
    return nullptr;
647
0
}
648
649
/*!
650
    Creates and returns a pixmap constructed by grabbing the contents
651
    of the given \a window restricted by QRect(\a x, \a y, \a width,
652
    \a height). If \a window is 0, then the entire screen will be
653
    grabbed.
654
655
    The arguments (\a{x}, \a{y}) specify the offset in the window,
656
    whereas (\a{width}, \a{height}) specify the area to be copied. If
657
    \a width is negative, the function copies everything to the right
658
    border of the window. If \a height is negative, the function
659
    copies everything to the bottom of the window.
660
661
    The offset and size arguments are specified in device independent
662
    pixels. The returned pixmap may be larger than the requested size
663
    when grabbing from a high-DPI screen. Call QPixmap::devicePixelRatio()
664
    to determine if this is the case.
665
666
    The window system identifier (\c WId) can be retrieved using the
667
    QWidget::winId() function. The rationale for using a window
668
    identifier and not a QWidget, is to enable grabbing of windows
669
    that are not part of the application, window system frames, and so
670
    on.
671
672
    When \a window is \e{0}, the behavior is platform-dependent.
673
    \list
674
        \li On platforms where coordinates are screen-local (Windows, X11),
675
        (\a{x}, \a{y}) are relative to this screen's origin.
676
        \li On platforms where coordinates are global (macOS),
677
        (\a{x}, \a{y}) are relative to the virtual desktop.
678
        This requires callers to subtract \c{screen->geometry().topLeft()}
679
        to achieve the same result as on Windows.
680
    \endlist
681
682
    To grab the entire screen portably across platforms, use \c{grabWindow(0)}
683
    without specifying coordinates. Code that grabs a sub-area must account for
684
    this difference explicitly.
685
686
    \warning Grabbing windows that are not part of the application is
687
    not supported on systems such as iOS, where sandboxing/security
688
    prevents reading pixels of windows not owned by the application.
689
690
    The grabWindow() function grabs pixels from the screen, not from
691
    the window, i.e. if there is another window partially or entirely
692
    over the one you grab, you get pixels from the overlying window,
693
    too. The mouse cursor is generally not grabbed.
694
695
    Note on X11 that if the given \a window doesn't have the same depth
696
    as the root window, and another window partially or entirely
697
    obscures the one you grab, you will \e not get pixels from the
698
    overlying window. The contents of the obscured areas in the
699
    pixmap will be undefined and uninitialized.
700
701
    On Windows Vista and above grabbing a layered window, which is
702
    created by setting the Qt::WA_TranslucentBackground attribute, will
703
    not work. Instead grabbing the desktop widget should work.
704
705
    \warning In general, grabbing an area outside the screen is not
706
    safe. This depends on the underlying window system.
707
*/
708
709
QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height)
710
0
{
711
0
    const QPlatformScreen *platformScreen = handle();
712
0
    if (!platformScreen) {
713
0
        qWarning("invoked with handle==0");
714
0
        return QPixmap();
715
0
    }
716
0
    const qreal factor = QHighDpiScaling::factor(this);
717
0
    if (qFuzzyCompare(factor, 1))
718
0
        return platformScreen->grabWindow(window, x, y, width, height);
719
720
0
    const QPoint nativePos = QHighDpi::toNative(QPoint(x, y), factor);
721
0
    QSize nativeSize(width, height);
722
0
    if (nativeSize.isValid())
723
0
        nativeSize = QHighDpi::toNative(nativeSize, factor);
724
0
    QPixmap result =
725
0
        platformScreen->grabWindow(window, nativePos.x(), nativePos.y(),
726
0
                                   nativeSize.width(), nativeSize.height());
727
0
    result.setDevicePixelRatio(result.devicePixelRatio() * factor);
728
0
    return result;
729
0
}
730
731
/*!
732
    \fn template <typename QNativeInterface> QNativeInterface *QScreen::nativeInterface() const
733
734
    Returns a native interface of the given type for the screen.
735
736
    This function provides access to platform specific functionality
737
    of QScreen, as defined in the QNativeInterface namespace:
738
739
    \annotatedlist native-interfaces-qscreen
740
741
    If the requested interface is not available a \nullptr is returned.
742
 */
743
744
void *QScreen::resolveInterface(const char *name, int revision) const
745
0
{
746
0
    using namespace QNativeInterface;
747
0
    using namespace QNativeInterface::Private;
748
749
0
    auto *platformScreen = handle();
750
0
    Q_UNUSED(platformScreen);
751
0
    Q_UNUSED(name);
752
0
    Q_UNUSED(revision);
753
754
#if QT_CONFIG(xcb)
755
    QT_NATIVE_INTERFACE_RETURN_IF(QXcbScreen, platformScreen);
756
#endif
757
758
#if QT_CONFIG(vsp2)
759
    QT_NATIVE_INTERFACE_RETURN_IF(QVsp2Screen, platformScreen);
760
#endif
761
762
#if defined(Q_OS_WEBOS)
763
    QT_NATIVE_INTERFACE_RETURN_IF(QWebOSScreen, platformScreen);
764
#endif
765
766
#if defined(Q_OS_WIN32)
767
    QT_NATIVE_INTERFACE_RETURN_IF(QWindowsScreen, platformScreen);
768
#endif
769
770
#if defined(Q_OS_ANDROID)
771
    QT_NATIVE_INTERFACE_RETURN_IF(QAndroidScreen, platformScreen);
772
#endif
773
774
#if QT_CONFIG(wayland)
775
    QT_NATIVE_INTERFACE_RETURN_IF(QWaylandScreen, platformScreen);
776
#endif
777
778
#if defined(Q_OS_MACOS)
779
    QT_NATIVE_INTERFACE_RETURN_IF(QCocoaScreen, platformScreen);
780
#endif
781
782
0
    return nullptr;
783
0
}
784
785
#ifndef QT_NO_DEBUG_STREAM
786
Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QScreen *screen)
787
0
{
788
0
    const QDebugStateSaver saver(debug);
789
0
    debug.nospace();
790
0
    debug << "QScreen(" << (const void *)screen;
791
0
    if (screen) {
792
0
        debug << ", name=" << screen->name();
793
0
        if (debug.verbosity() > 2) {
794
0
            if (screen == QGuiApplication::primaryScreen())
795
0
                debug << ", primary";
796
0
            debug << ", geometry=" << screen->geometry();
797
0
            debug << ", available=" << screen->availableGeometry();
798
0
            debug << ", logical DPI=" << screen->logicalDotsPerInchX()
799
0
                << ',' << screen->logicalDotsPerInchY()
800
0
                << ", physical DPI=" << screen->physicalDotsPerInchX()
801
0
                << ',' << screen->physicalDotsPerInchY()
802
0
                << ", devicePixelRatio=" << screen->devicePixelRatio()
803
0
                << ", orientation=" << screen->orientation()
804
0
                << ", physical size=" << screen->physicalSize().width()
805
0
                << 'x' << screen->physicalSize().height() << "mm";
806
0
        }
807
0
    }
808
0
    debug << ')';
809
0
    return debug;
810
0
}
811
#endif // !QT_NO_DEBUG_STREAM
812
813
QScreenPrivate::UpdateEmitter::UpdateEmitter(QScreen *screen)
814
0
{
815
0
    initialState.platformScreen = screen->handle();
816
817
    // Use public APIs to read out current state, rather
818
    // than accessing the QScreenPrivate members, so that
819
    // we detect any changes to the high-DPI scale factors
820
    // that may be applied in the getters.
821
822
0
    initialState.logicalDpi = QDpi{
823
0
        screen->logicalDotsPerInchX(),
824
0
        screen->logicalDotsPerInchY()
825
0
    };
826
0
    initialState.geometry = screen->geometry();
827
0
    initialState.availableGeometry = screen->availableGeometry();
828
0
    initialState.primaryOrientation = screen->primaryOrientation();
829
0
}
830
831
QScreenPrivate::UpdateEmitter::~UpdateEmitter()
832
0
{
833
0
    QScreen *screen = initialState.platformScreen->screen();
834
835
0
    const auto logicalDotsPerInch = QDpi{
836
0
        screen->logicalDotsPerInchX(),
837
0
        screen->logicalDotsPerInchY()
838
0
    };
839
0
    if (logicalDotsPerInch != initialState.logicalDpi)
840
0
        emit screen->logicalDotsPerInchChanged(screen->logicalDotsPerInch());
841
842
0
    const auto geometry = screen->geometry();
843
0
    const auto geometryChanged = geometry != initialState.geometry;
844
0
    if (geometryChanged)
845
0
        emit screen->geometryChanged(geometry);
846
847
0
    const auto availableGeometry = screen->availableGeometry();
848
0
    const auto availableGeometryChanged = availableGeometry != initialState.availableGeometry;
849
0
    if (availableGeometryChanged)
850
0
        emit screen->availableGeometryChanged(availableGeometry);
851
852
0
    if (geometryChanged || availableGeometryChanged) {
853
0
        const auto siblings = screen->virtualSiblings();
854
0
        for (QScreen* sibling : siblings)
855
0
            emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
856
0
    }
857
858
0
    if (geometryChanged) {
859
0
        emit screen->physicalDotsPerInchChanged(screen->physicalDotsPerInch());
860
861
0
        const auto primaryOrientation = screen->primaryOrientation();
862
0
        if (primaryOrientation != initialState.primaryOrientation)
863
0
            emit screen->primaryOrientationChanged(primaryOrientation);
864
0
    }
865
0
}
866
867
QT_END_NAMESPACE
868
869
#include "moc_qscreen.cpp"