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 QtQuick.Window 2.0
19import AccountsService 0.1
21import Unity.Application 0.1
22import Ubuntu.Components 0.1
23import Ubuntu.Components.Popups 1.0
24import Ubuntu.Gestures 0.1
25import Ubuntu.Telephony 0.1 as Telephony
26import Unity.Connectivity 0.1
27import Unity.Launcher 0.1
29import LightDM 0.1 as LightDM
31import SessionBroadcast 0.1
38import "Panel/Indicators"
40import Unity.Notifications 1.0 as NotificationBackend
41import Unity.Session 0.1
42import Unity.DashCommunicator 0.1
47 // this is only here to select the width / height of the window if not running fullscreen
48 property bool tablet: false
49 width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
50 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
52 enabled: !greeter.waiting
54 property real edgeSize: units.gu(2)
55 property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
56 property url background: asImageTester.status == Image.Ready ? asImageTester.source
57 : gsImageTester.status == Image.Ready ? gsImageTester.source : defaultBackground
58 readonly property real panelHeight: panel.panelHeight
60 readonly property alias locked: greeter.locked
62 property bool sideStageEnabled: shell.width >= units.gu(100)
63 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
65 property int maxFailedLogins: -1 // disabled by default for now, will enable via settings in future
66 property int failedLoginsDelayAttempts: 7 // number of failed logins
67 property int failedLoginsDelayMinutes: 5 // minutes of forced waiting
69 property int orientation
70 readonly property int deviceOrientationAngle: Screen.angleBetween(Screen.primaryOrientation, Screen.orientation)
71 onDeviceOrientationAngleChanged: {
72 if (!OrientationLock.enabled) {
73 orientation = Screen.orientation;
76 readonly property bool orientationLockEnabled: OrientationLock.enabled
77 onOrientationLockEnabledChanged: {
78 if (orientationLockEnabled) {
79 OrientationLock.savedOrientation = Screen.orientation;
81 orientation = Screen.orientation;
85 function activateApplication(appId) {
86 if (ApplicationManager.findApplication(appId)) {
87 ApplicationManager.requestFocusApplication(appId);
89 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
90 ApplicationManager.startApplication(appId, execFlags);
94 function startLockedApp(app) {
96 greeter.lockedApp = app;
98 shell.activateApplication(app);
101 // This is a dummy image to detect if the custom AS set wallpaper loads successfully.
104 source: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : ""
112 id: backgroundSettings
113 schema.id: "org.gnome.desktop.background"
116 // This is a dummy image to detect if the custom GSettings set wallpaper loads successfully.
119 source: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : ""
127 target: LauncherModel
128 property: "applicationManager"
129 value: ApplicationManager
132 Component.onCompleted: {
133 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
134 if (ApplicationManager.count > 0) {
135 ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
137 if (orientationLockEnabled) {
138 orientation = OrientationLock.savedOrientation;
140 Connectivity.unlockAllModems();
149 objectName: "dashCommunicator"
155 enabled: Powerd.status === Powerd.On
159 target: ApplicationManager
160 property: "forceDashActive"
161 value: launcher.shown || launcher.dashSwipe
166 onVolumeDownPressed: volumeControl.volumeDown()
167 onVolumeUpPressed: volumeControl.volumeUp()
168 onBothVolumeKeysPressed: screenGrabber.capture()
173 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
174 dialogs.onPowerKeyPressed();
175 event.accepted = true;
177 volumeKeyFilter.onKeyPressed(event.key);
178 event.accepted = false;
183 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
184 dialogs.onPowerKeyReleased();
185 event.accepted = true;
187 volumeKeyFilter.onKeyReleased(event.key);
188 event.accepted = false;
197 height: parent.height
198 visible: !ApplicationManager.empty
201 target: ApplicationManager
204 if (appId === "dialer-app" && callManager.hasCalls && greeter.locked) {
205 // If we are in the middle of a call, make dialer lockedApp and show it.
206 // This can happen if user backs out of dialer back to greeter, then
207 // launches dialer again.
211 greeter.notifyAppFocused(appId);
214 onFocusedApplicationIdChanged: {
215 greeter.notifyFocusChanged(ApplicationManager.focusedApplicationId);
216 panel.indicators.hide();
219 onApplicationAdded: {
220 if (edgeDemo.running && appId != "unity8-dash") {
221 // If this happens on first boot, we may be in edge
222 // tutorial or wizard while receiving a call. But a call
223 // is more important than wizard so just bail out of those.
224 edgeDemo.hideEdgeDemos();
228 greeter.notifyAppAdded(appId);
234 id: applicationsDisplayLoader
235 objectName: "applicationsDisplayLoader"
238 // When we have a locked app, we only want to show that one app.
239 // FIXME: do this in a less traumatic way. We currently only allow
240 // locked apps in phone mode (see FIXME in Lockscreen component in
241 // this same file). When that changes, we need to do something
242 // nicer here. But this code is currently just to prevent a
243 // theoretical attack where user enters lockedApp mode, then makes
244 // the screen larger (maybe connects to monitor) and tries to enter
246 property bool tabletMode: shell.sideStageEnabled && !greeter.hasLockedApp
247 source: tabletMode ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
250 target: applicationsDisplayLoader.item
251 property: "objectName"
255 target: applicationsDisplayLoader.item
256 property: "dragAreaWidth"
257 value: shell.edgeSize
260 target: applicationsDisplayLoader.item
261 property: "maximizedAppTopMargin"
262 // Not just using panel.panelHeight as that changes depending on the focused app.
263 value: panel.indicators.minimizedPanelHeight + units.dp(2) // dp(2) for orange line
266 target: applicationsDisplayLoader.item
267 property: "interactive"
268 value: edgeDemo.stagesEnabled && !greeter.fullyShown && panel.indicators.fullyClosed && launcher.progress == 0 && !notifications.useModal
271 target: applicationsDisplayLoader.item
272 property: "spreadEnabled"
273 value: edgeDemo.stagesEnabled && !greeter.hasLockedApp
276 target: applicationsDisplayLoader.item
277 property: "inverseProgress"
278 value: launcher.progress
281 target: applicationsDisplayLoader.item
282 property: "orientation"
283 value: shell.orientation
290 objectName: "inputMethod"
291 anchors { fill: parent; topMargin: panel.panelHeight }
292 z: notifications.useModal || panel.indicators.shown ? overlay.z + 1 : overlay.z - 1
296 target: SurfaceManager
298 if (surface.type == MirSurfaceItem.InputMethod) {
299 inputMethod.surface = surface;
303 onSurfaceDestroyed: {
304 if (inputMethod.surface == surface) {
305 inputMethod.surface = null;
306 surface.parent = null;
308 if (!surface.parent) {
309 // there's no one displaying it. delete it right away
315 target: SessionManager
317 if (!session.parentSession && !session.application) {
318 // nothing is using it. delete it right away
326 objectName: "greeter"
328 hides: [launcher, panel.indicators]
329 tabletMode: shell.sideStageEnabled
330 launcherOffset: narrowMode ? launcher.progress : 0
331 forcedUnlock: edgeDemo.running
332 background: shell.background
335 anchors.topMargin: panel.panelHeight
341 onTease: launcher.tease()
342 onEmergencyCall: startLockedApp("dialer-app")
345 target: ApplicationManager
346 property: "suspended"
347 value: greeter.fullyShown
356 if (shell.locked && callManager.hasCalls) {
357 // We just received an incoming call while locked. The
358 // indicator will have already launched dialer-app for us, but
359 // there is a race between "hasCalls" changing and the dialer
360 // starting up. So in case we lose that race, we'll start/
361 // focus the dialer ourselves here too. Even if the indicator
362 // didn't launch the dialer for some reason (or maybe a call
363 // started via some other means), if an active call is
364 // happening, we want to be in the dialer.
365 startLockedApp("dialer-app")
375 if (Powerd.status === Powerd.Off && reason !== Powerd.Proximity &&
376 !callManager.hasCalls && !edgeDemo.running) {
382 function showHome() {
383 if (edgeDemo.running) {
387 if (LightDM.Greeter.active) {
388 greeter.startUnlock()
391 var animate = !LightDM.Greeter.active && !stages.shown
392 dash.setCurrentScope(0, animate, false)
393 ApplicationManager.requestFocusApplication("unity8-dash")
396 function showDash() {
397 if (greeter.hasLockedApp || // just in case user gets here
398 (!greeter.narrowMode && shell.locked)) {
407 if (ApplicationManager.focusedApplicationId != "unity8-dash") {
408 ApplicationManager.requestFocusApplication("unity8-dash")
422 anchors.fill: parent //because this draws indicator menus
425 available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && !greeter.hasLockedApp
426 contentEnabled: edgeDemo.panelContentEnabled
427 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
429 minimizedPanelHeight: units.gu(3)
430 expandedPanelHeight: units.gu(7)
432 indicatorsModel: visibleIndicators.model
436 id: visibleIndicators
437 // TODO: This should be sourced by device type (eg "desktop", "tablet", "phone"...)
438 Component.onCompleted: initialise(indicatorProfile)
441 greeterShown: greeter.fullyShown
444 property bool topmostApplicationIsFullscreen:
445 ApplicationManager.focusedApplicationId &&
446 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
448 fullscreenMode: (topmostApplicationIsFullscreen && !LightDM.Greeter.active && launcher.progress == 0)
449 || greeter.hasLockedApp
454 objectName: "launcher"
456 readonly property bool dashSwipe: progress > 0
458 anchors.top: parent.top
459 anchors.bottom: parent.bottom
461 dragAreaWidth: shell.edgeSize
462 available: edgeDemo.launcherEnabled && (!shell.locked || AccountsService.enableLauncherWhileLocked) && !greeter.hasLockedApp
464 onShowDashHome: showHome()
466 onDashSwipeChanged: {
468 dash.setCurrentScope(0, false, true)
471 onLauncherApplicationSelected: {
472 if (!edgeDemo.running) {
473 greeter.notifyAboutToStartApp(appId);
474 shell.activateApplication(appId)
479 panel.indicators.hide()
487 background: shell.background
491 id: modalNotificationBackground
493 visible: notifications.useModal && (notifications.state == "narrow")
506 model: NotificationBackend.Model
509 y: topmostIsFullscreen ? 0 : panel.panelHeight
511 height: parent.height - (topmostIsFullscreen ? 0 : panel.panelHeight)
516 when: overlay.width <= units.gu(60)
517 AnchorChanges { target: notifications; anchors.left: parent.left }
521 when: overlay.width > units.gu(60)
522 AnchorChanges { target: notifications; anchors.left: undefined }
523 PropertyChanges { target: notifications; width: units.gu(38) }
534 shutdownFadeOutRectangle.enabled = true;
535 shutdownFadeOutRectangle.visible = true;
536 shutdownFadeOut.start();
542 objectName: "edgeDemo"
544 paused: Powerd.status === Powerd.Off || wizard.active // Saves power
552 target: SessionBroadcast
553 onShowHome: showHome()
557 id: shutdownFadeOutRectangle
564 NumberAnimation on opacity {
569 if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
570 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