QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsscreenhelper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsscreenhelper.cpp
3 ---------------
4 Date : August 2022
5 Copyright : (C) 2022 by Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsscreenhelper.h"
17#include "qgis.h"
18#include <QWidget>
19#include <QEvent>
20#include <QWindow>
21#include <QScreen>
22
23
25 : QObject( parent )
26 , mWidget( parent )
27{
28 mWidget->installEventFilter( this );
29}
30
32{
34 {
35 return windowHandle->screen();
36 }
37 return nullptr;
38}
39
41{
42 if ( QWidget *window = mWidget->window() )
43 return window->windowHandle();
44
45 return nullptr;
46}
47
48bool QgsScreenHelper::eventFilter( QObject *watched, QEvent *event )
49{
50 if ( watched != mWidget )
51 return false;
52
53 switch ( event->type() )
54 {
55 case QEvent::Show:
56 {
57 updateDevicePixelFromScreen();
58 updateAvailableGeometryFromScreen();
59
60 // keep device pixel ratio up to date on screen or resolution change
61 if ( QWindow *handle = windowHandle() )
62 {
63 connect( handle, &QWindow::screenChanged, this, [ = ]( QScreen * )
64 {
65 disconnect( mScreenDpiChangedConnection );
66 disconnect( mAvailableGeometryChangedConnection );
67
68 if ( QWindow *windowHandleInLambda = windowHandle() )
69 {
70 mScreenDpiChangedConnection = connect( windowHandleInLambda->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsScreenHelper::updateDevicePixelFromScreen );
71 updateDevicePixelFromScreen();
72
73 mAvailableGeometryChangedConnection = connect( windowHandleInLambda->screen(), &QScreen::availableGeometryChanged, this, &QgsScreenHelper::updateAvailableGeometryFromScreen );
74 updateAvailableGeometryFromScreen();
75 }
76 } );
77
78 mScreenDpiChangedConnection = connect( handle->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsScreenHelper::updateDevicePixelFromScreen );
79 mAvailableGeometryChangedConnection = connect( handle->screen(), &QScreen::availableGeometryChanged, this, &QgsScreenHelper::updateAvailableGeometryFromScreen );
80 }
81 break;
82 }
83
84 default:
85 break;
86 }
87
88 return false;
89}
90
91void QgsScreenHelper::updateDevicePixelFromScreen()
92{
93 if ( QScreen *screen = QgsScreenHelper::screen() )
94 {
95 const double newDpi = screen->physicalDotsPerInch();
96 if ( !qgsDoubleNear( newDpi, mScreenDpi ) )
97 {
98 mScreenDpi = newDpi;
99 emit screenDpiChanged( mScreenDpi );
100 }
101 }
102}
103
104void QgsScreenHelper::updateAvailableGeometryFromScreen()
105{
106 if ( QScreen *screen = QgsScreenHelper::screen() )
107 {
108 const QRect newGeometry = screen->availableGeometry();
109 if ( newGeometry != mAvailableGeometry )
110 {
111 mAvailableGeometry = newGeometry;
112 emit availableGeometryChanged( mAvailableGeometry );
113 }
114 }
115}
QWindow * windowHandle()
Returns the window handle for the window the parent widget is associated with, or nullptr.
QScreen * screen()
Returns the screen that the parent widget appears on, or nullptr.
bool eventFilter(QObject *watched, QEvent *event) override
QgsScreenHelper(QWidget *parent)
Constructor for QgsScreenHelper for the specified parent widget.
void availableGeometryChanged(const QRect &geometry)
Emitted whenever the available geometry of the screen associated with the widget is changed.
void screenDpiChanged(double dpi)
Emitted whenever the screen dpi associated with the widget is changed.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2527