@@ -82,12 +82,69 @@ FocusScope {
8282
8383 QtObject {
8484 id: priv
85+ objectName: "spreadDelegatePriv"
8586 property bool startingUp: true
8687 }
8788
8889 Component.onCompleted: { finishStartUpTimer.start(); }
8990 Timer { id: finishStartUpTimer; interval: 400; onTriggered: priv.startingUp = false }
9091
92+ // JS version of QPlatformScreen::angleBetween C++ implementation.
93+ // So don't ask me how it works because I don't know.
94+ // Calling Screen.angleBetween from within a Binding component doesn't work for some reason.
95+ function angleBetween(a, b) {
96+ if (a == b)
97+ return 0;
98+
99+ var ia = Math.log(a) / Math.LN2;
100+ var ib = Math.log(b) / Math.LN2;
101+
102+ var delta = ia - ib;
103+
104+ if (delta < 0)
105+ delta = delta + 4;
106+
107+ var angles = [ 0, 90, 180, 270 ];
108+ return angles[delta];
109+ }
110+
111+ // Sets the initial orientationAngle of the window, when it first slides into view
112+ // (with the splash screen likely being displayed). At that point we just try to
113+ // match shell's current orientation. We need a bit of time in this state as the
114+ // information we need to decide orientationAngle may take a few cycles to
115+ // be set.
116+ Binding {
117+ target: appWindowWithShadow
118+ property: "orientationAngle"
119+ when: priv.startingUp
120+ value: {
121+ var supportedOrientations = root.supportedOrientations;
122+
123+ if (supportedOrientations === Qt.PrimaryOrientation) {
124+ supportedOrientations = root.orientations.primary;
125+ }
126+
127+ // If it doesn't support shell's current orientation
128+ // then simply pick some arbitraty one that it does support
129+ var chosenOrientation = 0;
130+ if (supportedOrientations & root.shellOrientation) {
131+ chosenOrientation = root.shellOrientation;
132+ } else if (supportedOrientations & Qt.PortraitOrientation) {
133+ chosenOrientation = root.orientations.portrait;
134+ } else if (supportedOrientations & Qt.LandscapeOrientation) {
135+ chosenOrientation = root.orientations.landscape;
136+ } else if (supportedOrientations & Qt.InvertedPortraitOrientation) {
137+ chosenOrientation = root.orientations.invertedPortrait;
138+ } else if (supportedOrientations & Qt.InvertedLandscapeOrientation) {
139+ chosenOrientation = root.orientations.invertedLandscape;
140+ } else {
141+ chosenOrientation = root.orientations.primary;
142+ }
143+
144+ return angleBetween(root.orientations.native_, chosenOrientation);
145+ }
146+ }
147+
91148 Rectangle {
92149 id: background
93150 color: "black"
@@ -129,9 +186,7 @@ FocusScope {
129186 }
130187
131188 state: {
132− if (priv.startingUp) {
133− return "startingUp";
134− } else if (root.application && root.application.rotatesWindowContents) {
189+ if (root.application && root.application.rotatesWindowContents) {
135190 return "counterRotate";
136191 } else if (orientationChangeAnimation.running) {
137192 return "animatingRotation";
@@ -149,118 +204,53 @@ FocusScope {
149204 }
150205
151206 states: [
152− // Sets the initial orientationAngle of the window, when it first slides into view
153− // (with the splash screen likely being displayed). At that point we just try to
154− // match shell's current orientation. We need a bit of time in this state as the
155− // information we need to decide orientationAngle may take a few cycles to
156− // be set.
207+ // A base state containing bindings common to others
208+ // Ensures appWindowWithShadow fills the root area.
157209 State {
158− name: "startingUp"
210+ name: "fillRootArea"
159211 PropertyChanges {
160212 target: appWindowWithShadow
161213 restoreEntryValues: false
162− orientationAngle: {
163− if (!root.application || root.application.rotatesWindowContents) {
164− return 0;
165− }
166−
167− var supportedOrientations = root.supportedOrientations;
168−
169− if (supportedOrientations === Qt.PrimaryOrientation) {
170− supportedOrientations = root.orientations.primary;
171− }
172−
173− // If it doesn't support shell's current orientation
174− // then simply pick some arbitraty one that it does support
175− var chosenOrientation = 0;
176− if (supportedOrientations & root.shellOrientation) {
177− chosenOrientation = root.shellOrientation;
178− } else if (supportedOrientations & Qt.PortraitOrientation) {
179− chosenOrientation = root.orientations.portrait;
180− } else if (supportedOrientations & Qt.LandscapeOrientation) {
181− chosenOrientation = root.orientations.landscape;
182− } else if (supportedOrientations & Qt.InvertedPortraitOrientation) {
183− chosenOrientation = root.orientations.invertedPortrait;
184− } else if (supportedOrientations & Qt.InvertedLandscapeOrientation) {
185− chosenOrientation = root.orientations.invertedLandscape;
186− } else {
187− chosenOrientation = root.orientations.primary;
188− }
189−
190− return Screen.angleBetween(root.orientations.native_, chosenOrientation);
191− }
192−
193− rotation: normalizeAngle(appWindowWithShadow.orientationAngle - root.shellOrientationAngle)
194− width: {
195− if (rotation == 0 || rotation == 180) {
196− return root.width;
197− } else {
198− return root.height;
199− }
200− }
201− height: {
202− if (rotation == 0 || rotation == 180)
203− return root.height;
204− else
205− return root.width;
206− }
214+ width: appWindowWithShadow.rotation == 0 || appWindowWithShadow.rotation == 180 ? root.width : root.height
215+ height: appWindowWithShadow.rotation == 0 || appWindowWithShadow.rotation == 180 ? root.height : root.width
207216 }
208217 },
209218 // In this state we stick to our currently set orientationAngle, which may change only due
210219 // to calls made to matchShellOrientation() or animateToShellOrientation()
211220 State {
212− id: keepSceneRotationState
213221 name: "keepSceneRotation"
214−
215− StateChangeScript { script: {
216− // break binding
217− appWindowWithShadow.orientationAngle = appWindowWithShadow.orientationAngle;
218− } }
222+ extend: "fillRootArea"
219223 PropertyChanges {
220224 target: appWindowWithShadow
221225 restoreEntryValues: false
222226 rotation: normalizeAngle(appWindowWithShadow.orientationAngle - root.shellOrientationAngle)
223− width: {
224− if (rotation == 0 || rotation == 180) {
225− return root.width;
226− } else {
227− return root.height;
228− }
229− }
230− height: {
231− if (rotation == 0 || rotation == 180)
232− return root.height;
233− else
234− return root.width;
235− }
236227 }
237228 },
238229 // In this state we counteract any shell rotation so that the window, in scene coordinates,
239230 // remains unrotated.
231+ // But the splash screen should still obey the set orientationAngle set by shell
240232 State {
241233 name: "counterRotate"
242− StateChangeScript { script: {
243− // break binding
244− appWindowWithShadow.orientationAngle = appWindowWithShadow.orientationAngle;
245− } }
234+ extend: "fillRootArea"
246235 PropertyChanges {
247236 target: appWindowWithShadow
248− width: root.shellOrientationAngle == 0 || root.shellOrientationAngle == 180 ? root.width : root.height
249− height: root.shellOrientationAngle == 0 || root.shellOrientationAngle == 180 ? root.height : root.width
250237 rotation: normalizeAngle(-root.shellOrientationAngle)
251238 }
252239 PropertyChanges {
253240 target: appWindow
254241 surfaceOrientationAngle: appWindowWithShadow.orientationAngle
242+ splashRotation: appWindowWithShadow.orientationAngle
255243 }
256244 },
245+ // Dummy state.
246+ // The animation may indiscriminately break any bindings assigned to appWindowWithShadow rotation,
247+ // width or height.
257248 State {
258249 name: "animatingRotation"
259250 }
260251 ]
261252
262− x: (parent.width - width) / 2
263− y: (parent.height - height) / 2
253+ anchors.centerIn: parent
264254
265255 BorderImage {
266256 anchors {