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
39import Unity.Notifications 1.0 as NotificationBackend
40import Unity.Session 0.1
41import Unity.DashCommunicator 0.1
42import Unity.Indicators 0.1 as Indicators
47 // Disable everything while greeter is waiting, so that the user can't swipe
48 // the greeter or launcher until we know whether the session is locked.
49 enabled: !greeter.waiting
51 // this is only here to select the width / height of the window if not running fullscreen
52 property bool tablet: false
53 width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
54 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
56 property real edgeSize: units.gu(2)
57 property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
58 property url background: asImageTester.status == Image.Ready ? asImageTester.source
59 : gsImageTester.status == Image.Ready ? gsImageTester.source : defaultBackground
60 readonly property real panelHeight: panel.panelHeight
62 property bool sideStageEnabled: shell.width >= units.gu(100)
63 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
65 property int orientation
66 readonly property int deviceOrientationAngle: Screen.angleBetween(Screen.primaryOrientation, Screen.orientation)
67 onDeviceOrientationAngleChanged: {
68 if (!OrientationLock.enabled) {
69 orientation = Screen.orientation;
72 readonly property bool orientationLockEnabled: OrientationLock.enabled
73 onOrientationLockEnabledChanged: {
74 if (orientationLockEnabled) {
75 OrientationLock.savedOrientation = Screen.orientation;
77 orientation = Screen.orientation;
81 function activateApplication(appId) {
82 if (ApplicationManager.findApplication(appId)) {
83 ApplicationManager.requestFocusApplication(appId);
85 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
86 ApplicationManager.startApplication(appId, execFlags);
90 function startLockedApp(app) {
92 greeter.lockedApp = app;
94 shell.activateApplication(app);
97 // This is a dummy image to detect if the custom AS set wallpaper loads successfully.
100 source: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : ""
108 id: backgroundSettings
109 objectName: "backgroundSettings"
110 schema.id: "org.gnome.desktop.background"
113 // This is a dummy image to detect if the custom GSettings set wallpaper loads successfully.
116 source: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : ""
124 id: usageModeSettings
125 schema.id: "com.canonical.Unity8"
129 target: LauncherModel
130 property: "applicationManager"
131 value: ApplicationManager
134 Component.onCompleted: {
135 Theme.name = "Ubuntu.Components.Themes.SuruGradient"
136 if (ApplicationManager.count > 0) {
137 ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
139 if (orientationLockEnabled) {
140 orientation = OrientationLock.savedOrientation;
142 Connectivity.unlockAllModems();
151 objectName: "dashCommunicator"
157 enabled: Powerd.status === Powerd.On
161 target: ApplicationManager
162 property: "forceDashActive"
163 value: launcher.shown || launcher.dashSwipe
168 onVolumeDownPressed: volumeControl.volumeDown()
169 onVolumeUpPressed: volumeControl.volumeUp()
170 onBothVolumeKeysPressed: screenGrabber.capture()
175 // Nokia earpieces give TogglePlayPause, while the iPhone's earpiece gives Play
176 if (event.key == Qt.Key_MediaTogglePlayPause || event.key == Qt.Key_MediaPlay) {
177 event.accepted = callManager.handleMediaKey(false);
178 } else if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
179 // FIXME: We only consider power key presses if the screen is
180 // on because of bugs 1410830/1409003. The theory is that when
181 // those bugs are encountered, there is a >2s delay between the
182 // power press event and the power release event, which causes
183 // the shutdown dialog to appear on resume. So to avoid that
184 // symptom while we investigate the root cause, we simply won't
185 // initiate any dialogs when the screen is off.
186 if (Powerd.status === Powerd.On) {
187 dialogs.onPowerKeyPressed();
189 event.accepted = true;
191 volumeKeyFilter.onKeyPressed(event.key);
192 event.accepted = false;
197 if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
198 dialogs.onPowerKeyReleased();
199 event.accepted = true;
201 volumeKeyFilter.onKeyReleased(event.key);
202 event.accepted = false;
211 height: parent.height
212 visible: !ApplicationManager.empty
215 target: ApplicationManager
218 if (appId === "dialer-app" && callManager.hasCalls && greeter.locked) {
219 // If we are in the middle of a call, make dialer lockedApp and show it.
220 // This can happen if user backs out of dialer back to greeter, then
221 // launches dialer again.
222 greeter.lockedApp = appId;
225 greeter.notifyAppFocused(appId);
228 onFocusedApplicationIdChanged: {
229 greeter.notifyAppFocused(ApplicationManager.focusedApplicationId);
230 panel.indicators.hide();
233 onApplicationAdded: {
234 if (edgeDemo.running && appId != "unity8-dash") {
235 // If this happens on first boot, we may be in edge
236 // tutorial or wizard while receiving a call. But a call
237 // is more important than wizard so just bail out of those.
238 edgeDemo.hideEdgeDemos();
242 greeter.notifyAppFocused(appId);
248 id: applicationsDisplayLoader
249 objectName: "applicationsDisplayLoader"
252 // When we have a locked app, we only want to show that one app.
253 // FIXME: do this in a less traumatic way. We currently only allow
254 // locked apps in phone mode (see FIXME in Lockscreen component in
255 // this same file). When that changes, we need to do something
256 // nicer here. But this code is currently just to prevent a
257 // theoretical attack where user enters lockedApp mode, then makes
258 // the screen larger (maybe connects to monitor) and tries to enter
260 property bool tabletMode: shell.sideStageEnabled && !greeter.hasLockedApp
261 source: usageModeSettings.usageMode === "Windowed" ? "Stages/DesktopStage.qml"
262 : tabletMode ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
265 target: applicationsDisplayLoader.item
266 property: "objectName"
270 target: applicationsDisplayLoader.item
271 property: "dragAreaWidth"
272 value: shell.edgeSize
275 target: applicationsDisplayLoader.item
276 property: "maximizedAppTopMargin"
277 // Not just using panel.panelHeight as that changes depending on the focused app.
278 value: panel.indicators.minimizedPanelHeight + units.dp(2) // dp(2) for orange line
281 target: applicationsDisplayLoader.item
282 property: "interactive"
283 value: edgeDemo.stagesEnabled && !greeter.shown && panel.indicators.fullyClosed && launcher.progress == 0 && !notifications.useModal
286 target: applicationsDisplayLoader.item
287 property: "spreadEnabled"
288 value: edgeDemo.stagesEnabled && !greeter.hasLockedApp
291 target: applicationsDisplayLoader.item
292 property: "inverseProgress"
293 value: launcher.progress
296 target: applicationsDisplayLoader.item
297 property: "orientation"
298 value: shell.orientation
301 target: applicationsDisplayLoader.item
302 property: "background"
303 value: shell.background
310 objectName: "inputMethod"
311 anchors { fill: parent; topMargin: panel.panelHeight }
312 z: notifications.useModal || panel.indicators.shown || wizard.active ? overlay.z + 1 : overlay.z - 1
316 target: SurfaceManager
318 if (surface.type == MirSurfaceItem.InputMethod) {
319 inputMethod.surface = surface;
323 onSurfaceDestroyed: {
324 if (inputMethod.surface == surface) {
325 inputMethod.surface = null;
326 surface.parent = null;
328 if (!surface.parent) {
329 // there's no one displaying it. delete it right away
335 target: SessionManager
337 if (!session.parentSession && !session.application) {
338 // nothing is using it. delete it right away
346 objectName: "greeter"
348 hides: [launcher, panel.indicators]
349 tabletMode: shell.sideStageEnabled
350 launcherOffset: launcher.progress
351 forcedUnlock: edgeDemo.running
352 background: shell.background
355 anchors.topMargin: panel.panelHeight
357 // avoid overlapping with Launcher's edge drag area
358 // FIXME: Fix TouchRegistry & friends and remove this workaround
359 // Issue involves launcher's DDA getting disabled on a long
361 dragHandleLeftMargin: launcher.available ? launcher.dragAreaWidth + 1 : 0
367 onTease: launcher.tease()
369 onEmergencyCall: startLockedApp("dialer-app")
372 // See powerConnection for why this is useful
373 id: showGreeterDelayed
381 target: ApplicationManager
382 property: "suspended"
392 if (greeter.locked && callManager.hasCalls && greeter.lockedApp !== "dialer-app") {
393 // We just received an incoming call while locked. The
394 // indicator will have already launched dialer-app for us, but
395 // there is a race between "hasCalls" changing and the dialer
396 // starting up. So in case we lose that race, we'll start/
397 // focus the dialer ourselves here too. Even if the indicator
398 // didn't launch the dialer for some reason (or maybe a call
399 // started via some other means), if an active call is
400 // happening, we want to be in the dialer.
401 startLockedApp("dialer-app")
411 if (Powerd.status === Powerd.Off && reason !== Powerd.Proximity &&
412 !callManager.hasCalls && !edgeDemo.running) {
413 // We don't want to simply call greeter.showNow() here, because
414 // that will take too long. Qt will delay button event
415 // handling until the greeter is done loading and may think the
416 // user held down the power button the whole time, leading to a
417 // power dialog being shown. Instead, delay showing the
418 // greeter until we've finished handling the event. We could
419 // make the greeter load asynchronously instead, but that
420 // introduces a whole host of timing issues, especially with
421 // its animations. So this is simpler.
422 showGreeterDelayed.start();
427 function showHome() {
428 if (edgeDemo.running) {
432 greeter.notifyAboutToFocusApp("unity8-dash");
434 var animate = !LightDM.Greeter.active && !stages.shown
435 dash.setCurrentScope(0, animate, false)
436 ApplicationManager.requestFocusApplication("unity8-dash")
439 function showDash() {
440 if (greeter.active) {
441 greeter.notifyShowingDashFromDrag();
445 if (ApplicationManager.focusedApplicationId != "unity8-dash") {
446 ApplicationManager.requestFocusApplication("unity8-dash")
460 anchors.fill: parent //because this draws indicator menus
463 available: edgeDemo.panelEnabled && (!greeter.locked || AccountsService.enableIndicatorsWhileLocked) && !greeter.hasLockedApp
464 contentEnabled: edgeDemo.panelContentEnabled
465 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
467 minimizedPanelHeight: units.gu(3)
468 expandedPanelHeight: units.gu(7)
470 indicatorsModel: Indicators.IndicatorsModel {
471 Component.onCompleted: load(indicatorProfile);
475 greeterShown: greeter.shown
478 property bool topmostApplicationIsFullscreen:
479 ApplicationManager.focusedApplicationId &&
480 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
482 fullscreenMode: (topmostApplicationIsFullscreen && !LightDM.Greeter.active && launcher.progress == 0)
483 || greeter.hasLockedApp
488 objectName: "launcher"
490 readonly property bool dashSwipe: progress > 0
492 anchors.top: parent.top
493 anchors.topMargin: inverted ? 0 : panel.panelHeight
494 anchors.bottom: parent.bottom
496 dragAreaWidth: shell.edgeSize
497 available: edgeDemo.launcherEnabled && (!greeter.locked || AccountsService.enableLauncherWhileLocked) && !greeter.hasLockedApp
498 inverted: usageModeSettings.usageMode === "Staged"
500 onShowDashHome: showHome()
502 onDashSwipeChanged: {
504 dash.setCurrentScope(0, false, true)
507 onLauncherApplicationSelected: {
508 if (!edgeDemo.running) {
509 greeter.notifyAboutToFocusApp(appId);
510 shell.activateApplication(appId)
515 panel.indicators.hide()
523 background: shell.background
527 id: modalNotificationBackground
529 visible: notifications.useModal && (notifications.state == "narrow")
542 model: NotificationBackend.Model
545 y: topmostIsFullscreen ? 0 : panel.panelHeight
546 height: parent.height - (topmostIsFullscreen ? 0 : panel.panelHeight)
551 when: overlay.width <= units.gu(60)
553 target: notifications
554 anchors.left: parent.left
555 anchors.right: parent.right
560 when: overlay.width > units.gu(60)
562 target: notifications
563 anchors.left: undefined
564 anchors.right: parent.right
566 PropertyChanges { target: notifications; width: units.gu(38) }
577 shutdownFadeOutRectangle.enabled = true;
578 shutdownFadeOutRectangle.visible = true;
579 shutdownFadeOut.start();
585 objectName: "edgeDemo"
587 paused: Powerd.status === Powerd.Off || wizard.active // Saves power
595 target: SessionBroadcast
596 onShowHome: showHome()
600 id: shutdownFadeOutRectangle
607 NumberAnimation on opacity {
612 if (shutdownFadeOutRectangle.enabled && shutdownFadeOutRectangle.visible) {
613 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