From 80653bf4ce8d03f4af2fe8cc2f3751d32bd31d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 5 Jun 2012 14:17:24 +0200 Subject: Added QScreen::setOrientationUpdateMask(). It might be too expensive to always have an accelerometer sensor running, so introduce API so that the application has to explictly ask to get the orientation updates it's interested in. Change-Id: Ib7dc5ad8807718409f744ebef53f4476aa05175d Reviewed-by: Ian Monroe Reviewed-by: Sean Harmer Reviewed-by: Gunnar Sletta Reviewed-by: Kevin Ottens --- src/gui/kernel/qguiapplication.cpp | 19 +++++++++++++++--- src/gui/kernel/qguiapplication_p.h | 1 + src/gui/kernel/qplatformscreen.h | 1 + src/gui/kernel/qplatformscreen_qpa.cpp | 23 ++++++++++++++++++++++ src/gui/kernel/qscreen.cpp | 36 +++++++++++++++++++++++++++++++++- src/gui/kernel/qscreen.h | 3 +++ src/gui/kernel/qscreen_p.h | 11 +++++++++-- 7 files changed, 88 insertions(+), 6 deletions(-) (limited to 'src/gui/kernel') 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 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 @@ -344,6 +344,35 @@ QRect QScreen::availableVirtualGeometry() const return result; } +/*! + 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 -- cgit v1.2.3