QtBase  v6.3.1
qscreen.cpp
Go to the documentation of this file.
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 
52 
76 QScreen::QScreen(QPlatformScreen *screen)
77  : QObject(*new QScreenPrivate(), nullptr)
78 {
79  Q_D(QScreen);
80  d->setPlatformScreen(screen);
81 }
82 
84 {
85  const QRect oldGeometry = geometry;
86  const QRect oldAvailableGeometry = availableGeometry;
87  updateHighDpi();
88  emitGeometryChangeSignals(oldGeometry != geometry, oldAvailableGeometry != availableGeometry);
89 }
90 
91 void QScreenPrivate::emitGeometryChangeSignals(bool geometryChanged, bool availableGeometryChanged)
92 {
93  Q_Q(QScreen);
94  if (geometryChanged)
95  emit q->geometryChanged(geometry);
96 
97  if (availableGeometryChanged)
98  emit q->availableGeometryChanged(availableGeometry);
99 
100  if (geometryChanged || availableGeometryChanged) {
101  const auto siblings = q->virtualSiblings();
102  for (QScreen* sibling : siblings)
103  emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
104  }
105 
106  if (geometryChanged)
107  emit q->physicalDotsPerInchChanged(q->physicalDotsPerInch());
108 }
109 
111 {
112  Q_Q(QScreen);
114  platformScreen->d_func()->screen = q;
116 
118 
120  // safeguard ourselves against buggy platform behavior...
121  if (refreshRate < 1.0)
122  refreshRate = 60.0;
123 
124  updateHighDpi();
125  updatePrimaryOrientation(); // derived from the geometry
126 }
127 
128 
133 {
134  // Remove screen
135  const bool wasPrimary = QGuiApplication::primaryScreen() == this;
138 
139  if (!qGuiApp)
140  return;
141 
142  QScreen *newPrimaryScreen = QGuiApplication::primaryScreen();
143  if (wasPrimary && newPrimaryScreen)
144  emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
145 
146  // Allow clients to manage windows that are affected by the screen going
147  // away, before we fall back to moving them to the primary screen.
148  emit qApp->screenRemoved(this);
149 
151  return;
152 
153  bool movingFromVirtualSibling = newPrimaryScreen
154  && newPrimaryScreen->handle()->virtualSiblings().contains(handle());
155 
156  // Move any leftover windows to the primary screen
157  const auto allWindows = QGuiApplication::allWindows();
158  for (QWindow *window : allWindows) {
159  if (!window->isTopLevel() || window->screen() != this)
160  continue;
161 
162  const bool wasVisible = window->isVisible();
163  window->setScreen(newPrimaryScreen);
164 
165  // Re-show window if moved from a virtual sibling screen. Otherwise
166  // leave it up to the application developer to show the window.
167  if (movingFromVirtualSibling)
168  window->setVisible(wasVisible);
169  }
170 }
171 
178 {
179  Q_D(const QScreen);
180  return d->platformScreen;
181 }
182 
191 {
192  Q_D(const QScreen);
193  return d->platformScreen->name();
194 }
195 
203 {
204  Q_D(const QScreen);
205  return d->platformScreen->manufacturer();
206 }
207 
215 {
216  Q_D(const QScreen);
217  return d->platformScreen->model();
218 }
219 
227 {
228  Q_D(const QScreen);
229  return d->platformScreen->serialNumber();
230 }
231 
236 int QScreen::depth() const
237 {
238  Q_D(const QScreen);
239  return d->platformScreen->depth();
240 }
241 
247 {
248  Q_D(const QScreen);
249  return d->geometry.size();
250 }
251 
266 {
267  return size().width() / physicalSize().width() * qreal(25.4);
268 }
269 
284 {
285  return size().height() / physicalSize().height() * qreal(25.4);
286 }
287 
306 {
307  QSize sz = size();
308  QSizeF psz = physicalSize();
309  return ((sz.height() / psz.height()) + (sz.width() / psz.width())) * qreal(25.4 * 0.5);
310 }
311 
321 {
322  Q_D(const QScreen);
324  return QHighDpiScaling::logicalDpi(this).first;
325  return d->logicalDpi.first;
326 }
327 
337 {
338  Q_D(const QScreen);
340  return QHighDpiScaling::logicalDpi(this).second;
341  return d->logicalDpi.second;
342 }
343 
357 {
358  Q_D(const QScreen);
360  return (dpi.first + dpi.second) * qreal(0.5);
361 }
362 
376 {
377  Q_D(const QScreen);
378  return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor(this);
379 }
380 
392 {
393  Q_D(const QScreen);
394  return d->platformScreen->physicalSize();
395 }
396 
405 {
406  Q_D(const QScreen);
407  return d->availableGeometry.size();
408 }
409 
418 {
419  Q_D(const QScreen);
420  return d->geometry;
421 }
422 
435 {
436  Q_D(const QScreen);
437  return d->availableGeometry;
438 }
439 
448 {
449  Q_D(const QScreen);
450  const QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings();
451  QList<QScreen *> screens;
452  screens.reserve(platformScreens.count());
453  for (QPlatformScreen *platformScreen : platformScreens)
454  screens << platformScreen->screen();
455  return screens;
456 }
457 
469 {
470  return virtualGeometry().size();
471 }
472 
484 {
485  QRect result;
486  const auto screens = virtualSiblings();
487  for (QScreen *screen : screens)
488  result |= screen->geometry();
489  return result;
490 }
491 
503 {
504  return availableVirtualGeometry().size();
505 }
506 
518 {
519  QRect result;
520  const auto screens = virtualSiblings();
521  for (QScreen *screen : screens)
523  return result;
524 }
525 
542 {
543  Q_D(const QScreen);
544  return d->orientation;
545 }
546 
557 {
558  Q_D(const QScreen);
559  return d->refreshRate;
560 }
561 
576 {
577  Q_D(const QScreen);
578  return d->primaryOrientation;
579 }
580 
593 {
594  Q_D(const QScreen);
595  return d->platformScreen->nativeOrientation();
596 }
597 
607 {
608  if (a == Qt::PrimaryOrientation)
609  a = primaryOrientation();
610 
611  if (b == Qt::PrimaryOrientation)
612  b = primaryOrientation();
613 
615 }
616 
630 {
631  if (a == Qt::PrimaryOrientation)
632  a = primaryOrientation();
633 
634  if (b == Qt::PrimaryOrientation)
635  b = primaryOrientation();
636 
638 }
639 
650 {
651  if (a == Qt::PrimaryOrientation)
652  a = primaryOrientation();
653 
654  if (b == Qt::PrimaryOrientation)
655  b = primaryOrientation();
656 
658 }
659 
667 {
670 }
671 
679 {
682 }
683 
703 {
705 }
706 
717 {
718  const auto &siblings = virtualSiblings();
719  for (QScreen *sibling : siblings) {
720  if (sibling->geometry().contains(point))
721  return sibling;
722  }
723  return nullptr;
724 }
725 
772 QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height)
773 {
774  const QPlatformScreen *platformScreen = handle();
775  if (!platformScreen) {
776  qWarning("invoked with handle==0");
777  return QPixmap();
778  }
779  const qreal factor = QHighDpiScaling::factor(this);
780  if (qFuzzyCompare(factor, 1))
781  return platformScreen->grabWindow(window, x, y, width, height);
782 
783  const QPoint nativePos = QHighDpi::toNative(QPoint(x, y), factor);
784  QSize nativeSize(width, height);
785  if (nativeSize.isValid())
786  nativeSize = QHighDpi::toNative(nativeSize, factor);
787  QPixmap result =
788  platformScreen->grabWindow(window, nativePos.x(), nativePos.y(),
789  nativeSize.width(), nativeSize.height());
790  result.setDevicePixelRatio(result.devicePixelRatio() * factor);
791  return result;
792 }
793 void *QScreen::resolveInterface(const char *name, int revision) const
794 {
795  using namespace QNativeInterface::Private;
796 
797  auto *platformScreen = handle();
798  Q_UNUSED(platformScreen);
799  Q_UNUSED(name);
800  Q_UNUSED(revision);
801 
802 #if QT_CONFIG(xcb)
803  QT_NATIVE_INTERFACE_RETURN_IF(QXcbScreen, platformScreen);
804 #endif
805 
806 #if QT_CONFIG(vsp2)
807  QT_NATIVE_INTERFACE_RETURN_IF(QVsp2Screen, platformScreen);
808 #endif
809 
810 #if defined(Q_OS_WEBOS)
811  QT_NATIVE_INTERFACE_RETURN_IF(QWebOSScreen, platformScreen);
812 #endif
813 
814  return nullptr;
815 }
816 
817 #ifndef QT_NO_DEBUG_STREAM
818 
819 static inline void formatRect(QDebug &debug, const QRect r)
820 {
821  debug << r.width() << 'x' << r.height()
822  << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
823 }
824 
826 {
827  const QDebugStateSaver saver(debug);
828  debug.nospace();
829  debug << "QScreen(" << (const void *)screen;
830  if (screen) {
831  debug << ", name=" << screen->name();
832  if (debug.verbosity() > 2) {
834  debug << ", primary";
835  debug << ", geometry=";
836  formatRect(debug, screen->geometry());
837  debug << ", available=";
838  formatRect(debug, screen->availableGeometry());
839  debug << ", logical DPI=" << screen->logicalDotsPerInchX()
840  << ',' << screen->logicalDotsPerInchY()
841  << ", physical DPI=" << screen->physicalDotsPerInchX()
842  << ',' << screen->physicalDotsPerInchY()
843  << ", devicePixelRatio=" << screen->devicePixelRatio()
844  << ", orientation=" << screen->orientation()
845  << ", physical size=" << screen->physicalSize().width()
846  << 'x' << screen->physicalSize().height() << "mm";
847  }
848  }
849  debug << ')';
850  return debug;
851 }
852 #endif // !QT_NO_DEBUG_STREAM
853 
855 
856 #include "moc_qscreen.cpp"
static bool closingDown()
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:65
Convenience class for custom QDebug operators.
Definition: qdebug.h:176
static QWindowList allWindows()
QScreen * primaryScreen
the primary (or default) screen of the application.
static QList< QScreen * > screen_list
static void resetCachedDevicePixelRatio()
static bool isActive()
static qreal factor(C *context)
static QDpi logicalDpi(const QScreen *screen)
bool removeOne(const AT &t)
Definition: qlist.h:596
qsizetype count() const noexcept
Definition: qlist.h:415
void reserve(qsizetype size)
Definition: qlist.h:757
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
The QPixmap class is an off-screen image representation that can be used as a paint device.
Definition: qpixmap.h:63
void setDevicePixelRatio(qreal scaleFactor)
Definition: qpixmap.cpp:639
static QDpi overrideDpi(const QDpi &in)
virtual Qt::ScreenOrientation orientation() const
static QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect)
QScreen * screen() const
virtual QDpi logicalDpi() const
virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const
static QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target)
virtual QList< QPlatformScreen * > virtualSiblings() const
static int angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b)
virtual qreal refreshRate() const
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
constexpr int x() const noexcept
Definition: qpoint.h:155
constexpr int y() const noexcept
Definition: qpoint.h:160
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
constexpr int height() const noexcept
Definition: qrect.h:266
constexpr QSize size() const noexcept
Definition: qrect.h:269
constexpr int width() const noexcept
Definition: qrect.h:263
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition: qscreen.h:68
QSize availableVirtualSize
the available size of the virtual desktop to which this screen belongs
Definition: qscreen.h:80
qreal logicalDotsPerInchY
the number of logical dots or pixels per inch in the vertical direction
Definition: qscreen.h:93
qreal devicePixelRatio
the screen's ratio between physical pixels and device-independent pixels
Definition: qscreen.h:95
QString model
the model of the screen
Definition: qscreen.h:74
bool isPortrait(Qt::ScreenOrientation orientation) const
Definition: qscreen.cpp:666
bool isLandscape(Qt::ScreenOrientation orientation) const
Definition: qscreen.cpp:678
int angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b) const
Definition: qscreen.cpp:606
Qt::ScreenOrientation nativeOrientation
the native screen orientation
Definition: qscreen.h:99
QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target) const
Definition: qscreen.cpp:629
qreal logicalDotsPerInchX
the number of logical dots or pixels per inch in the horizontal direction
Definition: qscreen.h:92
QList< QScreen * > virtualSiblings() const
Definition: qscreen.cpp:447
QRect availableGeometry
the screen's available geometry in pixels
Definition: qscreen.h:82
QSizeF physicalSize
the screen's physical size (in millimeters)
Definition: qscreen.h:86
QRect geometry
the screen's geometry in pixels
Definition: qscreen.h:81
QPixmap grabWindow(WId window=0, int x=0, int y=0, int w=-1, int h=-1)
Definition: qscreen.cpp:772
qreal refreshRate
the approximate vertical refresh rate of the screen in Hz
Definition: qscreen.h:100
qreal physicalDotsPerInchY
the number of physical dots or pixels per inch in the vertical direction
Definition: qscreen.h:90
QSize size
the pixel resolution of the screen
Definition: qscreen.h:77
Qt::ScreenOrientation primaryOrientation
the primary screen orientation
Definition: qscreen.h:97
QRect virtualGeometry
the pixel geometry of the virtual desktop to which this screen belongs
Definition: qscreen.h:83
QSize virtualSize
the pixel size of the virtual desktop to which this screen belongs
Definition: qscreen.h:79
int depth
the color depth of the screen
Definition: qscreen.h:76
QString manufacturer
the manufacturer of the screen
Definition: qscreen.h:73
Qt::ScreenOrientation orientation
the screen orientation
Definition: qscreen.h:98
QString name
a user presentable string representing the screen
Definition: qscreen.h:72
QSize availableSize
the screen's available size in pixels
Definition: qscreen.h:78
qreal logicalDotsPerInch
the number of logical dots or pixels per inch
Definition: qscreen.h:94
qreal physicalDotsPerInchX
the number of physical dots or pixels per inch in the horizontal direction
Definition: qscreen.h:88
QString serialNumber
the serial number of the screen
Definition: qscreen.h:75
QScreen * virtualSiblingAt(QPoint point)
Definition: qscreen.cpp:716
~QScreen()
Definition: qscreen.cpp:132
QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect) const
Definition: qscreen.cpp:649
QPlatformScreen * handle() const
Definition: qscreen.cpp:177
QRect availableVirtualGeometry
the available geometry of the virtual desktop to which this screen belongs
Definition: qscreen.h:85
qreal physicalDotsPerInch
the number of physical dots or pixels per inch
Definition: qscreen.h:91
void setPlatformScreen(QPlatformScreen *screen)
Definition: qscreen.cpp:110
QRect availableGeometry
Definition: qscreen_p.h:83
Qt::ScreenOrientation primaryOrientation
Definition: qscreen_p.h:81
void updatePrimaryOrientation()
Definition: qscreen.cpp:702
qreal refreshRate
Definition: qscreen_p.h:85
QDpi logicalDpi
Definition: qscreen_p.h:84
void updateHighDpi()
Definition: qscreen_p.h:68
QRect geometry
Definition: qscreen_p.h:82
Qt::ScreenOrientation orientation
Definition: qscreen_p.h:80
QPlatformScreen * platformScreen
Definition: qscreen_p.h:78
void emitGeometryChangeSignals(bool geometryChanged, bool availableGeometryChanged)
Definition: qscreen.cpp:91
void updateGeometriesWithSignals()
Definition: qscreen.cpp:83
The QSizeF class defines the size of a two-dimensional object using floating point precision.
Definition: qsize.h:235
constexpr qreal width() const noexcept
Definition: qsize.h:349
constexpr qreal height() const noexcept
Definition: qsize.h:352
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
constexpr int height() const noexcept
Definition: qsize.h:160
constexpr int width() const noexcept
Definition: qsize.h:157
constexpr bool isValid() const noexcept
Definition: qsize.h:154
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:56
The QWindow class represents a window in the underlying windowing system.
Definition: qwindow.h:99
float factor
rect
[4]
T toNative(const T &value, qreal scaleFactor, QPoint origin=QPoint(0, 0))
Q_WIDGETS_EXPORT qreal dpi(const QStyleOption *option)
QTextStream & noforcesign(QTextStream &stream)
ScreenOrientation
Definition: qnamespace.h:296
@ InvertedLandscapeOrientation
Definition: qnamespace.h:301
@ InvertedPortraitOrientation
Definition: qnamespace.h:300
@ LandscapeOrientation
Definition: qnamespace.h:299
@ PortraitOrientation
Definition: qnamespace.h:298
@ PrimaryOrientation
Definition: qnamespace.h:297
QTextStream & forcesign(QTextStream &stream)
#define qApp
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition: qfloat16.h:233
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
#define qGuiApp
QPair< qreal, qreal > QDpi
#define qWarning
Definition: qlogging.h:179
#define QT_NATIVE_INTERFACE_RETURN_IF(NativeInterface, baseType)
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLboolean r
[2]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLsizei width
GLenum target
GLuint name
GLint y
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QScreen *screen)
Definition: qscreen.cpp:825
#define emit
Definition: qtmetamacros.h:85
Q_UNUSED(salary)
[21]
QScreen * screen
[1]
Definition: main.cpp:76
QObject::connect nullptr
aWidget window() -> setWindowTitle("New Window Title")
[2]
bool contains(const AT &t) const noexcept
Definition: qlist.h:78