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.Gestures 0.1
23import Unity.Launcher 0.1
25import LightDM 0.1 as LightDM
27import SessionBroadcast 0.1
35import Unity.Notifications 1.0 as NotificationBackend
36import Unity.Session 0.1
41 // this is only here to select the width / height of the window if not running fullscreen
42 property bool tablet: false
43 width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
44 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
46 property real edgeSize: units.gu(2)
47 property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
48 property url background
49 readonly property real panelHeight: panel.panelHeight
51 property bool dashShown: dash.shown && dash.available && underlay.visible
53 property bool sideStageEnabled: shell.width >= units.gu(100)
54 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
56 function activateApplication(appId) {
57 if (ApplicationManager.findApplication(appId)) {
58 ApplicationManager.requestFocusApplication(appId);
60 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
61 ApplicationManager.startApplication(appId, execFlags);
68 property: "applicationManager"
69 value: ApplicationManager
72 Component.onCompleted: {
73 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
77 id: backgroundSettings
78 schema.id: "org.gnome.desktop.background"
80 property url gSettingsPicture: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : shell.defaultBackground
81 onGSettingsPictureChanged: {
82 shell.background = gSettingsPicture
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; }
95 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
96 dialogs.onPowerKeyPressed();
97 event.accepted = true;
99 event.accepted = false;
104 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
105 dialogs.onPowerKeyReleased();
106 event.accepted = true;
108 event.accepted = false;
115 objectName: "underlay"
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
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
133 overviewHandleHeight: shell.edgeSize
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 }}
151 direction: Direction.Leftwards
153 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
154 width: shell.edgeSize
156 property real progress: stages.width
159 if (status == DirectionalDragArea.Recognized) {
160 if (ApplicationManager.empty) {
161 progress = Math.max(stages.width - stagesDragArea.width + touchX, stages.width * .3);
163 progress = stages.width - stagesDragArea.width + touchX;
170 if (!ApplicationManager.empty && progress < stages.width - units.gu(10)) {
173 stagesDragArea.progress = Qt.binding(function () { return stages.width; });
182 height: parent.height
184 visible: !fullyHidden && !ApplicationManager.empty
188 if (locked || greeter.fakeActiveForApp !== "") {
191 return launcher.progress;
193 return stagesDragArea.progress
196 Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
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.
215 property real showProgress: shell.width ? MathUtils.clamp(1 - x / shell.width, 0, 1) : 0
217 property bool fullyShown: x == 0
218 property bool fullyHidden: x == width
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)
234 target: ApplicationManager
236 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
243 onFocusedApplicationIdChanged: {
244 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
247 panel.indicators.hide();
250 onApplicationAdded: {
260 if (ApplicationManager.empty) {
267 id: applicationsDisplayLoader
270 source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
273 target: applicationsDisplayLoader.item
274 property: "objectName"
278 target: applicationsDisplayLoader.item
279 property: "dragAreaWidth"
280 value: shell.edgeSize
283 target: applicationsDisplayLoader.item
284 property: "maximizedAppTopMargin"
285 // Not just using panel.panelHeight as that changes depending on the focused app.
286 value: panel.indicators.panelHeight
289 target: applicationsDisplayLoader.item
290 property: "interactive"
291 value: stages.roughlyFullyShown && !greeter.shown && !lockscreen.shown
292 && panel.indicators.fullyClosed
295 target: applicationsDisplayLoader.item
296 property: "spreadEnabled"
297 value: greeter.fakeActiveForApp === "" // to support emergency dialer hack
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
331 objectName: "lockscreen"
333 readonly property int backgroundTopMargin: -panel.panelHeight
335 hides: [launcher, panel.indicators]
338 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
339 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
343 height: parent.height - panel.panelHeight
344 background: shell.background
345 alphaNumeric: AccountsService.passwordDisplayHint === AccountsService.Keyboard
349 onEntered: LightDM.Greeter.respond(passphrase);
350 onCancel: greeter.show()
352 greeter.fakeActiveForApp = "dialer-app"
353 shell.activateApplication("dialer-app")
357 onShownChanged: if (shown) greeter.fakeActiveForApp = ""
359 Component.onCompleted: {
360 if (greeter.narrowMode) {
361 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
367 target: LightDM.Greeter
369 onShowGreeter: greeter.show()
372 if (greeter.narrowMode) {
373 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text.toLowerCase());
378 onPromptlessChanged: {
379 if (LightDM.Greeter.promptless) {
387 onAuthenticationComplete: {
388 if (LightDM.Greeter.promptless) {
391 if (LightDM.Greeter.authenticated) {
395 lockscreen.clear(true);
396 if (greeter.narrowMode) {
397 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
404 target: LightDM.Greeter
406 value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
412 opacity: greeterWrapper.showProgress * 0.8
416 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
421 height: parent.height - panel.panelHeight
424 enabled: !launcher.dashSwipe
428 property bool fullyShown: showProgress === 1.0
429 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
430 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
434 objectName: "greeter"
436 signal sessionStarted() // helpful for tests
438 property string fakeActiveForApp: ""
441 hides: [launcher, panel.indicators]
444 defaultBackground: shell.background
447 height: parent.height
449 dragHandleWidth: shell.edgeSize
453 if (LightDM.Greeter.startSessionSync()) {
464 if (greeter.narrowMode) {
465 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
467 if (!LightDM.Greeter.promptless) {
471 greeter.fakeActiveForApp = "";
472 greeter.forceActiveFocus();
476 onUnlocked: greeter.hide()
478 // Update launcher items for new user
479 var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
480 AccountsService.user = user;
481 LauncherModel.setUser(user);
484 onTease: launcher.tease()
487 target: ApplicationManager
488 property: "suspended"
489 value: greeter.shown && greeterWrapper.showProgress == 1
498 onDisplayPowerStateChange: {
499 // We ignore any display-off signals when the proximity sensor
500 // is active. This usually indicates something like a phone call.
501 if (status == Powerd.Off && reason != Powerd.Proximity) {
505 // No reason to chew demo CPU when user isn't watching
506 if (status == Powerd.Off) {
507 edgeDemo.paused = true;
508 } else if (status == Powerd.On) {
509 edgeDemo.paused = false;
514 function showHome() {
515 if (edgeDemo.running) {
519 if (LightDM.Greeter.active) {
520 if (!LightDM.Greeter.promptless) {
526 var animate = !LightDM.Greeter.active && !stages.shown
527 dash.setCurrentScope("clickscope", animate, false)
531 function showDash() {
532 if (LightDM.Greeter.active && !LightDM.Greeter.promptless) {
536 if (!stages.locked) {
540 launcher.switchToNextState("visible");
558 anchors.fill: parent //because this draws indicator menus
561 available: edgeDemo.panelEnabled && greeter.fakeActiveForApp === ""
562 contentEnabled: edgeDemo.panelContentEnabled
563 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
564 panelHeight: units.gu(3)
567 property bool topmostApplicationIsFullscreen:
568 ApplicationManager.focusedApplicationId &&
569 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
571 fullscreenMode: (stages.roughlyFullyShown && topmostApplicationIsFullscreen
572 && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== ""
577 objectName: "launcher"
579 readonly property bool dashSwipe: progress > 0
581 anchors.top: parent.top
582 anchors.bottom: parent.bottom
584 dragAreaWidth: shell.edgeSize
585 available: edgeDemo.launcherEnabled && greeter.fakeActiveForApp === ""
587 onShowDashHome: showHome()
589 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
590 onLauncherApplicationSelected: {
591 if (greeter.fakeActiveForApp !== "") {
594 if (!edgeDemo.running)
595 shell.activateApplication(appId)
599 panel.indicators.hide()
605 id: modalNotificationBackground
607 visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
620 model: NotificationBackend.Model
625 height: parent.height - panel.panelHeight
630 when: overlay.width <= units.gu(60)
631 AnchorChanges { target: notifications; anchors.left: parent.left }
635 when: overlay.width > units.gu(60)
636 AnchorChanges { target: notifications; anchors.left: undefined }
637 PropertyChanges { target: notifications; width: units.gu(38) }
654 shutdownFadeOutRectangle.enabled = true;
655 shutdownFadeOutRectangle.visible = true;
656 shutdownFadeOut.start();
661 id: alphaDisclaimerLabel
662 anchors.centerIn: parent
663 visible: ApplicationManager.fake ? ApplicationManager.fake : false
665 text: "EARLY ALPHA\nNOT READY FOR USE"
668 font.weight: Font.Black
669 horizontalAlignment: Text.AlignHCenter
670 verticalAlignment: Text.AlignVCenter
671 fontSizeMode: Text.Fit
673 scale: Math.min(parent.width, parent.height) / width
678 z: alphaDisclaimerLabel.z + 10
682 indicators: panel.indicators
687 target: SessionBroadcast
688 onShowHome: showHome()
692 id: shutdownFadeOutRectangle
699 NumberAnimation on opacity {
704 if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
705 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