- 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 theorientationUpdateMaskhas been been set.QScreen::orientationUpdateMask: limits which orientations are reflected in the orientation property. The default value is 0, meaning theorientationproperty 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
orientationfollowprimaryOrientationwhen noorientationUpdateMaskhas been set? A change inprimaryOrientationmeans 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 theorientationhas also changed. Or can we? Are there other ways theprimaryOrientationcan 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
orientationproperty?
A2: The property has the following behavior:- When
QScreenis constructed based on an addedQPlatformScreen, theQScreenPrivateconstructor 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 offilteredOrienationis 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
QScreenconstruction, the getter for the property inQScreenjust 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 theorientationUpdateMaskmatches the new orientation. - For every call to
setOrientationUpdateMaskthe internal orientation of the screen will be re-evaluated against the mask, andfilteredOrientationwill possibly be updated and a change signal emitted.
- When