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);
}
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());
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(
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);
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;
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();
}
/*!
+ 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
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()
Qt::ScreenOrientation QScreen::orientation() const
{
Q_D(const QScreen);
- return d->orientation == Qt::PrimaryOrientation ? primaryOrientation() : d->orientation;
+ return d->filteredOrientation;
}
/*!
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;
public:
QScreenPrivate(QPlatformScreen *screen)
: platformScreen(screen)
+ , orientationUpdateMask(0)
{
orientation = screen->orientation();
geometry = screen->geometry();
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
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>