@@ -19,9 +19,9 @@ import AccountsService 0.1
1919import GSettings 1.0
2020import Unity.Application 0.1
2121import Ubuntu.Components 0.1
22−import Ubuntu.Components.Popups 0.1
2322import Ubuntu.Gestures 0.1
2423import Unity.Launcher 0.1
24+import Utils 0.1
2525import LightDM 0.1 as LightDM
2626import Powerd 0.1
2727import SessionBroadcast 0.1
@@ -31,10 +31,11 @@ import "Launcher"
3131import "Panel"
3232import "Components"
3333import "Notifications"
34+import "Stages"
3435import Unity.Notifications 1.0 as NotificationBackend
3536import Unity.Session 0.1
3637
37−FocusScope {
38+Item {
3839 id: shell
3940
4041 // this is only here to select the width / height of the window if not running fullscreen
@@ -47,7 +48,7 @@ FocusScope {
4748 property url background
4849 readonly property real panelHeight: panel.panelHeight
4950
50− property bool dashShown: dash.shown
51+ property bool dashShown: dash.shown && dash.available && underlay.visible
5152
5253 property bool sideStageEnabled: shell.width >= units.gu(100)
5354 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
@@ -55,14 +56,10 @@ FocusScope {
5556 function activateApplication(appId) {
5657 if (ApplicationManager.findApplication(appId)) {
5758 ApplicationManager.requestFocusApplication(appId);
58− stages.show(true);
59− if (stages.locked && ApplicationManager.focusedApplicationId == appId) {
60− applicationsDisplayLoader.item.select(appId);
61− }
6259 } else {
6360 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
6461 ApplicationManager.startApplication(appId, execFlags);
65− stages.show(false);
62+ stages.show();
6663 }
6764 }
6865
@@ -89,76 +86,68 @@ FocusScope {
8986 id: volumeControl
9087 }
9188
92− Keys.onVolumeUpPressed: volumeControl.volumeUp()
93− Keys.onVolumeDownPressed: volumeControl.volumeDown()
89+ WindowKeysFilter {
90+ // Handle but do not filter out volume keys
91+ Keys.onVolumeUpPressed: { volumeControl.volumeUp(); event.accepted = false; }
92+ Keys.onVolumeDownPressed: { volumeControl.volumeDown(); event.accepted = false; }
9493
95− Item {
96− id: underlayClipper
97− anchors.fill: parent
98− anchors.rightMargin: stages.overlayWidth
99− clip: stages.overlayMode && !stages.painting
100−
101− InputFilterArea {
102− anchors.fill: parent
103− blockInput: parent.clip
94+ Keys.onPressed: {
95+ if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
96+ dialogs.onPowerKeyPressed();
97+ event.accepted = true;
98+ } else {
99+ event.accepted = false;
100+ }
104101 }
105102
106− Item {
107− id: underlay
108− objectName: "underlay"
109− anchors.fill: parent
110− anchors.rightMargin: -parent.anchors.rightMargin
111−
112− // Whether the underlay is fully covered by opaque UI elements.
113− property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicators.width
114−
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
117−
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
121−
122− Rectangle {
123− anchors.fill: parent
124− color: "black"
125− opacity: dash.disappearingAnimationProgress
103+ Keys.onReleased: {
104+ if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
105+ dialogs.onPowerKeyReleased();
106+ event.accepted = true;
107+ } else {
108+ event.accepted = false;
126109 }
110+ }
111+ }
127112
128− Dash {
129− id: dash
130− objectName: "dash"
113+ Item {
114+ id: underlay
115+ objectName: "underlay"
116+ anchors.fill: parent
131117
132− available: !LightDM.Greeter.active
133− hides: [stages, launcher, panel.indicators]
134− shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
135− enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
118+ // Whether the underlay is fully covered by opaque UI elements.
119+ property bool fullyCovered: (panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth)
120+ || stages.fullyShown || greeterWrapper.fullyShown
121+ visible: !fullyCovered
136122
137− overviewHandleHeight: shell.edgeSize
123+ Dash {
124+ id: dash
125+ objectName: "dash"
138126
139− anchors {
140− fill: parent
141− topMargin: panel.panelHeight
142− }
127+ available: !LightDM.Greeter.active
128+ hides: [stages, launcher, panel.indicators]
129+ shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0 &&
130+ !(panel.indicators.fullyOpened && !sideStageEnabled)
131+ enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
143132
144− contentScale: 1.0 - 0.2 * disappearingAnimationProgress
145− opacity: 1.0 - disappearingAnimationProgress
146− property real disappearingAnimationProgress: {
147− if (stages.overlayMode) {
148− return 0;
149− } else {
150− return stages.showProgress
151− }
152− }
133+ overviewHandleHeight: shell.edgeSize
153134
154− // FIXME: only necessary because stages.showProgress is not animated
155− Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
135+ anchors {
136+ fill: parent
137+ topMargin: panel.panelHeight
156138 }
139+
140+ contentScale: 1.0 - 0.2 * disappearingAnimationProgress
141+ opacity: 1.0 - disappearingAnimationProgress
142+ property real disappearingAnimationProgress: stages.showProgress
143+
144+ // FIXME: only necessary because stages.showProgress is not animated
145+ Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
157146 }
158147 }
159148
160149 EdgeDragArea {
161− id: stagesDragHandle
150+ id: stagesDragArea
162151 direction: Direction.Leftwards
163152
164153 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
@@ -168,20 +157,20 @@ FocusScope {
168157
169158 onTouchXChanged: {
170159 if (status == DirectionalDragArea.Recognized) {
171− if (ApplicationManager.count == 0) {
172− progress = Math.max(stages.width - stagesDragHandle.width + touchX, stages.width * .3)
160+ if (ApplicationManager.empty) {
161+ progress = Math.max(stages.width - stagesDragArea.width + touchX, stages.width * .3);
173162 } else {
174− progress = stages.width - stagesDragHandle.width + touchX
163+ progress = stages.width - stagesDragArea.width + touchX;
175164 }
176165 }
177166 }
178167
179168 onDraggingChanged: {
180169 if (!dragging) {
181− if (ApplicationManager.count > 0 && progress < stages.width - units.gu(10)) {
182− stages.show(true)
170+ if (!ApplicationManager.empty && progress < stages.width - units.gu(10)) {
171+ stages.show();
183172 }
184− stagesDragHandle.progress = stages.width;
173+ stagesDragArea.progress = Qt.binding(function () { return stages.width; });
185174 }
186175 }
187176 }
@@ -192,253 +181,93 @@ FocusScope {
192181 width: parent.width
193182 height: parent.height
194183
184+ visible: !fullyHidden && !ApplicationManager.empty
185+
195186 x: {
196187 if (shown) {
197− if (overlayMode || locked || greeter.fakeActiveForApp !== "") {
188+ if (locked || greeter.fakeActiveForApp !== "") {
198189 return 0;
199190 }
200− return launcher.progress
191+ return launcher.progress;
201192 } else {
202− return stagesDragHandle.progress
193+ return stagesDragArea.progress
203194 }
204195 }
205−
206196 Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
207197
208198 property bool shown: false
199+ onShownChanged: {
200+ if (shown) {
201+ if (ApplicationManager.count > 0) {
202+ ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
203+ }
204+ } else {
205+ if (ApplicationManager.focusedApplicationId) {
206+ ApplicationManager.updateScreenshot(ApplicationManager.focusedApplicationId);
207+ ApplicationManager.unfocusCurrentApplication();
208+ }
209+ }
210+ }
209211
210− property real showProgress: overlayMode ? 0 : MathUtils.clamp(1 - x / shell.width, 0, 1)
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.
215+ property real showProgress: shell.width ? MathUtils.clamp(1 - x / shell.width, 0, 1) : 0
211216
212217 property bool fullyShown: x == 0
213218 property bool fullyHidden: x == width
214219
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
219220 property bool locked: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.locked : false
220221
221− function show(focusApp) {
222+ // It might technically not be fullyShown but visually it just looks so.
223+ property bool roughlyFullyShown: x >= 0 && x <= units.gu(1)
224+
225+ function show() {
222226 shown = true;
223− panel.indicators.hide();
224− edgeDemo.stopDemo();
225− greeter.hide();
226− if (!ApplicationManager.focusedApplicationId && ApplicationManager.count > 0 && focusApp) {
227− ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
228− }
229227 }
230228
231229 function hide() {
232230 shown = false;
233− if (ApplicationManager.focusedApplicationId) {
234− ApplicationManager.unfocusCurrentApplication();
235− }
236231 }
237232
238233 Connections {
239234 target: ApplicationManager
240−
241235 onFocusRequested: {
242236 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
243237 lockscreen.show();
244238 }
245239 greeter.hide();
246− stages.show(true);
240+ stages.show();
247241 }
248242
249243 onFocusedApplicationIdChanged: {
250244 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
251245 lockscreen.show();
252246 }
253− if (ApplicationManager.focusedApplicationId.length > 0) {
254− stages.show(false);
255− } else {
256− if (!stages.overlayMode) {
257− stages.hide();
258− }
259− }
247+ panel.indicators.hide();
260248 }
261249
262250 onApplicationAdded: {
263− stages.show(false);
264− }
265−
266− onApplicationRemoved: {
267− if (ApplicationManager.focusedApplicationId.length == 0) {
268− stages.hide();
269− }
270− }
271− }
272−
273− property bool dialogShown: false
274−
275− Component {
276− id: logoutDialog
277− Dialog {
278− id: dialogueLogout
279− title: "Logout"
280− text: "Are you sure that you want to logout?"
281− Button {
282− text: "Cancel"
283− onClicked: {
284− PopupUtils.close(dialogueLogout);
285− stages.dialogShown = false;
286− }
287− }
288− Button {
289− text: "Yes"
290− onClicked: {
291− DBusUnitySessionService.Logout();
292− PopupUtils.close(dialogueLogout);
293− stages.dialogShown = false;
294− }
295− }
296− }
297− }
298−
299− Component {
300− id: shutdownDialog
301− Dialog {
302− id: dialogueShutdown
303− title: "Shutdown"
304− text: "Are you sure that you want to shutdown?"
305− Button {
306− text: "Cancel"
307− onClicked: {
308− PopupUtils.close(dialogueShutdown);
309− stages.dialogShown = false;
310− }
311− }
312− Button {
313− text: "Yes"
314− onClicked: {
315− dBusUnitySessionServiceConnection.closeAllApps();
316− DBusUnitySessionService.Shutdown();
317− PopupUtils.close(dialogueShutdown);
318− stages.dialogShown = false;
319− }
320− }
321− }
322− }
323−
324− Component {
325− id: rebootDialog
326− Dialog {
327− id: dialogueReboot
328− title: "Reboot"
329− text: "Are you sure that you want to reboot?"
330− Button {
331− text: "Cancel"
332− onClicked: {
333− PopupUtils.close(dialogueReboot)
334− stages.dialogShown = false;
335− }
336− }
337− Button {
338− text: "Yes"
339− onClicked: {
340− dBusUnitySessionServiceConnection.closeAllApps();
341− DBusUnitySessionService.Reboot();
342− PopupUtils.close(dialogueReboot);
343− stages.dialogShown = false;
344− }
345− }
346− }
347− }
348−
349− Component {
350− id: powerDialog
351− Dialog {
352− id: dialoguePower
353− title: "Power"
354− text: i18n.tr("Are you sure you would like to turn power off?")
355− Button {
356− text: i18n.tr("Power off")
357− onClicked: {
358− dBusUnitySessionServiceConnection.closeAllApps();
359− PopupUtils.close(dialoguePower);
360− stages.dialogShown = false;
361− shutdownFadeOutRectangle.enabled = true;
362− shutdownFadeOutRectangle.visible = true;
363− shutdownFadeOut.start();
364− }
365− }
366− Button {
367− text: i18n.tr("Restart")
368− onClicked: {
369− dBusUnitySessionServiceConnection.closeAllApps();
370− DBusUnitySessionService.Reboot();
371− PopupUtils.close(dialoguePower);
372− stages.dialogShown = false;
373− }
374− }
375− Button {
376− text: i18n.tr("Cancel")
377− onClicked: {
378− PopupUtils.close(dialoguePower);
379− stages.dialogShown = false;
380− }
381− }
382− }
383− }
384−
385− function showPowerDialog() {
386− if (!stages.dialogShown) {
387− stages.dialogShown = true;
388− PopupUtils.open(powerDialog);
389− }
390− }
391−
392− Connections {
393− id: dBusUnitySessionServiceConnection
394− objectName: "dBusUnitySessionServiceConnection"
395− target: DBusUnitySessionService
396−
397− function closeAllApps() {
398− while (true) {
399− var app = ApplicationManager.get(0);
400− if (app === null) {
401− break;
402− }
403− ApplicationManager.stopApplication(app.appId);
251+ if (greeter.shown) {
252+ greeter.hide();
404253 }
405− }
406−
407− onLogoutRequested: {
408− // Display a dialog to ask the user to confirm.
409− if (!stages.dialogShown) {
410− stages.dialogShown = true;
411− PopupUtils.open(logoutDialog);
254+ if (!stages.shown) {
255+ stages.show();
412256 }
413257 }
414258
415− onShutdownRequested: {
416− // Display a dialog to ask the user to confirm.
417− if (!stages.dialogShown) {
418− stages.dialogShown = true;
419− PopupUtils.open(shutdownDialog);
420− }
421− }
422−
423− onRebootRequested: {
424− // Display a dialog to ask the user to confirm.
425− if (!stages.dialogShown) {
426− stages.dialogShown = true;
427− PopupUtils.open(rebootDialog);
259+ onEmptyChanged: {
260+ if (ApplicationManager.empty) {
261+ stages.hide();
428262 }
429263 }
430−
431− onLogoutReady: {
432− closeAllApps();
433− Qt.quit();
434− }
435264 }
436265
437266 Loader {
438267 id: applicationsDisplayLoader
439268 anchors.fill: parent
440269
441− source: shell.sideStageEnabled ? "Stages/StageWithSideStage.qml" : "Stages/PhoneStage.qml"
270+ source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
442271
443272 Binding {
444273 target: applicationsDisplayLoader.item
@@ -447,18 +276,20 @@ FocusScope {
447276 }
448277 Binding {
449278 target: applicationsDisplayLoader.item
450− property: "moving"
451− value: !stages.fullyShown
279+ property: "dragAreaWidth"
280+ value: shell.edgeSize
452281 }
453282 Binding {
454283 target: applicationsDisplayLoader.item
455− property: "shown"
456− value: stages.shown
284+ property: "maximizedAppTopMargin"
285+ // Not just using panel.panelHeight as that changes depending on the focused app.
286+ value: panel.indicators.panelHeight
457287 }
458288 Binding {
459289 target: applicationsDisplayLoader.item
460− property: "dragAreaWidth"
461− value: shell.edgeSize
290+ property: "interactive"
291+ value: stages.roughlyFullyShown && !greeter.shown && !lockscreen.shown
292+ && panel.indicators.fullyClosed
462293 }
463294 Binding {
464295 target: applicationsDisplayLoader.item
@@ -468,6 +299,33 @@ FocusScope {
468299 }
469300 }
470301
302+ InputMethod {
303+ id: inputMethod
304+ objectName: "inputMethod"
305+ anchors { fill: parent; topMargin: panel.panelHeight }
306+ z: notifications.useModal || panel.indicators.shown ? overlay.z + 1 : overlay.z - 1
307+ }
308+
309+ Connections {
310+ target: SurfaceManager
311+ onSurfaceCreated: {
312+ if (surface.type == MirSurfaceItem.InputMethod) {
313+ inputMethod.surface = surface;
314+ }
315+ }
316+
317+ onSurfaceDestroyed: {
318+ if (inputMethod.surface == surface) {
319+ inputMethod.surface = null;
320+ surface.parent = null;
321+ }
322+ if (!surface.parent) {
323+ // there's no one displaying it. delete it right away
324+ surface.release();
325+ }
326+ }
327+ }
328+
471329 Lockscreen {
472330 id: lockscreen
473331 objectName: "lockscreen"
@@ -480,7 +338,7 @@ FocusScope {
480338 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
481339 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
482340 y: panel.panelHeight
483− x: required ? 0 : - width
341+ visible: required
484342 width: parent.width
485343 height: parent.height - panel.panelHeight
486344 background: shell.background
@@ -560,6 +418,7 @@ FocusScope {
560418 StandardAnimation {}
561419 }
562420
421+ property bool fullyShown: showProgress === 1.0
563422 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
564423 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
565424
@@ -626,12 +485,6 @@ FocusScope {
626485 }
627486 }
628487
629− InputFilterArea {
630− anchors.fill: parent
631− blockInput: ApplicationManager.focusedApplicationId.length === 0 || greeter.shown || lockscreen.shown || launcher.shown
632− || panel.indicators.shown
633− }
634−
635488 Connections {
636489 id: powerConnection
637490 target: Powerd
@@ -674,7 +527,7 @@ FocusScope {
674527 return;
675528 }
676529
677− if (stages.shown && !stages.overlayMode && !stages.locked) {
530+ if (!stages.locked) {
678531 stages.hide();
679532 launcher.fadeOut();
680533 } else {
@@ -689,6 +542,7 @@ FocusScope {
689542
690543 Item {
691544 id: overlay
545+ z: 10
692546
693547 anchors.fill: parent
694548
@@ -703,29 +557,13 @@ FocusScope {
703557 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
704558 panelHeight: units.gu(3)
705559 }
706− property string focusedAppId: ApplicationManager.focusedApplicationId
707− property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
708− fullscreenMode: (focusedApplication && stages.fullscreen && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== ""
709560
710− InputFilterArea {
711− anchors {
712− top: parent.top
713− left: parent.left
714− right: parent.right
715− }
716− height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
717− blockInput: true
718− }
719− }
561+ property bool topmostApplicationIsFullscreen:
562+ ApplicationManager.focusedApplicationId &&
563+ ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
720564
721− InputFilterArea {
722− blockInput: launcher.shown
723− anchors {
724− top: parent.top
725− bottom: parent.bottom
726− left: parent.left
727− }
728− width: launcher.width
565+ fullscreenMode: (stages.roughlyFullyShown && topmostApplicationIsFullscreen
566+ && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== ""
729567 }
730568
731569 Launcher {
@@ -768,11 +606,6 @@ FocusScope {
768606 MouseArea {
769607 anchors.fill: parent
770608 }
771−
772− InputFilterArea {
773− anchors.fill: parent
774− blockInput: modalNotificationBackground.visible
775− }
776609 }
777610
778611 Notifications {
@@ -798,36 +631,7 @@ FocusScope {
798631 PropertyChanges { target: notifications; width: units.gu(38) }
799632 }
800633 ]
801−
802− InputFilterArea {
803− anchors { left: parent.left; right: parent.right }
804− height: parent.contentHeight
805− blockInput: height > 0
806− }
807− }
808− }
809−
810− focus: true
811− onFocusChanged: if (!focus) forceActiveFocus();
812−
813− InputFilterArea {
814− anchors {
815− top: parent.top
816− bottom: parent.bottom
817− left: parent.left
818− }
819− width: shell.edgeSize
820− blockInput: true
821− }
822−
823− InputFilterArea {
824− anchors {
825− top: parent.top
826− bottom: parent.bottom
827− right: parent.right
828634 }
829− width: shell.edgeSize
830− blockInput: true
831635 }
832636
833637 Binding {
@@ -836,24 +640,22 @@ FocusScope {
836640 value: "unity8"
837641 }
838642
839− OSKController {
840− anchors.topMargin: panel.panelHeight
841− anchors.fill: parent // as needs to know the geometry of the shell
842− }
843−
844− //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
845− MouseArea {
846− anchors.bottom: parent.bottom
847− anchors.left: parent.left
848− anchors.right: parent.right
849− height: ApplicationManager.keyboardVisible ? ApplicationManager.keyboardHeight : 0
850−
851− enabled: ApplicationManager.keyboardVisible
643+ Dialogs {
644+ id: dialogs
645+ anchors.fill: parent
646+ z: overlay.z + 10
647+ onPowerOffClicked: {
648+ shutdownFadeOutRectangle.enabled = true;
649+ shutdownFadeOutRectangle.visible = true;
650+ shutdownFadeOut.start();
651+ }
852652 }
853653
854654 Label {
655+ id: alphaDisclaimerLabel
855656 anchors.centerIn: parent
856657 visible: ApplicationManager.fake ? ApplicationManager.fake : false
658+ z: dialogs.z + 10
857659 text: "EARLY ALPHA\nNOT READY FOR USE"
858660 color: "lightgrey"
859661 opacity: 0.2
@@ -867,6 +669,7 @@ FocusScope {
867669
868670 EdgeDemo {
869671 id: edgeDemo
672+ z: alphaDisclaimerLabel.z + 10
870673 greeter: greeter
871674 launcher: launcher
872675 dash: dash
@@ -879,35 +682,9 @@ FocusScope {
879682 onShowHome: showHome()
880683 }
881684
882− Keys.onPressed: {
883− if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
884− if (!powerKeyTimer.running) {
885− powerKeyTimer.start();
886− }
887− event.accepted = true;
888− }
889− }
890−
891− Keys.onReleased: {
892− if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
893− powerKeyTimer.stop();
894− event.accepted = true;
895− }
896− }
897−
898− Timer {
899− id: powerKeyTimer
900− interval: 2000
901− repeat: false
902− triggeredOnStart: false
903−
904− onTriggered: {
905− stages.showPowerDialog();
906− }
907− }
908−
909685 Rectangle {
910686 id: shutdownFadeOutRectangle
687+ z: edgeDemo.z + 10
911688 enabled: false
912689 visible: false
913690 color: "black"
@@ -924,4 +701,5 @@ FocusScope {
924701 }
925702 }
926703 }
704+
927705}