Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qscreen.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qscreen.h"
5#include "qscreen_p.h"
6#include "qpixmap.h"
8#include <qpa/qplatformscreen.h>
9#include <qpa/qplatformscreen_p.h>
10
11#include <QtCore/QDebug>
12#include <QtCore/private/qobject_p.h>
14
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
46QScreen::QScreen(QPlatformScreen *platformScreen)
47 : QObject(*new QScreenPrivate(), nullptr)
48{
49 Q_D(QScreen);
50
51 d->platformScreen = platformScreen;
52 platformScreen->d_func()->screen = this;
53
54 d->orientation = platformScreen->orientation();
55 d->logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
56 d->refreshRate = platformScreen->refreshRate();
57 // safeguard ourselves against buggy platform behavior...
58 if (d->refreshRate < 1.0)
59 d->refreshRate = 60.0;
60
61 d->updateGeometry();
62 d->updatePrimaryOrientation(); // derived from the geometry
63}
64
65void QScreenPrivate::updateGeometry()
66{
67 qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
68 QRect nativeGeometry = platformScreen->geometry();
69 geometry = QRect(nativeGeometry.topLeft(), QHighDpi::fromNative(nativeGeometry.size(), scaleFactor));
70 QRect nativeAvailableGeometry = platformScreen->availableGeometry();
71 availableGeometry = QRect(nativeAvailableGeometry.topLeft(), QHighDpi::fromNative(nativeAvailableGeometry.size(), scaleFactor));
72}
73
74/*!
75 Destroys the screen.
76
77 \internal
78 */
79QScreen::~QScreen()
80{
81 Q_ASSERT_X(!QGuiApplicationPrivate::screen_list.contains(this), "QScreen",
82 "QScreens should be removed via QWindowSystemInterface::handleScreenRemoved()");
83}
84
85/*!
86 Get the platform screen handle.
87
88 \sa {Qt Platform Abstraction}{Qt Platform Abstraction (QPA)}
89*/
90QPlatformScreen *QScreen::handle() const
91{
92 Q_D(const QScreen);
93 return d->platformScreen;
94}
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*/
107QString QScreen::name() const
108{
109 Q_D(const QScreen);
110 return d->platformScreen->name();
111}
112
113/*!
114 \property QScreen::manufacturer
115 \brief the manufacturer of the screen
116
117 \since 5.9
118*/
119QString QScreen::manufacturer() const
120{
121 Q_D(const QScreen);
122 return d->platformScreen->manufacturer();
123}
124
125/*!
126 \property QScreen::model
127 \brief the model of the screen
128
129 \since 5.9
130*/
131QString QScreen::model() const
132{
133 Q_D(const QScreen);
134 return d->platformScreen->model();
135}
136
137/*!
138 \property QScreen::serialNumber
139 \brief the serial number of the screen
140
141 \since 5.9
142*/
143QString QScreen::serialNumber() const
144{
145 Q_D(const QScreen);
146 return d->platformScreen->serialNumber();
147}
148
149/*!
150 \property QScreen::depth
151 \brief the color depth of the screen
152*/
153int QScreen::depth() const
154{
155 Q_D(const QScreen);
156 return d->platformScreen->depth();
157}
158
159/*!
160 \property QScreen::size
161 \brief the pixel resolution of the screen
162*/
163QSize QScreen::size() const
164{
165 Q_D(const QScreen);
166 return d->geometry.size();
167}
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*/
182qreal QScreen::physicalDotsPerInchX() const
183{
184 return size().width() / physicalSize().width() * qreal(25.4);
185}
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*/
200qreal QScreen::physicalDotsPerInchY() const
201{
202 return size().height() / physicalSize().height() * qreal(25.4);
203}
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*/
222qreal QScreen::physicalDotsPerInch() const
223{
224 QSize sz = size();
225 QSizeF psz = physicalSize();
226 return ((sz.height() / psz.height()) + (sz.width() / psz.width())) * qreal(25.4 * 0.5);
227}
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*/
237qreal QScreen::logicalDotsPerInchX() const
238{
239 Q_D(const QScreen);
240 if (QHighDpiScaling::isActive())
241 return QHighDpiScaling::logicalDpi(this).first;
242 return d->logicalDpi.first;
243}
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*/
253qreal QScreen::logicalDotsPerInchY() const
254{
255 Q_D(const QScreen);
256 if (QHighDpiScaling::isActive())
257 return QHighDpiScaling::logicalDpi(this).second;
258 return d->logicalDpi.second;
259}
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*/
273qreal QScreen::logicalDotsPerInch() const
274{
275 Q_D(const QScreen);
276 QDpi dpi = QHighDpiScaling::isActive() ? QHighDpiScaling::logicalDpi(this) : d->logicalDpi;
277 return (dpi.first + dpi.second) * qreal(0.5);
278}
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*/
297qreal QScreen::devicePixelRatio() const
298{
299 Q_D(const QScreen);
300 return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor(this);
301}
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*/
313QSizeF QScreen::physicalSize() const
314{
315 Q_D(const QScreen);
316 return d->platformScreen->physicalSize();
317}
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*/
326QSize QScreen::availableSize() const
327{
328 Q_D(const QScreen);
329 return d->availableGeometry.size();
330}
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*/
339QRect QScreen::geometry() const
340{
341 Q_D(const QScreen);
342 return d->geometry;
343}
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*/
356QRect QScreen::availableGeometry() const
357{
358 Q_D(const QScreen);
359 return d->availableGeometry;
360}
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*/
369QList<QScreen *> QScreen::virtualSiblings() const
370{
371 Q_D(const QScreen);
372 const QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings();
373 QList<QScreen *> screens;
374 screens.reserve(platformScreens.size());
375 for (QPlatformScreen *platformScreen : platformScreens) {
376 // Only consider platform screens that have been added
377 if (auto *knownScreen = platformScreen->screen())
378 screens << knownScreen;
379 }
380 return screens;
381}
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*/
393QSize QScreen::virtualSize() const
394{
395 return virtualGeometry().size();
396}
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*/
408QRect QScreen::virtualGeometry() const
409{
410 QRect result;
411 const auto screens = virtualSiblings();
412 for (QScreen *screen : screens)
413 result |= screen->geometry();
414 return result;
415}
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*/
427QSize QScreen::availableVirtualSize() const
428{
429 return availableVirtualGeometry().size();
430}
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*/
442QRect QScreen::availableVirtualGeometry() const
443{
444 QRect result;
445 const auto screens = virtualSiblings();
446 for (QScreen *screen : screens)
447 result |= screen->availableGeometry();
448 return result;
449}
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*/
466Qt::ScreenOrientation QScreen::orientation() const
467{
468 Q_D(const QScreen);
469 return d->orientation;
470}
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*/
481qreal QScreen::refreshRate() const
482{
483 Q_D(const QScreen);
484 return d->refreshRate;
485}
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*/
500Qt::ScreenOrientation QScreen::primaryOrientation() const
501{
502 Q_D(const QScreen);
503 return d->primaryOrientation;
504}
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*/
517Qt::ScreenOrientation QScreen::nativeOrientation() const
518{
519 Q_D(const QScreen);
520 return d->platformScreen->nativeOrientation();
521}
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*/
531int QScreen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b) const
532{
533 if (a == Qt::PrimaryOrientation)
534 a = primaryOrientation();
535
536 if (b == Qt::PrimaryOrientation)
537 b = primaryOrientation();
538
539 return QPlatformScreen::angleBetween(a, b);
540}
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*/
554QTransform QScreen::transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target) const
555{
556 if (a == Qt::PrimaryOrientation)
557 a = primaryOrientation();
558
559 if (b == Qt::PrimaryOrientation)
560 b = primaryOrientation();
561
562 return QPlatformScreen::transformBetween(a, b, target);
563}
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*/
574QRect QScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect) const
575{
576 if (a == Qt::PrimaryOrientation)
577 a = primaryOrientation();
578
579 if (b == Qt::PrimaryOrientation)
580 b = primaryOrientation();
581
582 return QPlatformScreen::mapBetween(a, b, rect);
583}
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*/
591bool QScreen::isPortrait(Qt::ScreenOrientation o) const
592{
593 return o == Qt::PortraitOrientation || o == Qt::InvertedPortraitOrientation
594 || (o == Qt::PrimaryOrientation && primaryOrientation() == Qt::PortraitOrientation);
595}
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*/
603bool QScreen::isLandscape(Qt::ScreenOrientation o) const
604{
605 return o == Qt::LandscapeOrientation || o == Qt::InvertedLandscapeOrientation
606 || (o == Qt::PrimaryOrientation && primaryOrientation() == Qt::LandscapeOrientation);
607}
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
628{
629 primaryOrientation = geometry.width() >= geometry.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
630}
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*/
641QScreen *QScreen::virtualSiblingAt(QPoint point)
642{
643 const auto &siblings = virtualSiblings();
644 for (QScreen *sibling : siblings) {
645 if (sibling->geometry().contains(point))
646 return sibling;
647 }
648 return nullptr;
649}
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
697QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height)
698{
699 const QPlatformScreen *platformScreen = handle();
700 if (!platformScreen) {
701 qWarning("invoked with handle==0");
702 return QPixmap();
703 }
704 const qreal factor = QHighDpiScaling::factor(this);
705 if (qFuzzyCompare(factor, 1))
706 return platformScreen->grabWindow(window, x, y, width, height);
707
708 const QPoint nativePos = QHighDpi::toNative(QPoint(x, y), factor);
709 QSize nativeSize(width, height);
710 if (nativeSize.isValid())
711 nativeSize = QHighDpi::toNative(nativeSize, factor);
712 QPixmap result =
713 platformScreen->grabWindow(window, nativePos.x(), nativePos.y(),
714 nativeSize.width(), nativeSize.height());
715 result.setDevicePixelRatio(result.devicePixelRatio() * factor);
716 return result;
717}
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
732void *QScreen::resolveInterface(const char *name, int revision) const
733{
734 using namespace QNativeInterface;
735 using namespace QNativeInterface::Private;
736
737 auto *platformScreen = handle();
738 Q_UNUSED(platformScreen);
739 Q_UNUSED(name);
740 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#if defined(Q_OS_MACOS)
767 QT_NATIVE_INTERFACE_RETURN_IF(QCocoaScreen, platformScreen);
768#endif
769
770 return nullptr;
771}
772
773#ifndef QT_NO_DEBUG_STREAM
774Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QScreen *screen)
775{
776 const QDebugStateSaver saver(debug);
777 debug.nospace();
778 debug << "QScreen(" << (const void *)screen;
779 if (screen) {
780 debug << ", name=" << screen->name();
781 if (debug.verbosity() > 2) {
782 if (screen == QGuiApplication::primaryScreen())
783 debug << ", primary";
784 debug << ", geometry=" << screen->geometry();
785 debug << ", available=" << screen->availableGeometry();
786 debug << ", logical DPI=" << screen->logicalDotsPerInchX()
787 << ',' << screen->logicalDotsPerInchY()
788 << ", physical DPI=" << screen->physicalDotsPerInchX()
789 << ',' << screen->physicalDotsPerInchY()
790 << ", devicePixelRatio=" << screen->devicePixelRatio()
791 << ", orientation=" << screen->orientation()
792 << ", physical size=" << screen->physicalSize().width()
793 << 'x' << screen->physicalSize().height() << "mm";
794 }
795 }
796 debug << ')';
797 return debug;
798}
799#endif // !QT_NO_DEBUG_STREAM
800
802{
803 initialState.platformScreen = screen->handle();
804
805 // Use public APIs to read out current state, rather
806 // than accessing the QScreenPrivate members, so that
807 // we detect any changes to the high-DPI scale factors
808 // that may be applied in the getters.
809
810 initialState.logicalDpi = QDpi{
811 screen->logicalDotsPerInchX(),
812 screen->logicalDotsPerInchY()
813 };
814 initialState.geometry = screen->geometry();
815 initialState.availableGeometry = screen->availableGeometry();
816 initialState.primaryOrientation = screen->primaryOrientation();
817}
818
820{
821 QScreen *screen = initialState.platformScreen->screen();
822
823 const auto logicalDotsPerInch = QDpi{
824 screen->logicalDotsPerInchX(),
825 screen->logicalDotsPerInchY()
826 };
827 if (logicalDotsPerInch != initialState.logicalDpi)
828 emit screen->logicalDotsPerInchChanged(screen->logicalDotsPerInch());
829
830 const auto geometry = screen->geometry();
831 const auto geometryChanged = geometry != initialState.geometry;
832 if (geometryChanged)
833 emit screen->geometryChanged(geometry);
834
835 const auto availableGeometry = screen->availableGeometry();
836 const auto availableGeometryChanged = availableGeometry != initialState.availableGeometry;
837 if (availableGeometryChanged)
838 emit screen->availableGeometryChanged(availableGeometry);
839
840 if (geometryChanged || availableGeometryChanged) {
841 const auto siblings = screen->virtualSiblings();
842 for (QScreen* sibling : siblings)
843 emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
844 }
845
846 if (geometryChanged) {
847 emit screen->physicalDotsPerInchChanged(screen->physicalDotsPerInch());
848
849 const auto primaryOrientation = screen->primaryOrientation();
850 if (primaryOrientation != initialState.primaryOrientation)
851 emit screen->primaryOrientationChanged(primaryOrientation);
852 }
853}
854
855QT_END_NAMESPACE
856
857#include "moc_qscreen.cpp"
UpdateEmitter(QScreen *screen)
Definition qscreen.cpp:801
void updatePrimaryOrientation()
Definition qscreen.cpp:627
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2568