From 7016da39c8475ef376c586ee0f1bfd71420a0799 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sat, 28 Aug 2021 21:58:29 +0300 Subject: [PATCH] Move active output tracking to workspace Active output is a window management concept. It indicates what output new windows have to be placed on if they have no output hint. So Workspace seems to be a better place for it than the Screens class, which is obsolete. --- autotests/integration/activation_test.cpp | 2 +- autotests/integration/activities_test.cpp | 2 +- .../integration/decoration_input_test.cpp | 2 +- .../integration/desktop_window_x11_test.cpp | 2 +- .../dont_crash_aurorae_destroy_deco.cpp | 2 +- .../dont_crash_cursor_physical_size_empty.cpp | 2 +- .../integration/dont_crash_empty_deco.cpp | 2 +- .../integration/dont_crash_no_border.cpp | 2 +- .../dont_crash_useractions_menu.cpp | 2 +- .../integration/globalshortcuts_test.cpp | 2 +- .../integration/input_stacking_order.cpp | 2 +- autotests/integration/inputmethod_test.cpp | 2 +- autotests/integration/kwinbindings_test.cpp | 2 +- .../integration/layershellv1client_test.cpp | 2 +- autotests/integration/lockscreen.cpp | 2 +- autotests/integration/maximize_test.cpp | 2 +- .../modifier_only_shortcut_test.cpp | 2 +- .../integration/move_resize_window_test.cpp | 2 +- .../integration/no_global_shortcuts_test.cpp | 2 +- .../integration/outputmanagement_test.cpp | 3 +- autotests/integration/placement_test.cpp | 2 +- autotests/integration/plasmawindow_test.cpp | 2 +- .../integration/pointer_constraints_test.cpp | 2 +- autotests/integration/pointer_input.cpp | 2 +- autotests/integration/quick_tiling_test.cpp | 2 +- autotests/integration/screen_changes_test.cpp | 3 +- .../screenedge_client_show_test.cpp | 2 +- autotests/integration/screens_test.cpp | 134 ++++-------------- autotests/integration/shade_test.cpp | 2 +- autotests/integration/struts_test.cpp | 2 +- autotests/integration/tabbox_test.cpp | 2 +- autotests/integration/touch_input_test.cpp | 2 +- autotests/integration/transient_placement.cpp | 2 +- .../integration/virtual_desktop_test.cpp | 5 +- autotests/integration/window_rules_test.cpp | 2 +- .../integration/window_selection_test.cpp | 2 +- .../integration/xdgshellclient_rules_test.cpp | 2 +- autotests/integration/xdgshellclient_test.cpp | 2 +- autotests/integration/xwayland_input_test.cpp | 2 +- src/abstract_client.cpp | 20 +-- src/activation.cpp | 6 +- src/effects.cpp | 2 +- src/focuschain.cpp | 6 +- src/layershellv1integration.cpp | 2 +- src/options.cpp | 11 ++ src/options.h | 8 ++ src/screens.cpp | 82 ----------- src/screens.h | 35 ----- src/scripting/workspace_wrapper.cpp | 2 +- src/tabbox/switcheritem.cpp | 4 +- src/tabbox/tabbox.cpp | 9 +- src/toplevel.cpp | 2 +- src/useractions.cpp | 6 +- src/workspace.cpp | 43 ++++-- src/workspace.h | 5 + src/x11client.cpp | 6 +- src/xdgshellclient.cpp | 4 +- 57 files changed, 169 insertions(+), 299 deletions(-) diff --git a/autotests/integration/activation_test.cpp b/autotests/integration/activation_test.cpp index 08625a7694..deeb5a21ae 100644 --- a/autotests/integration/activation_test.cpp +++ b/autotests/integration/activation_test.cpp @@ -66,7 +66,7 @@ void ActivationTest::init() { QVERIFY(Test::setupWaylandConnection()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/activities_test.cpp b/autotests/integration/activities_test.cpp index e3bb701c8b..0bc5cbcae7 100644 --- a/autotests/integration/activities_test.cpp +++ b/autotests/integration/activities_test.cpp @@ -76,7 +76,7 @@ void ActivitiesTest::cleanupTestCase() void ActivitiesTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/decoration_input_test.cpp b/autotests/integration/decoration_input_test.cpp index d53e24c093..d0a6eeadc7 100644 --- a/autotests/integration/decoration_input_test.cpp +++ b/autotests/integration/decoration_input_test.cpp @@ -150,7 +150,7 @@ void DecorationInputTest::init() QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat | Test::AdditionalWaylandInterface::Decoration)); QVERIFY(Test::waitForWaylandPointer()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/desktop_window_x11_test.cpp b/autotests/integration/desktop_window_x11_test.cpp index 175c3acd58..3bc0845a54 100644 --- a/autotests/integration/desktop_window_x11_test.cpp +++ b/autotests/integration/desktop_window_x11_test.cpp @@ -60,7 +60,7 @@ void X11DesktopWindowTest::initTestCase() void X11DesktopWindowTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/dont_crash_aurorae_destroy_deco.cpp b/autotests/integration/dont_crash_aurorae_destroy_deco.cpp index fc132cdc2a..bd00aeed98 100644 --- a/autotests/integration/dont_crash_aurorae_destroy_deco.cpp +++ b/autotests/integration/dont_crash_aurorae_destroy_deco.cpp @@ -71,7 +71,7 @@ void DontCrashAuroraeDestroyDecoTest::initTestCase() void DontCrashAuroraeDestroyDecoTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/dont_crash_cursor_physical_size_empty.cpp b/autotests/integration/dont_crash_cursor_physical_size_empty.cpp index 4caaa6caeb..2435f05825 100644 --- a/autotests/integration/dont_crash_cursor_physical_size_empty.cpp +++ b/autotests/integration/dont_crash_cursor_physical_size_empty.cpp @@ -43,7 +43,7 @@ void DontCrashCursorPhysicalSizeEmpty::init() { QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/dont_crash_empty_deco.cpp b/autotests/integration/dont_crash_empty_deco.cpp index 1fe94d0fac..9baf2033b3 100644 --- a/autotests/integration/dont_crash_empty_deco.cpp +++ b/autotests/integration/dont_crash_empty_deco.cpp @@ -62,7 +62,7 @@ void DontCrashEmptyDecorationTest::initTestCase() void DontCrashEmptyDecorationTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/dont_crash_no_border.cpp b/autotests/integration/dont_crash_no_border.cpp index e758111b80..1465b3bdca 100644 --- a/autotests/integration/dont_crash_no_border.cpp +++ b/autotests/integration/dont_crash_no_border.cpp @@ -74,7 +74,7 @@ void DontCrashNoBorder::init() { QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/dont_crash_useractions_menu.cpp b/autotests/integration/dont_crash_useractions_menu.cpp index dd217dbdde..809ae0ea50 100644 --- a/autotests/integration/dont_crash_useractions_menu.cpp +++ b/autotests/integration/dont_crash_useractions_menu.cpp @@ -67,7 +67,7 @@ void TestDontCrashUseractionsMenu::init() { QVERIFY(Test::setupWaylandConnection()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/globalshortcuts_test.cpp b/autotests/integration/globalshortcuts_test.cpp index 96c3ca07b2..fc0f8a6729 100644 --- a/autotests/integration/globalshortcuts_test.cpp +++ b/autotests/integration/globalshortcuts_test.cpp @@ -74,7 +74,7 @@ void GlobalShortcutsTest::initTestCase() void GlobalShortcutsTest::init() { QVERIFY(Test::setupWaylandConnection()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); auto xkb = input()->keyboard()->xkb(); diff --git a/autotests/integration/input_stacking_order.cpp b/autotests/integration/input_stacking_order.cpp index 5c0a9a4418..473c676311 100644 --- a/autotests/integration/input_stacking_order.cpp +++ b/autotests/integration/input_stacking_order.cpp @@ -71,7 +71,7 @@ void InputStackingOrderTest::init() QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); QVERIFY(Test::waitForWaylandPointer()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/inputmethod_test.cpp b/autotests/integration/inputmethod_test.cpp index ea3c44c853..cd7c5c1c32 100644 --- a/autotests/integration/inputmethod_test.cpp +++ b/autotests/integration/inputmethod_test.cpp @@ -91,7 +91,7 @@ void InputMethodTest::init() Test::AdditionalWaylandInterface::TextInputManagerV3)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); InputMethod::self()->setEnabled(true); diff --git a/autotests/integration/kwinbindings_test.cpp b/autotests/integration/kwinbindings_test.cpp index 07b707d1d1..95a3c95611 100644 --- a/autotests/integration/kwinbindings_test.cpp +++ b/autotests/integration/kwinbindings_test.cpp @@ -62,7 +62,7 @@ void KWinBindingsTest::initTestCase() void KWinBindingsTest::init() { QVERIFY(Test::setupWaylandConnection()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/layershellv1client_test.cpp b/autotests/integration/layershellv1client_test.cpp index 9a1e7e6637..31ed156bce 100644 --- a/autotests/integration/layershellv1client_test.cpp +++ b/autotests/integration/layershellv1client_test.cpp @@ -71,7 +71,7 @@ void LayerShellV1ClientTest::init() { QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::LayerShellV1)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/lockscreen.cpp b/autotests/integration/lockscreen.cpp index 5259d11839..7b2a189875 100644 --- a/autotests/integration/lockscreen.cpp +++ b/autotests/integration/lockscreen.cpp @@ -202,7 +202,7 @@ void LockScreenTest::init() m_shm = Test::waylandShmPool(); m_seat = Test::waylandSeat(); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/maximize_test.cpp b/autotests/integration/maximize_test.cpp index e150eaf5a3..707f24f449 100644 --- a/autotests/integration/maximize_test.cpp +++ b/autotests/integration/maximize_test.cpp @@ -70,7 +70,7 @@ void TestMaximized::init() Test::AdditionalWaylandInterface::XdgDecorationV1 | Test::AdditionalWaylandInterface::PlasmaShell)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/modifier_only_shortcut_test.cpp b/autotests/integration/modifier_only_shortcut_test.cpp index ac1dcb87d3..3d0b63eeda 100644 --- a/autotests/integration/modifier_only_shortcut_test.cpp +++ b/autotests/integration/modifier_only_shortcut_test.cpp @@ -95,7 +95,7 @@ void ModifierOnlyShortcutTest::initTestCase() void ModifierOnlyShortcutTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/move_resize_window_test.cpp b/autotests/integration/move_resize_window_test.cpp index ab9710753e..f1d13aad81 100644 --- a/autotests/integration/move_resize_window_test.cpp +++ b/autotests/integration/move_resize_window_test.cpp @@ -97,7 +97,7 @@ void MoveResizeWindowTest::init() m_connection = Test::waylandConnection(); m_compositor = Test::waylandCompositor(); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); } void MoveResizeWindowTest::cleanup() diff --git a/autotests/integration/no_global_shortcuts_test.cpp b/autotests/integration/no_global_shortcuts_test.cpp index 83946a8c17..0975ca9af3 100644 --- a/autotests/integration/no_global_shortcuts_test.cpp +++ b/autotests/integration/no_global_shortcuts_test.cpp @@ -105,7 +105,7 @@ void NoGlobalShortcutsTest::initTestCase() void NoGlobalShortcutsTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/outputmanagement_test.cpp b/autotests/integration/outputmanagement_test.cpp index 7c9aba4928..cbe29cf866 100644 --- a/autotests/integration/outputmanagement_test.cpp +++ b/autotests/integration/outputmanagement_test.cpp @@ -13,6 +13,7 @@ #include "platform.h" #include "screens.h" #include "wayland_server.h" +#include "workspace.h" #include #include @@ -76,7 +77,7 @@ void TestOutputManagement::init() QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::OutputManagement | Test::AdditionalWaylandInterface::OutputDevice)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); //put mouse in the middle of screen one KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/placement_test.cpp b/autotests/integration/placement_test.cpp index b4c28d8144..740cca07c5 100644 --- a/autotests/integration/placement_test.cpp +++ b/autotests/integration/placement_test.cpp @@ -65,7 +65,7 @@ void TestPlacement::init() { QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::PlasmaShell)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/plasmawindow_test.cpp b/autotests/integration/plasmawindow_test.cpp index 18f9c4629c..1878f88da2 100644 --- a/autotests/integration/plasmawindow_test.cpp +++ b/autotests/integration/plasmawindow_test.cpp @@ -79,7 +79,7 @@ void PlasmaWindowTest::init() m_windowManagement = Test::waylandWindowManagement(); m_compositor = Test::waylandCompositor(); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/pointer_constraints_test.cpp b/autotests/integration/pointer_constraints_test.cpp index 0e69b8ce24..e51da8160c 100644 --- a/autotests/integration/pointer_constraints_test.cpp +++ b/autotests/integration/pointer_constraints_test.cpp @@ -85,7 +85,7 @@ void TestPointerConstraints::init() QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat | Test::AdditionalWaylandInterface::PointerConstraints)); QVERIFY(Test::waitForWaylandPointer()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/pointer_input.cpp b/autotests/integration/pointer_input.cpp index a7a9bf9491..7b1f1efc39 100644 --- a/autotests/integration/pointer_input.cpp +++ b/autotests/integration/pointer_input.cpp @@ -165,7 +165,7 @@ void PointerInputTest::init() m_compositor = Test::waylandCompositor(); m_seat = Test::waylandSeat(); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/quick_tiling_test.cpp b/autotests/integration/quick_tiling_test.cpp index 8598b0c58b..08ae2a2213 100644 --- a/autotests/integration/quick_tiling_test.cpp +++ b/autotests/integration/quick_tiling_test.cpp @@ -110,7 +110,7 @@ void QuickTilingTest::init() m_connection = Test::waylandConnection(); m_compositor = Test::waylandCompositor(); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/screen_changes_test.cpp b/autotests/integration/screen_changes_test.cpp index 0747135179..155d0a5243 100644 --- a/autotests/integration/screen_changes_test.cpp +++ b/autotests/integration/screen_changes_test.cpp @@ -11,6 +11,7 @@ #include "platform.h" #include "screens.h" #include "wayland_server.h" +#include "workspace.h" #include #include @@ -49,7 +50,7 @@ void ScreenChangesTest::init() { QVERIFY(Test::setupWaylandConnection()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/screenedge_client_show_test.cpp b/autotests/integration/screenedge_client_show_test.cpp index 80a00af7e4..e50739dbff 100644 --- a/autotests/integration/screenedge_client_show_test.cpp +++ b/autotests/integration/screenedge_client_show_test.cpp @@ -66,7 +66,7 @@ void ScreenEdgeClientShowTest::initTestCase() void ScreenEdgeClientShowTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); QVERIFY(waylandServer()->clients().isEmpty()); } diff --git a/autotests/integration/screens_test.cpp b/autotests/integration/screens_test.cpp index 2f7d7e1ee5..abbe5c9c90 100644 --- a/autotests/integration/screens_test.cpp +++ b/autotests/integration/screens_test.cpp @@ -30,9 +30,6 @@ private Q_SLOTS: void initTestCase(); void init(); void cleanup(); - void testCurrentFollowsMouse(); - void testReconfigure_data(); - void testReconfigure(); void testSize_data(); void testSize(); void testCount(); @@ -40,7 +37,6 @@ private Q_SLOTS: void testIntersecting(); void testCurrent_data(); void testCurrent(); - void testCurrentClient(); void testCurrentWithFollowsMouse_data(); void testCurrentWithFollowsMouse(); void testCurrentPoint_data(); @@ -56,6 +52,8 @@ void ScreensTest::initTestCase() QVERIFY(waylandServer()->init(s_socketName)); QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2)); + kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig)); + kwinApp()->start(); QVERIFY(applicationStartedSpy.wait()); QCOMPARE(screens()->count(), 2); @@ -66,7 +64,7 @@ void ScreensTest::initTestCase() void ScreensTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); QVERIFY(Test::setupWaylandConnection()); @@ -86,58 +84,15 @@ void ScreensTest::cleanup() Test::destroyWaylandConnection(); // Wipe the screens config clean. - auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); + auto config = kwinApp()->config(); purge(config.data()); config->sync(); - screens()->setConfig(config); - screens()->reconfigure(); + workspace()->slotReconfigure(); // Reset the screen layout of the test environment. QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2)); } -void ScreensTest::testCurrentFollowsMouse() -{ - QVERIFY(screens()->isCurrentFollowsMouse()); - screens()->setCurrentFollowsMouse(false); - QVERIFY(!screens()->isCurrentFollowsMouse()); - // setting to same should not do anything - screens()->setCurrentFollowsMouse(false); - QVERIFY(!screens()->isCurrentFollowsMouse()); - - // setting back to other value - screens()->setCurrentFollowsMouse(true); - QVERIFY(screens()->isCurrentFollowsMouse()); - // setting to same should not do anything - screens()->setCurrentFollowsMouse(true); - QVERIFY(screens()->isCurrentFollowsMouse()); -} - -void ScreensTest::testReconfigure_data() -{ - QTest::addColumn("focusPolicy"); - QTest::addColumn("expectedDefault"); - QTest::addColumn("setting"); - - QTest::newRow("ClickToFocus") << QStringLiteral("ClickToFocus") << false << true; - QTest::newRow("FocusFollowsMouse") << QStringLiteral("FocusFollowsMouse") << true << false; - QTest::newRow("FocusUnderMouse") << QStringLiteral("FocusUnderMouse") << true << false; - QTest::newRow("FocusStrictlyUnderMouse") << QStringLiteral("FocusStrictlyUnderMouse") << true << false; -} - -void ScreensTest::testReconfigure() -{ - screens()->reconfigure(); - QVERIFY(screens()->isCurrentFollowsMouse()); - - QFETCH(bool, setting); - KSharedConfig::Ptr config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); - config->group("Windows").writeEntry("ActiveMouseScreen", setting); - config->sync(); - screens()->reconfigure(); - QCOMPARE(screens()->isCurrentFollowsMouse(), setting); -} - void ScreensTest::testSize_data() { QTest::addColumn>("geometries"); @@ -216,61 +171,25 @@ void ScreensTest::testIntersecting() void ScreensTest::testCurrent_data() { - QTest::addColumn("current"); - QTest::addColumn("signal"); + QTest::addColumn("currentId"); - QTest::newRow("unchanged") << 0 << false; - QTest::newRow("changed") << 1 << true; + QTest::newRow("first") << 0; + QTest::newRow("second") << 1; } void ScreensTest::testCurrent() { - QSignalSpy currentChangedSpy(screens(), &KWin::Screens::currentChanged); - QVERIFY(currentChangedSpy.isValid()); + QFETCH(int, currentId); + AbstractOutput *output = kwinApp()->platform()->findOutput(currentId); - QFETCH(int, current); - AbstractOutput *output = kwinApp()->platform()->findOutput(current); + // Disable "active screen follows mouse" + auto group = kwinApp()->config()->group("Windows"); + group.writeEntry("ActiveMouseScreen", false); + group.sync(); + workspace()->slotReconfigure(); - screens()->setCurrentFollowsMouse(false); - screens()->setCurrent(output); - QCOMPARE(screens()->currentOutput(), output); - QTEST(!currentChangedSpy.isEmpty(), "signal"); -} - -void ScreensTest::testCurrentClient() -{ - QSignalSpy currentChangedSpy(screens(), &Screens::currentChanged); - QVERIFY(currentChangedSpy.isValid()); - - const QVector outputs = kwinApp()->platform()->enabledOutputs(); - screens()->setCurrentFollowsMouse(false); - - // create a test window - QScopedPointer surface(Test::createSurface()); - QScopedPointer shellSurface(Test::createXdgToplevelSurface(surface.data())); - AbstractClient *client = Test::renderAndWaitForShown(surface.data(), QSize(200, 100), Qt::red); - QVERIFY(client); - QVERIFY(client->isActive()); - - // if the window is sent to another screen, that screen will become current - client->sendToOutput(outputs[1]); - QCOMPARE(currentChangedSpy.count(), 1); - QCOMPARE(screens()->currentOutput(), outputs[1]); - - // setting current with the same client again should not change - screens()->setCurrent(client); - QCOMPARE(currentChangedSpy.count(), 1); - - // and it should even still be on screen 1 if we make the client non-current again - workspace()->setActiveClient(nullptr); - client->setActive(false); - QCOMPARE(screens()->currentOutput(), outputs[1]); - - // it's not the active client, so changing won't work - screens()->setCurrent(client); - client->sendToOutput(outputs[0]); - QCOMPARE(currentChangedSpy.count(), 1); - QCOMPARE(screens()->currentOutput(), outputs[1]); + workspace()->setActiveOutput(output); + QCOMPARE(workspace()->activeOutput(), output); } void ScreensTest::testCurrentWithFollowsMouse_data() @@ -290,7 +209,12 @@ void ScreensTest::testCurrentWithFollowsMouse() { QSignalSpy changedSpy(screens(), &Screens::changed); QVERIFY(changedSpy.isValid()); - screens()->setCurrentFollowsMouse(true); + + // Enable "active screen follows mouse" + auto group = kwinApp()->config()->group("Windows"); + group.writeEntry("ActiveMouseScreen", true); + group.sync(); + workspace()->slotReconfigure(); QFETCH(QVector, geometries); QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::QueuedConnection, @@ -302,7 +226,7 @@ void ScreensTest::testCurrentWithFollowsMouse() QFETCH(int, expectedId); AbstractOutput *expected = kwinApp()->platform()->findOutput(expectedId); - QCOMPARE(screens()->currentOutput(), expected); + QCOMPARE(workspace()->activeOutput(), expected); } void ScreensTest::testCurrentPoint_data() @@ -328,14 +252,18 @@ void ScreensTest::testCurrentPoint() Q_ARG(int, geometries.count()), Q_ARG(QVector, geometries)); QVERIFY(changedSpy.wait()); - screens()->setCurrentFollowsMouse(false); + // Disable "active screen follows mouse" + auto group = kwinApp()->config()->group("Windows"); + group.writeEntry("ActiveMouseScreen", false); + group.sync(); + workspace()->slotReconfigure(); QFETCH(QPoint, cursorPos); - screens()->setCurrent(cursorPos); + workspace()->setActiveOutput(cursorPos); QFETCH(int, expectedId); AbstractOutput *expected = kwinApp()->platform()->findOutput(expectedId); - QCOMPARE(screens()->currentOutput(), expected); + QCOMPARE(workspace()->activeOutput(), expected); } } // namespace KWin diff --git a/autotests/integration/shade_test.cpp b/autotests/integration/shade_test.cpp index 50b25755a8..5619f154d5 100644 --- a/autotests/integration/shade_test.cpp +++ b/autotests/integration/shade_test.cpp @@ -55,7 +55,7 @@ void ShadeTest::initTestCase() void ShadeTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/struts_test.cpp b/autotests/integration/struts_test.cpp index a8a49ba5d5..ec398d826d 100644 --- a/autotests/integration/struts_test.cpp +++ b/autotests/integration/struts_test.cpp @@ -88,7 +88,7 @@ void StrutsTest::init() m_compositor = Test::waylandCompositor(); m_plasmaShell = Test::waylandPlasmaShell(); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); QVERIFY(waylandServer()->clients().isEmpty()); } diff --git a/autotests/integration/tabbox_test.cpp b/autotests/integration/tabbox_test.cpp index 759ff7d62b..028b90c481 100644 --- a/autotests/integration/tabbox_test.cpp +++ b/autotests/integration/tabbox_test.cpp @@ -61,7 +61,7 @@ void TabBoxTest::initTestCase() void TabBoxTest::init() { QVERIFY(Test::setupWaylandConnection()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/touch_input_test.cpp b/autotests/integration/touch_input_test.cpp index 0a33fd867e..4cf33407a6 100644 --- a/autotests/integration/touch_input_test.cpp +++ b/autotests/integration/touch_input_test.cpp @@ -71,7 +71,7 @@ void TouchInputTest::init() QVERIFY(m_touch); QVERIFY(m_touch->isValid()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/transient_placement.cpp b/autotests/integration/transient_placement.cpp index 33035e200e..a807221380 100644 --- a/autotests/integration/transient_placement.cpp +++ b/autotests/integration/transient_placement.cpp @@ -80,7 +80,7 @@ void TransientPlacementTest::init() { QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration | Test::AdditionalWaylandInterface::PlasmaShell)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/virtual_desktop_test.cpp b/autotests/integration/virtual_desktop_test.cpp index 4fe1191a5c..7a033dbd3d 100644 --- a/autotests/integration/virtual_desktop_test.cpp +++ b/autotests/integration/virtual_desktop_test.cpp @@ -11,8 +11,9 @@ #include "main.h" #include "platform.h" #include "screens.h" -#include "wayland_server.h" #include "virtualdesktops.h" +#include "wayland_server.h" +#include "workspace.h" #include @@ -65,7 +66,7 @@ void VirtualDesktopTest::initTestCase() void VirtualDesktopTest::init() { QVERIFY(Test::setupWaylandConnection()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); VirtualDesktopManager::self()->setCount(1); } diff --git a/autotests/integration/window_rules_test.cpp b/autotests/integration/window_rules_test.cpp index d7974eb8d0..c425a0fd00 100644 --- a/autotests/integration/window_rules_test.cpp +++ b/autotests/integration/window_rules_test.cpp @@ -59,7 +59,7 @@ void WindowRuleTest::initTestCase() void WindowRuleTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); QVERIFY(waylandServer()->clients().isEmpty()); } diff --git a/autotests/integration/window_selection_test.cpp b/autotests/integration/window_selection_test.cpp index 88d91b2b43..d9d508472b 100644 --- a/autotests/integration/window_selection_test.cpp +++ b/autotests/integration/window_selection_test.cpp @@ -73,7 +73,7 @@ void TestWindowSelection::init() QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); QVERIFY(Test::waitForWaylandPointer()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/xdgshellclient_rules_test.cpp b/autotests/integration/xdgshellclient_rules_test.cpp index cc5dd10cc1..32d2b1e995 100644 --- a/autotests/integration/xdgshellclient_rules_test.cpp +++ b/autotests/integration/xdgshellclient_rules_test.cpp @@ -155,7 +155,7 @@ void TestXdgShellClientRules::init() VirtualDesktopManager::self()->setCurrent(VirtualDesktopManager::self()->desktops().first()); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); } void TestXdgShellClientRules::cleanup() diff --git a/autotests/integration/xdgshellclient_test.cpp b/autotests/integration/xdgshellclient_test.cpp index e564679f8e..7a327ae53a 100644 --- a/autotests/integration/xdgshellclient_test.cpp +++ b/autotests/integration/xdgshellclient_test.cpp @@ -193,7 +193,7 @@ void TestXdgShellClient::init() Test::AdditionalWaylandInterface::AppMenu)); QVERIFY(Test::waitForWaylandPointer()); - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); //put mouse in the middle of screen one KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); } diff --git a/autotests/integration/xwayland_input_test.cpp b/autotests/integration/xwayland_input_test.cpp index 35a921b107..d752a791be 100644 --- a/autotests/integration/xwayland_input_test.cpp +++ b/autotests/integration/xwayland_input_test.cpp @@ -59,7 +59,7 @@ void XWaylandInputTest::initTestCase() void XWaylandInputTest::init() { - screens()->setCurrent(QPoint(640, 512)); + workspace()->setActiveOutput(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512)); xcb_warp_pointer(connection(), XCB_WINDOW_NONE, kwinApp()->x11RootWindow(), 0, 0, 0, 0, 640, 512); xcb_flush(connection()); diff --git a/src/abstract_client.cpp b/src/abstract_client.cpp index d717ada508..09ffb2e3b0 100644 --- a/src/abstract_client.cpp +++ b/src/abstract_client.cpp @@ -85,7 +85,7 @@ AbstractClient::AbstractClient() Q_UNUSED(c) if (isOnScreenDisplay() && !frameGeometry().isEmpty() && old.size() != frameGeometry().size() && isPlaceable()) { GeometryUpdatesBlocker blocker(this); - placeIn(workspace()->clientArea(PlacementArea, this, Screens::self()->currentOutput())); + placeIn(workspace()->clientArea(PlacementArea, this, workspace()->activeOutput())); } } ); @@ -1222,7 +1222,7 @@ void AbstractClient::handleInteractiveMoveResize(int x, int y, int x_root, int y // Make sure the titlebar isn't behind a restricted area. We don't need to restrict // the other directions. If not visible enough, move the window to the closest valid // point. We bruteforce this by slowly moving the window back to its previous position - QRegion availableArea(workspace()->clientArea(FullArea, this, screens()->currentOutput())); + QRegion availableArea(workspace()->clientArea(FullArea, this, workspace()->activeOutput())); availableArea -= workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop()); bool transposed = false; int requiredPixels; @@ -1350,7 +1350,7 @@ void AbstractClient::handleInteractiveMoveResize(int x, int y, int x_root, int y if (!isUnrestrictedInteractiveMoveResize()) { const QRegion strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop()); - QRegion availableArea(workspace()->clientArea(FullArea, this, screens()->currentOutput())); + QRegion availableArea(workspace()->clientArea(FullArea, this, workspace()->activeOutput())); availableArea -= strut; // Strut areas bool transposed = false; int requiredPixels; @@ -1776,30 +1776,30 @@ bool AbstractClient::performMouseCommand(Options::MouseCommand cmd, const QPoint } } workspace()->takeActivity(this, Workspace::ActivityFocus | Workspace::ActivityRaise); - screens()->setCurrent(globalPos); + workspace()->setActiveOutput(globalPos); replay = replay || mustReplay; break; } case Options::MouseActivateAndLower: workspace()->requestFocus(this); workspace()->lowerClient(this); - screens()->setCurrent(globalPos); + workspace()->setActiveOutput(globalPos); replay = replay || !rules()->checkAcceptFocus(acceptsFocus()); break; case Options::MouseActivate: replay = isActive(); // for clickraise mode workspace()->takeActivity(this, Workspace::ActivityFocus); - screens()->setCurrent(globalPos); + workspace()->setActiveOutput(globalPos); replay = replay || !rules()->checkAcceptFocus(acceptsFocus()); break; case Options::MouseActivateRaiseAndPassClick: workspace()->takeActivity(this, Workspace::ActivityFocus | Workspace::ActivityRaise); - screens()->setCurrent(globalPos); + workspace()->setActiveOutput(globalPos); replay = true; break; case Options::MouseActivateAndPassClick: workspace()->takeActivity(this, Workspace::ActivityFocus); - screens()->setCurrent(globalPos); + workspace()->setActiveOutput(globalPos); replay = true; break; case Options::MouseMaximize: @@ -1848,7 +1848,7 @@ bool AbstractClient::performMouseCommand(Options::MouseCommand cmd, const QPoint case Options::MouseActivateRaiseAndUnrestrictedMove: workspace()->raiseClient(this); workspace()->requestFocus(this); - screens()->setCurrent(globalPos); + workspace()->setActiveOutput(globalPos); // fallthrough case Options::MouseMove: case Options::MouseUnrestrictedMove: { @@ -3225,7 +3225,7 @@ void AbstractClient::sendToOutput(AbstractOutput *newOutput) { newOutput = rules()->checkOutput(newOutput); if (isActive()) { - screens()->setCurrent(newOutput); + workspace()->setActiveOutput(newOutput); // might impact the layer of a fullscreen window Q_FOREACH (AbstractClient *cc, workspace()->allClientList()) { if (cc->isFullScreen() && cc->output() == newOutput) { diff --git a/src/activation.cpp b/src/activation.cpp index c255eb9011..2f59ab20b6 100644 --- a/src/activation.cpp +++ b/src/activation.cpp @@ -393,7 +393,7 @@ bool Workspace::takeActivity(AbstractClient* c, ActivityFlags flags) workspace()->raiseClient(c); if (!c->isOnActiveOutput()) { - screens()->setCurrent(c->output()); + setActiveOutput(c->output()); } return ret; @@ -467,7 +467,7 @@ bool Workspace::activateNextClient(AbstractClient* c) get_focus = findDesktop(true, desktop); // to not break the state if (!get_focus && options->isNextFocusPrefersMouse()) { - get_focus = clientUnderMouse(c ? c->output() : screens()->currentOutput()); + get_focus = clientUnderMouse(c ? c->output() : workspace()->activeOutput()); if (get_focus && (get_focus == c || get_focus->isDesktop())) { // should rather not happen, but it cannot get the focus. rest of usability is tested above get_focus = nullptr; @@ -512,7 +512,7 @@ void Workspace::switchToOutput(AbstractOutput *output) get_focus = findDesktop(true, desktop); if (get_focus != nullptr && get_focus != mostRecentlyActivatedClient()) requestFocus(get_focus); - screens()->setCurrent(output); + setActiveOutput(output); } void Workspace::gotFocusIn(const AbstractClient* c) diff --git a/src/effects.cpp b/src/effects.cpp index defc7f3030..09c623cd9a 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -1190,7 +1190,7 @@ void EffectsHandlerImpl::addRepaint(int x, int y, int w, int h) int EffectsHandlerImpl::activeScreen() const { - return Screens::self()->current(); + return kwinApp()->platform()->enabledOutputs().indexOf(workspace()->activeOutput()); } int EffectsHandlerImpl::numScreens() const diff --git a/src/focuschain.cpp b/src/focuschain.cpp index f24a2121be..8f7f2748ee 100644 --- a/src/focuschain.cpp +++ b/src/focuschain.cpp @@ -8,7 +8,7 @@ */ #include "focuschain.h" #include "abstract_client.h" -#include "screens.h" +#include "workspace.h" namespace KWin { @@ -52,7 +52,7 @@ void FocusChain::removeDesktop(VirtualDesktop *desktop) AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop) const { - return getForActivation(desktop, screens()->currentOutput()); + return getForActivation(desktop, workspace()->activeOutput()); } AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop, AbstractOutput *output) const @@ -207,7 +207,7 @@ bool FocusChain::isUsableFocusCandidate(AbstractClient *c, AbstractClient *prev) { return c != prev && c->isShown(false) && c->isOnCurrentDesktop() && c->isOnCurrentActivity() && - (!m_separateScreenFocus || c->isOnOutput(prev ? prev->output() : screens()->currentOutput())); + (!m_separateScreenFocus || c->isOnOutput(prev ? prev->output() : workspace()->activeOutput())); } AbstractClient *FocusChain::nextForDesktop(AbstractClient *reference, VirtualDesktop *desktop) const diff --git a/src/layershellv1integration.cpp b/src/layershellv1integration.cpp index 0d03c257df..f1910435b6 100644 --- a/src/layershellv1integration.cpp +++ b/src/layershellv1integration.cpp @@ -41,7 +41,7 @@ void LayerShellV1Integration::createClient(LayerSurfaceV1Interface *shellSurface { AbstractOutput *output = waylandServer()->findOutput(shellSurface->output()); if (!output) { - output = screens()->currentOutput(); + output = workspace()->activeOutput(); } if (!output) { qCWarning(KWIN_CORE) << "Could not find any suitable output for a layer surface"; diff --git a/src/options.cpp b/src/options.cpp index 877862dee4..42fb513f98 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -42,6 +42,7 @@ Options::Options(QObject *parent) , m_shadeHover(false) , m_shadeHoverInterval(0) , m_separateScreenFocus(false) + , m_activeMouseScreen(false) , m_placement(Placement::NoPlacement) , m_borderSnapZone(0) , m_windowSnapZone(0) @@ -226,6 +227,15 @@ void Options::setSeparateScreenFocus(bool separateScreenFocus) Q_EMIT separateScreenFocusChanged(m_separateScreenFocus); } +void Options::setActiveMouseScreen(bool activeMouseScreen) +{ + if (m_activeMouseScreen == activeMouseScreen) { + return; + } + m_activeMouseScreen = activeMouseScreen; + Q_EMIT activeMouseScreenChanged(); +} + void Options::setPlacement(int placement) { if (m_placement == static_cast(placement)) { @@ -771,6 +781,7 @@ void Options::syncFromKcfgc() setFocusPolicy(m_settings->focusPolicy()); setNextFocusPrefersMouse(m_settings->nextFocusPrefersMouse()); setSeparateScreenFocus(m_settings->separateScreenFocus()); + setActiveMouseScreen(m_settings->activeMouseScreen()); setRollOverDesktops(m_settings->rollOverDesktops()); setFocusStealingPreventionLevel(m_settings->focusStealingPreventionLevel()); setXwaylandCrashPolicy(m_settings->xwaylandCrashPolicy()); diff --git a/src/options.h b/src/options.h index 36d5499d0b..9a0ff0b7e2 100644 --- a/src/options.h +++ b/src/options.h @@ -103,6 +103,7 @@ class KWIN_EXPORT Options : public QObject * Whether to see Xinerama screens separately for focus (in Alt+Tab, when activating next client) */ Q_PROPERTY(bool separateScreenFocus READ isSeparateScreenFocus WRITE setSeparateScreenFocus NOTIFY separateScreenFocusChanged) + Q_PROPERTY(bool activeMouseScreen READ activeMouseScreen WRITE setActiveMouseScreen NOTIFY activeMouseScreenChanged) Q_PROPERTY(int placement READ placement WRITE setPlacement NOTIFY placementChanged) Q_PROPERTY(bool focusPolicyIsReasonable READ focusPolicyIsReasonable NOTIFY focusPolicyIsResonableChanged) /** @@ -306,6 +307,10 @@ public: return m_separateScreenFocus; } + bool activeMouseScreen() const { + return m_activeMouseScreen; + } + Placement::Policy placement() const { return m_placement; } @@ -621,6 +626,7 @@ public: void setShadeHover(bool shadeHover); void setShadeHoverInterval(int shadeHoverInterval); void setSeparateScreenFocus(bool separateScreenFocus); + void setActiveMouseScreen(bool activeMouseScreen); void setPlacement(int placement); void setBorderSnapZone(int borderSnapZone); void setWindowSnapZone(int windowSnapZone); @@ -793,6 +799,7 @@ Q_SIGNALS: void shadeHoverChanged(); void shadeHoverIntervalChanged(); void separateScreenFocusChanged(bool); + void activeMouseScreenChanged(); void placementChanged(); void borderSnapZoneChanged(); void windowSnapZoneChanged(); @@ -856,6 +863,7 @@ private: bool m_shadeHover; int m_shadeHoverInterval; bool m_separateScreenFocus; + bool m_activeMouseScreen; Placement::Policy m_placement; int m_borderSnapZone; int m_windowSnapZone; diff --git a/src/screens.cpp b/src/screens.cpp index 8c89e03f49..8fbd6ea5cd 100644 --- a/src/screens.cpp +++ b/src/screens.cpp @@ -42,8 +42,6 @@ Screens *Screens::create(QObject *parent) Screens::Screens(QObject *parent) : QObject(parent) , m_count(0) - , m_current(0) - , m_currentFollowsMouse(false) , m_maxScale(1.0) { // TODO: Do something about testScreens and other tests that use MockScreens. @@ -66,9 +64,6 @@ void Screens::init() connect(this, &Screens::changed, this, &Screens::updateSize); connect(this, &Screens::sizeChanged, this, &Screens::geometryChanged); - Settings settings; - settings.setDefaults(); - m_currentFollowsMouse = settings.activeMouseScreen(); Q_EMIT changed(); } @@ -133,16 +128,6 @@ qreal Screens::maxScale() const return m_maxScale; } -void Screens::reconfigure() -{ - if (!m_config) { - return; - } - Settings settings(m_config); - settings.read(); - setCurrentFollowsMouse(settings.activeMouseScreen()); -} - void Screens::updateSize() { QRect bounding; @@ -176,68 +161,6 @@ void Screens::setCount(int count) Q_EMIT countChanged(previous, count); } -void Screens::setCurrent(int current) -{ - if (m_current == current) { - return; - } - m_current = current; - Q_EMIT currentChanged(); -} - -void Screens::setCurrent(AbstractOutput *output) -{ -#ifdef KWIN_UNIT_TEST - Q_UNUSED(output) -#else - setCurrent(kwinApp()->platform()->enabledOutputs().indexOf(output)); -#endif -} - -void Screens::setCurrent(const QPoint &pos) -{ - setCurrent(number(pos)); -} - -void Screens::setCurrent(const AbstractClient *c) -{ - if (!c->isActive()) { - return; - } - if (!c->isOnScreen(m_current)) { - setCurrent(c->screen()); - } -} - -void Screens::setCurrentFollowsMouse(bool follows) -{ - if (m_currentFollowsMouse == follows) { - return; - } - m_currentFollowsMouse = follows; -} - -int Screens::current() const -{ - if (m_currentFollowsMouse) { - return number(Cursors::self()->mouse()->pos()); - } - AbstractClient *client = Workspace::self()->activeClient(); - if (client && !client->isOnScreen(m_current)) { - return client->screen(); - } - return m_current; -} - -AbstractOutput *Screens::currentOutput() const -{ -#ifdef KWIN_UNIT_TEST - return nullptr; -#else - return kwinApp()->platform()->findOutput(current()); -#endif -} - int Screens::intersecting(const QRect &r) const { int cnt = 0; @@ -260,11 +183,6 @@ Qt::ScreenOrientation Screens::orientation(int screen) const return Qt::PrimaryOrientation; } -void Screens::setConfig(KSharedConfig::Ptr config) -{ - m_config = config; -} - int Screens::physicalDpiX(int screen) const { return size(screen).width() / physicalSize(screen).width() * qreal(25.4); diff --git a/src/screens.h b/src/screens.h index 1c59487723..639a6f6b10 100644 --- a/src/screens.h +++ b/src/screens.h @@ -31,32 +31,10 @@ class KWIN_EXPORT Screens : public QObject { Q_OBJECT Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged) - Q_PROPERTY(int current READ current WRITE setCurrent NOTIFY currentChanged) - Q_PROPERTY(bool currentFollowsMouse READ isCurrentFollowsMouse WRITE setCurrentFollowsMouse) public: ~Screens() override; - /** - * @internal - */ - void setConfig(KSharedConfig::Ptr config); int count() const; - int current() const; - AbstractOutput *currentOutput() const; - void setCurrent(int current); - /** - * Called e.g. when a user clicks on a window, set current screen to be the screen - * where the click occurred - */ - void setCurrent(const QPoint &pos); - void setCurrent(AbstractOutput *output); - /** - * Check whether a client moved completely out of what's considered the current screen, - * if yes, set a new active screen. - */ - void setCurrent(const AbstractClient *c); - bool isCurrentFollowsMouse() const; - void setCurrentFollowsMouse(bool follows); virtual QRect geometry(int screen) const; /** * The bounding geometry of all screens combined. Overlapping areas @@ -143,16 +121,12 @@ public: */ RenderLoop::VrrPolicy vrrPolicy(int screen) const; -public Q_SLOTS: - void reconfigure(); - Q_SIGNALS: void countChanged(int previousCount, int newCount); /** * Emitted whenever the screens are changed either count or geometry. */ void changed(); - void currentChanged(); /** * Emitted when the geometry of all screens combined changes. * Not emitted when the geometry of an individual screen changes. @@ -190,9 +164,6 @@ private: AbstractOutput *findOutput(int screenId) const; int m_count; - int m_current; - bool m_currentFollowsMouse; - KSharedConfig::Ptr m_config; QSize m_boundingSize; qreal m_maxScale; @@ -205,12 +176,6 @@ int Screens::count() const return m_count; } -inline -bool Screens::isCurrentFollowsMouse() const -{ - return m_currentFollowsMouse; -} - inline QSize Screens::size() const { diff --git a/src/scripting/workspace_wrapper.cpp b/src/scripting/workspace_wrapper.cpp index 5af7b70283..def111863b 100644 --- a/src/scripting/workspace_wrapper.cpp +++ b/src/scripting/workspace_wrapper.cpp @@ -363,7 +363,7 @@ int WorkspaceWrapper::numScreens() const int WorkspaceWrapper::activeScreen() const { - return screens()->current(); + return kwinApp()->platform()->enabledOutputs().indexOf(workspace()->activeOutput()); } QRect WorkspaceWrapper::virtualScreenGeometry() const diff --git a/src/tabbox/switcheritem.cpp b/src/tabbox/switcheritem.cpp index 05cfbe8388..d9e47d6742 100644 --- a/src/tabbox/switcheritem.cpp +++ b/src/tabbox/switcheritem.cpp @@ -8,9 +8,11 @@ */ #include "switcheritem.h" // KWin +#include "abstract_output.h" #include "composite.h" #include "tabboxhandler.h" #include "screens.h" +#include "workspace.h" // Qt #include @@ -69,7 +71,7 @@ void SwitcherItem::setVisible(bool visible) QRect SwitcherItem::screenGeometry() const { - return screens()->geometry(screens()->current()); + return workspace()->activeOutput()->geometry(); } void SwitcherItem::setCurrentIndex(int index) diff --git a/src/tabbox/tabbox.cpp b/src/tabbox/tabbox.cpp index b54df171dd..2462b5e849 100644 --- a/src/tabbox/tabbox.cpp +++ b/src/tabbox/tabbox.cpp @@ -30,6 +30,7 @@ #include "keyboard_input.h" #include "pointer_input.h" #include "focuschain.h" +#include "platform.h" #include "screenedge.h" #include "screens.h" #include "unmanaged.h" @@ -81,7 +82,7 @@ TabBoxHandlerImpl::~TabBoxHandlerImpl() int TabBoxHandlerImpl::activeScreen() const { - return screens()->current(); + return kwinApp()->platform()->enabledOutputs().indexOf(workspace()->activeOutput()); } int TabBoxHandlerImpl::currentDesktop() const @@ -235,9 +236,9 @@ bool TabBoxHandlerImpl::checkMultiScreen(TabBoxClient* client) const case TabBoxConfig::IgnoreMultiScreen: return true; case TabBoxConfig::ExcludeCurrentScreenClients: - return current->output() != screens()->currentOutput(); + return current->output() != workspace()->activeOutput(); default: // TabBoxConfig::OnlyCurrentScreenClients - return current->output() == screens()->currentOutput(); + return current->output() == workspace()->activeOutput(); } } @@ -322,7 +323,7 @@ QWeakPointer TabBoxHandlerImpl::desktopClient() const { Q_FOREACH (Toplevel *toplevel, Workspace::self()->stackingOrder()) { auto client = qobject_cast(toplevel); - if (client && client->isDesktop() && client->isOnCurrentDesktop() && client->output() == screens()->currentOutput()) { + if (client && client->isDesktop() && client->isOnCurrentDesktop() && client->output() == workspace()->activeOutput()) { return client->tabBoxClient(); } } diff --git a/src/toplevel.cpp b/src/toplevel.cpp index 650cc71c1a..4d766dd8d4 100644 --- a/src/toplevel.cpp +++ b/src/toplevel.cpp @@ -422,7 +422,7 @@ bool Toplevel::isOnScreen(int screen) const bool Toplevel::isOnActiveOutput() const { - return isOnOutput(screens()->currentOutput()); + return isOnOutput(workspace()->activeOutput()); } bool Toplevel::isOnOutput(AbstractOutput *output) const diff --git a/src/useractions.cpp b/src/useractions.cpp index 0949ae9c80..233e7002ce 100644 --- a/src/useractions.cpp +++ b/src/useractions.cpp @@ -1289,7 +1289,7 @@ void Workspace::slotWindowToDesktop(VirtualDesktop *desktop) static bool screenSwitchImpossible() { - if (!screens()->isCurrentFollowsMouse()) + if (!options->activeMouseScreen()) return false; QStringList args; args << QStringLiteral("--passivepopup") << i18n("The window manager is configured to consider the screen with the mouse on it as active one.\n" @@ -1328,14 +1328,14 @@ void Workspace::slotSwitchToNextScreen() { if (screenSwitchImpossible()) return; - switchToOutput(nextOutput(screens()->currentOutput())); + switchToOutput(nextOutput(activeOutput())); } void Workspace::slotSwitchToPrevScreen() { if (screenSwitchImpossible()) return; - switchToOutput(previousOutput(screens()->currentOutput())); + switchToOutput(previousOutput(activeOutput())); } void Workspace::slotWindowToScreen() diff --git a/src/workspace.cpp b/src/workspace.cpp index 7a0cd3f1bb..9fb3d0f33f 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -207,11 +207,6 @@ Workspace::Workspace() void Workspace::init() { KSharedConfigPtr config = kwinApp()->config(); - Screens *screens = Screens::self(); - // get screen support - screens->setConfig(config); - screens->reconfigure(); - connect(options, &Options::configChanged, screens, &Screens::reconfigure); ScreenEdges *screenEdges = ScreenEdges::self(); screenEdges->setConfig(config); screenEdges->init(); @@ -786,7 +781,7 @@ void Workspace::addShellClient(AbstractClient *client) client->updateLayer(); if (client->isPlaceable()) { - const QRect area = clientArea(PlacementArea, client, Screens::self()->currentOutput()); + const QRect area = clientArea(PlacementArea, client, activeOutput()); bool placementDone = false; if (client->isRequestedFullScreen()) { placementDone = true; @@ -1207,12 +1202,20 @@ void Workspace::updateCurrentActivity(const QString &new_activity) void Workspace::slotOutputEnabled(AbstractOutput *output) { + if (!m_activeOutput) { + m_activeOutput = output; + } + connect(output, &AbstractOutput::geometryChanged, this, &Workspace::desktopResized); desktopResized(); } void Workspace::slotOutputDisabled(AbstractOutput *output) { + if (m_activeOutput == output) { + m_activeOutput = kwinApp()->platform()->outputAt(output->geometry().center()); + } + const auto stack = xStackingOrder(); for (Toplevel *toplevel : stack) { if (toplevel->output() == output) { @@ -1610,7 +1613,7 @@ QString Workspace::supportInformation() const support.append(QStringLiteral("no\n")); } support.append(QStringLiteral("Active screen follows mouse: ")); - if (screens()->isCurrentFollowsMouse()) + if (options->activeMouseScreen()) support.append(QStringLiteral(" yes\n")); else support.append(QStringLiteral(" no\n")); @@ -1932,7 +1935,7 @@ void Workspace::addInternalClient(InternalClient *client) client->updateLayer(); if (client->isPlaceable()) { - const QRect area = clientArea(PlacementArea, client, screens()->currentOutput()); + const QRect area = clientArea(PlacementArea, client, workspace()->activeOutput()); client->placeIn(area); } @@ -2409,6 +2412,30 @@ int Workspace::oldDisplayHeight() const return olddisplaysize.height(); } +AbstractOutput *Workspace::activeOutput() const +{ + if (options->activeMouseScreen()) { + return kwinApp()->platform()->outputAt(Cursors::self()->mouse()->pos()); + } + + AbstractClient *client = Workspace::self()->activeClient(); + if (active_client && !client->isOnOutput(m_activeOutput)) { + return client->output(); + } + + return m_activeOutput; +} + +void Workspace::setActiveOutput(AbstractOutput *output) +{ + m_activeOutput = output; +} + +void Workspace::setActiveOutput(const QPoint &pos) +{ + setActiveOutput(kwinApp()->platform()->outputAt(pos)); +} + /** * Client \a c is moved around to position \a pos. This gives the * workspace the opportunity to interveniate and to implement diff --git a/src/workspace.h b/src/workspace.h index b29af9265e..0e41986536 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -154,6 +154,10 @@ public: bool initializing() const; + AbstractOutput *activeOutput() const; + void setActiveOutput(AbstractOutput *output); + void setActiveOutput(const QPoint &pos); + /** * Returns the active client, i.e. the client that has the focus (or None * if no client has the focus) @@ -596,6 +600,7 @@ private: void updateXStackingOrder(); void updateTabbox(); + AbstractOutput *m_activeOutput = nullptr; AbstractClient* active_client; AbstractClient* last_active_client; AbstractClient* movingClient; diff --git a/src/x11client.cpp b/src/x11client.cpp index e2e3af0f43..2bea369a35 100644 --- a/src/x11client.cpp +++ b/src/x11client.cpp @@ -614,7 +614,7 @@ bool X11Client::manage(xcb_window_t w, bool isMapped) output = kwinApp()->platform()->findOutput(asn_data.xinerama()); } if (!output) { - output = screens()->currentOutput(); + output = workspace()->activeOutput(); } output = rules()->checkOutput(output, !isMapped); area = workspace()->clientArea(PlacementArea, this, output->geometry().center()); @@ -4069,7 +4069,9 @@ void X11Client::moveResizeInternal(const QRect &rect, MoveResizeMode mode) m_lastFrameGeometry = m_frameGeometry; m_lastClientGeometry = m_clientGeometry; - screens()->setCurrent(this); + if (isActive()) { + workspace()->setActiveOutput(output()); + } workspace()->updateStackingOrder(); if (oldBufferGeometry != m_bufferGeometry) { diff --git a/src/xdgshellclient.cpp b/src/xdgshellclient.cpp index d1366b68ef..0c00b2dcb2 100644 --- a/src/xdgshellclient.cpp +++ b/src/xdgshellclient.cpp @@ -1235,7 +1235,7 @@ void XdgToplevelClient::initialize() needsPlacement = false; } if (needsPlacement) { - const QRect area = workspace()->clientArea(PlacementArea, this, Screens::self()->currentOutput()); + const QRect area = workspace()->clientArea(PlacementArea, this, workspace()->activeOutput()); placeIn(area); } @@ -2059,7 +2059,7 @@ void XdgPopupClient::initialize() updateReactive(); - const QRect area = workspace()->clientArea(PlacementArea, this, Screens::self()->currentOutput()); + const QRect area = workspace()->clientArea(PlacementArea, this, workspace()->activeOutput()); placeIn(area); scheduleConfigure(); }