on xenial help sign in
Focus first app if there are already some running when we're starting up Fixes: 1339883

Approved by: Gerry Boland

commitb6cc77c27628d7e2cb9ac70d1c7b872f907e3716 authorMichael Zanetti <michael.zanetti@canonical.com> dateThu 18 Sep 2014, 09:42 (12 years ago) parentbd05eece2148e2
17 files changed+385−6
plugins/Unity/Session/CMakeLists.txt+7 plugins/Unity/Session/orientationlock.cpp+74 plugins/Unity/Session/orientationlock.h+62 plugins/Unity/Session/plugin.cpp+8−4 qml/Shell.qml+28 qml/Stages/ApplicationWindow.qml+2 qml/Stages/PhoneStage.qml+9 qml/Stages/SessionContainer.qml+7 qml/Stages/SpreadDelegate.qml+2 qml/Stages/SurfaceContainer.qml+5 qml/Stages/TabletStage.qml+8 tests/mocks/Unity/Application/MirSurfaceItem.cpp+14 tests/mocks/Unity/Application/MirSurfaceItem.h+7 tests/mocks/Unity/Application/MirSurfaceItem.qml+12−2 tests/qmltests/Stages/tst_ApplicationWindow.qml+19 tests/qmltests/Stages/tst_PhoneStage.qml+58 tests/qmltests/Stages/tst_SessionContainer.qml+63
plugins/Unity/Session/CMakeLists.txt+7
@@ -1,10 +1,16 @@
1+include(FindPkgConfig)
2+
3+pkg_search_module(GIO REQUIRED gio-2.0)
4+
15include_directories(
26 ${CMAKE_CURRENT_SOURCE_DIR}
7+ ${GIO_INCLUDE_DIRS}
38)
49
510set(QMLSESSIONPLUGIN_SRC
611 plugin.cpp
712 dbusunitysessionservice.cpp
13+ orientationlock.cpp
814 )
915
1016add_library(UnitySession-qml MODULE
@@ -12,6 +18,7 @@ add_library(UnitySession-qml MODULE
1218 )
1319
1420qt5_use_modules(UnitySession-qml DBus Qml)
21+target_link_libraries(UnitySession-qml ${GIO_LDFLAGS})
1522
1623# export the qmldir and qmltypes files
1724add_unity8_plugin(Unity.Session 0.1 Unity/Session TARGETS UnitySession-qml)
plugins/Unity/Session/orientationlock.cppnew file+74
@@ -0,0 +1,74 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "orientationlock.h"
18+
19+#include <QDBusConnection>
20+#include <QDBusInterface>
21+
22+OrientationLock::OrientationLock(QObject *parent)
23+ : QObject(parent)
24+ , m_enabled(false)
25+ , m_savedOrientation(Qt::PortraitOrientation)
26+{
27+ systemSettings = g_settings_new("com.ubuntu.touch.system");
28+ g_signal_connect(systemSettings, "changed::rotation-lock",
29+ G_CALLBACK(OrientationLock::onEnabledChangedProxy), this);
30+ m_enabled = g_settings_get_boolean(systemSettings, "rotation-lock");
31+}
32+
33+OrientationLock::~OrientationLock()
34+{
35+ g_signal_handlers_disconnect_by_data(systemSettings, this);
36+ g_object_unref(systemSettings);
37+}
38+
39+bool OrientationLock::enabled() const
40+{
41+ return m_enabled;
42+}
43+
44+Qt::ScreenOrientation OrientationLock::savedOrientation() const
45+{
46+ return m_savedOrientation;
47+}
48+
49+void OrientationLock::onEnabledChangedProxy(GSettings */*settings*/, const gchar */*key*/, gpointer data)
50+{
51+ OrientationLock* _this = static_cast<OrientationLock*>(data);
52+ _this->onEnabledChanged();
53+}
54+
55+void OrientationLock::onEnabledChanged()
56+{
57+ const bool enabled = g_settings_get_boolean(systemSettings, "rotation-lock");
58+ if (m_enabled != enabled) {
59+ m_enabled = enabled;
60+ Q_EMIT enabledChanged();
61+ }
62+}
63+
64+void OrientationLock::setSavedOrientation(const Qt::ScreenOrientation orientation)
65+{
66+ if (orientation == m_savedOrientation) {
67+ return;
68+ }
69+
70+ m_savedOrientation = orientation;
71+
72+ //TODO - save value with dbus to persist over sessions
73+ Q_EMIT savedOrientationChanged();
74+}
plugins/Unity/Session/orientationlock.hnew file+62
@@ -0,0 +1,62 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef ORIENTATIONLOCK_H
18+#define ORIENTATIONLOCK_H
19+
20+#include <gio/gio.h>
21+#include <QtCore/QObject>
22+#include <QtDBus/QDBusInterface>
23+
24+/**
25+ * @brief The OrientationLock class exports orientation lock related properties to QML
26+ * It has two properties:
27+ * - readonly boolean with the Orientation lock property state
28+ * - Qt::ScreenOrientation to save the locked orientation state across Sessions (only relevant if lock is true)
29+ */
30+class OrientationLock : public QObject
31+{
32+ Q_OBJECT
33+
34+ Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
35+ Q_PROPERTY(Qt::ScreenOrientation savedOrientation READ savedOrientation WRITE setSavedOrientation
36+ NOTIFY savedOrientationChanged)
37+
38+public:
39+ explicit OrientationLock(QObject *parent = 0);
40+ ~OrientationLock();
41+
42+ bool enabled() const;
43+ Qt::ScreenOrientation savedOrientation() const;
44+ void setSavedOrientation(const Qt::ScreenOrientation orientation);
45+
46+Q_SIGNALS:
47+ void enabledChanged();
48+ void savedOrientationChanged();
49+
50+private Q_SLOTS:
51+ static void onEnabledChangedProxy(GSettings *settings, const gchar *key, gpointer data);
52+ void onEnabledChanged();
53+
54+private:
55+ QDBusInterface *dbusInterface;
56+ GSettings *systemSettings;
57+
58+ bool m_enabled;
59+ Qt::ScreenOrientation m_savedOrientation;
60+};
61+
62+#endif // ORIENTATIONLOCK_H
plugins/Unity/Session/plugin.cpp+8−4
@@ -18,23 +18,27 @@
1818
1919#include "plugin.h"
2020#include "dbusunitysessionservice.h"
21+#include "orientationlock.h"
2122
2223#include <QAbstractItemModel>
2324#include <QDBusConnection>
2425#include <QtQml/qqml.h>
2526
26−static QObject *dbusunitysessionservice_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
27+static QObject *dbusunitysessionservice_provider(QQmlEngine */*engine*/, QJSEngine */*jsEngine*/)
2728{
28− Q_UNUSED(engine)
29− Q_UNUSED(scriptEngine)
30−
3129 return new DBusUnitySessionService();
3230}
3331
32+static QObject *orientationlock_provider(QQmlEngine */*engine*/, QJSEngine */*jsEngine*/)
33+{
34+ return new OrientationLock();
35+}
36+
3437void SessionPlugin::registerTypes(const char *uri)
3538{
3639 qmlRegisterType<QAbstractItemModel>();
3740
3841 Q_ASSERT(uri == QLatin1String("Unity.Session"));
3942 qmlRegisterSingletonType<DBusUnitySessionService>(uri, 0, 1, "DBusUnitySessionService", dbusunitysessionservice_provider);
43+ qmlRegisterSingletonType<OrientationLock>(uri, 0, 1, "OrientationLock", orientationlock_provider);
4044}
qml/Shell.qml+28
@@ -15,6 +15,7 @@
1515 */
1616
1717import QtQuick 2.0
18+import QtQuick.Window 2.0
1819import AccountsService 0.1
1920import GSettings 1.0
2021import Unity.Application 0.1
@@ -61,6 +62,22 @@ Item {
6162 property int failedLoginsDelayAttempts: 7 // number of failed logins
6263 property int failedLoginsDelaySeconds: 5 * 60 // seconds of forced waiting
6364
65+ property int orientation
66+ readonly property int deviceOrientationAngle: Screen.angleBetween(Screen.primaryOrientation, Screen.orientation)
67+ onDeviceOrientationAngleChanged: {
68+ if (!OrientationLock.enabled) {
69+ orientation = Screen.orientation;
70+ }
71+ }
72+ readonly property bool orientationLockEnabled: OrientationLock.enabled
73+ onOrientationLockEnabledChanged: {
74+ if (orientationLockEnabled) {
75+ OrientationLock.savedOrientation = Screen.orientation;
76+ } else {
77+ orientation = Screen.orientation;
78+ }
79+ }
80+
6481 function activateApplication(appId) {
6582 if (ApplicationManager.findApplication(appId)) {
6683 ApplicationManager.requestFocusApplication(appId);
@@ -85,6 +102,12 @@ Item {
85102
86103 Component.onCompleted: {
87104 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
105+ if (ApplicationManager.count > 0) {
106+ ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
107+ }
108+ if (orientationLockEnabled) {
109+ orientation = OrientationLock.savedOrientation;
110+ }
88111 }
89112
90113 GSettings {
@@ -207,6 +230,11 @@ Item {
207230 property: "inverseProgress"
208231 value: launcher.progress
209232 }
233+ Binding {
234+ target: applicationsDisplayLoader.item
235+ property: "orientation"
236+ value: shell.orientation
237+ }
210238 }
211239 }
212240
qml/Stages/ApplicationWindow.qml+2
@@ -27,6 +27,7 @@ Item {
2727
2828 // to be set from outside
2929 property QtObject application
30+ property int orientation
3031
3132 QtObject {
3233 id: d
@@ -111,6 +112,7 @@ Item {
111112 id: sessionContainer
112113 session: application ? application.session : null
113114 anchors.fill: parent
115+ orientation: root.orientation
114116
115117 onSurfaceChanged: {
116118 if (sessionContainer.surface) {
qml/Stages/PhoneStage.qml+9
@@ -18,6 +18,7 @@ import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Ubuntu.Gestures 0.1
2020import Unity.Application 0.1
21+import Unity.Session 0.1
2122import Utils 0.1
2223import "../Components"
2324
@@ -30,6 +31,7 @@ Rectangle {
3031 property bool interactive
3132 property bool spreadEnabled: true // If false, animations and right edge will be disabled
3233 property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
34+ property int orientation: Qt.PortraitOrientation
3335
3436 color: "black"
3537
@@ -372,6 +374,13 @@ Rectangle {
372374 progress: appDelegate.progress - spreadView.positionMarker1
373375 }
374376
377+ Binding {
378+ target: appDelegate
379+ property: "orientation"
380+ when: appDelegate.interactive
381+ value: root.orientation
382+ }
383+
375384 onClicked: {
376385 if (spreadView.phase == 2) {
377386 if (ApplicationManager.focusedApplicationId == ApplicationManager.get(index).appId) {
qml/Stages/SessionContainer.qml+7
@@ -24,12 +24,14 @@ Item {
2424 readonly property var childSessions: session ? session.childSessions : null
2525 readonly property alias surface: _surfaceContainer.surface
2626 property bool interactive: true
27+ property int orientation
2728
2829 readonly property alias surfaceContainer: _surfaceContainer
2930 SurfaceContainer {
3031 id: _surfaceContainer
3132 anchors.fill: parent
3233 surface: session ? session.surface : null
34+ orientation: root.orientation
3335 }
3436
3537 Binding {
@@ -74,6 +76,11 @@ Item {
7476 target: item; when: item
7577 property: "height"; value: root.height
7678 }
79+
80+ Binding {
81+ target: item; when: item
82+ property: "orientation"; value: root.orientation
83+ }
7784 }
7885 }
7986
qml/Stages/SpreadDelegate.qml+2
@@ -36,6 +36,7 @@ Item {
3636 property alias swipeToCloseEnabled: dragArea.enabled
3737 property bool closeable
3838 property alias application: appWindow.application
39+ property int orientation
3940
4041 Item {
4142 objectName: "appWindowWithShadow"
@@ -62,6 +63,7 @@ Item {
6263 }
6364
6465 interactive: root.interactive
66+ orientation: root.orientation
6567 }
6668 }
6769
qml/Stages/SurfaceContainer.qml+5
@@ -22,6 +22,7 @@ Item {
2222 objectName: "surfaceContainer"
2323 property Item surface: null
2424 property bool hadSurface: false
25+ property int orientation
2526
2627 onSurfaceChanged: {
2728 if (surface) {
@@ -34,6 +35,10 @@ Item {
3435 target: surface
3536 property: "anchors.fill"; value: root
3637 }
38+ Binding {
39+ target: surface
40+ property: "orientation"; value: root.orientation
41+ }
3742
3843 states: [
3944 State {
qml/Stages/TabletStage.qml+8
@@ -34,6 +34,7 @@ Rectangle {
3434 property real maximizedAppTopMargin
3535 property bool interactive
3636 property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
37+ property int orientation: Qt.PortraitOrientation
3738
3839 onInverseProgressChanged: {
3940 // This can't be a simple binding because that would be triggered after this handler
@@ -535,6 +536,13 @@ Rectangle {
535536 return progress;
536537 }
537538
539+ Binding {
540+ target: spreadTile
541+ property: "orientation"
542+ when: spreadTile.interactive
543+ value: root.orientation
544+ }
545+
538546 onClicked: {
539547 if (spreadView.phase == 2) {
540548 spreadView.snapTo(index);
tests/mocks/Unity/Application/MirSurfaceItem.cpp+14
@@ -39,6 +39,7 @@ MirSurfaceItem::MirSurfaceItem(const QString& name,
3939 , m_type(type)
4040 , m_state(state)
4141 , m_live(true)
42+ , m_orientation(Qt::PortraitOrientation)
4243 , m_qmlItem(nullptr)
4344 , m_screenshotUrl(screenshot)
4445{
@@ -108,6 +109,19 @@ void MirSurfaceItem::release()
108109 }
109110}
110111
112+void MirSurfaceItem::setOrientation(const Qt::ScreenOrientation orientation)
113+{
114+ if (m_orientation == orientation)
115+ return;
116+
117+ m_orientation = orientation;
118+
119+ QQmlProperty orientationProp(m_qmlItem, "orientation");
120+ orientationProp.write(QVariant::fromValue(orientation));
121+
122+ Q_EMIT orientationChanged();
123+}
124+
111125void MirSurfaceItem::setSession(Session* session)
112126{
113127 m_session = session;
tests/mocks/Unity/Application/MirSurfaceItem.h+7
@@ -34,6 +34,7 @@ class MirSurfaceItem : public QQuickItem
3434 Q_PROPERTY(State state READ state NOTIFY stateChanged)
3535 Q_PROPERTY(QString name READ name CONSTANT)
3636 Q_PROPERTY(bool live READ live NOTIFY liveChanged)
37+ Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged DESIGNABLE false)
3738
3839public:
3940 enum Type {
@@ -64,6 +65,9 @@ public:
6465 State state() const { return m_state; }
6566 QString name() const { return m_name; }
6667 bool live() const { return m_live; }
68+ Qt::ScreenOrientation orientation() const { return m_orientation; }
69+
70+ void setOrientation(const Qt::ScreenOrientation orientation);
6771
6872 void setSession(Session* item);
6973 void setScreenshot(const QUrl& screenshot);
@@ -76,6 +80,7 @@ Q_SIGNALS:
7680 void typeChanged(Type);
7781 void stateChanged(State);
7882 void liveChanged(bool live);
83+ void orientationChanged();
7984
8085 void inputMethodRequested();
8186 void inputMethodDismissed();
@@ -104,6 +109,7 @@ private:
104109 const Type m_type;
105110 State m_state;
106111 bool m_live;
112+ Qt::ScreenOrientation m_orientation;
107113
108114 QQmlComponent *m_qmlContentComponent;
109115 QQuickItem *m_qmlItem;
@@ -114,5 +120,6 @@ private:
114120
115121Q_DECLARE_METATYPE(MirSurfaceItem*)
116122Q_DECLARE_METATYPE(QList<MirSurfaceItem*>)
123+Q_DECLARE_METATYPE(Qt::ScreenOrientation)
117124
118125#endif // MIRSURFACEITEM_H
tests/mocks/Unity/Application/MirSurfaceItem.qml+12−2
@@ -21,12 +21,22 @@ Rectangle {
2121 id: root
2222 color: "pink"
2323
24− anchors.fill: parent
25−
2624 implicitWidth: units.gu(40)
2725 implicitHeight: units.gu(70)
2826
27+ rotation: {
28+ if (orientation == Qt.PortraitOrientation) return 0;
29+ else if (orientation == Qt.LandscapeOrientation) return 90;
30+ else if (orientation == Qt.InvertedPortraitOrientation) return 180;
31+ else return 270;
32+ }
33+ x: parent ? (parent.width - width) / 2 : 0
34+ y: parent ? (parent.height - height) / 2 : 0
35+ width: parent ? (rotation == 0 || rotation == 180 ? parent.width : parent.height) : implicitWidth
36+ height: parent ? (rotation == 0 || rotation == 180 ? parent.height : parent.width) : implicitHeight
37+
2938 property alias screenshotSource: screenshotImage.source
39+ property int orientation: Qt.PortraitOrientation
3040
3141 property bool wantInputMethod: false
3242
tests/qmltests/Stages/tst_ApplicationWindow.qml+19
@@ -50,6 +50,7 @@ Rectangle {
5050 ApplicationWindow {
5151 anchors.fill: parent
5252 application: fakeApplication
53+ orientation: Qt.PortraitOrientation
5354 }
5455 }
5556 FocusScope {
@@ -147,6 +148,24 @@ Rectangle {
147148 }
148149 }
149150
151+ Button {
152+ anchors { left: parent.left; right: parent.right }
153+ text: "Rotate device \u27F3"
154+ onClicked: {
155+ var orientation = applicationWindowLoader.item.orientation
156+ if (orientation == Qt.PortraitOrientation) {
157+ orientation = Qt.LandscapeOrientation;
158+ } else if (orientation == Qt.LandscapeOrientation) {
159+ orientation = Qt.InvertedPortraitOrientation;
160+ } else if (orientation == Qt.InvertedPortraitOrientation) {
161+ orientation = Qt.InvertedLandscapeOrientation;
162+ } else {
163+ orientation = Qt.PortraitOrientation;
164+ }
165+ applicationWindowLoader.item.orientation = orientation;
166+ }
167+ }
168+
150169 }
151170 }
152171
tests/qmltests/Stages/tst_PhoneStage.qml+58
@@ -31,6 +31,8 @@ Item {
3131 anchors { fill: parent; rightMargin: units.gu(30) }
3232 dragAreaWidth: units.gu(2)
3333 maximizedAppTopMargin: units.gu(3) + units.dp(2)
34+ interactive: true
35+ orientation: Qt.PortraitOrientation
3436 }
3537
3638 Binding {
@@ -67,6 +69,21 @@ Item {
6769 ApplicationManager.get(appList.selectedAppIndex).setState(ApplicationInfoInterface.Stopped);
6870 }
6971 }
72+ Button {
73+ anchors { left: parent.left; right: parent.right }
74+ text: "Rotate device \u27F3"
75+ onClicked: {
76+ if (phoneStage.orientation == Qt.PortraitOrientation) {
77+ phoneStage.orientation = Qt.LandscapeOrientation;
78+ } else if (phoneStage.orientation == Qt.LandscapeOrientation) {
79+ phoneStage.orientation = Qt.InvertedPortraitOrientation;
80+ } else if (phoneStage.orientation == Qt.InvertedPortraitOrientation) {
81+ phoneStage.orientation = Qt.InvertedLandscapeOrientation;
82+ } else {
83+ phoneStage.orientation = Qt.PortraitOrientation;
84+ }
85+ }
86+ }
7087 }
7188 ListView {
7289 id: appList
@@ -256,6 +273,46 @@ Item {
256273 compare(ApplicationManager.focusedApplicationId, selectedApp.appId);
257274 }
258275
276+ function test_orientation_change_sent_to_focused_app() {
277+ phoneStage.orientation = Qt.PortraitOrientation;
278+ addApps(1);
279+
280+ var spreadView = findChild(phoneStage, "spreadView");
281+ var app = findChild(spreadView, "appDelegate0");
282+ tryCompare(app, "orientation", Qt.PortraitOrientation);
283+
284+ phoneStage.orientation = Qt.LandscapeOrientation;
285+ tryCompare(app, "orientation", Qt.LandscapeOrientation);
286+ }
287+
288+ function test_orientation_change_not_sent_to_apps_while_spread_open() {
289+ phoneStage.orientation = Qt.PortraitOrientation;
290+ addApps(1);
291+
292+ var spreadView = findChild(phoneStage, "spreadView");
293+ var app = findChild(spreadView, "appDelegate0");
294+ tryCompare(app, "orientation", Qt.PortraitOrientation);
295+
296+ goToSpread();
297+ phoneStage.orientation = Qt.LandscapeOrientation;
298+ tryCompare(app, "orientation", Qt.PortraitOrientation);
299+ }
300+
301+ function test_orientation_change_not_sent_to_unfocused_app_until_it_focused() {
302+ phoneStage.orientation = Qt.PortraitOrientation;
303+ addApps(1);
304+
305+ var spreadView = findChild(phoneStage, "spreadView");
306+ var app = findChild(spreadView, "appDelegate0");
307+
308+ goToSpread();
309+ phoneStage.orientation = Qt.LandscapeOrientation;
310+ tryCompare(app, "orientation", Qt.PortraitOrientation);
311+
312+ phoneStage.select(app.application.appId);
313+ tryCompare(app, "orientation", Qt.LandscapeOrientation);
314+ }
315+
259316 function cleanup() {
260317 while (ApplicationManager.count > 1) {
261318 var oldCount = ApplicationManager.count;
@@ -263,6 +320,7 @@ Item {
263320 ApplicationManager.stopApplication(ApplicationManager.get(closingIndex).appId)
264321 tryCompare(ApplicationManager, "count", oldCount - 1)
265322 }
323+ phoneStage.orientation = Qt.PortraitOrientation;
266324 }
267325 }
268326}
tests/qmltests/Stages/tst_SessionContainer.qml+63
@@ -41,6 +41,7 @@ Rectangle {
4141 SessionContainer {
4242 id: sessionContainer
4343 anchors.fill: parent
44+ orientation: Qt.PortraitOrientation
4445 }
4546 }
4647
@@ -112,6 +113,24 @@ Rectangle {
112113 session: sessionContainerLoader.item ? sessionContainerLoader.item.session : null
113114 }
114115 }
116+
117+ Button {
118+ anchors { left: parent.left; right: parent.right }
119+ text: "Rotate device \u27F3"
120+ onClicked: {
121+ var orientation = sessionContainerLoader.item.orientation
122+ if (orientation == Qt.PortraitOrientation) {
123+ orientation = Qt.LandscapeOrientation;
124+ } else if (orientation == Qt.LandscapeOrientation) {
125+ orientation = Qt.InvertedPortraitOrientation;
126+ } else if (orientation == Qt.InvertedPortraitOrientation) {
127+ orientation = Qt.InvertedLandscapeOrientation;
128+ } else {
129+ orientation = Qt.PortraitOrientation;
130+ }
131+ sessionContainerLoader.item.orientation = orientation;
132+ }
133+ }
115134 }
116135 }
117136
@@ -263,5 +282,49 @@ Rectangle {
263282 // wait for animation to end
264283 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false);
265284 }
285+
286+ function test_orientationPropagatedToChildren_data() {
287+ return [ { tag: "count=1", count: 1 },
288+ { tag: "count=4", count: 4 } ];
289+ }
290+
291+ /* Test orientation changes are propagated to all children immediately */
292+ function test_orientationPropagatedToChildren(data) {
293+ sessionCheckbox.checked = true;
294+ var rootSessionContainer = sessionContainerLoader.item;
295+ compare(rootSessionContainer.childSessions.count(), 0);
296+
297+ var i;
298+ var sessions = [];
299+ for (i = 0; i < data.count; i++) {
300+ var session = ApplicationTest.addChildSession(rootSessionContainer.session,
301+ "gallery");
302+ session.createSurface();
303+ rootSessionContainer.session.addChildSession(session);
304+
305+ // Check child SessionContainer has orientation matching the parent
306+ var delegate = findChild(rootSessionContainer, "childDelegate" + i);
307+ var childSessionContainer = findChild(delegate, "sessionContainer");
308+
309+ tryCompare(rootSessionContainer, "orientation", childSessionContainer.orientation);
310+
311+ sessions.push(session);
312+ }
313+
314+ // Change orientation and verify all children updated
315+ rootSessionContainer.orientation = Qt.LandscapeOrientation;
316+
317+ for (i = 0; i < data.count; i++) {
318+ var delegate = findChild(rootSessionContainer, "childDelegate" + i);
319+ var childSessionContainer = findChild(delegate, "sessionContainer");
320+
321+ tryCompare(rootSessionContainer, "orientation", childSessionContainer.orientation);
322+ }
323+
324+ // Clean up
325+ for (i = data.count-1; i >= 0; i--) {
326+ ApplicationTest.removeSession(sessions[i]);
327+ }
328+ }
266329 }
267330}