@@ -19,9 +19,9 @@ import AccountsService 0.1
19import GSettings 1.0
19import GSettings 1.0
20import Unity.Application 0.1
20import Unity.Application 0.1
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22−import Ubuntu.Components.Popups 0.1
23import Ubuntu.Gestures 0.1
22import Ubuntu.Gestures 0.1
24import Unity.Launcher 0.1
23import Unity.Launcher 0.1
25import LightDM 0.1 as LightDM
25import LightDM 0.1 as LightDM
26import Powerd 0.1
26import Powerd 0.1
27import SessionBroadcast 0.1
27import SessionBroadcast 0.1
@@ -31,10 +31,11 @@ import "Launcher"
31import "Panel"
31import "Panel"
32import "Components"
32import "Components"
33import "Notifications"
33import "Notifications"
34import Unity.Notifications 1.0 as NotificationBackend
35import Unity.Notifications 1.0 as NotificationBackend
35import Unity.Session 0.1
36import Unity.Session 0.1
40 // this is only here to select the width / height of the window if not running fullscreen
41 // this is only here to select the width / height of the window if not running fullscreen
@@ -47,7 +48,7 @@ FocusScope {
47 property url background
48 property url background
48 readonly property real panelHeight: panel.panelHeight
49 readonly property real panelHeight: panel.panelHeight
50− property bool dashShown: dash.shown
51+ property bool dashShown: dash.shown && dash.available && underlay.visible
52 property bool sideStageEnabled: shell.width >= units.gu(100)
53 property bool sideStageEnabled: shell.width >= units.gu(100)
53 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
54 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
@@ -55,14 +56,10 @@ FocusScope {
55 function activateApplication(appId) {
56 function activateApplication(appId) {
56 if (ApplicationManager.findApplication(appId)) {
57 if (ApplicationManager.findApplication(appId)) {
57 ApplicationManager.requestFocusApplication(appId);
58 ApplicationManager.requestFocusApplication(appId);
59− if (stages.locked && ApplicationManager.focusedApplicationId == appId) {
60− applicationsDisplayLoader.item.select(appId);
63 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
60 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
64 ApplicationManager.startApplication(appId, execFlags);
61 ApplicationManager.startApplication(appId, execFlags);
65− stages.show(false);
62+ stages.show();
@@ -89,76 +86,68 @@ FocusScope {
89 id: volumeControl
86 id: volumeControl
90+ // Handle but do not filter out volume keys
92− Keys.onVolumeUpPressed: volumeControl.volumeUp()
91+ Keys.onVolumeUpPressed: { volumeControl.volumeUp(); event.accepted = false; }
93− Keys.onVolumeDownPressed: volumeControl.volumeDown()
92+ Keys.onVolumeDownPressed: { volumeControl.volumeDown(); event.accepted = false; }
95− Item {
94+ Keys.onPressed: {
96− id: underlayClipper
95+ if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
97− anchors.fill: parent
96+ dialogs.onPowerKeyPressed();
98− anchors.rightMargin: stages.overlayWidth
97+ event.accepted = true;
99− clip: stages.overlayMode && !stages.painting
98+ } else {
100−
99+ event.accepted = false;
101− InputFilterArea {
100+ }
102− anchors.fill: parent
103− blockInput: parent.clip
106− Item {
103+ Keys.onReleased: {
107− id: underlay
104+ if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
108− objectName: "underlay"
105+ dialogs.onPowerKeyReleased();
109− anchors.fill: parent
106+ event.accepted = true;
110− anchors.rightMargin: -parent.anchors.rightMargin
107+ } else {
111−
108+ event.accepted = false;
112− // Whether the underlay is fully covered by opaque UI elements.
113− property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicators.width
115− // Whether the user should see the topmost application surface (if there's one at all).
116− readonly property bool applicationSurfaceShouldBeSeen: stages.shown && !stages.painting && !stages.overlayMode
118− // NB! Application surfaces are stacked behind the shell one. So they can only be seen by the user
119− // through the translucent parts of the shell surface.
120− visible: !fullyCovered && !applicationSurfaceShouldBeSeen
123− anchors.fill: parent
125− opacity: dash.disappearingAnimationProgress
129− id: dash
114+ id: underlay
130− objectName: "dash"
115+ objectName: "underlay"
116+ anchors.fill: parent
132− available: !LightDM.Greeter.active
118+ // Whether the underlay is fully covered by opaque UI elements.
133− hides: [stages, launcher, panel.indicators]
119+ property bool fullyCovered: (panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth)
134− shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
120+ || stages.fullyShown || greeterWrapper.fullyShown
135− enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
121+ visible: !fullyCovered
137− overviewHandleHeight: shell.edgeSize
123+ Dash {
139− anchors {
127+ available: !LightDM.Greeter.active
140− fill: parent
128+ hides: [stages, launcher, panel.indicators]
141− topMargin: panel.panelHeight
129+ shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0 &&
142− }
130+ !(panel.indicators.fullyOpened && !sideStageEnabled)
131+ enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
144− contentScale: 1.0 - 0.2 * disappearingAnimationProgress
133+ overviewHandleHeight: shell.edgeSize
145− opacity: 1.0 - disappearingAnimationProgress
146− property real disappearingAnimationProgress: {
147− if (stages.overlayMode) {
150− return stages.showProgress
154− // FIXME: only necessary because stages.showProgress is not animated
135+ anchors {
155− Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
136+ fill: parent
137+ topMargin: panel.panelHeight
140+ contentScale: 1.0 - 0.2 * disappearingAnimationProgress
141+ opacity: 1.0 - disappearingAnimationProgress
142+ property real disappearingAnimationProgress: stages.showProgress
144+ // FIXME: only necessary because stages.showProgress is not animated
145+ Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
160 EdgeDragArea {
149 EdgeDragArea {
161− id: stagesDragHandle
150+ id: stagesDragArea
162 direction: Direction.Leftwards
151 direction: Direction.Leftwards
164 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
153 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
@@ -168,20 +157,20 @@ FocusScope {
169 onTouchXChanged: {
158 onTouchXChanged: {
170 if (status == DirectionalDragArea.Recognized) {
159 if (status == DirectionalDragArea.Recognized) {
171− if (ApplicationManager.count == 0) {
160+ if (ApplicationManager.empty) {
172− progress = Math.max(stages.width - stagesDragHandle.width + touchX, stages.width * .3)
161+ progress = Math.max(stages.width - stagesDragArea.width + touchX, stages.width * .3);
174− progress = stages.width - stagesDragHandle.width + touchX
163+ progress = stages.width - stagesDragArea.width + touchX;
179 onDraggingChanged: {
168 onDraggingChanged: {
180 if (!dragging) {
169 if (!dragging) {
181− if (ApplicationManager.count > 0 && progress < stages.width - units.gu(10)) {
170+ if (!ApplicationManager.empty && progress < stages.width - units.gu(10)) {
182− stages.show(true)
171+ stages.show();
184− stagesDragHandle.progress = stages.width;
173+ stagesDragArea.progress = Qt.binding(function () { return stages.width; });
@@ -192,253 +181,93 @@ FocusScope {
192 width: parent.width
181 width: parent.width
193 height: parent.height
182 height: parent.height
184+ visible: !fullyHidden && !ApplicationManager.empty
196 if (shown) {
187 if (shown) {
197− if (overlayMode || locked || greeter.fakeActiveForApp !== "") {
188+ if (locked || greeter.fakeActiveForApp !== "") {
198 return 0;
189 return 0;
200− return launcher.progress
191+ return launcher.progress;
202− return stagesDragHandle.progress
193+ return stagesDragArea.progress
206 Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
196 Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
208 property bool shown: false
198 property bool shown: false
201+ if (ApplicationManager.count > 0) {
202+ ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
205+ if (ApplicationManager.focusedApplicationId) {
206+ ApplicationManager.updateScreenshot(ApplicationManager.focusedApplicationId);
207+ ApplicationManager.unfocusCurrentApplication();
212+ // Avoid a silent "divide by zero -> NaN" situation during init as shell.width will be
213+ // zero. That breaks the property binding and the function won't be reevaluated once
214+ // shell.width is set, with the NaN result staying there for good.
210− property real showProgress: overlayMode ? 0 : MathUtils.clamp(1 - x / shell.width, 0, 1)
215+ property real showProgress: shell.width ? MathUtils.clamp(1 - x / shell.width, 0, 1) : 0
212 property bool fullyShown: x == 0
217 property bool fullyShown: x == 0
213 property bool fullyHidden: x == width
218 property bool fullyHidden: x == width
215− property bool painting: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.painting : false
216− property bool fullscreen: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.fullscreen : false
217− property bool overlayMode: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.overlayMode : false
218− property int overlayWidth: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.overlayWidth : false
219 property bool locked: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.locked : false
220 property bool locked: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.locked : false
222+ // It might technically not be fullyShown but visually it just looks so.
223+ property bool roughlyFullyShown: x >= 0 && x <= units.gu(1)
221− function show(focusApp) {
225+ function show() {
222 shown = true;
226 shown = true;
223− panel.indicators.hide();
224− edgeDemo.stopDemo();
226− if (!ApplicationManager.focusedApplicationId && ApplicationManager.count > 0 && focusApp) {
227− ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
231 function hide() {
229 function hide() {
232 shown = false;
230 shown = false;
233− if (ApplicationManager.focusedApplicationId) {
234− ApplicationManager.unfocusCurrentApplication();
238 Connections {
233 Connections {
239 target: ApplicationManager
234 target: ApplicationManager
241 onFocusRequested: {
235 onFocusRequested: {
242 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
236 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
243 lockscreen.show();
237 lockscreen.show();
245 greeter.hide();
239 greeter.hide();
246− stages.show(true);
240+ stages.show();
249 onFocusedApplicationIdChanged: {
243 onFocusedApplicationIdChanged: {
250 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
244 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
251 lockscreen.show();
245 lockscreen.show();
253− if (ApplicationManager.focusedApplicationId.length > 0) {
247+ panel.indicators.hide();
256− if (!stages.overlayMode) {
262 onApplicationAdded: {
250 onApplicationAdded: {
263− stages.show(false);
251+ if (greeter.shown) {
264− }
252+ greeter.hide();
266− onApplicationRemoved: {
267− if (ApplicationManager.focusedApplicationId.length == 0) {
273− property bool dialogShown: false
280− text: "Are you sure that you want to logout?"
284− PopupUtils.close(dialogueLogout);
285− stages.dialogShown = false;
291− DBusUnitySessionService.Logout();
292− PopupUtils.close(dialogueLogout);
293− stages.dialogShown = false;
302− id: dialogueShutdown
304− text: "Are you sure that you want to shutdown?"
308− PopupUtils.close(dialogueShutdown);
309− stages.dialogShown = false;
315− dBusUnitySessionServiceConnection.closeAllApps();
316− DBusUnitySessionService.Shutdown();
317− PopupUtils.close(dialogueShutdown);
318− stages.dialogShown = false;
329− text: "Are you sure that you want to reboot?"
333− PopupUtils.close(dialogueReboot)
334− stages.dialogShown = false;
340− dBusUnitySessionServiceConnection.closeAllApps();
341− DBusUnitySessionService.Reboot();
342− PopupUtils.close(dialogueReboot);
343− stages.dialogShown = false;
354− text: i18n.tr("Are you sure you would like to turn power off?")
356− text: i18n.tr("Power off")
358− dBusUnitySessionServiceConnection.closeAllApps();
359− PopupUtils.close(dialoguePower);
360− stages.dialogShown = false;
361− shutdownFadeOutRectangle.enabled = true;
362− shutdownFadeOutRectangle.visible = true;
363− shutdownFadeOut.start();
367− text: i18n.tr("Restart")
369− dBusUnitySessionServiceConnection.closeAllApps();
370− DBusUnitySessionService.Reboot();
371− PopupUtils.close(dialoguePower);
372− stages.dialogShown = false;
376− text: i18n.tr("Cancel")
378− PopupUtils.close(dialoguePower);
379− stages.dialogShown = false;
385− function showPowerDialog() {
386− if (!stages.dialogShown) {
387− stages.dialogShown = true;
388− PopupUtils.open(powerDialog);
393− id: dBusUnitySessionServiceConnection
394− objectName: "dBusUnitySessionServiceConnection"
395− target: DBusUnitySessionService
397− function closeAllApps() {
399− var app = ApplicationManager.get(0);
403− ApplicationManager.stopApplication(app.appId);
407− onLogoutRequested: {
408− // Display a dialog to ask the user to confirm.
409− if (!stages.dialogShown) {
254+ if (!stages.shown) {
410− stages.dialogShown = true;
255+ stages.show();
411− PopupUtils.open(logoutDialog);
415− onShutdownRequested: {
259+ onEmptyChanged: {
416− // Display a dialog to ask the user to confirm.
260+ if (ApplicationManager.empty) {
417− if (!stages.dialogShown) {
261+ stages.hide();
418− stages.dialogShown = true;
419− PopupUtils.open(shutdownDialog);
423− onRebootRequested: {
424− // Display a dialog to ask the user to confirm.
425− if (!stages.dialogShown) {
426− stages.dialogShown = true;
427− PopupUtils.open(rebootDialog);
438 id: applicationsDisplayLoader
267 id: applicationsDisplayLoader
439 anchors.fill: parent
268 anchors.fill: parent
441− source: shell.sideStageEnabled ? "Stages/StageWithSideStage.qml" : "Stages/PhoneStage.qml"
270+ source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
443 Binding {
272 Binding {
444 target: applicationsDisplayLoader.item
273 target: applicationsDisplayLoader.item
@@ -447,18 +276,20 @@ FocusScope {
448 Binding {
277 Binding {
449 target: applicationsDisplayLoader.item
278 target: applicationsDisplayLoader.item
450− property: "moving"
279+ property: "dragAreaWidth"
451− value: !stages.fullyShown
280+ value: shell.edgeSize
453 Binding {
282 Binding {
454 target: applicationsDisplayLoader.item
283 target: applicationsDisplayLoader.item
455− property: "shown"
284+ property: "maximizedAppTopMargin"
456− value: stages.shown
285+ // Not just using panel.panelHeight as that changes depending on the focused app.
286+ value: panel.indicators.panelHeight
458 Binding {
288 Binding {
459 target: applicationsDisplayLoader.item
289 target: applicationsDisplayLoader.item
460− property: "dragAreaWidth"
290+ property: "interactive"
461− value: shell.edgeSize
291+ value: stages.roughlyFullyShown && !greeter.shown && !lockscreen.shown
292+ && panel.indicators.fullyClosed
463 Binding {
294 Binding {
464 target: applicationsDisplayLoader.item
295 target: applicationsDisplayLoader.item
@@ -468,6 +299,33 @@ FocusScope {
304+ objectName: "inputMethod"
305+ anchors { fill: parent; topMargin: panel.panelHeight }
306+ z: notifications.useModal || panel.indicators.shown ? overlay.z + 1 : overlay.z - 1
310+ target: SurfaceManager
312+ if (surface.type == MirSurfaceItem.InputMethod) {
313+ inputMethod.surface = surface;
317+ onSurfaceDestroyed: {
318+ if (inputMethod.surface == surface) {
319+ inputMethod.surface = null;
320+ surface.parent = null;
322+ if (!surface.parent) {
323+ // there's no one displaying it. delete it right away
471 Lockscreen {
329 Lockscreen {
472 id: lockscreen
330 id: lockscreen
473 objectName: "lockscreen"
331 objectName: "lockscreen"
@@ -480,7 +338,7 @@ FocusScope {
480 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
338 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
481 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
339 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
482 y: panel.panelHeight
340 y: panel.panelHeight
483− x: required ? 0 : - width
341+ visible: required
484 width: parent.width
342 width: parent.width
485 height: parent.height - panel.panelHeight
343 height: parent.height - panel.panelHeight
486 background: shell.background
344 background: shell.background
@@ -560,6 +418,7 @@ FocusScope {
560 StandardAnimation {}
418 StandardAnimation {}
421+ property bool fullyShown: showProgress === 1.0
563 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
422 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
564 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
423 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
@@ -626,12 +485,6 @@ FocusScope {
630− anchors.fill: parent
631− blockInput: ApplicationManager.focusedApplicationId.length === 0 || greeter.shown || lockscreen.shown || launcher.shown
632− || panel.indicators.shown
635 Connections {
488 Connections {
636 id: powerConnection
489 id: powerConnection
637 target: Powerd
490 target: Powerd
@@ -674,7 +527,7 @@ FocusScope {
677− if (stages.shown && !stages.overlayMode && !stages.locked) {
530+ if (!stages.locked) {
678 stages.hide();
531 stages.hide();
679 launcher.fadeOut();
532 launcher.fadeOut();
@@ -689,6 +542,7 @@ FocusScope {
691 id: overlay
544 id: overlay
693 anchors.fill: parent
547 anchors.fill: parent
@@ -703,29 +557,13 @@ FocusScope {
703 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
557 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
704 panelHeight: units.gu(3)
558 panelHeight: units.gu(3)
706− property string focusedAppId: ApplicationManager.focusedApplicationId
707− property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
708− fullscreenMode: (focusedApplication && stages.fullscreen && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== ""
710− InputFilterArea {
561+ property bool topmostApplicationIsFullscreen:
711− anchors {
562+ ApplicationManager.focusedApplicationId &&
712− top: parent.top
563+ ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
716− height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
721− InputFilterArea {
565+ fullscreenMode: (stages.roughlyFullyShown && topmostApplicationIsFullscreen
722− blockInput: launcher.shown
566+ && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== ""
725− bottom: parent.bottom
728− width: launcher.width
731 Launcher {
569 Launcher {
@@ -768,11 +606,6 @@ FocusScope {
768 MouseArea {
606 MouseArea {
769 anchors.fill: parent
607 anchors.fill: parent
773− anchors.fill: parent
774− blockInput: modalNotificationBackground.visible
778 Notifications {
611 Notifications {
@@ -798,36 +631,7 @@ FocusScope {
798 PropertyChanges { target: notifications; width: units.gu(38) }
631 PropertyChanges { target: notifications; width: units.gu(38) }
803− anchors { left: parent.left; right: parent.right }
804− height: parent.contentHeight
805− blockInput: height > 0
811− onFocusChanged: if (!focus) forceActiveFocus();
816− bottom: parent.bottom
819− width: shell.edgeSize
826− bottom: parent.bottom
829− width: shell.edgeSize
833 Binding {
637 Binding {
@@ -836,24 +640,22 @@ FocusScope {
836 value: "unity8"
640 value: "unity8"
839− OSKController {
643+ Dialogs {
840− anchors.topMargin: panel.panelHeight
644+ id: dialogs
841− anchors.fill: parent // as needs to know the geometry of the shell
645+ anchors.fill: parent
842− }
646+ z: overlay.z + 10
843−
647+ onPowerOffClicked: {
844− //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
648+ shutdownFadeOutRectangle.enabled = true;
845− MouseArea {
649+ shutdownFadeOutRectangle.visible = true;
846− anchors.bottom: parent.bottom
650+ shutdownFadeOut.start();
847− anchors.left: parent.left
651+ }
848− anchors.right: parent.right
849− height: ApplicationManager.keyboardVisible ? ApplicationManager.keyboardHeight : 0
851− enabled: ApplicationManager.keyboardVisible
655+ id: alphaDisclaimerLabel
855 anchors.centerIn: parent
656 anchors.centerIn: parent
856 visible: ApplicationManager.fake ? ApplicationManager.fake : false
657 visible: ApplicationManager.fake ? ApplicationManager.fake : false
857 text: "EARLY ALPHA\nNOT READY FOR USE"
659 text: "EARLY ALPHA\nNOT READY FOR USE"
858 color: "lightgrey"
660 color: "lightgrey"
859 opacity: 0.2
661 opacity: 0.2
@@ -867,6 +669,7 @@ FocusScope {
868 EdgeDemo {
670 EdgeDemo {
869 id: edgeDemo
671 id: edgeDemo
672+ z: alphaDisclaimerLabel.z + 10
870 greeter: greeter
673 greeter: greeter
871 launcher: launcher
674 launcher: launcher
872 dash: dash
675 dash: dash
@@ -879,35 +682,9 @@ FocusScope {
879 onShowHome: showHome()
682 onShowHome: showHome()
883− if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
884− if (!powerKeyTimer.running) {
885− powerKeyTimer.start();
887− event.accepted = true;
892− if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
893− powerKeyTimer.stop();
894− event.accepted = true;
902− triggeredOnStart: false
905− stages.showPowerDialog();
909 Rectangle {
685 Rectangle {
910 id: shutdownFadeOutRectangle
686 id: shutdownFadeOutRectangle
911 enabled: false
688 enabled: false
912 visible: false
689 visible: false
913 color: "black"
690 color: "black"
@@ -924,4 +701,5 @@ FocusScope {