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.Components.Popups 1.0
23import Ubuntu.Gestures 0.1
24import Ubuntu.SystemImage 0.1
25import Unity.Launcher 0.1
27import LightDM 0.1 as LightDM
29import SessionBroadcast 0.1
36import Unity.Notifications 1.0 as NotificationBackend
37import Unity.Session 0.1
38import Unity.DashCommunicator 0.1
43 // this is only here to select the width / height of the window if not running fullscreen
44 property bool tablet: false
45 width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
46 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
48 property real edgeSize: units.gu(2)
49 property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
50 property url background
51 readonly property real panelHeight: panel.panelHeight
53 readonly property bool locked: LightDM.Greeter.active && !LightDM.Greeter.authenticated
55 property bool sideStageEnabled: shell.width >= units.gu(100)
56 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
58 property int maxFailedLogins: -1 // disabled by default for now, will enable via settings in future
59 property int failedLoginsDelayAttempts: 7 // number of failed logins
60 property int failedLoginsDelaySeconds: 5 * 60 // seconds of forced waiting
62 function activateApplication(appId) {
63 if (ApplicationManager.findApplication(appId)) {
64 ApplicationManager.requestFocusApplication(appId);
66 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
67 ApplicationManager.startApplication(appId, execFlags);
73 property: "applicationManager"
74 value: ApplicationManager
77 Component.onCompleted: {
78 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
82 id: backgroundSettings
83 schema.id: "org.gnome.desktop.background"
85 property url gSettingsPicture: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : shell.defaultBackground
86 onGSettingsPictureChanged: {
87 shell.background = gSettingsPicture
96 objectName: "dashCommunicator"
100 // Handle but do not filter out volume keys
101 Keys.onVolumeUpPressed: { volumeControl.volumeUp(); event.accepted = false; }
102 Keys.onVolumeDownPressed: { volumeControl.volumeDown(); event.accepted = false; }
105 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
106 dialogs.onPowerKeyPressed();
107 event.accepted = true;
109 event.accepted = false;
114 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
115 dialogs.onPowerKeyReleased();
116 event.accepted = true;
118 event.accepted = false;
127 height: parent.height
128 visible: !ApplicationManager.empty
131 target: ApplicationManager
133 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
139 onFocusedApplicationIdChanged: {
140 if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
143 panel.indicators.hide();
146 onApplicationAdded: {
147 if (greeter.shown && appId != "unity8-dash") {
154 id: applicationsDisplayLoader
157 source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
160 target: applicationsDisplayLoader.item
161 property: "objectName"
165 target: applicationsDisplayLoader.item
166 property: "dragAreaWidth"
167 value: shell.edgeSize
170 target: applicationsDisplayLoader.item
171 property: "maximizedAppTopMargin"
172 // Not just using panel.panelHeight as that changes depending on the focused app.
173 value: panel.indicators.panelHeight
176 target: applicationsDisplayLoader.item
177 property: "interactive"
178 value: edgeDemo.stagesEnabled && !greeter.shown && !lockscreen.shown && panel.indicators.fullyClosed && launcher.progress == 0
181 target: applicationsDisplayLoader.item
182 property: "spreadEnabled"
183 value: edgeDemo.stagesEnabled && greeter.fakeActiveForApp === "" // to support emergency dialer hack
186 target: applicationsDisplayLoader.item
187 property: "inverseProgress"
188 value: launcher.progress
195 objectName: "inputMethod"
196 anchors { fill: parent; topMargin: panel.panelHeight }
197 z: notifications.useModal || panel.indicators.shown ? overlay.z + 1 : overlay.z - 1
201 target: SurfaceManager
203 if (surface.type == MirSurfaceItem.InputMethod) {
204 inputMethod.surface = surface;
208 onSurfaceDestroyed: {
209 if (inputMethod.surface == surface) {
210 inputMethod.surface = null;
211 surface.parent = null;
213 if (!surface.parent) {
214 // there's no one displaying it. delete it right away
222 objectName: "lockscreen"
224 readonly property int backgroundTopMargin: -panel.panelHeight
226 hides: [launcher, panel.indicators]
229 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
230 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
234 height: parent.height - panel.panelHeight
235 background: shell.background
236 alphaNumeric: AccountsService.passwordDisplayHint === AccountsService.Keyboard
240 onEntered: LightDM.Greeter.respond(passphrase);
241 onCancel: greeter.show()
243 greeter.fakeActiveForApp = "dialer-app"
244 shell.activateApplication("dialer-app")
248 onShownChanged: if (shown) greeter.fakeActiveForApp = ""
250 Component.onCompleted: {
251 if (greeter.narrowMode) {
252 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
258 target: LightDM.Greeter
260 onShowGreeter: greeter.show()
263 if (greeter.narrowMode) {
264 var promptText = text.toLowerCase()
265 if (isDefaultPrompt) {
266 promptText = lockscreen.alphaNumeric ?
267 i18n.tr("passphrase") : i18n.tr("passcode")
269 lockscreen.placeholderText = i18n.tr("Enter your %1").arg(promptText)
270 lockscreen.wrongPlaceholderText = i18n.tr("Incorrect %1").arg(promptText) +
272 i18n.tr("Please re-enter")
277 onPromptlessChanged: {
278 if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
286 onAuthenticationComplete: {
287 if (LightDM.Greeter.authenticated) {
288 AccountsService.failedLogins = 0
290 // Else only penalize user for a failed login if they actually were
291 // prompted for a password. We do this below after the promptless
294 if (LightDM.Greeter.promptless) {
298 if (LightDM.Greeter.authenticated) {
302 AccountsService.failedLogins++
303 if (maxFailedLogins >= 2) { // require at least a warning
304 if (AccountsService.failedLogins === maxFailedLogins - 1) {
305 var title = lockscreen.alphaNumeric ?
306 i18n.tr("Sorry, incorrect passphrase.") :
307 i18n.tr("Sorry, incorrect passcode.")
308 var text = i18n.tr("This will be your last attempt.") + " " +
309 (lockscreen.alphaNumeric ?
310 i18n.tr("If passphrase is entered incorrectly, your phone will conduct a factory reset and all personal data will be deleted.") :
311 i18n.tr("If passcode is entered incorrectly, your phone will conduct a factory reset and all personal data will be deleted."))
312 lockscreen.showInfoPopup(title, text)
313 } else if (AccountsService.failedLogins >= maxFailedLogins) {
314 SystemImage.factoryReset() // Ouch!
317 if (failedLoginsDelayAttempts > 0 && AccountsService.failedLogins % failedLoginsDelayAttempts == 0) {
318 lockscreen.forceDelay(failedLoginsDelaySeconds * 1000)
321 lockscreen.clear(true);
322 if (greeter.narrowMode) {
323 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
330 target: LightDM.Greeter
332 value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
338 opacity: greeterWrapper.showProgress * 0.8
342 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
347 height: parent.height - panel.panelHeight
350 enabled: !launcher.dashSwipe
354 property bool fullyShown: showProgress === 1.0
355 onFullyShownChanged: {
356 // Wait until the greeter is completely covering lockscreen before resetting it.
357 if (fullyShown && !LightDM.Greeter.authenticated) {
363 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
364 onShowProgressChanged: if (LightDM.Greeter.authenticated && showProgress === 0) greeter.login()
368 objectName: "greeter"
370 signal sessionStarted() // helpful for tests
372 property string fakeActiveForApp: ""
375 hides: [launcher, panel.indicators]
377 loadContent: required || lockscreen.required // keeps content in memory for quick show()
379 defaultBackground: shell.background
382 height: parent.height
384 dragHandleWidth: shell.edgeSize
388 if (LightDM.Greeter.startSessionSync()) {
399 if (greeter.narrowMode) {
400 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
402 greeter.fakeActiveForApp = "";
403 greeter.forceActiveFocus();
407 onUnlocked: greeter.hide()
409 // Update launcher items for new user
410 var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
411 AccountsService.user = user;
412 LauncherModel.setUser(user);
415 onTease: launcher.tease()
418 target: ApplicationManager
419 property: "suspended"
420 value: greeter.shown && greeterWrapper.showProgress == 1
429 onDisplayPowerStateChange: {
430 // We ignore any display-off signals when the proximity sensor
431 // is active. This usually indicates something like a phone call.
432 if (status == Powerd.Off && reason != Powerd.Proximity && !edgeDemo.running) {
436 // No reason to chew demo CPU when user isn't watching
437 if (status == Powerd.Off) {
438 edgeDemo.paused = true;
439 } else if (status == Powerd.On) {
440 edgeDemo.paused = false;
445 function showHome() {
446 if (edgeDemo.running) {
450 if (LightDM.Greeter.active) {
451 if (!LightDM.Greeter.authenticated) {
457 var animate = !LightDM.Greeter.active && !stages.shown
458 dash.setCurrentScope("clickscope", animate, false)
459 ApplicationManager.requestFocusApplication("unity8-dash")
462 function showDash() {
471 ApplicationManager.requestFocusApplication("unity8-dash")
484 anchors.fill: parent //because this draws indicator menus
487 available: edgeDemo.panelEnabled && !shell.locked
488 contentEnabled: edgeDemo.panelContentEnabled
489 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
490 panelHeight: units.gu(3)
493 property bool topmostApplicationIsFullscreen:
494 ApplicationManager.focusedApplicationId &&
495 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
497 fullscreenMode: (topmostApplicationIsFullscreen && !LightDM.Greeter.active && launcher.progress == 0)
498 || greeter.fakeActiveForApp !== ""
503 objectName: "launcher"
505 readonly property bool dashSwipe: progress > 0
507 anchors.top: parent.top
508 anchors.bottom: parent.bottom
510 dragAreaWidth: shell.edgeSize
511 available: edgeDemo.launcherEnabled && !shell.locked
513 onShowDashHome: showHome()
515 onDashSwipeChanged: {
516 if (dashSwipe && ApplicationManager.focusedApplicationId !== "unity8-dash") {
517 dash.setCurrentScope("clickscope", false, true)
520 onLauncherApplicationSelected: {
521 if (greeter.fakeActiveForApp !== "") {
524 if (!edgeDemo.running)
525 shell.activateApplication(appId)
529 panel.indicators.hide()
535 id: modalNotificationBackground
537 visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
550 model: NotificationBackend.Model
555 height: parent.height - panel.panelHeight
560 when: overlay.width <= units.gu(60)
561 AnchorChanges { target: notifications; anchors.left: parent.left }
565 when: overlay.width > units.gu(60)
566 AnchorChanges { target: notifications; anchors.left: undefined }
567 PropertyChanges { target: notifications; width: units.gu(38) }
584 shutdownFadeOutRectangle.enabled = true;
585 shutdownFadeOutRectangle.visible = true;
586 shutdownFadeOut.start();
591 id: alphaDisclaimerLabel
592 anchors.centerIn: parent
593 visible: ApplicationManager.fake ? ApplicationManager.fake : false
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
608 z: alphaDisclaimerLabel.z + 10
611 indicators: panel.indicators
616 target: SessionBroadcast
617 onShowHome: showHome()
621 id: shutdownFadeOutRectangle
628 NumberAnimation on opacity {
633 if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
634 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