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 <ian.monroe@nokia.com>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Reviewed-by: Kevin Ottens <kevin.ottens.qnx@kdab.com>
This commit is contained in:
Samuel Rødal 2012-06-05 14:17:24 +02:00 committed by Qt by Nokia
parent 09001e72dc
commit 80653bf4ce
8 changed files with 101 additions and 6 deletions

View File

@ -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(

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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;
}
/*!

View File

@ -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;

View File

@ -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

View File

@ -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>