Port FocusChain to VirtualDesktop
This commit is contained in:
parent
42f2afd80d
commit
7c8d9c5b1c
5 changed files with 45 additions and 48 deletions
|
@ -482,7 +482,7 @@ bool Workspace::activateNextClient(AbstractClient* c)
|
|||
}
|
||||
if (!get_focus) {
|
||||
// nope, ask the focus chain for the next candidate
|
||||
get_focus = FocusChain::self()->nextForDesktop(c, desktop->x11DesktopNumber());
|
||||
get_focus = FocusChain::self()->nextForDesktop(c, desktop);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,7 +506,7 @@ void Workspace::setCurrentScreen(int new_screen)
|
|||
return;
|
||||
closeActivePopup();
|
||||
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
|
||||
AbstractClient *get_focus = FocusChain::self()->getForActivation(desktop->x11DesktopNumber(), new_screen);
|
||||
AbstractClient *get_focus = FocusChain::self()->getForActivation(desktop, new_screen);
|
||||
if (get_focus == nullptr)
|
||||
get_focus = findDesktop(true, desktop);
|
||||
if (get_focus != nullptr && get_focus != mostRecentlyActivatedClient())
|
||||
|
|
|
@ -19,7 +19,6 @@ FocusChain::FocusChain(QObject *parent)
|
|||
: QObject(parent)
|
||||
, m_separateScreenFocus(false)
|
||||
, m_activeClient(nullptr)
|
||||
, m_currentDesktop(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -38,22 +37,25 @@ void FocusChain::remove(AbstractClient *client)
|
|||
m_mostRecentlyUsed.removeAll(client);
|
||||
}
|
||||
|
||||
void FocusChain::resize(uint previousSize, uint newSize)
|
||||
void FocusChain::addDesktop(VirtualDesktop *desktop)
|
||||
{
|
||||
for (uint i = previousSize + 1; i <= newSize; ++i) {
|
||||
m_desktopFocusChains.insert(i, Chain());
|
||||
}
|
||||
for (uint i = previousSize; i > newSize; --i) {
|
||||
m_desktopFocusChains.remove(i);
|
||||
}
|
||||
m_desktopFocusChains.insert(desktop, Chain());
|
||||
}
|
||||
|
||||
AbstractClient *FocusChain::getForActivation(uint desktop) const
|
||||
void FocusChain::removeDesktop(VirtualDesktop *desktop)
|
||||
{
|
||||
if (m_currentDesktop == desktop) {
|
||||
m_currentDesktop = nullptr;
|
||||
}
|
||||
m_desktopFocusChains.remove(desktop);
|
||||
}
|
||||
|
||||
AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop) const
|
||||
{
|
||||
return getForActivation(desktop, screens()->current());
|
||||
}
|
||||
|
||||
AbstractClient *FocusChain::getForActivation(uint desktop, int screen) const
|
||||
AbstractClient *FocusChain::getForActivation(VirtualDesktop *desktop, int screen) const
|
||||
{
|
||||
auto it = m_desktopFocusChains.constFind(desktop);
|
||||
if (it == m_desktopFocusChains.constEnd()) {
|
||||
|
@ -208,7 +210,7 @@ bool FocusChain::isUsableFocusCandidate(AbstractClient *c, AbstractClient *prev)
|
|||
(!m_separateScreenFocus || c->isOnScreen(prev ? prev->screen() : screens()->current()));
|
||||
}
|
||||
|
||||
AbstractClient *FocusChain::nextForDesktop(AbstractClient *reference, uint desktop) const
|
||||
AbstractClient *FocusChain::nextForDesktop(AbstractClient *reference, VirtualDesktop *desktop) const
|
||||
{
|
||||
auto it = m_desktopFocusChains.constFind(desktop);
|
||||
if (it == m_desktopFocusChains.constEnd()) {
|
||||
|
@ -250,7 +252,7 @@ void FocusChain::makeLastInChain(AbstractClient *client, Chain &chain)
|
|||
chain.prepend(client);
|
||||
}
|
||||
|
||||
bool FocusChain::contains(AbstractClient *client, uint desktop) const
|
||||
bool FocusChain::contains(AbstractClient *client, VirtualDesktop *desktop) const
|
||||
{
|
||||
auto it = m_desktopFocusChains.constFind(desktop);
|
||||
if (it == m_desktopFocusChains.constEnd()) {
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace KWin
|
|||
{
|
||||
// forward declarations
|
||||
class AbstractClient;
|
||||
class VirtualDesktop;
|
||||
|
||||
/**
|
||||
* @brief Singleton class to handle the various focus chains.
|
||||
|
@ -87,7 +88,7 @@ public:
|
|||
* @param desktop The virtual desktop to look for a Client for activation
|
||||
* @return :X11Client *The Client which could be activated or @c null if there is none.
|
||||
*/
|
||||
AbstractClient *getForActivation(uint desktop) const;
|
||||
AbstractClient *getForActivation(VirtualDesktop *desktop) const;
|
||||
/**
|
||||
* @brief Finds the best Client to become the new active Client in the focus chain for the given
|
||||
* virtual @p desktop on the given @p screen.
|
||||
|
@ -100,7 +101,7 @@ public:
|
|||
* @param screen 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(uint desktop, int screen) const;
|
||||
AbstractClient *getForActivation(VirtualDesktop *desktop, int screen) const;
|
||||
|
||||
/**
|
||||
* @brief Checks whether the most recently used focus chain contains the given @p client.
|
||||
|
@ -119,7 +120,7 @@ public:
|
|||
* @param desktop The virtual desktop whose focus chain should be used
|
||||
* @return bool @c true if the focus chain for @p desktop contains @p client, @c false otherwise.
|
||||
*/
|
||||
bool contains(AbstractClient *client, uint desktop) const;
|
||||
bool contains(AbstractClient *client, VirtualDesktop *desktop) const;
|
||||
/**
|
||||
* @brief Queries the most recently used focus chain for the next Client after the given
|
||||
* @p reference Client.
|
||||
|
@ -145,7 +146,7 @@ public:
|
|||
* @param desktop The virtual desktop whose focus chain should be used
|
||||
* @return :X11Client *The next usable Client or @c null if none can be found.
|
||||
*/
|
||||
AbstractClient *nextForDesktop(AbstractClient *reference, uint desktop) const;
|
||||
AbstractClient *nextForDesktop(AbstractClient *reference, VirtualDesktop *desktop) const;
|
||||
/**
|
||||
* @brief Returns the first Client in the most recently used focus chain. First Client in this
|
||||
* case means really the first Client in the chain and not the most recently used Client.
|
||||
|
@ -157,16 +158,6 @@ public:
|
|||
bool isUsableFocusCandidate(AbstractClient *c, AbstractClient *prev) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* @brief Resizes the per virtual desktop focus chains from @p previousSize to @p newSize.
|
||||
* This means that for each virtual desktop between previous and new size a new focus chain is
|
||||
* created and in case the number is reduced the focus chains are destroyed.
|
||||
*
|
||||
* @param previousSize The previous number of virtual desktops
|
||||
* @param newSize The new number of virtual desktops
|
||||
* @return void
|
||||
*/
|
||||
void resize(uint previousSize, uint newSize);
|
||||
/**
|
||||
* @brief Removes @p client from all focus chains.
|
||||
*
|
||||
|
@ -176,7 +167,9 @@ public Q_SLOTS:
|
|||
void remove(KWin::AbstractClient *client);
|
||||
void setSeparateScreenFocus(bool enabled);
|
||||
void setActiveClient(KWin::AbstractClient *client);
|
||||
void setCurrentDesktop(uint previous, uint newDesktop);
|
||||
void setCurrentDesktop(VirtualDesktop *desktop);
|
||||
void addDesktop(VirtualDesktop *desktop);
|
||||
void removeDesktop(VirtualDesktop *desktop);
|
||||
|
||||
private:
|
||||
using Chain = QList<AbstractClient*>;
|
||||
|
@ -206,10 +199,10 @@ private:
|
|||
void updateClientInChain(AbstractClient *client, Change change, Chain &chain);
|
||||
void insertClientIntoChain(AbstractClient *client, Chain &chain);
|
||||
Chain m_mostRecentlyUsed;
|
||||
QHash<uint, Chain> m_desktopFocusChains;
|
||||
QHash<VirtualDesktop *, Chain> m_desktopFocusChains;
|
||||
bool m_separateScreenFocus;
|
||||
AbstractClient *m_activeClient;
|
||||
uint m_currentDesktop;
|
||||
VirtualDesktop *m_currentDesktop = nullptr;
|
||||
|
||||
KWIN_SINGLETON_VARIABLE(FocusChain, s_manager)
|
||||
};
|
||||
|
@ -233,10 +226,9 @@ void FocusChain::setActiveClient(AbstractClient *client)
|
|||
}
|
||||
|
||||
inline
|
||||
void FocusChain::setCurrentDesktop(uint previous, uint newDesktop)
|
||||
void FocusChain::setCurrentDesktop(VirtualDesktop *desktop)
|
||||
{
|
||||
Q_UNUSED(previous)
|
||||
m_currentDesktop = newDesktop;
|
||||
m_currentDesktop = desktop;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -223,8 +223,11 @@ void Workspace::init()
|
|||
FocusChain *focusChain = FocusChain::create(this);
|
||||
connect(this, &Workspace::clientRemoved, focusChain, &FocusChain::remove);
|
||||
connect(this, &Workspace::clientActivated, focusChain, &FocusChain::setActiveClient);
|
||||
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::countChanged, focusChain, &FocusChain::resize);
|
||||
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::currentChanged, focusChain, &FocusChain::setCurrentDesktop);
|
||||
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::desktopCreated, focusChain, &FocusChain::addDesktop);
|
||||
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::desktopRemoved, focusChain, &FocusChain::removeDesktop);
|
||||
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::currentChanged, focusChain, [focusChain]() {
|
||||
focusChain->setCurrentDesktop(VirtualDesktopManager::self()->currentDesktop());
|
||||
});
|
||||
connect(options, &Options::separateScreenFocusChanged, focusChain, &FocusChain::setSeparateScreenFocus);
|
||||
focusChain->setSeparateScreenFocus(options->isSeparateScreenFocus());
|
||||
|
||||
|
@ -1018,15 +1021,15 @@ void Workspace::slotCurrentDesktopChanged(uint oldDesktop, uint newDesktop)
|
|||
closeActivePopup();
|
||||
++block_focus;
|
||||
StackingUpdatesBlocker blocker(this);
|
||||
updateClientVisibilityOnDesktopChange(newDesktop);
|
||||
updateClientVisibilityOnDesktopChange(VirtualDesktopManager::self()->desktopForX11Id(newDesktop));
|
||||
// Restore the focus on this desktop
|
||||
--block_focus;
|
||||
|
||||
activateClientOnNewDesktop(newDesktop);
|
||||
activateClientOnNewDesktop(VirtualDesktopManager::self()->desktopForX11Id(newDesktop));
|
||||
Q_EMIT currentDesktopChanged(oldDesktop, movingClient);
|
||||
}
|
||||
|
||||
void Workspace::updateClientVisibilityOnDesktopChange(uint newDesktop)
|
||||
void Workspace::updateClientVisibilityOnDesktopChange(VirtualDesktop *newDesktop)
|
||||
{
|
||||
for (auto it = stacking_order.constBegin();
|
||||
it != stacking_order.constEnd();
|
||||
|
@ -1045,7 +1048,7 @@ void Workspace::updateClientVisibilityOnDesktopChange(uint newDesktop)
|
|||
}
|
||||
|
||||
if (movingClient && !movingClient->isOnDesktop(newDesktop)) {
|
||||
movingClient->setDesktop(newDesktop);
|
||||
movingClient->setDesktops({newDesktop});
|
||||
}
|
||||
|
||||
for (int i = stacking_order.size() - 1; i >= 0 ; --i) {
|
||||
|
@ -1060,7 +1063,7 @@ void Workspace::updateClientVisibilityOnDesktopChange(uint newDesktop)
|
|||
setShowingDesktop(false);
|
||||
}
|
||||
|
||||
void Workspace::activateClientOnNewDesktop(uint desktop)
|
||||
void Workspace::activateClientOnNewDesktop(VirtualDesktop *desktop)
|
||||
{
|
||||
AbstractClient* c = nullptr;
|
||||
if (options->focusPolicyIsReasonable()) {
|
||||
|
@ -1073,7 +1076,7 @@ void Workspace::activateClientOnNewDesktop(uint desktop)
|
|||
c = active_client;
|
||||
|
||||
if (!c)
|
||||
c = findDesktop(true, VirtualDesktopManager::self()->desktopForX11Id(desktop));
|
||||
c = findDesktop(true, desktop);
|
||||
|
||||
if (c != active_client)
|
||||
setActiveClient(nullptr);
|
||||
|
@ -1084,7 +1087,7 @@ void Workspace::activateClientOnNewDesktop(uint desktop)
|
|||
focusToNull();
|
||||
}
|
||||
|
||||
AbstractClient *Workspace::findClientToActivateOnDesktop(uint desktop)
|
||||
AbstractClient *Workspace::findClientToActivateOnDesktop(VirtualDesktop *desktop)
|
||||
{
|
||||
if (movingClient != nullptr && active_client == movingClient &&
|
||||
FocusChain::self()->contains(active_client, desktop) &&
|
||||
|
@ -1178,7 +1181,7 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
|
|||
//FIXME below here is a lot of focuschain stuff, probably all wrong now
|
||||
if (options->focusPolicyIsReasonable()) {
|
||||
// Search in focus chain
|
||||
c = FocusChain::self()->getForActivation(VirtualDesktopManager::self()->current());
|
||||
c = FocusChain::self()->getForActivation(VirtualDesktopManager::self()->currentDesktop());
|
||||
}
|
||||
// If "unreasonable focus policy" and active_client is on_all_desktops and
|
||||
// under mouse (Hence == old_active_client), conserve focus.
|
||||
|
@ -1393,7 +1396,7 @@ void Workspace::setShowingDesktop(bool showing)
|
|||
if (showing_desktop && topDesk) {
|
||||
requestFocus(topDesk);
|
||||
} else if (!showing_desktop && changed) {
|
||||
const auto client = FocusChain::self()->getForActivation(VirtualDesktopManager::self()->current());
|
||||
const auto client = FocusChain::self()->getForActivation(VirtualDesktopManager::self()->currentDesktop());
|
||||
if (client) {
|
||||
activateClient(client);
|
||||
}
|
||||
|
|
|
@ -558,9 +558,9 @@ private:
|
|||
void closeActivePopup();
|
||||
void updateClientArea(bool force);
|
||||
void resetClientAreas(uint desktopCount);
|
||||
void updateClientVisibilityOnDesktopChange(uint newDesktop);
|
||||
void activateClientOnNewDesktop(uint desktop);
|
||||
AbstractClient *findClientToActivateOnDesktop(uint desktop);
|
||||
void updateClientVisibilityOnDesktopChange(VirtualDesktop *newDesktop);
|
||||
void activateClientOnNewDesktop(VirtualDesktop *desktop);
|
||||
AbstractClient *findClientToActivateOnDesktop(VirtualDesktop *desktop);
|
||||
void removeAbstractClient(AbstractClient *client);
|
||||
|
||||
struct Constraint
|
||||
|
|
Loading…
Reference in a new issue