diff --git a/autotests/integration/CMakeLists.txt b/autotests/integration/CMakeLists.txt --- a/autotests/integration/CMakeLists.txt +++ b/autotests/integration/CMakeLists.txt @@ -44,6 +44,7 @@ integrationTest(NAME testPointerConstraints SRCS pointer_constraints_test.cpp) integrationTest(NAME testKeyboardLayout SRCS keyboard_layout_test.cpp) integrationTest(NAME testKeymapCreationFailure SRCS keymap_creation_failure_test.cpp) +integrationTest(NAME testShowingDesktop SRCS showing_desktop_test.cpp) if (XCB_ICCCM_FOUND) integrationTest(NAME testMoveResize SRCS move_resize_window_test.cpp LIBS XCB::ICCCM) diff --git a/autotests/integration/showing_desktop_test.cpp b/autotests/integration/showing_desktop_test.cpp new file mode 100644 --- /dev/null +++ b/autotests/integration/showing_desktop_test.cpp @@ -0,0 +1,128 @@ +/******************************************************************** +KWin - the KDE window manager +This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "kwin_wayland_test.h" +#include "platform.h" +#include "shell_client.h" +#include "wayland_server.h" +#include "workspace.h" + +#include +#include +#include + +using namespace KWin; +using namespace KWayland::Client; + +static const QString s_socketName = QStringLiteral("wayland_test_kwin_showing_desktop-0"); + +class ShowingDesktopTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void init(); + void cleanup(); + + void testRestoreFocus(); + void testRestoreFocusWithDesktopWindow(); +}; + +void ShowingDesktopTest::initTestCase() +{ + qRegisterMetaType(); + qRegisterMetaType(); + QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); + QVERIFY(workspaceCreatedSpy.isValid()); + kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); + QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit())); + + kwinApp()->start(); + QVERIFY(workspaceCreatedSpy.wait()); + waylandServer()->initWorkspace(); +} + +void ShowingDesktopTest::init() +{ + QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::PlasmaShell)); +} + +void ShowingDesktopTest::cleanup() +{ + Test::destroyWaylandConnection(); +} + +void ShowingDesktopTest::testRestoreFocus() +{ + QScopedPointer surface1(Test::createSurface()); + QScopedPointer shellSurface1(Test::createShellSurface(surface1.data())); + auto client1 = Test::renderAndWaitForShown(surface1.data(), QSize(100, 50), Qt::blue); + QScopedPointer surface2(Test::createSurface()); + QScopedPointer shellSurface2(Test::createShellSurface(surface2.data())); + auto client2 = Test::renderAndWaitForShown(surface2.data(), QSize(100, 50), Qt::blue); + QVERIFY(client1 != client2); + + QCOMPARE(workspace()->activeClient(), client2); + workspace()->slotToggleShowDesktop(); + QVERIFY(workspace()->showingDesktop()); + workspace()->slotToggleShowDesktop(); + QVERIFY(!workspace()->showingDesktop()); + + QVERIFY(workspace()->activeClient()); + QCOMPARE(workspace()->activeClient(), client2); +} + +void ShowingDesktopTest::testRestoreFocusWithDesktopWindow() +{ + // first create a desktop window + + QScopedPointer desktopSurface(Test::createSurface()); + QVERIFY(!desktopSurface.isNull()); + QScopedPointer desktopShellSurface(Test::createShellSurface(desktopSurface.data())); + QVERIFY(!desktopSurface.isNull()); + QScopedPointer plasmaSurface(Test::waylandPlasmaShell()->createSurface(desktopSurface.data())); + QVERIFY(!plasmaSurface.isNull()); + plasmaSurface->setRole(PlasmaShellSurface::Role::Desktop); + + auto desktop = Test::renderAndWaitForShown(desktopSurface.data(), QSize(100, 50), Qt::blue); + QVERIFY(desktop); + QVERIFY(desktop->isDesktop()); + + // now create some windows + QScopedPointer surface1(Test::createSurface()); + QScopedPointer shellSurface1(Test::createShellSurface(surface1.data())); + auto client1 = Test::renderAndWaitForShown(surface1.data(), QSize(100, 50), Qt::blue); + QScopedPointer surface2(Test::createSurface()); + QScopedPointer shellSurface2(Test::createShellSurface(surface2.data())); + auto client2 = Test::renderAndWaitForShown(surface2.data(), QSize(100, 50), Qt::blue); + QVERIFY(client1 != client2); + + QCOMPARE(workspace()->activeClient(), client2); + workspace()->slotToggleShowDesktop(); + QVERIFY(workspace()->showingDesktop()); + QCOMPARE(workspace()->activeClient(), desktop); + workspace()->slotToggleShowDesktop(); + QVERIFY(!workspace()->showingDesktop()); + + QVERIFY(workspace()->activeClient()); + QCOMPARE(workspace()->activeClient(), client2); +} + +WAYLANDTEST_MAIN(ShowingDesktopTest) +#include "showing_desktop_test.moc" diff --git a/workspace.cpp b/workspace.cpp --- a/workspace.cpp +++ b/workspace.cpp @@ -1307,8 +1307,14 @@ } } // ~StackingUpdatesBlocker - if (showing_desktop && topDesk) + if (showing_desktop && topDesk) { requestFocus(topDesk); + } else if (!showing_desktop && changed) { + const auto client = FocusChain::self()->getForActivation(VirtualDesktopManager::self()->current()); + if (client) { + activateClient(client); + } + } if (changed) emit showingDesktopChanged(showing); }