Coverage Report

Created: 2025-07-16 07:53

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