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.
icc-effect-5.26.4
Vlad Zahorodnii 2021-08-28 21:58:29 +03:00
parent 16bc522bfc
commit 7016da39c8
57 changed files with 169 additions and 299 deletions

View File

@ -66,7 +66,7 @@ void ActivationTest::init()
{ {
QVERIFY(Test::setupWaylandConnection()); QVERIFY(Test::setupWaylandConnection());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -76,7 +76,7 @@ void ActivitiesTest::cleanupTestCase()
void ActivitiesTest::init() void ActivitiesTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -150,7 +150,7 @@ void DecorationInputTest::init()
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat | Test::AdditionalWaylandInterface::Decoration)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat | Test::AdditionalWaylandInterface::Decoration));
QVERIFY(Test::waitForWaylandPointer()); QVERIFY(Test::waitForWaylandPointer());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -60,7 +60,7 @@ void X11DesktopWindowTest::initTestCase()
void X11DesktopWindowTest::init() void X11DesktopWindowTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -71,7 +71,7 @@ void DontCrashAuroraeDestroyDecoTest::initTestCase()
void DontCrashAuroraeDestroyDecoTest::init() void DontCrashAuroraeDestroyDecoTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -43,7 +43,7 @@ void DontCrashCursorPhysicalSizeEmpty::init()
{ {
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration));
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -62,7 +62,7 @@ void DontCrashEmptyDecorationTest::initTestCase()
void DontCrashEmptyDecorationTest::init() void DontCrashEmptyDecorationTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -74,7 +74,7 @@ void DontCrashNoBorder::init()
{ {
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration));
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -67,7 +67,7 @@ void TestDontCrashUseractionsMenu::init()
{ {
QVERIFY(Test::setupWaylandConnection()); QVERIFY(Test::setupWaylandConnection());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -74,7 +74,7 @@ void GlobalShortcutsTest::initTestCase()
void GlobalShortcutsTest::init() void GlobalShortcutsTest::init()
{ {
QVERIFY(Test::setupWaylandConnection()); QVERIFY(Test::setupWaylandConnection());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
auto xkb = input()->keyboard()->xkb(); auto xkb = input()->keyboard()->xkb();

View File

@ -71,7 +71,7 @@ void InputStackingOrderTest::init()
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat));
QVERIFY(Test::waitForWaylandPointer()); QVERIFY(Test::waitForWaylandPointer());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -91,7 +91,7 @@ void InputMethodTest::init()
Test::AdditionalWaylandInterface::TextInputManagerV3)); Test::AdditionalWaylandInterface::TextInputManagerV3));
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
InputMethod::self()->setEnabled(true); InputMethod::self()->setEnabled(true);

View File

@ -62,7 +62,7 @@ void KWinBindingsTest::initTestCase()
void KWinBindingsTest::init() void KWinBindingsTest::init()
{ {
QVERIFY(Test::setupWaylandConnection()); QVERIFY(Test::setupWaylandConnection());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -71,7 +71,7 @@ void LayerShellV1ClientTest::init()
{ {
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::LayerShellV1)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::LayerShellV1));
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -202,7 +202,7 @@ void LockScreenTest::init()
m_shm = Test::waylandShmPool(); m_shm = Test::waylandShmPool();
m_seat = Test::waylandSeat(); m_seat = Test::waylandSeat();
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -70,7 +70,7 @@ void TestMaximized::init()
Test::AdditionalWaylandInterface::XdgDecorationV1 | Test::AdditionalWaylandInterface::XdgDecorationV1 |
Test::AdditionalWaylandInterface::PlasmaShell)); Test::AdditionalWaylandInterface::PlasmaShell));
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -95,7 +95,7 @@ void ModifierOnlyShortcutTest::initTestCase()
void ModifierOnlyShortcutTest::init() void ModifierOnlyShortcutTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -97,7 +97,7 @@ void MoveResizeWindowTest::init()
m_connection = Test::waylandConnection(); m_connection = Test::waylandConnection();
m_compositor = Test::waylandCompositor(); m_compositor = Test::waylandCompositor();
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
} }
void MoveResizeWindowTest::cleanup() void MoveResizeWindowTest::cleanup()

View File

@ -105,7 +105,7 @@ void NoGlobalShortcutsTest::initTestCase()
void NoGlobalShortcutsTest::init() void NoGlobalShortcutsTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -13,6 +13,7 @@
#include "platform.h" #include "platform.h"
#include "screens.h" #include "screens.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "workspace.h"
#include <KWayland/Client/outputmanagement.h> #include <KWayland/Client/outputmanagement.h>
#include <KWayland/Client/outputconfiguration.h> #include <KWayland/Client/outputconfiguration.h>
@ -76,7 +77,7 @@ void TestOutputManagement::init()
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::OutputManagement | QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::OutputManagement |
Test::AdditionalWaylandInterface::OutputDevice)); Test::AdditionalWaylandInterface::OutputDevice));
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
//put mouse in the middle of screen one //put mouse in the middle of screen one
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -65,7 +65,7 @@ void TestPlacement::init()
{ {
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::PlasmaShell)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::PlasmaShell));
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -79,7 +79,7 @@ void PlasmaWindowTest::init()
m_windowManagement = Test::waylandWindowManagement(); m_windowManagement = Test::waylandWindowManagement();
m_compositor = Test::waylandCompositor(); m_compositor = Test::waylandCompositor();
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -85,7 +85,7 @@ void TestPointerConstraints::init()
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat | Test::AdditionalWaylandInterface::PointerConstraints)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat | Test::AdditionalWaylandInterface::PointerConstraints));
QVERIFY(Test::waitForWaylandPointer()); QVERIFY(Test::waitForWaylandPointer());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -165,7 +165,7 @@ void PointerInputTest::init()
m_compositor = Test::waylandCompositor(); m_compositor = Test::waylandCompositor();
m_seat = Test::waylandSeat(); m_seat = Test::waylandSeat();
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -110,7 +110,7 @@ void QuickTilingTest::init()
m_connection = Test::waylandConnection(); m_connection = Test::waylandConnection();
m_compositor = Test::waylandCompositor(); m_compositor = Test::waylandCompositor();
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -11,6 +11,7 @@
#include "platform.h" #include "platform.h"
#include "screens.h" #include "screens.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "workspace.h"
#include <KWayland/Client/output.h> #include <KWayland/Client/output.h>
#include <KWayland/Client/xdgoutput.h> #include <KWayland/Client/xdgoutput.h>
@ -49,7 +50,7 @@ void ScreenChangesTest::init()
{ {
QVERIFY(Test::setupWaylandConnection()); QVERIFY(Test::setupWaylandConnection());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -66,7 +66,7 @@ void ScreenEdgeClientShowTest::initTestCase()
void ScreenEdgeClientShowTest::init() void ScreenEdgeClientShowTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
QVERIFY(waylandServer()->clients().isEmpty()); QVERIFY(waylandServer()->clients().isEmpty());
} }

View File

@ -30,9 +30,6 @@ private Q_SLOTS:
void initTestCase(); void initTestCase();
void init(); void init();
void cleanup(); void cleanup();
void testCurrentFollowsMouse();
void testReconfigure_data();
void testReconfigure();
void testSize_data(); void testSize_data();
void testSize(); void testSize();
void testCount(); void testCount();
@ -40,7 +37,6 @@ private Q_SLOTS:
void testIntersecting(); void testIntersecting();
void testCurrent_data(); void testCurrent_data();
void testCurrent(); void testCurrent();
void testCurrentClient();
void testCurrentWithFollowsMouse_data(); void testCurrentWithFollowsMouse_data();
void testCurrentWithFollowsMouse(); void testCurrentWithFollowsMouse();
void testCurrentPoint_data(); void testCurrentPoint_data();
@ -56,6 +52,8 @@ void ScreensTest::initTestCase()
QVERIFY(waylandServer()->init(s_socketName)); QVERIFY(waylandServer()->init(s_socketName));
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2)); QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2));
kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig));
kwinApp()->start(); kwinApp()->start();
QVERIFY(applicationStartedSpy.wait()); QVERIFY(applicationStartedSpy.wait());
QCOMPARE(screens()->count(), 2); QCOMPARE(screens()->count(), 2);
@ -66,7 +64,7 @@ void ScreensTest::initTestCase()
void ScreensTest::init() void ScreensTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
QVERIFY(Test::setupWaylandConnection()); QVERIFY(Test::setupWaylandConnection());
@ -86,58 +84,15 @@ void ScreensTest::cleanup()
Test::destroyWaylandConnection(); Test::destroyWaylandConnection();
// Wipe the screens config clean. // Wipe the screens config clean.
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); auto config = kwinApp()->config();
purge(config.data()); purge(config.data());
config->sync(); config->sync();
screens()->setConfig(config); workspace()->slotReconfigure();
screens()->reconfigure();
// Reset the screen layout of the test environment. // Reset the screen layout of the test environment.
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2)); 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<QString>("focusPolicy");
QTest::addColumn<bool>("expectedDefault");
QTest::addColumn<bool>("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() void ScreensTest::testSize_data()
{ {
QTest::addColumn<QVector<QRect>>("geometries"); QTest::addColumn<QVector<QRect>>("geometries");
@ -216,61 +171,25 @@ void ScreensTest::testIntersecting()
void ScreensTest::testCurrent_data() void ScreensTest::testCurrent_data()
{ {
QTest::addColumn<int>("current"); QTest::addColumn<int>("currentId");
QTest::addColumn<bool>("signal");
QTest::newRow("unchanged") << 0 << false; QTest::newRow("first") << 0;
QTest::newRow("changed") << 1 << true; QTest::newRow("second") << 1;
} }
void ScreensTest::testCurrent() void ScreensTest::testCurrent()
{ {
QSignalSpy currentChangedSpy(screens(), &KWin::Screens::currentChanged); QFETCH(int, currentId);
QVERIFY(currentChangedSpy.isValid()); AbstractOutput *output = kwinApp()->platform()->findOutput(currentId);
QFETCH(int, current); // Disable "active screen follows mouse"
AbstractOutput *output = kwinApp()->platform()->findOutput(current); auto group = kwinApp()->config()->group("Windows");
group.writeEntry("ActiveMouseScreen", false);
group.sync();
workspace()->slotReconfigure();
screens()->setCurrentFollowsMouse(false); workspace()->setActiveOutput(output);
screens()->setCurrent(output); QCOMPARE(workspace()->activeOutput(), output);
QCOMPARE(screens()->currentOutput(), output);
QTEST(!currentChangedSpy.isEmpty(), "signal");
}
void ScreensTest::testCurrentClient()
{
QSignalSpy currentChangedSpy(screens(), &Screens::currentChanged);
QVERIFY(currentChangedSpy.isValid());
const QVector<AbstractOutput *> outputs = kwinApp()->platform()->enabledOutputs();
screens()->setCurrentFollowsMouse(false);
// create a test window
QScopedPointer<KWayland::Client::Surface> surface(Test::createSurface());
QScopedPointer<Test::XdgToplevel> 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]);
} }
void ScreensTest::testCurrentWithFollowsMouse_data() void ScreensTest::testCurrentWithFollowsMouse_data()
@ -290,7 +209,12 @@ void ScreensTest::testCurrentWithFollowsMouse()
{ {
QSignalSpy changedSpy(screens(), &Screens::changed); QSignalSpy changedSpy(screens(), &Screens::changed);
QVERIFY(changedSpy.isValid()); 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<QRect>, geometries); QFETCH(QVector<QRect>, geometries);
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::QueuedConnection, QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::QueuedConnection,
@ -302,7 +226,7 @@ void ScreensTest::testCurrentWithFollowsMouse()
QFETCH(int, expectedId); QFETCH(int, expectedId);
AbstractOutput *expected = kwinApp()->platform()->findOutput(expectedId); AbstractOutput *expected = kwinApp()->platform()->findOutput(expectedId);
QCOMPARE(screens()->currentOutput(), expected); QCOMPARE(workspace()->activeOutput(), expected);
} }
void ScreensTest::testCurrentPoint_data() void ScreensTest::testCurrentPoint_data()
@ -328,14 +252,18 @@ void ScreensTest::testCurrentPoint()
Q_ARG(int, geometries.count()), Q_ARG(QVector<QRect>, geometries)); Q_ARG(int, geometries.count()), Q_ARG(QVector<QRect>, geometries));
QVERIFY(changedSpy.wait()); 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); QFETCH(QPoint, cursorPos);
screens()->setCurrent(cursorPos); workspace()->setActiveOutput(cursorPos);
QFETCH(int, expectedId); QFETCH(int, expectedId);
AbstractOutput *expected = kwinApp()->platform()->findOutput(expectedId); AbstractOutput *expected = kwinApp()->platform()->findOutput(expectedId);
QCOMPARE(screens()->currentOutput(), expected); QCOMPARE(workspace()->activeOutput(), expected);
} }
} // namespace KWin } // namespace KWin

View File

@ -55,7 +55,7 @@ void ShadeTest::initTestCase()
void ShadeTest::init() void ShadeTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -88,7 +88,7 @@ void StrutsTest::init()
m_compositor = Test::waylandCompositor(); m_compositor = Test::waylandCompositor();
m_plasmaShell = Test::waylandPlasmaShell(); m_plasmaShell = Test::waylandPlasmaShell();
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
QVERIFY(waylandServer()->clients().isEmpty()); QVERIFY(waylandServer()->clients().isEmpty());
} }

View File

@ -61,7 +61,7 @@ void TabBoxTest::initTestCase()
void TabBoxTest::init() void TabBoxTest::init()
{ {
QVERIFY(Test::setupWaylandConnection()); QVERIFY(Test::setupWaylandConnection());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -71,7 +71,7 @@ void TouchInputTest::init()
QVERIFY(m_touch); QVERIFY(m_touch);
QVERIFY(m_touch->isValid()); QVERIFY(m_touch->isValid());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -80,7 +80,7 @@ void TransientPlacementTest::init()
{ {
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration | Test::AdditionalWaylandInterface::PlasmaShell)); 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)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -11,8 +11,9 @@
#include "main.h" #include "main.h"
#include "platform.h" #include "platform.h"
#include "screens.h" #include "screens.h"
#include "wayland_server.h"
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "wayland_server.h"
#include "workspace.h"
#include <KWayland/Client/surface.h> #include <KWayland/Client/surface.h>
@ -65,7 +66,7 @@ void VirtualDesktopTest::initTestCase()
void VirtualDesktopTest::init() void VirtualDesktopTest::init()
{ {
QVERIFY(Test::setupWaylandConnection()); QVERIFY(Test::setupWaylandConnection());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
VirtualDesktopManager::self()->setCount(1); VirtualDesktopManager::self()->setCount(1);
} }

View File

@ -59,7 +59,7 @@ void WindowRuleTest::initTestCase()
void WindowRuleTest::init() void WindowRuleTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512)); Cursors::self()->mouse()->setPos(QPoint(640, 512));
QVERIFY(waylandServer()->clients().isEmpty()); QVERIFY(waylandServer()->clients().isEmpty());
} }

View File

@ -73,7 +73,7 @@ void TestWindowSelection::init()
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat));
QVERIFY(Test::waitForWaylandPointer()); QVERIFY(Test::waitForWaylandPointer());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -155,7 +155,7 @@ void TestXdgShellClientRules::init()
VirtualDesktopManager::self()->setCurrent(VirtualDesktopManager::self()->desktops().first()); VirtualDesktopManager::self()->setCurrent(VirtualDesktopManager::self()->desktops().first());
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration));
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
} }
void TestXdgShellClientRules::cleanup() void TestXdgShellClientRules::cleanup()

View File

@ -193,7 +193,7 @@ void TestXdgShellClient::init()
Test::AdditionalWaylandInterface::AppMenu)); Test::AdditionalWaylandInterface::AppMenu));
QVERIFY(Test::waitForWaylandPointer()); QVERIFY(Test::waitForWaylandPointer());
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
//put mouse in the middle of screen one //put mouse in the middle of screen one
KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512)); KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
} }

View File

@ -59,7 +59,7 @@ void XWaylandInputTest::initTestCase()
void XWaylandInputTest::init() void XWaylandInputTest::init()
{ {
screens()->setCurrent(QPoint(640, 512)); workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(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_warp_pointer(connection(), XCB_WINDOW_NONE, kwinApp()->x11RootWindow(), 0, 0, 0, 0, 640, 512);
xcb_flush(connection()); xcb_flush(connection());

View File

@ -85,7 +85,7 @@ AbstractClient::AbstractClient()
Q_UNUSED(c) Q_UNUSED(c)
if (isOnScreenDisplay() && !frameGeometry().isEmpty() && old.size() != frameGeometry().size() && isPlaceable()) { if (isOnScreenDisplay() && !frameGeometry().isEmpty() && old.size() != frameGeometry().size() && isPlaceable()) {
GeometryUpdatesBlocker blocker(this); 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 // 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 // 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 // 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()); availableArea -= workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop());
bool transposed = false; bool transposed = false;
int requiredPixels; int requiredPixels;
@ -1350,7 +1350,7 @@ void AbstractClient::handleInteractiveMoveResize(int x, int y, int x_root, int y
if (!isUnrestrictedInteractiveMoveResize()) { if (!isUnrestrictedInteractiveMoveResize()) {
const QRegion strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop()); 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 availableArea -= strut; // Strut areas
bool transposed = false; bool transposed = false;
int requiredPixels; int requiredPixels;
@ -1776,30 +1776,30 @@ bool AbstractClient::performMouseCommand(Options::MouseCommand cmd, const QPoint
} }
} }
workspace()->takeActivity(this, Workspace::ActivityFocus | Workspace::ActivityRaise); workspace()->takeActivity(this, Workspace::ActivityFocus | Workspace::ActivityRaise);
screens()->setCurrent(globalPos); workspace()->setActiveOutput(globalPos);
replay = replay || mustReplay; replay = replay || mustReplay;
break; break;
} }
case Options::MouseActivateAndLower: case Options::MouseActivateAndLower:
workspace()->requestFocus(this); workspace()->requestFocus(this);
workspace()->lowerClient(this); workspace()->lowerClient(this);
screens()->setCurrent(globalPos); workspace()->setActiveOutput(globalPos);
replay = replay || !rules()->checkAcceptFocus(acceptsFocus()); replay = replay || !rules()->checkAcceptFocus(acceptsFocus());
break; break;
case Options::MouseActivate: case Options::MouseActivate:
replay = isActive(); // for clickraise mode replay = isActive(); // for clickraise mode
workspace()->takeActivity(this, Workspace::ActivityFocus); workspace()->takeActivity(this, Workspace::ActivityFocus);
screens()->setCurrent(globalPos); workspace()->setActiveOutput(globalPos);
replay = replay || !rules()->checkAcceptFocus(acceptsFocus()); replay = replay || !rules()->checkAcceptFocus(acceptsFocus());
break; break;
case Options::MouseActivateRaiseAndPassClick: case Options::MouseActivateRaiseAndPassClick:
workspace()->takeActivity(this, Workspace::ActivityFocus | Workspace::ActivityRaise); workspace()->takeActivity(this, Workspace::ActivityFocus | Workspace::ActivityRaise);
screens()->setCurrent(globalPos); workspace()->setActiveOutput(globalPos);
replay = true; replay = true;
break; break;
case Options::MouseActivateAndPassClick: case Options::MouseActivateAndPassClick:
workspace()->takeActivity(this, Workspace::ActivityFocus); workspace()->takeActivity(this, Workspace::ActivityFocus);
screens()->setCurrent(globalPos); workspace()->setActiveOutput(globalPos);
replay = true; replay = true;
break; break;
case Options::MouseMaximize: case Options::MouseMaximize:
@ -1848,7 +1848,7 @@ bool AbstractClient::performMouseCommand(Options::MouseCommand cmd, const QPoint
case Options::MouseActivateRaiseAndUnrestrictedMove: case Options::MouseActivateRaiseAndUnrestrictedMove:
workspace()->raiseClient(this); workspace()->raiseClient(this);
workspace()->requestFocus(this); workspace()->requestFocus(this);
screens()->setCurrent(globalPos); workspace()->setActiveOutput(globalPos);
// fallthrough // fallthrough
case Options::MouseMove: case Options::MouseMove:
case Options::MouseUnrestrictedMove: { case Options::MouseUnrestrictedMove: {
@ -3225,7 +3225,7 @@ void AbstractClient::sendToOutput(AbstractOutput *newOutput)
{ {
newOutput = rules()->checkOutput(newOutput); newOutput = rules()->checkOutput(newOutput);
if (isActive()) { if (isActive()) {
screens()->setCurrent(newOutput); workspace()->setActiveOutput(newOutput);
// might impact the layer of a fullscreen window // might impact the layer of a fullscreen window
Q_FOREACH (AbstractClient *cc, workspace()->allClientList()) { Q_FOREACH (AbstractClient *cc, workspace()->allClientList()) {
if (cc->isFullScreen() && cc->output() == newOutput) { if (cc->isFullScreen() && cc->output() == newOutput) {

View File

@ -393,7 +393,7 @@ bool Workspace::takeActivity(AbstractClient* c, ActivityFlags flags)
workspace()->raiseClient(c); workspace()->raiseClient(c);
if (!c->isOnActiveOutput()) { if (!c->isOnActiveOutput()) {
screens()->setCurrent(c->output()); setActiveOutput(c->output());
} }
return ret; return ret;
@ -467,7 +467,7 @@ bool Workspace::activateNextClient(AbstractClient* c)
get_focus = findDesktop(true, desktop); // to not break the state get_focus = findDesktop(true, desktop); // to not break the state
if (!get_focus && options->isNextFocusPrefersMouse()) { 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())) { 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 // should rather not happen, but it cannot get the focus. rest of usability is tested above
get_focus = nullptr; get_focus = nullptr;
@ -512,7 +512,7 @@ void Workspace::switchToOutput(AbstractOutput *output)
get_focus = findDesktop(true, desktop); get_focus = findDesktop(true, desktop);
if (get_focus != nullptr && get_focus != mostRecentlyActivatedClient()) if (get_focus != nullptr && get_focus != mostRecentlyActivatedClient())
requestFocus(get_focus); requestFocus(get_focus);
screens()->setCurrent(output); setActiveOutput(output);
} }
void Workspace::gotFocusIn(const AbstractClient* c) void Workspace::gotFocusIn(const AbstractClient* c)

View File

@ -1190,7 +1190,7 @@ void EffectsHandlerImpl::addRepaint(int x, int y, int w, int h)
int EffectsHandlerImpl::activeScreen() const int EffectsHandlerImpl::activeScreen() const
{ {
return Screens::self()->current(); return kwinApp()->platform()->enabledOutputs().indexOf(workspace()->activeOutput());
} }
int EffectsHandlerImpl::numScreens() const int EffectsHandlerImpl::numScreens() const

View File

@ -8,7 +8,7 @@
*/ */
#include "focuschain.h" #include "focuschain.h"
#include "abstract_client.h" #include "abstract_client.h"
#include "screens.h" #include "workspace.h"
namespace KWin namespace KWin
{ {
@ -52,7 +52,7 @@ void FocusChain::removeDesktop(VirtualDesktop *desktop)
AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop) const AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop) const
{ {
return getForActivation(desktop, screens()->currentOutput()); return getForActivation(desktop, workspace()->activeOutput());
} }
AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop, AbstractOutput *output) const AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop, AbstractOutput *output) const
@ -207,7 +207,7 @@ bool FocusChain::isUsableFocusCandidate(AbstractClient *c, AbstractClient *prev)
{ {
return c != prev && return c != prev &&
c->isShown(false) && c->isOnCurrentDesktop() && c->isOnCurrentActivity() && 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 AbstractClient *FocusChain::nextForDesktop(AbstractClient *reference, VirtualDesktop *desktop) const

View File

@ -41,7 +41,7 @@ void LayerShellV1Integration::createClient(LayerSurfaceV1Interface *shellSurface
{ {
AbstractOutput *output = waylandServer()->findOutput(shellSurface->output()); AbstractOutput *output = waylandServer()->findOutput(shellSurface->output());
if (!output) { if (!output) {
output = screens()->currentOutput(); output = workspace()->activeOutput();
} }
if (!output) { if (!output) {
qCWarning(KWIN_CORE) << "Could not find any suitable output for a layer surface"; qCWarning(KWIN_CORE) << "Could not find any suitable output for a layer surface";

View File

@ -42,6 +42,7 @@ Options::Options(QObject *parent)
, m_shadeHover(false) , m_shadeHover(false)
, m_shadeHoverInterval(0) , m_shadeHoverInterval(0)
, m_separateScreenFocus(false) , m_separateScreenFocus(false)
, m_activeMouseScreen(false)
, m_placement(Placement::NoPlacement) , m_placement(Placement::NoPlacement)
, m_borderSnapZone(0) , m_borderSnapZone(0)
, m_windowSnapZone(0) , m_windowSnapZone(0)
@ -226,6 +227,15 @@ void Options::setSeparateScreenFocus(bool separateScreenFocus)
Q_EMIT separateScreenFocusChanged(m_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) void Options::setPlacement(int placement)
{ {
if (m_placement == static_cast<Placement::Policy>(placement)) { if (m_placement == static_cast<Placement::Policy>(placement)) {
@ -771,6 +781,7 @@ void Options::syncFromKcfgc()
setFocusPolicy(m_settings->focusPolicy()); setFocusPolicy(m_settings->focusPolicy());
setNextFocusPrefersMouse(m_settings->nextFocusPrefersMouse()); setNextFocusPrefersMouse(m_settings->nextFocusPrefersMouse());
setSeparateScreenFocus(m_settings->separateScreenFocus()); setSeparateScreenFocus(m_settings->separateScreenFocus());
setActiveMouseScreen(m_settings->activeMouseScreen());
setRollOverDesktops(m_settings->rollOverDesktops()); setRollOverDesktops(m_settings->rollOverDesktops());
setFocusStealingPreventionLevel(m_settings->focusStealingPreventionLevel()); setFocusStealingPreventionLevel(m_settings->focusStealingPreventionLevel());
setXwaylandCrashPolicy(m_settings->xwaylandCrashPolicy()); setXwaylandCrashPolicy(m_settings->xwaylandCrashPolicy());

View File

@ -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) * 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 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(int placement READ placement WRITE setPlacement NOTIFY placementChanged)
Q_PROPERTY(bool focusPolicyIsReasonable READ focusPolicyIsReasonable NOTIFY focusPolicyIsResonableChanged) Q_PROPERTY(bool focusPolicyIsReasonable READ focusPolicyIsReasonable NOTIFY focusPolicyIsResonableChanged)
/** /**
@ -306,6 +307,10 @@ public:
return m_separateScreenFocus; return m_separateScreenFocus;
} }
bool activeMouseScreen() const {
return m_activeMouseScreen;
}
Placement::Policy placement() const { Placement::Policy placement() const {
return m_placement; return m_placement;
} }
@ -621,6 +626,7 @@ public:
void setShadeHover(bool shadeHover); void setShadeHover(bool shadeHover);
void setShadeHoverInterval(int shadeHoverInterval); void setShadeHoverInterval(int shadeHoverInterval);
void setSeparateScreenFocus(bool separateScreenFocus); void setSeparateScreenFocus(bool separateScreenFocus);
void setActiveMouseScreen(bool activeMouseScreen);
void setPlacement(int placement); void setPlacement(int placement);
void setBorderSnapZone(int borderSnapZone); void setBorderSnapZone(int borderSnapZone);
void setWindowSnapZone(int windowSnapZone); void setWindowSnapZone(int windowSnapZone);
@ -793,6 +799,7 @@ Q_SIGNALS:
void shadeHoverChanged(); void shadeHoverChanged();
void shadeHoverIntervalChanged(); void shadeHoverIntervalChanged();
void separateScreenFocusChanged(bool); void separateScreenFocusChanged(bool);
void activeMouseScreenChanged();
void placementChanged(); void placementChanged();
void borderSnapZoneChanged(); void borderSnapZoneChanged();
void windowSnapZoneChanged(); void windowSnapZoneChanged();
@ -856,6 +863,7 @@ private:
bool m_shadeHover; bool m_shadeHover;
int m_shadeHoverInterval; int m_shadeHoverInterval;
bool m_separateScreenFocus; bool m_separateScreenFocus;
bool m_activeMouseScreen;
Placement::Policy m_placement; Placement::Policy m_placement;
int m_borderSnapZone; int m_borderSnapZone;
int m_windowSnapZone; int m_windowSnapZone;

View File

@ -42,8 +42,6 @@ Screens *Screens::create(QObject *parent)
Screens::Screens(QObject *parent) Screens::Screens(QObject *parent)
: QObject(parent) : QObject(parent)
, m_count(0) , m_count(0)
, m_current(0)
, m_currentFollowsMouse(false)
, m_maxScale(1.0) , m_maxScale(1.0)
{ {
// TODO: Do something about testScreens and other tests that use MockScreens. // 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::changed, this, &Screens::updateSize);
connect(this, &Screens::sizeChanged, this, &Screens::geometryChanged); connect(this, &Screens::sizeChanged, this, &Screens::geometryChanged);
Settings settings;
settings.setDefaults();
m_currentFollowsMouse = settings.activeMouseScreen();
Q_EMIT changed(); Q_EMIT changed();
} }
@ -133,16 +128,6 @@ qreal Screens::maxScale() const
return m_maxScale; return m_maxScale;
} }
void Screens::reconfigure()
{
if (!m_config) {
return;
}
Settings settings(m_config);
settings.read();
setCurrentFollowsMouse(settings.activeMouseScreen());
}
void Screens::updateSize() void Screens::updateSize()
{ {
QRect bounding; QRect bounding;
@ -176,68 +161,6 @@ void Screens::setCount(int count)
Q_EMIT countChanged(previous, 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 Screens::intersecting(const QRect &r) const
{ {
int cnt = 0; int cnt = 0;
@ -260,11 +183,6 @@ Qt::ScreenOrientation Screens::orientation(int screen) const
return Qt::PrimaryOrientation; return Qt::PrimaryOrientation;
} }
void Screens::setConfig(KSharedConfig::Ptr config)
{
m_config = config;
}
int Screens::physicalDpiX(int screen) const int Screens::physicalDpiX(int screen) const
{ {
return size(screen).width() / physicalSize(screen).width() * qreal(25.4); return size(screen).width() / physicalSize(screen).width() * qreal(25.4);

View File

@ -31,32 +31,10 @@ class KWIN_EXPORT Screens : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged) 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: public:
~Screens() override; ~Screens() override;
/**
* @internal
*/
void setConfig(KSharedConfig::Ptr config);
int count() const; 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; virtual QRect geometry(int screen) const;
/** /**
* The bounding geometry of all screens combined. Overlapping areas * The bounding geometry of all screens combined. Overlapping areas
@ -143,16 +121,12 @@ public:
*/ */
RenderLoop::VrrPolicy vrrPolicy(int screen) const; RenderLoop::VrrPolicy vrrPolicy(int screen) const;
public Q_SLOTS:
void reconfigure();
Q_SIGNALS: Q_SIGNALS:
void countChanged(int previousCount, int newCount); void countChanged(int previousCount, int newCount);
/** /**
* Emitted whenever the screens are changed either count or geometry. * Emitted whenever the screens are changed either count or geometry.
*/ */
void changed(); void changed();
void currentChanged();
/** /**
* Emitted when the geometry of all screens combined changes. * Emitted when the geometry of all screens combined changes.
* Not emitted when the geometry of an individual screen changes. * Not emitted when the geometry of an individual screen changes.
@ -190,9 +164,6 @@ private:
AbstractOutput *findOutput(int screenId) const; AbstractOutput *findOutput(int screenId) const;
int m_count; int m_count;
int m_current;
bool m_currentFollowsMouse;
KSharedConfig::Ptr m_config;
QSize m_boundingSize; QSize m_boundingSize;
qreal m_maxScale; qreal m_maxScale;
@ -205,12 +176,6 @@ int Screens::count() const
return m_count; return m_count;
} }
inline
bool Screens::isCurrentFollowsMouse() const
{
return m_currentFollowsMouse;
}
inline inline
QSize Screens::size() const QSize Screens::size() const
{ {

View File

@ -363,7 +363,7 @@ int WorkspaceWrapper::numScreens() const
int WorkspaceWrapper::activeScreen() const int WorkspaceWrapper::activeScreen() const
{ {
return screens()->current(); return kwinApp()->platform()->enabledOutputs().indexOf(workspace()->activeOutput());
} }
QRect WorkspaceWrapper::virtualScreenGeometry() const QRect WorkspaceWrapper::virtualScreenGeometry() const

View File

@ -8,9 +8,11 @@
*/ */
#include "switcheritem.h" #include "switcheritem.h"
// KWin // KWin
#include "abstract_output.h"
#include "composite.h" #include "composite.h"
#include "tabboxhandler.h" #include "tabboxhandler.h"
#include "screens.h" #include "screens.h"
#include "workspace.h"
// Qt // Qt
#include <QAbstractItemModel> #include <QAbstractItemModel>
@ -69,7 +71,7 @@ void SwitcherItem::setVisible(bool visible)
QRect SwitcherItem::screenGeometry() const QRect SwitcherItem::screenGeometry() const
{ {
return screens()->geometry(screens()->current()); return workspace()->activeOutput()->geometry();
} }
void SwitcherItem::setCurrentIndex(int index) void SwitcherItem::setCurrentIndex(int index)

View File

@ -30,6 +30,7 @@
#include "keyboard_input.h" #include "keyboard_input.h"
#include "pointer_input.h" #include "pointer_input.h"
#include "focuschain.h" #include "focuschain.h"
#include "platform.h"
#include "screenedge.h" #include "screenedge.h"
#include "screens.h" #include "screens.h"
#include "unmanaged.h" #include "unmanaged.h"
@ -81,7 +82,7 @@ TabBoxHandlerImpl::~TabBoxHandlerImpl()
int TabBoxHandlerImpl::activeScreen() const int TabBoxHandlerImpl::activeScreen() const
{ {
return screens()->current(); return kwinApp()->platform()->enabledOutputs().indexOf(workspace()->activeOutput());
} }
int TabBoxHandlerImpl::currentDesktop() const int TabBoxHandlerImpl::currentDesktop() const
@ -235,9 +236,9 @@ bool TabBoxHandlerImpl::checkMultiScreen(TabBoxClient* client) const
case TabBoxConfig::IgnoreMultiScreen: case TabBoxConfig::IgnoreMultiScreen:
return true; return true;
case TabBoxConfig::ExcludeCurrentScreenClients: case TabBoxConfig::ExcludeCurrentScreenClients:
return current->output() != screens()->currentOutput(); return current->output() != workspace()->activeOutput();
default: // TabBoxConfig::OnlyCurrentScreenClients default: // TabBoxConfig::OnlyCurrentScreenClients
return current->output() == screens()->currentOutput(); return current->output() == workspace()->activeOutput();
} }
} }
@ -322,7 +323,7 @@ QWeakPointer<TabBoxClient> TabBoxHandlerImpl::desktopClient() const
{ {
Q_FOREACH (Toplevel *toplevel, Workspace::self()->stackingOrder()) { Q_FOREACH (Toplevel *toplevel, Workspace::self()->stackingOrder()) {
auto client = qobject_cast<AbstractClient*>(toplevel); auto client = qobject_cast<AbstractClient*>(toplevel);
if (client && client->isDesktop() && client->isOnCurrentDesktop() && client->output() == screens()->currentOutput()) { if (client && client->isDesktop() && client->isOnCurrentDesktop() && client->output() == workspace()->activeOutput()) {
return client->tabBoxClient(); return client->tabBoxClient();
} }
} }

View File

@ -422,7 +422,7 @@ bool Toplevel::isOnScreen(int screen) const
bool Toplevel::isOnActiveOutput() const bool Toplevel::isOnActiveOutput() const
{ {
return isOnOutput(screens()->currentOutput()); return isOnOutput(workspace()->activeOutput());
} }
bool Toplevel::isOnOutput(AbstractOutput *output) const bool Toplevel::isOnOutput(AbstractOutput *output) const

View File

@ -1289,7 +1289,7 @@ void Workspace::slotWindowToDesktop(VirtualDesktop *desktop)
static bool screenSwitchImpossible() static bool screenSwitchImpossible()
{ {
if (!screens()->isCurrentFollowsMouse()) if (!options->activeMouseScreen())
return false; return false;
QStringList args; QStringList args;
args << QStringLiteral("--passivepopup") << i18n("The window manager is configured to consider the screen with the mouse on it as active one.\n" 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()) if (screenSwitchImpossible())
return; return;
switchToOutput(nextOutput(screens()->currentOutput())); switchToOutput(nextOutput(activeOutput()));
} }
void Workspace::slotSwitchToPrevScreen() void Workspace::slotSwitchToPrevScreen()
{ {
if (screenSwitchImpossible()) if (screenSwitchImpossible())
return; return;
switchToOutput(previousOutput(screens()->currentOutput())); switchToOutput(previousOutput(activeOutput()));
} }
void Workspace::slotWindowToScreen() void Workspace::slotWindowToScreen()

View File

@ -207,11 +207,6 @@ Workspace::Workspace()
void Workspace::init() void Workspace::init()
{ {
KSharedConfigPtr config = kwinApp()->config(); 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 *screenEdges = ScreenEdges::self();
screenEdges->setConfig(config); screenEdges->setConfig(config);
screenEdges->init(); screenEdges->init();
@ -786,7 +781,7 @@ void Workspace::addShellClient(AbstractClient *client)
client->updateLayer(); client->updateLayer();
if (client->isPlaceable()) { if (client->isPlaceable()) {
const QRect area = clientArea(PlacementArea, client, Screens::self()->currentOutput()); const QRect area = clientArea(PlacementArea, client, activeOutput());
bool placementDone = false; bool placementDone = false;
if (client->isRequestedFullScreen()) { if (client->isRequestedFullScreen()) {
placementDone = true; placementDone = true;
@ -1207,12 +1202,20 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
void Workspace::slotOutputEnabled(AbstractOutput *output) void Workspace::slotOutputEnabled(AbstractOutput *output)
{ {
if (!m_activeOutput) {
m_activeOutput = output;
}
connect(output, &AbstractOutput::geometryChanged, this, &Workspace::desktopResized); connect(output, &AbstractOutput::geometryChanged, this, &Workspace::desktopResized);
desktopResized(); desktopResized();
} }
void Workspace::slotOutputDisabled(AbstractOutput *output) void Workspace::slotOutputDisabled(AbstractOutput *output)
{ {
if (m_activeOutput == output) {
m_activeOutput = kwinApp()->platform()->outputAt(output->geometry().center());
}
const auto stack = xStackingOrder(); const auto stack = xStackingOrder();
for (Toplevel *toplevel : stack) { for (Toplevel *toplevel : stack) {
if (toplevel->output() == output) { if (toplevel->output() == output) {
@ -1610,7 +1613,7 @@ QString Workspace::supportInformation() const
support.append(QStringLiteral("no\n")); support.append(QStringLiteral("no\n"));
} }
support.append(QStringLiteral("Active screen follows mouse: ")); support.append(QStringLiteral("Active screen follows mouse: "));
if (screens()->isCurrentFollowsMouse()) if (options->activeMouseScreen())
support.append(QStringLiteral(" yes\n")); support.append(QStringLiteral(" yes\n"));
else else
support.append(QStringLiteral(" no\n")); support.append(QStringLiteral(" no\n"));
@ -1932,7 +1935,7 @@ void Workspace::addInternalClient(InternalClient *client)
client->updateLayer(); client->updateLayer();
if (client->isPlaceable()) { if (client->isPlaceable()) {
const QRect area = clientArea(PlacementArea, client, screens()->currentOutput()); const QRect area = clientArea(PlacementArea, client, workspace()->activeOutput());
client->placeIn(area); client->placeIn(area);
} }
@ -2409,6 +2412,30 @@ int Workspace::oldDisplayHeight() const
return olddisplaysize.height(); 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 * Client \a c is moved around to position \a pos. This gives the
* workspace the opportunity to interveniate and to implement * workspace the opportunity to interveniate and to implement

View File

@ -154,6 +154,10 @@ public:
bool initializing() const; 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 * Returns the active client, i.e. the client that has the focus (or None
* if no client has the focus) * if no client has the focus)
@ -596,6 +600,7 @@ private:
void updateXStackingOrder(); void updateXStackingOrder();
void updateTabbox(); void updateTabbox();
AbstractOutput *m_activeOutput = nullptr;
AbstractClient* active_client; AbstractClient* active_client;
AbstractClient* last_active_client; AbstractClient* last_active_client;
AbstractClient* movingClient; AbstractClient* movingClient;

View File

@ -614,7 +614,7 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
output = kwinApp()->platform()->findOutput(asn_data.xinerama()); output = kwinApp()->platform()->findOutput(asn_data.xinerama());
} }
if (!output) { if (!output) {
output = screens()->currentOutput(); output = workspace()->activeOutput();
} }
output = rules()->checkOutput(output, !isMapped); output = rules()->checkOutput(output, !isMapped);
area = workspace()->clientArea(PlacementArea, this, output->geometry().center()); 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_lastFrameGeometry = m_frameGeometry;
m_lastClientGeometry = m_clientGeometry; m_lastClientGeometry = m_clientGeometry;
screens()->setCurrent(this); if (isActive()) {
workspace()->setActiveOutput(output());
}
workspace()->updateStackingOrder(); workspace()->updateStackingOrder();
if (oldBufferGeometry != m_bufferGeometry) { if (oldBufferGeometry != m_bufferGeometry) {

View File

@ -1235,7 +1235,7 @@ void XdgToplevelClient::initialize()
needsPlacement = false; needsPlacement = false;
} }
if (needsPlacement) { if (needsPlacement) {
const QRect area = workspace()->clientArea(PlacementArea, this, Screens::self()->currentOutput()); const QRect area = workspace()->clientArea(PlacementArea, this, workspace()->activeOutput());
placeIn(area); placeIn(area);
} }
@ -2059,7 +2059,7 @@ void XdgPopupClient::initialize()
updateReactive(); updateReactive();
const QRect area = workspace()->clientArea(PlacementArea, this, Screens::self()->currentOutput()); const QRect area = workspace()->clientArea(PlacementArea, this, workspace()->activeOutput());
placeIn(area); placeIn(area);
scheduleConfigure(); scheduleConfigure();
} }