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 Mir.Application 0.1
21import Ubuntu.Components 0.1
22import Ubuntu.Gestures 0.1
23import Unity.Launcher 0.1
24import LightDM 0.1 as LightDM
26import SessionBroadcast 0.1
34import Unity.Notifications 1.0 as NotificationBackend
39 property int supportedScreenOrientations: {
40 if (stages.shown && ApplicationManager.topmostApplication) {
41 return ApplicationManager.topmostApplication.supportedOrientations;
43 return Qt.PortraitOrientation
44 | Qt.InvertedPortraitOrientation
45 | Qt.LandscapeOrientation
46 | Qt.InvertedLandscapeOrientation;
50 property real edgeSize: units.gu(2)
51 property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
52 property url background
53 readonly property real panelHeight: panel.panelHeight
55 property bool dashShown: dash.shown
57 property bool sideStageEnabled: shell.width >= units.gu(100)
59 function activateApplication(appId) {
60 if (ApplicationManager.findApplication(appId)) {
61 ApplicationManager.requestFocusApplication(appId);
63 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
64 ApplicationManager.startApplication(appId, execFlags);
71 property: "applicationManager"
72 value: ApplicationManager
75 Component.onCompleted: {
76 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
80 id: backgroundSettings
81 schema.id: "org.gnome.desktop.background"
83 property url gSettingsPicture: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : shell.defaultBackground
84 onGSettingsPictureChanged: {
85 shell.background = gSettingsPicture
92 Keys.onVolumeUpPressed: volumeControl.volumeUp()
93 Keys.onVolumeDownPressed: volumeControl.volumeDown()
97 objectName: "underlay"
100 // Whether the underlay is fully covered by opaque UI elements.
101 property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
103 // NB! Application surfaces are stacked behind the shell one. So they can only be seen by the user
104 // through the translucent parts of the shell surface.
105 visible: !fullyCovered
110 opacity: dash.disappearingAnimationProgress
115 source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png"
116 fillMode: Image.PreserveAspectCrop
117 horizontalAlignment: Image.AlignRight
118 verticalAlignment: Image.AlignTop
125 available: !greeter.shown && !lockscreen.shown
126 hides: [stages, launcher, panel.indicators]
127 shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
128 enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
132 topMargin: panel.panelHeight
135 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
136 opacity: 1.0 - disappearingAnimationProgress
137 property real disappearingAnimationProgress: stages.showProgress
139 // FIXME: only necessary because stages.showProgress is not animated
140 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
146 direction: Direction.Leftwards
148 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
149 width: shell.edgeSize
151 property real progress: stages.width
154 if (status == DirectionalDragArea.Recognized) {
155 if (ApplicationManager.empty) {
156 progress = Math.max(stages.width - stagesDragArea.width + touchX, stages.width * .3);
158 progress = stages.width - stagesDragArea.width + touchX;
165 if (!ApplicationManager.empty && progress < stages.width - units.gu(10)) {
168 stagesDragArea.progress = Qt.binding(function () { return stages.width; });
177 height: parent.height
180 visible: !fullyHidden
182 x: shown ? launcher.progress : stagesDragArea.progress
183 //Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
185 property bool shown: false
188 if (ApplicationManager.topmostApplication) {
189 ApplicationManager.focusApplication(ApplicationManager.topmostApplication.appId);
192 if (ApplicationManager.focusedApplicationId) {
193 ApplicationManager.updateScreenshot(ApplicationManager.focusedApplicationId);
194 ApplicationManager.unfocusCurrentApplication();
199 // Avoid a silent "divide by zero -> NaN" situation during init as shell.width will be
200 // zero. That breaks the property binding and the function won't be reevaluated once
201 // shell.width is set, with the NaN result staying there for good.
202 property real showProgress: shell.width ? MathUtils.clamp(1 - x / shell.width, 0, 1) : 0
204 property bool fullyShown: x == 0
205 property bool fullyHidden: x == width
207 // It might technically not be fullyShown but visually it just looks so.
208 property bool roughlyFullyShown: x >= 0 && x <= units.gu(1)
219 target: ApplicationManager
220 onFocusRequested: { stages.show(); }
223 if (ApplicationManager.empty) {
230 id: applicationsDisplayLoader
233 source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
236 target: applicationsDisplayLoader.item
237 property: "dragAreaWidth"
238 value: shell.edgeSize
241 target: applicationsDisplayLoader.item
242 property: "maximizedAppTopMargin"
243 value: panel.panelHeight
251 z: notifications.useModal ? overlay.z + 1 : overlay.z - 1
255 target: SurfaceManager
257 if (surface.type == MirSurfaceItem.InputMethod) {
258 inputMethod.surface = surface;
264 onSurfaceDestroyed: {
265 if (inputMethod.surface == surface) {
266 inputMethod.surface = null;
267 surface.parent = null;
269 if (!surface.parent) {
270 // there's no one displaying it. delete it right away
278 objectName: "lockscreen"
280 readonly property int backgroundTopMargin: -panel.panelHeight
282 hides: [launcher, panel.indicators]
285 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
286 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
288 x: required ? 0 : - width
290 height: parent.height - panel.panelHeight
291 background: shell.background
295 onEntered: LightDM.Greeter.respond(passphrase);
296 onCancel: greeter.show()
298 Component.onCompleted: {
299 if (LightDM.Users.count == 1) {
300 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
306 target: LightDM.Greeter
309 if (LightDM.Users.count == 1) {
310 // TODO: There's no better way for now to determine if its a PIN or a passphrase.
312 lockscreen.alphaNumeric = false
314 lockscreen.alphaNumeric = true
316 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
321 onAuthenticationComplete: {
322 if (LightDM.Greeter.promptless) {
325 if (LightDM.Greeter.authenticated) {
328 lockscreen.clear(true);
336 opacity: greeterWrapper.showProgress * 0.8
340 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
345 height: parent.height - panel.panelHeight
348 enabled: !launcher.dashSwipe
352 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
356 objectName: "greeter"
359 hides: [launcher, panel.indicators]
362 defaultBackground: shell.background
365 height: parent.height
367 dragHandleWidth: shell.edgeSize
372 // If there is only one user, we start authenticating with that one here.
373 // If there are more users, the Greeter will handle that
374 if (LightDM.Users.count == 1) {
375 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
377 greeter.forceActiveFocus();
381 onUnlocked: greeter.hide()
383 // Update launcher items for new user
384 var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
385 AccountsService.user = user;
386 LauncherModel.setUser(user);
389 onTease: launcher.tease()
392 target: ApplicationManager
393 property: "suspended"
394 value: greeter.shown && greeterWrapper.showProgress == 1
403 onDisplayPowerStateChange: {
404 // We ignore any display-off signals when the proximity sensor
405 // is active. This usually indicates something like a phone call.
406 if (status == Powerd.Off && (flags & Powerd.UseProximity) == 0) {
410 // No reason to chew demo CPU when user isn't watching
411 if (status == Powerd.Off) {
412 edgeDemo.paused = true;
413 } else if (status == Powerd.On) {
414 edgeDemo.paused = false;
419 function showHome() {
420 var animate = !greeter.shown && !stages.shown
422 dash.setCurrentScope("clickscope", animate, false)
426 function hideIndicatorMenu(delay) {
427 panel.hideIndicatorMenu(delay);
438 anchors.fill: parent //because this draws indicator menus
439 indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
442 available: edgeDemo.panelEnabled
443 contentEnabled: edgeDemo.panelContentEnabled
446 property bool topmostApplicationIsFullscreen:
447 ApplicationManager.topmostApplication &&
448 ApplicationManager.topmostApplication.fullscreen
450 fullscreenMode: stages.roughlyFullyShown && topmostApplicationIsFullscreen
451 && !greeter.shown && !lockscreen.shown
453 searchVisible: !greeter.shown && !lockscreen.shown && dash.shown && dash.searchable
459 readonly property bool dashSwipe: progress > 0
461 anchors.top: parent.top
462 anchors.bottom: parent.bottom
464 dragAreaWidth: shell.edgeSize
465 available: edgeDemo.launcherEnabled
468 if (edgeDemo.running)
474 if (!stages.locked) {
483 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
484 onLauncherApplicationSelected: {
485 if (!edgeDemo.running)
486 shell.activateApplication(appId)
490 panel.indicators.hide()
496 id: modalNotificationBackground
498 visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
511 model: NotificationBackend.Model
517 bottom: parent.bottom
518 topMargin: panel.panelHeight
523 when: overlay.width <= units.gu(60)
524 AnchorChanges { target: notifications; anchors.left: parent.left }
528 when: overlay.width > units.gu(60)
529 AnchorChanges { target: notifications; anchors.left: undefined }
530 PropertyChanges { target: notifications; width: units.gu(38) }
537 onFocusChanged: if (!focus) forceActiveFocus();
546 id: alphaDisclaimerLabel
547 anchors.centerIn: parent
548 visible: ApplicationManager.fake ? ApplicationManager.fake : false
550 text: "EARLY ALPHA\nNOT READY FOR USE"
553 font.weight: Font.Black
554 horizontalAlignment: Text.AlignHCenter
555 verticalAlignment: Text.AlignVCenter
556 fontSizeMode: Text.Fit
558 scale: Math.min(parent.width, parent.height) / width
563 z: alphaDisclaimerLabel.z + 10
567 indicators: panel.indicators
572 target: SessionBroadcast
573 onShowHome: showHome()
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