on xenial help sign in
Basic shell-controlled orientation support with added orientation lock
04b59dbGerry Boland
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+18
@@ -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
@@ -167,6 +168,18 @@ Item {
167 }
168 }
168 }
169 }
169
170
171+ property int orientation
172+ readonly property int deviceOrientation: Screen.angleBetween(Screen.primaryOrientation, Screen.orientation)
173+ onDeviceOrientationChanged: {
174+ if (!OrientationLock.enabled)
175+ orientation = Screen.orientation;
176+ }
177+ readonly property bool orientationLockEnabled: OrientationLock.enabled
178+ onOrientationLockEnabledChanged: {
179+ if (!OrientationLock.enabled)
180+ orientation = Screen.orientation;
181+ }
182+
170 Loader {
183 Loader {
171 id: applicationsDisplayLoader
184 id: applicationsDisplayLoader
172 anchors.fill: parent
185 anchors.fill: parent
@@ -204,6 +217,11 @@ Item {
204 property: "inverseProgress"
217 property: "inverseProgress"
205 value: launcher.progress
218 value: launcher.progress
206 }
219 }
220+ Binding {
221+ target: applicationsDisplayLoader.item
222+ property: "orientation"
223+ value: stages.orientation
224+ }
207 }
225 }
208 }
226 }
209
227
qml/Stages/ApplicationWindow.qml+2
@@ -27,6 +27,7 @@ Item {
27 // to be set from outside
27 // to be set from outside
28 property bool interactive: true
28 property bool interactive: true
29 property QtObject application
29 property QtObject application
30+ property int orientation
30
31
31 QtObject {
32 QtObject {
32 id: d
33 id: d
@@ -57,6 +58,7 @@ Item {
57 property bool surfaceInitialized: false
58 property bool surfaceInitialized: false
58 onSurfaceChanged: {
59 onSurfaceChanged: {
59 if (surface) {
60 if (surface) {
61+ surface.orientation = Qt.binding( function() { return root.orientation; } );
60 surfaceInitTimer.start();
62 surfaceInitTimer.start();
61 } else {
63 } else {
62 hadSurface = true;
64 hadSurface = true;
qml/Stages/PhoneStage.qml+10
@@ -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
33
35
34 color: "black"
36 color: "black"
35
37
@@ -389,6 +391,14 @@ Rectangle {
389 spreadView.closingIndex = index;
391 spreadView.closingIndex = index;
390 ApplicationManager.stopApplication(ApplicationManager.get(index).appId);
392 ApplicationManager.stopApplication(ApplicationManager.get(index).appId);
391 }
393 }
394+
395+ onInteractiveChanged: {
396+ if (interactive) {
397+ appDelegate.orientation = Qt.binding( function() { return root.orientation; } );
398+ } else {
399+ appDelegate.orientation = root.orientation; // breaks the binding intentionally
400+ }
401+ }
392 }
402 }
393 }
403 }
394 }
404 }
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"
@@ -66,6 +67,7 @@ Item {
66 }
67 }
67
68
68 interactive: root.interactive
69 interactive: root.interactive
70+ orientation: root.orientation
69 }
71 }
70 }
72 }
71
73
qml/Stages/TabletStage.qml+13
@@ -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
37
38
38 onInverseProgressChanged: {
39 onInverseProgressChanged: {
39 if (inverseProgress == 0 && priv.oldInverseProgress > 0) {
40 if (inverseProgress == 0 && priv.oldInverseProgress > 0) {
@@ -549,6 +550,18 @@ Rectangle {
549 ApplicationManager.stopApplication(ApplicationManager.get(index).appId);
550 ApplicationManager.stopApplication(ApplicationManager.get(index).appId);
550 }
551 }
551
552
553+ onInteractiveChanged: {
554+ if (isInSideStage) {
555+ appDelegate.orientation = Qt.PortraitOrientation; // FIXME! Need Proper Rotation Support
556+ } else {
557+ if (interactive) {
558+ appDelegate.orientation = Qt.binding( function() { return root.orientation; } );
559+ } else {
560+ appDelegate.orientation = root.orientation; // breaks the binding intentionally
561+ }
562+ }
563+ }
564+
552 EasingCurve {
565 EasingCurve {
553 id: snappingCurve
566 id: snappingCurve
554 type: EasingCurve.Linear
567 type: EasingCurve.Linear