From 8e32dd4fdc5b2bd932884c076e9b6550c3ebbbe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 22 Dec 2016 21:12:46 +0100 Subject: [PATCH] Cycle between windows of the same desktop on switch Summary: When switching virtual desktops using shortcuts, the behavior is to switch to a virtual desktop in the opposite direction if the current one is on the edges of the layout. For example, in a one row layout with 4 virtual desktops, "Switch One Desktop to the Left" while in virtual desktop # 1 will send the user to virtual desktop # 4. Likewise, in a 3 rows layout with 9 virtual desktops, "Switch One Desktop Down" while in virtual desktop # 8 will lead the user to desktop # 2. This patch uses the same behavior whilst changing windows using "Switch to Window Above|Below|to the Right|to the Left". For example, in a 3 display set-up (my set-up), the user would go from an application in the rightmost position to an application in the leftmost position using just one key combination: "Switch to Window to the Right". Currently, the shortcuts are no-op in these cases (ie, trying "Switch to Window to the Left" from the leftmost window has no outcome, which is mostly accurate with the shortcut semantics but totally useless in behavior). Reviewers: #vdg, #kwin, graesslin Reviewed By: #kwin, graesslin Subscribers: luebking, subdiff, colomar, graesslin, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D3602 --- useractions.cpp | 32 +++++++++++++++++++++++++++++--- workspace.h | 1 + 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/useractions.cpp b/useractions.cpp index 8e26389bc5..983ad8795f 100755 --- a/useractions.cpp +++ b/useractions.cpp @@ -1568,13 +1568,37 @@ void Workspace::switchWindow(Direction direction) if (!active_client) return; AbstractClient *c = active_client; - Client *switchTo = 0; - int bestScore = 0; - int d = c->isOnAllDesktops() ? VirtualDesktopManager::self()->current() : c->desktop(); + int desktopNumber = c->isOnAllDesktops() ? VirtualDesktopManager::self()->current() : c->desktop(); + // Centre of the active window QPoint curPos(c->pos().x() + c->geometry().width() / 2, c->pos().y() + c->geometry().height() / 2); + if (!switchWindow(c, direction, curPos, desktopNumber)) { + auto opposite = [&] { + switch(direction) { + case DirectionNorth: + return QPoint(curPos.x(), screens()->geometry().height()); + case DirectionSouth: + return QPoint(curPos.x(), 0); + case DirectionEast: + return QPoint(0, curPos.y()); + case DirectionWest: + return QPoint(screens()->geometry().width(), curPos.y()); + default: + Q_UNREACHABLE(); + } + }; + + switchWindow(c, direction, opposite(), desktopNumber); + } +} + +bool Workspace::switchWindow(AbstractClient *c, Direction direction, QPoint curPos, int d) +{ + Client *switchTo = nullptr; + int bestScore = 0; + ToplevelList clist = stackingOrder(); for (ToplevelList::Iterator i = clist.begin(); i != clist.end(); ++i) { Client *client = qobject_cast(*i); @@ -1626,6 +1650,8 @@ void Workspace::switchWindow(Direction direction) switchTo = switchTo->tabGroup()->current(); activateClient(switchTo); } + + return switchTo; } /*! diff --git a/workspace.h b/workspace.h index e7a131d644..d2e49bd72a 100644 --- a/workspace.h +++ b/workspace.h @@ -503,6 +503,7 @@ private: DirectionWest }; void switchWindow(Direction direction); + bool switchWindow(AbstractClient *c, Direction direction, QPoint curPos, int desktop); void propagateClients(bool propagate_new_clients); // Called only from updateStackingOrder ToplevelList constrainedStackingOrder();