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 Ubuntu.Application 0.1
19import Ubuntu.Components 0.1
20import Ubuntu.Gestures 0.1
21import LightDM 0.1 as LightDM
22import AccountsService 0.1
29import "Components/Math.js" as MathLocal
33import Unity.Notifications 1.0 as NotificationBackend
38 // this is only here to select the width / height of the window if not running fullscreen
39 property bool tablet: false
40 width: tablet ? units.gu(160) : units.gu(40)
41 height: tablet ? units.gu(100) : units.gu(71)
43 property real edgeSize: units.gu(2)
44 property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
45 property url background: default_background
46 readonly property real panelHeight: panel.panelHeight
48 property bool dashShown: dash.shown
49 property bool stageScreenshotsReady: {
50 if (sideStage.shown) {
51 if (mainStage.applications.count > 0) {
52 return mainStage.usingScreenshots && sideStage.usingScreenshots;
54 return sideStage.usingScreenshots;
57 return mainStage.usingScreenshots;
61 property bool showEdgeDemo: true
62 property bool showEdgeDemoInGreeter: showEdgeDemo //AccountsService.getUserProperty("lightdm", "demo-edges")
64 function hideEdgeDemo() {
65 var user = LightDM.Users.data(greeter.currentIndex, LightDM.UserRoles.NameRole);
66 AccountsService.setUserProperty(user, "demo-edges", false);
67 shell.showEdgeDemo = false;
69 function hideEdgeDemoInGreeter() {
70 //AccountsService.setUserProperty("lightdm", "demo-edges", false);
71 shell.showEdgeDemoInGreeter = false;
74 property ListModel searchHistory: SearchHistoryModel {}
76 property var applicationManager: ApplicationManagerWrapper {}
78 Component.onCompleted: {
79 applicationManager.sideStageEnabled = Qt.binding(function() { return sideStage.enabled })
81 // FIXME: if application focused before shell starts, shell draws on top of it only.
82 // We should detect already running applications on shell start and bring them to the front.
83 applicationManager.unfocusCurrentApplication();
86 readonly property bool fullscreenMode: {
87 if (greeter.shown || lockscreen.shown) {
89 } else if (mainStage.usingScreenshots) { // Window Manager animating so want to re-evaluate fullscreen mode
90 return mainStage.switchingFromFullscreenToFullscreen;
91 } else if (applicationManager.mainStageFocusedApplication) {
92 return applicationManager.mainStageFocusedApplication.fullscreen;
99 target: applicationManager
100 ignoreUnknownSignals: true
102 // TODO: this should be protected to only unlock for certain applications / certain usecases
103 // potentially only in connection with a notification
105 shell.activateApplication(desktopFile);
109 function activateApplication(desktopFile, argument) {
110 if (applicationManager) {
111 // For newly started applications, as it takes them time to draw their first frame
112 // we add a delay before we hide the animation screenshots to compensate.
113 var addDelay = !applicationManager.getApplicationFromDesktopFile(desktopFile);
116 application = applicationManager.activateApplication(desktopFile, argument);
117 if (application == null) {
120 if (application.stage == ApplicationInfo.MainStage || !sideStage.enabled) {
121 mainStage.activateApplication(desktopFile, addDelay);
123 sideStage.activateApplication(desktopFile, addDelay);
133 Keys.onVolumeUpPressed: volumeControl.volumeUp()
134 Keys.onVolumeDownPressed: volumeControl.volumeDown()
137 if (event.key == Qt.Key_PowerOff) {
145 visible: !(panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth)
146 && (stages.fullyHidden
147 || (stages.fullyShown && mainStage.usingScreenshots)
148 || !stages.fullyShown && (mainStage.usingScreenshots || (sideStage.shown && sideStage.usingScreenshots)))
152 source: shell.background
153 sourceSize.width: parent.width
154 sourceSize.height: parent.height
161 opacity: dash.disappearingAnimationProgress
167 available: !greeter.shown && !lockscreen.shown
168 hides: [stages, launcher, panel.indicators]
169 shown: disappearingAnimationProgress !== 1.0
170 enabled: disappearingAnimationProgress === 0.0 && !leftEdgeDemo.visible && !topEdgeDemo.visible
171 // FIXME: unfocus all applications when going back to the dash
174 shell.applicationManager.unfocusCurrentApplication()
180 topMargin: panel.panelHeight
183 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
184 opacity: 1.0 - disappearingAnimationProgress
185 property real disappearingAnimationProgress: {
187 return greeter.showProgress;
189 return stagesOuterContainer.showProgress;
193 // FIXME: only necessary because stagesRevealer.animatedProgress and
194 // greeterRevealer.animatedProgress are not animated
195 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
202 title: i18n.tr("Top edge")
203 text: i18n.tr("Try swiping from the top edge to access the indicators")
206 enabled: shell.showEdgeDemo
207 onSkip: shell.hideEdgeDemo()
211 onShownChanged: if (!greeter.shown) topEdgeDemo.visible = true
215 target: panel.indicators
216 onFullyOpenedChanged: if (panel.indicators.fullyOpened) topEdgeDemo.visible = false
224 title: i18n.tr("Left edge")
225 text: i18n.tr("Swipe from the left to reveal the launcher for quick access to apps")
228 enabled: shell.showEdgeDemo
229 onSkip: shell.hideEdgeDemo()
232 target: bottomEdgeDemo
233 onVisibleChanged: if (!bottomEdgeDemo.visible) leftEdgeDemo.visible = true
239 if (launcher.progress >= 1.0) {
240 leftEdgeDemo.visible = false;
241 shell.hideEdgeDemo();
250 id: stagesOuterContainer
253 height: parent.height
255 Behavior on x {SmoothedAnimation{velocity: 600}}
257 property real showProgress:
258 MathLocal.clamp(1 - (x + stages.x) / shell.width, 0, 1)
265 property bool fullyShown: shown && x == 0 && parent.x == 0
266 property bool fullyHidden: !shown && x == width
267 available: !greeter.shown
268 hides: [launcher, panel.indicators]
271 showAnimation: StandardAnimation { property: "x"; duration: 350; to: 0; easing.type: Easing.OutCubic }
272 hideAnimation: StandardAnimation { property: "x"; duration: 350; to: width; easing.type: Easing.OutCubic }
275 height: parent.height
277 // close the stages when no focused application remains
279 target: shell.applicationManager
280 onMainStageFocusedApplicationChanged: stages.closeIfNoApplications()
281 onSideStageFocusedApplicationChanged: stages.closeIfNoApplications()
282 ignoreUnknownSignals: true
285 function closeIfNoApplications() {
286 if (!shell.applicationManager.mainStageFocusedApplication
287 && !shell.applicationManager.sideStageFocusedApplication
288 && shell.applicationManager.mainStageApplications.count == 0
289 && shell.applicationManager.sideStageApplications.count == 0) {
294 // show the stages when an application gets the focus
296 target: shell.applicationManager
297 onMainStageFocusedApplicationChanged: {
298 if (shell.applicationManager.mainStageFocusedApplication) {
303 onSideStageFocusedApplicationChanged: {
304 if (shell.applicationManager.sideStageFocusedApplication) {
309 ignoreUnknownSignals: true
317 fullyShown: stages.fullyShown
318 shouldUseScreenshots: !fullyShown
319 rightEdgeEnabled: !sideStage.enabled
321 applicationManager: shell.applicationManager
322 rightEdgeDraggingAreaWidth: shell.edgeSize
323 normalApplicationY: shell.panelHeight
332 // FIXME: workaround the fact that focusing a main stage application
333 // raises its surface on top of all other surfaces including the ones
334 // that belong to side stage applications.
335 onFocusedApplicationChanged: {
336 if (focusedApplication && sideStage.focusedApplication && sideStage.fullyShown) {
337 shell.applicationManager.focusApplication(sideStage.focusedApplication);
345 applicationManager: shell.applicationManager
346 rightEdgeDraggingAreaWidth: shell.edgeSize
347 normalApplicationY: shell.panelHeight
350 if (!shown && mainStage.applications.count == 0) {
354 // FIXME: when hiding the side stage, refocus the main stage
355 // application so that it goes in front of the side stage
356 // application and hides it
357 onFullyShownChanged: {
358 if (!fullyShown && stages.fullyShown && sideStage.focusedApplication != null) {
359 shell.applicationManager.focusApplication(mainStage.focusedApplication);
363 enabled: shell.width >= units.gu(60)
365 fullyShown: stages.fullyShown && shown
366 && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
367 shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
369 available: !greeter.shown && !lockscreen.shown && enabled
370 hides: [launcher, panel.indicators]
372 showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
373 hideAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.closedValue; easing.type: Easing.OutQuint }
376 height: stages.height
377 handleExpanded: sideStageRevealer.pressed
381 id: sideStageRevealer
383 enabled: mainStage.applications.count > 0 && sideStage.applications.count > 0
384 && sideStage.available
385 direction: Qt.RightToLeft
386 openedValue: parent.width - sideStage.width
387 hintDisplacement: units.gu(3)
388 /* The size of the sidestage handle needs to be bigger than the
389 typical size used for edge detection otherwise it is really
392 handleSize: sideStage.shown ? units.gu(4) : shell.edgeSize
393 closedValue: parent.width + sideStage.handleSizeCollapsed
395 x: parent.width - width
396 width: sideStage.width + handleSize * 0.7
397 height: sideStage.height
398 orientation: Qt.Horizontal
404 anchors.top: parent.top
405 anchors.bottom: parent.bottom
406 anchors.right: parent.left
408 width: shell.edgeSize
409 direction: Direction.Leftwards
410 enabled: mainStage.applications.count > 0 || sideStage.applications.count > 0
417 hides: [launcher, panel.indicators, hud]
420 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
421 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
423 x: required ? 0 : - width
425 height: parent.height - panel.panelHeight
426 background: shell.background
428 onUnlocked: lockscreen.hide()
429 onCancel: greeter.show()
431 Component.onCompleted: {
432 if (LightDM.Users.count == 1) {
433 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
440 target: LightDM.Greeter
443 if (LightDM.Users.count == 1) {
444 // TODO: There's no better way for now to determine if its a PIN or a passphrase.
446 lockscreen.alphaNumeric = false
448 lockscreen.alphaNumeric = true
450 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
460 hides: [launcher, panel.indicators, hud]
465 height: parent.height - panel.panelHeight
467 dragHandleWidth: shell.edgeSize
469 property var previousMainApp: null
470 property var previousSideApp: null
475 // If there is only one user, we start authenticating with that one here.
476 // If there are more users, the Greeter will handle that
477 if (LightDM.Users.count == 1) {
478 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
481 greeter.forceActiveFocus();
482 // FIXME: *FocusedApplication are not updated when unfocused, hence the need to check whether
483 // the stage was actually shown
484 if (mainStage.fullyShown) greeter.previousMainApp = applicationManager.mainStageFocusedApplication;
485 if (sideStage.fullyShown) greeter.previousSideApp = applicationManager.sideStageFocusedApplication;
486 applicationManager.unfocusCurrentApplication();
488 if (greeter.previousMainApp) {
489 applicationManager.focusApplication(greeter.previousMainApp);
490 greeter.previousMainApp = null;
492 if (greeter.previousSideApp) {
493 applicationManager.focusApplication(greeter.previousSideApp);
494 greeter.previousSideApp = null;
499 onUnlocked: greeter.hide()
502 var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
503 shell.background = bgPath ? bgPath : default_background
504 // Update edge demo hint
505 var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole)
506 shell.showEdgeDemo = AccountsService.getUserProperty(user, "demo-edges")
509 onLeftTeaserPressedChanged: {
510 if (leftTeaserPressed) {
519 title: i18n.tr("Right edge")
520 text: i18n.tr("Try swiping from the right edge to unlock the phone")
522 enabled: shell.showEdgeDemoInGreeter
524 shell.hideEdgeDemoInGreeter()
530 onUnlocked: rightEdgeDemo.visible = false
532 if (!greeter.shown) {
533 rightEdgeDemo.visible = false
534 shell.hideEdgeDemoInGreeter()
542 blockInput: greeter.shown || lockscreen.shown
553 anchors.fill: parent //because this draws indicator menus
554 indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
557 available: !rightEdgeDemo.visible && !leftEdgeDemo.visible
559 fullscreenMode: shell.fullscreenMode
560 searchVisible: !greeter.shown && !lockscreen.shown
564 blockInput: panel.indicators.shown
571 title: i18n.tr("Close")
572 text: i18n.tr("Swipe up again to close the settings screen")
573 anchors.fill: panel.indicators
575 enabled: shell.showEdgeDemo
576 onSkip: shell.hideEdgeDemo()
579 target: panel.indicators
580 onFullyOpenedChanged: if (panel.indicators.fullyOpened) bottomEdgeDemo.visible = true
581 onPartiallyOpenedChanged: if (!panel.indicators.partiallyOpened && !panel.indicators.fullyOpened) bottomEdgeDemo.visible = false
589 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
590 height: parent.height
592 available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown && !topEdgeDemo.visible
594 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
595 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
598 target: shell.applicationManager
599 onMainStageFocusedApplicationChanged: hud.hide()
600 onSideStageFocusedApplicationChanged: hud.hide()
605 blockInput: hud.shown
614 anchors.left: hud.left
615 height: parent.height
616 target: hud.revealerTarget
619 direction: Qt.RightToLeft
620 orientation: Qt.Vertical
621 handleSize: hud.handleHeight
622 onCloseClicked: target.hide()
628 enabled: !panel.indicators.shown
629 applicationIsOnForeground: applicationManager.mainStageFocusedApplication
630 || applicationManager.sideStageFocusedApplication
634 blockInput: launcher.shown
637 bottom: parent.bottom
640 width: launcher.width
646 anchors.top: parent.top
647 anchors.bottom: parent.bottom
649 dragAreaWidth: shell.edgeSize
650 available: !greeter.locked && !rightEdgeDemo.visible && !topEdgeDemo.visible && !bottomEdgeDemo.visible
651 onDashItemSelected: {
653 // Animate if moving between application and dash
655 dash.setCurrentScope("home.scope", true, false)
657 dash.setCurrentScope("home.scope", false, false)
663 dash.setCurrentScope("applications.scope", true, false)
668 onLauncherApplicationSelected:{
670 shell.activateApplication(desktopFile)
674 panel.indicators.hide()
683 model: NotificationBackend.Model
687 bottom: parent.bottom
688 leftMargin: units.gu(1)
689 rightMargin: units.gu(1)
690 topMargin: panel.panelHeight + units.gu(1)
695 when: overlay.width <= units.gu(60)
696 AnchorChanges { target: notifications; anchors.left: parent.left }
700 when: overlay.width > units.gu(60)
701 AnchorChanges { target: notifications; anchors.left: undefined }
702 PropertyChanges { target: notifications; width: units.gu(38) }
713 bottom: parent.bottom
716 width: shell.edgeSize
723 bottom: parent.bottom
726 width: shell.edgeSize
736 //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
738 anchors.bottom: parent.bottom
739 anchors.left: parent.left
740 anchors.right: parent.right
741 height: shell.applicationManager ? shell.applicationManager.keyboardHeight : 0
743 enabled: shell.applicationManager && shell.applicationManager.keyboardVisible
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