Commit 1ce7dc9e authored by Xaver Hugl's avatar Xaver Hugl
Browse files

move FocusChain singleton into Workspace

parent 0a7661c9
......@@ -238,7 +238,7 @@ void Workspace::setActiveWindow(Window *window)
if (m_activeWindow) {
m_lastActiveWindow = m_activeWindow;
FocusChain::self()->update(m_activeWindow, FocusChain::MakeFirst);
m_focusChain->update(m_activeWindow, FocusChain::MakeFirst);
m_activeWindow->demandAttention(false);
// activating a client can cause a non active fullscreen window to loose the ActiveLayer status on > 1 screens
......@@ -489,14 +489,14 @@ bool Workspace::activateNextWindow(Window *window)
// first try to pass the focus to the (former) active clients leader
if (window && window->isTransient()) {
auto leaders = window->mainWindows();
if (leaders.count() == 1 && FocusChain::self()->isUsableFocusCandidate(leaders.at(0), window)) {
if (leaders.count() == 1 && m_focusChain->isUsableFocusCandidate(leaders.at(0), window)) {
focusCandidate = leaders.at(0);
raiseWindow(focusCandidate); // also raise - we don't know where it came from
}
}
if (!focusCandidate) {
// nope, ask the focus chain for the next candidate
focusCandidate = FocusChain::self()->nextForDesktop(window, desktop);
focusCandidate = m_focusChain->nextForDesktop(window, desktop);
}
}
......@@ -520,7 +520,7 @@ void Workspace::switchToOutput(Output *output)
}
closeActivePopup();
VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
Window *get_focus = FocusChain::self()->getForActivation(desktop, output);
Window *get_focus = m_focusChain->getForActivation(desktop, output);
if (get_focus == nullptr) {
get_focus = findDesktop(true, desktop);
}
......
......@@ -206,7 +206,7 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
// e->xmaprequest.window is different from e->xany.window
// TODO this shouldn't be necessary now
window->windowEvent(e);
FocusChain::self()->update(window, FocusChain::Update);
m_focusChain->update(window, FocusChain::Update);
} else if (true /*|| e->xmaprequest.parent != root */) {
// NOTICE don't check for the parent being the root window, this breaks when some app unmaps
// a window, changes something and immediately maps it back, without giving KWin
......
......@@ -13,20 +13,6 @@
namespace KWin
{
KWIN_SINGLETON_FACTORY_VARIABLE(FocusChain, s_manager)
FocusChain::FocusChain(QObject *parent)
: QObject(parent)
, m_separateScreenFocus(false)
, m_activeWindow(nullptr)
{
}
FocusChain::~FocusChain()
{
s_manager = nullptr;
}
void FocusChain::remove(Window *window)
{
for (auto it = m_desktopFocusChains.begin();
......
......@@ -46,7 +46,8 @@ public:
Update,
MakeFirstMinimized = MakeFirst
};
~FocusChain() override;
explicit FocusChain() = default;
/**
* @brief Updates the position of the @p window according to the requested @p change in the
* focus chain.
......@@ -201,11 +202,9 @@ private:
void insertWindowIntoChain(Window *window, Chain &chain);
Chain m_mostRecentlyUsed;
QHash<VirtualDesktop *, Chain> m_desktopFocusChains;
bool m_separateScreenFocus;
Window *m_activeWindow;
bool m_separateScreenFocus = false;
Window *m_activeWindow = nullptr;
VirtualDesktop *m_currentDesktop = nullptr;
KWIN_SINGLETON_VARIABLE(FocusChain, s_manager)
};
inline bool FocusChain::contains(Window *window) const
......
......@@ -443,7 +443,7 @@ void Workspace::restack(Window *window, Window *under, bool force)
}
Q_ASSERT(unconstrained_stacking_order.contains(window));
FocusChain::self()->moveAfterWindow(window, under);
m_focusChain->moveAfterWindow(window, under);
updateStackingOrder();
}
......
......@@ -109,7 +109,7 @@ QString TabBoxHandlerImpl::desktopName(int desktop) const
QWeakPointer<TabBoxClient> TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient *client) const
{
if (TabBoxClientImpl *c = static_cast<TabBoxClientImpl *>(client)) {
auto next = FocusChain::self()->nextMostRecentlyUsed(c->client());
auto next = Workspace::self()->focusChain()->nextMostRecentlyUsed(c->client());
if (next) {
return qWeakPointerCast<TabBoxClient, TabBoxClientImpl>(next->tabBoxClient());
}
......@@ -119,7 +119,7 @@ QWeakPointer<TabBoxClient> TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient
QWeakPointer<TabBoxClient> TabBoxHandlerImpl::firstClientFocusChain() const
{
if (auto c = FocusChain::self()->firstMostRecentlyUsed()) {
if (auto c = Workspace::self()->focusChain()->firstMostRecentlyUsed()) {
return qWeakPointerCast<TabBoxClient, TabBoxClientImpl>(c->tabBoxClient());
} else {
return QWeakPointer<TabBoxClient>();
......@@ -129,7 +129,7 @@ QWeakPointer<TabBoxClient> TabBoxHandlerImpl::firstClientFocusChain() const
bool TabBoxHandlerImpl::isInFocusChain(TabBoxClient *client) const
{
if (TabBoxClientImpl *c = static_cast<TabBoxClientImpl *>(client)) {
return FocusChain::self()->contains(c->client());
return Workspace::self()->focusChain()->contains(c->client());
}
return false;
}
......
......@@ -794,7 +794,7 @@ void Window::setSkipTaskbar(bool b)
doSetSkipTaskbar();
updateWindowRules(Rules::SkipTaskbar);
if (was_wants_tab_focus != wantsTabFocus()) {
FocusChain::self()->update(this, isActive() ? FocusChain::MakeFirst : FocusChain::Update);
Workspace::self()->focusChain()->update(this, isActive() ? FocusChain::MakeFirst : FocusChain::Update);
}
Q_EMIT skipTaskbarChanged();
}
......@@ -1144,7 +1144,7 @@ void Window::setDesktops(QVector<VirtualDesktop *> desktops)
doSetDesktop();
FocusChain::self()->update(this, FocusChain::MakeFirst);
Workspace::self()->focusChain()->update(this, FocusChain::MakeFirst);
updateWindowRules(Rules::Desktops);
Q_EMIT desktopChanged();
......@@ -1387,7 +1387,7 @@ void Window::minimize(bool avoid_animation)
updateWindowRules(Rules::Minimize);
if (options->moveMinimizedWindowsToEndOfTabBoxFocusChain()) {
FocusChain::self()->update(this, FocusChain::MakeFirstMinimized);
Workspace::self()->focusChain()->update(this, FocusChain::MakeFirstMinimized);
}
// TODO: merge signal with s_minimized
......@@ -3561,7 +3561,7 @@ void Window::updateActivities(bool includeTransients)
}
Q_EMIT activitiesChanged(this);
m_blockedActivityUpdatesRequireTransients = false; // reset
FocusChain::self()->update(this, FocusChain::MakeFirst);
Workspace::self()->focusChain()->update(this, FocusChain::MakeFirst);
updateWindowRules(Rules::Activity);
}
......
......@@ -121,6 +121,7 @@ Workspace::Workspace()
, m_userActionsMenu(new UserActionsMenu(this))
, workspaceInit(true)
, m_sessionManager(new SessionManager(this))
, m_focusChain(std::make_unique<FocusChain>())
{
// If KWin was already running it saved its configuration after loosing the selection -> Reread
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
......@@ -198,14 +199,13 @@ void Workspace::init()
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::layoutChanged, screenEdges, &ScreenEdges::updateLayout);
connect(this, &Workspace::windowActivated, screenEdges, &ScreenEdges::checkBlocking);
FocusChain *focusChain = FocusChain::create(this);
connect(this, &Workspace::windowRemoved, focusChain, &FocusChain::remove);
connect(this, &Workspace::windowActivated, focusChain, &FocusChain::setActiveWindow);
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::currentChanged, focusChain, [focusChain]() {
focusChain->setCurrentDesktop(VirtualDesktopManager::self()->currentDesktop());
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(options, &Options::separateScreenFocusChanged, focusChain, &FocusChain::setSeparateScreenFocus);
focusChain->setSeparateScreenFocus(options->isSeparateScreenFocus());
connect(options, &Options::separateScreenFocusChanged, m_focusChain.get(), &FocusChain::setSeparateScreenFocus);
m_focusChain->setSeparateScreenFocus(options->isSeparateScreenFocus());
Platform *platform = kwinApp()->platform();
connect(platform, &Platform::outputEnabled, this, &Workspace::slotOutputEnabled);
......@@ -682,7 +682,7 @@ void Workspace::addX11Window(X11Window *window)
requestFocus(window); // TODO: Make sure desktop is active after startup if there's no other window active
}
} else {
FocusChain::self()->update(window, FocusChain::Update);
m_focusChain->update(window, FocusChain::Update);
}
m_x11Clients.append(window);
m_allClients.append(window);
......@@ -1063,7 +1063,7 @@ void Workspace::activateWindowOnNewDesktop(VirtualDesktop *desktop)
Window *Workspace::findWindowToActivateOnDesktop(VirtualDesktop *desktop)
{
if (m_moveResizeWindow != nullptr && m_activeWindow == m_moveResizeWindow && FocusChain::self()->contains(m_activeWindow, desktop) && m_activeWindow->isShown() && m_activeWindow->isOnCurrentDesktop()) {
if (m_moveResizeWindow != nullptr && m_activeWindow == m_moveResizeWindow && m_focusChain->contains(m_activeWindow, desktop) && m_activeWindow->isShown() && m_activeWindow->isOnCurrentDesktop()) {
// A requestFocus call will fail, as the window is already active
return m_activeWindow;
}
......@@ -1089,7 +1089,7 @@ Window *Workspace::findWindowToActivateOnDesktop(VirtualDesktop *desktop)
}
}
}
return FocusChain::self()->getForActivation(desktop);
return m_focusChain->getForActivation(desktop);
}
/**
......@@ -1158,7 +1158,7 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
window = m_activeWindow;
} else if (options->focusPolicyIsReasonable()) {
// Search in focus chain
window = FocusChain::self()->getForActivation(VirtualDesktopManager::self()->currentDesktop());
window = m_focusChain->getForActivation(VirtualDesktopManager::self()->currentDesktop());
}
if (!window) {
......@@ -1251,7 +1251,7 @@ void Workspace::slotOutputDisabled(Output *output)
void Workspace::slotDesktopAdded(VirtualDesktop *desktop)
{
FocusChain::self()->addDesktop(desktop);
m_focusChain->addDesktop(desktop);
Placement::self()->reinitCascading(0);
updateClientArea();
}
......@@ -1271,7 +1271,7 @@ void Workspace::slotDesktopRemoved(VirtualDesktop *desktop)
updateClientArea();
Placement::self()->reinitCascading(0);
FocusChain::self()->removeDesktop(desktop);
m_focusChain->removeDesktop(desktop);
}
void Workspace::selectWmInputEventMask()
......@@ -1415,7 +1415,7 @@ void Workspace::setShowingDesktop(bool showing, bool animated)
if (showing_desktop && topDesk) {
requestFocus(topDesk);
} else if (!showing_desktop && changed) {
const auto window = FocusChain::self()->getForActivation(VirtualDesktopManager::self()->currentDesktop());
const auto window = m_focusChain->getForActivation(VirtualDesktopManager::self()->currentDesktop());
if (window) {
activateWindow(window);
}
......@@ -2823,4 +2823,9 @@ void Workspace::fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_rep
}
}
FocusChain *Workspace::focusChain() const
{
return m_focusChain.get();
}
} // namespace
......@@ -54,6 +54,7 @@ class UserActionsMenu;
class VirtualDesktop;
class X11Window;
class X11EventFilter;
class FocusChain;
enum class Predicate;
class KWIN_EXPORT Workspace : public QObject
......@@ -423,6 +424,7 @@ public:
{
return m_lastActiveWindow;
}
FocusChain *focusChain() const;
public Q_SLOTS:
void performWindowOperation(KWin::Window *window, Options::WindowOperation op);
......@@ -691,6 +693,7 @@ private:
QScopedPointer<X11EventFilter> m_syncAlarmFilter;
SessionManager *m_sessionManager;
std::unique_ptr<FocusChain> m_focusChain;
private:
friend bool performTransiencyCheck();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment