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());
screens()->setCurrent(QPoint(640, 512));
workspace()->setActiveOutput(QPoint(640, 512));
Cursors::self()->mouse()->setPos(QPoint(640, 512));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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();

View File

@ -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));
}

View File

@ -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);

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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()

View File

@ -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));
}

View File

@ -13,6 +13,7 @@
#include "platform.h"
#include "screens.h"
#include "wayland_server.h"
#include "workspace.h"
#include <KWayland/Client/outputmanagement.h>
#include <KWayland/Client/outputconfiguration.h>
@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -11,6 +11,7 @@
#include "platform.h"
#include "screens.h"
#include "wayland_server.h"
#include "workspace.h"
#include <KWayland/Client/output.h>
#include <KWayland/Client/xdgoutput.h>
@ -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));
}

View File

@ -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());
}

View File

@ -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<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()
{
QTest::addColumn<QVector<QRect>>("geometries");
@ -216,61 +171,25 @@ void ScreensTest::testIntersecting()
void ScreensTest::testCurrent_data()
{
QTest::addColumn<int>("current");
QTest::addColumn<bool>("signal");
QTest::addColumn<int>("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<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]);
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<QRect>, 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<QRect>, 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

View File

@ -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));
}

View File

@ -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());
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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 <KWayland/Client/surface.h>
@ -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);
}

View File

@ -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());
}

View File

@ -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));
}

View File

@ -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()

View File

@ -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));
}

View File

@ -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());

View File

@ -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) {

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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";

View File

@ -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::Policy>(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());

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)
*/
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;

View File

@ -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);

View File

@ -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
{

View File

@ -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

View File

@ -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 <QAbstractItemModel>
@ -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)

View File

@ -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<TabBoxClient> TabBoxHandlerImpl::desktopClient() const
{
Q_FOREACH (Toplevel *toplevel, Workspace::self()->stackingOrder()) {
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();
}
}

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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();
}