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 SessionBroadcast 0.1
26import SessionManager 0.1
35import Unity.Notifications 1.0 as NotificationBackend
40 readonly property real panelHeight: panel.panelHeight
42 property bool dashShown: dash.shown
43 property bool stageScreenshotsReady: {
44 if (sideStage.shown) {
45 if (mainStage.applications.count > 0) {
46 return mainStage.usingScreenshots && sideStage.usingScreenshots;
48 return sideStage.usingScreenshots;
51 return mainStage.usingScreenshots;
55 property ListModel searchHistory: SearchHistoryModel {}
57 property var applicationManager: ApplicationManagerWrapper {}
61 property: "applicationManager"
62 value: ApplicationManager
65 Component.onCompleted: {
66 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
68 applicationManager.sideStageEnabled = Qt.binding(function() { return sideStage.enabled })
70 // FIXME: if application focused before shell starts, shell draws on top of it only.
71 // We should detect already running applications on shell start and bring them to the front.
72 applicationManager.unfocusCurrentApplication();
75 readonly property bool applicationFocused: !!applicationManager.mainStageFocusedApplication
76 || !!applicationManager.sideStageFocusedApplication
77 // Used for autopilot testing.
78 readonly property string currentFocusedAppId: ApplicationManager.focusedApplicationId
80 readonly property bool fullscreenMode: {
81 if (mainStage.usingScreenshots) { // Window Manager animating so want to re-evaluate fullscreen mode
82 return mainStage.switchingFromFullscreenToFullscreen;
83 } else if (applicationManager.mainStageFocusedApplication) {
84 return applicationManager.mainStageFocusedApplication.fullscreen;
90 function activateApplication(desktopFile, argument) {
91 if (applicationManager) {
92 // For newly started applications, as it takes them time to draw their first frame
93 // we add a delay before we hide the animation screenshots to compensate.
94 var addDelay = !applicationManager.getApplicationFromDesktopFile(desktopFile);
97 application = applicationManager.activateApplication(desktopFile, argument);
98 if (application == null) {
101 if (application.stage == ApplicationInfo.MainStage || !sideStage.enabled) {
102 mainStage.activateApplication(desktopFile, addDelay);
104 sideStage.activateApplication(desktopFile, addDelay);
111 id: backgroundSettings
112 schema.id: "org.gnome.desktop.background"
114 backgroundSource: backgroundSettings.pictureUri
118 objectName: "underlay"
121 // Whether the underlay is fully covered by opaque UI elements.
122 property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
124 readonly property bool applicationRunning: ((mainStage.applications && mainStage.applications.count > 0)
125 || (sideStage.applications && sideStage.applications.count > 0))
127 // Whether the user should see the topmost application surface (if there's one at all).
128 readonly property bool applicationSurfaceShouldBeSeen: applicationRunning && !stages.fullyHidden
129 && !mainStage.usingScreenshots // but want sideStage animating over app surface
133 // NB! Application surfaces are stacked behing the shell one. So they can only be seen by the user
134 // through the translucent parts of the shell surface.
135 visible: !fullyCovered && !applicationSurfaceShouldBeSeen
139 objectName: "backgroundImage"
142 source: shell.background
143 fillMode: Image.PreserveAspectCrop
149 opacity: dash.disappearingAnimationProgress
156 hides: [stages, launcher, panel.indicators]
157 shown: disappearingAnimationProgress !== 1.0
158 enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
159 // FIXME: unfocus all applications when going back to the dash
162 shell.applicationManager.unfocusCurrentApplication()
168 topMargin: panel.panelHeight
171 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
172 opacity: 1.0 - disappearingAnimationProgress
173 property real disappearingAnimationProgress: stagesOuterContainer.showProgress
175 // FIXME: only necessary because stagesOuterContainer.showProgress
177 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
182 id: stagesOuterContainer
185 height: parent.height
187 Behavior on x {SmoothedAnimation{velocity: 600}}
189 property real showProgress:
190 MathUtils.clamp(1 - (x + stages.x) / shell.width, 0, 1)
198 property bool fullyShown: shown && x == 0 && parent.x == 0
199 property bool fullyHidden: !shown && x == width
200 hides: [panel.indicators]
203 showAnimation: StandardAnimation { property: "x"; duration: 350; to: 0; easing.type: Easing.OutCubic }
204 hideAnimation: StandardAnimation { property: "x"; duration: 350; to: width; easing.type: Easing.OutCubic }
207 height: parent.height
209 // close the stages when no focused application remains
211 target: shell.applicationManager
212 onMainStageFocusedApplicationChanged: stages.closeIfNoApplications()
213 onSideStageFocusedApplicationChanged: stages.closeIfNoApplications()
214 ignoreUnknownSignals: true
217 function closeIfNoApplications() {
218 if (!shell.applicationManager.mainStageFocusedApplication
219 && !shell.applicationManager.sideStageFocusedApplication
220 && shell.applicationManager.mainStageApplications.count == 0
221 && shell.applicationManager.sideStageApplications.count == 0) {
226 // show the stages when an application gets the focus
228 target: shell.applicationManager
229 onMainStageFocusedApplicationChanged: {
230 if (shell.applicationManager.mainStageFocusedApplication) {
235 onSideStageFocusedApplicationChanged: {
236 if (shell.applicationManager.sideStageFocusedApplication) {
241 ignoreUnknownSignals: true
248 fullyShown: stages.fullyShown
249 fullyHidden: stages.fullyHidden
250 shouldUseScreenshots: !fullyShown
251 rightEdgeEnabled: !sideStage.enabled
253 applicationManager: shell.applicationManager
254 rightEdgeDraggingAreaWidth: shell.edgeSize
255 normalApplicationY: shell.panelHeight
264 // FIXME: workaround the fact that focusing a main stage application
265 // raises its surface on top of all other surfaces including the ones
266 // that belong to side stage applications.
267 onFocusedApplicationChanged: {
268 if (focusedApplication && sideStage.focusedApplication && sideStage.fullyShown) {
269 shell.applicationManager.focusApplication(sideStage.focusedApplication);
277 applicationManager: shell.applicationManager
278 rightEdgeDraggingAreaWidth: shell.edgeSize
279 normalApplicationY: shell.panelHeight
282 if (!shown && mainStage.applications.count == 0) {
286 // FIXME: when hiding the side stage, refocus the main stage
287 // application so that it goes in front of the side stage
288 // application and hides it
289 onFullyShownChanged: {
290 if (!fullyShown && stages.fullyShown && sideStage.focusedApplication != null) {
291 shell.applicationManager.focusApplication(mainStage.focusedApplication);
295 enabled: shell.width >= units.gu(60)
297 fullyShown: stages.fullyShown && shown
298 && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
299 shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
302 hides: [launcher, panel.indicators]
304 showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
305 hideAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.closedValue; easing.type: Easing.OutQuint }
308 height: stages.height
309 handleExpanded: sideStageRevealer.pressed
313 id: sideStageRevealer
315 enabled: mainStage.applications.count > 0 && sideStage.applications.count > 0
316 && sideStage.available
317 direction: Qt.RightToLeft
318 openedValue: parent.width - sideStage.width
319 hintDisplacement: units.gu(3)
320 /* The size of the sidestage handle needs to be bigger than the
321 typical size used for edge detection otherwise it is really
324 handleSize: sideStage.shown ? units.gu(4) : shell.edgeSize
325 closedValue: parent.width + sideStage.handleSizeCollapsed
327 x: parent.width - width
328 width: sideStage.width + handleSize * 0.7
329 height: sideStage.height
330 orientation: Qt.Horizontal
336 anchors.top: parent.top
337 anchors.bottom: parent.bottom
338 anchors.right: parent.left
340 width: shell.edgeSize
341 direction: Direction.Leftwards
342 enabled: edgeDemo.dashEnabled
343 property bool haveApps: mainStage.applications.count > 0 || sideStage.applications.count > 0
345 maxTotalDragDistance: haveApps ? parent.width : parent.width * 0.7
346 // Make autocompletion impossible when !haveApps
347 edgeDragEvaluator.minDragDistance: haveApps ? maxTotalDragDistance * 0.1 : Number.MAX_VALUE
353 id: sessionConnection
354 target: SessionManager
356 property var previousMainApp: null
357 property var previousSideApp: null
359 function removeApplicationFocus() {
360 sessionConnection.previousMainApp = applicationManager.mainStageFocusedApplication;
361 sessionConnection.previousSideApp = applicationManager.sideStageFocusedApplication;
362 applicationManager.unfocusCurrentApplication();
365 function restoreApplicationFocus() {
366 if (sessionConnection.previousMainApp) {
367 applicationManager.focusApplication(sessionConnection.previousMainApp);
368 sessionConnection.previousMainApp = null;
370 if (sessionConnection.previousSideApp) {
371 applicationManager.focusApplication(sessionConnection.previousSideApp);
372 sessionConnection.previousSideApp = null;
377 if (SessionManager.active) {
378 restoreApplicationFocus();
380 removeApplicationFocus();
389 onDisplayPowerStateChange: {
390 // We ignore any display-off signals when the proximity sensor
391 // is active. This usually indicates something like a phone call.
392 if (status == Powerd.Off && (flags & Powerd.UseProximity) == 0) {
393 SessionManager.lock();
396 // No reason to chew demo CPU when user isn't watching
397 if (status == Powerd.Off) {
398 edgeDemo.paused = true;
399 } else if (status == Powerd.On) {
400 edgeDemo.paused = false;
405 function showHome(fromLauncher) {
406 var animate = fromLauncher && !stages.shown
407 dash.setCurrentScope("home.scope", animate, false)
418 anchors.fill: parent //because this draws indicator menus
419 indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
422 available: edgeDemo.panelEnabled
423 contentEnabled: edgeDemo.panelContentEnabled
425 fullscreenMode: shell.fullscreenMode
426 searchVisible: dash.shown
434 height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
442 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
443 height: parent.height
445 available: !panel.indicators.shown && edgeDemo.dashEnabled
447 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
448 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
451 target: shell.applicationManager
452 onMainStageFocusedApplicationChanged: hud.hide()
453 onSideStageFocusedApplicationChanged: hud.hide()
462 anchors.left: hud.left
463 height: parent.height
464 target: hud.revealerTarget
467 direction: Qt.RightToLeft
468 orientation: Qt.Vertical
469 handleSize: hud.handleHeight
470 onCloseClicked: target.hide()
477 enabled: hud.available
478 applicationIsOnForeground: applicationFocused
482 blockInput: launcher.shown
485 bottom: parent.bottom
488 width: launcher.width
494 readonly property bool dashSwipe: progress > 0
496 anchors.top: parent.top
497 anchors.bottom: parent.bottom
499 dragAreaWidth: shell.edgeSize
500 available: edgeDemo.launcherEnabled
501 onDashItemSelected: showHome(true)
508 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("applications.scope", false, true)
509 onLauncherApplicationSelected:{
510 shell.activateApplication(appId)
514 panel.indicators.hide()
524 model: NotificationBackend.Model
528 bottom: parent.bottom
529 leftMargin: units.gu(1)
530 rightMargin: units.gu(1)
531 topMargin: panel.panelHeight + units.gu(1)
536 when: overlay.width <= units.gu(60)
537 AnchorChanges { target: notifications; anchors.left: parent.left }
541 when: overlay.width > units.gu(60)
542 AnchorChanges { target: notifications; anchors.left: undefined }
543 PropertyChanges { target: notifications; width: units.gu(38) }
548 anchors { left: parent.left; right: parent.right }
549 height: parent.contentHeight
550 blockInput: height > 0
558 bottom: parent.bottom
561 width: shell.edgeSize
565 //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
567 anchors.bottom: parent.bottom
568 anchors.left: parent.left
569 anchors.right: parent.right
570 height: shell.applicationManager ? shell.applicationManager.keyboardHeight : 0
572 enabled: shell.applicationManager && shell.applicationManager.keyboardVisible
576 anchors.centerIn: parent
577 visible: applicationManager.fake
578 text: "EARLY ALPHA\nNOT READY FOR USE"
581 font.weight: Font.Black
582 horizontalAlignment: Text.AlignHCenter
583 verticalAlignment: Text.AlignVCenter
584 fontSizeMode: Text.Fit
586 scale: Math.min(parent.width, parent.height) / width
593 indicators: panel.indicators
598 target: SessionBroadcast
599 onShowHome: showHome(false)
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