diff options
Diffstat (limited to 'tests/auto/qml/windowitem2/tst_windowitem2.qml')
-rw-r--r-- | tests/auto/qml/windowitem2/tst_windowitem2.qml | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/tests/auto/qml/windowitem2/tst_windowitem2.qml b/tests/auto/qml/windowitem2/tst_windowitem2.qml new file mode 100644 index 00000000..51759539 --- /dev/null +++ b/tests/auto/qml/windowitem2/tst_windowitem2.qml @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtApplicationManager module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.3 +import QtTest 1.0 +import QtApplicationManager.SystemUI 2.0 + +Item { + id: root + width: 500 + height: 500 + visible: true + + WindowItem { + id: windowItem + } + + Connections { + target: WindowManager + function onWindowAdded(window) { + windowItem.window = window; + } + + function onWindowAboutToBeRemoved(window) { + if (window === windowItem.window) { + windowItem.window = null; + } + } + } + + // Force redraws so that pings and other events are quickly processed between + // wayland client and server. + Rectangle { + width: 10 + height: 10 + color: "brown" + RotationAnimator on rotation { + from: 0; to: 360; duration: 1000 + loops: Animation.Infinite + running: true + } + } + + TestCase { + id: testCase + when: windowShown + name: "WindowItem2" + + function init() { + } + + function cleanup() { + waitUntilAllAppsAreStopped(); + } + + function waitUntilAllAppsAreStopped() { + while (true) { + var numRunningApps = 0; + for (var i = 0; i < ApplicationManager.count; i++) { + var app = ApplicationManager.application(i); + if (app.runState !== Am.NotRunning) + numRunningApps += 1; + } + + if (numRunningApps > 0) { + wait(50); + } else + break; + } + } + + /* + The sequence below only takes place if WindowManager has direct connections to + Window::isBeingDisplayedChanged and Window::contentStateChanged and those connections call + WindowManager::removeWindow: + + 1. When Window.contentState changes to Window::NoSurface, WindowManager calls removeWindow() on it. + 2. Inside WindowManager::removeWindow, windowAboutToBeRemoved gets emitted. + 3. The onWindowAboutToBeRemoved signal handler above is called and sets WindowItem.window to null + 4. That causes Window.isBeingDisplayedChanged to turn to false, which in turn gets + WindowManager to call removeWindow() on that same window once again. + 5. The innermost removeWindow() from 4 successfuly executes and removes the window from WindowManager's + internal vector + 6. once the outermost removeWindow() from 1. finally goes past the signal emission from 2. and tries + to remove the item from for index it previously collected, that index is no longer valid as the vector + already changed. Then you either are removing the wrong item or trying to remove a now invalid index, + which causes a crash. + + This is a regression test for such crash + */ + function test_triggerNestedRemoval() { + var app = ApplicationManager.application("test.windowitem2.app"); + app.start(); + + tryVerify(function() { return windowItem.window !== null }); + wait(50); + + app.stop(); + } + + } +} |