Unity8 shell rotation

Registered by kevin gunn on 2014-04-22

This blueprint is meant to capture work toward providing true dynamic shell rotation for the phone and tablet form factors. This blueprint will be targeted at unity-mir's use of Qt compositor as a plugin to Mir.

Blueprint information

Not started
kevin gunn
Unity Team
Needs approval
Unity UI Team
Series goal:
Milestone target:
milestone icon ubuntu-14.06


some assumptions, Mir changes to enable Qt comp are done and that unity-mir changes are available to leverage it.

Composition vs App
didn't we already decide on app-internal rotation ?
Saviq: yeah, but there was some discussion again on that, maybe we need to restate that's what we want to do?
kgunn: +1 on restating plans

Update May9, 2014
Based on Design direction
( https://drive.google.com/a/canonical.com/file/d/0B4GvOYxwuvpFTmNlUlJFNlVDQlU/edit?usp=sharing )
1. stop composition / take snapshot
2. overlay the snapshot on top of shell and start rotating
3. inform shell surface to resize
4. shell informs all surfaces to resize
5. fade snapshot out ~2/5ths along the way
6. fade shell in halfway

Questions re sidestage:
- disallowed or squeezed on edge
   * kgunn Apr28,2014 update: Design team "thinks" that sidestage should be allowed on tablet portrait, but in overlay-mode only, no split stage
- if disallowed, in case of already in sidestage mode does it "hide" or does it refuse to rotate
- if disallowed, in case of portrait mode does sidestage app launch result in forced rotation back to landscape or friendly notification

Questions re transitions:
- reflow vs surface resize order
- what happens in case indicators are already in a revealed state
- what if launcher revealed
- what if in spread view
- what if in dash expanded/category view (or are there any special cases to revert to an idle view)
- what about notifications on display (incl snap-d)
- assuming if only split is allowed in landscape, overlay in potrait
  * does rotating a landscape-splitstaged set of apps force a splitstage out into overlay for portrait
  * does rotating back to landscape after the above remain in overlay or return to split
- what if sidestage app supports mainstage, would we want to fully reflow into mainstage with a rotation into portrait
   * general question there, are there a finite number of application support combinations wrt mainstage vs sidestage, splistage, locked view to portrait/landscape - do we have a matrix to show the options available to an application in the sdk?
- in the case of mainstage only supporting landscape, in rotated will sidestage simply return to overlay with the mismatch in orientation ? or does everything remain locked to landscape....and how would the user know mainstage app is the limiting factor ?
- Instead of making side-stage "disallowed" or moving apps from side-stage to main-stage (or worse, blocking rotation because of what's open), could the way side-stage is displayed simply change based on the available width? For example, when (width > a), sidestage splits the screen with main-stage. When (a > width > b), side-stage overlays on top of main-stage. And when (width < b) it "merges" with the mainstage, so that apps are displayed the same way, regardless of whether they're technically in main-stage or side-stage. That way when you rotate back to landscape (or plug into a larger screen) the side-stage display simply goes back to how it was, nothing is blocked and state (is the side-stage open, what's in it, etc) is not lost.

duflu: This plan seems labour intensive for the same outcome as the morphing screen rotations that Mir will eventually have server-side anyway. Just FYI, you'll hopefully soon have two options and one of them requires zero modification to the shell/clients (other than responding to MirResizeEvent in some cases). I don't see any reason to implement rotation logic in a shell or client unless parts of the screen rotate while others don't (which would be unusual).

@duflu: One reason to have some rotation logic in the client is that the application is the only one that knows how to best animate the rotation of its contents (I mean for anything more than a crossfading/"morph"). Also I don't think something as changeable as a rotation animation should be baked into mir (are all shells implemented with mir getting the same rotation animation?). An animation should be specified in something that you can change easily like qml (you know, designers change their minds all the time) unless there is a technical limitation.
I didn't go deep into the subject yet but I think the app should be receiving orders from the shell and not reading directly from a sensor and the shell is the one orchestrating the overall rotation (shell components + application).
Please check the rotation mechanics of iOS to get an idea of the kind of collaboration and division of responsibilities I'm talking about:
(see "Handling View Rotations")
There might be situations/states in which the shell can't rotate, either because it doesn't make sense, because it's a lot of work to get it done (e.g. right-edge spread) or because the foreground/focused app doesn't support it. Therefore it has to have the last word on it. We would also like, for instance, to rotate the status bar in sync with the foreground app and virtual keyboard (if it happens to be up). And QML is very good at defining animations (it was designed for that).

Saviq May 13th:
@dandrader: I agree with you in that sense, and that's what we did until now (let apps rotate themselves in their own surfaces), but looking at the transition that we have designed, we don't need this. Sure, we need all the APIs around orientation support and locking and such, but we can just tell the surfaces "you're now WxH" halfway through the rotation transition and just be done with it. Are you saying we'd need the other approach for other shells to implement their own approach to rotation where the apps actually rotate inside their surfaces? Is it a common usecase enough to warrant all the work that would come out of it?


Work Items

Work items for ubuntu-14.05:
[unity-ui-team] deliver a landscape image for flo for MAE in June: TODO

Work items:
[unity-design-team] design UX around side stage and rotation: TODO
[unity-design-team] design decide UX on what orientations are available (0, 90, 180, 270): TODO
[unity-design-team] design rotation transitions: TODO
[dandrader] prototype shell rotation on "qt compositor" branches (unity8 & friends): DONE
[dandrader] rotate application thumbnails in dash to follow shell rotation: DONE
[dandrader] Make Dash behave on rotation (it's switching scopes now): INPROGRESS
[dandrader] Make the Stage resizeable (i.e., neatly handle resizes caused by relayouts from portrait to landscape and vice versa): INPROGRESS
[dandrader] bring up stage when app thumbnail or icon gets clicked: DONE
[dandrader] Fix app thumbnail updates: DONE
[dandrader] make application start in shells current orientation: DONE
[dandrader] Fix mess with indicators bar not showing/hiding correctly on app launch or restore: DONE
[dandrader] Fix stage drag autocomplete: TODO
shell stopping its QOrientationSensor (from qtmir) when the display is off (are there other situations?): TODO
hide other sufaces (and their shadows) in the spread when topmost surface is focused/fully shown: TODO
Extend unity8 to support the orientation lock: TODO
[mzanetti] package up qtmir and prepare a PPA for all the Qt compositor branches: DONE
[dandrader] Fix virtual keyboard: DONE
Fix camera app: TODO
UITK team - decide API to allow app define what orientations its surface supports (i.e. can it support portrait, or landscape, or both?) - is http://qt-project.org/doc/qt-5/qscreen.html sufficient for us (see also the discussion in https://tinyurl.com/ldnjgdp)?: TODO
Mir needs ability to let the shell send an orientation event to any surface: TODO
[dandrader] Use Mir side-channel to allow clients specify what orientations they support: TODO
platform-api needs extending to support passing orientation events/data: TODO
[dandrader] platform-api needs to process and expose MirResizeEvents: DONE
Update qtubuntu to support new platform-api orientation APIs: TODO
Settings - Add an orientation lock setting: TODO
Bonus, low-pri. Animate stages.show() and stages.hide() without messing up with the orientation change case: TODO
Bonus, low-pri. Animate orientation change: TODO
[mzanetti] Adapt TabletRightEdge branch to work with QtCompositor branches: INPROGRESS

Dependency tree

* Blueprints in grey have been implemented.

This blueprint contains Public information 
Everyone can see this information.