on xenial help sign in
Merge lp:~unity-team/unity8/new-scopes-clean-to-trunk
commit3f81874abef73c786b9bb9234f2e73f9e56862f1 authorMichał Sawicz <michal.sawicz@canonical.com> dateThu 6 Mar 2014, 12:00 (13 years ago) parent3f2582e78f8baa
13 files changed+108−283
debian/unity8.install−1 qml/Components/ApplicationManagerWrapper.qml−8 qml/Components/ApplicationScreenshot.qml+2−1 qml/Components/Showable.qml−8 qml/Components/Stage.qml+5 qml/Dash/Apps/RunningApplicationsGrid.qml−30 qml/Dash/DashFilterGrid.qml−2 qml/Dash/DashRenderer.qml−30 qml/Dash/GenericScopeView.qml+25−3 qml/Panel/MenuContent.qml−1 qml/Shell.qml+75−145 qml/ShellOrientator.qml−43 src/main.cpp+1−11
debian/unity8.install−1
@@ -10,7 +10,6 @@ usr/share/unity8/Launcher
1010usr/share/unity8/Notifications
1111usr/share/unity8/Panel
1212usr/share/unity8/Shell.qml
13−usr/share/unity8/ShellOrientator.qml
1413usr/share/unity8/SideStage
1514usr/share/unity8/graphics
1615data/unity8.conf usr/share/upstart/sessions/
qml/Components/ApplicationManagerWrapper.qml−8
@@ -166,12 +166,4 @@ Item {
166166 }
167167 return desktopFile.substring(left+1, right);
168168 }
169−
170− function setMainStageAppRect(item) {
171− ApplicationManager.setMainStageAppRect(item);
172− }
173−
174− function setSideStageAppRect(item) {
175− ApplicationManager.setSideStageAppRect(item);
176− }
177169}
qml/Components/ApplicationScreenshot.qml+2−1
@@ -53,7 +53,8 @@ Item {
5353 ApplicationImage {
5454 id: applicationImage
5555 objectName: "screenshot image"
56− anchors.fill: parent
56+ width: applicationScreenshot.application ? parent.width : 0
57+ height: applicationScreenshot.application ? parent.height : 0
5758 visible: applicationScreenshot.application != null && ready
5859 source: ApplicationManager.findApplication((application) ? application.appId : "")
5960 }
qml/Components/Showable.qml−8
@@ -107,9 +107,6 @@ Item {
107107 if (!hideAnimation.running) {
108108 hideAnimation.restart()
109109 }
110− if (__skipShowAnimation) {
111− hideAnimation.complete();
112− }
113110 } else {
114111 visible = false
115112 required = false
@@ -118,11 +115,6 @@ Item {
118115 shown = false
119116 }
120117
121− function hideNow() {
122− __skipShowAnimation = true;
123− hide();
124− }
125−
126118 Connections {
127119 target: hideAnimation ? hideAnimation: null
128120 onRunningChanged: {
qml/Components/Stage.qml+5
@@ -86,6 +86,11 @@ Showable {
8686 }
8787 }
8888
89+ Connections {
90+ target: applicationManager
91+ onFocusRequested: activateApplication(appId)
92+ }
93+
8994 /* Keep a reference to the focused application so that we can safely
9095 unfocus it when the stage is not fully shown and refocus it when the stage
9196 is fully shown again.
qml/Dash/Apps/RunningApplicationsGrid.qml−30
@@ -27,12 +27,6 @@ ResponsiveFlowView {
2727 property alias enableHeightBehavior: heightBehaviour.enabled
2828 property bool enableHeightBehaviorOnNextCreation: firstModel.count + secondModel.count == 0
2929
30− /// Whether this is the first item in the list
31− property bool firstItem: false
32−
33− /// Whether this is the last item in the list
34− property bool lastItem: false
35−
3630 Connections {
3731 target: shell
3832 onDashShownChanged: if (shell.dashShown && shell.stageScreenshotsReady) updateScreenshots();
@@ -123,28 +117,4 @@ ResponsiveFlowView {
123117 root.terminationModeEnabled = false;
124118 }
125119 }
126−
127− Image {
128− visible: !firstItem
129− anchors {
130− top: parent.top
131− left: parent.left
132− right: parent.right
133− }
134− fillMode: Image.Stretch
135− source: "../graphics/dash_divider_top_lightgrad.png"
136− z: -1
137− }
138−
139− Image {
140− visible: !lastItem
141− anchors {
142− bottom: parent.bottom
143− left: parent.left
144− right: parent.right
145− }
146− fillMode: Image.Stretch
147− source: "../graphics/dash_divider_top_darkgrad.png"
148− z: -1
149− }
150120}
qml/Dash/DashFilterGrid.qml−2
@@ -31,8 +31,6 @@ DashRenderer {
3131 property alias minimumHorizontalSpacing: filterGrid.minimumHorizontalSpacing
3232 property alias collapsedRowCount: filterGrid.collapsedRowCount
3333
34− property FilterGrid grid: filterGrid
35−
3634 collapsedHeight: filterGrid.collapsedHeight
3735 columns: filterGrid.columns
3836 rows: filter ? filterGrid.collapsedRowCount : filterGrid.uncollapsedRowCount
qml/Dash/DashRenderer.qml−30
@@ -68,34 +68,4 @@ Item {
6868
6969 /// Component mapping and configuration from the scope
7070 property var components
71−
72− /// Whether this is the first item in the list
73− property bool firstItem: false
74−
75− /// Whether this is the last item in the list
76− property bool lastItem: false
77−
78− Image {
79− visible: !firstItem
80− anchors {
81− top: parent.top
82− left: parent.left
83− right: parent.right
84− }
85− fillMode: Image.Stretch
86− source: "graphics/dash_divider_top_lightgrad.png"
87− z: -1
88− }
89−
90− Image {
91− visible: !lastItem
92− anchors {
93− bottom: parent.bottom
94− left: parent.left
95− right: parent.right
96− }
97− fillMode: Image.Stretch
98− source: "graphics/dash_divider_top_darkgrad.png"
99− z: -1
100− }
10171}
qml/Dash/GenericScopeView.qml+25−3
@@ -144,9 +144,6 @@ FocusScope {
144144 source: getRenderer(model.renderer, results)
145145
146146 onLoaded: {
147− item.firstItem = Qt.binding(function() { return index === 0 });
148− // FIXME Should not rely on count field of model, SortfilterProxyModel in this case.
149− item.lastItem = Qt.binding(function() { return index === categoryView.model.count - 1 });
150147 if (item.enableHeightBehavior !== undefined && item.enableHeightBehaviorOnNextCreation !== undefined) {
151148 item.enableHeightBehavior = scopeView.enableHeightBehaviorOnNextCreation;
152149 scopeView.enableHeightBehaviorOnNextCreation = false;
@@ -258,6 +255,31 @@ FocusScope {
258255 }
259256 }
260257 }
258+
259+ Image {
260+ visible: index != 0
261+ anchors {
262+ top: parent.top
263+ left: parent.left
264+ right: parent.right
265+ }
266+ fillMode: Image.Stretch
267+ source: "graphics/dash_divider_top_lightgrad.png"
268+ z: -1
269+ }
270+
271+ Image {
272+ // FIXME Should not rely on count field of model, SortfilterProxyModel in this case.
273+ visible: index != categoryView.model.count - 1
274+ anchors {
275+ bottom: parent.bottom
276+ left: parent.left
277+ right: parent.right
278+ }
279+ fillMode: Image.Stretch
280+ source: "graphics/dash_divider_top_darkgrad.png"
281+ z: -1
282+ }
261283 }
262284
263285 onHeightChanged: rendererLoader.updateDelegateCreationRange();
qml/Panel/MenuContent.qml−1
@@ -26,7 +26,6 @@ import "../Components"
2626MainView {
2727 id: content
2828
29− nativeOrientationAngle: 0 // stop contents being re-rotated when shell in landscape
3029 property QtObject indicatorsModel: null
3130 property bool __contentActive: false
3231 readonly property int currentMenuIndex: tabs.selectedTabIndex
qml/Shell.qml+75−145
@@ -37,7 +37,6 @@ import Unity.Notifications 1.0 as NotificationBackend
3737
3838FocusScope {
3939 id: shell
40− objectName: "shell"
4140
4241 // this is only here to select the width / height of the window if not running fullscreen
4342 property bool tablet: false
@@ -78,11 +77,10 @@ FocusScope {
7877 // FIXME: if application focused before shell starts, shell draws on top of it only.
7978 // We should detect already running applications on shell start and bring them to the front.
8079 applicationManager.unfocusCurrentApplication();
81−
82− applicationManager.setMainStageAppRect(mainStageAppRect);
83− applicationManager.setSideStageAppRect(sideStageAppRect);
8480 }
8581
82+ readonly property bool applicationFocused: !!applicationManager.mainStageFocusedApplication
83+ || !!applicationManager.sideStageFocusedApplication
8684 // Used for autopilot testing.
8785 readonly property string currentFocusedAppId: ApplicationManager.focusedApplicationId
8886
@@ -118,11 +116,6 @@ FocusScope {
118116 }
119117 }
120118
121− Connections {
122− target: applicationManager
123− onFocusRequested: activateApplication(appId)
124− }
125−
126119 GSettings {
127120 id: backgroundSettings
128121 schema.id: "org.gnome.desktop.background"
@@ -147,94 +140,66 @@ FocusScope {
147140 // Whether the underlay is fully covered by opaque UI elements.
148141 property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
149142
150− readonly property bool mainStageApplicationRunning: mainStage.applications && mainStage.applications.count > 0
151− readonly property bool sideStageApplicationRunning: sideStage.applications && sideStage.applications.count > 0
143+ readonly property bool applicationRunning: ((mainStage.applications && mainStage.applications.count > 0)
144+ || (sideStage.applications && sideStage.applications.count > 0))
152145
153146 // Whether the user should see the topmost application surface (if there's one at all).
154− readonly property bool mainStageApplicationShown: mainStageApplicationRunning && !stages.fullyHidden
147+ readonly property bool applicationSurfaceShouldBeSeen: applicationRunning && !stages.fullyHidden
155148 && !mainStage.usingScreenshots // but want sideStage animating over app surface
156149
157150
158151
159152 // NB! Application surfaces are stacked behing the shell one. So they can only be seen by the user
160153 // through the translucent parts of the shell surface.
161− visible: !fullyCovered && !mainStageApplicationShown
162−
163− Item {
164− id: underlayClipper
165− clip: !parent.mainStageApplicationShown && parent.sideStageApplicationRunning && stagesOuterContainer.showProgress > 0
166− width: {
167− if (clip) {
168− var w = parent.width - sideStage.width
169− w += stagesOuterContainer.x + stages.x + (sideStage.x - sideStageRevealer.openedValue)
170− return Math.min(w, parent.width);
171− } else {
172− return parent.width;
173− }
174− }
175− height: parent.height
154+ visible: !fullyCovered && !applicationSurfaceShouldBeSeen
176155
177− Image {
178− anchors.fill: dash
179− source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png"
180− fillMode: Image.PreserveAspectCrop
181− horizontalAlignment: Image.AlignRight
182− verticalAlignment: Image.AlignTop
183− }
184−
185− Dash {
186− id: dash
187− objectName: "dash"
188−
189− available: !greeter.shown && !lockscreen.shown
190− hides: [stages, launcher, panel.indicators]
191− shown: disappearingAnimationProgress !== 1.0
192− enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
193− // FIXME: unfocus all applications when going back to the dash
194− onEnabledChanged: {
195− if (enabled) {
196− shell.applicationManager.unfocusCurrentApplication()
197− }
198− }
156+ Rectangle {
157+ anchors.fill: parent
158+ color: "black"
159+ opacity: dash.disappearingAnimationProgress
160+ }
199161
200− width: underlay.width
201− height: underlay.height - y
202− y: panel.panelHeight
203−
204− contentScale: 1.0 - 0.2 * disappearingAnimationProgress
205− opacity: 1.0 - disappearingAnimationProgress
206− property real disappearingAnimationProgress: {
207− if (greeter.shown) {
208− return greeter.showProgress;
209− } else {
210− if (underlayClipper.clip)
211− return 0;
212− else
213− return stagesOuterContainer.showProgress;
214− }
215− }
162+ Image {
163+ anchors.fill: dash
164+ source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png"
165+ fillMode: Image.PreserveAspectCrop
166+ horizontalAlignment: Image.AlignRight
167+ verticalAlignment: Image.AlignTop
168+ }
216169
217− // FIXME: only necessary because stagesOuterContainer.showProgress and
218− // greeterRevealer.animatedProgress are not animated
219− Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
170+ Dash {
171+ id: dash
172+ objectName: "dash"
173+
174+ available: !greeter.shown && !lockscreen.shown
175+ hides: [stages, launcher, panel.indicators]
176+ shown: disappearingAnimationProgress !== 1.0
177+ enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
178+ // FIXME: unfocus all applications when going back to the dash
179+ onEnabledChanged: {
180+ if (enabled) {
181+ shell.applicationManager.unfocusCurrentApplication()
182+ }
220183 }
221184
222− Rectangle {
223− width: underlay.width
224− height: underlay.height
225− color: "black"
226− opacity: 0.5 * ((sideStage.x - sideStageRevealer.closedValue) / (sideStageRevealer.openedValue - sideStageRevealer.closedValue))
227− visible: sideStageHideButton.enabled
185+ anchors {
186+ fill: parent
187+ topMargin: panel.panelHeight
228188 }
229189
230− AbstractButton {
231− id: sideStageHideButton
232− enabled: mainStage.applications.count == 0 && sideStage.shown
233− anchors.fill: parent
234− onClicked: {
235− sideStage.hide();
190+ contentScale: 1.0 - 0.2 * disappearingAnimationProgress
191+ opacity: 1.0 - disappearingAnimationProgress
192+ property real disappearingAnimationProgress: {
193+ if (greeter.shown) {
194+ return greeter.showProgress;
195+ } else {
196+ return stagesOuterContainer.showProgress;
236197 }
237198 }
199+
200+ // FIXME: only necessary because stagesOuterContainer.showProgress and
201+ // greeterRevealer.animatedProgress are not animated
202+ Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
238203 }
239204 }
240205
@@ -243,7 +208,7 @@ FocusScope {
243208
244209 width: parent.width
245210 height: parent.height
246− x: mainStage.applications.count > 0 ? launcher.progress : 0
211+ x: launcher.progress
247212 Behavior on x {SmoothedAnimation{velocity: 600}}
248213
249214 property real showProgress:
@@ -255,16 +220,6 @@ FocusScope {
255220
256221 x: width
257222
258− function doLauncherHide() {
259− if (mainStage.applications.count > 0) {
260− hide();
261− } else {
262− if (sideStage.shown) {
263− sideStage.hide();
264− }
265− }
266− }
267−
268223 property bool fullyShown: shown && x == 0 && parent.x == 0
269224 property bool fullyHidden: !shown && x == width
270225 available: !greeter.shown
@@ -349,6 +304,11 @@ FocusScope {
349304 rightEdgeDraggingAreaWidth: shell.edgeSize
350305 normalApplicationY: shell.panelHeight
351306
307+ onShownChanged: {
308+ if (!shown && mainStage.applications.count == 0) {
309+ stages.hide();
310+ }
311+ }
352312 // FIXME: when hiding the side stage, refocus the main stage
353313 // application so that it goes in front of the side stage
354314 // application and hides it
@@ -373,29 +333,12 @@ FocusScope {
373333 width: units.gu(40)
374334 height: stages.height
375335 handleExpanded: sideStageRevealer.pressed
376−
377− Connections {
378− target: sideStage.applications
379− onCountChanged: {
380− if (sideStage.applications.count == 0) {
381− if (sideStage.shown) { // if all SS app closed, hide side stage
382− sideStage.hide();
383− } else {
384− // Sidestage is hidden and there is no main app, make sure the
385− // stages is totally hidden too
386− if (mainStage.applications.count == 0) {
387− stages.hideNow();
388− }
389− }
390− }
391− }
392− }
393336 }
394337
395338 Revealer {
396339 id: sideStageRevealer
397340
398− enabled: sideStage.applications.count > 0
341+ enabled: mainStage.applications.count > 0 && sideStage.applications.count > 0
399342 && sideStage.available
400343 direction: Qt.RightToLeft
401344 openedValue: parent.width - sideStage.width
@@ -413,26 +356,6 @@ FocusScope {
413356 orientation: Qt.Horizontal
414357 }
415358
416− // Defines the rectangle occupied by an application on the main or side stage.
417− // Used only to inform the ApplicationManager. Can be removed when the proper
418− // architecture is in place (unity8 as mir compositor).
419− Item {
420− id: mainStageAppRect
421− x: mainStage.x
422− y: mainStage.y + mainStage.normalApplicationY
423− width: mainStage.width
424− height: mainStage.height
425− visible: false; enabled: false
426− }
427− Item {
428− id: sideStageAppRect
429− x: sideStageRevealer.openedValue
430− y: sideStage.y + sideStage.normalApplicationY
431− width: sideStage.width
432− height: sideStage.height
433− visible: false; enabled: false
434− }
435−
436359 DragHandle {
437360 id: stagesDragHandle
438361
@@ -516,7 +439,7 @@ FocusScope {
516439 hides: [launcher, panel.indicators, hud]
517440 shown: true
518441
519− defaultBackground: shell.defaultBackground
442+ defaultBackground: shell.background
520443
521444 y: panel.panelHeight
522445 width: parent.width
@@ -529,9 +452,7 @@ FocusScope {
529452
530453 function removeApplicationFocus() {
531454 greeter.previousMainApp = applicationManager.mainStageFocusedApplication;
532− if (sideStage.fullyShown) { // if side stage hidden, don't focus it on restore
533− greeter.previousSideApp = applicationManager.sideStageFocusedApplication;
534− }
455+ greeter.previousSideApp = applicationManager.sideStageFocusedApplication;
535456 applicationManager.unfocusCurrentApplication();
536457 }
537458
@@ -600,14 +521,8 @@ FocusScope {
600521 }
601522
602523 InputFilterArea {
603− width: {
604− if (applicationManager.sideStageFocusedApplication && sideStage.shown)
605− return parent.width - sideStage.width;
606− else
607− return parent.width;
608− }
609− height: parent.height
610− blockInput: !applicationManager.mainStageFocusedApplication || greeter.shown || lockscreen.shown || launcher.shown
524+ anchors.fill: parent
525+ blockInput: !applicationFocused || greeter.shown || lockscreen.shown || launcher.shown
611526 || panel.indicators.shown || hud.shown
612527 }
613528
@@ -709,7 +624,7 @@ FocusScope {
709624 theHud: hud
710625 anchors.fill: parent
711626 enabled: hud.available
712− applicationIsOnForeground: (stages.shown && mainStage.applications.count > 0) || (stages.shown && sideStage.shown)
627+ applicationIsOnForeground: applicationFocused
713628 }
714629
715630 InputFilterArea {
@@ -731,7 +646,7 @@ FocusScope {
731646 anchors.bottom: parent.bottom
732647 width: parent.width
733648 dragAreaWidth: shell.edgeSize
734− available: !greeter.locked && edgeDemo.launcherEnabled
649+ available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
735650
736651 onShowDashHome: {
737652 if (edgeDemo.running)
@@ -741,7 +656,7 @@ FocusScope {
741656 }
742657 onDash: {
743658 if (stages.shown) {
744− stages.doLauncherHide();
659+ stages.hide();
745660 launcher.hide();
746661 }
747662 }
@@ -825,6 +740,21 @@ FocusScope {
825740 value: "unity8"
826741 }
827742
743+ OSKController {
744+ anchors.topMargin: panel.panelHeight
745+ anchors.fill: parent // as needs to know the geometry of the shell
746+ }
747+
748+ //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
749+ MouseArea {
750+ anchors.bottom: parent.bottom
751+ anchors.left: parent.left
752+ anchors.right: parent.right
753+ height: shell.applicationManager ? shell.applicationManager.keyboardHeight : 0
754+
755+ enabled: shell.applicationManager && shell.applicationManager.keyboardVisible
756+ }
757+
828758 Label {
829759 anchors.centerIn: parent
830760 visible: applicationManager.fake
@@ -845,7 +775,7 @@ FocusScope {
845775 launcher: launcher
846776 dash: dash
847777 indicators: panel.indicators
848− underlay: underlayClipper
778+ underlay: underlay
849779 }
850780
851781 Connections {
qml/ShellOrientator.qmldeleted−43
@@ -1,43 +0,0 @@
1−/*
2− * Copyright (C) 2014 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.0
18−import QtQuick.Window 2.0
19−import Unity.Application 0.1
20−
21−Item {
22− id: orientator
23−
24− // this is only here to select the width / height of the window if not running fullscreen
25− property bool tablet: false
26− width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
27− height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
28−
29− Item {
30− anchors.fill: parent
31− rotation: Screen.angleBetween(nativeOrientation, Screen.primaryOrientation)
32− Shell {
33− x: (parent.rotation == 0) ? 0 : (parent.width - parent.height) / 2
34− y: (parent.rotation == 0) ? 0 : -(parent.width - parent.height) / 2
35− width: (parent.rotation == 0) ? parent.width : parent.height
36− height: (parent.rotation == 0) ? parent.height : parent.width
37− }
38− }
39−
40− OSKController {
41− anchors.fill: parent // as needs to know the geometry of the shell
42− }
43−}
src/main.cpp+1−11
@@ -98,16 +98,6 @@ int startShell(int argc, const char** argv, void* server)
9898 view->setFlags(Qt::FramelessWindowHint);
9999 }
100100
101− const QByteArray orientation = qgetenv("NATIVE_ORIENTATION");
102− Qt::ScreenOrientation orientationAngle = Qt::PrimaryOrientation;
103− if (orientation == "landscape") {
104− orientationAngle = Qt::LandscapeOrientation;
105− } else if (!orientation.isEmpty() && orientation != "portrait") {
106− qDebug() << "Unknown NATIVE_ORIENTATION setting, ignoring";
107− }
108−
109− view->rootContext()->setContextProperty("nativeOrientation", orientationAngle);
110−
111101 // You will need this if you want to interact with touch-only components using a mouse
112102 // Needed only when manually testing on a desktop.
113103 MouseTouchAdaptor *mouseTouchAdaptor = 0;
@@ -125,7 +115,7 @@ int startShell(int argc, const char** argv, void* server)
125115 nativeInterface->setProperty("ubuntuSessionType", 1);
126116 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
127117
128− QUrl source(::qmlDirectory()+"ShellOrientator.qml");
118+ QUrl source(::qmlDirectory()+"Shell.qml");
129119 prependImportPaths(view->engine(), ::overrideImportPaths());
130120 appendImportPaths(view->engine(), ::fallbackImportPaths());
131121