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
130 source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png"
131 fillMode: Image.PreserveAspectCrop
132 horizontalAlignment: Image.AlignRight
133 verticalAlignment: Image.AlignTop
140 available: !LightDM.Greeter.active
141 hides: [stages, launcher, panel.indicators]
142 shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
143 enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
147 topMargin: panel.panelHeight
150 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
151 opacity: 1.0 - disappearingAnimationProgress
152 property real disappearingAnimationProgress: {
153 if (stages.overlayMode) {
156 return stages.showProgress
160 // FIXME: only necessary because stages.showProgress is not animated
161 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
168 direction: Direction.Leftwards
170 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
171 width: shell.edgeSize
173 property real progress: stages.width
176 if (status == DirectionalDragArea.Recognized) {
177 if (ApplicationManager.count == 0) {
178 progress = Math.max(stages.width - stagesDragHandle.width + touchX, stages.width * .3)
180 progress = stages.width - stagesDragHandle.width + touchX
187 if (ApplicationManager.count > 0 && progress < stages.width - units.gu(10)) {
190 stagesDragHandle.progress = stages.width;
199 height: parent.height
203 if (overlayMode || locked || greeter.fakeActiveForApp !== "") {
206 return launcher.progress
208 return stagesDragHandle.progress
212 Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
214 property bool shown: false
216 property real showProgress: overlayMode ? 0 : MathUtils.clamp(1 - x / shell.width, 0, 1)
218 property bool fullyShown: x == 0
219 property bool fullyHidden: x == width
221 property bool painting: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.painting : false
222 property bool fullscreen: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.fullscreen : false
223 property bool overlayMode: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.overlayMode : false
224 property int overlayWidth: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.overlayWidth : false
225 property bool locked: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.locked : false
227 function show(focusApp) {
229 panel.indicators.hide();
232 if (!ApplicationManager.focusedApplicationId && ApplicationManager.count > 0 && focusApp) {
233 ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
239 if (ApplicationManager.focusedApplicationId) {
240 ApplicationManager.unfocusCurrentApplication();
245 target: ApplicationManager
248 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
255 onFocusedApplicationIdChanged: {
256 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
259 if (ApplicationManager.focusedApplicationId.length > 0) {
262 if (!stages.overlayMode) {
268 onApplicationAdded: {
272 onApplicationRemoved: {
273 if (ApplicationManager.focusedApplicationId.length == 0) {
279 property bool dialogShown: false
286 text: "Are you sure that you want to logout?"
290 PopupUtils.close(dialogueLogout);
291 stages.dialogShown = false;
297 DBusUnitySessionService.Logout();
298 PopupUtils.close(dialogueLogout);
299 stages.dialogShown = false;
310 text: "Are you sure that you want to shutdown?"
314 PopupUtils.close(dialogueShutdown);
315 stages.dialogShown = false;
321 dBusUnitySessionServiceConnection.closeAllApps();
322 DBusUnitySessionService.Shutdown();
323 PopupUtils.close(dialogueShutdown);
324 stages.dialogShown = false;
335 text: "Are you sure that you want to reboot?"
339 PopupUtils.close(dialogueReboot)
340 stages.dialogShown = false;
346 dBusUnitySessionServiceConnection.closeAllApps();
347 DBusUnitySessionService.Reboot();
348 PopupUtils.close(dialogueReboot);
349 stages.dialogShown = false;
360 text: i18n.tr("Are you sure you would like to turn power off?")
362 text: i18n.tr("Power off")
364 dBusUnitySessionServiceConnection.closeAllApps();
365 PopupUtils.close(dialoguePower);
366 stages.dialogShown = false;
367 shutdownFadeOutRectangle.enabled = true;
368 shutdownFadeOutRectangle.visible = true;
369 shutdownFadeOut.start();
373 text: i18n.tr("Restart")
375 dBusUnitySessionServiceConnection.closeAllApps();
376 DBusUnitySessionService.Reboot();
377 PopupUtils.close(dialoguePower);
378 stages.dialogShown = false;
382 text: i18n.tr("Cancel")
384 PopupUtils.close(dialoguePower);
385 stages.dialogShown = false;
391 function showPowerDialog() {
392 if (!stages.dialogShown) {
393 stages.dialogShown = true;
394 PopupUtils.open(powerDialog);
399 id: dBusUnitySessionServiceConnection
400 objectName: "dBusUnitySessionServiceConnection"
401 target: DBusUnitySessionService
403 function closeAllApps() {
405 var app = ApplicationManager.get(0);
409 ApplicationManager.stopApplication(app.appId);
414 // Display a dialog to ask the user to confirm.
415 if (!stages.dialogShown) {
416 stages.dialogShown = true;
417 PopupUtils.open(logoutDialog);
421 onShutdownRequested: {
422 // Display a dialog to ask the user to confirm.
423 if (!stages.dialogShown) {
424 stages.dialogShown = true;
425 PopupUtils.open(shutdownDialog);
430 // Display a dialog to ask the user to confirm.
431 if (!stages.dialogShown) {
432 stages.dialogShown = true;
433 PopupUtils.open(rebootDialog);
444 id: applicationsDisplayLoader
447 source: shell.sideStageEnabled ? "Stages/StageWithSideStage.qml" : "Stages/PhoneStage.qml"
450 target: applicationsDisplayLoader.item
451 property: "objectName"
455 target: applicationsDisplayLoader.item
457 value: !stages.fullyShown
460 target: applicationsDisplayLoader.item
465 target: applicationsDisplayLoader.item
466 property: "dragAreaWidth"
467 value: shell.edgeSize
470 target: applicationsDisplayLoader.item
471 property: "spreadEnabled"
472 value: greeter.fakeActiveForApp === "" // to support emergency dialer hack
479 objectName: "lockscreen"
481 readonly property int backgroundTopMargin: -panel.panelHeight
483 hides: [launcher, panel.indicators]
486 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
487 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
489 x: required ? 0 : - width
491 height: parent.height - panel.panelHeight
492 background: shell.background
496 onEntered: LightDM.Greeter.respond(passphrase);
497 onCancel: greeter.show()
499 greeter.fakeActiveForApp = "dialer-app"
500 shell.activateApplication("dialer-app")
504 onShownChanged: if (shown) greeter.fakeActiveForApp = ""
506 Component.onCompleted: {
507 if (LightDM.Users.count == 1) {
508 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
514 target: LightDM.Greeter
516 onShowGreeter: greeter.show()
519 if (LightDM.Users.count == 1) {
520 // TODO: There's no better way for now to determine if its a PIN or a passphrase.
522 lockscreen.alphaNumeric = false
524 lockscreen.alphaNumeric = true
526 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
531 onAuthenticationComplete: {
532 if (LightDM.Greeter.promptless) {
535 if (LightDM.Greeter.authenticated) {
539 lockscreen.clear(true);
545 target: LightDM.Greeter
547 value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
553 opacity: greeterWrapper.showProgress * 0.8
557 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
562 height: parent.height - panel.panelHeight
565 enabled: !launcher.dashSwipe
569 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
570 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
574 objectName: "greeter"
576 signal sessionStarted() // helpful for tests
578 property string fakeActiveForApp: ""
581 hides: [launcher, panel.indicators]
584 defaultBackground: shell.background
587 height: parent.height
589 dragHandleWidth: shell.edgeSize
593 LightDM.Greeter.startSessionSync();
604 if (!LightDM.Greeter.promptless) {
607 // If there is only one user, we start authenticating with that one here.
608 // If there are more users, the Greeter will handle that
609 if (LightDM.Users.count == 1) {
610 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
612 greeter.fakeActiveForApp = "";
613 greeter.forceActiveFocus();
617 onUnlocked: greeter.hide()
619 // Update launcher items for new user
620 var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
621 AccountsService.user = user;
622 LauncherModel.setUser(user);
625 onTease: launcher.tease()
628 target: ApplicationManager
629 property: "suspended"
630 value: greeter.shown && greeterWrapper.showProgress == 1
637 blockInput: ApplicationManager.focusedApplicationId.length === 0 || greeter.shown || lockscreen.shown || launcher.shown
638 || panel.indicators.shown
645 onDisplayPowerStateChange: {
646 // We ignore any display-off signals when the proximity sensor
647 // is active. This usually indicates something like a phone call.
648 if (status == Powerd.Off && reason != Powerd.Proximity) {
652 // No reason to chew demo CPU when user isn't watching
653 if (status == Powerd.Off) {
654 edgeDemo.paused = true;
655 } else if (status == Powerd.On) {
656 edgeDemo.paused = false;
661 function showHome() {
662 if (edgeDemo.running) {
666 if (LightDM.Greeter.active) {
667 if (!LightDM.Greeter.promptless) {
673 var animate = !LightDM.Greeter.active && !stages.shown
674 dash.setCurrentScope("clickscope", animate, false)
678 function showDash() {
679 if (LightDM.Greeter.active && !LightDM.Greeter.promptless) {
683 if (stages.shown && !stages.overlayMode && !stages.locked) {
687 launcher.switchToNextState("visible");
704 anchors.fill: parent //because this draws indicator menus
707 available: edgeDemo.panelEnabled && greeter.fakeActiveForApp === ""
708 contentEnabled: edgeDemo.panelContentEnabled
709 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
710 panelHeight: units.gu(3)
712 property string focusedAppId: ApplicationManager.focusedApplicationId
713 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
714 fullscreenMode: (focusedApplication && stages.fullscreen && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== ""
722 height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
728 blockInput: launcher.shown
731 bottom: parent.bottom
734 width: launcher.width
739 objectName: "launcher"
741 readonly property bool dashSwipe: progress > 0
743 anchors.top: parent.top
744 anchors.bottom: parent.bottom
746 dragAreaWidth: shell.edgeSize
747 available: edgeDemo.launcherEnabled && greeter.fakeActiveForApp === ""
749 onShowDashHome: showHome()
751 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
752 onLauncherApplicationSelected: {
753 if (greeter.fakeActiveForApp !== "") {
756 if (!edgeDemo.running)
757 shell.activateApplication(appId)
761 panel.indicators.hide()
767 id: modalNotificationBackground
769 visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
780 blockInput: modalNotificationBackground.visible
787 model: NotificationBackend.Model
792 height: parent.height - panel.panelHeight
797 when: overlay.width <= units.gu(60)
798 AnchorChanges { target: notifications; anchors.left: parent.left }
802 when: overlay.width > units.gu(60)
803 AnchorChanges { target: notifications; anchors.left: undefined }
804 PropertyChanges { target: notifications; width: units.gu(38) }
809 anchors { left: parent.left; right: parent.right }
810 height: parent.contentHeight
811 blockInput: height > 0
817 onFocusChanged: if (!focus) forceActiveFocus();
822 bottom: parent.bottom
825 width: shell.edgeSize
832 bottom: parent.bottom
835 width: shell.edgeSize
846 anchors.topMargin: panel.panelHeight
847 anchors.fill: parent // as needs to know the geometry of the shell
850 //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
852 anchors.bottom: parent.bottom
853 anchors.left: parent.left
854 anchors.right: parent.right
855 height: ApplicationManager.keyboardVisible ? ApplicationManager.keyboardHeight : 0
857 enabled: ApplicationManager.keyboardVisible
861 anchors.centerIn: parent
862 visible: ApplicationManager.fake ? ApplicationManager.fake : false
863 text: "EARLY ALPHA\nNOT READY FOR USE"
866 font.weight: Font.Black
867 horizontalAlignment: Text.AlignHCenter
868 verticalAlignment: Text.AlignVCenter
869 fontSizeMode: Text.Fit
871 scale: Math.min(parent.width, parent.height) / width
879 indicators: panel.indicators
884 target: SessionBroadcast
885 onShowHome: showHome()
889 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
890 if (!powerKeyTimer.running) {
891 powerKeyTimer.start();
893 event.accepted = true;
898 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
899 powerKeyTimer.stop();
900 event.accepted = true;
908 triggeredOnStart: false
911 stages.showPowerDialog();
916 id: shutdownFadeOutRectangle
922 NumberAnimation on opacity {
927 if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
928 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