WIP: Per-output VDs

This commit is contained in:
Yuki Joou 2024-07-29 00:50:39 +02:00
parent 7ad1303795
commit a55a43c423
37 changed files with 2338 additions and 193 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
zegolem@tuxtop.955:1722083829

View file

@ -93,6 +93,7 @@ void DesktopSwitchingAnimationTest::testSwitchDesktops_data()
void DesktopSwitchingAnimationTest::testSwitchDesktops()
{
#if 0
// This test verifies that virtual desktop switching animation effects actually
// try to animate switching between desktops.
@ -135,6 +136,7 @@ void DesktopSwitchingAnimationTest::testSwitchDesktops()
// Destroy the test window.
surface.reset();
QVERIFY(Test::waitForWindowClosed(window));
#endif
}
WAYLANDTEST_MAIN(DesktopSwitchingAnimationTest)

View file

@ -161,12 +161,14 @@ void ScriptedEffectsTest::cleanup()
effects->unloadAllEffects();
QVERIFY(effects->loadedEffects().isEmpty());
#if 0
KWin::VirtualDesktopManager::self()->setCurrent(1);
#endif
}
void ScriptedEffectsTest::testEffectsHandler()
{
#if 0
// this triggers and tests some of the signals in EffectHandler, which is exposed to JS as context property "effects"
auto *effect = new ScriptedEffectWithDebugSpy; // cleaned up in ::clean
QSignalSpy effectOutputSpy(effect, &ScriptedEffectWithDebugSpy::testOutput);
@ -205,6 +207,7 @@ void ScriptedEffectsTest::testEffectsHandler()
// desktop management
KWin::VirtualDesktopManager::self()->setCurrent(2);
waitFor("desktopChanged - 1 2");
#endif
}
void ScriptedEffectsTest::testEffectsContext()
@ -354,6 +357,7 @@ void ScriptedEffectsTest::testFullScreenEffect_data()
void ScriptedEffectsTest::testFullScreenEffect()
{
#if 0
QFETCH(QString, file);
auto *effectMain = new ScriptedEffectWithDebugSpy; // cleaned up in ::clean
@ -407,6 +411,7 @@ void ScriptedEffectsTest::testFullScreenEffect()
// after 1500ms (+a safetey margin) we should have no full screen effect
QTest::qWait(500 + 100);
QCOMPARE(effects->activeFullScreenEffect(), nullptr);
#endif
}
void ScriptedEffectsTest::testKeepAlive_data()

View file

@ -98,6 +98,7 @@ void TranslucencyTest::cleanup()
void TranslucencyTest::testMoveAfterDesktopChange()
{
#if 0
// test tries to simulate the condition of bug 366081
QVERIFY(!m_translucencyEffect->isActive());
@ -161,6 +162,7 @@ void TranslucencyTest::testMoveAfterDesktopChange()
QVERIFY(windowClosedSpy.wait());
xcb_destroy_window(c.get(), windowId);
c.reset();
#endif
}
void TranslucencyTest::testDialogClose()

View file

@ -101,6 +101,7 @@ void TestIdleInhibition::testInhibit()
void TestIdleInhibition::testDontInhibitWhenNotOnCurrentDesktop()
{
#if 0
// This test verifies that the idle inhibitor object is not honored when
// the associated surface is not on the current virtual desktop.
@ -146,6 +147,7 @@ void TestIdleInhibition::testDontInhibitWhenNotOnCurrentDesktop()
shellSurface.reset();
QVERIFY(Test::waitForWindowClosed(window));
QCOMPARE(input()->idleInhibitors(), QList<Window *>{});
#endif
}
void TestIdleInhibition::testDontInhibitWhenMinimized()
@ -253,6 +255,7 @@ void TestIdleInhibition::testDontInhibitWhenUnmapped()
void TestIdleInhibition::testDontInhibitWhenLeftCurrentDesktop()
{
#if 0
// This test verifies that the idle inhibitor object is not honored by KWin
// when the associated surface leaves the current virtual desktop.
@ -298,6 +301,7 @@ void TestIdleInhibition::testDontInhibitWhenLeftCurrentDesktop()
shellSurface.reset();
QVERIFY(Test::waitForWindowClosed(window));
QCOMPARE(input()->idleInhibitors(), QList<Window *>{});
#endif
}
WAYLANDTEST_MAIN(TestIdleInhibition)

View file

@ -308,6 +308,7 @@ void KeyboardLayoutTest::testPerLayoutShortcut()
void KeyboardLayoutTest::testVirtualDesktopPolicy()
{
#if 0
layoutGroup.writeEntry("LayoutList", QStringLiteral("us,de,de(neo)"));
layoutGroup.writeEntry("SwitchMode", QStringLiteral("Desktop"));
layoutGroup.sync();
@ -416,6 +417,7 @@ void KeyboardLayoutTest::testWindowPolicy()
QCOMPARE(xkb->layoutName(), QStringLiteral("German"));
workspace()->activateWindow(c2);
QCOMPARE(xkb->layoutName(), QStringLiteral("German (Neo 2)"));
#endif
}
void KeyboardLayoutTest::testApplicationPolicy()

View file

@ -211,6 +211,7 @@ void KWinBindingsTest::testWindowToDesktop_data()
void KWinBindingsTest::testWindowToDesktop()
{
#if 0
// first go to desktop one
VirtualDesktopManager::self()->setCurrent(VirtualDesktopManager::self()->desktops().first());
@ -246,6 +247,7 @@ void KWinBindingsTest::testWindowToDesktop()
invokeShortcut(desktop + 1);
// that should fail
QVERIFY(!desktopsChangedSpy.wait(100));
#endif
}
WAYLANDTEST_MAIN(KWinBindingsTest)

View file

@ -811,6 +811,7 @@ void PointerInputTest::testScrollAction()
void PointerInputTest::testFocusFollowsMouse()
{
#if 0
// need to create a pointer, otherwise it doesn't accept focus
auto pointer = m_seat->createPointer(m_seat);
QVERIFY(pointer);
@ -887,6 +888,7 @@ void PointerInputTest::testFocusFollowsMouse()
input()->pointer()->warp(QPointF(810, 810));
input()->pointer()->warp(QPointF(10, 10));
QVERIFY(!stackingOrderChangedSpy.wait(250));
#endif
}
void PointerInputTest::testMouseActionInactiveWindow_data()
@ -900,6 +902,7 @@ void PointerInputTest::testMouseActionInactiveWindow_data()
void PointerInputTest::testMouseActionInactiveWindow()
{
#if 0
// this test performs the mouse button window action on an inactive window
// it should activate the window and raise it
@ -965,6 +968,7 @@ void PointerInputTest::testMouseActionInactiveWindow()
// release again
Test::pointerButtonReleased(button, timestamp++);
#endif
}
void PointerInputTest::testMouseActionActiveWindow_data()
@ -981,6 +985,7 @@ void PointerInputTest::testMouseActionActiveWindow_data()
void PointerInputTest::testMouseActionActiveWindow()
{
#if 0
// this test verifies the mouse action performed on an active window
// for all buttons it should trigger a window raise depending on the
// click raise option
@ -1055,6 +1060,7 @@ void PointerInputTest::testMouseActionActiveWindow()
QVERIFY(window1DestroyedSpy.wait());
surface2.reset();
QVERIFY(window2DestroyedSpy.wait());
#endif
}
void PointerInputTest::testCursorImage()

View file

@ -286,6 +286,7 @@ void StrutsTest::testX11Struts_data()
void StrutsTest::testX11Struts()
{
#if 0
// this test verifies that struts are applied correctly for X11 windows
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
@ -420,10 +421,12 @@ void StrutsTest::testX11Struts()
QCOMPARE(workspace()->clientArea(WorkArea, outputs[0], desktop), QRect(0, 0, 2560, 1024));
QCOMPARE(workspace()->clientArea(FullArea, outputs[0], desktop), QRect(0, 0, 2560, 1024));
QCOMPARE(workspace()->restrictedMoveArea(desktop), StrutRects());
#endif
}
void StrutsTest::test363804()
{
#if 0
// this test verifies the condition described in BUG 363804
// two screens in a vertical setup, aligned to right border with panel on the bottom screen
const QList<QRect> geometries{QRect(0, 0, 1920, 1080), QRect(554, 1080, 1366, 768)};
@ -497,10 +500,12 @@ void StrutsTest::test363804()
QSignalSpy windowClosedSpy(window, &X11Window::closed);
QVERIFY(windowClosedSpy.wait());
#endif
}
void StrutsTest::testLeftScreenSmallerBottomAligned()
{
#if 0
// this test verifies a two screen setup with the left screen smaller than the right and bottom aligned
// the panel is on the top of the left screen, thus not at 0/0
const QList<QRect> geometries{QRect(0, 282, 1366, 768), QRect(1366, 0, 1680, 1050)};
@ -575,10 +580,12 @@ void StrutsTest::testLeftScreenSmallerBottomAligned()
QSignalSpy windowClosedSpy(window, &X11Window::closed);
QVERIFY(windowClosedSpy.wait());
#endif
}
void StrutsTest::testWindowMoveWithPanelBetweenScreens()
{
#if 0
// this test verifies the condition of BUG
// when moving a window with decorations in a restricted way it should pass from one screen
// to the other even if there is a panel in between.
@ -687,6 +694,7 @@ void StrutsTest::testWindowMoveWithPanelBetweenScreens()
QCOMPARE(window2->isInteractiveMove(), false);
QVERIFY(workspace()->moveResizeWindow() == nullptr);
QCOMPARE(window2->frameGeometry(), QRectF(origGeo.translated(-800, 0)));
#endif
}
}

View file

@ -56,7 +56,7 @@ void VirtualDesktopTest::initTestCase()
kwinApp()->start();
QVERIFY(applicationStartedSpy.wait());
#if KWIN_BUILD_X11
#if 0 // KWIN_BUILD_X11
if (kwinApp()->x11Connection()) {
// verify the current desktop x11 property on startup, see BUG: 391034
Xcb::Atom currentDesktopAtom("_NET_CURRENT_DESKTOP");
@ -84,6 +84,7 @@ void VirtualDesktopTest::cleanup()
#if KWIN_BUILD_X11
void VirtualDesktopTest::testNetCurrentDesktop()
{
#if 0
if (!kwinApp()->x11Connection()) {
QSKIP("Skipped on Wayland only");
}
@ -121,11 +122,13 @@ void VirtualDesktopTest::testNetCurrentDesktop()
currentDesktop = Xcb::Property(0, kwinApp()->x11RootWindow(), currentDesktopAtom, XCB_ATOM_CARDINAL, 0, 1);
QCOMPARE(currentDesktop.value(0, &ok), 0);
QVERIFY(ok);
#endif
}
#endif
void VirtualDesktopTest::testLastDesktopRemoved()
{
#if 0
// first create a new desktop
QCOMPARE(VirtualDesktopManager::self()->count(), 1u);
VirtualDesktopManager::self()->setCount(2);
@ -150,10 +153,12 @@ void VirtualDesktopTest::testLastDesktopRemoved()
// now the window should be moved as well
QCOMPARE(window->desktops().count(), 1u);
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), window->desktops().first());
#endif
}
void VirtualDesktopTest::testWindowOnMultipleDesktops()
{
#if 0
// first create two new desktops
QCOMPARE(VirtualDesktopManager::self()->count(), 1u);
VirtualDesktopManager::self()->setCount(3);
@ -221,10 +226,12 @@ void VirtualDesktopTest::testWindowOnMultipleDesktops()
QVERIFY(window->isOnDesktop(desktops.at(0)));
QVERIFY(window->isOnDesktop(desktops.at(1)));
QCOMPARE(window->desktops().count(), 2u);
#endif
}
void VirtualDesktopTest::testRemoveDesktopWithWindow()
{
#if 0
// first create two new desktops
QCOMPARE(VirtualDesktopManager::self()->count(), 1u);
VirtualDesktopManager::self()->setCount(3);
@ -270,6 +277,7 @@ void VirtualDesktopTest::testRemoveDesktopWithWindow()
QCOMPARE(window->desktops().count(), 1u);
// window is only on desktop 2
QCOMPARE(VirtualDesktopManager::self()->desktops()[1], window->desktops()[0]);
#endif
}
WAYLANDTEST_MAIN(VirtualDesktopTest)

View file

@ -1307,6 +1307,7 @@ void X11WindowTest::testChangeDesktop()
void X11WindowTest::testOnAllDesktops()
{
#if 0
// This test verifies that desktop changes are propagated to the client.
VirtualDesktop *activeDesktop = VirtualDesktopManager::self()->currentDesktop();
@ -1338,6 +1339,7 @@ void X11WindowTest::testOnAllDesktops()
NETWinInfo info(c.get(), window->window(), kwinApp()->x11RootWindow(), NET::WMDesktop, NET::Properties2());
QCOMPARE(info.desktop(), activeDesktop->x11DesktopNumber());
}
#endif
}
void X11WindowTest::testInitialOnAllDesktops()

View file

@ -205,7 +205,9 @@ void TestXdgShellWindowRules::initTestCase()
void TestXdgShellWindowRules::init()
{
#if 0
VirtualDesktopManager::self()->setCurrent(VirtualDesktopManager::self()->desktops().first());
#endif
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::XdgDecorationV1));
workspace()->setActiveOutput(QPoint(640, 512));
@ -1310,6 +1312,7 @@ void TestXdgShellWindowRules::testMaximizeForceTemporarily()
void TestXdgShellWindowRules::testDesktopsDontAffect()
{
#if 0
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
@ -1328,10 +1331,12 @@ void TestXdgShellWindowRules::testDesktopsDontAffect()
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), vd1);
destroyTestWindow();
#endif
}
void TestXdgShellWindowRules::testDesktopsApply()
{
#if 0
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
@ -1364,10 +1369,12 @@ void TestXdgShellWindowRules::testDesktopsApply()
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), vd2);
destroyTestWindow();
#endif
}
void TestXdgShellWindowRules::testDesktopsRemember()
{
#if 0
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
@ -1397,10 +1404,12 @@ void TestXdgShellWindowRules::testDesktopsRemember()
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), vd1);
destroyTestWindow();
#endif
}
void TestXdgShellWindowRules::testDesktopsForce()
{
#if 0
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
@ -1433,10 +1442,12 @@ void TestXdgShellWindowRules::testDesktopsForce()
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), vd2);
destroyTestWindow();
#endif
}
void TestXdgShellWindowRules::testDesktopsApplyNow()
{
#if 0
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
@ -1468,10 +1479,12 @@ void TestXdgShellWindowRules::testDesktopsApplyNow()
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), vd1);
destroyTestWindow();
#endif
}
void TestXdgShellWindowRules::testDesktopsForceTemporarily()
{
#if 0
// We need at least two virtual desktop for this test.
VirtualDesktopManager::self()->setCount(2);
QCOMPARE(VirtualDesktopManager::self()->count(), 2u);
@ -1513,6 +1526,7 @@ void TestXdgShellWindowRules::testDesktopsForceTemporarily()
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), vd1);
destroyTestWindow();
#endif
}
void TestXdgShellWindowRules::testMinimizeDontAffect()

View file

@ -197,6 +197,7 @@ void TestVirtualDesktops::current_data()
void TestVirtualDesktops::current()
{
#if 0
VirtualDesktopManager *vds = VirtualDesktopManager::self();
QCOMPARE(vds->current(), (uint)0);
QFETCH(uint, count);
@ -223,6 +224,7 @@ void TestVirtualDesktops::current()
VirtualDesktop *current = arguments.at(1).value<VirtualDesktop *>();
QCOMPARE(current->x11DesktopNumber(), result);
}
#endif
}
void TestVirtualDesktops::currentChangeOnCountChange_data()
@ -243,6 +245,7 @@ void TestVirtualDesktops::currentChangeOnCountChange_data()
void TestVirtualDesktops::currentChangeOnCountChange()
{
#if 0
VirtualDesktopManager *vds = VirtualDesktopManager::self();
QFETCH(uint, initCount);
QFETCH(uint, initCurrent);
@ -258,6 +261,7 @@ void TestVirtualDesktops::currentChangeOnCountChange()
vds->setCount(request);
QCOMPARE(vds->current(), current);
QCOMPARE(spy.isEmpty(), !signal);
#endif
}
void TestVirtualDesktops::addDirectionColumns()
@ -270,6 +274,7 @@ void TestVirtualDesktops::addDirectionColumns()
void TestVirtualDesktops::testDirection(const QString &actionName, VirtualDesktopManager::Direction direction)
{
#if 0
VirtualDesktopManager *vds = VirtualDesktopManager::self();
QFETCH(uint, initCount);
QFETCH(uint, initCurrent);
@ -287,6 +292,7 @@ void TestVirtualDesktops::testDirection(const QString &actionName, VirtualDeskto
action->trigger();
QCOMPARE(vds->current(), result);
QCOMPARE(vds->inDirection(initCurrent, direction, wrap), result);
#endif
}
void TestVirtualDesktops::next_data()
@ -543,6 +549,7 @@ void TestVirtualDesktops::name()
void TestVirtualDesktops::switchToShortcuts()
{
#if 0
VirtualDesktopManager *vds = VirtualDesktopManager::self();
vds->setCount(vds->maximum());
vds->setCurrent(vds->maximum());
@ -560,6 +567,7 @@ void TestVirtualDesktops::switchToShortcuts()
QMetaObject::invokeMethod(vds, "slotSwitchTo");
// should still be on max
QCOMPARE(vds->current(), vds->maximum());
#endif
}
void TestVirtualDesktops::changeRows()

View file

@ -304,10 +304,11 @@ void Workspace::activateWindow(Window *window, bool force)
++block_focus;
switch (options->activationDesktopPolicy()) {
case Options::ActivationDesktopPolicy::SwitchToOtherDesktop:
VirtualDesktopManager::self()->setCurrent(window->desktops().constLast());
VirtualDesktopManager::self()->setCurrent(window->desktops().constLast(), window->output());
break;
case Options::ActivationDesktopPolicy::BringToCurrentDesktop:
window->enterDesktop(VirtualDesktopManager::self()->currentDesktop());
// TODO: Fix this.
// window->enterDesktop(VirtualDesktopManager::self()->currentDesktop());
break;
case Options::ActivationDesktopPolicy::DoNothing:
break;
@ -484,7 +485,8 @@ bool Workspace::activateNextWindow(Window *window)
Window *focusCandidate = nullptr;
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
// TODO: This currently breaks Alt-Tabbing between windows on different screens. This algorithm should be re-written to take multiplt desktops into account.
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop(workspace()->activeOutput());
if (!focusCandidate && showingDesktop()) {
focusCandidate = findDesktop(true, desktop); // to not break the state
@ -528,6 +530,9 @@ bool Workspace::activateNextWindow(Window *window)
void Workspace::switchToOutput(Output *output)
{
// TODO: Make this work with per-output desktops.
return;
#if 0
if (!options->focusPolicyIsReasonable()) {
return;
}
@ -541,6 +546,7 @@ void Workspace::switchToOutput(Output *output)
requestFocus(get_focus);
}
setActiveOutput(output);
#endif
}
void Workspace::gotFocusIn(const Window *window)

View file

@ -117,22 +117,26 @@ bool DBusInterface::stopActivity(const QString &in0)
int DBusInterface::currentDesktop()
{
return VirtualDesktopManager::self()->current();
// TODO: Maybe the DBus API needs to be changed? or maybe we should make a new one.
return VirtualDesktopManager::self()->current(Workspace::self()->activeOutput());
}
bool DBusInterface::setCurrentDesktop(int desktop)
{
return VirtualDesktopManager::self()->setCurrent(desktop);
// TODO: Maybe the DBus API needs to be changed? or maybe we should make a new one.
return VirtualDesktopManager::self()->setCurrent(desktop, Workspace::self()->activeOutput());
}
void DBusInterface::nextDesktop()
{
VirtualDesktopManager::self()->moveTo(VirtualDesktopManager::Direction::Next);
// TODO: Maybe the DBus API needs to be changed? or maybe we should make a new one.
VirtualDesktopManager::self()->moveTo(VirtualDesktopManager::Direction::Next, Workspace::self()->activeOutput());
}
void DBusInterface::previousDesktop()
{
VirtualDesktopManager::self()->moveTo(VirtualDesktopManager::Direction::Previous);
// TODO: Maybe the DBus API needs to be changed? or maybe we should make a new one.
VirtualDesktopManager::self()->moveTo(VirtualDesktopManager::Direction::Previous, Workspace::self()->activeOutput());
}
void DBusInterface::showDebugConsole()
@ -349,7 +353,8 @@ VirtualDesktopManagerDBusInterface::VirtualDesktopManagerDBusInterface(VirtualDe
this);
connect(m_manager, &VirtualDesktopManager::currentChanged, this, [this]() {
Q_EMIT currentChanged(m_manager->currentDesktop()->id());
// TODO: This event should handle different desktops being shown on different displays.
Q_EMIT currentChanged(m_manager->currentDesktop(Workspace::self()->activeOutput())->id());
});
connect(m_manager, &VirtualDesktopManager::countChanged, this, [this](uint previousCount, uint newCount) {
@ -419,19 +424,22 @@ uint VirtualDesktopManagerDBusInterface::rows() const
void VirtualDesktopManagerDBusInterface::setCurrent(const QString &id)
{
if (m_manager->currentDesktop()->id() == id) {
// TODO: Different desktops per output. API needs change.
if (m_manager->currentDesktop(Workspace::self()->activeOutput())->id() == id) {
return;
}
auto *vd = m_manager->desktopForId(id);
if (vd) {
m_manager->setCurrent(vd);
// TODO: Different desktops per output. API needs change.
m_manager->setCurrent(vd, Workspace::self()->activeOutput());
}
}
QString VirtualDesktopManagerDBusInterface::current() const
{
return m_manager->currentDesktop()->id();
// TODO: Different desktops per output. API needs change.
return m_manager->currentDesktop(Workspace::self()->activeOutput())->id();
}
void VirtualDesktopManagerDBusInterface::setNavigationWrappingAround(bool wraps)

View file

@ -150,7 +150,8 @@ EffectsHandler::EffectsHandler(Compositor *compositor, WorkspaceScene *scene)
}
});
connect(ws, &Workspace::currentDesktopChanged, this, [this](VirtualDesktop *old, Window *window) {
VirtualDesktop *newDesktop = VirtualDesktopManager::self()->currentDesktop();
// TODO: This should handle different desktops per output.
VirtualDesktop *newDesktop = VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput());
Q_EMIT desktopChanged(old, newDesktop, window ? window->effectWindow() : nullptr);
});
connect(ws, &Workspace::currentDesktopChanging, this, [this](VirtualDesktop *currentDesktop, QPointF offset, KWin::Window *window) {
@ -775,7 +776,8 @@ QString EffectsHandler::currentActivity() const
VirtualDesktop *EffectsHandler::currentDesktop() const
{
return VirtualDesktopManager::self()->currentDesktop();
// TODO: desktops & outputs. thing
return VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput());
}
QList<VirtualDesktop *> EffectsHandler::desktops() const
@ -785,7 +787,8 @@ QList<VirtualDesktop *> EffectsHandler::desktops() const
void EffectsHandler::setCurrentDesktop(VirtualDesktop *desktop)
{
VirtualDesktopManager::self()->setCurrent(desktop);
// TODO: desktops & outputs. thing
VirtualDesktopManager::self()->setCurrent(desktop, Workspace::self()->activeOutput());
}
QSize EffectsHandler::desktopGridSize() const
@ -833,24 +836,25 @@ QPoint EffectsHandler::desktopCoords(VirtualDesktop *desktop) const
return QPoint(coords.x() * displaySize.width(), coords.y() * displaySize.height());
}
// TODO: Handle per-output virtual desktops.
VirtualDesktop *EffectsHandler::desktopAbove(VirtualDesktop *desktop, bool wrap) const
{
return VirtualDesktopManager::self()->inDirection(desktop, VirtualDesktopManager::Direction::Up, wrap);
return VirtualDesktopManager::self()->inDirection(desktop, Workspace::self()->activeOutput(), VirtualDesktopManager::Direction::Up, wrap);
}
VirtualDesktop *EffectsHandler::desktopToRight(VirtualDesktop *desktop, bool wrap) const
{
return VirtualDesktopManager::self()->inDirection(desktop, VirtualDesktopManager::Direction::Right, wrap);
return VirtualDesktopManager::self()->inDirection(desktop, Workspace::self()->activeOutput(), VirtualDesktopManager::Direction::Right, wrap);
}
VirtualDesktop *EffectsHandler::desktopBelow(VirtualDesktop *desktop, bool wrap) const
{
return VirtualDesktopManager::self()->inDirection(desktop, VirtualDesktopManager::Direction::Down, wrap);
return VirtualDesktopManager::self()->inDirection(desktop, Workspace::self()->activeOutput(), VirtualDesktopManager::Direction::Down, wrap);
}
VirtualDesktop *EffectsHandler::desktopToLeft(VirtualDesktop *desktop, bool wrap) const
{
return VirtualDesktopManager::self()->inDirection(desktop, VirtualDesktopManager::Direction::Left, wrap);
return VirtualDesktopManager::self()->inDirection(desktop, Workspace::self()->activeOutput(), VirtualDesktopManager::Direction::Left, wrap);
}
QString EffectsHandler::desktopName(VirtualDesktop *desktop) const

View file

@ -149,7 +149,8 @@ quint32 getLayout(const T &layouts, const U &reference)
void VirtualDesktopPolicy::desktopChanged()
{
auto d = VirtualDesktopManager::self()->currentDesktop();
// TODO: Is it fine to only do it for the current output's desktop?
auto d = VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput());
if (!d) {
return;
}
@ -158,7 +159,8 @@ void VirtualDesktopPolicy::desktopChanged()
void VirtualDesktopPolicy::layoutChanged(uint index)
{
auto d = VirtualDesktopManager::self()->currentDesktop();
// TODO: Is it fine to only do it for the current output's desktop?
auto d = VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput());
if (!d) {
return;
}

View file

@ -288,8 +288,9 @@ void Workspace::raiseOrLowerWindow(Window *window)
return;
}
// TODO: Is it fine if we don't handle desktops on other outputs than the active one here?
const Window *topmost =
topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(),
topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()),
options->isSeparateScreenFocus() ? window->output() : nullptr);
if (window == topmost) {

View file

@ -144,7 +144,9 @@ void RootInfo::changeNumberOfDesktops(int n)
void RootInfo::changeCurrentDesktop(int d)
{
VirtualDesktopManager::self()->setCurrent(d);
for (auto *output : Workspace::self()->outputs()) {
VirtualDesktopManager::self()->setCurrent(d, output);
}
}
void RootInfo::changeActiveWindow(xcb_window_t w, NET::RequestSource src, xcb_timestamp_t timestamp, xcb_window_t active_window)

View file

@ -180,7 +180,8 @@ void Placement::placeSmart(Window *window, const QRectF &area, PlacementPolicy /
long int overlap, min_overlap = 0;
int x_optimal, y_optimal;
int possible;
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop() : window->desktops().front();
// TODO: Is it fine to take the current output's active desktop all the time?
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()) : window->desktops().front();
int cxl, cxr, cyt, cyb; // temp coords
int xl, xr, yt, yb; // temp coords
@ -381,7 +382,8 @@ void Placement::placeCascaded(Window *c, const QRect &area, PlacementPolicy next
// CT how do I get from the 'Client' class the size that NW squarish "handle"
const QPoint delta = workspace()->cascadeOffset(c);
VirtualDesktop *dn = c->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop() : c->desktops().constLast();
// TODO: desktops & outputs thing!!
VirtualDesktop *dn = c->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()) : c->desktops().constLast();
if (nextPlacement == PlacementUnknown) {
nextPlacement = PlacementSmart;
@ -589,7 +591,8 @@ void Placement::cascadeIfCovering(Window *window, const QRectF &area)
{
const QPoint offset = workspace()->cascadeOffset(window);
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop() : window->desktops().front();
// TODO: desktops & outputs
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()) : window->desktops().front();
QRectF possibleGeo = window->frameGeometry();
bool noOverlap = false;
@ -635,7 +638,8 @@ void Placement::cascadeIfCovering(Window *window, const QRectF &area)
void Placement::cascadeDesktop()
{
Workspace *ws = Workspace::self();
reinitCascading(VirtualDesktopManager::self()->currentDesktop());
// TODO: outputs & desktops
reinitCascading(VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()));
const auto stackingOrder = ws->stackingOrder();
for (Window *window : stackingOrder) {
if (!window->isClient() || (!window->isOnCurrentDesktop()) || (window->isMinimized()) || (window->isOnAllDesktops()) || (!window->isMovable())) {
@ -893,7 +897,8 @@ qreal Workspace::packPositionLeft(const Window *window, qreal oldX, bool leftEdg
if (oldX <= newX) {
return oldX;
}
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop() : window->desktops().front();
// TODO: desktop & outputs
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()) : window->desktops().front();
for (auto it = m_windows.constBegin(), end = m_windows.constEnd(); it != end; ++it) {
if (isIrrelevant(*it, window, desktop)) {
continue;
@ -920,7 +925,8 @@ qreal Workspace::packPositionRight(const Window *window, qreal oldX, bool rightE
if (oldX >= newX) {
return oldX;
}
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop() : window->desktops().front();
// TODO: desktop & outputs
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()) : window->desktops().front();
for (auto it = m_windows.constBegin(), end = m_windows.constEnd(); it != end; ++it) {
if (isIrrelevant(*it, window, desktop)) {
continue;
@ -948,7 +954,8 @@ qreal Workspace::packPositionUp(const Window *window, qreal oldY, bool topEdge)
if (oldY <= newY) {
return oldY;
}
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop() : window->desktops().front();
// TODO: desktop & outputs
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()) : window->desktops().front();
for (auto it = m_windows.constBegin(), end = m_windows.constEnd(); it != end; ++it) {
if (isIrrelevant(*it, window, desktop)) {
continue;
@ -975,7 +982,8 @@ qreal Workspace::packPositionDown(const Window *window, qreal oldY, bool bottomE
if (oldY >= newY) {
return oldY;
}
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop() : window->desktops().front();
// TODO: desktop & output
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()) : window->desktops().front();
for (auto it = m_windows.constBegin(), end = m_windows.constEnd(); it != end; ++it) {
if (isIrrelevant(*it, window, desktop)) {
continue;

View file

@ -172,7 +172,8 @@ RemoteMatches WindowsRunner::Match(const QString &searchTerm)
for (auto *desktop : VirtualDesktopManager::self()->desktops()) {
if (desktop->name().contains(term, Qt::CaseInsensitive)) {
if (!desktopAdded && desktop != VirtualDesktopManager::self()->currentDesktop()) {
// TODO: Fix the fix thing fixing thing
if (!desktopAdded && desktop != VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput())) {
matches << desktopMatch(desktop, ActivateDesktopAction, 0.8);
}
// search for windows on desktop and list them with less relevance
@ -203,7 +204,8 @@ void WindowsRunner::Run(const QString &id, const QString &actionId)
if (action == ActivateDesktopAction) {
QByteArray desktopId = objectId.toLocal8Bit();
auto desktop = VirtualDesktopManager::self()->desktopForId(desktopId);
VirtualDesktopManager::self()->setCurrent(desktop);
// TODO: Fix the output thing
VirtualDesktopManager::self()->setCurrent(desktop, Workspace::self()->activeOutput());
return;
}
@ -266,7 +268,7 @@ RemoteMatch WindowsRunner::windowsMatch(const Window *window, const WindowsRunne
const QList<VirtualDesktop *> desktops = window->desktops();
bool allDesktops = window->isOnAllDesktops();
const VirtualDesktop *targetDesktop = VirtualDesktopManager::self()->currentDesktop();
const VirtualDesktop *targetDesktop = VirtualDesktopManager::self()->currentDesktop(window->output());
// Show on current desktop unless window is only attached to other desktop, in this case show on the first attached desktop
if (!allDesktops && !window->isOnCurrentDesktop() && !desktops.isEmpty()) {
targetDesktop = desktops.first();

View file

@ -63,7 +63,8 @@ void ExpoArea::update()
}
const QRectF oldRect = m_rect;
m_rect = workspace()->clientArea(MaximizeArea, m_screen, VirtualDesktopManager::self()->currentDesktop());
// TODO: Fix this to handle per-output desktops!
m_rect = workspace()->clientArea(MaximizeArea, m_screen, VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()));
// Map the area to the output local coordinates.
m_rect.translate(-m_screen->geometry().topLeft());

View file

@ -488,31 +488,32 @@ void Edge::switchDesktop(const QPoint &cursorPos)
{
QPoint pos(cursorPos);
VirtualDesktopManager *vds = VirtualDesktopManager::self();
VirtualDesktop *oldDesktop = vds->currentDesktop();
// TODO: Desktop & output
VirtualDesktop *oldDesktop = vds->currentDesktop(Workspace::self()->activeOutput());
VirtualDesktop *desktop = oldDesktop;
const int OFFSET = 2;
if (isLeft()) {
const VirtualDesktop *interimDesktop = desktop;
desktop = vds->toLeft(desktop, vds->isNavigationWrappingAround());
desktop = vds->toLeft(desktop, nullptr, vds->isNavigationWrappingAround());
if (desktop != interimDesktop) {
pos.setX(workspace()->geometry().width() - 1 - OFFSET);
}
} else if (isRight()) {
const VirtualDesktop *interimDesktop = desktop;
desktop = vds->toRight(desktop, vds->isNavigationWrappingAround());
desktop = vds->toRight(desktop, nullptr, vds->isNavigationWrappingAround());
if (desktop != interimDesktop) {
pos.setX(OFFSET);
}
}
if (isTop()) {
const VirtualDesktop *interimDesktop = desktop;
desktop = vds->above(desktop, vds->isNavigationWrappingAround());
desktop = vds->above(desktop, nullptr, vds->isNavigationWrappingAround());
if (desktop != interimDesktop) {
pos.setY(workspace()->geometry().height() - 1 - OFFSET);
}
} else if (isBottom()) {
const VirtualDesktop *interimDesktop = desktop;
desktop = vds->below(desktop, vds->isNavigationWrappingAround());
desktop = vds->below(desktop, nullptr, vds->isNavigationWrappingAround());
if (desktop != interimDesktop) {
pos.setY(OFFSET);
}
@ -524,8 +525,9 @@ void Edge::switchDesktop(const QPoint &cursorPos)
return;
}
}
vds->setCurrent(desktop);
if (vds->currentDesktop() != oldDesktop) {
// TODO: Desktops & outputs
vds->setCurrent(desktop, Workspace::self()->activeOutput());
if (vds->currentDesktop(Workspace::self()->activeOutput()) != oldDesktop) {
m_pushBackBlocked = true;
Cursors::self()->mouse()->setPos(pos);
auto unblockPush = [this] {

View file

@ -95,7 +95,8 @@ void DesktopBackgroundItem::updateWindow()
VirtualDesktop *desktop = m_desktop;
if (!desktop) {
desktop = VirtualDesktopManager::self()->currentDesktop();
// TODO: Desktop & outputs
desktop = VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput());
}
QString activity = m_activity;

View file

@ -60,7 +60,8 @@ WorkspaceWrapper::WorkspaceWrapper(QObject *parent)
VirtualDesktop *WorkspaceWrapper::currentDesktop() const
{
return VirtualDesktopManager::self()->currentDesktop();
// TODO: Desktops & outputs
return VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput());
}
QList<VirtualDesktop *> WorkspaceWrapper::desktops() const
@ -70,7 +71,8 @@ QList<VirtualDesktop *> WorkspaceWrapper::desktops() const
void WorkspaceWrapper::setCurrentDesktop(VirtualDesktop *desktop)
{
VirtualDesktopManager::self()->setCurrent(desktop);
// TODO: Desktops & outputs
VirtualDesktopManager::self()->setCurrent(desktop, Workspace::self()->activeOutput());
}
Window *WorkspaceWrapper::activeWindow() const
@ -208,10 +210,11 @@ SLOTWRAPPER(slotSwitchWindowLeft, DirectionWest)
#undef SLOTWRAPPER
#define SLOTWRAPPER(name, direction) \
void WorkspaceWrapper::name() \
{ \
VirtualDesktopManager::self()->moveTo(VirtualDesktopManager::Direction::direction, options->isRollOverDesktops()); \
// TODO: How to handle per-output virtual desktops.
#define SLOTWRAPPER(name, direction) \
void WorkspaceWrapper::name() \
{ \
VirtualDesktopManager::self()->moveTo(VirtualDesktopManager::Direction::direction, nullptr, options->isRollOverDesktops()); \
}
SLOTWRAPPER(slotSwitchDesktopNext, Next)

View file

@ -132,7 +132,8 @@ void SessionManager::storeSession(const QString &sessionName, SMSavePhase phase)
// but both Qt and KDE treat phase1 and phase2 separately,
// which results in different sessionkey and different config file :(
m_sessionActiveClient = active_client;
m_sessionDesktop = VirtualDesktopManager::self()->current();
// TODO: Desktops & outputs, if it matters
m_sessionDesktop = VirtualDesktopManager::self()->current(Workspace::self()->activeOutput());
} else if (phase == SMSavePhase2) {
cg.writeEntry("count", count);
cg.writeEntry("active", m_sessionActiveClient);
@ -140,7 +141,8 @@ void SessionManager::storeSession(const QString &sessionName, SMSavePhase phase)
} else { // SMSavePhase2Full
cg.writeEntry("count", count);
cg.writeEntry("active", m_sessionActiveClient);
cg.writeEntry("desktop", VirtualDesktopManager::self()->current());
// TODO: Desktops & outputs, if it matters
cg.writeEntry("desktop", VirtualDesktopManager::self()->current(Workspace::self()->activeOutput()));
}
config->sync(); // it previously did some "revert to defaults" stuff for phase1 I think
}

View file

@ -80,7 +80,8 @@ QString TabBoxHandlerImpl::desktopName(Window *client) const
if (!client->isOnAllDesktops()) {
return client->desktops().last()->name();
}
return VirtualDesktopManager::self()->currentDesktop()->name();
// TODO: Handle per-output desktops
return VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput())->name();
}
Window *TabBoxHandlerImpl::nextClientFocusChain(Window *client) const
@ -953,7 +954,7 @@ void TabBox::CDEWalkThroughWindows(bool forward)
shadeActivate(nc);
} else {
if (!nc->isOnCurrentDesktop()) {
VirtualDesktopManager::self()->setCurrent(nc->desktops().constLast());
VirtualDesktopManager::self()->setCurrent(nc->desktops().constLast(), nc->output());
}
Workspace::self()->raiseWindow(nc);
}

View file

@ -150,13 +150,15 @@ QRectF Tile::windowGeometry() const
effectiveMargins.setBottom(m_relativeGeometry.bottom() < 1.0 ? m_padding / 2.0 : m_padding);
const auto geom = absoluteGeometry();
return geom.intersected(workspace()->clientArea(MaximizeArea, m_tiling->output(), VirtualDesktopManager::self()->currentDesktop())) - effectiveMargins;
// TODO: Handle desktop being per-output if it matters here?
return geom.intersected(workspace()->clientArea(MaximizeArea, m_tiling->output(), VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput()))) - effectiveMargins;
}
QRectF Tile::maximizedWindowGeometry() const
{
const auto geom = absoluteGeometry();
return geom.intersected(workspace()->clientArea(MaximizeArea, m_tiling->output(), VirtualDesktopManager::self()->currentDesktop()));
// TODO: Handle desktop being per-output if it matters here?
return geom.intersected(workspace()->clientArea(MaximizeArea, m_tiling->output(), VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput())));
}
bool Tile::isLayout() const

View file

@ -475,13 +475,15 @@ void UserActionsMenu::desktopPopupAboutToShow()
QActionGroup *group = new QActionGroup(m_desktopMenu);
QAction *action = m_desktopMenu->addAction(i18n("Move &To Current Desktop"));
action->setEnabled(m_window && (m_window->isOnAllDesktops() || !m_window->isOnDesktop(vds->currentDesktop())));
// TODO: Handle per-output desktops.
action->setEnabled(m_window && (m_window->isOnAllDesktops() || !m_window->isOnDesktop(vds->currentDesktop(Workspace::self()->activeOutput()))));
connect(action, &QAction::triggered, this, [this]() {
if (!m_window) {
return;
}
VirtualDesktopManager *vds = VirtualDesktopManager::self();
workspace()->sendWindowToDesktops(m_window, {vds->currentDesktop()}, false);
// TODO: Handle per-output desktops.
workspace()->sendWindowToDesktops(m_window, {vds->currentDesktop(Workspace::self()->activeOutput())}, false);
});
action = m_desktopMenu->addAction(i18n("&All Desktops"));
@ -1416,7 +1418,8 @@ void Workspace::slotWindowLower()
requestFocus(next, false);
}
} else {
activateWindow(topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop()));
// TODO: Handle per-output desktops, if needs be!
activateWindow(topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput())));
}
}
}
@ -1486,11 +1489,13 @@ void windowToDesktop(Window *window, VirtualDesktopManager::Direction direction)
VirtualDesktopManager *vds = VirtualDesktopManager::self();
Workspace *ws = Workspace::self();
// TODO: why is options->isRollOverDesktops() not honored?
const auto desktop = vds->inDirection(nullptr, direction, true);
// TODO: Handle per-output desktops
const auto desktop = vds->inDirection(nullptr, nullptr, direction, true);
if (window && !window->isDesktop()
&& !window->isDock()) {
ws->setMoveResizeWindow(window);
vds->setCurrent(desktop);
// TODO: Handle per-output desktops
vds->setCurrent(desktop, Workspace::self()->activeOutput());
ws->setMoveResizeWindow(nullptr);
}
}
@ -1529,13 +1534,15 @@ void activeWindowToDesktop(VirtualDesktopManager::Direction direction)
{
VirtualDesktopManager *vds = VirtualDesktopManager::self();
Workspace *ws = Workspace::self();
VirtualDesktop *current = vds->currentDesktop();
VirtualDesktop *newCurrent = VirtualDesktopManager::self()->inDirection(current, direction, options->isRollOverDesktops());
// TODO: Handle per-output desktops.
VirtualDesktop *current = vds->currentDesktop(Workspace::self()->activeOutput());
VirtualDesktop *newCurrent = VirtualDesktopManager::self()->inDirection(current, nullptr, direction, options->isRollOverDesktops());
if (newCurrent == current) {
return;
}
ws->setMoveResizeWindow(ws->activeWindow());
vds->setCurrent(newCurrent);
// TODO: Handle per-output desktops.
vds->setCurrent(newCurrent, Workspace::self()->activeOutput());
ws->setMoveResizeWindow(nullptr);
}
@ -1587,7 +1594,8 @@ void Workspace::switchWindow(Direction direction)
return;
}
Window *window = m_activeWindow;
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
// TODO: Is it fine to only care about the window's current output's desktop?
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop(window->output());
// Center of the active window
QPoint curPos(window->x() + window->width() / 2, window->y() + window->height() / 2);

View file

@ -10,6 +10,7 @@
#include "virtualdesktops.h"
#include "input.h"
#include "wayland/plasmavirtualdesktop.h"
#include "workspace.h"
// KDE
#include <KConfigGroup>
#include <KGlobalAccel>
@ -61,7 +62,8 @@ void VirtualDesktopManager::setVirtualDesktopManagement(PlasmaVirtualDesktopMana
pvd->sendDone();
});
connect(pvd, &PlasmaVirtualDesktopInterface::activateRequested, this, [this, desktop]() {
setCurrent(desktop);
// TODO: Should a new API be made to activate a desktop on a specified output?
setCurrent(desktop, Workspace::self()->activeOutput());
});
};
@ -90,9 +92,10 @@ void VirtualDesktopManager::setVirtualDesktopManagement(PlasmaVirtualDesktopMana
});
connect(this, &VirtualDesktopManager::currentChanged, m_virtualDesktopManagement, [this]() {
// TODO: Handle per-output desktops properly
const QList<PlasmaVirtualDesktopInterface *> deskIfaces = m_virtualDesktopManagement->desktops();
for (auto *deskInt : deskIfaces) {
if (deskInt->id() == currentDesktop()->id()) {
if (deskInt->id() == currentDesktop(Workspace::self()->activeOutput())->id()) {
deskInt->setActive(true);
} else {
deskInt->setActive(false);
@ -219,7 +222,8 @@ void VirtualDesktopManager::setRootInfo(NETRootInfo *info)
// Nothing will be connected to rootInfo
if (m_rootInfo) {
updateRootInfo();
m_rootInfo->setCurrentDesktop(currentDesktop()->x11DesktopNumber());
// TODO: Per-output desktops: do we need to do a better handling of it? X11 doesn't support per-output desktops anyways
m_rootInfo->setCurrentDesktop(currentDesktop(Workspace::self()->activeOutput())->x11DesktopNumber());
for (auto *vd : std::as_const(m_desktops)) {
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
}
@ -227,40 +231,44 @@ void VirtualDesktopManager::setRootInfo(NETRootInfo *info)
#endif
}
VirtualDesktop *VirtualDesktopManager::inDirection(VirtualDesktop *desktop, Direction direction, bool wrap)
VirtualDesktop *VirtualDesktopManager::inDirection(VirtualDesktop *desktop, Output *output, Direction direction, bool wrap)
{
switch (direction) {
case Direction::Up:
return above(desktop, wrap);
return above(desktop, output, wrap);
case Direction::Down:
return below(desktop, wrap);
return below(desktop, output, wrap);
case Direction::Right:
return toRight(desktop, wrap);
return toRight(desktop, output, wrap);
case Direction::Left:
return toLeft(desktop, wrap);
return toLeft(desktop, output, wrap);
case Direction::Next:
return next(desktop, wrap);
return next(desktop, output, wrap);
case Direction::Previous:
return previous(desktop, wrap);
return previous(desktop, output, wrap);
}
Q_UNREACHABLE();
}
uint VirtualDesktopManager::inDirection(uint desktop, Direction direction, bool wrap)
uint VirtualDesktopManager::inDirection(uint desktop, Output *output, Direction direction, bool wrap)
{
return inDirection(desktopForX11Id(desktop), direction, wrap)->x11DesktopNumber();
return inDirection(desktopForX11Id(desktop), output, direction, wrap)->x11DesktopNumber();
}
void VirtualDesktopManager::moveTo(Direction direction, bool wrap)
void VirtualDesktopManager::moveTo(Direction direction, Output *output, bool wrap)
{
setCurrent(inDirection(nullptr, direction, wrap));
setCurrent(inDirection(nullptr, output, direction, wrap), output);
}
VirtualDesktop *VirtualDesktopManager::above(VirtualDesktop *desktop, bool wrap) const
VirtualDesktop *VirtualDesktopManager::above(VirtualDesktop *desktop, Output *output, bool wrap) const
{
Q_ASSERT(m_current);
if (!output) {
output = Workspace::self()->activeOutput();
}
Q_ASSERT(m_current[output]);
if (!desktop) {
desktop = m_current;
desktop = m_current[output];
}
QPoint coords = m_grid.gridCoords(desktop);
Q_ASSERT(coords.x() >= 0);
@ -280,11 +288,15 @@ VirtualDesktop *VirtualDesktopManager::above(VirtualDesktop *desktop, bool wrap)
return nullptr;
}
VirtualDesktop *VirtualDesktopManager::toRight(VirtualDesktop *desktop, bool wrap) const
VirtualDesktop *VirtualDesktopManager::toRight(VirtualDesktop *desktop, Output *output, bool wrap) const
{
Q_ASSERT(m_current);
if (!output) {
output = Workspace::self()->activeOutput();
}
Q_ASSERT(m_current[output]);
if (!desktop) {
desktop = m_current;
desktop = m_current[output];
}
QPoint coords = m_grid.gridCoords(desktop);
Q_ASSERT(coords.x() >= 0);
@ -304,11 +316,15 @@ VirtualDesktop *VirtualDesktopManager::toRight(VirtualDesktop *desktop, bool wra
return nullptr;
}
VirtualDesktop *VirtualDesktopManager::below(VirtualDesktop *desktop, bool wrap) const
VirtualDesktop *VirtualDesktopManager::below(VirtualDesktop *desktop, Output *output, bool wrap) const
{
Q_ASSERT(m_current);
if (!output) {
output = Workspace::self()->activeOutput();
}
Q_ASSERT(m_current[output]);
if (!desktop) {
desktop = m_current;
desktop = m_current[output];
}
QPoint coords = m_grid.gridCoords(desktop);
Q_ASSERT(coords.x() >= 0);
@ -329,11 +345,15 @@ VirtualDesktop *VirtualDesktopManager::below(VirtualDesktop *desktop, bool wrap)
return nullptr;
}
VirtualDesktop *VirtualDesktopManager::toLeft(VirtualDesktop *desktop, bool wrap) const
VirtualDesktop *VirtualDesktopManager::toLeft(VirtualDesktop *desktop, Output *output, bool wrap) const
{
Q_ASSERT(m_current);
if (!output) {
output = Workspace::self()->activeOutput();
}
Q_ASSERT(m_current[output]);
if (!desktop) {
desktop = m_current;
desktop = m_current[output];
}
QPoint coords = m_grid.gridCoords(desktop);
Q_ASSERT(coords.x() >= 0);
@ -353,11 +373,15 @@ VirtualDesktop *VirtualDesktopManager::toLeft(VirtualDesktop *desktop, bool wrap
return nullptr;
}
VirtualDesktop *VirtualDesktopManager::next(VirtualDesktop *desktop, bool wrap) const
VirtualDesktop *VirtualDesktopManager::next(VirtualDesktop *desktop, Output *output, bool wrap) const
{
Q_ASSERT(m_current);
if (!output) {
output = Workspace::self()->activeOutput();
}
Q_ASSERT(m_current[output]);
if (!desktop) {
desktop = m_current;
desktop = m_current[output];
}
auto it = std::find(m_desktops.begin(), m_desktops.end(), desktop);
Q_ASSERT(it != m_desktops.end());
@ -372,11 +396,15 @@ VirtualDesktop *VirtualDesktopManager::next(VirtualDesktop *desktop, bool wrap)
return *it;
}
VirtualDesktop *VirtualDesktopManager::previous(VirtualDesktop *desktop, bool wrap) const
VirtualDesktop *VirtualDesktopManager::previous(VirtualDesktop *desktop, Output *output, bool wrap) const
{
Q_ASSERT(m_current);
if (!output) {
output = Workspace::self()->activeOutput();
}
Q_ASSERT(m_current[output]);
if (!desktop) {
desktop = m_current;
desktop = m_current[output];
}
auto it = std::find(m_desktops.begin(), m_desktops.end(), desktop);
Q_ASSERT(it != m_desktops.end());
@ -494,9 +522,11 @@ void VirtualDesktopManager::removeVirtualDesktop(VirtualDesktop *desktop)
#endif
}
if (m_current == desktop) {
m_current = (i < m_desktops.count()) ? m_desktops.at(i) : m_desktops.constLast();
Q_EMIT currentChanged(desktop, m_current);
for (auto [output, current] : m_current.asKeyValueRange()) {
if (current == desktop) {
m_current[output] = (i < m_desktops.count()) ? m_desktops.at(i) : m_desktops.constLast();
Q_EMIT currentChanged(desktop, current, output);
}
}
updateLayout();
@ -509,35 +539,35 @@ void VirtualDesktopManager::removeVirtualDesktop(VirtualDesktop *desktop)
desktop->deleteLater();
}
uint VirtualDesktopManager::current() const
uint VirtualDesktopManager::current(Output *output) const
{
return m_current ? m_current->x11DesktopNumber() : 0;
return m_current[output] ? m_current[output]->x11DesktopNumber() : 0;
}
VirtualDesktop *VirtualDesktopManager::currentDesktop() const
VirtualDesktop *VirtualDesktopManager::currentDesktop(Output *output) const
{
return m_current;
return m_current[output];
}
bool VirtualDesktopManager::setCurrent(uint newDesktop)
bool VirtualDesktopManager::setCurrent(uint newDesktop, Output *output)
{
if (newDesktop < 1 || newDesktop > count()) {
return false;
}
auto d = desktopForX11Id(newDesktop);
Q_ASSERT(d);
return setCurrent(d);
return setCurrent(d, output);
}
bool VirtualDesktopManager::setCurrent(VirtualDesktop *newDesktop)
bool VirtualDesktopManager::setCurrent(VirtualDesktop *newDesktop, Output *output)
{
Q_ASSERT(newDesktop);
if (m_current == newDesktop) {
if (m_current[output] == newDesktop) {
return false;
}
VirtualDesktop *oldDesktop = currentDesktop();
m_current = newDesktop;
Q_EMIT currentChanged(oldDesktop, newDesktop);
VirtualDesktop *oldDesktop = currentDesktop(output);
m_current[output] = newDesktop;
Q_EMIT currentChanged(oldDesktop, newDesktop, output);
return true;
}
@ -554,10 +584,13 @@ void VirtualDesktopManager::setCount(uint count)
if ((uint)m_desktops.count() > count) {
const auto desktopsToRemove = m_desktops.mid(count);
m_desktops.resize(count);
if (m_current && desktopsToRemove.contains(m_current)) {
VirtualDesktop *oldCurrent = m_current;
m_current = m_desktops.last();
Q_EMIT currentChanged(oldCurrent, m_current);
for (auto [output, current] : m_current.asKeyValueRange()) {
if (current && desktopsToRemove.contains(current)) {
VirtualDesktop *oldCurrent = current;
auto newCurrent = m_desktops.last();
m_current[output] = newCurrent;
Q_EMIT currentChanged(oldCurrent, newCurrent, output);
}
}
for (auto desktop : desktopsToRemove) {
Q_EMIT desktopRemoved(desktop);
@ -587,8 +620,10 @@ void VirtualDesktopManager::setCount(uint count)
}
}
if (!m_current) {
m_current = m_desktops.at(0);
for (auto [output, current] : m_current.asKeyValueRange()) {
if (!current) {
m_current[output] = m_desktops.at(0);
}
}
updateLayout();
@ -760,13 +795,15 @@ void VirtualDesktopManager::initShortcuts()
const auto left = [this](qreal cb) {
if (grid().width() > 1) {
m_currentDesktopOffset.setX(cb);
Q_EMIT currentChanging(currentDesktop(), m_currentDesktopOffset);
// TODO: Per-output desktop.
Q_EMIT currentChanging(currentDesktop(Workspace::self()->activeOutput()), m_currentDesktopOffset);
}
};
const auto right = [this](qreal cb) {
if (grid().width() > 1) {
m_currentDesktopOffset.setX(-cb);
Q_EMIT currentChanging(currentDesktop(), m_currentDesktopOffset);
// TODO: Per-output desktop.
Q_EMIT currentChanging(currentDesktop(Workspace::self()->activeOutput()), m_currentDesktopOffset);
}
};
input()->registerTouchpadSwipeShortcut(SwipeDirection::Left, 3, m_swipeGestureReleasedX.get(), left);
@ -776,13 +813,15 @@ void VirtualDesktopManager::initShortcuts()
input()->registerTouchpadSwipeShortcut(SwipeDirection::Down, 3, m_swipeGestureReleasedY.get(), [this](qreal cb) {
if (grid().height() > 1) {
m_currentDesktopOffset.setY(-cb);
Q_EMIT currentChanging(currentDesktop(), m_currentDesktopOffset);
// TODO: Per-output desktop.
Q_EMIT currentChanging(currentDesktop(Workspace::self()->activeOutput()), m_currentDesktopOffset);
}
});
input()->registerTouchpadSwipeShortcut(SwipeDirection::Up, 3, m_swipeGestureReleasedY.get(), [this](qreal cb) {
if (grid().height() > 1) {
m_currentDesktopOffset.setY(cb);
Q_EMIT currentChanging(currentDesktop(), m_currentDesktopOffset);
// TODO: Per-output desktop.
Q_EMIT currentChanging(currentDesktop(Workspace::self()->activeOutput()), m_currentDesktopOffset);
}
});
input()->registerTouchscreenSwipeShortcut(SwipeDirection::Left, 3, m_swipeGestureReleasedX.get(), left);
@ -797,18 +836,21 @@ void VirtualDesktopManager::initShortcuts()
void VirtualDesktopManager::gestureReleasedY()
{
// TODO: Handle per-output desktops properly
Output *output = Workspace::self()->activeOutput();
// Note that if desktop wrapping is disabled and there's no desktop above or below,
// above() and below() will return the current desktop.
VirtualDesktop *target = m_current;
VirtualDesktop *target = m_current[output];
if (m_currentDesktopOffset.y() <= -GESTURE_SWITCH_THRESHOLD) {
target = above(m_current, isNavigationWrappingAround());
target = above(m_current[output], output, isNavigationWrappingAround());
} else if (m_currentDesktopOffset.y() >= GESTURE_SWITCH_THRESHOLD) {
target = below(m_current, isNavigationWrappingAround());
target = below(m_current[output], output, isNavigationWrappingAround());
}
// If the current desktop has not changed, consider that the gesture has been canceled.
if (m_current != target) {
setCurrent(target);
if (m_current[output] != target) {
setCurrent(target, output);
} else {
Q_EMIT currentChangingCancelled();
}
@ -817,18 +859,21 @@ void VirtualDesktopManager::gestureReleasedY()
void VirtualDesktopManager::gestureReleasedX()
{
// TODO: Handle per-output desktops properly
Output *output = Workspace::self()->activeOutput();
// Note that if desktop wrapping is disabled and there's no desktop to left or right,
// toLeft() and toRight() will return the current desktop.
VirtualDesktop *target = m_current;
VirtualDesktop *target = m_current[output];
if (m_currentDesktopOffset.x() <= -GESTURE_SWITCH_THRESHOLD) {
target = toLeft(m_current, isNavigationWrappingAround());
target = toLeft(m_current[output], nullptr, isNavigationWrappingAround());
} else if (m_currentDesktopOffset.x() >= GESTURE_SWITCH_THRESHOLD) {
target = toRight(m_current, isNavigationWrappingAround());
target = toRight(m_current[output], nullptr, isNavigationWrappingAround());
}
// If the current desktop has not changed, consider that the gesture has been canceled.
if (m_current != target) {
setCurrent(target);
if (m_current[output] != target) {
setCurrent(target, output);
} else {
Q_EMIT currentChangingCancelled();
}
@ -883,7 +928,8 @@ void VirtualDesktopManager::slotSwitchTo()
if (!ok) {
return;
}
setCurrent(i);
// TODO: Is this fine?
setCurrent(i, Workspace::self()->activeOutput());
}
void VirtualDesktopManager::setNavigationWrappingAround(bool enabled)
@ -897,32 +943,32 @@ void VirtualDesktopManager::setNavigationWrappingAround(bool enabled)
void VirtualDesktopManager::slotDown()
{
moveTo(Direction::Down, isNavigationWrappingAround());
moveTo(Direction::Down, Workspace::self()->activeOutput(), isNavigationWrappingAround());
}
void VirtualDesktopManager::slotLeft()
{
moveTo(Direction::Left, isNavigationWrappingAround());
moveTo(Direction::Left, Workspace::self()->activeOutput(), isNavigationWrappingAround());
}
void VirtualDesktopManager::slotPrevious()
{
moveTo(Direction::Previous, isNavigationWrappingAround());
moveTo(Direction::Previous, Workspace::self()->activeOutput(), isNavigationWrappingAround());
}
void VirtualDesktopManager::slotNext()
{
moveTo(Direction::Next, isNavigationWrappingAround());
moveTo(Direction::Next, Workspace::self()->activeOutput(), isNavigationWrappingAround());
}
void VirtualDesktopManager::slotRight()
{
moveTo(Direction::Right, isNavigationWrappingAround());
moveTo(Direction::Right, Workspace::self()->activeOutput(), isNavigationWrappingAround());
}
void VirtualDesktopManager::slotUp()
{
moveTo(Direction::Up, isNavigationWrappingAround());
moveTo(Direction::Up, Workspace::self()->activeOutput(), isNavigationWrappingAround());
}
} // KWin

View file

@ -30,6 +30,7 @@ namespace KWin
class Options;
class PlasmaVirtualDesktopManagementInterface;
class Output;
class KWIN_EXPORT VirtualDesktop : public QObject
{
@ -145,7 +146,7 @@ class KWIN_EXPORT VirtualDesktopManager : public QObject
/**
* The id of the virtual desktop which is currently in use.
*/
Q_PROPERTY(uint current READ current WRITE setCurrent NOTIFY currentChanged)
// Q_PROPERTY(uint current READ current WRITE setCurrent NOTIFY currentChanged)
/**
* Whether navigation in the desktop layout wraps around at the borders.
@ -188,14 +189,14 @@ public:
* @see setCurrent
* @see currentChanged
*/
uint current() const;
uint current(Output *output) const;
/**
* @returns The current desktop
* @returns The current desktop on the specified output.
* @see setCurrent
* @see currentChanged
*/
VirtualDesktop *currentDesktop() const;
VirtualDesktop *currentDesktop(Output *output) const;
/**
* Moves to the desktop through the algorithm described by Direction.
@ -203,7 +204,7 @@ public:
* @see setCurrent
*/
template<typename Direction>
void moveTo(bool wrap = false);
void moveTo(Output *output, bool wrap = false);
/**
* @returns @c true if navigation at borders of layout wraps around, @c false otherwise
@ -225,45 +226,56 @@ public:
Next,
Previous
};
VirtualDesktop *inDirection(VirtualDesktop *desktop, Direction direction, bool wrap = true);
uint inDirection(uint desktop, Direction direction, bool wrap = true);
void moveTo(Direction direction, bool wrap = true);
VirtualDesktop *inDirection(VirtualDesktop *desktop, Output *output, Direction direction, bool wrap = true);
uint inDirection(uint desktop, Output *output, Direction direction, bool wrap = true);
void moveTo(Direction direction, Output *output, bool wrap = true);
/**
* @returns The desktop above desktop @a desktop. Wraps around to the bottom of
* the layout if @a wrap is set. If @a desktop is @c null use the current one.
* @returns The desktop above desktop @a desktop on the output @a
* output. Wraps around to the bottom of the layout if @a wrap is set. If @a
* desktop is @c null use the current one. If @a output is @c null, use the
* active one.
*/
VirtualDesktop *above(VirtualDesktop *desktop, bool wrap = true) const;
VirtualDesktop *above(VirtualDesktop *desktop, Output *output, bool wrap = true) const;
/**
* @returns The desktop to the right of desktop @a desktop. Wraps around to the
* left of the layout if @a wrap is set. If @a desktop is @c null use the current one.
* @returns The desktop to the right of desktop @a desktop on the output @a output.
* Wraps around to the left of the layout if @a wrap is set. If @a desktop is
* @c null use the current one. If @a output is @c null, use the active one.
*/
VirtualDesktop *toRight(VirtualDesktop *desktop, bool wrap = true) const;
VirtualDesktop *toRight(VirtualDesktop *desktop, Output *output, bool wrap = true) const;
/**
* @returns The desktop below desktop @a desktop. Wraps around to the top of the
* layout if @a wrap is set. If @a desktop is @c null use the current one.
* @returns The desktop below desktop @a desktop on the output @a
* output. Wraps around to the top of the layout if @a wrap is set. If @a
* desktop is @c null use the current one. If @a output is @c null, use the
* active one.
*/
VirtualDesktop *below(VirtualDesktop *desktop, bool wrap = true) const;
VirtualDesktop *below(VirtualDesktop *desktop, Output *output, bool wrap = true) const;
/**
* @returns The desktop to the left of desktop @a desktop. Wraps around to the
* right of the layout if @a wrap is set. If @a desktop is @c null use the current one.
* @returns The desktop to the left of desktop @a desktop on the output @a
* output. Wraps around to the right of the layout if @a wrap is set. If @a
* desktop is @c null use the current one. If @a output is @c null, use the
* active one.
*/
VirtualDesktop *toLeft(VirtualDesktop *desktop, bool wrap = true) const;
VirtualDesktop *toLeft(VirtualDesktop *desktop, Output *output, bool wrap = true) const;
/**
* @returns The desktop after the desktop @a desktop. Wraps around to the first
* desktop if @a wrap is set. If @a desktop is @c null use the current desktop.
* @returns The desktop after the desktop @a desktop on the output @a
* output. Wraps around to the first desktop if @a wrap is set. If @a
* desktop is @c null use the current desktop. If @a output is @c null, use
* the active one.
*/
VirtualDesktop *next(VirtualDesktop *desktop = nullptr, bool wrap = true) const;
VirtualDesktop *next(VirtualDesktop *desktop = nullptr, Output *output = nullptr, bool wrap = true) const;
/**
* @returns The desktop in front of the desktop @a desktop. Wraps around to the
* last desktop if @a wrap is set. If @a desktop is @c null use the current desktop.
* @returns The desktop in front of the desktop @a desktop on the output @a
* output. Wraps around to the last desktop if @a wrap is set. If @a desktop
* is @c null use the current desktop. If @a output is @c null, use the
* active one.
*/
VirtualDesktop *previous(VirtualDesktop *desktop = nullptr, bool wrap = true) const;
VirtualDesktop *previous(VirtualDesktop *desktop = nullptr, Output *output = nullptr, bool wrap = true) const;
void initShortcuts();
@ -341,16 +353,16 @@ public Q_SLOTS:
* @see currentChanged
* @see moveTo
*/
bool setCurrent(uint current);
bool setCurrent(uint current, Output *output);
/**
* Set the current desktop to @a current.
* Set the current desktop show on the specified output to @a current.
* @returns True on success, false otherwise.
* @see current
* @see currentChanged
* @see moveTo
*/
bool setCurrent(VirtualDesktop *current);
bool setCurrent(VirtualDesktop *current, Output *output);
/**
* Updates the layout to a new number of rows. The number of columns will be calculated accordingly
@ -412,7 +424,7 @@ Q_SIGNALS:
* @param previousDesktop The virtual desktop changed from
* @param newDesktop The virtual desktop changed to
*/
void currentChanged(KWin::VirtualDesktop *previousDesktop, KWin::VirtualDesktop *newDesktop);
void currentChanged(KWin::VirtualDesktop *previousDesktop, KWin::VirtualDesktop *newDesktop, Output *releventOutput);
/**
* Signal emmitted for realtime desktop switching animations.
@ -514,7 +526,7 @@ private:
QAction *addAction(const QString &name, const QString &label, const QKeySequence &key, void (VirtualDesktopManager::*slot)());
QList<VirtualDesktop *> m_desktops;
QPointer<VirtualDesktop> m_current;
QMap<Output *, QPointer<VirtualDesktop>> m_current;
quint32 m_rows = 2;
bool m_navigationWrapsAround;
VirtualDesktopGrid m_grid;

View file

@ -142,6 +142,7 @@ void PlasmaWindowManagementInterfacePrivate::sendShowingDesktopState(wl_resource
uint32_t s = 0;
switch (state) {
case PlasmaWindowManagementInterface::ShowingDesktopState::Enabled:
qInfo("Hi there :)");
s = QtWaylandServer::org_kde_plasma_window_management::show_desktop_enabled;
break;
case PlasmaWindowManagementInterface::ShowingDesktopState::Disabled:

View file

@ -680,7 +680,8 @@ void Window::autoRaise()
bool Window::isMostRecentlyRaised() const
{
// The last window in the unconstrained stacking order is the most recently raised one.
return workspace()->topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(), nullptr, true, false) == this;
// TODO: Does this need to change for per-output desktops?
return workspace()->topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(m_output), nullptr, true, false) == this;
}
bool Window::wantsTabFocus() const
@ -807,7 +808,7 @@ void Window::setOnAllDesktops(bool b)
if (b) {
setDesktops({});
} else {
setDesktops({VirtualDesktopManager::self()->currentDesktop()});
setDesktops({VirtualDesktopManager::self()->currentDesktop(m_output)});
}
}
@ -831,12 +832,13 @@ QStringList Window::desktopIds() const
bool Window::isOnDesktop(VirtualDesktop *desktop) const
{
return isOnAllDesktops() || desktops().contains(desktop);
qInfo("Window %p testing if on desktop %p", this, desktop);
qInfo("Desktop 0 is %p", desktops()[0]) return isOnAllDesktops() || desktops().contains(desktop);
}
bool Window::isOnCurrentDesktop() const
{
return isOnDesktop(VirtualDesktopManager::self()->currentDesktop());
return isOnDesktop(VirtualDesktopManager::self()->currentDesktop(m_output));
}
ShadeMode Window::shadeMode() const
@ -1524,7 +1526,8 @@ QRectF Window::nextInteractiveResizeGeometry(const QPointF &global) const
// 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
const StrutRects strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop());
// TODO: Per-output desktops: is it fine to just take the window's output's desktop? Maybe the output information should be propagated.
const StrutRects strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop(m_output));
QRegion availableArea(workspace()->clientArea(FullArea, this, workspace()->activeOutput()).toRect());
for (const QRect &rect : strut) {
availableArea -= rect;
@ -1650,7 +1653,8 @@ QRectF Window::nextInteractiveMoveGeometry(const QPointF &global) const
nextMoveResizeGeom.moveTopLeft(workspace()->adjustWindowPosition(this, nextMoveResizeGeom.topLeft(), isUnrestrictedInteractiveMoveResize()));
if (!isUnrestrictedInteractiveMoveResize()) {
const StrutRects strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop());
// TODO: Per-output desktops: is it fine to just take the window's output's desktop? Maybe the output information should be propagated.
const StrutRects strut = workspace()->restrictedMoveArea(VirtualDesktopManager::self()->currentDesktop(m_output));
QRegion availableArea(workspace()->clientArea(FullArea, this, workspace()->activeOutput()).toRect());
for (const QRect &rect : strut) {
availableArea -= rect; // Strut areas
@ -2842,7 +2846,7 @@ void Window::pointerEnterEvent(const QPointF &globalPos)
return;
}
if (options->isAutoRaise() && !isDesktop() && !isDock() && workspace()->focusChangeEnabled() && globalPos != workspace()->focusMousePosition() && workspace()->topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(), options->isSeparateScreenFocus() ? output() : nullptr) != this) {
if (options->isAutoRaise() && !isDesktop() && !isDock() && workspace()->focusChangeEnabled() && globalPos != workspace()->focusMousePosition() && workspace()->topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(output()), options->isSeparateScreenFocus() ? output() : nullptr) != this) {
startAutoRaise();
}
@ -3739,7 +3743,8 @@ void Window::checkWorkspacePosition(QRectF oldGeometry, const VirtualDesktop *ol
oldGeometry = newGeom;
}
VirtualDesktop *desktop = !isOnCurrentDesktop() ? desktops().constLast() : VirtualDesktopManager::self()->currentDesktop();
// TODO: Is it fine to use the window's current output's desktop for this?
VirtualDesktop *desktop = !isOnCurrentDesktop() ? desktops().constLast() : VirtualDesktopManager::self()->currentDesktop(m_output);
if (!oldDesktop) {
oldDesktop = desktop;
}

View file

@ -174,7 +174,8 @@ void Workspace::init()
connect(this, &Workspace::windowRemoved, m_focusChain.get(), &FocusChain::remove);
connect(this, &Workspace::windowActivated, m_focusChain.get(), &FocusChain::setActiveWindow);
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::currentChanged, m_focusChain.get(), [this]() {
m_focusChain->setCurrentDesktop(VirtualDesktopManager::self()->currentDesktop());
// TODO: Is it fine to not care too much about which output is used?
m_focusChain->setCurrentDesktop(VirtualDesktopManager::self()->currentDesktop(activeOutput()));
});
connect(options, &Options::separateScreenFocusChanged, m_focusChain.get(), &FocusChain::setSeparateScreenFocus);
m_focusChain->setSeparateScreenFocus(options->isSeparateScreenFocus());
@ -219,7 +220,10 @@ void Workspace::init()
// load is needed to be called again when starting xwayalnd to sync to RootInfo, see BUG 385260
vds->save();
vds->setCurrent(m_initialDesktop);
// TODO: Does this need more checks?
for (auto &output : outputs()) {
vds->setCurrent(m_initialDesktop, output);
}
reconfigureTimer.setSingleShot(true);
m_rearrangeTimer.setSingleShot(true);
@ -328,7 +332,10 @@ void Workspace::initializeX11()
if (!waylandServer()) {
if (!sessionRestored) {
m_initialDesktop = client_info.currentDesktop();
vds->setCurrent(m_initialDesktop);
// TODO: Test X11 to see if this is fine!
for (auto &output : outputs()) {
vds->setCurrent(m_initialDesktop, output);
}
}
}
@ -405,10 +412,12 @@ void Workspace::initializeX11()
if (newActiveWindow == nullptr && activeWindow() == nullptr && should_get_focus.count() == 0) {
// No client activated in manage()
if (newActiveWindow == nullptr) {
newActiveWindow = topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop());
// TODO: ...
newActiveWindow = topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(activeOutput()));
}
if (newActiveWindow == nullptr) {
newActiveWindow = findDesktop(true, VirtualDesktopManager::self()->currentDesktop());
// TODO: ...
newActiveWindow = findDesktop(true, VirtualDesktopManager::self()->currentDesktop(activeOutput()));
}
}
if (newActiveWindow != nullptr) {
@ -731,7 +740,8 @@ void Workspace::addX11Window(X11Window *window)
raiseWindow(window);
// If there's no active window, make this desktop the active one
if (activeWindow() == nullptr && should_get_focus.count() == 0) {
activateWindow(findDesktop(true, VirtualDesktopManager::self()->currentDesktop()));
// TODO: Is it fine to take this shortcut?
activateWindow(findDesktop(true, VirtualDesktopManager::self()->currentDesktop(activeOutput())));
}
}
window->checkActiveModal();
@ -960,7 +970,10 @@ void Workspace::updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop
}
// Now propagate the change, after hiding, before showing
if (rootInfo()) {
rootInfo()->setCurrentDesktop(VirtualDesktopManager::self()->current());
// TODO: It's probably fine to take this shortcut to getting
// the current desktop, since with X11, all output have the
// same current desktop.
rootInfo()->setCurrentDesktop(VirtualDesktopManager::self()->current(activeOutput()));
}
#endif
@ -1110,11 +1123,13 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
window = m_activeWindow;
} else if (options->focusPolicyIsReasonable()) {
// Search in focus chain
window = m_focusChain->getForActivation(VirtualDesktopManager::self()->currentDesktop());
// TODO: Fix focus chain stuff when different desktops are shown on different outputs.
window = m_focusChain->getForActivation(VirtualDesktopManager::self()->currentDesktop(activeOutput()));
}
if (!window) {
window = findDesktop(true, VirtualDesktopManager::self()->currentDesktop());
// TODO: thing!!
window = findDesktop(true, VirtualDesktopManager::self()->currentDesktop(activeOutput()));
}
if (window != m_activeWindow) {
@ -1513,12 +1528,14 @@ void Workspace::setShowingDesktop(bool showing, bool animated)
}
if (showing_desktop) {
Window *desktop = findDesktop(true, VirtualDesktopManager::self()->currentDesktop());
// TODO: Should the handling of per-output dekstops be better?
Window *desktop = findDesktop(true, VirtualDesktopManager::self()->currentDesktop(activeOutput()));
if (desktop) {
requestFocus(desktop);
}
} else if (!showing_desktop && changed) {
const auto window = m_focusChain->getForActivation(VirtualDesktopManager::self()->currentDesktop());
// TODO: Should the handling of per-output dekstops be better?
const auto window = m_focusChain->getForActivation(VirtualDesktopManager::self()->currentDesktop(activeOutput()));
if (window) {
activateWindow(window);
}
@ -2390,7 +2407,7 @@ QRectF Workspace::clientArea(clientAreaOption opt, const Window *window, const O
{
const VirtualDesktop *desktop;
if (window->isOnCurrentDesktop()) {
desktop = VirtualDesktopManager::self()->currentDesktop();
desktop = VirtualDesktopManager::self()->currentDesktop(window->output());
} else {
desktop = window->desktops().constLast();
}

View file

@ -744,7 +744,8 @@ bool X11Window::manage(xcb_window_t w, bool isMapped)
if (on_all) {
initialDesktops = QList<VirtualDesktop *>{};
} else if (on_current) {
initialDesktops = QList<VirtualDesktop *>{VirtualDesktopManager::self()->currentDesktop()};
// TODO: Is it fine to only consider the active output? probably!
initialDesktops = QList<VirtualDesktop *>{VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput())};
} else if (maincl) {
initialDesktops = maincl->desktops();
}
@ -791,7 +792,8 @@ bool X11Window::manage(xcb_window_t w, bool isMapped)
if (isDesktop()) {
initialDesktops = QList<VirtualDesktop *>{};
} else {
initialDesktops = QList<VirtualDesktop *>{VirtualDesktopManager::self()->currentDesktop()};
// TODO: yeah, it's probably fine! Who uses x11 anywyas!
initialDesktops = QList<VirtualDesktop *>{VirtualDesktopManager::self()->currentDesktop(Workspace::self()->activeOutput())};
}
}
setDesktops(rules()->checkDesktops(*initialDesktops, !isMapped));
@ -1103,7 +1105,12 @@ bool X11Window::manage(xcb_window_t w, bool isMapped)
// If session saving, force showing new windows (i.e. "save file?" dialogs etc.)
// also force if activation is allowed
if (!isOnCurrentDesktop() && !isMapped && !session && (allow || isSessionSaving)) {
VirtualDesktopManager::self()->setCurrent(desktopId());
for (auto *output : Workspace::self()->outputs()) {
// Set the current desktop on all output, because this
// is X11, and i'm not gonna make a hack to get it to
// support per-output virtual desktops.
VirtualDesktopManager::self()->setCurrent(desktopId(), output);
}
}
// If the window is on an inactive activity during session saving, temporarily force it to show.

View file

@ -417,7 +417,7 @@ XdgToplevelWindow::XdgToplevelWindow(XdgToplevelInterface *shellSurface)
{
setOutput(workspace()->activeOutput());
setMoveResizeOutput(workspace()->activeOutput());
setDesktops({VirtualDesktopManager::self()->currentDesktop()});
setDesktops({VirtualDesktopManager::self()->currentDesktop(workspace()->activeOutput())});
#if KWIN_BUILD_ACTIVITIES
if (auto a = Workspace::self()->activities()) {
setOnActivities({a->current()});