@@ -1,5 +1,5 @@
2− * Copyright (C) 2013-2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -131,9 +131,6 @@ Rectangle {
131 anchors.right: root.right
131 anchors.right: root.right
132 width: units.gu(30)
132 width: units.gu(30)
134− property var focusedApp: ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
135− property var focusedSurface: focusedApp && focusedApp.session ? focusedApp.session.lastSurface : null
137 Rectangle {
134 Rectangle {
138 id: controlRect
135 id: controlRect
139 anchors { left: parent.left; right: parent.right }
136 anchors { left: parent.left; right: parent.right }
@@ -185,6 +182,17 @@ Rectangle {
186+ text: "Show Launcher"
187+ activeFocusOnPress: false
189+ if (shellLoader.status !== Loader.Ready)
192+ var launcher = testCase.findChild(shellLoader.item, "launcher");
193+ launcher.state = "visible";
188 ListItem.ItemSelector {
196 ListItem.ItemSelector {
189 anchors { left: parent.left; right: parent.right }
197 anchors { left: parent.left; right: parent.right }
190 activeFocusOnPress: false
198 activeFocusOnPress: false
@@ -274,21 +282,21 @@ Rectangle {
274 id: fullscreeAppCheck
282 id: fullscreeAppCheck
276 onTriggered: {
284 onTriggered: {
277− if (!controls.focusedSurface) return;
285+ if (!MirFocusController.focusedSurface) return;
278− if (controls.focusedSurface.state == Mir.FullscreenState) {
286+ if (MirFocusController.focusedSurface.state == Mir.FullscreenState) {
279− controls.focusedSurface.state = Mir.RestoredState;
287+ MirFocusController.focusedSurface.state = Mir.RestoredState;
281− controls.focusedSurface.state = Mir.FullscreenState;
289+ MirFocusController.focusedSurface.state = Mir.FullscreenState;
285 Binding {
293 Binding {
286 target: fullscreeAppCheck
294 target: fullscreeAppCheck
287− when: controls.focusedSurface
295+ when: MirFocusController.focusedSurface
288 property: "checked"
296 property: "checked"
290− if (!controls.focusedSurface) return false;
298+ if (!MirFocusController.focusedSurface) return false;
291− return controls.focusedSurface.state === Mir.FullscreenState
299+ return MirFocusController.focusedSurface.state === Mir.FullscreenState
@@ -302,21 +310,21 @@ Rectangle {
302 id: chromeAppCheck
310 id: chromeAppCheck
304 onTriggered: {
312 onTriggered: {
305− if (!controls.focusedSurface) return;
313+ if (!MirFocusController.focusedSurface) return;
306− if (controls.focusedSurface.shellChrome == Mir.LowChrome) {
314+ if (MirFocusController.focusedSurface.shellChrome == Mir.LowChrome) {
307− controls.focusedSurface.setShellChrome(Mir.NormalChrome);
315+ MirFocusController.focusedSurface.setShellChrome(Mir.NormalChrome);
309− controls.focusedSurface.setShellChrome(Mir.LowChrome);
317+ MirFocusController.focusedSurface.setShellChrome(Mir.LowChrome);
313 Binding {
321 Binding {
314 target: chromeAppCheck
322 target: chromeAppCheck
315− when: controls.focusedSurface !== null
323+ when: MirFocusController.focusedSurface !== null
316 property: "checked"
324 property: "checked"
318− if (!controls.focusedSurface) return false;
326+ if (!MirFocusController.focusedSurface) return false;
319− controls.focusedSurface.shellChrome === Mir.LowChrome
327+ MirFocusController.focusedSurface.shellChrome === Mir.LowChrome
@@ -381,12 +389,6 @@ Rectangle {
381 signalName: "actionInvoked"
389 signalName: "actionInvoked"
386− target: ApplicationManager
387− signalName: "applicationRemoved"
390 Telephony.CallEntry {
392 Telephony.CallEntry {
391 id: phoneCall
393 id: phoneCall
392 phoneNumber: "+447812221111"
394 phoneNumber: "+447812221111"
@@ -412,6 +414,7 @@ Rectangle {
412 when: windowShown
414 when: windowShown
414 property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
416 property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
417+ property QtObject topLevelSurfaceList: null
416 function init() {
419 function init() {
417 if (shellLoader.active) {
420 if (shellLoader.active) {
@@ -449,6 +452,9 @@ Rectangle {
449 panel.dismissTimer = fakeDismissTimer;
452 panel.dismissTimer = fakeDismissTimer;
451 waitForGreeterToStabilize();
454 waitForGreeterToStabilize();
456+ topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
457+ verify(topLevelSurfaceList);
454 function loadDesktopShellWithApps() {
460 function loadDesktopShellWithApps() {
@@ -463,7 +469,9 @@ Rectangle {
463 var app5 = ApplicationManager.startApplication("camera-app")
469 var app5 = ApplicationManager.startApplication("camera-app")
464 var app6 = ApplicationManager.startApplication("gallery-app")
470 var app6 = ApplicationManager.startApplication("gallery-app")
465 var app7 = ApplicationManager.startApplication("calendar-app")
471 var app7 = ApplicationManager.startApplication("calendar-app")
472+ for (var i = 0; i < topLevelSurfaceList.count; ++i) {
466− waitUntilAppWindowIsFullyLoaded(app7);
473+ waitUntilAppWindowIsFullyLoaded(topLevelSurfaceList.idAt(i));
469 function waitForGreeterToStabilize() {
477 function waitForGreeterToStabilize() {
@@ -503,7 +511,7 @@ Rectangle {
503 Wizard.System.wizardEnabled = false;
511 Wizard.System.wizardEnabled = false;
505 // kill all (fake) running apps
513 // kill all (fake) running apps
506− killApps(ApplicationManager);
514+ killApps();
508 unlockAllModemsSpy.clear()
516 unlockAllModemsSpy.clear()
509 LightDM.Greeter.authenticate(""); // reset greeter
517 LightDM.Greeter.authenticate(""); // reset greeter
@@ -511,26 +519,25 @@ Rectangle {
511 sessionSpy.clear();
519 sessionSpy.clear();
513 GSettingsController.setLifecycleExemptAppids([]);
521 GSettingsController.setLifecycleExemptAppids([]);
516− function killApps() {
523+ // there should be only unity8-dash window over there
517− while (ApplicationManager.count > 1) {
524+ tryCompare(ApplicationManager, "count", 1);
518− var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
519− ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
521− compare(ApplicationManager.count, 1)
525+ compare(ApplicationManager.get(0).appId, "unity8-dash");
524 function test_snapDecisionDismissalReturnsFocus() {
528 function test_snapDecisionDismissalReturnsFocus() {
525 loadShell("phone");
529 loadShell("phone");
526 swipeAwayGreeter();
530 swipeAwayGreeter();
527 var notifications = findChild(shell, "notificationList");
531 var notifications = findChild(shell, "notificationList");
532+ var appSurfaceId = topLevelSurfaceList.nextId;
528 var app = ApplicationManager.startApplication("camera-app");
533 var app = ApplicationManager.startApplication("camera-app");
534+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
529 var stage = findChild(shell, "stage")
535 var stage = findChild(shell, "stage")
530− // Open an application and focus
536+
531− waitUntilApplicationWindowIsFullyVisible(app);
537+ var appSurface = app.surfaceList.get(0);
532− ApplicationManager.focusApplication(app);
538+ verify(appSurface);
533− tryCompare(app.session.lastSurface, "activeFocus", true);
540+ tryCompare(appSurface, "activeFocus", true);
535 notifications.model = mockNotificationsModel;
542 notifications.model = mockNotificationsModel;
@@ -552,7 +559,7 @@ Rectangle {
552 waitForRendering(notification);
559 waitForRendering(notification);
554 // Make sure activeFocus went away from the app window
561 // Make sure activeFocus went away from the app window
555− tryCompare(app.session.lastSurface, "activeFocus", false);
562+ tryCompare(appSurface, "activeFocus", false);
556 tryCompare(stage, "interactive", false);
563 tryCompare(stage, "interactive", false);
558 // Clicking the button should dismiss the notification and return focus
565 // Clicking the button should dismiss the notification and return focus
@@ -560,7 +567,7 @@ Rectangle {
560 mouseClick(buttonAccept);
567 mouseClick(buttonAccept);
562 // Make sure we're back to normal
569 // Make sure we're back to normal
563− tryCompare(app.session.lastSurface, "activeFocus", true);
570+ tryCompare(appSurface, "activeFocus", true);
564 compare(stage.interactive, true, "Stages not interactive again after modal notification has closed");
571 compare(stage.interactive, true, "Stages not interactive again after modal notification has closed");
@@ -618,10 +625,9 @@ Rectangle {
618 loadShell("phone");
625 loadShell("phone");
619 swipeAwayGreeter();
626 swipeAwayGreeter();
620 dragLauncherIntoView();
627 dragLauncherIntoView();
628+ var appSurfaceId = topLevelSurfaceList.nextId;
621 tapOnAppIconInLauncher();
629 tapOnAppIconInLauncher();
622− waitUntilApplicationWindowIsFullyVisible();
630+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
623− ApplicationManager.focusApplication(data.focusedApp)
624− waitUntilApplicationWindowIsFullyVisible();
626 var greeter = findChild(shell, "greeter");
632 var greeter = findChild(shell, "greeter");
627 if (data.greeterShown) {
633 if (data.greeterShown) {
@@ -637,16 +643,18 @@ Rectangle {
637 waitUntilDashIsFocused();
643 waitUntilDashIsFocused();
638 tryCompare(greeter, "shown", false);
644 tryCompare(greeter, "shown", false);
640− waitUntilApplicationWindowIsFullyVisible();
641 compare(greeter.fullyShown, data.greeterShown);
646 compare(greeter.fullyShown, data.greeterShown);
644 var launcher = findChild(shell, "launcherPanel");
649 var launcher = findChild(shell, "launcherPanel");
645 tryCompare(launcher, "x", data.launcherHides ? -launcher.width : 0)
650 tryCompare(launcher, "x", data.launcherHides ? -launcher.width : 0)
652+ //FIXME: This check fails. Don't understand the rationale behind it.
647 // Make sure the helper for sliding out the launcher wasn't touched. We want to fade it out here.
654 // Make sure the helper for sliding out the launcher wasn't touched. We want to fade it out here.
648 var animateTimer = findInvisibleChild(shell, "animateTimer");
655 var animateTimer = findInvisibleChild(shell, "animateTimer");
649 compare(animateTimer.nextState, "visible");
656 compare(animateTimer.nextState, "visible");
652 function test_tabletLeftEdgeDrag_data() {
660 function test_tabletLeftEdgeDrag_data() {
@@ -673,10 +681,11 @@ Rectangle {
673 dragLauncherIntoView();
681 dragLauncherIntoView();
674 dashCommunicatorSpy.clear();
682 dashCommunicatorSpy.clear();
684+ var appSurfaceId = topLevelSurfaceList.nextId;
676 tapOnAppIconInLauncher();
685 tapOnAppIconInLauncher();
677− waitUntilApplicationWindowIsFullyVisible();
686+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
679− verify(ApplicationManager.focusedApplicationId !== "unity8-dash")
688+ tryCompareFunction(function() { return ApplicationManager.focusedApplicationId !== "unity8-dash"; }, true);
681 //Long left swipe
690 //Long left swipe
682 swipeFromLeftEdge(units.gu(30));
691 swipeFromLeftEdge(units.gu(30));
@@ -709,8 +718,9 @@ Rectangle {
710 // Launch an app from the launcher
719 // Launch an app from the launcher
711 dragLauncherIntoView();
720 dragLauncherIntoView();
721+ var appSurfaceId = topLevelSurfaceList.nextId;
712 tapOnAppIconInLauncher();
722 tapOnAppIconInLauncher();
713− waitUntilApplicationWindowIsFullyVisible();
723+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
715 var mainAppId = ApplicationManager.focusedApplicationId;
725 var mainAppId = ApplicationManager.focusedApplicationId;
716 verify(mainAppId != "");
726 verify(mainAppId != "");
@@ -835,9 +845,9 @@ Rectangle {
835 dragLauncherIntoView();
845 dragLauncherIntoView();
837 // Launch an app from the launcher
847 // Launch an app from the launcher
848+ var appSurfaceId = topLevelSurfaceList.nextId;
838 tapOnAppIconInLauncher();
849 tapOnAppIconInLauncher();
839−
850+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
840− waitUntilApplicationWindowIsFullyVisible();
842 verify(ApplicationManager.focusedApplicationId !== "unity8-dash")
852 verify(ApplicationManager.focusedApplicationId !== "unity8-dash")
@@ -873,10 +883,22 @@ Rectangle {
873 tryCompare(item, "visible", false);
883 tryCompare(item, "visible", false);
886+ function findAppWindowForSurfaceId(surfaceId) {
887+ // for PhoneStage and TabletStage
888+ var delegate = findChild(shell, "spreadDelegate_" + surfaceId);
891+ delegate = findChild(shell, "appDelegate_" + surfaceId);
894+ var appWindow = findChild(delegate, "appWindow");
876 // Wait until the ApplicationWindow for the given Application object is fully loaded
898 // Wait until the ApplicationWindow for the given Application object is fully loaded
877 // (ie, the real surface has replaced the splash screen)
899 // (ie, the real surface has replaced the splash screen)
878− function waitUntilAppWindowIsFullyLoaded(app) {
900+ function waitUntilAppWindowIsFullyLoaded(surfaceId) {
879− var appWindow = findChild(shell, "appWindow_" + app.appId);
901+ var appWindow = findAppWindowForSurfaceId(surfaceId);
880 var appWindowStateGroup = findInvisibleChild(appWindow, "applicationWindowStateGroup");
902 var appWindowStateGroup = findInvisibleChild(appWindow, "applicationWindowStateGroup");
881 tryCompareFunction(function() { return appWindowStateGroup.state === "surface" }, true);
903 tryCompareFunction(function() { return appWindowStateGroup.state === "surface" }, true);
882 waitUntilTransitionsEnd(appWindowStateGroup);
904 waitUntilTransitionsEnd(appWindowStateGroup);
@@ -885,10 +907,13 @@ Rectangle {
885 function test_surfaceLosesActiveFocusWhilePanelIsOpen() {
907 function test_surfaceLosesActiveFocusWhilePanelIsOpen() {
886 loadShell("phone");
908 loadShell("phone");
887 swipeAwayGreeter();
909 swipeAwayGreeter();
910+ var appSurfaceId = topLevelSurfaceList.nextId;
888 var app = ApplicationManager.startApplication("dialer-app");
911 var app = ApplicationManager.startApplication("dialer-app");
889− waitUntilAppWindowIsFullyLoaded(app);
912+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
913+ var appSurface = app.surfaceList.get(0);
891− tryCompare(app.session.lastSurface, "activeFocus", true);
916+ tryCompare(appSurface, "activeFocus", true);
893 // Drag the indicators panel half-open
918 // Drag the indicators panel half-open
894 var touchX = shell.width / 2;
919 var touchX = shell.width / 2;
@@ -899,7 +924,7 @@ Rectangle {
899 true /* beginTouch */, false /* endTouch */);
924 true /* beginTouch */, false /* endTouch */);
900 verify(indicators.partiallyOpened);
925 verify(indicators.partiallyOpened);
902− tryCompare(app.session.lastSurface, "activeFocus", false);
927+ tryCompare(appSurface, "activeFocus", false);
904 // And finish getting it open
929 // And finish getting it open
905 touchFlick(indicators,
930 touchFlick(indicators,
@@ -908,11 +933,11 @@ Rectangle {
908 false /* beginTouch */, true /* endTouch */);
933 false /* beginTouch */, true /* endTouch */);
909 tryCompare(indicators, "fullyOpened", true);
934 tryCompare(indicators, "fullyOpened", true);
911− tryCompare(app.session.lastSurface, "activeFocus", false);
936+ tryCompare(appSurface, "activeFocus", false);
913 dragToCloseIndicatorsPanel();
938 dragToCloseIndicatorsPanel();
915− tryCompare(app.session.lastSurface, "activeFocus", true);
940+ tryCompare(appSurface, "activeFocus", true);
918 function test_launchedAppHasActiveFocus_data() {
943 function test_launchedAppHasActiveFocus_data() {
@@ -928,54 +953,44 @@ Rectangle {
928 shell.usageScenario = data.usageScenario;
953 shell.usageScenario = data.usageScenario;
929 swipeAwayGreeter();
954 swipeAwayGreeter();
956+ var webAppSurfaceId = topLevelSurfaceList.nextId;
931 var webApp = ApplicationManager.startApplication("webbrowser-app");
957 var webApp = ApplicationManager.startApplication("webbrowser-app");
932 verify(webApp);
958 verify(webApp);
933− waitUntilAppSurfaceShowsUp("webbrowser-app")
959+ waitUntilAppWindowIsFullyLoaded(webAppSurfaceId);
935− verify(webApp.session.lastSurface);
961+ var webAppSurface = webApp.surfaceList.get(topLevelSurfaceList.indexForId(webAppSurfaceId));
962+ verify(webAppSurface);
937− tryCompare(webApp.session.lastSurface, "activeFocus", true);
964+ tryCompare(webAppSurface, "activeFocus", true);
940 function test_launchedAppKeepsActiveFocusOnUsageModeChange() {
967 function test_launchedAppKeepsActiveFocusOnUsageModeChange() {
941 loadShell("tablet");
968 loadShell("tablet");
942 swipeAwayGreeter();
969 swipeAwayGreeter();
971+ var webAppSurfaceId = topLevelSurfaceList.nextId;
944 var webApp = ApplicationManager.startApplication("webbrowser-app");
972 var webApp = ApplicationManager.startApplication("webbrowser-app");
945 verify(webApp);
973 verify(webApp);
946− waitUntilAppSurfaceShowsUp("webbrowser-app")
974+ waitUntilAppWindowIsFullyLoaded(webAppSurfaceId);
948− verify(webApp.session.lastSurface);
976+ var webAppSurface = webApp.surfaceList.get(topLevelSurfaceList.indexForId(webAppSurfaceId));
977+ verify(webAppSurface);
950− tryCompare(webApp.session.lastSurface, "activeFocus", true);
979+ tryCompare(webAppSurface, "activeFocus", true);
952 shell.usageScenario = "desktop";
981 shell.usageScenario = "desktop";
954 // check that the desktop stage and window have been loaded
983 // check that the desktop stage and window have been loaded
955− {
984+ waitUntilAppWindowIsFullyLoaded(webAppSurfaceId);
956− var desktopWindow = findChild(shell, "appWindow_webbrowser-app");
957− verify(desktopWindow);
960− tryCompare(webApp.session.lastSurface, "activeFocus", true);
986+ tryCompare(webAppSurface, "activeFocus", true);
962 shell.usageScenario = "tablet";
988 shell.usageScenario = "tablet";
964 // check that the tablet stage and app surface delegate have been loaded
990 // check that the tablet stage and app surface delegate have been loaded
965− {
991+ waitUntilAppWindowIsFullyLoaded(webAppSurfaceId);
966− var desktopWindow = findChild(shell, "tabletSpreadDelegate_webbrowser-app");
967− verify(desktopWindow);
970− tryCompare(webApp.session.lastSurface, "activeFocus", true);
993+ tryCompare(webAppSurface, "activeFocus", true);
973− function waitUntilAppSurfaceShowsUp(appId) {
974− var appWindow = findChild(shell, "appWindow_" + appId);
976− var appWindowStates = findInvisibleChild(appWindow, "applicationWindowStateGroup");
977− verify(appWindowStates);
978− tryCompare(appWindowStates, "state", "surface");
981 function dragToCloseIndicatorsPanel() {
996 function dragToCloseIndicatorsPanel() {
@@ -1025,12 +1040,6 @@ Rectangle {
1028− function waitUntilApplicationWindowIsFullyVisible() {
1029− var appDelegate = findChild(shell, "appDelegate0")
1030− var surfaceContainer = findChild(appDelegate, "surfaceContainer");
1031− tryCompareFunction(function() { return surfaceContainer.surface !== null; }, true);
1034 function waitUntilDashIsFocused() {
1043 function waitUntilDashIsFocused() {
1035 tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
1044 tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
@@ -1087,9 +1096,9 @@ Rectangle {
1087 swipeAwayGreeter();
1096 swipeAwayGreeter();
1088 var greeter = findChild(shell, "greeter");
1097 var greeter = findChild(shell, "greeter");
1099+ var appSurfaceId = topLevelSurfaceList.nextId;
1090 var app = ApplicationManager.startApplication("dialer-app");
1100 var app = ApplicationManager.startApplication("dialer-app");
1091− // wait until the app is fully loaded (ie, real surface replaces splash screen)
1101+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
1092− tryCompareFunction(function() { return app.session !== null && app.session.lastSurface !== null }, true);
1094 // Minimize the application we just launched
1103 // Minimize the application we just launched
1095 swipeFromLeftEdge(shell.width * 0.75);
1104 swipeFromLeftEdge(shell.width * 0.75);
@@ -1150,13 +1159,17 @@ Rectangle {
1150 swipeAwayGreeter();
1159 swipeAwayGreeter();
1151 var panel = findChild(shell, "panel");
1160 var panel = findChild(shell, "panel");
1152 compare(panel.fullscreenMode, false);
1161 compare(panel.fullscreenMode, false);
1162+ var cameraSurfaceId = topLevelSurfaceList.nextId;
1153− ApplicationManager.startApplication("camera-app");
1163+ var cameraApp = ApplicationManager.startApplication("camera-app");
1164+ waitUntilAppWindowIsFullyLoaded(cameraSurfaceId);
1154 tryCompare(panel, "fullscreenMode", true);
1165 tryCompare(panel, "fullscreenMode", true);
1166+ var dialerSurfaceId = topLevelSurfaceList.nextId;
1155− ApplicationManager.startApplication("dialer-app");
1167+ var dialerApp = ApplicationManager.startApplication("dialer-app");
1168+ waitUntilAppWindowIsFullyLoaded(dialerSurfaceId);
1156 tryCompare(panel, "fullscreenMode", false);
1169 tryCompare(panel, "fullscreenMode", false);
1157− ApplicationManager.requestFocusApplication("camera-app");
1170+ ApplicationManager.requestFocusApplication(cameraApp.appId);
1158 tryCompare(panel, "fullscreenMode", true);
1171 tryCompare(panel, "fullscreenMode", true);
1159− ApplicationManager.requestFocusApplication("dialer-app");
1172+ ApplicationManager.requestFocusApplication(dialerApp.appId);
1160 tryCompare(panel, "fullscreenMode", false);
1173 tryCompare(panel, "fullscreenMode", false);
@@ -1227,24 +1240,32 @@ Rectangle {
1227 var tutorial = findChild(shell, "tutorial");
1240 var tutorial = findChild(shell, "tutorial");
1228 tryCompare(wizard, "active", true);
1241 tryCompare(wizard, "active", true);
1229 tryCompare(tutorial, "running", true);
1242 tryCompare(tutorial, "running", true);
1230− tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
1243+ tryCompareFunction(function() { return topLevelSurfaceList.applicationAt(0).appId; }, "unity8-dash");
1232− // Make sure we stay running when nothing focused (can happen for
1245+ // Make sure we stay running when there's no top level window (can happen for
1233 // a moment when we restart the dash after switching language)
1246 // a moment when we restart the dash after switching language)
1234− ApplicationManager.stopApplication("unity8-dash");
1247+ var dashApplication = ApplicationManager.findApplication("unity8-dash");
1235− tryCompare(ApplicationManager, "focusedApplicationId", "");
1248+ ApplicationManager.stopApplication(dashApplication.appId);
1249+ // wait until all zombie surfaces are gone. As MirSurfaceItems hold references over them.
1250+ // They won't be gone until those surface items are destroyed.
1251+ tryCompareFunction(function() { return dashApplication.surfaceList.count }, 0);
1253+ tryCompare(topLevelSurfaceList, "count", 0);
1236 compare(wizard.shown, true);
1254 compare(wizard.shown, true);
1237 compare(tutorial.running, true);
1255 compare(tutorial.running, true);
1239− // And make sure we stay running when dash focused again
1257+ // And make sure we stay running when dash comes back again
1258+ var dashSurfaceId = topLevelSurfaceList.nextId;
1240− ApplicationManager.startApplication("unity8-dash");
1259+ ApplicationManager.startApplication(dashApplication.appId);
1241− tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
1260+ waitUntilAppWindowIsFullyLoaded(dashSurfaceId);
1242 compare(wizard.shown, true);
1261 compare(wizard.shown, true);
1243 compare(tutorial.running, true);
1262 compare(tutorial.running, true);
1245− // And make sure we stop when something else is focused
1264+ // And make sure we stop when some other surface shows app
1265+ var gallerySurfaceId = topLevelSurfaceList.nextId;
1246− ApplicationManager.startApplication("gallery-app");
1266+ var galleryApp = ApplicationManager.startApplication("gallery-app");
1247− tryCompare(ApplicationManager, "focusedApplicationId", "gallery-app");
1267+ waitUntilAppWindowIsFullyLoaded(gallerySurfaceId);
1268+ tryCompareFunction(function() { return topLevelSurfaceList.applicationAt(0).appId; }, "gallery-app");
1248 compare(wizard.shown, false);
1269 compare(wizard.shown, false);
1249 compare(tutorial.running, false);
1270 compare(tutorial.running, false);
1250 tryCompare(AccountsService, "demoEdges", false);
1271 tryCompare(AccountsService, "demoEdges", false);
@@ -1269,7 +1290,7 @@ Rectangle {
1269 function test_tapOnRightEdgeReachesApplicationSurface() {
1290 function test_tapOnRightEdgeReachesApplicationSurface() {
1270 loadShell("phone");
1291 loadShell("phone");
1271 swipeAwayGreeter();
1292 swipeAwayGreeter();
1272− var topmostSpreadDelegate = findChild(shell, "appDelegate0");
1293+ var topmostSpreadDelegate = findChild(shell, "spreadDelegate_" + topLevelSurfaceList.idAt(0));
1273 verify(topmostSpreadDelegate);
1294 verify(topmostSpreadDelegate);
1275 waitUntilFocusedApplicationIsShowingItsSurface();
1296 waitUntilFocusedApplicationIsShowingItsSurface();
@@ -1298,7 +1319,7 @@ Rectangle {
1298 function test_rightEdgeDragDoesNotReachApplicationSurface() {
1319 function test_rightEdgeDragDoesNotReachApplicationSurface() {
1299 loadShell("phone");
1320 loadShell("phone");
1300 swipeAwayGreeter();
1321 swipeAwayGreeter();
1301− var topmostSpreadDelegate = findChild(shell, "appDelegate0");
1322+ var topmostSpreadDelegate = findChild(shell, "spreadDelegate_" + topLevelSurfaceList.idAt(0));
1302 var topmostSurfaceItem = findChild(topmostSpreadDelegate, "surfaceItem");
1323 var topmostSurfaceItem = findChild(topmostSpreadDelegate, "surfaceItem");
1303 var rightEdgeDragArea = findChild(shell, "spreadDragArea");
1324 var rightEdgeDragArea = findChild(shell, "spreadDragArea");
@@ -1318,7 +1339,7 @@ Rectangle {
1319 function waitUntilFocusedApplicationIsShowingItsSurface()
1340 function waitUntilFocusedApplicationIsShowingItsSurface()
1321− var spreadDelegate = findChild(shell, "appDelegate0");
1342+ var spreadDelegate = findChild(shell, "spreadDelegate_" + topLevelSurfaceList.idAt(0));
1322 var appState = findInvisibleChild(spreadDelegate, "applicationWindowStateGroup");
1343 var appState = findInvisibleChild(spreadDelegate, "applicationWindowStateGroup");
1323 tryCompare(appState, "state", "surface");
1344 tryCompare(appState, "state", "surface");
1324 var transitions = appState.transitions;
1345 var transitions = appState.transitions;
@@ -1467,11 +1488,13 @@ Rectangle {
1467 loadShell("tablet");
1488 loadShell("tablet");
1468 shell.usageScenario = "desktop";
1489 shell.usageScenario = "desktop";
1491+ var webBrowserSurfaceId = topLevelSurfaceList.nextId;
1470 var webBrowserApp = ApplicationManager.startApplication("webbrowser-app");
1492 var webBrowserApp = ApplicationManager.startApplication("webbrowser-app");
1471− waitUntilAppWindowIsFullyLoaded(webBrowserApp);
1493+ waitUntilAppWindowIsFullyLoaded(webBrowserSurfaceId);
1495+ var gallerySurfaceId = topLevelSurfaceList.nextId;
1473 var galleryApp = ApplicationManager.startApplication("gallery-app");
1496 var galleryApp = ApplicationManager.startApplication("gallery-app");
1474− waitUntilAppWindowIsFullyLoaded(galleryApp);
1497+ waitUntilAppWindowIsFullyLoaded(gallerySurfaceId);
1476 ApplicationManager.requestFocusApplication("unity8-dash");
1499 ApplicationManager.requestFocusApplication("unity8-dash");
1477 tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
1500 tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
@@ -1489,11 +1512,13 @@ Rectangle {
1489 loadShell("tablet");
1512 loadShell("tablet");
1490 shell.usageScenario = "tablet";
1513 shell.usageScenario = "tablet";
1515+ var webBrowserSurfaceId = topLevelSurfaceList.nextId;
1492 var webBrowserApp = ApplicationManager.startApplication("webbrowser-app");
1516 var webBrowserApp = ApplicationManager.startApplication("webbrowser-app");
1493− waitUntilAppWindowIsFullyLoaded(webBrowserApp);
1517+ waitUntilAppWindowIsFullyLoaded(webBrowserSurfaceId);
1519+ var gallerySurfaceId = topLevelSurfaceList.nextId;
1495 var galleryApp = ApplicationManager.startApplication("gallery-app");
1520 var galleryApp = ApplicationManager.startApplication("gallery-app");
1496− waitUntilAppWindowIsFullyLoaded(galleryApp);
1521+ waitUntilAppWindowIsFullyLoaded(gallerySurfaceId);
1498 ApplicationManager.requestFocusApplication("unity8-dash");
1523 ApplicationManager.requestFocusApplication("unity8-dash");
1499 tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
1524 tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
@@ -1523,17 +1548,26 @@ Rectangle {
1523 var desktopStage = findChild(shell, "stage");
1548 var desktopStage = findChild(shell, "stage");
1524 verify(desktopStage != null)
1549 verify(desktopStage != null)
1551+ var app1SurfaceId = topLevelSurfaceList.nextId;
1526 var app1 = ApplicationManager.startApplication("dialer-app")
1552 var app1 = ApplicationManager.startApplication("dialer-app")
1527− waitUntilAppWindowIsFullyLoaded(app1);
1553+ waitUntilAppWindowIsFullyLoaded(app1SurfaceId);
1555+ var app2SurfaceId = topLevelSurfaceList.nextId;
1528 var app2 = ApplicationManager.startApplication("webbrowser-app")
1556 var app2 = ApplicationManager.startApplication("webbrowser-app")
1529− waitUntilAppWindowIsFullyLoaded(app2);
1557+ waitUntilAppWindowIsFullyLoaded(app2SurfaceId);
1558+ var app2Surface = app2.surfaceList.get(0);
1559+ verify(app2Surface);
1561+ var app3SurfaceId = topLevelSurfaceList.nextId;
1530 var app3 = ApplicationManager.startApplication("camera-app")
1562 var app3 = ApplicationManager.startApplication("camera-app")
1531− waitUntilAppWindowIsFullyLoaded(app3);
1563+ waitUntilAppWindowIsFullyLoaded(app3SurfaceId);
1564+ var app3Surface = app3.surfaceList.get(0);
1565+ verify(app3Surface);
1533 // Do a quick alt-tab and see if focus changes
1567 // Do a quick alt-tab and see if focus changes
1534− tryCompare(app3.session.lastSurface, "activeFocus", true)
1568+ tryCompare(app3Surface, "activeFocus", true)
1535 keyClick(Qt.Key_Tab, Qt.AltModifier)
1569 keyClick(Qt.Key_Tab, Qt.AltModifier)
1536− tryCompare(app2.session.lastSurface, "activeFocus", true)
1570+ tryCompare(app2Surface, "activeFocus", true)
1538 // Press Alt+Tab
1572 // Press Alt+Tab
1539 keyPress(Qt.Key_Alt);
1573 keyPress(Qt.Key_Alt);
@@ -1541,7 +1575,7 @@ Rectangle {
1541 keyRelease(Qt.Key_Alt)
1575 keyRelease(Qt.Key_Alt)
1543 // Focus should have switched back now
1577 // Focus should have switched back now
1544− tryCompare(app3.session.lastSurface, "activeFocus", true)
1578+ tryCompare(app3Surface, "activeFocus", true)
1547 function test_altTabWrapAround() {
1581 function test_altTabWrapAround() {
@@ -1590,7 +1624,9 @@ Rectangle {
1590 tryCompare(desktopSpread, "state", "")
1624 tryCompare(desktopSpread, "state", "")
1592 // Make sure that after wrapping around once, we have the same one focused as at the beginning
1626 // Make sure that after wrapping around once, we have the same one focused as at the beginning
1593− tryCompare(focused.session.lastSurface, "activeFocus", true)
1627+ var focusedAppSurface = focused.surfaceList.get(0);
1628+ verify(focusedAppSurface);
1629+ tryCompare(focusedAppSurface, "activeFocus", true)
1596 function test_altBackTabNavigation() {
1632 function test_altBackTabNavigation() {
@@ -1624,7 +1660,7 @@ Rectangle {
1624 keyRelease(Qt.Key_Alt);
1660 keyRelease(Qt.Key_Alt);
1627− function test_highlightFollowsMouse() {
1663+ function otest_highlightFollowsMouse() {
1628 loadDesktopShellWithApps()
1664 loadDesktopShellWithApps()
1630 var spreadRepeater = findInvisibleChild(shell, "spreadRepeater");
1666 var spreadRepeater = findInvisibleChild(shell, "spreadRepeater");
@@ -1661,9 +1697,7 @@ Rectangle {
1661 keyPress(Qt.Key_Alt)
1697 keyPress(Qt.Key_Alt)
1662 keyClick(Qt.Key_Tab);
1698 keyClick(Qt.Key_Tab);
1664− appRemovedSpy.clear();
1700+ var surfaceId = topLevelSurfaceList.idAt(2);
1666− var closedAppId = ApplicationManager.get(2).appId;
1667 var spreadDelegate2 = spreadRepeater.itemAt(2);
1701 var spreadDelegate2 = spreadRepeater.itemAt(2);
1668 var closeMouseArea = findChild(spreadDelegate2, "closeMouseArea");
1702 var closeMouseArea = findChild(spreadDelegate2, "closeMouseArea");
@@ -1678,12 +1712,14 @@ Rectangle {
1679 tryCompare(closeMouseArea, "enabled", true)
1713 tryCompare(closeMouseArea, "enabled", true)
1715+ var countBeforeClickingCloseButton = topLevelSurfaceList.count;
1716+ verify(topLevelSurfaceList.indexForId(surfaceId) === 2);
1681 // Close the app using the close button
1718 // Close the app using the close button
1682 mouseClick(closeMouseArea, closeMouseArea.width / 2, closeMouseArea.height / 2)
1719 mouseClick(closeMouseArea, closeMouseArea.width / 2, closeMouseArea.height / 2)
1684− // Verify applicationRemoved has been emitted correctly
1721+ tryCompare(topLevelSurfaceList, "count", countBeforeClickingCloseButton - 1);
1685− tryCompare(appRemovedSpy, "count", 1)
1722+ verify(topLevelSurfaceList.indexForId(surfaceId) === -1);
1686− compare(appRemovedSpy.signalArguments[0][0], closedAppId);
1688 keyRelease(Qt.Key_Alt);
1724 keyRelease(Qt.Key_Alt);
@@ -1708,7 +1744,7 @@ Rectangle {
1708 keyPress(Qt.Key_Alt)
1744 keyPress(Qt.Key_Alt)
1709 keyClick(Qt.Key_Tab);
1745 keyClick(Qt.Key_Tab);
1711− var focusAppId = ApplicationManager.get(2).appId;
1747+ var surface = topLevelSurfaceList.surfaceAt(2);
1712 var spreadDelegate2 = spreadRepeater.itemAt(2);
1748 var spreadDelegate2 = spreadRepeater.itemAt(2);
1713 var clippedSpreadDelegate = findChild(spreadDelegate2, "clippedSpreadDelegate");
1749 var clippedSpreadDelegate = findChild(spreadDelegate2, "clippedSpreadDelegate");
@@ -1730,7 +1766,7 @@ Rectangle {
1731 // Verify that we left the spread and app2 is the focused one now
1767 // Verify that we left the spread and app2 is the focused one now
1732 tryCompare(stage, "state", "");
1768 tryCompare(stage, "state", "");
1733− tryCompare(ApplicationManager, "focusedApplicationId", focusAppId);
1769+ tryCompare(surface, "focused", true);
1735 keyRelease(Qt.Key_Alt);
1771 keyRelease(Qt.Key_Alt);
@@ -1794,7 +1830,7 @@ Rectangle {
1794 function test_workspacePreviewsHighlightedApp() {
1830 function test_workspacePreviewsHighlightedApp() {
1795 loadDesktopShellWithApps()
1831 loadDesktopShellWithApps()
1797− var targetZ = ApplicationManager.count + 1;
1833+ var targetZ = topLevelSurfaceList.count + 1;
1799 var spreadRepeater = findInvisibleChild(shell, "spreadRepeater");
1835 var spreadRepeater = findInvisibleChild(shell, "spreadRepeater");
1800 verify(spreadRepeater !== null);
1836 verify(spreadRepeater !== null);
@@ -1870,7 +1906,8 @@ Rectangle {
1870 loadDesktopShellWithApps();
1906 loadDesktopShellWithApps();
1872 var appRepeater = findChild(shell, "appRepeater")
1908 var appRepeater = findChild(shell, "appRepeater")
1873− var appId = ApplicationManager.get(0).appId;
1909+ var application = topLevelSurfaceList.applicationAt(0);
1910+ var surfaceId = topLevelSurfaceList.idAt(0);
1874 var appDelegate = appRepeater.itemAt(0);
1911 var appDelegate = appRepeater.itemAt(0);
1875 var maximizeButton = findChild(appDelegate, "maximizeWindowButton");
1912 var maximizeButton = findChild(appDelegate, "maximizeWindowButton");
@@ -1881,17 +1918,20 @@ Rectangle {
1881 tryCompare(appDelegate, "state", "maximized");
1918 tryCompare(appDelegate, "state", "maximized");
1882 tryCompare(PanelState, "buttonsVisible", true)
1919 tryCompare(PanelState, "buttonsVisible", true)
1884− ApplicationManager.stopApplication(appId);
1921+ ApplicationManager.stopApplication(application.appId);
1885 tryCompare(PanelState, "buttonsVisible", false)
1922 tryCompare(PanelState, "buttonsVisible", false)
1924+ // wait until all zombie surfaces are gone. As MirSurfaceItems hold references over them.
1925+ // They won't be gone until those surface items are destroyed.
1926+ tryCompareFunction(function() { return application.surfaceList.count }, 0);
1887− ApplicationManager.startApplication(appId);
1928+ ApplicationManager.startApplication(application.appId);
1888 tryCompare(PanelState, "buttonsVisible", true)
1929 tryCompare(PanelState, "buttonsVisible", true)
1891 function test_newAppHasValidGeometry() {
1932 function test_newAppHasValidGeometry() {
1892 loadDesktopShellWithApps();
1933 loadDesktopShellWithApps();
1893 var appRepeater = findChild(shell, "appRepeater");
1934 var appRepeater = findChild(shell, "appRepeater");
1894− var appId = ApplicationManager.get(0).appId;
1895 var appDelegate = appRepeater.itemAt(0);
1935 var appDelegate = appRepeater.itemAt(0);
1897 var resizeArea = findChild(appDelegate, "windowResizeArea");
1937 var resizeArea = findChild(appDelegate, "windowResizeArea");
@@ -1908,7 +1948,6 @@ Rectangle {
1908 function test_switchToStagedHidesPanelButtons() {
1948 function test_switchToStagedHidesPanelButtons() {
1909 loadDesktopShellWithApps();
1949 loadDesktopShellWithApps();
1910 var appRepeater = findChild(shell, "appRepeater")
1950 var appRepeater = findChild(shell, "appRepeater")
1911− var appId = ApplicationManager.get(0).appId;
1912 var appDelegate = appRepeater.itemAt(0);
1951 var appDelegate = appRepeater.itemAt(0);
1913 var panelButtons = findChild(shell, "panelWindowControlButtons")
1952 var panelButtons = findChild(shell, "panelWindowControlButtons")
@@ -1925,7 +1964,6 @@ Rectangle {
1925 function test_lockingGreeterHidesPanelButtons() {
1964 function test_lockingGreeterHidesPanelButtons() {
1926 loadDesktopShellWithApps();
1965 loadDesktopShellWithApps();
1927 var appRepeater = findChild(shell, "appRepeater")
1966 var appRepeater = findChild(shell, "appRepeater")
1928− var appId = ApplicationManager.get(0).appId;
1929 var appDelegate = appRepeater.itemAt(0);
1967 var appDelegate = appRepeater.itemAt(0);
1930 var panelButtons = findChild(shell, "panelWindowControlButtons")
1968 var panelButtons = findChild(shell, "panelWindowControlButtons")
@@ -1955,12 +1993,15 @@ Rectangle {
1955 shell.usageScenario = "desktop";
1993 shell.usageScenario = "desktop";
1956 waitForRendering(shell);
1994 waitForRendering(shell);
1996+ var appSurfaceId = topLevelSurfaceList.nextId;
1958 var app = ApplicationManager.startApplication("dialer-app")
1997 var app = ApplicationManager.startApplication("dialer-app")
1959− waitUntilAppWindowIsFullyLoaded(app);
1998+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
1961 var appContainer = findChild(shell, "appContainer");
2000 var appContainer = findChild(shell, "appContainer");
2001+ verify(appContainer);
1962− var appDelegate = findChild(appContainer, "appDelegate_dialer-app");
2002+ var appDelegate = findChild(appContainer, "appDelegate_" + appSurfaceId);
2003+ verify(appDelegate);
1963− var decoration = findChild(appDelegate, "appWindowDecoration_dialer-app");
2004+ var decoration = findChild(appDelegate, "appWindowDecoration");
1964 verify(decoration);
2005 verify(decoration);
1966 // move it away from launcher and panel
2007 // move it away from launcher and panel
@@ -1978,18 +2019,22 @@ Rectangle {
1978 function test_restoreWindowStateFixesIfUnderPanel() {
2019 function test_restoreWindowStateFixesIfUnderPanel() {
1979 loadDesktopShellWithApps();
2020 loadDesktopShellWithApps();
1980 var appRepeater = findChild(shell, "appRepeater")
2021 var appRepeater = findChild(shell, "appRepeater")
1981− var appId = ApplicationManager.get(0).appId;
2022+ var application = topLevelSurfaceList.applicationAt(0);
1982 var appDelegate = appRepeater.itemAt(0);
2023 var appDelegate = appRepeater.itemAt(0);
1984 // Move it under the panel programmatically (might happen later with an alt+drag)
2025 // Move it under the panel programmatically (might happen later with an alt+drag)
1985 appDelegate.y = -units.gu(10)
2026 appDelegate.y = -units.gu(10)
1987− ApplicationManager.stopApplication(appId)
2028+ ApplicationManager.stopApplication(application.appId);
2029+ // wait until all zombie surfaces are gone. As MirSurfaceItems hold references over them.
2030+ // They won't be gone until those surface items are destroyed.
2031+ tryCompareFunction(function() { return application.surfaceList.count }, 0);
1988− ApplicationManager.startApplication(appId)
2033+ ApplicationManager.startApplication(application.appId);
1989 waitForRendering(shell)
2034 waitForRendering(shell)
1991 // Make sure the newly started one is at index 0 again
2036 // Make sure the newly started one is at index 0 again
1992− tryCompare(ApplicationManager.get(0), "appId", appId);
2037+ tryCompareFunction(function () { return topLevelSurfaceList.applicationAt(0).appId; }, application.appId);
1994 appDelegate = appRepeater.itemAt(0);
2039 appDelegate = appRepeater.itemAt(0);
1995 compare(appDelegate.y >= PanelState.panelHeight, true);
2040 compare(appDelegate.y >= PanelState.panelHeight, true);
@@ -2008,16 +2053,22 @@ Rectangle {
2009 // Add two main stage apps, the second in order to suspend the first.
2054 // Add two main stage apps, the second in order to suspend the first.
2010 // LibreOffice has isTouchApp set to false by our mocks.
2055 // LibreOffice has isTouchApp set to false by our mocks.
2056+ var app1SurfaceId = topLevelSurfaceList.nextId;
2011 var app1 = ApplicationManager.startApplication("libreoffice");
2057 var app1 = ApplicationManager.startApplication("libreoffice");
2012− waitUntilAppWindowIsFullyLoaded(app1);
2058+ waitUntilAppWindowIsFullyLoaded(app1SurfaceId);
2059+ var app2SurfaceId = topLevelSurfaceList.nextId;
2013 var app2 = ApplicationManager.startApplication("gallery-app");
2060 var app2 = ApplicationManager.startApplication("gallery-app");
2014− waitUntilAppWindowIsFullyLoaded(app2);
2061+ waitUntilAppWindowIsFullyLoaded(app2SurfaceId);
2016 // Sanity checking
2063 // Sanity checking
2017 compare(app1.stage, ApplicationInfoInterface.MainStage);
2064 compare(app1.stage, ApplicationInfoInterface.MainStage);
2018 compare(app2.stage, ApplicationInfoInterface.MainStage);
2065 compare(app2.stage, ApplicationInfoInterface.MainStage);
2019 verify(!app1.isTouchApp);
2066 verify(!app1.isTouchApp);
2068+ var app1Surface = app1.surfaceList.get(0);
2069+ verify(app1Surface);
2020− verify(!app1.session.lastSurface.activeFocus);
2071+ verify(!app1Surface.activeFocus);
2022 // Make sure app1 is exempt with a requested suspend
2073 // Make sure app1 is exempt with a requested suspend
2023 verify(app1.exemptFromLifecycle);
2074 verify(app1.exemptFromLifecycle);
@@ -2038,15 +2089,21 @@ Rectangle {
2038 GSettingsController.setLifecycleExemptAppids(["webbrowser-app"]);
2089 GSettingsController.setLifecycleExemptAppids(["webbrowser-app"]);
2040 // Add two main stage apps, the second in order to suspend the first
2091 // Add two main stage apps, the second in order to suspend the first
2092+ var app1SurfaceId = topLevelSurfaceList.nextId;
2041 var app1 = ApplicationManager.startApplication("webbrowser-app");
2093 var app1 = ApplicationManager.startApplication("webbrowser-app");
2042− waitUntilAppWindowIsFullyLoaded(app1);
2094+ waitUntilAppWindowIsFullyLoaded(app1SurfaceId);
2095+ var app2SurfaceId = topLevelSurfaceList.nextId;
2043 var app2 = ApplicationManager.startApplication("gallery-app");
2096 var app2 = ApplicationManager.startApplication("gallery-app");
2044− waitUntilAppWindowIsFullyLoaded(app2);
2097+ waitUntilAppWindowIsFullyLoaded(app2SurfaceId);
2046 // Sanity checking
2099 // Sanity checking
2047 compare(app1.stage, ApplicationInfoInterface.MainStage);
2100 compare(app1.stage, ApplicationInfoInterface.MainStage);
2048 compare(app2.stage, ApplicationInfoInterface.MainStage);
2101 compare(app2.stage, ApplicationInfoInterface.MainStage);
2103+ var app1Surface = app1.surfaceList.get(0);
2104+ verify(app1Surface);
2049− verify(!app1.session.lastSurface.activeFocus);
2106+ verify(!app1Surface.activeFocus);
2051 // Make sure app1 is exempt with a requested suspend
2108 // Make sure app1 is exempt with a requested suspend
2052 verify(app1.exemptFromLifecycle);
2109 verify(app1.exemptFromLifecycle);
@@ -2205,9 +2262,10 @@ Rectangle {
2205 var appContainer = findChild(shell, "appContainer");
2262 var appContainer = findChild(shell, "appContainer");
2206 var launcher = findChild(shell, "launcher");
2263 var launcher = findChild(shell, "launcher");
2265+ var appSurfaceId = topLevelSurfaceList.nextId;
2208 var app = ApplicationManager.startApplication("music-app");
2266 var app = ApplicationManager.startApplication("music-app");
2209− waitUntilAppWindowIsFullyLoaded(app);
2267+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
2210− var appDelegate = findChild(appContainer, "appDelegate_music-app");
2268+ var appDelegate = findChild(appContainer, "appDelegate_" + appSurfaceId);
2211 appDelegate.maximize();
2269 appDelegate.maximize();
2212 tryCompare(appDelegate, "visuallyMaximized", true);
2270 tryCompare(appDelegate, "visuallyMaximized", true);
2213 waitForRendering(shell);
2271 waitForRendering(shell);
@@ -2235,8 +2293,18 @@ Rectangle {
2236 tryCompare(launcher, "lockedVisible", true);
2294 tryCompare(launcher, "lockedVisible", true);
2296+ var surfaceId = topLevelSurfaceList.nextId;
2238− var cameraApp = ApplicationManager.startApplication("camera-app");
2297+ var app = ApplicationManager.startApplication("gmail-webapp");
2239− waitUntilAppWindowIsFullyLoaded(cameraApp);
2299+ waitUntilAppWindowIsFullyLoaded(surfaceId);
2301+ // Sanity check: ensure the fake app we chose creates a surface the way
2302+ // we expect it to.
2303+ compare(app.surfaceList.get(0).shellChrome, Mir.NormalChrome);
2305+ compare(launcher.lockedVisible, true);
2307+ app.surfaceList.get(0).state = Mir.FullscreenState;
2241 tryCompare(launcher, "lockedVisible", false);
2309 tryCompare(launcher, "lockedVisible", false);
@@ -2257,8 +2325,9 @@ Rectangle {
2257 swipeAwayGreeter();
2325 swipeAwayGreeter();
2259 // Let's open a fullscreen app
2327 // Let's open a fullscreen app
2328+ var appSurfaceId = topLevelSurfaceList.nextId;
2260 var app = ApplicationManager.startApplication("camera-app");
2329 var app = ApplicationManager.startApplication("camera-app");
2261− waitUntilAppWindowIsFullyLoaded(app);
2330+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
2263 var appRepeater = findChild(shell, data.repeaterName);
2332 var appRepeater = findChild(shell, data.repeaterName);
2264 var topmostAppDelegate = appRepeater.itemAt(0);
2333 var topmostAppDelegate = appRepeater.itemAt(0);
@@ -2295,19 +2364,21 @@ Rectangle {
2295 AccountsService.keymaps = ["sk", "cz+qwerty", "fr"] // "configure" the keymaps for user
2364 AccountsService.keymaps = ["sk", "cz+qwerty", "fr"] // "configure" the keymaps for user
2297 // start some app
2366 // start some app
2367+ var appSurfaceId = topLevelSurfaceList.nextId;
2298 var app = ApplicationManager.startApplication("dialer-app");
2368 var app = ApplicationManager.startApplication("dialer-app");
2299− waitUntilAppWindowIsFullyLoaded(app);
2369+ waitUntilAppWindowIsFullyLoaded(appSurfaceId);
2370+ var appSurface = app.surfaceList.get(0);
2301 // verify the initial keymap of the newly started app is the first one from the list
2372 // verify the initial keymap of the newly started app is the first one from the list
2302− tryCompare(app.session.lastSurface, "keymap", "sk");
2373+ tryCompare(appSurface, "keymap", "sk");
2304 // switch to next keymap, should go to "cz+qwerty"
2375 // switch to next keymap, should go to "cz+qwerty"
2305 keyClick(Qt.Key_Space, Qt.MetaModifier);
2376 keyClick(Qt.Key_Space, Qt.MetaModifier);
2306− tryCompare(app.session.lastSurface, "keymap", "cz+qwerty");
2377+ tryCompare(appSurface, "keymap", "cz+qwerty");
2308 // switch to next keymap, should go to "fr"
2379 // switch to next keymap, should go to "fr"
2309 keyClick(Qt.Key_Space, Qt.MetaModifier);
2380 keyClick(Qt.Key_Space, Qt.MetaModifier);
2310− tryCompare(app.session.lastSurface, "keymap", "fr");
2381+ tryCompare(appSurface, "keymap", "fr");
2312 // go to e.g. desktop stage
2383 // go to e.g. desktop stage
2313 loadShell("desktop");
2384 loadShell("desktop");
@@ -2315,30 +2386,32 @@ Rectangle {
2315 waitForRendering(shell);
2386 waitForRendering(shell);
2317 // start a second app, should get the last configured keyboard, "fr"
2388 // start a second app, should get the last configured keyboard, "fr"
2389+ var app2SurfaceId = topLevelSurfaceList.nextId;
2318 var app2 = ApplicationManager.startApplication("calendar-app");
2390 var app2 = ApplicationManager.startApplication("calendar-app");
2319− waitUntilAppWindowIsFullyLoaded(app2);
2391+ waitUntilAppWindowIsFullyLoaded(app2SurfaceId);
2392+ var app2Surface = app2.surfaceList.get(0);
2320− tryCompare(app2.session.lastSurface, "keymap", "fr");
2393+ tryCompare(app2Surface, "keymap", "fr");
2322 // focus our first app, make sure it also has the "fr" keymap
2395 // focus our first app, make sure it also has the "fr" keymap
2323 ApplicationManager.requestFocusApplication("dialer-app");
2396 ApplicationManager.requestFocusApplication("dialer-app");
2324− tryCompare(app.session.lastSurface, "keymap", "fr");
2397+ tryCompare(appSurface, "keymap", "fr");
2326 // switch to previous keymap, should be "cz+qwerty"
2399 // switch to previous keymap, should be "cz+qwerty"
2327 keyClick(Qt.Key_Space, Qt.MetaModifier|Qt.ShiftModifier);
2400 keyClick(Qt.Key_Space, Qt.MetaModifier|Qt.ShiftModifier);
2328− tryCompare(app.session.lastSurface, "keymap", "cz+qwerty");
2401+ tryCompare(appSurface, "keymap", "cz+qwerty");
2330 // go next twice to "sk", past the end
2403 // go next twice to "sk", past the end
2331 keyClick(Qt.Key_Space, Qt.MetaModifier);
2404 keyClick(Qt.Key_Space, Qt.MetaModifier);
2332 keyClick(Qt.Key_Space, Qt.MetaModifier);
2405 keyClick(Qt.Key_Space, Qt.MetaModifier);
2333− tryCompare(app.session.lastSurface, "keymap", "sk");
2406+ tryCompare(appSurface, "keymap", "sk");
2335 // go back once to past the beginning, to "fr"
2408 // go back once to past the beginning, to "fr"
2336 keyClick(Qt.Key_Space, Qt.MetaModifier|Qt.ShiftModifier);
2409 keyClick(Qt.Key_Space, Qt.MetaModifier|Qt.ShiftModifier);
2337− tryCompare(app.session.lastSurface, "keymap", "fr");
2410+ tryCompare(appSurface, "keymap", "fr");
2339 // switch to app2, should also get "fr"
2412 // switch to app2, should also get "fr"
2340 ApplicationManager.requestFocusApplication("calendar-app");
2413 ApplicationManager.requestFocusApplication("calendar-app");
2341− tryCompare(app2.session.lastSurface, "keymap", "fr");
2414+ tryCompare(app2Surface, "keymap", "fr");