WIP/focuschain: added support for per-output VDs

This commit is contained in:
Yuki Joou 2024-09-13 01:37:37 +02:00
parent ebf8bb3535
commit a1b5ee11f8
5 changed files with 17 additions and 11 deletions

View file

@ -30,8 +30,11 @@ void FocusChain::addDesktop(VirtualDesktop *desktop)
void FocusChain::removeDesktop(VirtualDesktop *desktop)
{
if (m_currentDesktop == desktop) {
m_currentDesktop = nullptr;
// TODO: Test if this works lmao
for (auto &desktop : m_currentDesktop) {
if (desktop == desktop) {
desktop = nullptr;
}
}
m_desktopFocusChains.remove(desktop);
}
@ -43,6 +46,7 @@ Window *FocusChain::getForActivation(VirtualDesktop *desktop) const
Window *FocusChain::getForActivation(VirtualDesktop *desktop, Output *output) const
{
// TODO: Find windows on other dedsktops that are also currently visible.
auto it = m_desktopFocusChains.constFind(desktop);
if (it == m_desktopFocusChains.constEnd()) {
return nullptr;
@ -74,7 +78,7 @@ void FocusChain::update(Window *window, FocusChain::Change change)
++it) {
auto &chain = it.value();
// Making first/last works only on current desktop, don't affect all desktops
if (it.key() == m_currentDesktop
if (it.key() == m_currentDesktop[window->output()] // TODO: Is using the window's output the right thing to do?
&& (change == MakeFirst || change == MakeLast)) {
if (change == MakeFirst) {
makeFirstInChain(window, chain);

View file

@ -176,7 +176,7 @@ public Q_SLOTS:
void remove(KWin::Window *window);
void setSeparateScreenFocus(bool enabled);
void setActiveWindow(KWin::Window *window);
void setCurrentDesktop(VirtualDesktop *desktop);
void setCurrentDesktop(VirtualDesktop *desktop, Output *output);
void addDesktop(VirtualDesktop *desktop);
void removeDesktop(VirtualDesktop *desktop);
@ -212,7 +212,7 @@ private:
QHash<VirtualDesktop *, Chain> m_desktopFocusChains;
bool m_separateScreenFocus = false;
Window *m_activeWindow = nullptr;
VirtualDesktop *m_currentDesktop = nullptr;
QHash<Output *, VirtualDesktop *> m_currentDesktop = {};
};
inline bool FocusChain::contains(Window *window) const
@ -230,9 +230,10 @@ inline void FocusChain::setActiveWindow(Window *window)
m_activeWindow = window;
}
inline void FocusChain::setCurrentDesktop(VirtualDesktop *desktop)
inline void FocusChain::setCurrentDesktop(VirtualDesktop *desktop, Output *output)
{
m_currentDesktop = desktop;
Q_ASSERT(output);
m_currentDesktop[output] = desktop;
}
} // namespace

View file

@ -574,7 +574,7 @@ bool VirtualDesktopManager::setCurrentForOutput(VirtualDesktop *newDesktop, Outp
}
VirtualDesktop *oldDesktop = m_currentForOutput[targetOutput];
m_currentForOutput[targetOutput] = newDesktop;
Q_EMIT currentChanged(oldDesktop, newDesktop);
Q_EMIT currentChanged(oldDesktop, newDesktop, targetOutput);
return true;
}

View file

@ -417,8 +417,9 @@ Q_SIGNALS:
* Signal emitted whenever the current desktop changes.
* @param previousDesktop The virtual desktop changed from
* @param newDesktop The virtual desktop changed to
* @param output The output where the change happened. `nullptr` when the code reporting the change doesn't handle multiple outputs.
*/
void currentChanged(KWin::VirtualDesktop *previousDesktop, KWin::VirtualDesktop *newDesktop);
void currentChanged(KWin::VirtualDesktop *previousDesktop, KWin::VirtualDesktop *newDesktop, Output *output = nullptr);
/**
* Signal emmitted for realtime desktop switching animations.

View file

@ -175,8 +175,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());
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::currentChanged, m_focusChain.get(), [this](KWin::VirtualDesktop *, KWin::VirtualDesktop *newDesktop, Output *output) {
m_focusChain->setCurrentDesktop(newDesktop, output);
});
connect(options, &Options::separateScreenFocusChanged, m_focusChain.get(), &FocusChain::setSeparateScreenFocus);
m_focusChain->setSeparateScreenFocus(options->isSeparateScreenFocus());