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
125 source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png"
126 fillMode: Image.PreserveAspectCrop
127 horizontalAlignment: Image.AlignRight
128 verticalAlignment: Image.AlignTop
135 available: !LightDM.Greeter.active
136 hides: [stages, launcher, panel.indicators]
137 shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0 &&
138 !(panel.indicators.fullyOpened && !sideStageEnabled)
139 enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
143 topMargin: panel.panelHeight
146 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
147 opacity: 1.0 - disappearingAnimationProgress
148 property real disappearingAnimationProgress: stages.showProgress
150 // FIXME: only necessary because stages.showProgress is not animated
151 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
157 direction: Direction.Leftwards
159 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
160 width: shell.edgeSize
162 property real progress: stages.width
165 if (status == DirectionalDragArea.Recognized) {
166 if (ApplicationManager.empty) {
167 progress = Math.max(stages.width - stagesDragArea.width + touchX, stages.width * .3);
169 progress = stages.width - stagesDragArea.width + touchX;
176 if (!ApplicationManager.empty && progress < stages.width - units.gu(10)) {
179 stagesDragArea.progress = Qt.binding(function () { return stages.width; });
188 height: parent.height
190 visible: !fullyHidden && !ApplicationManager.empty
194 if (locked || greeter.fakeActiveForApp !== "") {
197 return launcher.progress;
199 return stagesDragArea.progress
202 Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
204 property bool shown: false
207 if (ApplicationManager.count > 0) {
208 ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
211 if (ApplicationManager.focusedApplicationId) {
212 ApplicationManager.updateScreenshot(ApplicationManager.focusedApplicationId);
213 ApplicationManager.unfocusCurrentApplication();
218 // Avoid a silent "divide by zero -> NaN" situation during init as shell.width will be
219 // zero. That breaks the property binding and the function won't be reevaluated once
220 // shell.width is set, with the NaN result staying there for good.
221 property real showProgress: shell.width ? MathUtils.clamp(1 - x / shell.width, 0, 1) : 0
223 property bool fullyShown: x == 0
224 property bool fullyHidden: x == width
226 property bool locked: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.locked : false
228 // It might technically not be fullyShown but visually it just looks so.
229 property bool roughlyFullyShown: x >= 0 && x <= units.gu(1)
240 target: ApplicationManager
242 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
249 onFocusedApplicationIdChanged: {
250 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
253 panel.indicators.hide();
256 onApplicationAdded: {
266 if (ApplicationManager.empty) {
273 id: applicationsDisplayLoader
276 source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
279 target: applicationsDisplayLoader.item
280 property: "objectName"
284 target: applicationsDisplayLoader.item
285 property: "dragAreaWidth"
286 value: shell.edgeSize
289 target: applicationsDisplayLoader.item
290 property: "maximizedAppTopMargin"
291 // Not just using panel.panelHeight as that changes depending on the focused app.
292 value: panel.indicators.panelHeight
295 target: applicationsDisplayLoader.item
296 property: "interactive"
297 value: stages.roughlyFullyShown && !greeter.shown && !lockscreen.shown
298 && panel.indicators.fullyClosed
301 target: applicationsDisplayLoader.item
302 property: "spreadEnabled"
303 value: greeter.fakeActiveForApp === "" // to support emergency dialer hack
310 objectName: "inputMethod"
311 anchors { fill: parent; topMargin: panel.panelHeight }
312 z: notifications.useModal || panel.indicators.shown ? overlay.z + 1 : overlay.z - 1
316 target: SurfaceManager
318 if (surface.type == MirSurfaceItem.InputMethod) {
319 inputMethod.surface = surface;
323 onSurfaceDestroyed: {
324 if (inputMethod.surface == surface) {
325 inputMethod.surface = null;
326 surface.parent = null;
328 if (!surface.parent) {
329 // there's no one displaying it. delete it right away
337 objectName: "lockscreen"
339 readonly property int backgroundTopMargin: -panel.panelHeight
341 hides: [launcher, panel.indicators]
344 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
345 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
349 height: parent.height - panel.panelHeight
350 background: shell.background
351 alphaNumeric: AccountsService.passwordDisplayHint === AccountsService.Keyboard
355 onEntered: LightDM.Greeter.respond(passphrase);
356 onCancel: greeter.show()
358 greeter.fakeActiveForApp = "dialer-app"
359 shell.activateApplication("dialer-app")
363 onShownChanged: if (shown) greeter.fakeActiveForApp = ""
365 Component.onCompleted: {
366 if (greeter.narrowMode) {
367 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
373 target: LightDM.Greeter
375 onShowGreeter: greeter.show()
378 if (greeter.narrowMode) {
379 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text.toLowerCase());
384 onPromptlessChanged: {
385 if (LightDM.Greeter.promptless) {
393 onAuthenticationComplete: {
394 if (LightDM.Greeter.promptless) {
397 if (LightDM.Greeter.authenticated) {
401 lockscreen.clear(true);
402 if (greeter.narrowMode) {
403 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
410 target: LightDM.Greeter
412 value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
418 opacity: greeterWrapper.showProgress * 0.8
422 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
427 height: parent.height - panel.panelHeight
430 enabled: !launcher.dashSwipe
434 property bool fullyShown: showProgress === 1.0
435 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
436 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
440 objectName: "greeter"
442 signal sessionStarted() // helpful for tests
444 property string fakeActiveForApp: ""
447 hides: [launcher, panel.indicators]
450 defaultBackground: shell.background
453 height: parent.height
455 dragHandleWidth: shell.edgeSize
459 if (LightDM.Greeter.startSessionSync()) {
470 if (greeter.narrowMode) {
471 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
473 if (!LightDM.Greeter.promptless) {
477 greeter.fakeActiveForApp = "";
478 greeter.forceActiveFocus();
482 onUnlocked: greeter.hide()
484 // Update launcher items for new user
485 var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
486 AccountsService.user = user;
487 LauncherModel.setUser(user);
490 onTease: launcher.tease()
493 target: ApplicationManager
494 property: "suspended"
495 value: greeter.shown && greeterWrapper.showProgress == 1
504 onDisplayPowerStateChange: {
505 // We ignore any display-off signals when the proximity sensor
506 // is active. This usually indicates something like a phone call.
507 if (status == Powerd.Off && reason != Powerd.Proximity) {
511 // No reason to chew demo CPU when user isn't watching
512 if (status == Powerd.Off) {
513 edgeDemo.paused = true;
514 } else if (status == Powerd.On) {
515 edgeDemo.paused = false;
520 function showHome() {
521 if (edgeDemo.running) {
525 if (LightDM.Greeter.active) {
526 if (!LightDM.Greeter.promptless) {
532 var animate = !LightDM.Greeter.active && !stages.shown
533 dash.setCurrentScope("clickscope", animate, false)
537 function showDash() {
538 if (LightDM.Greeter.active && !LightDM.Greeter.promptless) {
542 if (!stages.locked) {
546 launcher.switchToNextState("visible");
564 anchors.fill: parent //because this draws indicator menus
567 available: edgeDemo.panelEnabled && greeter.fakeActiveForApp === ""
568 contentEnabled: edgeDemo.panelContentEnabled
569 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
570 panelHeight: units.gu(3)
573 property bool topmostApplicationIsFullscreen:
574 ApplicationManager.focusedApplicationId &&
575 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
577 fullscreenMode: (stages.roughlyFullyShown && topmostApplicationIsFullscreen
578 && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== ""
583 objectName: "launcher"
585 readonly property bool dashSwipe: progress > 0
587 anchors.top: parent.top
588 anchors.bottom: parent.bottom
590 dragAreaWidth: shell.edgeSize
591 available: edgeDemo.launcherEnabled && greeter.fakeActiveForApp === ""
593 onShowDashHome: showHome()
595 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
596 onLauncherApplicationSelected: {
597 if (greeter.fakeActiveForApp !== "") {
600 if (!edgeDemo.running)
601 shell.activateApplication(appId)
605 panel.indicators.hide()
611 id: modalNotificationBackground
613 visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
626 model: NotificationBackend.Model
631 height: parent.height - panel.panelHeight
636 when: overlay.width <= units.gu(60)
637 AnchorChanges { target: notifications; anchors.left: parent.left }
641 when: overlay.width > units.gu(60)
642 AnchorChanges { target: notifications; anchors.left: undefined }
643 PropertyChanges { target: notifications; width: units.gu(38) }
660 shutdownFadeOutRectangle.enabled = true;
661 shutdownFadeOutRectangle.visible = true;
662 shutdownFadeOut.start();
667 id: alphaDisclaimerLabel
668 anchors.centerIn: parent
669 visible: ApplicationManager.fake ? ApplicationManager.fake : false
671 text: "EARLY ALPHA\nNOT READY FOR USE"
674 font.weight: Font.Black
675 horizontalAlignment: Text.AlignHCenter
676 verticalAlignment: Text.AlignVCenter
677 fontSizeMode: Text.Fit
679 scale: Math.min(parent.width, parent.height) / width
684 z: alphaDisclaimerLabel.z + 10
688 indicators: panel.indicators
693 target: SessionBroadcast
694 onShowHome: showHome()
698 id: shutdownFadeOutRectangle
705 NumberAnimation on opacity {
710 if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
711 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