on b6829c2 help sign in
unity8/Shell.qml
810 lines 29 kB history raw
1/*
2 * Copyright (C) 2013 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 */
17import QtQuick 2.0
18import Ubuntu.Application 0.1
19import Ubuntu.Components 0.1
20import Ubuntu.Gestures 0.1
21import LightDM 0.1 as LightDM
22import AccountsService 0.1
23import Powerd 0.1
24import "Dash"
25import "Greeter"
26import "Launcher"
27import "Panel"
28import "Hud"
29import "Components"
30import "Components/Math.js" as MathLocal
31import "Bottombar"
32import "SideStage"
33import "Notifications"
34import Unity.Notifications 1.0 as NotificationBackend
36FocusScope {
37 id: shell
39 // this is only here to select the width / height of the window if not running fullscreen
40 property bool tablet: false
41 width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
42 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
44 property real edgeSize: units.gu(2)
45 property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
46 property url background: default_background
47 readonly property real panelHeight: panel.panelHeight
49 property bool dashShown: dash.shown
50 property bool stageScreenshotsReady: {
51 if (sideStage.shown) {
52 if (mainStage.applications.count > 0) {
53 return mainStage.usingScreenshots && sideStage.usingScreenshots;
54 } else {
55 return sideStage.usingScreenshots;
56 }
57 } else {
58 return mainStage.usingScreenshots;
59 }
60 }
62 property bool showEdgeDemo: true
63 property bool showEdgeDemoInGreeter: showEdgeDemo //AccountsService.getUserProperty("lightdm", "demo-edges")
65 function hideEdgeDemo() {
66 var user = LightDM.Users.data(greeter.currentIndex, LightDM.UserRoles.NameRole);
67 AccountsService.setUserProperty(user, "demo-edges", false);
68 shell.showEdgeDemo = false;
69 }
70 function hideEdgeDemoInGreeter() {
71 //AccountsService.setUserProperty("lightdm", "demo-edges", false);
72 shell.showEdgeDemoInGreeter = false;
73 }
75 property ListModel searchHistory: SearchHistoryModel {}
77 property var applicationManager: ApplicationManagerWrapper {}
79 Component.onCompleted: {
80 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
82 applicationManager.sideStageEnabled = Qt.binding(function() { return sideStage.enabled })
84 // FIXME: if application focused before shell starts, shell draws on top of it only.
85 // We should detect already running applications on shell start and bring them to the front.
86 applicationManager.unfocusCurrentApplication();
87 }
89 readonly property bool fullscreenMode: {
90 if (greeter.shown || lockscreen.shown) {
91 return false;
92 } else if (mainStage.usingScreenshots) { // Window Manager animating so want to re-evaluate fullscreen mode
93 return mainStage.switchingFromFullscreenToFullscreen;
94 } else if (applicationManager.mainStageFocusedApplication) {
95 return applicationManager.mainStageFocusedApplication.fullscreen;
96 } else {
97 return false;
98 }
99 }
101 Connections {
102 target: applicationManager
103 ignoreUnknownSignals: true
104 onFocusRequested: {
105 // TODO: this should be protected to only unlock for certain applications / certain usecases
106 // potentially only in connection with a notification
107 greeter.hide();
108 shell.activateApplication(desktopFile);
109 }
110 }
112 function activateApplication(desktopFile, argument) {
113 if (applicationManager) {
114 // For newly started applications, as it takes them time to draw their first frame
115 // we add a delay before we hide the animation screenshots to compensate.
116 var addDelay = !applicationManager.getApplicationFromDesktopFile(desktopFile);
118 var application;
119 application = applicationManager.activateApplication(desktopFile, argument);
120 if (application == null) {
121 return;
122 }
123 if (application.stage == ApplicationInfo.MainStage || !sideStage.enabled) {
124 mainStage.activateApplication(desktopFile, addDelay);
125 } else {
126 sideStage.activateApplication(desktopFile, addDelay);
127 }
128 stages.show();
129 }
130 }
132 VolumeControl {
133 id: volumeControl
134 }
136 Keys.onVolumeUpPressed: volumeControl.volumeUp()
137 Keys.onVolumeDownPressed: volumeControl.volumeDown()
139 Item {
140 id: underlay
141 objectName: "underlay"
142 anchors.fill: parent
144 // Whether the underlay is fully covered by opaque UI elements.
145 property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
147 // Whether the user should see the topmost application surface (if there's one at all).
148 property bool applicationSurfaceShouldBeSeen:
149 (mainStage.applications && mainStage.applications.count > 0)
150 && (!stages.fullyHidden && !mainStage.usingScreenshots)
152 // NB! Application surfaces are stacked behing the shell one. So they can only be seen by the user
153 // through the translucent parts of the shell surface.
154 visible: !fullyCovered && !applicationSurfaceShouldBeSeen
156 Image {
157 id: backgroundImage
158 source: shell.background
159 sourceSize.width: parent.width
160 sourceSize.height: parent.height
161 anchors.fill: parent
162 }
164 Rectangle {
165 anchors.fill: parent
166 color: "black"
167 opacity: dash.disappearingAnimationProgress
168 }
170 Dash {
171 id: dash
172 objectName: "dash"
174 available: !greeter.shown && !lockscreen.shown
175 hides: [stages, launcher, panel.indicators]
176 shown: disappearingAnimationProgress !== 1.0
177 enabled: disappearingAnimationProgress === 0.0 && !leftEdgeDemo.active && !topEdgeDemo.active && !finalEdgeDemo.active
178 // FIXME: unfocus all applications when going back to the dash
179 onEnabledChanged: {
180 if (enabled) {
181 shell.applicationManager.unfocusCurrentApplication()
182 }
183 }
185 anchors {
186 fill: parent
187 topMargin: panel.panelHeight
188 }
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;
197 }
198 }
200 // FIXME: only necessary because stagesOuterContainer.showProgress and
201 // greeterRevealer.animatedProgress are not animated
202 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
203 }
205 DemoOverlay {
206 id: topEdgeDemo
208 edge: "top"
209 title: i18n.tr("Top edge")
210 text: i18n.tr("Try swiping from the top edge to access the indicators")
211 anchors.fill: dash
212 visible: false
213 enabled: shell.showEdgeDemo
214 onSkip: shell.hideEdgeDemo()
216 Connections {
217 target: greeter
218 onShownChanged: if (!greeter.shown) topEdgeDemo.visible = true
219 }
221 Connections {
222 target: panel.indicators
223 onFullyOpenedChanged: if (panel.indicators.fullyOpened) topEdgeDemo.enabled = false
224 }
225 }
227 DemoOverlay {
228 id: leftEdgeDemo
230 edge: "left"
231 title: i18n.tr("Left edge")
232 text: i18n.tr("Swipe from the left to reveal the launcher for quick access to apps")
233 anchors.fill: dash
234 visible: false
235 enabled: shell.showEdgeDemo
236 onSkip: shell.hideEdgeDemo()
238 Connections {
239 target: bottomEdgeDemo
240 onActiveChanged: if (!bottomEdgeDemo.active) leftEdgeDemo.visible = true
241 }
243 Connections {
244 target: launcher
245 onProgressChanged: if (launcher.progress >= 1.0) leftEdgeDemo.enabled = false
246 }
247 }
248 }
251 Item {
252 id: stagesOuterContainer
254 width: parent.width
255 height: parent.height
256 x: launcher.progress
257 Behavior on x {SmoothedAnimation{velocity: 600}}
259 property real showProgress:
260 MathLocal.clamp(1 - (x + stages.x) / shell.width, 0, 1)
262 Showable {
263 id: stages
264 objectName: "stages"
266 x: width
268 property bool fullyShown: shown && x == 0 && parent.x == 0
269 property bool fullyHidden: !shown && x == width
270 available: !greeter.shown
271 hides: [launcher, panel.indicators]
272 shown: false
273 opacity: 1.0
274 showAnimation: StandardAnimation { property: "x"; duration: 350; to: 0; easing.type: Easing.OutCubic }
275 hideAnimation: StandardAnimation { property: "x"; duration: 350; to: width; easing.type: Easing.OutCubic }
277 width: parent.width
278 height: parent.height
280 // close the stages when no focused application remains
281 Connections {
282 target: shell.applicationManager
283 onMainStageFocusedApplicationChanged: stages.closeIfNoApplications()
284 onSideStageFocusedApplicationChanged: stages.closeIfNoApplications()
285 ignoreUnknownSignals: true
286 }
288 function closeIfNoApplications() {
289 if (!shell.applicationManager.mainStageFocusedApplication
290 && !shell.applicationManager.sideStageFocusedApplication
291 && shell.applicationManager.mainStageApplications.count == 0
292 && shell.applicationManager.sideStageApplications.count == 0) {
293 stages.hide();
294 }
295 }
297 // show the stages when an application gets the focus
298 Connections {
299 target: shell.applicationManager
300 onMainStageFocusedApplicationChanged: {
301 if (shell.applicationManager.mainStageFocusedApplication) {
302 mainStage.show();
303 stages.show();
304 }
305 }
306 onSideStageFocusedApplicationChanged: {
307 if (shell.applicationManager.sideStageFocusedApplication) {
308 sideStage.show();
309 stages.show();
310 }
311 }
312 ignoreUnknownSignals: true
313 }
316 Stage {
317 id: mainStage
319 anchors.fill: parent
320 fullyShown: stages.fullyShown
321 fullyHidden: stages.fullyHidden
322 shouldUseScreenshots: !fullyShown
323 rightEdgeEnabled: !sideStage.enabled
325 applicationManager: shell.applicationManager
326 rightEdgeDraggingAreaWidth: shell.edgeSize
327 normalApplicationY: shell.panelHeight
329 shown: true
330 function show() {
331 stages.show();
332 }
333 function hide() {
334 }
336 // FIXME: workaround the fact that focusing a main stage application
337 // raises its surface on top of all other surfaces including the ones
338 // that belong to side stage applications.
339 onFocusedApplicationChanged: {
340 if (focusedApplication && sideStage.focusedApplication && sideStage.fullyShown) {
341 shell.applicationManager.focusApplication(sideStage.focusedApplication);
342 }
343 }
344 }
346 SideStage {
347 id: sideStage
349 applicationManager: shell.applicationManager
350 rightEdgeDraggingAreaWidth: shell.edgeSize
351 normalApplicationY: shell.panelHeight
353 onShownChanged: {
354 if (!shown && mainStage.applications.count == 0) {
355 stages.hide();
356 }
357 }
358 // FIXME: when hiding the side stage, refocus the main stage
359 // application so that it goes in front of the side stage
360 // application and hides it
361 onFullyShownChanged: {
362 if (!fullyShown && stages.fullyShown && sideStage.focusedApplication != null) {
363 shell.applicationManager.focusApplication(mainStage.focusedApplication);
364 }
365 }
367 enabled: shell.width >= units.gu(60)
368 visible: enabled
369 fullyShown: stages.fullyShown && shown
370 && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
371 shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
373 available: !greeter.shown && !lockscreen.shown && enabled
374 hides: [launcher, panel.indicators]
375 shown: false
376 showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
377 hideAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.closedValue; easing.type: Easing.OutQuint }
379 width: units.gu(40)
380 height: stages.height
381 handleExpanded: sideStageRevealer.pressed
382 }
384 Revealer {
385 id: sideStageRevealer
387 enabled: mainStage.applications.count > 0 && sideStage.applications.count > 0
388 && sideStage.available
389 direction: Qt.RightToLeft
390 openedValue: parent.width - sideStage.width
391 hintDisplacement: units.gu(3)
392 /* The size of the sidestage handle needs to be bigger than the
393 typical size used for edge detection otherwise it is really
394 hard to grab.
395 */
396 handleSize: sideStage.shown ? units.gu(4) : shell.edgeSize
397 closedValue: parent.width + sideStage.handleSizeCollapsed
398 target: sideStage
399 x: parent.width - width
400 width: sideStage.width + handleSize * 0.7
401 height: sideStage.height
402 orientation: Qt.Horizontal
403 }
405 DragHandle {
406 id: stagesDragHandle
408 anchors.top: parent.top
409 anchors.bottom: parent.bottom
410 anchors.right: parent.left
412 width: shell.edgeSize
413 direction: Direction.Leftwards
414 property bool haveApps: mainStage.applications.count > 0 || sideStage.applications.count > 0
416 maxTotalDragDistance: haveApps ? parent.width : parent.width * 0.7
417 // Make autocompletion impossible when !haveApps
418 edgeDragEvaluator.minDragDistance: haveApps ? maxTotalDragDistance * 0.1 : Number.MAX_VALUE
419 }
420 }
421 }
423 Lockscreen {
424 id: lockscreen
425 hides: [launcher, panel.indicators, hud]
426 shown: false
427 enabled: true
428 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
429 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
430 y: panel.panelHeight
431 x: required ? 0 : - width
432 width: parent.width
433 height: parent.height - panel.panelHeight
434 background: shell.background
436 onUnlocked: lockscreen.hide()
437 onCancel: greeter.show()
439 Component.onCompleted: {
440 if (LightDM.Users.count == 1) {
441 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
442 greeter.selected(0)
443 }
444 }
445 }
447 Connections {
448 target: LightDM.Greeter
450 onShowPrompt: {
451 if (LightDM.Users.count == 1) {
452 // TODO: There's no better way for now to determine if its a PIN or a passphrase.
453 if (text == "PIN") {
454 lockscreen.alphaNumeric = false
455 } else {
456 lockscreen.alphaNumeric = true
457 }
458 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
459 lockscreen.show();
460 }
461 }
462 }
464 Greeter {
465 id: greeter
467 available: true
468 hides: [launcher, panel.indicators, hud]
469 shown: true
471 y: panel.panelHeight
472 width: parent.width
473 height: parent.height - panel.panelHeight
475 dragHandleWidth: shell.edgeSize
477 onShownChanged: {
478 if (shown) {
479 lockscreen.reset();
480 // If there is only one user, we start authenticating with that one here.
481 // If there are more users, the Greeter will handle that
482 if (LightDM.Users.count == 1) {
483 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
484 greeter.selected(0);
485 }
486 greeter.forceActiveFocus();
487 }
488 }
490 onUnlocked: greeter.hide()
491 onSelected: {
492 // Update background
493 var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
494 shell.background = bgPath ? bgPath : default_background
495 // Update edge demo hint
496 var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole)
497 shell.showEdgeDemo = true //AccountsService.getUserProperty(user, "demo-edges")
498 }
500 onLeftTeaserPressedChanged: {
501 if (leftTeaserPressed) {
502 launcher.tease();
503 }
504 }
506 DemoOverlay {
507 id: rightEdgeDemo
509 edge: "right"
510 title: i18n.tr("Right edge")
511 text: i18n.tr("Try swiping from the right edge to unlock the phone")
512 anchors.fill: parent
513 visible: shell.showEdgeDemoInGreeter
514 onSkip: {
515 shell.hideEdgeDemoInGreeter()
516 shell.hideEdgeDemo()
517 }
519 Connections {
520 target: greeter
522 function hide() {
523 if (rightEdgeDemo.active) {
524 rightEdgeDemo.enabled = false
525 shell.hideEdgeDemoInGreeter()
526 }
527 }
529 onUnlocked: hide()
530 onShownChanged: if (!greeter.shown) hide()
531 }
532 }
533 }
535 InputFilterArea {
536 anchors.fill: parent
537 blockInput: greeter.shown || lockscreen.shown
538 }
540 Connections {
541 id: powerConnection
542 target: Powerd
544 property var previousMainApp: null
545 property var previousSideApp: null
547 function setFocused(focused) {
548 if (!focused) {
549 // FIXME: *FocusedApplication are not updated when unfocused, hence the need to check whether
550 // the stage was actually shown
551 if (mainStage.fullyShown) powerConnection.previousMainApp = applicationManager.mainStageFocusedApplication;
552 if (sideStage.fullyShown) powerConnection.previousSideApp = applicationManager.sideStageFocusedApplication;
553 applicationManager.unfocusCurrentApplication();
554 } else {
555 if (powerConnection.previousMainApp) {
556 applicationManager.focusApplication(powerConnection.previousMainApp);
557 powerConnection.previousMainApp = null;
558 }
559 if (powerConnection.previousSideApp) {
560 applicationManager.focusApplication(powerConnection.previousSideApp);
561 powerConnection.previousSideApp = null;
562 }
563 }
564 }
566 onPowerStateChange: {
567 if (state == 0) { // suspend
568 powerConnection.setFocused(false);
569 greeter.show();
570 } else if (state == 1) { // active
571 powerConnection.setFocused(true);
572 }
573 }
574 }
576 Item {
577 id: overlay
579 anchors.fill: parent
581 Panel {
582 id: panel
583 anchors.fill: parent //because this draws indicator menus
584 indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
585 indicators {
586 hides: [launcher]
587 available: !rightEdgeDemo.active && !leftEdgeDemo.active && !finalEdgeDemo.active
588 }
589 fullscreenMode: shell.fullscreenMode
590 searchVisible: !greeter.shown && !lockscreen.shown
592 InputFilterArea {
593 anchors.fill: parent
594 blockInput: panel.indicators.shown
595 }
597 DemoOverlay {
598 id: bottomEdgeDemo
600 edge: "bottom"
601 title: i18n.tr("Close")
602 text: i18n.tr("Swipe up again to close the settings screen")
603 anchors.fill: panel.indicators
604 visible: false
605 enabled: shell.showEdgeDemo
606 onSkip: shell.hideEdgeDemo()
608 Connections {
609 target: panel.indicators
610 onFullyOpenedChanged: if (panel.indicators.fullyOpened) bottomEdgeDemo.visible = true
611 onPartiallyOpenedChanged: if (!panel.indicators.partiallyOpened && !panel.indicators.fullyOpened) bottomEdgeDemo.enabled = false
612 }
613 }
614 }
616 Hud {
617 id: hud
619 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
620 height: parent.height
622 available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown && !topEdgeDemo.active
623 shown: false
624 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
625 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
627 Connections {
628 target: shell.applicationManager
629 onMainStageFocusedApplicationChanged: hud.hide()
630 onSideStageFocusedApplicationChanged: hud.hide()
631 }
633 InputFilterArea {
634 anchors.fill: parent
635 blockInput: hud.shown
636 }
637 }
639 Revealer {
640 id: hudRevealer
642 enabled: hud.shown
643 width: hud.width
644 anchors.left: hud.left
645 height: parent.height
646 target: hud.revealerTarget
647 closedValue: height
648 openedValue: 0
649 direction: Qt.RightToLeft
650 orientation: Qt.Vertical
651 handleSize: hud.handleHeight
652 onCloseClicked: target.hide()
653 }
655 Bottombar {
656 theHud: hud
657 anchors.fill: parent
658 enabled: !panel.indicators.shown
659 applicationIsOnForeground: applicationManager.mainStageFocusedApplication
660 || applicationManager.sideStageFocusedApplication
661 }
663 InputFilterArea {
664 blockInput: launcher.shown
665 anchors {
666 top: parent.top
667 bottom: parent.bottom
668 left: parent.left
669 }
670 width: launcher.width
671 }
673 Launcher {
674 id: launcher
676 anchors.top: parent.top
677 anchors.bottom: parent.bottom
678 width: parent.width
679 dragAreaWidth: shell.edgeSize
680 available: (!greeter.shown || greeter.narrowMode) && !rightEdgeDemo.active && !topEdgeDemo.active && !bottomEdgeDemo.active && !finalEdgeDemo.active
681 onDashItemSelected: {
682 greeter.hide()
683 // Animate if moving between application and dash
684 if (!stages.shown) {
685 dash.setCurrentScope("home.scope", true, false)
686 } else {
687 dash.setCurrentScope("home.scope", false, false)
688 }
689 stages.hide();
690 }
691 onDash: {
692 if (stages.shown) {
693 dash.setCurrentScope("applications.scope", true, false)
694 stages.hide();
695 launcher.hide();
696 }
697 }
698 onLauncherApplicationSelected:{
699 greeter.hide()
700 shell.activateApplication(desktopFile)
701 }
702 onShownChanged: {
703 if (shown) {
704 panel.indicators.hide()
705 hud.hide()
706 }
707 }
708 }
710 Notifications {
711 id: notifications
713 model: NotificationBackend.Model
714 anchors {
715 top: parent.top
716 right: parent.right
717 bottom: parent.bottom
718 leftMargin: units.gu(1)
719 rightMargin: units.gu(1)
720 topMargin: panel.panelHeight + units.gu(1)
721 }
722 states: [
723 State {
724 name: "narrow"
725 when: overlay.width <= units.gu(60)
726 AnchorChanges { target: notifications; anchors.left: parent.left }
727 },
728 State {
729 name: "wide"
730 when: overlay.width > units.gu(60)
731 AnchorChanges { target: notifications; anchors.left: undefined }
732 PropertyChanges { target: notifications; width: units.gu(38) }
733 }
734 ]
735 }
736 }
738 DemoOverlay {
739 id: finalEdgeDemo
741 edge: "none"
742 title: i18n.tr("Well done")
743 text: i18n.tr("You have now mastered the edge gestures and can start using the phone")
744 skipText: i18n.tr("Finish")
745 anchors.fill: overlay
746 visible: false
747 enabled: shell.showEdgeDemo
748 onSkip: {
749 launcher.hide();
750 shell.hideEdgeDemo();
751 }
753 Connections {
754 target: leftEdgeDemo
755 onActiveChanged: if (!leftEdgeDemo.active) finalEdgeDemo.visible = true
756 }
757 }
759 focus: true
761 InputFilterArea {
762 anchors {
763 top: parent.top
764 bottom: parent.bottom
765 left: parent.left
766 }
767 width: shell.edgeSize
768 blockInput: true
769 }
771 InputFilterArea {
772 anchors {
773 top: parent.top
774 bottom: parent.bottom
775 right: parent.right
776 }
777 width: shell.edgeSize
778 blockInput: true
779 }
781 Binding {
782 target: i18n
783 property: "domain"
784 value: "unity8"
785 }
787 //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
788 MouseArea {
789 anchors.bottom: parent.bottom
790 anchors.left: parent.left
791 anchors.right: parent.right
792 height: shell.applicationManager ? shell.applicationManager.keyboardHeight : 0
794 enabled: shell.applicationManager && shell.applicationManager.keyboardVisible
795 }
797 Label {
798 anchors.fill: parent
799 visible: applicationManager.fake
800 text: "EARLY ALPHA\nNOT READY FOR USE"
801 color: "lightgrey"
802 opacity: 0.2
803 font.weight: Font.Black
804 horizontalAlignment: Text.AlignHCenter
805 verticalAlignment: Text.AlignVCenter
806 fontSizeMode: Text.Fit
807 font.pixelSize: height/2
808 rotation: -45
809 }