2 * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
18import AccountsService 0.1
20import Unity.Application 0.1
21import Ubuntu.Components 0.1
22import Ubuntu.Components.Popups 0.1
23import Ubuntu.Gestures 0.1
24import Unity.Launcher 0.1
25import LightDM 0.1 as LightDM
27import SessionBroadcast 0.1
34import Unity.Notifications 1.0 as NotificationBackend
35import Unity.Session 0.1
40 // this is only here to select the width / height of the window if not running fullscreen
41 property bool tablet: false
42 width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
43 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
45 property real edgeSize: units.gu(2)
46 property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
47 property url background
48 readonly property real panelHeight: panel.panelHeight
50 property bool dashShown: dash.shown
52 property bool sideStageEnabled: shell.width >= units.gu(100)
53 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
55 function activateApplication(appId) {
56 if (ApplicationManager.findApplication(appId)) {
57 ApplicationManager.requestFocusApplication(appId);
59 if (stages.locked && ApplicationManager.focusedApplicationId == appId) {
60 applicationsDisplayLoader.item.select(appId);
63 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
64 ApplicationManager.startApplication(appId, execFlags);
71 property: "applicationManager"
72 value: ApplicationManager
75 Component.onCompleted: {
76 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
80 id: backgroundSettings
81 schema.id: "org.gnome.desktop.background"
83 property url gSettingsPicture: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : shell.defaultBackground
84 onGSettingsPictureChanged: {
85 shell.background = gSettingsPicture
92 Keys.onVolumeUpPressed: volumeControl.volumeUp()
93 Keys.onVolumeDownPressed: volumeControl.volumeDown()
98 anchors.rightMargin: stages.overlayWidth
99 clip: stages.overlayMode && !stages.painting
103 blockInput: parent.clip
108 objectName: "underlay"
110 anchors.rightMargin: -parent.anchors.rightMargin
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
125 opacity: dash.disappearingAnimationProgress
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
137 overviewHandleHeight: shell.edgeSize
141 topMargin: panel.panelHeight
144 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
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
155 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
162 direction: Direction.Leftwards
164 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
165 width: shell.edgeSize
167 property real progress: stages.width
170 if (status == DirectionalDragArea.Recognized) {
171 if (ApplicationManager.count == 0) {
172 progress = Math.max(stages.width - stagesDragHandle.width + touchX, stages.width * .3)
174 progress = stages.width - stagesDragHandle.width + touchX
181 if (ApplicationManager.count > 0 && progress < stages.width - units.gu(10)) {
184 stagesDragHandle.progress = stages.width;
193 height: parent.height
197 if (overlayMode || locked || greeter.fakeActiveForApp !== "") {
200 return launcher.progress
202 return stagesDragHandle.progress
206 Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
208 property bool shown: false
210 property real showProgress: overlayMode ? 0 : MathUtils.clamp(1 - x / shell.width, 0, 1)
212 property bool fullyShown: x == 0
213 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
221 function show(focusApp) {
223 panel.indicators.hide();
226 if (!ApplicationManager.focusedApplicationId && ApplicationManager.count > 0 && focusApp) {
227 ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
233 if (ApplicationManager.focusedApplicationId) {
234 ApplicationManager.unfocusCurrentApplication();
239 target: ApplicationManager
242 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
249 onFocusedApplicationIdChanged: {
250 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
253 if (ApplicationManager.focusedApplicationId.length > 0) {
256 if (!stages.overlayMode) {
262 onApplicationAdded: {
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;
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);
408 // Display a dialog to ask the user to confirm.
409 if (!stages.dialogShown) {
410 stages.dialogShown = true;
411 PopupUtils.open(logoutDialog);
415 onShutdownRequested: {
416 // Display a dialog to ask the user to confirm.
417 if (!stages.dialogShown) {
418 stages.dialogShown = true;
419 PopupUtils.open(shutdownDialog);
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
441 source: shell.sideStageEnabled ? "Stages/StageWithSideStage.qml" : "Stages/PhoneStage.qml"
444 target: applicationsDisplayLoader.item
445 property: "objectName"
449 target: applicationsDisplayLoader.item
451 value: !stages.fullyShown
454 target: applicationsDisplayLoader.item
459 target: applicationsDisplayLoader.item
460 property: "dragAreaWidth"
461 value: shell.edgeSize
464 target: applicationsDisplayLoader.item
465 property: "spreadEnabled"
466 value: greeter.fakeActiveForApp === "" // to support emergency dialer hack
473 objectName: "lockscreen"
475 readonly property int backgroundTopMargin: -panel.panelHeight
477 hides: [launcher, panel.indicators]
480 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
481 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
483 x: required ? 0 : - width
485 height: parent.height - panel.panelHeight
486 background: shell.background
490 onEntered: LightDM.Greeter.respond(passphrase);
491 onCancel: greeter.show()
493 greeter.fakeActiveForApp = "dialer-app"
494 shell.activateApplication("dialer-app")
498 onShownChanged: if (shown) greeter.fakeActiveForApp = ""
500 Component.onCompleted: {
501 if (LightDM.Users.count == 1) {
502 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
508 target: LightDM.Greeter
510 onShowGreeter: greeter.show()
513 if (LightDM.Users.count == 1) {
514 // TODO: There's no better way for now to determine if its a PIN or a passphrase.
516 lockscreen.alphaNumeric = false
518 lockscreen.alphaNumeric = true
520 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
525 onAuthenticationComplete: {
526 if (LightDM.Greeter.promptless) {
529 if (LightDM.Greeter.authenticated) {
533 lockscreen.clear(true);
539 target: LightDM.Greeter
541 value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
547 opacity: greeterWrapper.showProgress * 0.8
551 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
556 height: parent.height - panel.panelHeight
559 enabled: !launcher.dashSwipe
563 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
564 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
568 objectName: "greeter"
570 signal sessionStarted() // helpful for tests
572 property string fakeActiveForApp: ""
575 hides: [launcher, panel.indicators]
578 defaultBackground: shell.background
581 height: parent.height
583 dragHandleWidth: shell.edgeSize
587 LightDM.Greeter.startSessionSync();
598 if (!LightDM.Greeter.promptless) {
601 // If there is only one user, we start authenticating with that one here.
602 // If there are more users, the Greeter will handle that
603 if (LightDM.Users.count == 1) {
604 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
606 greeter.fakeActiveForApp = "";
607 greeter.forceActiveFocus();
611 onUnlocked: greeter.hide()
613 // Update launcher items for new user
614 var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
615 AccountsService.user = user;
616 LauncherModel.setUser(user);
619 onTease: launcher.tease()
622 target: ApplicationManager
623 property: "suspended"
624 value: greeter.shown && greeterWrapper.showProgress == 1
631 blockInput: ApplicationManager.focusedApplicationId.length === 0 || greeter.shown || lockscreen.shown || launcher.shown
632 || panel.indicators.shown
639 onDisplayPowerStateChange: {
640 // We ignore any display-off signals when the proximity sensor
641 // is active. This usually indicates something like a phone call.
642 if (status == Powerd.Off && reason != Powerd.Proximity) {
646 // No reason to chew demo CPU when user isn't watching
647 if (status == Powerd.Off) {
648 edgeDemo.paused = true;
649 } else if (status == Powerd.On) {
650 edgeDemo.paused = false;
655 function showHome() {
656 if (edgeDemo.running) {
660 if (LightDM.Greeter.active) {
661 if (!LightDM.Greeter.promptless) {
667 var animate = !LightDM.Greeter.active && !stages.shown
668 dash.setCurrentScope("clickscope", animate, false)
672 function showDash() {
673 if (LightDM.Greeter.active && !LightDM.Greeter.promptless) {
677 if (stages.shown && !stages.overlayMode && !stages.locked) {
681 launcher.switchToNextState("visible");
698 anchors.fill: parent //because this draws indicator menus
701 available: edgeDemo.panelEnabled && greeter.fakeActiveForApp === ""
702 contentEnabled: edgeDemo.panelContentEnabled
703 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
704 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 !== ""
716 height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
722 blockInput: launcher.shown
725 bottom: parent.bottom
728 width: launcher.width
733 objectName: "launcher"
735 readonly property bool dashSwipe: progress > 0
737 anchors.top: parent.top
738 anchors.bottom: parent.bottom
740 dragAreaWidth: shell.edgeSize
741 available: edgeDemo.launcherEnabled && greeter.fakeActiveForApp === ""
743 onShowDashHome: showHome()
745 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
746 onLauncherApplicationSelected: {
747 if (greeter.fakeActiveForApp !== "") {
750 if (!edgeDemo.running)
751 shell.activateApplication(appId)
755 panel.indicators.hide()
761 id: modalNotificationBackground
763 visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
774 blockInput: modalNotificationBackground.visible
781 model: NotificationBackend.Model
786 height: parent.height - panel.panelHeight
791 when: overlay.width <= units.gu(60)
792 AnchorChanges { target: notifications; anchors.left: parent.left }
796 when: overlay.width > units.gu(60)
797 AnchorChanges { target: notifications; anchors.left: undefined }
798 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
840 anchors.topMargin: panel.panelHeight
841 anchors.fill: parent // as needs to know the geometry of the shell
844 //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
846 anchors.bottom: parent.bottom
847 anchors.left: parent.left
848 anchors.right: parent.right
849 height: ApplicationManager.keyboardVisible ? ApplicationManager.keyboardHeight : 0
851 enabled: ApplicationManager.keyboardVisible
855 anchors.centerIn: parent
856 visible: ApplicationManager.fake ? ApplicationManager.fake : false
857 text: "EARLY ALPHA\nNOT READY FOR USE"
860 font.weight: Font.Black
861 horizontalAlignment: Text.AlignHCenter
862 verticalAlignment: Text.AlignVCenter
863 fontSizeMode: Text.Fit
865 scale: Math.min(parent.width, parent.height) / width
873 indicators: panel.indicators
878 target: SessionBroadcast
879 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();
910 id: shutdownFadeOutRectangle
916 NumberAnimation on opacity {
921 if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
922 DBusUnitySessionService.Shutdown();
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list