on xenial help sign in
merge prereq
commitab4ffb88c71a6d84ad4986e0e2c4c6d26508738f authorMichael Zanetti <michael.zanetti@canonical.com> dateThu 9 Mar 2017, 12:16 (10 years ago) parent75d41d4d4d6901
5 files changed+215−4
plugins/WindowManager/Screen.cpp+42−3 plugins/WindowManager/Screen.h+10 qml/Shell.qml+1−1 tests/qmltests/CMakeLists.txt+1 tests/qmltests/tst_ShellApplication.qml+161
plugins/WindowManager/Screen.cpp+42−3
@@ -39,13 +39,30 @@ Screen::Screen(qtmir::Screen* screen)
3939
4040 // Connect the active workspace to activate the screen.
4141 connect(m_workspaces.data(), &WorkspaceModel::workspaceAdded, this, [this](Workspace* workspace) {
42− connect(workspace, &Workspace::activeChanged, this, [this](bool active) {
43− if (active) activate();
42+ connect(workspace, &Workspace::activeChanged, this, [this, workspace](bool active) {
43+ if (active) {
44+ setCurrentWorkspace(workspace);
45+ activate();
46+ }
4447 });
45− if (workspace->isActive()) activate();
48+ if (workspace->isActive()) {
49+ activate();
50+ setCurrentWorkspace(workspace);
51+ }
52+ if (!m_currentWorspace) {
53+ setCurrentWorkspace(workspace);
54+ }
4655 });
4756 connect(m_workspaces.data(), &WorkspaceModel::workspaceRemoved, this, [this](Workspace* workspace) {
4857 disconnect(workspace, &Workspace::activeChanged, this, 0);
58+ if (workspace == m_currentWorspace) {
59+ resetCurrentWorkspace();
60+ }
61+ });
62+ connect(this, &Screen::activeChanged, this, [this](bool active) {
63+ if (active && m_currentWorspace) {
64+ m_currentWorspace->activate();
65+ }
4966 });
5067
5168 WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
@@ -71,6 +88,15 @@ Screen::Screen(const Screen &other)
7188 connect(m_wrapped, &qtmir::Screen::availableModesChanged, this, &Screen::availableModesChanged);
7289}
7390
91+void Screen::resetCurrentWorkspace()
92+{
93+ auto newCurrent = m_workspaces->rowCount() > 0 ? m_workspaces->get(0) : nullptr;
94+ if (m_currentWorspace != newCurrent) {
95+ m_currentWorspace = newCurrent;
96+ Q_EMIT currentWorkspaceChanged(newCurrent);
97+ }
98+}
99+
74100qtmir::OutputId Screen::outputId() const
75101{
76102 return m_wrapped->outputId();
@@ -151,6 +177,19 @@ WorkspaceModel *Screen::workspaces() const
151177 return m_workspaces.data();
152178}
153179
180+Workspace *Screen::currentWorkspace() const
181+{
182+ return m_currentWorspace.data();
183+}
184+
185+void Screen::setCurrentWorkspace(Workspace *workspace)
186+{
187+ if (m_currentWorspace != workspace) {
188+ m_currentWorspace = workspace;
189+ Q_EMIT currentWorkspaceChanged(workspace);
190+ }
191+}
192+
154193void Screen::sync(Screen *proxy)
155194{
156195 if (!proxy) return;
plugins/WindowManager/Screen.h+10
@@ -13,6 +13,7 @@ class Screen : public qtmir::Screen
1313{
1414 Q_OBJECT
1515 Q_PROPERTY(WorkspaceModel* workspaces READ workspaces CONSTANT)
16+ Q_PROPERTY(Workspace* currentWorkspace READ currentWorkspace WRITE setCurrentWorkspace NOTIFY currentWorkspaceChanged)
1617
1718public:
1819 explicit Screen(qtmir::Screen*const wrapped);
@@ -41,16 +42,25 @@ public:
4142
4243 WorkspaceModel* workspaces() const;
4344
45+ Workspace *currentWorkspace() const;
46+ void setCurrentWorkspace(Workspace* workspace);
47+
4448 void sync(Screen* proxy);
4549
4650public Q_SLOTS:
4751 void activate();
4852
53+Q_SIGNALS:
54+ void currentWorkspaceChanged(Workspace*);
55+
4956protected:
5057 Screen(Screen const& other);
5158
59+ void resetCurrentWorkspace();
60+
5261 qtmir::Screen*const m_wrapped;
5362 const QScopedPointer<WorkspaceModel> m_workspaces;
63+ QPointer<Workspace> m_currentWorspace;
5464};
5565
5666class ScreenProxy : public Screen
qml/Shell.qml+1−1
@@ -278,7 +278,7 @@ StyledItem {
278278 objectName: "topLevelSurfaceList"
279279 applicationManager: ApplicationManager // it's a singleton
280280 surfaceManager: SurfaceManager
281− workspace: WorkspaceManager.activeWorkspace
281+ workspace: screenWindow.screen.currentWorkspace
282282 }
283283
284284 Stage {
tests/qmltests/CMakeLists.txt+1
@@ -5,6 +5,7 @@ add_unity8_qmltest(. OrientedShell)
55add_unity8_qmltest(. DisabledScreenNotice)
66add_unity8_qmltest(. Shell)
77add_unity8_qmltest(. ShellWithPin)
8+add_unity8_qmltest(. ShellApplication)
89add_unity8_qmltest(. DeviceConfiguration)
910add_unity8_qmltest_data(. EdgeBarrierControls)
1011add_unity8_qmltest_data(. ApplicationMenuDataLoader)
tests/qmltests/tst_ShellApplication.qmlnew file+161
@@ -0,0 +1,161 @@
1+/*
2+ * Copyright (C) 2017 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import LightDM.FullLightDM 0.1 as LightDM
20+import LightDMController 0.1
21+import Unity.Application 0.1
22+import Unity.Test 0.1
23+
24+import "../../qml"
25+import "Stage"
26+
27+Rectangle {
28+ id: root
29+ color: "grey"
30+ width: units.gu(100)
31+ height: units.gu(71)
32+
33+ QtObject {
34+ id: args
35+ property bool hasFullscreen: false
36+ property bool hasFrameless: false
37+ property bool hasGeometry: true
38+ property size windowGeometry: Qt.size(root.width, root.height)
39+ property string deviceName: "desktop"
40+ property string mode: "full-greeter"
41+ }
42+ property alias applicationArguments: args
43+
44+ Component.onCompleted: {
45+ // must set the mock mode before loading the Shell
46+ LightDMController.userMode = "single";
47+ }
48+
49+ Flickable {
50+ id: controls
51+ contentHeight: controlRect.height
52+
53+ anchors.top: root.top
54+ anchors.bottom: root.bottom
55+ anchors.right: root.right
56+ width: units.gu(30)
57+
58+ Rectangle {
59+ id: controlRect
60+ anchors { left: parent.left; right: parent.right }
61+ color: "darkgrey"
62+ height: childrenRect.height + units.gu(2)
63+
64+ Column {
65+ anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
66+ spacing: units.gu(1)
67+
68+ Flow {
69+ spacing: units.gu(1)
70+ anchors { left: parent.left; right: parent.right }
71+
72+ Button {
73+ text: "Show Greeter"
74+ activeFocusOnPress: false
75+ onClicked: {
76+ LightDM.Greeter.showGreeter();
77+ }
78+ }
79+ Button {
80+ text: "Hide Greeter"
81+ activeFocusOnPress: false
82+ onClicked: {
83+ LightDM.Greeter.hideGreeter()
84+ }
85+ }
86+ }
87+
88+ MouseTouchEmulationCheckbox {
89+ id: mouseEmulation
90+ checked: true
91+ }
92+
93+ Row {
94+ anchors { left: parent.left; right: parent.right }
95+ CheckBox {
96+ id: autohideLauncherCheckbox
97+ onCheckedChanged: {
98+ GSettingsController.setAutohideLauncher(checked)
99+ }
100+ }
101+ Label {
102+ text: "Autohide launcher"
103+ }
104+ }
105+
106+ Label { text: "Applications"; font.bold: true }
107+
108+ Button {
109+ text: "Start all apps"
110+ width: parent.width
111+ activeFocusOnPress: false
112+ onClicked: {
113+ for (var i = 0; i < ApplicationManager.availableApplications.length; i++) {
114+ var appId = ApplicationManager.availableApplications[i];
115+ ApplicationManager.startApplication(appId)
116+ }
117+ }
118+ }
119+
120+ Repeater {
121+ id: appCheckBoxRepeater
122+ model: ApplicationManager.availableApplications
123+ ApplicationCheckBox {
124+ appId: modelData
125+ }
126+ }
127+
128+ Label {
129+ text: "Fingerprint"
130+ }
131+ Row {
132+ Button {
133+ text: "Success"
134+ onClicked: {
135+ var biometryd = testCase.findInvisibleChild(shellContainer, "biometryd");
136+ var uid = 0;
137+ for (var i = 0; i < LightDM.Users.count; i++) {
138+ if (LightDM.Users.data(i, LightDM.UserRoles.NameRole) == AccountsService.user) {
139+ uid = LightDM.Users.data(i, LightDM.UserRoles.UidRole);
140+ break;
141+ }
142+ }
143+ biometryd.operation.mockSuccess(uid);
144+ }
145+ }
146+
147+ Button {
148+ text: "Failure"
149+ onClicked: {
150+ var biometryd = testCase.findInvisibleChild(shellContainer, "biometryd");
151+ biometryd.operation.mockFailure("error");
152+ }
153+ }
154+ }
155+ }
156+ }
157+ }
158+
159+ ShellApplication {
160+ }
161+}