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 var applicationManager: ApplicationManagerWrapper {}
59 property: "applicationManager"
60 value: ApplicationManager
63 Component.onCompleted: {
64 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
66 applicationManager.sideStageEnabled = Qt.binding(function() { return sideStage.enabled })
68 // FIXME: if application focused before shell starts, shell draws on top of it only.
69 // We should detect already running applications on shell start and bring them to the front.
70 applicationManager.unfocusCurrentApplication();
73 readonly property bool applicationFocused: !!applicationManager.mainStageFocusedApplication
74 || !!applicationManager.sideStageFocusedApplication
75 // Used for autopilot testing.
76 readonly property string currentFocusedAppId: ApplicationManager.focusedApplicationId
78 readonly property bool fullscreenMode: {
79 if (mainStage.usingScreenshots) { // Window Manager animating so want to re-evaluate fullscreen mode
80 return mainStage.switchingFromFullscreenToFullscreen;
81 } else if (applicationManager.mainStageFocusedApplication) {
82 return applicationManager.mainStageFocusedApplication.fullscreen;
88 function activateApplication(appId, argument) {
89 if (applicationManager) {
90 // For newly started applications, as it takes them time to draw their first frame
91 // we add a delay before we hide the animation screenshots to compensate.
92 var addDelay = !applicationManager.getApplicationFromDesktopFile(appId);
95 application = applicationManager.activateApplication(appId, argument);
96 if (application == null) {
99 if (application.stage == ApplicationInfo.MainStage || !sideStage.enabled) {
100 mainStage.activateApplication(appId, addDelay);
102 sideStage.activateApplication(appId, addDelay);
109 id: backgroundSettings
110 schema.id: "org.gnome.desktop.background"
112 backgroundSource: backgroundSettings.pictureUri
116 objectName: "underlay"
119 // Whether the underlay is fully covered by opaque UI elements.
120 property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
122 readonly property bool applicationRunning: ((mainStage.applications && mainStage.applications.count > 0)
123 || (sideStage.applications && sideStage.applications.count > 0))
125 // Whether the user should see the topmost application surface (if there's one at all).
126 readonly property bool applicationSurfaceShouldBeSeen: applicationRunning && !stages.fullyHidden
127 && !mainStage.usingScreenshots // but want sideStage animating over app surface
131 // NB! Application surfaces are stacked behing the shell one. So they can only be seen by the user
132 // through the translucent parts of the shell surface.
133 visible: !fullyCovered && !applicationSurfaceShouldBeSeen
137 objectName: "backgroundImage"
140 source: shell.background
141 fillMode: Image.PreserveAspectCrop
147 opacity: dash.disappearingAnimationProgress
154 hides: [stages, launcher, panel.indicators]
155 shown: disappearingAnimationProgress !== 1.0
156 enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
157 // FIXME: unfocus all applications when going back to the dash
160 shell.applicationManager.unfocusCurrentApplication()
166 topMargin: panel.panelHeight
169 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
170 opacity: 1.0 - disappearingAnimationProgress
171 property real disappearingAnimationProgress: stagesOuterContainer.showProgress
173 // FIXME: only necessary because stagesOuterContainer.showProgress
175 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
180 id: stagesOuterContainer
183 height: parent.height
185 Behavior on x {SmoothedAnimation{velocity: 600}}
187 property real showProgress:
188 MathUtils.clamp(1 - (x + stages.x) / shell.width, 0, 1)
196 property bool fullyShown: shown && x == 0 && parent.x == 0
197 property bool fullyHidden: !shown && x == width
198 hides: [panel.indicators]
201 showAnimation: StandardAnimation { property: "x"; duration: 350; to: 0; easing.type: Easing.OutCubic }
202 hideAnimation: StandardAnimation { property: "x"; duration: 350; to: width; easing.type: Easing.OutCubic }
205 height: parent.height
207 // close the stages when no focused application remains
209 target: shell.applicationManager
210 onMainStageFocusedApplicationChanged: stages.closeIfNoApplications()
211 onSideStageFocusedApplicationChanged: stages.closeIfNoApplications()
212 ignoreUnknownSignals: true
215 function closeIfNoApplications() {
216 if (!shell.applicationManager.mainStageFocusedApplication
217 && !shell.applicationManager.sideStageFocusedApplication
218 && shell.applicationManager.mainStageApplications.count == 0
219 && shell.applicationManager.sideStageApplications.count == 0) {
224 // show the stages when an application gets the focus
226 target: shell.applicationManager
227 onMainStageFocusedApplicationChanged: {
228 if (shell.applicationManager.mainStageFocusedApplication) {
233 onSideStageFocusedApplicationChanged: {
234 if (shell.applicationManager.sideStageFocusedApplication) {
239 ignoreUnknownSignals: true
246 fullyShown: stages.fullyShown
247 fullyHidden: stages.fullyHidden
248 shouldUseScreenshots: !fullyShown
249 rightEdgeEnabled: !sideStage.enabled
251 applicationManager: shell.applicationManager
252 rightEdgeDraggingAreaWidth: shell.edgeSize
253 normalApplicationY: shell.panelHeight
262 // FIXME: workaround the fact that focusing a main stage application
263 // raises its surface on top of all other surfaces including the ones
264 // that belong to side stage applications.
265 onFocusedApplicationChanged: {
266 if (focusedApplication && sideStage.focusedApplication && sideStage.fullyShown) {
267 shell.applicationManager.focusApplication(sideStage.focusedApplication);
275 applicationManager: shell.applicationManager
276 rightEdgeDraggingAreaWidth: shell.edgeSize
277 normalApplicationY: shell.panelHeight
280 if (!shown && mainStage.applications.count == 0) {
284 // FIXME: when hiding the side stage, refocus the main stage
285 // application so that it goes in front of the side stage
286 // application and hides it
287 onFullyShownChanged: {
288 if (!fullyShown && stages.fullyShown && sideStage.focusedApplication != null) {
289 shell.applicationManager.focusApplication(mainStage.focusedApplication);
293 enabled: shell.width >= units.gu(60)
295 fullyShown: stages.fullyShown && shown
296 && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
297 shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
300 hides: [launcher, panel.indicators]
302 showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
303 hideAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.closedValue; easing.type: Easing.OutQuint }
306 height: stages.height
307 handleExpanded: sideStageRevealer.pressed
311 id: sideStageRevealer
313 enabled: mainStage.applications.count > 0 && sideStage.applications.count > 0
314 && sideStage.available
315 direction: Qt.RightToLeft
316 openedValue: parent.width - sideStage.width
317 hintDisplacement: units.gu(3)
318 /* The size of the sidestage handle needs to be bigger than the
319 typical size used for edge detection otherwise it is really
322 handleSize: sideStage.shown ? units.gu(4) : shell.edgeSize
323 closedValue: parent.width + sideStage.handleSizeCollapsed
325 x: parent.width - width
326 width: sideStage.width + handleSize * 0.7
327 height: sideStage.height
328 orientation: Qt.Horizontal
334 anchors.top: parent.top
335 anchors.bottom: parent.bottom
336 anchors.right: parent.left
338 width: shell.edgeSize
339 direction: Direction.Leftwards
340 enabled: edgeDemo.dashEnabled
341 property bool haveApps: mainStage.applications.count > 0 || sideStage.applications.count > 0
343 maxTotalDragDistance: haveApps ? parent.width : parent.width * 0.7
344 // Make autocompletion impossible when !haveApps
345 edgeDragEvaluator.minDragDistance: haveApps ? maxTotalDragDistance * 0.1 : Number.MAX_VALUE
352 blockInput: !applicationFocused || launcher.shown
353 || panel.indicators.shown || hud.shown
357 id: sessionConnection
358 target: SessionManager
360 property var previousMainApp: null
361 property var previousSideApp: null
363 function removeApplicationFocus() {
364 sessionConnection.previousMainApp = applicationManager.mainStageFocusedApplication;
365 sessionConnection.previousSideApp = applicationManager.sideStageFocusedApplication;
366 applicationManager.unfocusCurrentApplication();
369 function restoreApplicationFocus() {
370 if (sessionConnection.previousMainApp) {
371 applicationManager.focusApplication(sessionConnection.previousMainApp);
372 sessionConnection.previousMainApp = null;
374 if (sessionConnection.previousSideApp) {
375 applicationManager.focusApplication(sessionConnection.previousSideApp);
376 sessionConnection.previousSideApp = null;
381 if (SessionManager.active) {
382 restoreApplicationFocus();
384 removeApplicationFocus();
393 onDisplayPowerStateChange: {
394 // We ignore any display-off signals when the proximity sensor
395 // is active. This usually indicates something like a phone call.
396 if (status == Powerd.Off && (flags & Powerd.UseProximity) == 0) {
397 SessionManager.lock();
400 // No reason to chew demo CPU when user isn't watching
401 if (status == Powerd.Off) {
402 edgeDemo.paused = true;
403 } else if (status == Powerd.On) {
404 edgeDemo.paused = false;
409 function showHome(fromLauncher) {
410 var animate = fromLauncher && !stages.shown
411 dash.setCurrentScope("home.scope", animate, false)
415 function hideIndicatorMenu(delay) {
416 panel.hideIndicatorMenu(delay);
426 anchors.fill: parent //because this draws indicator menus
427 indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
430 available: edgeDemo.panelEnabled
431 contentEnabled: edgeDemo.panelContentEnabled
433 fullscreenMode: shell.fullscreenMode
434 searchVisible: dash.shown
442 height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
450 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
451 height: parent.height
453 available: !panel.indicators.shown && edgeDemo.dashEnabled
455 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
456 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
459 target: shell.applicationManager
460 onMainStageFocusedApplicationChanged: hud.hide()
461 onSideStageFocusedApplicationChanged: hud.hide()
470 anchors.left: hud.left
471 height: parent.height
472 target: hud.revealerTarget
475 direction: Qt.RightToLeft
476 orientation: Qt.Vertical
477 handleSize: hud.handleHeight
478 onCloseClicked: target.hide()
485 enabled: hud.available
486 applicationIsOnForeground: applicationFocused
490 blockInput: launcher.shown
493 bottom: parent.bottom
496 width: launcher.width
502 readonly property bool dashSwipe: progress > 0
504 anchors.top: parent.top
505 anchors.bottom: parent.bottom
507 dragAreaWidth: shell.edgeSize
508 available: edgeDemo.launcherEnabled
510 if (edgeDemo.running)
522 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("applications.scope", false, true)
523 onLauncherApplicationSelected:{
524 if (edgeDemo.running)
527 shell.activateApplication(appId)
531 panel.indicators.hide()
541 model: NotificationBackend.Model
547 bottom: parent.bottom
548 topMargin: panel.panelHeight
553 when: overlay.width <= units.gu(60)
554 AnchorChanges { target: notifications; anchors.left: parent.left }
558 when: overlay.width > units.gu(60)
559 AnchorChanges { target: notifications; anchors.left: undefined }
560 PropertyChanges { target: notifications; width: units.gu(38) }
565 anchors { left: parent.left; right: parent.right }
566 height: parent.contentHeight
567 blockInput: height > 0
575 bottom: parent.bottom
578 width: shell.edgeSize
582 //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
584 anchors.bottom: parent.bottom
585 anchors.left: parent.left
586 anchors.right: parent.right
587 height: shell.applicationManager ? shell.applicationManager.keyboardHeight : 0
589 enabled: shell.applicationManager && shell.applicationManager.keyboardVisible
593 anchors.centerIn: parent
594 visible: applicationManager.fake
595 text: "EARLY ALPHA\nNOT READY FOR USE"
598 font.weight: Font.Black
599 horizontalAlignment: Text.AlignHCenter
600 verticalAlignment: Text.AlignVCenter
601 fontSizeMode: Text.Fit
603 scale: Math.min(parent.width, parent.height) / width
610 indicators: panel.indicators
615 target: SessionBroadcast
616 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