summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qguiapplication.cpp19
-rw-r--r--src/gui/kernel/qguiapplication_p.h1
-rw-r--r--src/gui/kernel/qplatformscreen.h1
-rw-r--r--src/gui/kernel/qplatformscreen_qpa.cpp23
-rw-r--r--src/gui/kernel/qscreen.cpp36
-rw-r--r--src/gui/kernel/qscreen.h3
-rw-r--r--src/gui/kernel/qscreen_p.h11
-rw-r--r--tests/auto/gui/kernel/qscreen/tst_qscreen.cpp13
8 files changed, 101 insertions, 6 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index f71e611303..3e999bee8d 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1796,6 +1796,20 @@ void QGuiApplicationPrivate::reportScreenOrientationChange(QWindowSystemInterfac
QScreen *s = e->screen.data();
s->d_func()->orientation = e->orientation;
+ updateFilteredScreenOrientation(s);
+}
+
+void QGuiApplicationPrivate::updateFilteredScreenOrientation(QScreen *s)
+{
+ Qt::ScreenOrientation o = s->d_func()->orientation;
+ if (o == Qt::PrimaryOrientation)
+ o = s->primaryOrientation();
+ o = Qt::ScreenOrientation(o & s->orientationUpdateMask());
+ if (o == Qt::PrimaryOrientation)
+ return;
+ if (o == s->d_func()->filteredOrientation)
+ return;
+ s->d_func()->filteredOrientation = o;
reportScreenOrientationChange(s);
}
@@ -1820,7 +1834,6 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate:
s->d_func()->geometry = e->geometry;
Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
- Qt::ScreenOrientation orientation = s->orientation();
s->d_func()->updatePrimaryOrientation();
emit s->sizeChanged(s->size());
@@ -1834,8 +1847,8 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate:
if (s->primaryOrientation() != primaryOrientation)
emit s->primaryOrientationChanged(s->primaryOrientation());
- if (s->orientation() != orientation)
- reportScreenOrientationChange(s);
+ if (s->d_func()->orientation == Qt::PrimaryOrientation)
+ updateFilteredScreenOrientation(s);
}
void QGuiApplicationPrivate::reportAvailableGeometryChange(
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index e79c2afdf2..d538c393d7 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -112,6 +112,7 @@ public:
static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
+ static void updateFilteredScreenOrientation(QScreen *screen);
static void reportScreenOrientationChange(QScreen *screen);
static void reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e);
static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index 4baf0f65fb..31d459dffe 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -103,6 +103,7 @@ public:
virtual Qt::ScreenOrientation nativeOrientation() const;
virtual Qt::ScreenOrientation orientation() const;
+ virtual void setOrientationUpdateMask(Qt::ScreenOrientations mask);
virtual QWindow *topLevelAt(const QPoint &point) const;
virtual QList<QPlatformScreen *> virtualSiblings() const;
diff --git a/src/gui/kernel/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp
index fdb5d32687..d946e4f240 100644
--- a/src/gui/kernel/qplatformscreen_qpa.cpp
+++ b/src/gui/kernel/qplatformscreen_qpa.cpp
@@ -195,6 +195,29 @@ Qt::ScreenOrientation QPlatformScreen::orientation() const
return Qt::PrimaryOrientation;
}
+/*
+ Reimplement this function in subclass to filter out unneeded screen
+ orientation updates.
+
+ The orientations will anyway be filtered before QScreen::orientationChanged()
+ is emitted, but the mask can be used by the platform plugin for example to
+ prevent having to have an accelerometer sensor running all the time, or to
+ improve the reported values. As an example of the latter, in case of only
+ Landscape | InvertedLandscape being set in the mask, on a platform that gets
+ its orientation readings from an accelerometer sensor embedded in a handheld
+ device, the platform can report transitions between the two even when the
+ device is held in an orientation that's closer to portrait.
+
+ By default, the orientation update mask is empty, so unless this function
+ has been called with a non-empty mask the platform does not need to report
+ any orientation updates through
+ QWindowSystemInterface::handleScreenOrientationChange().
+*/
+void QPlatformScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
+{
+ Q_UNUSED(mask);
+}
+
QPlatformScreen * QPlatformScreen::platformScreenForWindow(const QWindow *window)
{
return window->screen()->handle();
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 2e0df43e66..fe8b15e9a0 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -345,6 +345,35 @@ QRect QScreen::availableVirtualGeometry() const
}
/*!
+ Sets the orientations that the application is interested in receiving
+ updates for in conjunction with this screen.
+
+ For example, to receive orientation() updates and thus have
+ orientationChanged() signals being emitted for LandscapeOrientation and
+ InvertedLandscapeOrientation, call setOrientationUpdateMask() with the
+ argument Qt::LandscapeOrientation | Qt::InvertedLandscapeOrientation.
+
+ The default, 0, means no orientationChanged() signals are fired.
+*/
+void QScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
+{
+ Q_D(QScreen);
+ d->orientationUpdateMask = mask;
+ d->platformScreen->setOrientationUpdateMask(mask);
+}
+
+/*!
+ Returns the currently set orientation update mask.
+
+ \sa setOrientationUpdateMask()
+*/
+Qt::ScreenOrientations QScreen::orientationUpdateMask() const
+{
+ Q_D(const QScreen);
+ return d->orientationUpdateMask;
+}
+
+/*!
\property QScreen::orientation
\brief the screen orientation
@@ -353,6 +382,11 @@ QRect QScreen::availableVirtualGeometry() const
will change based on the device is being held, and a desktop display
might be rotated so that it's in portrait mode.
+ Changes to this property will be filtered by orientationUpdateMask(),
+ so in order to receive orientation updates the application must first
+ call setOrientationUpdateMask() with a mask of the orientations it wants
+ to receive.
+
Qt::PrimaryOrientation is never returned.
\sa primaryOrientation(), orientationChanged()
@@ -360,7 +394,7 @@ QRect QScreen::availableVirtualGeometry() const
Qt::ScreenOrientation QScreen::orientation() const
{
Q_D(const QScreen);
- return d->orientation == Qt::PrimaryOrientation ? primaryOrientation() : d->orientation;
+ return d->filteredOrientation;
}
/*!
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index 17f3cd3d43..6c142162fe 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -119,6 +119,9 @@ public:
Qt::ScreenOrientation primaryOrientation() const;
Qt::ScreenOrientation orientation() const;
+ Qt::ScreenOrientations orientationUpdateMask() const;
+ void setOrientationUpdateMask(Qt::ScreenOrientations mask);
+
int angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b) const;
QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target) const;
QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect) const;
diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h
index b0e1b8671a..ca29acdd08 100644
--- a/src/gui/kernel/qscreen_p.h
+++ b/src/gui/kernel/qscreen_p.h
@@ -58,6 +58,7 @@ class QScreenPrivate : public QObjectPrivate
public:
QScreenPrivate(QPlatformScreen *screen)
: platformScreen(screen)
+ , orientationUpdateMask(0)
{
orientation = screen->orientation();
geometry = screen->geometry();
@@ -66,18 +67,24 @@ public:
refreshRate = screen->refreshRate();
updatePrimaryOrientation();
+
+ filteredOrientation = orientation;
+ if (filteredOrientation == Qt::PrimaryOrientation)
+ filteredOrientation = primaryOrientation;
}
void updatePrimaryOrientation();
+ QPlatformScreen *platformScreen;
+
+ Qt::ScreenOrientations orientationUpdateMask;
Qt::ScreenOrientation orientation;
+ Qt::ScreenOrientation filteredOrientation;
Qt::ScreenOrientation primaryOrientation;
QRect geometry;
QRect availableGeometry;
QDpi logicalDpi;
qreal refreshRate;
-
- QPlatformScreen *platformScreen;
};
QT_END_NAMESPACE
diff --git a/tests/auto/gui/kernel/qscreen/tst_qscreen.cpp b/tests/auto/gui/kernel/qscreen/tst_qscreen.cpp
index 475b6ca2a8..e6c28867c6 100644
--- a/tests/auto/gui/kernel/qscreen/tst_qscreen.cpp
+++ b/tests/auto/gui/kernel/qscreen/tst_qscreen.cpp
@@ -177,13 +177,26 @@ void tst_QScreen::transformBetween()
void tst_QScreen::orientationChange()
{
+ qRegisterMetaType<Qt::ScreenOrientation>("Qt::ScreenOrientation");
+
QScreen *screen = QGuiApplication::primaryScreen();
+ screen->setOrientationUpdateMask(Qt::LandscapeOrientation | Qt::PortraitOrientation);
+
QWindowSystemInterface::handleScreenOrientationChange(screen, Qt::LandscapeOrientation);
QTRY_COMPARE(screen->orientation(), Qt::LandscapeOrientation);
QWindowSystemInterface::handleScreenOrientationChange(screen, Qt::PortraitOrientation);
QTRY_COMPARE(screen->orientation(), Qt::PortraitOrientation);
+
+ QSignalSpy spy(screen, SIGNAL(orientationChanged(Qt::ScreenOrientation)));
+
+ QWindowSystemInterface::handleScreenOrientationChange(screen, Qt::InvertedLandscapeOrientation);
+ QWindowSystemInterface::handleScreenOrientationChange(screen, Qt::InvertedPortraitOrientation);
+ QWindowSystemInterface::handleScreenOrientationChange(screen, Qt::LandscapeOrientation);
+
+ QTRY_COMPARE(screen->orientation(), Qt::LandscapeOrientation);
+ QCOMPARE(spy.count(), 1);
}
#include <tst_qscreen.moc>