on xenial help sign in
Focus first app if there are already some running when we're starting up Fixes: 1339883
b6cc77cMichael Zanetti
plugins/Unity/Session/CMakeLists.txt+7
@@ -1,10 +1,16 @@
1+include(FindPkgConfig)
2+
3+pkg_search_module(GIO REQUIRED gio-2.0)
4+
1include_directories(
5include_directories(
2 ${CMAKE_CURRENT_SOURCE_DIR}
6 ${CMAKE_CURRENT_SOURCE_DIR}
7+ ${GIO_INCLUDE_DIRS}
3)
8)
4
9
5set(QMLSESSIONPLUGIN_SRC
10set(QMLSESSIONPLUGIN_SRC
6 plugin.cpp
11 plugin.cpp
7 dbusunitysessionservice.cpp
12 dbusunitysessionservice.cpp
13+ orientationlock.cpp
8 )
14 )
9
15
10add_library(UnitySession-qml MODULE
16add_library(UnitySession-qml MODULE
@@ -12,6 +18,7 @@ add_library(UnitySession-qml MODULE
12 )
18 )
13
19
14qt5_use_modules(UnitySession-qml DBus Qml)
20qt5_use_modules(UnitySession-qml DBus Qml)
21+target_link_libraries(UnitySession-qml ${GIO_LDFLAGS})
15
22
16# export the qmldir and qmltypes files
23# export the qmldir and qmltypes files
17add_unity8_plugin(Unity.Session 0.1 Unity/Session TARGETS UnitySession-qml)
24add_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 @@
18
18
19#include "plugin.h"
19#include "plugin.h"
20#include "dbusunitysessionservice.h"
20#include "dbusunitysessionservice.h"
21+#include "orientationlock.h"
21
22
22#include <QAbstractItemModel>
23#include <QAbstractItemModel>
23#include <QDBusConnection>
24#include <QDBusConnection>
24#include <QtQml/qqml.h>
25#include <QtQml/qqml.h>
25
26
26−static QObject *dbusunitysessionservice_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
27+static QObject *dbusunitysessionservice_provider(QQmlEngine */*engine*/, QJSEngine */*jsEngine*/)
27{
28{
28− Q_UNUSED(engine)
29− Q_UNUSED(scriptEngine)
30−
31 return new DBusUnitySessionService();
29 return new DBusUnitySessionService();
32}
30}
33
31
32+static QObject *orientationlock_provider(QQmlEngine */*engine*/, QJSEngine */*jsEngine*/)
33+{
34+ return new OrientationLock();
35+}
36+
34void SessionPlugin::registerTypes(const char *uri)
37void SessionPlugin::registerTypes(const char *uri)
35{
38{
36 qmlRegisterType<QAbstractItemModel>();
39 qmlRegisterType<QAbstractItemModel>();
37
40
38 Q_ASSERT(uri == QLatin1String("Unity.Session"));
41 Q_ASSERT(uri == QLatin1String("Unity.Session"));
39 qmlRegisterSingletonType<DBusUnitySessionService>(uri, 0, 1, "DBusUnitySessionService", dbusunitysessionservice_provider);
42 qmlRegisterSingletonType<DBusUnitySessionService>(uri, 0, 1, "DBusUnitySessionService", dbusunitysessionservice_provider);
43+ qmlRegisterSingletonType<OrientationLock>(uri, 0, 1, "OrientationLock", orientationlock_provider);
40}
44}
qml/Shell.qml+28
@@ -15,6 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import QtQuick.Window 2.0
18import AccountsService 0.1
19import AccountsService 0.1
19import GSettings 1.0
20import GSettings 1.0
20import Unity.Application 0.1
21import Unity.Application 0.1
@@ -61,6 +62,22 @@ Item {
61 property int failedLoginsDelayAttempts: 7 // number of failed logins
62 property int failedLoginsDelayAttempts: 7 // number of failed logins
62 property int failedLoginsDelaySeconds: 5 * 60 // seconds of forced waiting
63 property int failedLoginsDelaySeconds: 5 * 60 // seconds of forced waiting
63
64
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+
64 function activateApplication(appId) {
81 function activateApplication(appId) {
65 if (ApplicationManager.findApplication(appId)) {
82 if (ApplicationManager.findApplication(appId)) {
66 ApplicationManager.requestFocusApplication(appId);
83 ApplicationManager.requestFocusApplication(appId);
@@ -85,6 +102,12 @@ Item {
85
102
86 Component.onCompleted: {
103 Component.onCompleted: {
87 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
104 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+ }
88 }
111 }
89
112
90 GSettings {
113 GSettings {
@@ -207,6 +230,11 @@ Item {
207 property: "inverseProgress"
230 property: "inverseProgress"
208 value: launcher.progress
231 value: launcher.progress
209 }
232 }
233+ Binding {
234+ target: applicationsDisplayLoader.item
235+ property: "orientation"
236+ value: shell.orientation
237+ }
210 }
238 }
211 }
239 }
212
240
qml/Stages/ApplicationWindow.qml+2
@@ -27,6 +27,7 @@ Item {
27
27
28 // to be set from outside
28 // to be set from outside
29 property QtObject application
29 property QtObject application
30+ property int orientation
30
31
31 QtObject {
32 QtObject {
32 id: d
33 id: d
@@ -111,6 +112,7 @@ Item {
111 id: sessionContainer
112 id: sessionContainer
112 session: application ? application.session : null
113 session: application ? application.session : null
113 anchors.fill: parent
114 anchors.fill: parent
115+ orientation: root.orientation
114
116
115 onSurfaceChanged: {
117 onSurfaceChanged: {
116 if (sessionContainer.surface) {
118 if (sessionContainer.surface) {
qml/Stages/PhoneStage.qml+9
@@ -18,6 +18,7 @@ import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20import Unity.Application 0.1
20import Unity.Application 0.1
21+import Unity.Session 0.1
21import Utils 0.1
22import Utils 0.1
22import "../Components"
23import "../Components"
23
24
@@ -30,6 +31,7 @@ Rectangle {
30 property bool interactive
31 property bool interactive
31 property bool spreadEnabled: true // If false, animations and right edge will be disabled
32 property bool spreadEnabled: true // If false, animations and right edge will be disabled
32 property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
33 property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
34+ property int orientation: Qt.PortraitOrientation
33
35
34 color: "black"
36 color: "black"
35
37
@@ -372,6 +374,13 @@ Rectangle {
372 progress: appDelegate.progress - spreadView.positionMarker1
374 progress: appDelegate.progress - spreadView.positionMarker1
373 }
375 }
374
376
377+ Binding {
378+ target: appDelegate
379+ property: "orientation"
380+ when: appDelegate.interactive
381+ value: root.orientation
382+ }
383+
375 onClicked: {
384 onClicked: {
376 if (spreadView.phase == 2) {
385 if (spreadView.phase == 2) {
377 if (ApplicationManager.focusedApplicationId == ApplicationManager.get(index).appId) {
386 if (ApplicationManager.focusedApplicationId == ApplicationManager.get(index).appId) {
qml/Stages/SessionContainer.qml+7
@@ -24,12 +24,14 @@ Item {
24 readonly property var childSessions: session ? session.childSessions : null
24 readonly property var childSessions: session ? session.childSessions : null
25 readonly property alias surface: _surfaceContainer.surface
25 readonly property alias surface: _surfaceContainer.surface
26 property bool interactive: true
26 property bool interactive: true
27+ property int orientation
27
28
28 readonly property alias surfaceContainer: _surfaceContainer
29 readonly property alias surfaceContainer: _surfaceContainer
29 SurfaceContainer {
30 SurfaceContainer {
30 id: _surfaceContainer
31 id: _surfaceContainer
31 anchors.fill: parent
32 anchors.fill: parent
32 surface: session ? session.surface : null
33 surface: session ? session.surface : null
34+ orientation: root.orientation
33 }
35 }
34
36
35 Binding {
37 Binding {
@@ -74,6 +76,11 @@ Item {
74 target: item; when: item
76 target: item; when: item
75 property: "height"; value: root.height
77 property: "height"; value: root.height
76 }
78 }
79+
80+ Binding {
81+ target: item; when: item
82+ property: "orientation"; value: root.orientation
83+ }
77 }
84 }
78 }
85 }
79
86
qml/Stages/SpreadDelegate.qml+2
@@ -36,6 +36,7 @@ Item {
36 property alias swipeToCloseEnabled: dragArea.enabled
36 property alias swipeToCloseEnabled: dragArea.enabled
37 property bool closeable
37 property bool closeable
38 property alias application: appWindow.application
38 property alias application: appWindow.application
39+ property int orientation
39
40
40 Item {
41 Item {
41 objectName: "appWindowWithShadow"
42 objectName: "appWindowWithShadow"
@@ -62,6 +63,7 @@ Item {
62 }
63 }
63
64
64 interactive: root.interactive
65 interactive: root.interactive
66+ orientation: root.orientation
65 }
67 }
66 }
68 }
67
69
qml/Stages/SurfaceContainer.qml+5
@@ -22,6 +22,7 @@ Item {
22 objectName: "surfaceContainer"
22 objectName: "surfaceContainer"
23 property Item surface: null
23 property Item surface: null
24 property bool hadSurface: false
24 property bool hadSurface: false
25+ property int orientation
25
26
26 onSurfaceChanged: {
27 onSurfaceChanged: {
27 if (surface) {
28 if (surface) {
@@ -34,6 +35,10 @@ Item {
34 target: surface
35 target: surface
35 property: "anchors.fill"; value: root
36 property: "anchors.fill"; value: root
36 }
37 }
38+ Binding {
39+ target: surface
40+ property: "orientation"; value: root.orientation
41+ }
37
42
38 states: [
43 states: [
39 State {
44 State {
qml/Stages/TabletStage.qml+8
@@ -34,6 +34,7 @@ Rectangle {
34 property real maximizedAppTopMargin
34 property real maximizedAppTopMargin
35 property bool interactive
35 property bool interactive
36 property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
36 property real inverseProgress: 0 // This is the progress for left edge drags, in pixels.
37+ property int orientation: Qt.PortraitOrientation
37
38
38 onInverseProgressChanged: {
39 onInverseProgressChanged: {
39 // This can't be a simple binding because that would be triggered after this handler
40 // This can't be a simple binding because that would be triggered after this handler
@@ -535,6 +536,13 @@ Rectangle {
535 return progress;
536 return progress;
536 }
537 }
537
538
539+ Binding {
540+ target: spreadTile
541+ property: "orientation"
542+ when: spreadTile.interactive
543+ value: root.orientation
544+ }
545+
538 onClicked: {
546 onClicked: {
539 if (spreadView.phase == 2) {
547 if (spreadView.phase == 2) {
540 spreadView.snapTo(index);
548 spreadView.snapTo(index);
tests/mocks/Unity/Application/MirSurfaceItem.cpp+14
@@ -39,6 +39,7 @@ MirSurfaceItem::MirSurfaceItem(const QString& name,
39 , m_type(type)
39 , m_type(type)
40 , m_state(state)
40 , m_state(state)
41 , m_live(true)
41 , m_live(true)
42+ , m_orientation(Qt::PortraitOrientation)
42 , m_qmlItem(nullptr)
43 , m_qmlItem(nullptr)
43 , m_screenshotUrl(screenshot)
44 , m_screenshotUrl(screenshot)
44{
45{
@@ -108,6 +109,19 @@ void MirSurfaceItem::release()
108 }
109 }
109}
110}
110
111
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+
111void MirSurfaceItem::setSession(Session* session)
125void MirSurfaceItem::setSession(Session* session)
112{
126{
113 m_session = session;
127 m_session = session;
tests/mocks/Unity/Application/MirSurfaceItem.h+7
@@ -34,6 +34,7 @@ class MirSurfaceItem : public QQuickItem
34 Q_PROPERTY(State state READ state NOTIFY stateChanged)
34 Q_PROPERTY(State state READ state NOTIFY stateChanged)
35 Q_PROPERTY(QString name READ name CONSTANT)
35 Q_PROPERTY(QString name READ name CONSTANT)
36 Q_PROPERTY(bool live READ live NOTIFY liveChanged)
36 Q_PROPERTY(bool live READ live NOTIFY liveChanged)
37+ Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged DESIGNABLE false)
37
38
38public:
39public:
39 enum Type {
40 enum Type {
@@ -64,6 +65,9 @@ public:
64 State state() const { return m_state; }
65 State state() const { return m_state; }
65 QString name() const { return m_name; }
66 QString name() const { return m_name; }
66 bool live() const { return m_live; }
67 bool live() const { return m_live; }
68+ Qt::ScreenOrientation orientation() const { return m_orientation; }
69+
70+ void setOrientation(const Qt::ScreenOrientation orientation);
67
71
68 void setSession(Session* item);
72 void setSession(Session* item);
69 void setScreenshot(const QUrl& screenshot);
73 void setScreenshot(const QUrl& screenshot);
@@ -76,6 +80,7 @@ Q_SIGNALS:
76 void typeChanged(Type);
80 void typeChanged(Type);
77 void stateChanged(State);
81 void stateChanged(State);
78 void liveChanged(bool live);
82 void liveChanged(bool live);
83+ void orientationChanged();
79
84
80 void inputMethodRequested();
85 void inputMethodRequested();
81 void inputMethodDismissed();
86 void inputMethodDismissed();
@@ -104,6 +109,7 @@ private:
104 const Type m_type;
109 const Type m_type;
105 State m_state;
110 State m_state;
106 bool m_live;
111 bool m_live;
112+ Qt::ScreenOrientation m_orientation;
107
113
108 QQmlComponent *m_qmlContentComponent;
114 QQmlComponent *m_qmlContentComponent;
109 QQuickItem *m_qmlItem;
115 QQuickItem *m_qmlItem;
@@ -114,5 +120,6 @@ private:
114
120
115Q_DECLARE_METATYPE(MirSurfaceItem*)
121Q_DECLARE_METATYPE(MirSurfaceItem*)
116Q_DECLARE_METATYPE(QList<MirSurfaceItem*>)
122Q_DECLARE_METATYPE(QList<MirSurfaceItem*>)
123+Q_DECLARE_METATYPE(Qt::ScreenOrientation)
117
124
118#endif // MIRSURFACEITEM_H
125#endif // MIRSURFACEITEM_H
tests/mocks/Unity/Application/MirSurfaceItem.qml+12−2
@@ -21,12 +21,22 @@ Rectangle {
21 id: root
21 id: root
22 color: "pink"
22 color: "pink"
23
23
24− anchors.fill: parent
25−
26 implicitWidth: units.gu(40)
24 implicitWidth: units.gu(40)
27 implicitHeight: units.gu(70)
25 implicitHeight: units.gu(70)
28
26
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+
29 property alias screenshotSource: screenshotImage.source
38 property alias screenshotSource: screenshotImage.source
39+ property int orientation: Qt.PortraitOrientation
30
40
31 property bool wantInputMethod: false
41 property bool wantInputMethod: false
32
42
tests/qmltests/Stages/tst_ApplicationWindow.qml+19
@@ -50,6 +50,7 @@ Rectangle {
50 ApplicationWindow {
50 ApplicationWindow {
51 anchors.fill: parent
51 anchors.fill: parent
52 application: fakeApplication
52 application: fakeApplication
53+ orientation: Qt.PortraitOrientation
53 }
54 }
54 }
55 }
55 FocusScope {
56 FocusScope {
@@ -147,6 +148,24 @@ Rectangle {
147 }
148 }
148 }
149 }
149
150
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+
150 }
169 }
151 }
170 }
152
171
tests/qmltests/Stages/tst_PhoneStage.qml+58
@@ -31,6 +31,8 @@ Item {
31 anchors { fill: parent; rightMargin: units.gu(30) }
31 anchors { fill: parent; rightMargin: units.gu(30) }
32 dragAreaWidth: units.gu(2)
32 dragAreaWidth: units.gu(2)
33 maximizedAppTopMargin: units.gu(3) + units.dp(2)
33 maximizedAppTopMargin: units.gu(3) + units.dp(2)
34+ interactive: true
35+ orientation: Qt.PortraitOrientation
34 }
36 }
35
37
36 Binding {
38 Binding {
@@ -67,6 +69,21 @@ Item {
67 ApplicationManager.get(appList.selectedAppIndex).setState(ApplicationInfoInterface.Stopped);
69 ApplicationManager.get(appList.selectedAppIndex).setState(ApplicationInfoInterface.Stopped);
68 }
70 }
69 }
71 }
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+ }
70 }
87 }
71 ListView {
88 ListView {
72 id: appList
89 id: appList
@@ -256,6 +273,46 @@ Item {
256 compare(ApplicationManager.focusedApplicationId, selectedApp.appId);
273 compare(ApplicationManager.focusedApplicationId, selectedApp.appId);
257 }
274 }
258
275
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+
259 function cleanup() {
316 function cleanup() {
260 while (ApplicationManager.count > 1) {
317 while (ApplicationManager.count > 1) {
261 var oldCount = ApplicationManager.count;
318 var oldCount = ApplicationManager.count;
@@ -263,6 +320,7 @@ Item {
263 ApplicationManager.stopApplication(ApplicationManager.get(closingIndex).appId)
320 ApplicationManager.stopApplication(ApplicationManager.get(closingIndex).appId)
264 tryCompare(ApplicationManager, "count", oldCount - 1)
321 tryCompare(ApplicationManager, "count", oldCount - 1)
265 }
322 }
323+ phoneStage.orientation = Qt.PortraitOrientation;
266 }
324 }
267 }
325 }
268}
326}
tests/qmltests/Stages/tst_SessionContainer.qml+63
@@ -41,6 +41,7 @@ Rectangle {
41 SessionContainer {
41 SessionContainer {
42 id: sessionContainer
42 id: sessionContainer
43 anchors.fill: parent
43 anchors.fill: parent
44+ orientation: Qt.PortraitOrientation
44 }
45 }
45 }
46 }
46
47
@@ -112,6 +113,24 @@ Rectangle {
112 session: sessionContainerLoader.item ? sessionContainerLoader.item.session : null
113 session: sessionContainerLoader.item ? sessionContainerLoader.item.session : null
113 }
114 }
114 }
115 }
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+ }
115 }
134 }
116 }
135 }
117
136
@@ -263,5 +282,49 @@ Rectangle {
263 // wait for animation to end
282 // wait for animation to end
264 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false);
283 tryCompareFunction(function() { return isContainerAnimating(childContainer); }, false);
265 }
284 }
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+ }
266 }
329 }
267}
330}