2
* Copyright 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/>.
20
import "../../../qml/Components"
21
import Unity.Application 0.1
22
import Ubuntu.Components 0.1
23
import Unity.Test 0.1 as UT
28
height: stageRect.height
30
// Even though we replace the ApplicationScreenshot instances in Stage
31
// with our own fake ones, ApplicationScreenshot.qml still gives out a warning
32
// if shell.importUbuntuApplicationAvailable is missing.
33
// For we have this here for the sake of keeping a clean log output.
36
property bool importUbuntuApplicationAvailable: false
39
// A fake ApplicationManager implementation to be passed to Stage
42
property ListModel mainStageApplications: ListModel {}
43
property ListModel sideStageApplications: ListModel {}
44
property var mainStageFocusedApplication
46
property Component fakeAppWindowComponent: Component {
50
property alias text : txt.text
55
function activateApplication(desktopFile, argument) {
56
var appWindow = fakeAppWindowComponent.createObject(fakeWindowContainer)
59
'handle': desktopFile,
62
'desktopFile': desktopFile,
63
'stage': ApplicationInfo.MainStage,
68
appWindow.color = application.color
69
appWindow.text = desktopFile + " actual";
71
mainStageApplications.append(application)
72
updateZOrderOfWindows(mainStageApplications)
77
function focusApplication(application) {
78
mainStageFocusedApplication = application
81
function getApplicationFromDesktopFile(desktopFile, stageType) {
82
var sideStage = (stage == ApplicationInfo.SideStage);
83
var applications = sideStage ? sideStageApplications
84
: mainStageApplications;
86
for (var i = 0; i < applications.count; i++ ) {
87
var application = applications.get(i);
88
if (application.desktopFile === desktopFile) {
95
function moveRunningApplicationStackPosition(from, to, stage) {
96
var sideStage = (stage == ApplicationInfo.SideStage);
97
var applications = sideStage ? sideStageApplications
98
: mainStageApplications;
100
if (from !== to && applications.count > 0 && from >= 0 && to >= 0) {
101
applications.move(from, to, 1);
104
updateZOrderOfWindows(applications)
107
function updateZOrderOfWindows(applications) {
109
for (var i = 0; i < applications.count; i++ ) {
110
var application = applications.get(i);
111
application.window.z = nextZ--;
115
function deacticateApplication(desktopFile) {
116
for (var i = 0; i < mainStageApplications.count; i++ ) {
117
var application = mainStageApplications.get(i)
118
if (application.desktopFile === desktopFile) {
119
focusApplication(null)
120
application.window.destroy();
121
mainStageApplications.remove(i)
122
updateZOrderOfWindows(mainStageApplications)
133
width: childrenRect.width
134
height: childrenRect.height
138
// This is where the fake windows are held.
139
// They stay behind the stage, so that the stage's screenshots are shown
141
// On a real usage scenario, the current application's surface is composited behind
142
// the shell's surface (where Stage lives). fakeWindowContainer simulates this stacking
144
id: fakeWindowContainer
149
// A black rectangle behind the stage so that the window switch animations
150
// look good, just like in Stage's real usage.
154
visible: stage.usingScreenshots
160
shouldUseScreenshots: false
161
applicationManager: fakeAppManager
162
rightEdgeDraggingAreaWidth: units.gu(2)
165
newApplicationScreenshot: FakeApplicationScreenshot {
169
height: stage.height - stage.y}
170
oldApplicationScreenshot: FakeApplicationScreenshot {
174
height: stage.height - stage.y}
180
anchors.top: parent.top
181
anchors.bottom: parent.bottom
182
anchors.left: stageRect.right
183
anchors.right: parent.right
189
AppControl {id: redControl; desktopFile:"red"}
190
AppControl {id: greenControl; desktopFile:"green"}
191
AppControl {id: blueControl; desktopFile:"blue"}
199
function isCurrentAppFadingOut() {
200
// it should get a bit translucent and smaller
201
return oldAppScreenshot.opacity < 0.99
202
&& oldAppScreenshot.opacity >= 0.1
203
&& oldAppScreenshot.scale < 0.99
204
&& oldAppScreenshot.scale >= 0.1
205
&& oldAppScreenshot.visible
209
redControl.checked = false;
210
greenControl.checked = false;
211
blueControl.checked = false;
212
// give some room for animations to start
214
// wait until animations end, if any
215
tryCompare(stage, "usingScreenshots", false)
218
/* If you flick from the right edge of the stage leftwards it should cause an
219
application switch. */
220
function test_dragFromRightEdgeToSwitchApplication() {
221
redControl.checked = true
223
tryCompare(stage, "usingScreenshots", true) // wait for the animation to start
224
tryCompare(stage, "usingScreenshots", false) // and then for it to end
225
compare(fakeAppManager.mainStageFocusedApplication.desktopFile, "red")
226
compare(fakeAppManager.mainStageApplications.get(0).desktopFile, "red")
228
greenControl.checked = true
230
tryCompare(stage, "usingScreenshots", true) // wait for the animation to start
231
tryCompare(stage, "usingScreenshots", false) // and then for it to end
232
compare(fakeAppManager.mainStageFocusedApplication.desktopFile, "green")
233
compare(fakeAppManager.mainStageApplications.get(0).desktopFile, "green")
235
var touchX = stage.width - (stage.rightEdgeDraggingAreaWidth / 2)
236
var touchY = stage.height / 2
237
touchFlick(stage, touchX, touchY, stage.width * 0.25, touchY)
239
// wait until animations end, if any
240
tryCompare(stage, "usingScreenshots", false)
242
// "red" should be the new topmost, focused, application
243
compare(fakeAppManager.mainStageFocusedApplication.desktopFile, "red")
244
compare(fakeAppManager.mainStageApplications.get(0).desktopFile, "red")
247
/* When an application is launched, it needs a background before it's drawn on screen
248
so that the user does not see the previous running app while the new one is launching.
249
When switching between applications, backgrounds are unnecessary, 'cause the
250
applications are in front of them. */
251
function test_background() {
252
redControl.checked = true
253
tryCompare(stage, "usingScreenshots", true) // wait for the animation to start
255
compare(newAppScreenshot.withBackground, true, "starting app screenshot does not have background enabled")
257
tryCompare(stage, "usingScreenshots", false) // wait for the animation to finish
259
greenControl.checked = true
260
tryCompare(stage, "usingScreenshots", true) // wait for the animation to start
261
tryCompare(stage, "usingScreenshots", false) // and finish
263
var draggingAreaCenterX = stage.width - (stage.rightEdgeDraggingAreaWidth / 2)
264
var draggingAreaCenterY = stage.height / 2
265
var finalTouchX = draggingAreaCenterX - units.gu(5)
266
touchFlick(stage, draggingAreaCenterX, draggingAreaCenterY,
267
finalTouchX, draggingAreaCenterY,
268
true /* beginTouch */, false /* endTouch */)
270
// wait for the animation to start
271
tryCompare(stage, "usingScreenshots", true)
273
compare(newAppScreenshot.withBackground, false, "switched app does have background enabled")
275
touchRelease(stage, finalTouchX, draggingAreaCenterY)