Coverage Report

Created: 2025-09-27 07:50

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