- Auto-rotation: the process where the platform will read sensor data about the physical screen orientation and apply that to the screen properties, so that eg. a screen in a physical landscape orientation will have an observable width > height.
- Orientation-lock: More or less granular configuration of which orientations the platform is allowed to auto-rotate into
QScreen::nativeOrienation
: the fixed standard-orientation of the physical screen, eg the orienation where the logo makes sense. Typically landscape for desktop screens. Never changes.QScreen::primaryOrienation
: the 'logical' orientation of the screen, computed from its geometry properties. Typically landscape or portrait, depending on the width and height ratio. A screen that auto-rotated due to sensor input of the physical screen will have a new primary orientation.QScreen::orientation
: the physical orientation of the screen, resulting from reading sensor data about the screen when theorientationUpdateMask
has been been set.QScreen::orientationUpdateMask
: limits which orientations are reflected in the orientation property. The default value is 0, meaning theorientation
property will not change. This allows Qt to tell the system that we are not interested in orientation sensor updates. If the system then does not require any sensor readings of its own (due to auto-rotation, eg), it can disable the sensor and save battery. This is why the default is 0.QWindow::reportContentOrientation
: allows the application to inform the system that the content is oriented differently then what you would expect fromQScreen::primaryOrienation
, which allows the system to orient system-provided UI elements such as statusbars and system alert dialogs in the same orientation.
Note that we currenly have no API in Qt to configure auto-rotation (orientation-lock). This is partially because on both iOS and Android orientation-lock (or supported orientations) is a combination of build-system properties and runtime properties, which we haven't been able to unify as a single Qt API.
This scenario happens on eg. iOS, where the platform will by default auto-rotate to most orientations. During auto-rotation we reconfigure the QScreen, which then gets a new width and height (geometry), and in effect a new primaryOrientation
.
The orientation
property will stay static (based on what the orientation of the device was at startup), unless the orientationUpdateMask
is set. If set (to match all orientations), the orientation
property will start reporting the same value as primaryOrientation
, since the two are in sync due to auto-rotation. This is convenience for using a QOrientationSensor
.
If the auto-rotation (supported orientations) have been configured in eg. Xcode to limit to only portrait and landscape, not the inverse counterparts, the primaryOrientation
property will only switch between the two former orientations, while the orientation
property will report changes for all orientations that are part of the orientationUpdateMask
.
An application may be designed for only a single orientation, typically portrait on a mobile device. In this case the system APIs are used to lock the orientation (limit the supported orientations), eg using Xcode/Info.plist for iOS.
The primaryOrientation
in this case stays in portrait, and never changes. The same goes for the orientation
propery, as the orientationUpdateMask
is by default 0. This allows the platform to ignore orientation sensor readings and possibly save battery.
Auto-rotation by the system happens using system transitions/animations, typically a rotation of the whole window. In some cases (games eg.) it might be nicer to have a custom transition, eg. on individual items in the scene instead of the whole scene as one.
For this to work, step one is to disable auto-rotation, eg. by configuring supported orientation in Xcode/Info.plist for iOS, similar to #UC2
. This means the primaryOrientation
will be static (typically portrait).
Next, we set the orientationUpdateMask
so that we start reciving changes to the orientation
property. This could be done using QOrientationSensor
as well. Once we know the current physical orientation of the device, we apply a rotation transform with animation transition to eg. the individual items in the scene.
At this point the content of our application will rotate to match the physicall device orientation (using a cool custom animation), but any system UI elements such as the statusbar or system alert dialogs will pop up in portrait mode, since as far as the system knows, the screen is in portrait mode, as reflected by the primaryOrientation
property.
This is where reportContentOrientation
enters the picture. By reporting the true orientation of the content back to the system, it can adjust its UI elements to match our content orientation.
-
Q1: Why does not
orientation
followprimaryOrientation
when noorientationUpdateMask
has been set? A change inprimaryOrientation
means the system internally is checking the orientation sensor, so even if the application doesn't explicitly request updates to the orientation, we can still assume that theorientation
has also changed. Or can we? Are there other ways theprimaryOrientation
can change were the physical orientation of the device stays the same?
A1: Discussed here: https://gist.github.com/torarnv/0c9d36108f838c7bac9c and here: https://codereview.qt-project.org/#/c/95661/. -
Q2: What are the different states of the
orientation
property?
A2: The property has the following behavior:- When
QScreen
is constructed based on an addedQPlatformScreen
, theQScreenPrivate
constructor will read out the orientation from the platform screen, and set that as the initialfilteredOrientation
(falling back to the effective primary orientation if the platform screen returnsQt::PrimaryOrientation
). This initialization offilteredOrienation
is not filtered by any orientation update mask, so the platform screen is allowed to initialize the orientation to the actual physical orientation of the device. - After
QScreen
construction, the getter for the property inQScreen
just returns the internalfilteredOrientation
, meaning the only way to update the orientation after a screen has been added is to callQWindowSystemInterface::handleOrientationChange()
. The new orientation will then only be reflected if theorientationUpdateMask
matches the new orientation. - For every call to
setOrientationUpdateMask
the internal orientation of the screen will be re-evaluated against the mask, andfilteredOrientation
will possibly be updated and a change signal emitted.
- When