on xenial help sign in
Live surfaces & sessions
bd9428eNick Dedekind
qml/Stages/Animations/SwipeFromBottomAnimation.qml+1−1
@@ -27,7 +27,7 @@ BaseSessionAnimation {
27 AnchorAnimation { easing: UbuntuAnimation.StandardEasing; duration: UbuntuAnimation.BriskDuration }
27 AnchorAnimation { easing: UbuntuAnimation.StandardEasing; duration: UbuntuAnimation.BriskDuration }
28 PropertyAction { target: surfaceContainer; property: "visible"; value: !sessionContainer.removing }
28 PropertyAction { target: surfaceContainer; property: "visible"; value: !sessionContainer.removing }
29 PropertyAction { target: sessionContainer; property: "clip"; value: false }
29 PropertyAction { target: sessionContainer; property: "clip"; value: false }
30− ScriptAction { script: { if (sessionContainer.removing) sessionContainer.session.release(); } }
30+ ScriptAction { script: { sessionContainer.session.release(); } }
31 }
31 }
32 ]
32 ]
33
33
qml/Stages/SessionContainer.qml+7−4
@@ -22,7 +22,6 @@ Item {
22 objectName: "sessionContainer"
22 objectName: "sessionContainer"
23 property QtObject session
23 property QtObject session
24 property var childSessions: session ? session.childSessions : 0
24 property var childSessions: session ? session.childSessions : 0
25− property bool removing: false
26 property alias surface: _surfaceContainer.surface
25 property alias surface: _surfaceContainer.surface
27 property bool interactive: true
26 property bool interactive: true
28
27
@@ -58,6 +57,9 @@ Item {
58 onLoaded: {
57 onLoaded: {
59 item.session = modelData;
58 item.session = modelData;
60 item.interactive = Qt.binding(function() { return root.interactive; } );
59 item.interactive = Qt.binding(function() { return root.interactive; } );
60+ if (!modelData.live) {
61+ modelData.release();
62+ }
61 if (modelData.surface) {
63 if (modelData.surface) {
62 item.animateIn(swipeFromBottom);
64 item.animateIn(swipeFromBottom);
63 }
65 }
@@ -70,9 +72,10 @@ Item {
70 item.animateIn();
72 item.animateIn();
71 }
73 }
72 }
74 }
73− onRemoved: {
75+ onLiveChanged: {
74− item.removing = true;
76+ if (!modelData.live) {
75− item.animateOut();
77+ item.animateOut();
78+ }
76 }
79 }
77 }
80 }
78 }
81 }
qml/Stages/SurfaceContainer.qml+3−10
@@ -22,12 +22,9 @@ Item {
22 id: root
22 id: root
23 objectName: "surfaceContainer"
23 objectName: "surfaceContainer"
24 property Item surface: null
24 property Item surface: null
25− property bool surfaceRemoved: false
26
25
27 onSurfaceChanged: {
26 onSurfaceChanged: {
28 if (surface) {
27 if (surface) {
29− surfaceRemoved = false;
30− surface.removed.connect(onRemoved);
31 surface.parent = root;
28 surface.parent = root;
32 }
29 }
33 }
30 }
@@ -36,19 +33,15 @@ Item {
36 property: "anchors.fill"; value: root
33 property: "anchors.fill"; value: root
37 }
34 }
38
35
39− function onRemoved() {
40− surfaceRemoved = true;
41− }
42−
43 states: [
36 states: [
44 State {
37 State {
45− name: "removed"
38+ name: "zombie"
46− when: surfaceRemoved
39+ when: surface && !surface.live
47 }
40 }
48 ]
41 ]
49 transitions: [
42 transitions: [
50 Transition {
43 Transition {
51− from: ""; to: "removed"
44+ from: ""; to: "zombie"
52 SequentialAnimation {
45 SequentialAnimation {
53 UbuntuNumberAnimation { target: surface; property: "opacity"; to: 0.0
46 UbuntuNumberAnimation { target: surface; property: "opacity"; to: 0.0
54 duration: UbuntuAnimation.BriskDuration }
47 duration: UbuntuAnimation.BriskDuration }
tests/mocks/Unity/Application/ApplicationTestInterface.cpp+13−4
@@ -56,7 +56,18 @@ Session* ApplicationTestInterface::addChildSession(Session* existingSession, con
56
56
57void ApplicationTestInterface::removeSession(Session* existingSession)
57void ApplicationTestInterface::removeSession(Session* existingSession)
58{
58{
59+ qDebug() << "ApplicationTestInterface::removeSession - " << existingSession;
60+
59− Q_EMIT existingSession->removed();
61+ if (existingSession)
62+ existingSession->setLive(false);
63+}
64+
65+void ApplicationTestInterface::removeSurface(MirSurfaceItem* existingSurface)
66+{
67+ qDebug() << "ApplicationTestInterface::removeSurface - " << existingSurface;
68+
69+ if (existingSurface)
70+ existingSurface->setLive(false);
60}
71}
61
72
62quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage)
73quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage)
@@ -97,12 +108,10 @@ quint32 ApplicationTestInterface::addChildSession(const QString& appId, quint32
97
108
98void ApplicationTestInterface::removeSession(quint32 sessionId)
109void ApplicationTestInterface::removeSession(quint32 sessionId)
99{
110{
100− qDebug() << "ApplicationTestInterface::removeSession - " << sessionId;
101−
102 if (!m_childSessions.contains(sessionId)) {
111 if (!m_childSessions.contains(sessionId)) {
103 qDebug() << "ApplicationTestInterface::removeSession - No added session for " << sessionId;
112 qDebug() << "ApplicationTestInterface::removeSession - No added session for " << sessionId;
104 return;
113 return;
105 }
114 }
106 Session* session = m_childSessions.take(sessionId);
115 Session* session = m_childSessions.take(sessionId);
107− Q_EMIT session->removed();
116+ removeSession(session);
108}
117}
tests/mocks/Unity/Application/ApplicationTestInterface.h+1
@@ -32,6 +32,7 @@ public:
32
32
33 Q_INVOKABLE Session* addChildSession(Session* existingSession, const QString& surfaceImage);
33 Q_INVOKABLE Session* addChildSession(Session* existingSession, const QString& surfaceImage);
34 Q_INVOKABLE void removeSession(Session* existingSession);
34 Q_INVOKABLE void removeSession(Session* existingSession);
35+ Q_INVOKABLE void removeSurface(MirSurfaceItem* existingSurface);
35
36
36public Q_SLOTS:
37public Q_SLOTS:
37 quint32 addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage);
38 quint32 addChildSession(const QString& appId, quint32 existingSessionId, const QString& surfaceImage);
tests/mocks/Unity/Application/MirSurfaceItem.cpp+9
@@ -38,6 +38,7 @@ MirSurfaceItem::MirSurfaceItem(const QString& name,
38 , m_name(name)
38 , m_name(name)
39 , m_type(type)
39 , m_type(type)
40 , m_state(state)
40 , m_state(state)
41+ , m_live(true)
41 , m_qmlItem(nullptr)
42 , m_qmlItem(nullptr)
42 , m_screenshotUrl(screenshot)
43 , m_screenshotUrl(screenshot)
43{
44{
@@ -121,6 +122,14 @@ void MirSurfaceItem::setScreenshot(const QUrl& screenshot)
121 }
122 }
122}
123}
123
124
125+void MirSurfaceItem::setLive(bool live)
126+{
127+ if (m_live != live) {
128+ m_live = live;
129+ Q_EMIT liveChanged(m_live);
130+ }
131+}
132+
124void MirSurfaceItem::onQmlWantInputMethodChanged()
133void MirSurfaceItem::onQmlWantInputMethodChanged()
125{
134{
126 QQmlProperty prop(m_qmlItem, "wantInputMethod");
135 QQmlProperty prop(m_qmlItem, "wantInputMethod");
tests/mocks/Unity/Application/MirSurfaceItem.h+5−3
@@ -33,6 +33,7 @@ class MirSurfaceItem : public QQuickItem
33 Q_PROPERTY(Type type READ type NOTIFY typeChanged)
33 Q_PROPERTY(Type type READ type NOTIFY typeChanged)
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
37
37public:
38public:
38 enum Type {
39 enum Type {
@@ -62,9 +63,11 @@ public:
62 Type type() const { return m_type; }
63 Type type() const { return m_type; }
63 State state() const { return m_state; }
64 State state() const { return m_state; }
64 QString name() const { return m_name; }
65 QString name() const { return m_name; }
66+ bool live() const { return m_live; }
65
67
66 void setSession(Session* item);
68 void setSession(Session* item);
67 void setScreenshot(const QUrl& screenshot);
69 void setScreenshot(const QUrl& screenshot);
70+ void setLive(bool live);
68
71
69 Q_INVOKABLE void setState(State newState);
72 Q_INVOKABLE void setState(State newState);
70 Q_INVOKABLE void release();
73 Q_INVOKABLE void release();
@@ -72,9 +75,7 @@ public:
72Q_SIGNALS:
75Q_SIGNALS:
73 void typeChanged(Type);
76 void typeChanged(Type);
74 void stateChanged(State);
77 void stateChanged(State);
75− void parentSurfaceChanged(MirSurfaceItem*);
78+ void liveChanged(bool isLive);
76−
77− void removed();
78
79
79 void inputMethodRequested();
80 void inputMethodRequested();
80 void inputMethodDismissed();
81 void inputMethodDismissed();
@@ -102,6 +103,7 @@ private:
102 const QString m_name;
103 const QString m_name;
103 const Type m_type;
104 const Type m_type;
104 State m_state;
105 State m_state;
106+ bool m_live;
105
107
106 QQmlComponent *m_qmlContentComponent;
108 QQmlComponent *m_qmlContentComponent;
107 QQuickItem *m_qmlItem;
109 QQuickItem *m_qmlItem;
tests/mocks/Unity/Application/Session.cpp+9
@@ -28,6 +28,7 @@ Session::Session(const QString &name,
28 QObject *parent)
28 QObject *parent)
29 : QObject(parent)
29 : QObject(parent)
30 , m_name(name)
30 , m_name(name)
31+ , m_live(true)
31 , m_screenshot(screenshot)
32 , m_screenshot(screenshot)
32 , m_application(nullptr)
33 , m_application(nullptr)
33 , m_surface(nullptr)
34 , m_surface(nullptr)
@@ -113,6 +114,14 @@ void Session::setScreenshot(const QUrl& screenshot)
113 }
114 }
114}
115}
115
116
117+void Session::setLive(bool live)
118+{
119+ if (m_live != live) {
120+ m_live = live;
121+ Q_EMIT liveChanged(m_live);
122+ }
123+}
124+
116void Session::setParentSession(Session* session)
125void Session::setParentSession(Session* session)
117{
126{
118 if (m_parentSession == session || session == this)
127 if (m_parentSession == session || session == this)
tests/mocks/Unity/Application/Session.h+6−1
@@ -31,6 +31,7 @@ class Session : public QObject
31 Q_PROPERTY(MirSurfaceItem* surface READ surface NOTIFY surfaceChanged)
31 Q_PROPERTY(MirSurfaceItem* surface READ surface NOTIFY surfaceChanged)
32 Q_PROPERTY(Session* parentSession READ parentSession NOTIFY parentSessionChanged DESIGNABLE false)
32 Q_PROPERTY(Session* parentSession READ parentSession NOTIFY parentSessionChanged DESIGNABLE false)
33 Q_PROPERTY(SessionModel* childSessions READ childSessions DESIGNABLE false CONSTANT)
33 Q_PROPERTY(SessionModel* childSessions READ childSessions DESIGNABLE false CONSTANT)
34+ Q_PROPERTY(bool live READ live NOTIFY liveChanged)
34
35
35public:
36public:
36 explicit Session(const QString &name,
37 explicit Session(const QString &name,
@@ -42,6 +43,7 @@ public:
42
43
43 //getters
44 //getters
44 QString name() const { return m_name; }
45 QString name() const { return m_name; }
46+ bool live() const { return m_live; }
45 ApplicationInfo* application() const { return m_application; }
47 ApplicationInfo* application() const { return m_application; }
46 MirSurfaceItem* surface() const { return m_surface; }
48 MirSurfaceItem* surface() const { return m_surface; }
47 Session* parentSession() const { return m_parentSession; }
49 Session* parentSession() const { return m_parentSession; }
@@ -49,6 +51,7 @@ public:
49 void setApplication(ApplicationInfo* item);
51 void setApplication(ApplicationInfo* item);
50 void setSurface(MirSurfaceItem* surface);
52 void setSurface(MirSurfaceItem* surface);
51 void setScreenshot(const QUrl& m_screenshot);
53 void setScreenshot(const QUrl& m_screenshot);
54+ void setLive(bool live);
52
55
53 Q_INVOKABLE void addChildSession(Session* session);
56 Q_INVOKABLE void addChildSession(Session* session);
54 void insertChildSession(uint index, Session* session);
57 void insertChildSession(uint index, Session* session);
@@ -57,7 +60,8 @@ public:
57Q_SIGNALS:
60Q_SIGNALS:
58 void surfaceChanged(MirSurfaceItem*);
61 void surfaceChanged(MirSurfaceItem*);
59 void parentSessionChanged(Session*);
62 void parentSessionChanged(Session*);
60− void removed();
63+ void liveChanged(bool isLive);
64+
61 // internal mock use
65 // internal mock use
62 void deregister();
66 void deregister();
63
67
@@ -69,6 +73,7 @@ private:
69 void setParentSession(Session* session);
73 void setParentSession(Session* session);
70
74
71 QString m_name;
75 QString m_name;
76+ bool m_live;
72 QUrl m_screenshot;
77 QUrl m_screenshot;
73 ApplicationInfo* m_application;
78 ApplicationInfo* m_application;
74 MirSurfaceItem* m_surface;
79 MirSurfaceItem* m_surface;
tests/mocks/Unity/Application/SessionManager.cpp+2
@@ -48,6 +48,8 @@ void SessionManager::registerSession(Session *session)
48 Session* session = qobject_cast<Session*>(sender());
48 Session* session = qobject_cast<Session*>(sender());
49
49
50 disconnect(session, 0, this, 0);
50 disconnect(session, 0, this, 0);
51+
52+ session->setLive(false);
51 Q_EMIT sessionStopping(session);
53 Q_EMIT sessionStopping(session);
52 });
54 });
53}
55}
tests/mocks/Unity/Application/SurfaceManager.cpp+2
@@ -53,6 +53,8 @@ void SurfaceManager::registerSurface(MirSurfaceItem *surface)
53 connect(surface, &MirSurfaceItem::deregister, this, [this] {
53 connect(surface, &MirSurfaceItem::deregister, this, [this] {
54 MirSurfaceItem* surface = qobject_cast<MirSurfaceItem*>(sender());
54 MirSurfaceItem* surface = qobject_cast<MirSurfaceItem*>(sender());
55 disconnect(surface, 0, this, 0);
55 disconnect(surface, 0, this, 0);
56+
57+ surface->setLive(false);
56 Q_EMIT surfaceDestroyed(surface);
58 Q_EMIT surfaceDestroyed(surface);
57 });
59 });
58 connect(surface, &MirSurfaceItem::inputMethodRequested,
60 connect(surface, &MirSurfaceItem::inputMethodRequested,
tests/qmltests/Stages/RecursingChildSessionControl.qml+3−3
@@ -94,7 +94,7 @@ ColumnLayout {
94 if (checked) {
94 if (checked) {
95 root.session.createSurface();
95 root.session.createSurface();
96 } else if (root.session.surface) {
96 } else if (root.session.surface) {
97− root.session.surface.removed();
97+ ApplicationTest.removeSurface(root.session.surface);
98 }
98 }
99 }
99 }
100
100
@@ -121,8 +121,8 @@ ColumnLayout {
121 onClicked: {
121 onClicked: {
122 if (removable) {
122 if (removable) {
123 // release the surface first. simulates mir app closing
123 // release the surface first. simulates mir app closing
124− if (root.session.surface) root.session.surface.removed();
124+ if (root.session.surface) ApplicationTest.removeSurface(root.session.surface);
125− root.session.removed();
125+ ApplicationTest.removeSession(root.session);
126 } else {
126 } else {
127 root.session.release();
127 root.session.release();
128 }
128 }