diff --git a/src/activation.cpp b/src/activation.cpp index bf4c1a4248..e9afb25857 100644 --- a/src/activation.cpp +++ b/src/activation.cpp @@ -500,20 +500,18 @@ bool Workspace::activateNextClient(AbstractClient* c) } -void Workspace::setCurrentScreen(int new_screen) +void Workspace::setCurrentOutput(AbstractOutput *output) { - if (new_screen < 0 || new_screen >= screens()->count()) - return; if (!options->focusPolicyIsReasonable()) return; closeActivePopup(); VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop(); - AbstractClient *get_focus = FocusChain::self()->getForActivation(desktop, new_screen); + AbstractClient *get_focus = FocusChain::self()->getForActivation(desktop, output); if (get_focus == nullptr) get_focus = findDesktop(true, desktop); if (get_focus != nullptr && get_focus != mostRecentlyActivatedClient()) requestFocus(get_focus); - screens()->setCurrent(new_screen); + screens()->setCurrent(output); } void Workspace::gotFocusIn(const AbstractClient* c) diff --git a/src/focuschain.cpp b/src/focuschain.cpp index 5963e9b302..f24a2121be 100644 --- a/src/focuschain.cpp +++ b/src/focuschain.cpp @@ -52,10 +52,10 @@ void FocusChain::removeDesktop(VirtualDesktop *desktop) AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop) const { - return getForActivation(desktop, screens()->current()); + return getForActivation(desktop, screens()->currentOutput()); } -AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop, int screen) const +AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop, AbstractOutput *output) const { auto it = m_desktopFocusChains.constFind(desktop); if (it == m_desktopFocusChains.constEnd()) { @@ -66,7 +66,7 @@ AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop, int screen auto tmp = chain.at(i); // TODO: move the check into Client if (tmp->isShown(false) && tmp->isOnCurrentActivity() - && ( !m_separateScreenFocus || tmp->screen() == screen)) { + && ( !m_separateScreenFocus || tmp->output() == output)) { return tmp; } } @@ -207,7 +207,7 @@ bool FocusChain::isUsableFocusCandidate(AbstractClient *c, AbstractClient *prev) { return c != prev && c->isShown(false) && c->isOnCurrentDesktop() && c->isOnCurrentActivity() && - (!m_separateScreenFocus || c->isOnScreen(prev ? prev->screen() : screens()->current())); + (!m_separateScreenFocus || c->isOnOutput(prev ? prev->output() : screens()->currentOutput())); } AbstractClient *FocusChain::nextForDesktop(AbstractClient *reference, VirtualDesktop *desktop) const diff --git a/src/focuschain.h b/src/focuschain.h index 43751101b5..5647c87006 100644 --- a/src/focuschain.h +++ b/src/focuschain.h @@ -18,6 +18,7 @@ namespace KWin { // forward declarations class AbstractClient; +class AbstractOutput; class VirtualDesktop; /** @@ -98,10 +99,10 @@ public: * If no Client for activation is found @c null is returned. * * @param desktop The virtual desktop to look for a Client for activation - * @param screen The screen to constrain the search on with separate screen focus + * @param output The screen to constrain the search on with separate screen focus * @return :X11Client *The Client which could be activated or @c null if there is none. */ - AbstractClient *getForActivation(VirtualDesktop *desktop, int screen) const; + AbstractClient *getForActivation(VirtualDesktop *desktop, AbstractOutput *output) const; /** * @brief Checks whether the most recently used focus chain contains the given @p client. diff --git a/src/useractions.cpp b/src/useractions.cpp index fa0ee50efd..1e53cee751 100644 --- a/src/useractions.cpp +++ b/src/useractions.cpp @@ -1307,27 +1307,44 @@ static bool screenSwitchImpossible() return true; } +AbstractOutput *Workspace::nextOutput(AbstractOutput *reference) const +{ + const auto outputs = kwinApp()->platform()->enabledOutputs(); + const int index = outputs.indexOf(reference); + Q_ASSERT(index != -1); + return outputs[(index + 1) % outputs.count()]; +} + +AbstractOutput *Workspace::previousOutput(AbstractOutput *reference) const +{ + const auto outputs = kwinApp()->platform()->enabledOutputs(); + const int index = outputs.indexOf(reference); + Q_ASSERT(index != -1); + return outputs[(index + outputs.count() - 1) % outputs.count()]; +} + void Workspace::slotSwitchToScreen() { if (screenSwitchImpossible()) return; - const int i = senderValue(sender()); - if (i > -1) - setCurrentScreen(i); + AbstractOutput *output = kwinApp()->platform()->findOutput(senderValue(sender())); + if (output) { + setCurrentOutput(output); + } } void Workspace::slotSwitchToNextScreen() { if (screenSwitchImpossible()) return; - setCurrentScreen((screens()->current() + 1) % screens()->count()); + setCurrentOutput(nextOutput(screens()->currentOutput())); } void Workspace::slotSwitchToPrevScreen() { if (screenSwitchImpossible()) return; - setCurrentScreen((screens()->current() + screens()->count() - 1) % screens()->count()); + setCurrentOutput(previousOutput(screens()->currentOutput())); } void Workspace::slotWindowToScreen() diff --git a/src/workspace.h b/src/workspace.h index c791d95ee2..90c1753c47 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -317,7 +317,9 @@ public: // D-Bus interface QString supportInformation() const; - void setCurrentScreen(int new_screen); + AbstractOutput *nextOutput(AbstractOutput *reference) const; + AbstractOutput *previousOutput(AbstractOutput *reference) const; + void setCurrentOutput(AbstractOutput *output); void setShowingDesktop(bool showing); bool showingDesktop() const;