summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNikolai Nechaev <nikolay_nechaev@mail.ru>2025-11-26 07:44:26 +0900
committerGitHub <noreply@github.com>2025-11-25 22:44:26 +0000
commit40d8fa84919c6d0e9fcb1536f4bc09710d4c031c (patch)
treee45044c92e5d8f716f2aa15668c61fed5aaf5895 /src
parent1c1746de61a90dbbae072f3fc618c45af33fdd59 (diff)
compositor: Configurable behavior when window to be focused conflicts with fullscreen (#12033)
Renames `misc:new_window_takes_over_fullscreen` into `misc:on_focus_under_fullscreen` and implements the following behavior: - By default, when a tiling window is being focused on a workspace where a fullscreen/maximized window exists, respect the `misc:on_focus_under_fullscreen` config variable.
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp282
-rw-r--r--src/Compositor.hpp9
-rw-r--r--src/config/ConfigDescriptions.hpp14
-rw-r--r--src/config/ConfigManager.cpp4
-rw-r--r--src/debug/HyprCtl.cpp25
-rw-r--r--src/debug/HyprDebugOverlay.cpp3
-rw-r--r--src/desktop/LayerSurface.cpp16
-rw-r--r--src/desktop/Subsurface.cpp5
-rw-r--r--src/desktop/Window.cpp41
-rw-r--r--src/desktop/rule/windowRule/WindowRule.cpp3
-rw-r--r--src/desktop/state/FocusState.cpp330
-rw-r--r--src/desktop/state/FocusState.hpp43
-rw-r--r--src/events/Windows.cpp48
-rw-r--r--src/helpers/MiscFunctions.cpp35
-rw-r--r--src/helpers/Monitor.cpp37
-rw-r--r--src/hyprerror/HyprError.cpp3
-rw-r--r--src/layout/DwindleLayout.cpp19
-rw-r--r--src/layout/IHyprLayout.cpp19
-rw-r--r--src/layout/MasterLayout.cpp39
-rw-r--r--src/managers/KeybindManager.cpp232
-rw-r--r--src/managers/KeybindManager.hpp3
-rw-r--r--src/managers/PointerManager.cpp5
-rw-r--r--src/managers/SeatManager.cpp7
-rw-r--r--src/managers/SessionLockManager.cpp15
-rw-r--r--src/managers/XWaylandManager.cpp5
-rw-r--r--src/managers/input/InputManager.cpp79
-rw-r--r--src/managers/input/InputMethodRelay.cpp15
-rw-r--r--src/managers/input/TextInput.cpp9
-rw-r--r--src/managers/input/Touch.cpp4
-rw-r--r--src/managers/input/UnifiedWorkspaceSwipeGesture.cpp9
-rw-r--r--src/managers/input/trackpad/gestures/CloseGesture.cpp3
-rw-r--r--src/managers/input/trackpad/gestures/FloatGesture.cpp5
-rw-r--r--src/managers/input/trackpad/gestures/FullscreenGesture.cpp3
-rw-r--r--src/managers/input/trackpad/gestures/MoveGesture.cpp5
-rw-r--r--src/managers/input/trackpad/gestures/ResizeGesture.cpp5
-rw-r--r--src/managers/input/trackpad/gestures/SpecialWorkspaceGesture.cpp6
-rw-r--r--src/managers/input/trackpad/gestures/WorkspaceSwipeGesture.cpp4
-rw-r--r--src/protocols/FocusGrab.cpp3
-rw-r--r--src/protocols/ForeignToplevelWlr.cpp13
-rw-r--r--src/protocols/InputMethodV2.cpp7
-rw-r--r--src/protocols/PointerConstraints.cpp5
-rw-r--r--src/protocols/SessionLock.cpp6
-rw-r--r--src/protocols/ShortcutsInhibit.cpp7
-rw-r--r--src/render/OpenGL.cpp3
-rw-r--r--src/render/Renderer.cpp9
-rw-r--r--src/render/decorations/CHyprGroupBarDecoration.cpp19
-rw-r--r--src/render/pass/Pass.cpp7
-rw-r--r--src/xwayland/XWM.cpp3
48 files changed, 798 insertions, 673 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 0f24a8bf..e8829fd0 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -4,6 +4,7 @@
#include "Compositor.hpp"
#include "debug/Log.hpp"
#include "desktop/DesktopTypes.hpp"
+#include "desktop/state/FocusState.hpp"
#include "helpers/Splashes.hpp"
#include "config/ConfigValue.hpp"
#include "config/ConfigWatcher.hpp"
@@ -560,9 +561,6 @@ void CCompositor::cleanup() {
// still in a normal working state.
g_pPluginSystem->unloadAllPlugins();
- m_lastFocus.reset();
- m_lastWindow.reset();
-
m_workspaces.clear();
m_windows.clear();
@@ -951,7 +949,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
if (w->m_isX11 && w->isX11OverrideRedirect() && !w->m_xwaylandSurface->wantsFocus()) {
// Override Redirect
- return g_pCompositor->m_lastWindow.lock(); // we kinda trick everything here.
+ return Desktop::focusState()->window(); // we kinda trick everything here.
// TODO: this is wrong, we should focus the parent, but idk how to get it considering it's nullptr in most cases.
}
@@ -1115,201 +1113,6 @@ PHLMONITOR CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) {
return nullptr;
}
-void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface, bool preserveFocusHistory) {
-
- static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
- static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
- static auto PMODALPARENTBLOCKING = CConfigValue<Hyprlang::INT>("general:modal_parent_blocking");
-
- if (*PMODALPARENTBLOCKING && pWindow && pWindow->m_xdgSurface && pWindow->m_xdgSurface->m_toplevel && pWindow->m_xdgSurface->m_toplevel->anyChildModal()) {
- Debug::log(LOG, "Refusing focus to window shadowed by modal dialog");
- return;
- }
-
- if (!pWindow || !pWindow->priorityFocus()) {
- if (g_pSessionLockManager->isSessionLocked()) {
- Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
- return;
- }
-
- if (!g_pInputManager->m_exclusiveLSes.empty()) {
- Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
- return;
- }
- }
-
- if (pWindow && pWindow->m_isX11 && pWindow->isX11OverrideRedirect() && !pWindow->m_xwaylandSurface->wantsFocus())
- return;
-
- g_pLayoutManager->getCurrentLayout()->bringWindowToTop(pWindow);
-
- if (!pWindow || !validMapped(pWindow)) {
-
- if (m_lastWindow.expired() && !pWindow)
- return;
-
- const auto PLASTWINDOW = m_lastWindow.lock();
- m_lastWindow.reset();
-
- if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
- PLASTWINDOW->updateDecorationValues();
-
- g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
- }
-
- g_pSeatManager->setKeyboardFocus(nullptr);
-
- g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
- g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
-
- EMIT_HOOK_EVENT("activeWindow", PHLWINDOW{nullptr});
-
- g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
-
- m_lastFocus.reset();
-
- g_pInputManager->recheckIdleInhibitorStatus();
- return;
- }
-
- if (pWindow->m_ruleApplicator->noFocus().valueOrDefault()) {
- Debug::log(LOG, "Ignoring focus to nofocus window!");
- return;
- }
-
- if (m_lastWindow.lock() == pWindow && g_pSeatManager->m_state.keyboardFocus == pSurface && g_pSeatManager->m_state.keyboardFocus)
- return;
-
- if (pWindow->m_pinned)
- pWindow->m_workspace = m_lastMonitor->m_activeWorkspace;
-
- const auto PMONITOR = pWindow->m_monitor.lock();
-
- if (!pWindow->m_workspace || !pWindow->m_workspace->isVisible()) {
- const auto PWORKSPACE = pWindow->m_workspace;
- // This is to fix incorrect feedback on the focus history.
- PWORKSPACE->m_lastFocusedWindow = pWindow;
- if (m_lastMonitor->m_activeWorkspace)
- PWORKSPACE->rememberPrevWorkspace(m_lastMonitor->m_activeWorkspace);
- if (PWORKSPACE->m_isSpecialWorkspace)
- m_lastMonitor->changeWorkspace(PWORKSPACE, false, true); // if special ws, open on current monitor
- else if (PMONITOR)
- PMONITOR->changeWorkspace(PWORKSPACE, false, true);
- // changeworkspace already calls focusWindow
- return;
- }
-
- const auto PLASTWINDOW = m_lastWindow.lock();
- m_lastWindow = pWindow;
-
- /* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which
- window focuses are "via keybinds" and which ones aren't. */
- if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace != pWindow->m_workspace && !pWindow->m_pinned && !*PSPECIALFALLTHROUGH)
- PMONITOR->setSpecialWorkspace(nullptr);
-
- // we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
- if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
- PLASTWINDOW->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FOCUS);
-
- PLASTWINDOW->updateDecorationValues();
-
- if (!pWindow->m_isX11 || !pWindow->isX11OverrideRedirect())
- g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
- }
-
- m_lastWindow = PLASTWINDOW;
-
- const auto PWINDOWSURFACE = pSurface ? pSurface : pWindow->m_wlSurface->resource();
-
- focusSurface(PWINDOWSURFACE, pWindow);
-
- g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow
-
- pWindow->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_FOCUS);
- pWindow->onFocusAnimUpdate();
-
- pWindow->updateDecorationValues();
-
- if (pWindow->m_isUrgent)
- pWindow->m_isUrgent = false;
-
- // Send an event
- g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = pWindow->m_class + "," + pWindow->m_title});
- g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(pWindow.get()))});
-
- EMIT_HOOK_EVENT("activeWindow", pWindow);
-
- g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
-
- g_pInputManager->recheckIdleInhibitorStatus();
-
- if (!preserveFocusHistory) {
- // move to front of the window history
- const auto HISTORYPIVOT = std::ranges::find_if(m_windowFocusHistory, [&](const auto& other) { return other.lock() == pWindow; });
- if (HISTORYPIVOT == m_windowFocusHistory.end())
- Debug::log(ERR, "BUG THIS: {} has no pivot in history", pWindow);
- else
- std::rotate(m_windowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1);
- }
-
- if (*PFOLLOWMOUSE == 0)
- g_pInputManager->sendMotionEventsToFocused();
-
- if (pWindow->m_groupData.pNextWindow)
- pWindow->deactivateGroupMembers();
-}
-
-void CCompositor::focusSurface(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWindowOwner) {
-
- if (g_pSeatManager->m_state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->m_state.keyboardFocus == pWindowOwner->m_wlSurface->resource()))
- return; // Don't focus when already focused on this.
-
- if (g_pSessionLockManager->isSessionLocked() && pSurface && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
- return;
-
- if (g_pSeatManager->m_seatGrab && !g_pSeatManager->m_seatGrab->accepts(pSurface)) {
- Debug::log(LOG, "surface {:x} won't receive kb focus because grab rejected it", rc<uintptr_t>(pSurface.get()));
- return;
- }
-
- const auto PLASTSURF = m_lastFocus.lock();
-
- // Unfocus last surface if should
- if (m_lastFocus && !pWindowOwner)
- g_pXWaylandManager->activateSurface(m_lastFocus.lock(), false);
-
- if (!pSurface) {
- g_pSeatManager->setKeyboardFocus(nullptr);
- g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = ","});
- g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = ""});
- EMIT_HOOK_EVENT("keyboardFocus", SP<CWLSurfaceResource>{nullptr});
- m_lastFocus.reset();
- return;
- }
-
- if (g_pSeatManager->m_keyboard)
- g_pSeatManager->setKeyboardFocus(pSurface);
-
- if (pWindowOwner)
- Debug::log(LOG, "Set keyboard focus to surface {:x}, with {}", rc<uintptr_t>(pSurface.get()), pWindowOwner);
- else
- Debug::log(LOG, "Set keyboard focus to surface {:x}", rc<uintptr_t>(pSurface.get()));
-
- g_pXWaylandManager->activateSurface(pSurface, true);
- m_lastFocus = pSurface;
-
- EMIT_HOOK_EVENT("keyboardFocus", pSurface);
-
- const auto SURF = CWLSurface::fromResource(pSurface);
- const auto OLDSURF = CWLSurface::fromResource(PLASTSURF);
-
- if (OLDSURF && OLDSURF->constraint())
- OLDSURF->constraint()->deactivate();
-
- if (SURF && SURF->constraint())
- SURF->constraint()->activate();
-}
-
SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, PHLMONITOR monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
for (auto const& lsl : monitor->m_layerSurfaceLayers | std::views::reverse) {
for (auto const& ls : lsl | std::views::reverse) {
@@ -1390,7 +1193,7 @@ PHLWINDOW CCompositor::getUrgentWindow() {
}
bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
- if (m_lastWindow.expired() && !m_lastFocus)
+ if (!Desktop::focusState()->window() && !Desktop::focusState()->surface())
return false;
if (!pWindow->m_isMapped)
@@ -1398,7 +1201,7 @@ bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
const auto PSURFACE = pWindow->m_wlSurface->resource();
- return PSURFACE == m_lastFocus || pWindow == m_lastWindow.lock();
+ return PSURFACE == Desktop::focusState()->surface() || pWindow == Desktop::focusState()->window();
}
void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) {
@@ -1626,15 +1429,16 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
if (intersectLength > 0) {
// get idx
- int windowIDX = -1;
- for (size_t i = 0; i < g_pCompositor->m_windowFocusHistory.size(); ++i) {
- if (g_pCompositor->m_windowFocusHistory[i].lock() == w) {
+ int windowIDX = -1;
+ const auto& HISTORY = Desktop::focusState()->windowHistory();
+ for (size_t i = 0; i < HISTORY.size(); ++i) {
+ if (HISTORY[i] == w) {
windowIDX = i;
break;
}
}
- windowIDX = g_pCompositor->m_windowFocusHistory.size() - windowIDX;
+ windowIDX = Desktop::focusState()->windowHistory().size() - windowIDX;
if (windowIDX > leaderValue) {
leaderValue = windowIDX;
@@ -1739,8 +1543,10 @@ static PHLWINDOW getWeakWindowPred(Iterator cur, Iterator end, Iterator begin, c
PHLWINDOW CCompositor::getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly, std::optional<bool> floating, bool visible, bool next) {
const auto FINDER = [&](const PHLWINDOWREF& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); };
// also m_vWindowFocusHistory has reverse order, so when it is next - we need to reverse again
- return next ? getWeakWindowPred(std::ranges::find(m_windowFocusHistory | std::views::reverse, cur), m_windowFocusHistory.rend(), m_windowFocusHistory.rbegin(), FINDER) :
- getWeakWindowPred(std::ranges::find(m_windowFocusHistory, cur), m_windowFocusHistory.end(), m_windowFocusHistory.begin(), FINDER);
+ return next ? getWeakWindowPred(std::ranges::find(Desktop::focusState()->windowHistory() | std::views::reverse, cur), Desktop::focusState()->windowHistory().rend(),
+ Desktop::focusState()->windowHistory().rbegin(), FINDER) :
+ getWeakWindowPred(std::ranges::find(Desktop::focusState()->windowHistory(), cur), Desktop::focusState()->windowHistory().end(),
+ Desktop::focusState()->windowHistory().begin(), FINDER);
}
PHLWINDOW CCompositor::getWindowCycle(PHLWINDOW cur, bool focusableOnly, std::optional<bool> floating, bool visible, bool prev) {
@@ -1834,7 +1640,7 @@ CBox CCompositor::calculateX11WorkArea() {
}
PHLMONITOR CCompositor::getMonitorInDirection(const char& dir) {
- return getMonitorInDirection(m_lastMonitor.lock(), dir);
+ return getMonitorInDirection(Desktop::focusState()->monitor(), dir);
}
PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const char& dir) {
@@ -1997,12 +1803,12 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
PWORKSPACEA, PWORKSPACEA->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
- if (pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id || pMonitorB->m_id == g_pCompositor->m_lastMonitor->m_id) {
- const auto LASTWIN = pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow();
- g_pCompositor->focusWindow(LASTWIN ? LASTWIN :
- (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING)));
+ if (pMonitorA->m_id == Desktop::focusState()->monitor()->m_id || pMonitorB->m_id == Desktop::focusState()->monitor()->m_id) {
+ const auto LASTWIN = pMonitorA->m_id == Desktop::focusState()->monitor()->m_id ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow();
+ Desktop::focusState()->fullWindowFocus(
+ LASTWIN ? LASTWIN : (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING)));
- const auto PNEWWORKSPACE = pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id ? PWORKSPACEB : PWORKSPACEA;
+ const auto PNEWWORKSPACE = pMonitorA->m_id == Desktop::focusState()->monitor()->m_id ? PWORKSPACEB : PWORKSPACEA;
g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspace", .data = PNEWWORKSPACE->m_name});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspacev2", .data = std::format("{},{}", PNEWWORKSPACE->m_id, PNEWWORKSPACE->m_name)});
EMIT_HOOK_EVENT("workspace", PNEWWORKSPACE);
@@ -2020,7 +1826,7 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
if (name == "current")
- return g_pCompositor->m_lastMonitor.lock();
+ return Desktop::focusState()->monitor();
else if (isDirection(name))
return getMonitorInDirection(name[0]);
else if (name[0] == '+' || name[0] == '-') {
@@ -2041,7 +1847,7 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
int currentPlace = 0;
for (int i = 0; i < sc<int>(m_monitors.size()); i++) {
- if (m_monitors[i] == m_lastMonitor) {
+ if (m_monitors[i] == Desktop::focusState()->monitor()) {
currentPlace = i;
break;
}
@@ -2175,7 +1981,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
}
}
- if (SWITCHINGISACTIVE && POLDMON == g_pCompositor->m_lastMonitor) { // if it was active, preserve its' status. If it wasn't, don't.
+ if (SWITCHINGISACTIVE && POLDMON == Desktop::focusState()->monitor()) { // if it was active, preserve its' status. If it wasn't, don't.
Debug::log(LOG, "moveWorkspaceToMonitor: SWITCHINGISACTIVE, active {} -> {}", pMonitor->activeWorkspaceID(), pWorkspace->m_id);
if (valid(pMonitor->m_activeWorkspace)) {
@@ -2186,7 +1992,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
if (*PHIDESPECIALONWORKSPACECHANGE)
pMonitor->setSpecialWorkspace(nullptr);
- setActiveMonitor(pMonitor);
+ Desktop::focusState()->rawMonitorFocus(pMonitor);
auto oldWorkspace = pMonitor->m_activeWorkspace;
pMonitor->m_activeWorkspace = pWorkspace;
@@ -2247,6 +2053,7 @@ void CCompositor::changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, cons
sc<eFullscreenMode>(ON ? sc<uint8_t>(PWINDOW->m_fullscreenState.client) | sc<uint8_t>(MODE) : (sc<uint8_t>(PWINDOW->m_fullscreenState.client) & sc<uint8_t>(~MODE))));
}
+// TODO: move fs functions to Desktop::
void CCompositor::setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE) {
if (PWINDOW->m_ruleApplicator->syncFullscreen().valueOrDefault())
setWindowFullscreenState(PWINDOW, SFullscreenState{.internal = MODE, .client = MODE});
@@ -2387,16 +2194,16 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) {
auto regexp = trim(regexp_);
if (regexp.starts_with("active"))
- return m_lastWindow.lock();
+ return Desktop::focusState()->window();
else if (regexp.starts_with("floating") || regexp.starts_with("tiled")) {
// first floating on the current ws
- if (!valid(m_lastWindow))
+ if (!Desktop::focusState()->window())
return nullptr;
const bool FLOAT = regexp.starts_with("floating");
for (auto const& w : m_windows) {
- if (!w->m_isMapped || w->m_isFloating != FLOAT || w->m_workspace != m_lastWindow->m_workspace || w->isHidden())
+ if (!w->m_isMapped || w->m_isFloating != FLOAT || w->m_workspace != Desktop::focusState()->window()->m_workspace || w->isHidden())
continue;
return w;
@@ -2502,16 +2309,14 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
if (*PNOWARPS && !force) {
const auto PMONITORNEW = getMonitorFromVector(pos);
- if (PMONITORNEW != m_lastMonitor)
- setActiveMonitor(PMONITORNEW);
+ Desktop::focusState()->rawMonitorFocus(PMONITORNEW);
return;
}
g_pPointerManager->warpTo(pos);
const auto PMONITORNEW = getMonitorFromVector(pos);
- if (PMONITORNEW != m_lastMonitor)
- setActiveMonitor(PMONITORNEW);
+ Desktop::focusState()->rawMonitorFocus(PMONITORNEW);
}
void CCompositor::closeWindow(PHLWINDOW pWindow) {
@@ -2550,7 +2355,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con
if (!args.contains(' ') && !args.contains('\t'))
return relativeTo;
- const auto PMONITOR = m_lastMonitor;
+ const auto PMONITOR = Desktop::focusState()->monitor();
bool xIsPercent = false;
bool yIsPercent = false;
@@ -2618,27 +2423,6 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITO
return PWORKSPACE;
}
-void CCompositor::setActiveMonitor(PHLMONITOR pMonitor) {
- if (m_lastMonitor == pMonitor)
- return;
-
- if (!pMonitor) {
- m_lastMonitor.reset();
- return;
- }
-
- const auto PWORKSPACE = pMonitor->m_activeWorkspace;
-
- const auto WORKSPACE_ID = PWORKSPACE ? std::to_string(PWORKSPACE->m_id) : std::to_string(WORKSPACE_INVALID);
- const auto WORKSPACE_NAME = PWORKSPACE ? PWORKSPACE->m_name : "?";
-
- g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmon", .data = pMonitor->m_name + "," + WORKSPACE_NAME});
- g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmonv2", .data = pMonitor->m_name + "," + WORKSPACE_ID});
-
- EMIT_HOOK_EVENT("focusedMon", pMonitor);
- m_lastMonitor = pMonitor->m_self;
-}
-
bool CCompositor::isWorkspaceSpecial(const WORKSPACEID& id) {
return id >= SPECIAL_WORKSPACE_START && id <= -2;
}
@@ -2952,7 +2736,7 @@ void CCompositor::enterUnsafeState() {
m_unsafeState = true;
- setActiveMonitor(m_unsafeOutput.lock());
+ Desktop::focusState()->rawMonitorFocus(m_unsafeOutput.lock());
}
void CCompositor::leaveUnsafeState() {
@@ -3116,7 +2900,7 @@ bool CCompositor::shouldChangePreferredImageDescription() {
}
void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules, PHLWORKSPACE pWorkspace) {
- if (!m_lastMonitor)
+ if (!Desktop::focusState()->monitor())
return;
std::vector<PHLWORKSPACE> persistentFound;
@@ -3154,7 +2938,7 @@ void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspace
}
PWORKSPACE = getWorkspaceByID(id);
if (!PMONITOR)
- PMONITOR = m_lastMonitor.lock();
+ PMONITOR = Desktop::focusState()->monitor();
if (!PWORKSPACE)
PWORKSPACE = createNewWorkspace(id, PMONITOR->m_id, wsname, false);
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index 30b0f1bd..3e1e37f2 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -66,12 +66,6 @@ class CCompositor {
void bumpNofile();
void restoreNofile();
- WP<CWLSurfaceResource> m_lastFocus;
- PHLWINDOWREF m_lastWindow;
- PHLMONITORREF m_lastMonitor;
-
- std::vector<PHLWINDOWREF> m_windowFocusHistory; // first element is the most recently focused
-
bool m_readyToProcess = false;
bool m_sessionActive = true;
bool m_dpmsStateOn = true;
@@ -99,8 +93,6 @@ class CCompositor {
PHLMONITOR getMonitorFromCursor();
PHLMONITOR getMonitorFromVector(const Vector2D&);
void removeWindowFromVectorSafe(PHLWINDOW);
- void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr, bool preserveFocusHistory = false);
- void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
bool monitorExists(PHLMONITOR);
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*, bool aboveLockscreen = false);
@@ -150,7 +142,6 @@ class CCompositor {
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
[[nodiscard]] PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
bool isEmpty = true); // will be deleted next frame if left empty and unfocused!
- void setActiveMonitor(PHLMONITOR);
bool isWorkspaceSpecial(const WORKSPACEID&);
WORKSPACEID getNewSpecialID();
void performUserChecks();
diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp
index 78e86e17..6ef7c263 100644
--- a/src/config/ConfigDescriptions.hpp
+++ b/src/config/ConfigDescriptions.hpp
@@ -1279,11 +1279,11 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.data = SConfigOptionDescription::SBoolData{true},
},
SConfigOptionDescription{
- .value = "misc:new_window_takes_over_fullscreen",
- .description = "if there is a fullscreen or maximized window, decide whether a new tiled window opened should replace it, stay behind or disable the fullscreen/maximized "
- "state. 0 - behind, 1 - takes over, 2 - unfullscreen/unmaxize [0/1/2]",
+ .value = "misc:on_focus_under_fullscreen",
+ .description = "if there is a fullscreen or maximized window, decide whether a tiled window requested to focus should replace it, stay behind or disable the "
+ "fullscreen/maximized state. 0 - ignore focus request (keep focus on fullscreen window), 1 - takes over, 2 - unfullscreen/unmaximize [0/1/2]",
.type = CONFIG_OPTION_INT,
- .data = SConfigOptionDescription::SRangeData{0, 0, 2},
+ .data = SConfigOptionDescription::SRangeData{2, 0, 2},
},
SConfigOptionDescription{
.value = "misc:exit_window_retains_fullscreen",
@@ -1947,12 +1947,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.data = SConfigOptionDescription::SStringData{"left"},
},
SConfigOptionDescription{
- .value = "master:inherit_fullscreen",
- .description = "inherit fullscreen status when cycling/swapping to another window (e.g. monocle layout)",
- .type = CONFIG_OPTION_BOOL,
- .data = SConfigOptionDescription::SBoolData{true},
- },
- SConfigOptionDescription{
.value = "master:slave_count_for_center_master",
.description = "when using orientation=center, make the master window centered only when at least this many slave windows are open. (Set 0 to always_center_master)",
.type = CONFIG_OPTION_INT,
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index fc020d7a..b077988b 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -17,6 +17,7 @@
#include "../desktop/rule/windowRule/WindowRule.hpp"
#include "../desktop/rule/layerRule/LayerRule.hpp"
#include "../debug/HyprCtl.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "defaultConfig.hpp"
#include "../render/Renderer.hpp"
@@ -490,7 +491,7 @@ CConfigManager::CConfigManager() {
registerConfigVar("misc:session_lock_xray", Hyprlang::INT{0});
registerConfigVar("misc:close_special_on_empty", Hyprlang::INT{1});
registerConfigVar("misc:background_color", Hyprlang::INT{0xff111111});
- registerConfigVar("misc:new_window_takes_over_fullscreen", Hyprlang::INT{0});
+ registerConfigVar("misc:on_focus_under_fullscreen", Hyprlang::INT{2});
registerConfigVar("misc:exit_window_retains_fullscreen", Hyprlang::INT{0});
registerConfigVar("misc:initial_workspace_tracking", Hyprlang::INT{1});
registerConfigVar("misc:middle_click_paste", Hyprlang::INT{1});
@@ -619,7 +620,6 @@ CConfigManager::CConfigManager() {
registerConfigVar("master:new_on_active", {"none"});
registerConfigVar("master:new_on_top", Hyprlang::INT{0});
registerConfigVar("master:orientation", {"left"});
- registerConfigVar("master:inherit_fullscreen", Hyprlang::INT{1});
registerConfigVar("master:allow_small_split", Hyprlang::INT{0});
registerConfigVar("master:smart_resizing", Hyprlang::INT{1});
registerConfigVar("master:drop_at_cursor", Hyprlang::INT{1});
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index 505bc190..dc5be6ce 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -45,6 +45,7 @@ using namespace Hyprutils::OS;
#include "helpers/MiscFunctions.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../desktop/rule/Engine.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../version.h"
#include "../Compositor.hpp"
@@ -255,12 +256,12 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
sc<int>(m->m_output->physicalSize.y), m->m_refreshRate, sc<int>(m->m_position.x), sc<int>(m->m_position.y), m->activeWorkspaceID(),
(!m->m_activeWorkspace ? "" : escapeJSONStrings(m->m_activeWorkspace->m_name)), m->activeSpecialWorkspaceID(),
escapeJSONStrings(m->m_activeSpecialWorkspace ? m->m_activeSpecialWorkspace->m_name : ""), sc<int>(m->m_reservedTopLeft.x), sc<int>(m->m_reservedTopLeft.y),
- sc<int>(m->m_reservedBottomRight.x), sc<int>(m->m_reservedBottomRight.y), m->m_scale, sc<int>(m->m_transform), (m == g_pCompositor->m_lastMonitor ? "true" : "false"),
- (m->m_dpmsStatus ? "true" : "false"), (m->m_output->state->state().adaptiveSync ? "true" : "false"), rc<uint64_t>(m->m_solitaryClient.get()),
- getSolitaryBlockedReason(m, format), (m->m_tearingState.activelyTearing ? "true" : "false"), getTearingBlockedReason(m, format), rc<uint64_t>(m->m_lastScanout.get()),
- getDSBlockedReason(m, format), (m->m_enabled ? "false" : "true"), formatToString(m->m_output->state->state().drmFormat),
- m->m_mirrorOf ? std::format("{}", m->m_mirrorOf->m_id) : "none", availableModesForOutput(m, format), (NCMType::toString(m->m_cmType)), (m->m_sdrBrightness),
- (m->m_sdrSaturation), (m->m_sdrMinLuminance), (m->m_sdrMaxLuminance));
+ sc<int>(m->m_reservedBottomRight.x), sc<int>(m->m_reservedBottomRight.y), m->m_scale, sc<int>(m->m_transform),
+ (m == Desktop::focusState()->monitor() ? "true" : "false"), (m->m_dpmsStatus ? "true" : "false"), (m->m_output->state->state().adaptiveSync ? "true" : "false"),
+ rc<uint64_t>(m->m_solitaryClient.get()), getSolitaryBlockedReason(m, format), (m->m_tearingState.activelyTearing ? "true" : "false"),
+ getTearingBlockedReason(m, format), rc<uint64_t>(m->m_lastScanout.get()), getDSBlockedReason(m, format), (m->m_enabled ? "false" : "true"),
+ formatToString(m->m_output->state->state().drmFormat), m->m_mirrorOf ? std::format("{}", m->m_mirrorOf->m_id) : "none", availableModesForOutput(m, format),
+ (NCMType::toString(m->m_cmType)), (m->m_sdrBrightness), (m->m_sdrSaturation), (m->m_sdrMinLuminance), (m->m_sdrMaxLuminance));
} else {
result += std::format(
@@ -274,7 +275,7 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
m->m_output->make, m->m_output->model, sc<int>(m->m_output->physicalSize.x), sc<int>(m->m_output->physicalSize.y), m->m_output->serial, m->activeWorkspaceID(),
(!m->m_activeWorkspace ? "" : m->m_activeWorkspace->m_name), m->activeSpecialWorkspaceID(), (m->m_activeSpecialWorkspace ? m->m_activeSpecialWorkspace->m_name : ""),
sc<int>(m->m_reservedTopLeft.x), sc<int>(m->m_reservedTopLeft.y), sc<int>(m->m_reservedBottomRight.x), sc<int>(m->m_reservedBottomRight.y), m->m_scale,
- sc<int>(m->m_transform), (m == g_pCompositor->m_lastMonitor ? "yes" : "no"), sc<int>(m->m_dpmsStatus), m->m_output->state->state().adaptiveSync,
+ sc<int>(m->m_transform), (m == Desktop::focusState()->monitor() ? "yes" : "no"), sc<int>(m->m_dpmsStatus), m->m_output->state->state().adaptiveSync,
rc<uint64_t>(m->m_solitaryClient.get()), getSolitaryBlockedReason(m, format), m->m_tearingState.activelyTearing, getTearingBlockedReason(m, format),
rc<uint64_t>(m->m_lastScanout.get()), getDSBlockedReason(m, format), !m->m_enabled, formatToString(m->m_output->state->state().drmFormat),
m->m_mirrorOf ? std::format("{}", m->m_mirrorOf->m_id) : "none", availableModesForOutput(m, format), (NCMType::toString(m->m_cmType)), (m->m_sdrBrightness),
@@ -353,8 +354,8 @@ static std::string getGroupedData(PHLWINDOW w, eHyprCtlOutputFormat format) {
std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
auto getFocusHistoryID = [](PHLWINDOW wnd) -> int {
- for (size_t i = 0; i < g_pCompositor->m_windowFocusHistory.size(); ++i) {
- if (g_pCompositor->m_windowFocusHistory[i].lock() == wnd)
+ for (size_t i = 0; i < Desktop::focusState()->windowHistory().size(); ++i) {
+ if (Desktop::focusState()->windowHistory()[i].lock() == wnd)
return i;
}
return -1;
@@ -524,11 +525,11 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF
}
static std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string request) {
- if (!g_pCompositor->m_lastMonitor)
+ if (!Desktop::focusState()->monitor())
return "unsafe state";
std::string result = "";
- auto w = g_pCompositor->m_lastMonitor->m_activeWorkspace;
+ auto w = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!valid(w))
return "internal error";
@@ -578,7 +579,7 @@ static std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::strin
}
static std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string request) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!validMapped(PWINDOW))
return format == eHyprCtlOutputFormat::FORMAT_JSON ? "{}" : "Invalid";
diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp
index ce967446..8f4189b0 100644
--- a/src/debug/HyprDebugOverlay.cpp
+++ b/src/debug/HyprDebugOverlay.cpp
@@ -5,6 +5,7 @@
#include "../render/pass/TexPassElement.hpp"
#include "../render/Renderer.hpp"
#include "../managers/animation/AnimationManager.hpp"
+#include "../desktop/state/FocusState.hpp"
CHyprDebugOverlay::CHyprDebugOverlay() {
m_texture = makeShared<CTexture>();
@@ -57,7 +58,7 @@ void CHyprMonitorDebugOverlay::frameData(PHLMONITOR pMonitor) {
m_monitor = pMonitor;
// anim data too
- const auto PMONITORFORTICKS = g_pHyprRenderer->m_mostHzMonitor ? g_pHyprRenderer->m_mostHzMonitor.lock() : g_pCompositor->m_lastMonitor.lock();
+ const auto PMONITORFORTICKS = g_pHyprRenderer->m_mostHzMonitor ? g_pHyprRenderer->m_mostHzMonitor.lock() : Desktop::focusState()->monitor();
if (PMONITORFORTICKS == pMonitor) {
if (m_lastAnimationTicks.size() > sc<long unsigned int>(PMONITORFORTICKS->m_refreshRate))
m_lastAnimationTicks.pop_front();
diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp
index aab0b15a..4f08bff6 100644
--- a/src/desktop/LayerSurface.cpp
+++ b/src/desktop/LayerSurface.cpp
@@ -1,4 +1,5 @@
#include "LayerSurface.hpp"
+#include "state/FocusState.hpp"
#include "../Compositor.hpp"
#include "../events/Events.hpp"
#include "../protocols/LayerShell.hpp"
@@ -16,7 +17,7 @@
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
- auto pMonitor = resource->m_monitor.empty() ? g_pCompositor->m_lastMonitor.lock() : g_pCompositor->getMonitorFromName(resource->m_monitor);
+ auto pMonitor = resource->m_monitor.empty() ? Desktop::focusState()->monitor() : g_pCompositor->getMonitorFromName(resource->m_monitor);
pLS->m_surface->assign(resource->m_surface.lock(), pLS);
@@ -173,7 +174,7 @@ void CLayerSurface::onMap() {
g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
- g_pCompositor->focusSurface(m_surface->resource());
+ Desktop::focusState()->rawSurfaceFocus(m_surface->resource());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y);
g_pSeatManager->setPointerFocus(m_surface->resource(), LOCAL);
@@ -244,11 +245,12 @@ void CLayerSurface::onUnmap() {
// refocus if needed
// vvvvvvvvvvvvv if there is a last focus and the last focus is not keyboard focusable, fallback to window
- if (WASLASTFOCUS || (g_pCompositor->m_lastFocus && g_pCompositor->m_lastFocus->m_hlSurface && !g_pCompositor->m_lastFocus->m_hlSurface->keyboardFocusable())) {
+ if (WASLASTFOCUS ||
+ (Desktop::focusState()->surface() && Desktop::focusState()->surface()->m_hlSurface && !Desktop::focusState()->surface()->m_hlSurface->keyboardFocusable())) {
if (!g_pInputManager->refocusLastWindow(PMONITOR))
g_pInputManager->refocus();
- } else if (g_pCompositor->m_lastFocus && g_pCompositor->m_lastFocus != m_surface->resource())
- g_pSeatManager->setKeyboardFocus(g_pCompositor->m_lastFocus.lock());
+ } else if (Desktop::focusState()->surface() && Desktop::focusState()->surface() != m_surface->resource())
+ g_pSeatManager->setKeyboardFocus(Desktop::focusState()->surface());
CBox geomFixed = {m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y, m_geometry.width, m_geometry.height};
g_pHyprRenderer->damageBox(geomFixed);
@@ -374,7 +376,7 @@ void CLayerSurface::onCommit() {
if (WASLASTFOCUS && m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
// moveMouseUnified won't focus non interactive layers but it won't unfocus them either,
// so unfocus the surface here.
- g_pCompositor->focusSurface(nullptr);
+ Desktop::focusState()->rawSurfaceFocus(nullptr);
g_pInputManager->refocusLastWindow(m_monitor.lock());
} else if (WASLASTFOCUS && WASEXCLUSIVE && m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
g_pInputManager->simulateMouseMovement();
@@ -382,7 +384,7 @@ void CLayerSurface::onCommit() {
// if now exclusive and not previously
g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
- g_pCompositor->focusSurface(m_surface->resource());
+ Desktop::focusState()->rawSurfaceFocus(m_surface->resource());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y);
g_pSeatManager->setPointerFocus(m_surface->resource(), LOCAL);
diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp
index ba7340f1..cea6977a 100644
--- a/src/desktop/Subsurface.cpp
+++ b/src/desktop/Subsurface.cpp
@@ -1,6 +1,7 @@
#include "Subsurface.hpp"
#include "../events/Events.hpp"
-#include "../Compositor.hpp"
+#include "../desktop/state/FocusState.hpp"
+#include "../desktop/Window.hpp"
#include "../config/ConfigValue.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../protocols/core/Subcompositor.hpp"
@@ -163,7 +164,7 @@ void CSubsurface::onMap() {
void CSubsurface::onUnmap() {
damageLastArea();
- if (m_wlSurface->resource() == g_pCompositor->m_lastFocus)
+ if (m_wlSurface->resource() == Desktop::focusState()->surface())
g_pInputManager->releaseAllMouseButtons();
g_pInputManager->simulateMouseMovement();
diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp
index 6a602748..706d21cc 100644
--- a/src/desktop/Window.cpp
+++ b/src/desktop/Window.cpp
@@ -7,6 +7,7 @@
#include <bit>
#include <string_view>
#include "Window.hpp"
+#include "state/FocusState.hpp"
#include "../Compositor.hpp"
#include "../render/decorations/CHyprDropShadowDecoration.hpp"
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
@@ -121,9 +122,9 @@ CWindow::CWindow(SP<CXWaylandSurface> surface) : m_xwaylandSurface(surface) {
}
CWindow::~CWindow() {
- if (g_pCompositor->m_lastWindow == m_self) {
- g_pCompositor->m_lastFocus.reset();
- g_pCompositor->m_lastWindow.reset();
+ if (Desktop::focusState()->window() == m_self) {
+ Desktop::focusState()->surface().reset();
+ Desktop::focusState()->window().reset();
}
m_events.destroy.emit();
@@ -528,8 +529,6 @@ void CWindow::onUnmap() {
if (m_workspace->m_isSpecialWorkspace && m_workspace->getWindows() == 0)
m_lastWorkspace = m_monitor->activeWorkspaceID();
- std::erase_if(g_pCompositor->m_windowFocusHistory, [this](const auto& other) { return other.expired() || other == m_self; });
-
if (*PCLOSEONLASTSPECIAL && m_workspace && m_workspace->getWindows() == 0 && onSpecialWorkspace()) {
const auto PMONITOR = m_monitor.lock();
if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace == m_workspace)
@@ -594,8 +593,6 @@ void CWindow::onMap() {
m_movingFromWorkspaceAlpha->setValueAndWarp(1.F);
- g_pCompositor->m_windowFocusHistory.push_back(m_self);
-
m_reportedSize = m_pendingReportedSize;
m_animatingIn = true;
@@ -629,8 +626,8 @@ void CWindow::onBorderAngleAnimEnd(WP<CBaseAnimatedVariable> pav) {
void CWindow::setHidden(bool hidden) {
m_hidden = hidden;
- if (hidden && g_pCompositor->m_lastWindow == m_self)
- g_pCompositor->m_lastWindow.reset();
+ if (hidden && Desktop::focusState()->window() == m_self)
+ Desktop::focusState()->window().reset();
setSuspended(hidden);
}
@@ -862,7 +859,7 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
const auto WORKSPACE = PCURRENT->m_workspace;
const auto MODE = PCURRENT->m_fullscreenState.internal;
- const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_lastWindow.lock();
+ const auto CURRENTISFOCUS = PCURRENT == Desktop::focusState()->window();
const auto PWINDOWSIZE = PCURRENT->m_realSize->value();
const auto PWINDOWPOS = PCURRENT->m_realPosition->value();
@@ -897,7 +894,7 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
if (CURRENTISFOCUS)
- g_pCompositor->focusWindow(pWindow);
+ Desktop::focusState()->rawWindowFocus(pWindow);
g_pHyprRenderer->damageWindow(pWindow);
@@ -1240,7 +1237,7 @@ std::unordered_map<std::string, std::string> CWindow::getEnv() {
}
void CWindow::activate(bool force) {
- if (g_pCompositor->m_lastWindow == m_self)
+ if (Desktop::focusState()->window() == m_self)
return;
static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
@@ -1262,7 +1259,7 @@ void CWindow::activate(bool force) {
if (m_isFloating)
g_pCompositor->changeWindowZOrder(m_self.lock(), true);
- g_pCompositor->focusWindow(m_self.lock());
+ Desktop::focusState()->fullWindowFocus(m_self.lock());
warpCursor();
}
@@ -1276,7 +1273,7 @@ void CWindow::onUpdateState() {
if (m_isMapped) {
const auto monitor = g_pCompositor->getMonitorFromID(requestsID.value());
g_pCompositor->moveWindowToWorkspaceSafe(m_self.lock(), monitor->m_activeWorkspace);
- g_pCompositor->setActiveMonitor(monitor);
+ Desktop::focusState()->rawMonitorFocus(monitor);
}
if (!m_isMapped)
@@ -1311,7 +1308,7 @@ void CWindow::onUpdateMeta() {
g_pEventManager->postEvent(SHyprIPCEvent{.event = "windowtitlev2", .data = std::format("{:x},{}", rc<uintptr_t>(this), m_title)});
EMIT_HOOK_EVENT("windowTitle", m_self.lock());
- if (m_self == g_pCompositor->m_lastWindow) { // if it's the active, let's post an event to update others
+ if (m_self == Desktop::focusState()->window()) { // if it's the active, let's post an event to update others
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = m_class + "," + m_title});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(this))});
EMIT_HOOK_EVENT("activeWindow", m_self.lock());
@@ -1325,7 +1322,7 @@ void CWindow::onUpdateMeta() {
if (m_class != NEWCLASS) {
m_class = NEWCLASS;
- if (m_self == g_pCompositor->m_lastWindow) { // if it's the active, let's post an event to update others
+ if (m_self == Desktop::focusState()->window()) { // if it's the active, let's post an event to update others
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = m_class + "," + m_title});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(this))});
EMIT_HOOK_EVENT("activeWindow", m_self.lock());
@@ -1502,7 +1499,7 @@ PHLWINDOW CWindow::getSwallower() {
return candidates[0];
// walk up the focus history and find the last focused
- for (auto const& w : g_pCompositor->m_windowFocusHistory) {
+ for (auto const& w : Desktop::focusState()->windowHistory()) {
if (!w)
continue;
@@ -1781,7 +1778,7 @@ void CWindow::updateDecorationValues() {
setBorderColor(*RENDERDATA.borderGradient);
else {
const bool GROUPLOCKED = m_groupData.pNextWindow.lock() ? getGroupHead()->m_groupData.locked : false;
- if (m_self == g_pCompositor->m_lastWindow) {
+ if (m_self == Desktop::focusState()->window()) {
const auto* const ACTIVECOLOR =
!m_groupData.pNextWindow.lock() ? (!m_groupData.deny ? ACTIVECOL : NOGROUPACTIVECOL) : (GROUPLOCKED ? GROUPACTIVELOCKEDCOL : GROUPACTIVECOL);
setBorderColor(m_ruleApplicator->activeBorderColor().valueOr(*ACTIVECOLOR));
@@ -1797,7 +1794,7 @@ void CWindow::updateDecorationValues() {
if (isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) {
*m_activeInactiveAlpha = m_ruleApplicator->alphaFullscreen().valueOrDefault().applyAlpha(*PFULLSCREENALPHA);
} else {
- if (m_self == g_pCompositor->m_lastWindow)
+ if (m_self == Desktop::focusState()->window())
*m_activeInactiveAlpha = m_ruleApplicator->alpha().valueOrDefault().applyAlpha(*PACTIVEALPHA);
else
*m_activeInactiveAlpha = m_ruleApplicator->alphaInactive().valueOrDefault().applyAlpha(*PINACTIVEALPHA);
@@ -1805,7 +1802,7 @@ void CWindow::updateDecorationValues() {
// dim
float goalDim = 1.F;
- if (m_self == g_pCompositor->m_lastWindow.lock() || m_ruleApplicator->noDim().valueOrDefault() || !*PDIMENABLED)
+ if (m_self == Desktop::focusState()->window() || m_ruleApplicator->noDim().valueOrDefault() || !*PDIMENABLED)
goalDim = 0;
else
goalDim = *PDIMSTRENGTH;
@@ -1817,7 +1814,7 @@ void CWindow::updateDecorationValues() {
// shadow
if (!isX11OverrideRedirect() && !m_X11DoesntWantBorders) {
- if (m_self == g_pCompositor->m_lastWindow)
+ if (m_self == Desktop::focusState()->window())
*m_realShadowColor = CHyprColor(*PSHADOWCOL);
else
*m_realShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != -1 ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
@@ -1828,7 +1825,7 @@ void CWindow::updateDecorationValues() {
}
std::optional<double> CWindow::calculateSingleExpr(const std::string& s) {
- const auto PMONITOR = m_monitor ? m_monitor : g_pCompositor->m_lastMonitor;
+ const auto PMONITOR = m_monitor ? m_monitor : Desktop::focusState()->monitor();
const auto CURSOR_LOCAL = g_pInputManager->getMouseCoordsInternal() - (PMONITOR ? PMONITOR->m_position : Vector2D{});
Math::CExpression expr;
diff --git a/src/desktop/rule/windowRule/WindowRule.cpp b/src/desktop/rule/windowRule/WindowRule.cpp
index 6a6878d2..893243b0 100644
--- a/src/desktop/rule/windowRule/WindowRule.cpp
+++ b/src/desktop/rule/windowRule/WindowRule.cpp
@@ -3,6 +3,7 @@
#include "../../../helpers/Monitor.hpp"
#include "../../../Compositor.hpp"
#include "../../../managers/TokenManager.hpp"
+#include "../../../desktop/state/FocusState.hpp"
using namespace Desktop;
using namespace Desktop::Rule;
@@ -72,7 +73,7 @@ bool CWindowRule::matches(PHLWINDOW w, bool allowEnvLookup) {
return false;
break;
case RULE_PROP_FOCUS:
- if (!engine->match(g_pCompositor->m_lastWindow == w))
+ if (!engine->match(Desktop::focusState()->window() == w))
return false;
break;
case RULE_PROP_GROUP:
diff --git a/src/desktop/state/FocusState.cpp b/src/desktop/state/FocusState.cpp
new file mode 100644
index 00000000..8908d3de
--- /dev/null
+++ b/src/desktop/state/FocusState.cpp
@@ -0,0 +1,330 @@
+#include "FocusState.hpp"
+#include "../Window.hpp"
+#include "../../Compositor.hpp"
+#include "../../protocols/XDGShell.hpp"
+#include "../../render/Renderer.hpp"
+#include "../../managers/LayoutManager.hpp"
+#include "../../managers/EventManager.hpp"
+#include "../../managers/HookSystemManager.hpp"
+#include "../../xwayland/XSurface.hpp"
+#include "../../protocols/PointerConstraints.hpp"
+
+using namespace Desktop;
+
+SP<CFocusState> Desktop::focusState() {
+ static SP<CFocusState> state = makeShared<CFocusState>();
+ return state;
+}
+
+Desktop::CFocusState::CFocusState() {
+ m_windowOpen = g_pHookSystem->hookDynamic("openWindowEarly", [this](void* self, SCallbackInfo& info, std::any data) {
+ auto window = std::any_cast<PHLWINDOW>(data);
+
+ addWindowToHistory(window);
+ });
+
+ m_windowClose = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
+ auto window = std::any_cast<PHLWINDOW>(data);
+
+ removeWindowFromHistory(window);
+ });
+}
+
+struct SFullscreenWorkspaceFocusResult {
+ PHLWINDOW overrideFocusWindow = nullptr;
+};
+
+static SFullscreenWorkspaceFocusResult onFullscreenWorkspaceFocusWindow(PHLWINDOW pWindow, bool forceFSCycle) {
+ const auto FSWINDOW = pWindow->m_workspace->getFullscreenWindow();
+ const auto FSMODE = pWindow->m_workspace->m_fullscreenMode;
+
+ if (pWindow == FSWINDOW)
+ return {}; // no conflict
+
+ if (pWindow->m_isFloating) {
+ // if the window is floating, just bring it to the top
+ pWindow->m_createdOverFullscreen = true;
+ g_pHyprRenderer->damageWindow(pWindow);
+ return {};
+ }
+
+ static auto PONFOCUSUNDERFS = CConfigValue<Hyprlang::INT>("misc:on_focus_under_fullscreen");
+
+ switch (*PONFOCUSUNDERFS) {
+ case 0:
+ // focus the fullscreen window instead
+ return {.overrideFocusWindow = FSWINDOW};
+ case 2:
+ // undo fs, unless we force a cycle
+ if (!forceFSCycle) {
+ g_pCompositor->setWindowFullscreenInternal(FSWINDOW, FSMODE_NONE);
+ break;
+ }
+ [[fallthrough]];
+ case 1:
+ // replace fullscreen
+ g_pCompositor->setWindowFullscreenInternal(FSWINDOW, FSMODE_NONE);
+ g_pCompositor->setWindowFullscreenInternal(pWindow, FSMODE);
+ break;
+
+ default: Debug::log(ERR, "Invalid misc:on_focus_under_fullscreen mode: {}", *PONFOCUSUNDERFS); break;
+ }
+
+ return {};
+}
+
+void CFocusState::fullWindowFocus(PHLWINDOW pWindow, SP<CWLSurfaceResource> surface, bool preserveFocusHistory, bool forceFSCycle) {
+ if (pWindow) {
+ if (!pWindow->m_workspace)
+ return;
+
+ const auto CURRENT_FS_MODE = pWindow->m_workspace->m_hasFullscreenWindow ? pWindow->m_workspace->m_fullscreenMode : FSMODE_NONE;
+ if (CURRENT_FS_MODE != FSMODE_NONE) {
+ const auto RESULT = onFullscreenWorkspaceFocusWindow(pWindow, forceFSCycle);
+ if (RESULT.overrideFocusWindow)
+ pWindow = RESULT.overrideFocusWindow;
+ }
+ }
+
+ static auto PMODALPARENTBLOCKING = CConfigValue<Hyprlang::INT>("general:modal_parent_blocking");
+
+ if (*PMODALPARENTBLOCKING && pWindow && pWindow->m_xdgSurface && pWindow->m_xdgSurface->m_toplevel && pWindow->m_xdgSurface->m_toplevel->anyChildModal()) {
+ Debug::log(LOG, "Refusing focus to window shadowed by modal dialog");
+ return;
+ }
+
+ rawWindowFocus(pWindow, surface, preserveFocusHistory);
+}
+
+void CFocusState::rawWindowFocus(PHLWINDOW pWindow, SP<CWLSurfaceResource> surface, bool preserveFocusHistory) {
+ static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
+ static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
+
+ if (!pWindow || !pWindow->priorityFocus()) {
+ if (g_pSessionLockManager->isSessionLocked()) {
+ Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
+ return;
+ }
+
+ if (!g_pInputManager->m_exclusiveLSes.empty()) {
+ Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
+ return;
+ }
+ }
+
+ if (pWindow && pWindow->m_isX11 && pWindow->isX11OverrideRedirect() && !pWindow->m_xwaylandSurface->wantsFocus())
+ return;
+
+ g_pLayoutManager->getCurrentLayout()->bringWindowToTop(pWindow);
+
+ if (!pWindow || !validMapped(pWindow)) {
+
+ if (m_focusWindow.expired() && !pWindow)
+ return;
+
+ const auto PLASTWINDOW = m_focusWindow.lock();
+ m_focusWindow.reset();
+
+ if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
+ PLASTWINDOW->m_ruleApplicator->propertiesChanged(Rule::RULE_PROP_FOCUS);
+ PLASTWINDOW->updateDecorationValues();
+
+ g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
+ }
+
+ g_pSeatManager->setKeyboardFocus(nullptr);
+
+ g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
+ g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
+
+ EMIT_HOOK_EVENT("activeWindow", PHLWINDOW{nullptr});
+
+ g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
+
+ m_focusSurface.reset();
+
+ g_pInputManager->recheckIdleInhibitorStatus();
+ return;
+ }
+
+ if (pWindow->m_ruleApplicator->noFocus().valueOrDefault()) {
+ Debug::log(LOG, "Ignoring focus to nofocus window!");
+ return;
+ }
+
+ if (m_focusWindow.lock() == pWindow && g_pSeatManager->m_state.keyboardFocus == surface && g_pSeatManager->m_state.keyboardFocus)
+ return;
+
+ if (pWindow->m_pinned)
+ pWindow->m_workspace = m_focusMonitor->m_activeWorkspace;
+
+ const auto PMONITOR = pWindow->m_monitor.lock();
+
+ if (!pWindow->m_workspace || !pWindow->m_workspace->isVisible()) {
+ const auto PWORKSPACE = pWindow->m_workspace;
+ // This is to fix incorrect feedback on the focus history.
+ PWORKSPACE->m_lastFocusedWindow = pWindow;
+ if (m_focusMonitor->m_activeWorkspace)
+ PWORKSPACE->rememberPrevWorkspace(m_focusMonitor->m_activeWorkspace);
+ if (PWORKSPACE->m_isSpecialWorkspace)
+ m_focusMonitor->changeWorkspace(PWORKSPACE, false, true); // if special ws, open on current monitor
+ else if (PMONITOR)
+ PMONITOR->changeWorkspace(PWORKSPACE, false, true);
+ // changeworkspace already calls focusWindow
+ return;
+ }
+
+ const auto PLASTWINDOW = m_focusWindow.lock();
+ m_focusWindow = pWindow;
+
+ /* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which
+ window focuses are "via keybinds" and which ones aren't. */
+ if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace != pWindow->m_workspace && !pWindow->m_pinned && !*PSPECIALFALLTHROUGH)
+ PMONITOR->setSpecialWorkspace(nullptr);
+
+ // we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
+ if (PLASTWINDOW && PLASTWINDOW->m_isMapped) {
+ PLASTWINDOW->m_ruleApplicator->propertiesChanged(Rule::RULE_PROP_FOCUS);
+ PLASTWINDOW->updateDecorationValues();
+
+ if (!pWindow->m_isX11 || !pWindow->isX11OverrideRedirect())
+ g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
+ }
+
+ const auto PWINDOWSURFACE = surface ? surface : pWindow->m_wlSurface->resource();
+
+ rawSurfaceFocus(PWINDOWSURFACE, pWindow);
+
+ g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow
+
+ pWindow->m_ruleApplicator->propertiesChanged(Rule::RULE_PROP_FOCUS);
+ pWindow->onFocusAnimUpdate();
+ pWindow->updateDecorationValues();
+
+ if (pWindow->m_isUrgent)
+ pWindow->m_isUrgent = false;
+
+ // Send an event
+ g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = pWindow->m_class + "," + pWindow->m_title});
+ g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(pWindow.get()))});
+
+ EMIT_HOOK_EVENT("activeWindow", pWindow);
+
+ g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
+
+ g_pInputManager->recheckIdleInhibitorStatus();
+
+ if (!preserveFocusHistory) {
+ // move to front of the window history
+ moveWindowToLatestInHistory(pWindow);
+ }
+
+ if (*PFOLLOWMOUSE == 0)
+ g_pInputManager->sendMotionEventsToFocused();
+
+ if (pWindow->m_groupData.pNextWindow)
+ pWindow->deactivateGroupMembers();
+}
+
+void CFocusState::rawSurfaceFocus(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWindowOwner) {
+ if (g_pSeatManager->m_state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->m_state.keyboardFocus == pWindowOwner->m_wlSurface->resource()))
+ return; // Don't focus when already focused on this.
+
+ if (g_pSessionLockManager->isSessionLocked() && pSurface && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
+ return;
+
+ if (g_pSeatManager->m_seatGrab && !g_pSeatManager->m_seatGrab->accepts(pSurface)) {
+ Debug::log(LOG, "surface {:x} won't receive kb focus because grab rejected it", rc<uintptr_t>(pSurface.get()));
+ return;
+ }
+
+ const auto PLASTSURF = m_focusSurface.lock();
+
+ // Unfocus last surface if should
+ if (m_focusSurface && !pWindowOwner)
+ g_pXWaylandManager->activateSurface(m_focusSurface.lock(), false);
+
+ if (!pSurface) {
+ g_pSeatManager->setKeyboardFocus(nullptr);
+ g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = ","});
+ g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = ""});
+ EMIT_HOOK_EVENT("keyboardFocus", SP<CWLSurfaceResource>{nullptr});
+ m_focusSurface.reset();
+ return;
+ }
+
+ if (g_pSeatManager->m_keyboard)
+ g_pSeatManager->setKeyboardFocus(pSurface);
+
+ if (pWindowOwner)
+ Debug::log(LOG, "Set keyboard focus to surface {:x}, with {}", rc<uintptr_t>(pSurface.get()), pWindowOwner);
+ else
+ Debug::log(LOG, "Set keyboard focus to surface {:x}", rc<uintptr_t>(pSurface.get()));
+
+ g_pXWaylandManager->activateSurface(pSurface, true);
+ m_focusSurface = pSurface;
+
+ EMIT_HOOK_EVENT("keyboardFocus", pSurface);
+
+ const auto SURF = CWLSurface::fromResource(pSurface);
+ const auto OLDSURF = CWLSurface::fromResource(PLASTSURF);
+
+ if (OLDSURF && OLDSURF->constraint())
+ OLDSURF->constraint()->deactivate();
+
+ if (SURF && SURF->constraint())
+ SURF->constraint()->activate();
+}
+
+void CFocusState::rawMonitorFocus(PHLMONITOR pMonitor) {
+ if (m_focusMonitor == pMonitor)
+ return;
+
+ if (!pMonitor) {
+ m_focusMonitor.reset();
+ return;
+ }
+
+ const auto PWORKSPACE = pMonitor->m_activeWorkspace;
+
+ const auto WORKSPACE_ID = PWORKSPACE ? std::to_string(PWORKSPACE->m_id) : std::to_string(WORKSPACE_INVALID);
+ const auto WORKSPACE_NAME = PWORKSPACE ? PWORKSPACE->m_name : "?";
+
+ g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmon", .data = pMonitor->m_name + "," + WORKSPACE_NAME});
+ g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmonv2", .data = pMonitor->m_name + "," + WORKSPACE_ID});
+
+ EMIT_HOOK_EVENT("focusedMon", pMonitor);
+ m_focusMonitor = pMonitor;
+}
+
+SP<CWLSurfaceResource> CFocusState::surface() {
+ return m_focusSurface.lock();
+}
+
+PHLWINDOW CFocusState::window() {
+ return m_focusWindow.lock();
+}
+
+PHLMONITOR CFocusState::monitor() {
+ return m_focusMonitor.lock();
+}
+
+const std::vector<PHLWINDOWREF>& CFocusState::windowHistory() {
+ return m_windowFocusHistory;
+}
+
+void CFocusState::removeWindowFromHistory(PHLWINDOW w) {
+ std::erase_if(m_windowFocusHistory, [&w](const auto& e) { return !e || e == w; });
+}
+
+void CFocusState::addWindowToHistory(PHLWINDOW w) {
+ m_windowFocusHistory.emplace_back(w);
+}
+
+void CFocusState::moveWindowToLatestInHistory(PHLWINDOW w) {
+ const auto HISTORYPIVOT = std::ranges::find_if(m_windowFocusHistory, [&w](const auto& other) { return other.lock() == w; });
+ if (HISTORYPIVOT == m_windowFocusHistory.end())
+ Debug::log(TRACE, "CFocusState: {} has no pivot in history, ignoring request to move to latest", w);
+ else
+ std::rotate(m_windowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1);
+}
diff --git a/src/desktop/state/FocusState.hpp b/src/desktop/state/FocusState.hpp
new file mode 100644
index 00000000..2bf0953d
--- /dev/null
+++ b/src/desktop/state/FocusState.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "../DesktopTypes.hpp"
+#include "../../SharedDefs.hpp"
+
+class CWLSurfaceResource;
+
+namespace Desktop {
+ class CFocusState {
+ public:
+ CFocusState();
+ ~CFocusState() = default;
+
+ CFocusState(CFocusState&&) = delete;
+ CFocusState(CFocusState&) = delete;
+ CFocusState(const CFocusState&) = delete;
+
+ void fullWindowFocus(PHLWINDOW w, SP<CWLSurfaceResource> surface = nullptr, bool preserveFocusHistory = false, bool forceFSCycle = false);
+ void rawWindowFocus(PHLWINDOW w, SP<CWLSurfaceResource> surface = nullptr, bool preserveFocusHistory = false);
+ void rawSurfaceFocus(SP<CWLSurfaceResource> s, PHLWINDOW pWindowOwner = nullptr);
+ void rawMonitorFocus(PHLMONITOR m);
+
+ SP<CWLSurfaceResource> surface();
+ PHLWINDOW window();
+ PHLMONITOR monitor();
+ const std::vector<PHLWINDOWREF>& windowHistory();
+
+ void addWindowToHistory(PHLWINDOW w);
+
+ private:
+ void removeWindowFromHistory(PHLWINDOW w);
+ void moveWindowToLatestInHistory(PHLWINDOW w);
+
+ WP<CWLSurfaceResource> m_focusSurface;
+ PHLWINDOWREF m_focusWindow;
+ PHLMONITORREF m_focusMonitor;
+ std::vector<PHLWINDOWREF> m_windowFocusHistory; // first element is the most recently focused
+
+ SP<HOOK_CALLBACK_FN> m_windowOpen, m_windowClose;
+ };
+
+ SP<CFocusState> focusState();
+};
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index dfbb9f2e..9a1c07d9 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -20,6 +20,7 @@
#include "managers/animation/DesktopAnimationManager.hpp"
#include "managers/PointerManager.hpp"
#include "../desktop/LayerSurface.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
#include "../managers/animation/AnimationManager.hpp"
@@ -57,13 +58,13 @@ void Events::listener_mapWindow(void* owner, void* data) {
static auto PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
- static auto PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:new_window_takes_over_fullscreen");
+ static auto PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:on_focus_under_fullscreen");
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
- auto PMONITOR = g_pCompositor->m_lastMonitor.lock();
- if (!g_pCompositor->m_lastMonitor) {
- g_pCompositor->setActiveMonitor(g_pCompositor->getMonitorFromVector({}));
- PMONITOR = g_pCompositor->m_lastMonitor.lock();
+ auto PMONITOR = Desktop::focusState()->monitor();
+ if (!Desktop::focusState()->monitor()) {
+ Desktop::focusState()->rawMonitorFocus(g_pCompositor->getMonitorFromVector({}));
+ PMONITOR = Desktop::focusState()->monitor();
}
auto PWORKSPACE = PMONITOR->m_activeSpecialWorkspace ? PMONITOR->m_activeSpecialWorkspace : PMONITOR->m_activeWorkspace;
PWINDOW->m_monitor = PMONITOR;
@@ -323,7 +324,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
else if (PMONITOR->activeWorkspaceID() != requestedWorkspaceID && !PWINDOW->m_noInitialFocus)
g_pKeybindManager->m_dispatchers["workspace"](requestedWorkspaceName);
- PMONITOR = g_pCompositor->m_lastMonitor.lock();
+ PMONITOR = Desktop::focusState()->monitor();
}
requestedFSMonitor = MONITOR_INVALID;
@@ -368,6 +369,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
// emit the IPC event before the layout might focus the window to avoid a focus event first
g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", std::format("{:x},{},{},{}", PWINDOW, PWORKSPACE->m_name, PWINDOW->m_class, PWINDOW->m_title)});
+ EMIT_HOOK_EVENT("openWindowEarly", PWINDOW);
if (PWINDOW->m_isFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
@@ -423,7 +425,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_pseudoSize = PWINDOW->m_realSize->goal() - Vector2D(10, 10);
}
- const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_lastWindow.lock();
+ const auto PFOCUSEDWINDOWPREV = Desktop::focusState()->window();
if (PWINDOW->m_ruleApplicator->allowsInput().valueOrDefault()) { // if default value wasn't set to false getPriority() would throw an exception
PWINDOW->m_ruleApplicator->noFocusOverride(Desktop::Types::COverridableVar(false, PWINDOW->m_ruleApplicator->allowsInput().getPriority()));
@@ -433,7 +435,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
// check LS focus grab
const auto PFORCEFOCUS = g_pCompositor->getForceFocus();
- const auto PLSFROMFOCUS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_lastFocus.lock());
+ const auto PLSFROMFOCUS = g_pCompositor->getLayerSurfaceFromSurface(Desktop::focusState()->surface());
if (PLSFROMFOCUS && PLSFROMFOCUS->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE)
PWINDOW->m_noInitialFocus = true;
@@ -449,7 +451,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (!PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() && !PWINDOW->m_noInitialFocus &&
(!PWINDOW->isX11OverrideRedirect() || (PWINDOW->m_isX11 && PWINDOW->m_xwaylandSurface->wantsFocus())) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) &&
!g_pInputManager->isConstrained()) {
- g_pCompositor->focusWindow(PWINDOW);
+ Desktop::focusState()->fullWindowFocus(PWINDOW);
PWINDOW->m_activeInactiveAlpha->setValueAndWarp(*PACTIVEALPHA);
PWINDOW->m_dimPercent->setValueAndWarp(PWINDOW->m_ruleApplicator->noDim().valueOrDefault() ? 0.f : *PDIMSTRENGTH);
} else {
@@ -488,10 +490,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (workspaceSilent) {
if (validMapped(PFOCUSEDWINDOWPREV)) {
- g_pCompositor->focusWindow(PFOCUSEDWINDOWPREV);
+ Desktop::focusState()->rawWindowFocus(PFOCUSEDWINDOWPREV);
PFOCUSEDWINDOWPREV->updateWindowDecos(); // need to for some reason i cba to find out why
} else if (!PFOCUSEDWINDOWPREV)
- g_pCompositor->focusWindow(nullptr);
+ Desktop::focusState()->rawWindowFocus(nullptr);
}
// swallow
@@ -601,10 +603,10 @@ void Events::listener_unmapWindow(void* owner, void* data) {
bool wasLastWindow = false;
- if (PWINDOW == g_pCompositor->m_lastWindow.lock()) {
+ if (PWINDOW == Desktop::focusState()->window()) {
wasLastWindow = true;
- g_pCompositor->m_lastWindow.reset();
- g_pCompositor->m_lastFocus.reset();
+ Desktop::focusState()->window().reset();
+ Desktop::focusState()->surface().reset();
g_pInputManager->releaseAllMouseButtons();
}
@@ -636,8 +638,8 @@ void Events::listener_unmapWindow(void* owner, void* data) {
Debug::log(LOG, "On closed window, new focused candidate is {}", PWINDOWCANDIDATE);
- if (PWINDOWCANDIDATE != g_pCompositor->m_lastWindow.lock() && PWINDOWCANDIDATE) {
- g_pCompositor->focusWindow(PWINDOWCANDIDATE);
+ if (PWINDOWCANDIDATE != Desktop::focusState()->window() && PWINDOWCANDIDATE) {
+ Desktop::focusState()->fullWindowFocus(PWINDOWCANDIDATE);
if (*PEXITRETAINSFS && CURRENTWINDOWFSSTATE)
g_pCompositor->setWindowFullscreenInternal(PWINDOWCANDIDATE, CURRENTFSMODE);
}
@@ -648,7 +650,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
g_pInputManager->sendMotionEventsToFocused();
// CWindow::onUnmap will remove this window's active status, but we can't really do it above.
- if (PWINDOW == g_pCompositor->m_lastWindow.lock() || !g_pCompositor->m_lastWindow.lock()) {
+ if (PWINDOW == Desktop::focusState()->window() || !Desktop::focusState()->window()) {
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
EMIT_HOOK_EVENT("activeWindow", PHLWINDOW{nullptr});
@@ -751,9 +753,9 @@ void Events::listener_destroyWindow(void* owner, void* data) {
Debug::log(LOG, "{:c} destroyed, queueing.", PWINDOW);
- if (PWINDOW == g_pCompositor->m_lastWindow.lock()) {
- g_pCompositor->m_lastWindow.reset();
- g_pCompositor->m_lastFocus.reset();
+ if (PWINDOW == Desktop::focusState()->window()) {
+ Desktop::focusState()->window().reset();
+ Desktop::focusState()->surface().reset();
}
PWINDOW->m_wlSurface->unassign();
@@ -786,17 +788,17 @@ void Events::listener_activateX11(void* owner, void* data) {
Debug::log(LOG, "Unmanaged X11 {} requests activate", PWINDOW);
- if (g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->getPID() != PWINDOW->getPID())
+ if (Desktop::focusState()->window() && Desktop::focusState()->window()->getPID() != PWINDOW->getPID())
return;
if (!PWINDOW->m_xwaylandSurface->wantsFocus())
return;
- g_pCompositor->focusWindow(PWINDOW);
+ Desktop::focusState()->fullWindowFocus(PWINDOW);
return;
}
- if (PWINDOW == g_pCompositor->m_lastWindow.lock() || (PWINDOW->m_suppressedEvents & SUPPRESS_ACTIVATE))
+ if (PWINDOW == Desktop::focusState()->window() || (PWINDOW->m_suppressedEvents & SUPPRESS_ACTIVATE))
return;
PWINDOW->activate();
diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp
index d11e1be6..25b179e9 100644
--- a/src/helpers/MiscFunctions.cpp
+++ b/src/helpers/MiscFunctions.cpp
@@ -3,6 +3,7 @@
#include <algorithm>
#include "../Compositor.hpp"
#include "../managers/TokenManager.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "Monitor.hpp"
#include "../config/ConfigManager.hpp"
#include "fs/FsUtils.hpp"
@@ -146,7 +147,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else if (in.starts_with("empty")) {
const bool same_mon = in.substr(5).contains("m");
const bool next = in.substr(5).contains("n");
- if ((same_mon || next) && !g_pCompositor->m_lastMonitor) {
+ if ((same_mon || next) && !Desktop::focusState()->monitor()) {
Debug::log(ERR, "Empty monitor workspace on monitor null!");
return {WORKSPACE_INVALID};
}
@@ -155,12 +156,12 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
if (same_mon) {
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
const auto PMONITOR = g_pCompositor->getMonitorFromString(rule.monitor);
- if (PMONITOR && (PMONITOR->m_id != g_pCompositor->m_lastMonitor->m_id))
+ if (PMONITOR && (PMONITOR->m_id != Desktop::focusState()->monitor()->m_id))
invalidWSes.insert(rule.workspaceId);
}
}
- WORKSPACEID id = next ? g_pCompositor->m_lastMonitor->activeWorkspaceID() : 0;
+ WORKSPACEID id = next ? Desktop::focusState()->monitor()->activeWorkspaceID() : 0;
while (++id < LONG_MAX) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
if (!invalidWSes.contains(id) && (!PWORKSPACE || PWORKSPACE->getWindows() == 0)) {
@@ -169,10 +170,10 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
}
}
} else if (in.starts_with("prev")) {
- if (!g_pCompositor->m_lastMonitor)
+ if (!Desktop::focusState()->monitor())
return {WORKSPACE_INVALID};
- const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
+ const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!valid(PWORKSPACE))
return {WORKSPACE_INVALID};
@@ -191,12 +192,12 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
return {PLASTWORKSPACE->m_id, PLASTWORKSPACE->m_name};
} else if (in == "next") {
- if (!g_pCompositor->m_lastMonitor || !g_pCompositor->m_lastMonitor->m_activeWorkspace) {
+ if (!Desktop::focusState()->monitor() || !Desktop::focusState()->monitor()->m_activeWorkspace) {
Debug::log(ERR, "no active monitor or workspace for 'next'");
return {WORKSPACE_INVALID};
}
- auto PCURRENTWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
+ auto PCURRENTWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
WORKSPACEID nextId = PCURRENTWORKSPACE->m_id + 1;
@@ -209,7 +210,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else {
if (in[0] == 'r' && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) {
bool absolute = in[1] == '~';
- if (!g_pCompositor->m_lastMonitor) {
+ if (!Desktop::focusState()->monitor()) {
Debug::log(ERR, "Relative monitor workspace on monitor null!");
return {WORKSPACE_INVALID};
}
@@ -227,14 +228,14 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
// Collect all the workspaces we can't jump to.
for (auto const& ws : g_pCompositor->getWorkspaces()) {
- if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor)) {
+ if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor())) {
// Can't jump to this workspace
invalidWSes.insert(ws->m_id);
}
}
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
const auto PMONITOR = g_pCompositor->getMonitorFromString(rule.monitor);
- if (!PMONITOR || PMONITOR->m_id == g_pCompositor->m_lastMonitor->m_id) {
+ if (!PMONITOR || PMONITOR->m_id == Desktop::focusState()->monitor()->m_id) {
// Can't be invalid
continue;
}
@@ -245,7 +246,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
// Prepare all named workspaces in case when we need them
std::vector<WORKSPACEID> namedWSes;
for (auto const& ws : g_pCompositor->getWorkspaces()) {
- if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor) || ws->m_id >= 0)
+ if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor()) || ws->m_id >= 0)
continue;
namedWSes.push_back(ws->m_id);
@@ -272,7 +273,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else {
// Just take a blind guess at where we'll probably end up
- WORKSPACEID activeWSID = g_pCompositor->m_lastMonitor->m_activeWorkspace ? g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id : 1;
+ WORKSPACEID activeWSID = Desktop::focusState()->monitor()->m_activeWorkspace ? Desktop::focusState()->monitor()->m_activeWorkspace->m_id : 1;
WORKSPACEID predictedWSID = activeWSID + remains;
int remainingWSes = 0;
char walkDir = in[1];
@@ -371,7 +372,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
bool onAllMonitors = in[0] == 'e';
bool absolute = in[1] == '~';
- if (!g_pCompositor->m_lastMonitor) {
+ if (!Desktop::focusState()->monitor()) {
Debug::log(ERR, "Relative monitor workspace on monitor null!");
return {WORKSPACE_INVALID};
}
@@ -389,7 +390,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
std::vector<WORKSPACEID> validWSes;
for (auto const& ws : g_pCompositor->getWorkspaces()) {
- if (ws->m_isSpecialWorkspace || (ws->m_monitor != g_pCompositor->m_lastMonitor && !onAllMonitors))
+ if (ws->m_isSpecialWorkspace || (ws->m_monitor != Desktop::focusState()->monitor() && !onAllMonitors))
continue;
validWSes.push_back(ws->m_id);
@@ -414,7 +415,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size();
// get the current item
- WORKSPACEID activeWSID = g_pCompositor->m_lastMonitor->m_activeWorkspace ? g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id : 1;
+ WORKSPACEID activeWSID = Desktop::focusState()->monitor()->m_activeWorkspace ? Desktop::focusState()->monitor()->m_activeWorkspace->m_id : 1;
for (ssize_t i = 0; i < sc<ssize_t>(validWSes.size()); i++) {
if (validWSes[i] == activeWSID) {
currentItem = i;
@@ -437,8 +438,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
result.name = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_name;
} else {
if (in[0] == '+' || in[0] == '-') {
- if (g_pCompositor->m_lastMonitor) {
- const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, g_pCompositor->m_lastMonitor->activeWorkspaceID());
+ if (Desktop::focusState()->monitor()) {
+ const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, Desktop::focusState()->monitor()->activeWorkspaceID());
if (!PLUSMINUSRESULT.has_value())
return {WORKSPACE_INVALID};
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index ce9c6990..abf74b02 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -31,6 +31,7 @@
#include "sync/SyncTimeline.hpp"
#include "time/Time.hpp"
#include "../desktop/LayerSurface.hpp"
+#include "../desktop/state/FocusState.hpp"
#include <aquamarine/output/Output.hpp>
#include "debug/Log.hpp"
#include "debug/HyprNotificationOverlay.hpp"
@@ -298,8 +299,8 @@ void CMonitor::onConnect(bool noRule) {
if (!m_activeMonitorRule.mirrorOf.empty())
setMirror(m_activeMonitorRule.mirrorOf);
- if (!g_pCompositor->m_lastMonitor) // set the last monitor if it isn't set yet
- g_pCompositor->setActiveMonitor(m_self.lock());
+ if (!Desktop::focusState()->monitor()) // set the last monitor if it isn't set yet
+ Desktop::focusState()->rawMonitorFocus(m_self.lock());
g_pHyprRenderer->arrangeLayersForMonitor(m_id);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
@@ -310,7 +311,7 @@ void CMonitor::onConnect(bool noRule) {
// verify last mon valid
bool found = false;
for (auto const& m : g_pCompositor->m_monitors) {
- if (m == g_pCompositor->m_lastMonitor) {
+ if (m == Desktop::focusState()->monitor()) {
found = true;
break;
}
@@ -330,7 +331,7 @@ void CMonitor::onConnect(bool noRule) {
Debug::log(LOG, "Monitor {} was not on any workspace", m_name);
if (!found)
- g_pCompositor->setActiveMonitor(m_self.lock());
+ Desktop::focusState()->rawMonitorFocus(m_self.lock());
g_pCompositor->scheduleFrameForMonitor(m_self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEW_MONITOR);
@@ -437,9 +438,9 @@ void CMonitor::onDisconnect(bool destroy) {
g_pDesktopAnimationManager->startAnimation(w, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
}
} else {
- g_pCompositor->m_lastFocus.reset();
- g_pCompositor->m_lastWindow.reset();
- g_pCompositor->m_lastMonitor.reset();
+ Desktop::focusState()->surface().reset();
+ Desktop::focusState()->window().reset();
+ Desktop::focusState()->monitor().reset();
}
if (m_activeWorkspace)
@@ -453,8 +454,8 @@ void CMonitor::onDisconnect(bool destroy) {
if (!m_state.commit())
Debug::log(WARN, "state.commit() failed in CMonitor::onDisconnect");
- if (g_pCompositor->m_lastMonitor == m_self)
- g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_unsafeOutput.lock());
+ if (Desktop::focusState()->monitor() == m_self)
+ Desktop::focusState()->rawMonitorFocus(BACKUPMON ? BACKUPMON : g_pCompositor->m_unsafeOutput.lock());
if (g_pHyprRenderer->m_mostHzMonitor == m_self) {
int mostHz = 0;
@@ -1203,7 +1204,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
g_pCompositor->scheduleMonitorStateRecheck();
- g_pCompositor->setActiveMonitor(g_pCompositor->m_monitors.front());
+ Desktop::focusState()->rawMonitorFocus(g_pCompositor->m_monitors.front());
// Software lock mirrored monitor
g_pPointerManager->lockSoftwareForMonitor(PMIRRORMON);
@@ -1286,8 +1287,8 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
w->moveToWorkspace(pWorkspace);
}
- if (!noFocus && !g_pCompositor->m_lastMonitor->m_activeSpecialWorkspace &&
- !(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
+ if (!noFocus && !Desktop::focusState()->monitor()->m_activeSpecialWorkspace &&
+ !(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
auto pWindow = pWorkspace->m_hasFullscreenWindow ? pWorkspace->getFullscreenWindow() : pWorkspace->getLastFocusedWindow();
@@ -1302,7 +1303,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
pWindow = pWorkspace->getFirstWindow();
}
- g_pCompositor->focusWindow(pWindow);
+ Desktop::focusState()->fullWindowFocus(pWindow);
}
if (!noMouseMove)
@@ -1361,9 +1362,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
- if (!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
+ if (!(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
if (const auto PLAST = m_activeWorkspace->getLastFocusedWindow(); PLAST)
- g_pCompositor->focusWindow(PLAST);
+ Desktop::focusState()->fullWindowFocus(PLAST);
else
g_pInputManager->refocus();
}
@@ -1443,9 +1444,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
- if (!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) {
+ if (!(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
if (const auto PLAST = pWorkspace->getLastFocusedWindow(); PLAST)
- g_pCompositor->focusWindow(PLAST);
+ Desktop::focusState()->fullWindowFocus(PLAST);
else
g_pInputManager->refocus();
}
@@ -1553,7 +1554,7 @@ uint32_t CMonitor::isSolitaryBlocked(bool full) {
return reasons;
}
- if (g_pHyprError->active() && g_pCompositor->m_lastMonitor == m_self) {
+ if (g_pHyprError->active() && Desktop::focusState()->monitor() == m_self) {
reasons |= SC_ERRORBAR;
if (!full)
return reasons;
diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp
index ffb716c4..3446fc4b 100644
--- a/src/hyprerror/HyprError.cpp
+++ b/src/hyprerror/HyprError.cpp
@@ -7,6 +7,7 @@
#include "../managers/animation/AnimationManager.hpp"
#include "../render/Renderer.hpp"
#include "../managers/HookSystemManager.hpp"
+#include "../desktop/state/FocusState.hpp"
#include <hyprutils/utils/ScopeGuard.hpp>
using namespace Hyprutils::Animation;
@@ -18,7 +19,7 @@ CHyprError::CHyprError() {
if (!m_isCreated)
return;
- g_pHyprRenderer->damageMonitor(g_pCompositor->m_lastMonitor.lock());
+ g_pHyprRenderer->damageMonitor(Desktop::focusState()->monitor());
m_monitorChanged = true;
});
diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp
index 54b45426..cf833fb5 100644
--- a/src/layout/DwindleLayout.cpp
+++ b/src/layout/DwindleLayout.cpp
@@ -7,6 +7,7 @@
#include "../managers/input/InputManager.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "xwayland/XWayland.hpp"
void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) {
@@ -300,9 +301,9 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
OPENINGON = getClosestNodeOnWorkspace(PNODE->workspaceID, MOUSECOORDS);
} else if (*PUSEACTIVE) {
- if (g_pCompositor->m_lastWindow.lock() && !g_pCompositor->m_lastWindow->m_isFloating && g_pCompositor->m_lastWindow.lock() != pWindow &&
- g_pCompositor->m_lastWindow->m_workspace == pWindow->m_workspace && g_pCompositor->m_lastWindow->m_isMapped) {
- OPENINGON = getNodeFromWindow(g_pCompositor->m_lastWindow.lock());
+ if (Desktop::focusState()->window() && !Desktop::focusState()->window()->m_isFloating && Desktop::focusState()->window() != pWindow &&
+ Desktop::focusState()->window()->m_workspace == pWindow->m_workspace && Desktop::focusState()->window()->m_isMapped) {
+ OPENINGON = getNodeFromWindow(Desktop::focusState()->window());
} else {
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS));
}
@@ -602,7 +603,7 @@ void CHyprDwindleLayout::onBeginDragWindow() {
void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorner corner, PHLWINDOW pWindow) {
- const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = pWindow ? pWindow : Desktop::focusState()->window();
if (!validMapped(PWINDOW))
return;
@@ -922,7 +923,7 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
if (silent) {
const auto PNODETOFOCUS = getClosestNodeOnWorkspace(originalWorkspaceID, originalPos);
if (PNODETOFOCUS && PNODETOFOCUS->pWindow.lock())
- g_pCompositor->focusWindow(PNODETOFOCUS->pWindow.lock());
+ Desktop::focusState()->fullWindowFocus(PNODETOFOCUS->pWindow.lock());
}
}
@@ -1139,20 +1140,20 @@ void CHyprDwindleLayout::onDisable() {
}
Vector2D CHyprDwindleLayout::predictSizeForNewWindowTiled() {
- if (!g_pCompositor->m_lastMonitor)
+ if (!Desktop::focusState()->monitor())
return {};
// get window candidate
- PHLWINDOW candidate = g_pCompositor->m_lastWindow.lock();
+ PHLWINDOW candidate = Desktop::focusState()->window();
if (!candidate)
- candidate = g_pCompositor->m_lastMonitor->m_activeWorkspace->getFirstWindow();
+ candidate = Desktop::focusState()->monitor()->m_activeWorkspace->getFirstWindow();
// create a fake node
SDwindleNodeData node;
if (!candidate)
- return g_pCompositor->m_lastMonitor->m_size;
+ return Desktop::focusState()->monitor()->m_size;
else {
const auto PNODE = getNodeFromWindow(candidate);
diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp
index 18c100b7..fb47938f 100644
--- a/src/layout/IHyprLayout.cpp
+++ b/src/layout/IHyprLayout.cpp
@@ -5,6 +5,7 @@
#include "../config/ConfigValue.hpp"
#include "../config/ConfigManager.hpp"
#include "../desktop/Window.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp"
@@ -208,8 +209,8 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) {
static auto PAUTOGROUP = CConfigValue<Hyprlang::INT>("group:auto_group");
- const PHLWINDOW OPENINGON = g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_workspace == pWindow->m_workspace ?
- g_pCompositor->m_lastWindow.lock() :
+ const PHLWINDOW OPENINGON = Desktop::focusState()->window() && Desktop::focusState()->window()->m_workspace == pWindow->m_workspace ?
+ Desktop::focusState()->window() :
(pWindow->m_workspace ? pWindow->m_workspace->getFirstWindow() : nullptr);
const bool FLOATEDINTOTILED = pWindow->m_isFloating && OPENINGON && !OPENINGON->m_isFloating;
const bool SWALLOWING = pWindow->m_swallowed || pWindow->m_groupSwallowed;
@@ -304,7 +305,7 @@ void IHyprLayout::onBeginDragWindow() {
g_pKeybindManager->shadowKeybinds();
- g_pCompositor->focusWindow(DRAGGINGWINDOW);
+ Desktop::focusState()->rawWindowFocus(DRAGGINGWINDOW);
g_pCompositor->changeWindowZOrder(DRAGGINGWINDOW, true);
}
@@ -394,7 +395,7 @@ void IHyprLayout::onEndDragWindow() {
}
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
- g_pCompositor->focusWindow(DRAGGINGWINDOW);
+ Desktop::focusState()->fullWindowFocus(DRAGGINGWINDOW);
g_pInputManager->m_wasDraggingWindow = false;
}
@@ -785,7 +786,7 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
// fix pseudo leaving artifacts
g_pHyprRenderer->damageMonitor(pWindow->m_monitor.lock());
- if (pWindow == g_pCompositor->m_lastWindow)
+ if (pWindow == Desktop::focusState()->window())
m_lastTiledWindow = pWindow;
} else {
onWindowRemovedTiling(pWindow);
@@ -852,7 +853,7 @@ void IHyprLayout::fitFloatingWindowOnMonitor(PHLWINDOW w, std::optional<CBox> tb
}
void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) {
- const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = pWindow ? pWindow : Desktop::focusState()->window();
if (!validMapped(PWINDOW))
return;
@@ -927,7 +928,7 @@ PHLWINDOW IHyprLayout::getNextWindowCandidate(PHLWINDOW pWindow) {
pWindowCandidate = PWORKSPACE->getFirstWindow();
if (!pWindowCandidate || pWindow == pWindowCandidate || !pWindowCandidate->m_isMapped || pWindowCandidate->isHidden() || pWindowCandidate->m_X11ShouldntFocus ||
- pWindowCandidate->isX11OverrideRedirect() || pWindowCandidate->m_monitor != g_pCompositor->m_lastMonitor)
+ pWindowCandidate->isX11OverrideRedirect() || pWindowCandidate->m_monitor != Desktop::focusState()->monitor())
return nullptr;
return pWindowCandidate;
@@ -949,13 +950,13 @@ void IHyprLayout::bringWindowToTop(PHLWINDOW pWindow) {
void IHyprLayout::requestFocusForWindow(PHLWINDOW pWindow) {
bringWindowToTop(pWindow);
- g_pCompositor->focusWindow(pWindow);
+ Desktop::focusState()->fullWindowFocus(pWindow);
g_pCompositor->warpCursorTo(pWindow->middle());
}
Vector2D IHyprLayout::predictSizeForNewWindowFloating(PHLWINDOW pWindow) { // get all rules, see if we have any size overrides.
Vector2D sizeOverride = {};
- if (g_pCompositor->m_lastMonitor) {
+ if (Desktop::focusState()->monitor()) {
// If `persistentsize` is set, use the stored size if available.
const bool HASPERSISTENTSIZE = pWindow->m_ruleApplicator->persistentSize().valueOrDefault();
diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp
index 820e52c6..d0b82343 100644
--- a/src/layout/MasterLayout.cpp
+++ b/src/layout/MasterLayout.cpp
@@ -9,6 +9,7 @@
#include "../managers/input/InputManager.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "xwayland/XWayland.hpp"
SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) {
@@ -93,7 +94,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
const auto PNODE = [&]() {
if (*PNEWONACTIVE != "none" && !BNEWISMASTER) {
- const auto pLastNode = getNodeFromWindow(g_pCompositor->m_lastWindow.lock());
+ const auto pLastNode = getNodeFromWindow(Desktop::focusState()->window());
if (pLastNode && !(pLastNode->isMaster && (getMastersOnWorkspace(pWindow->workspaceID()) == 1 || *PNEWSTATUS == "slave"))) {
auto it = std::ranges::find(m_masterNodesData, *pLastNode);
if (!BNEWBEFOREACTIVE)
@@ -111,8 +112,8 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
static auto PMFACT = CConfigValue<Hyprlang::FLOAT>("master:mfact");
float lastSplitPercent = *PMFACT;
- auto OPENINGON = isWindowTiled(g_pCompositor->m_lastWindow.lock()) && g_pCompositor->m_lastWindow->m_workspace == pWindow->m_workspace ?
- getNodeFromWindow(g_pCompositor->m_lastWindow.lock()) :
+ auto OPENINGON = isWindowTiled(Desktop::focusState()->window()) && Desktop::focusState()->window()->m_workspace == pWindow->m_workspace ?
+ getNodeFromWindow(Desktop::focusState()->window()) :
getMasterNodeOnWorkspace(pWindow->workspaceID());
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
@@ -756,7 +757,7 @@ bool CHyprMasterLayout::isWindowTiled(PHLWINDOW pWindow) {
}
void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorner corner, PHLWINDOW pWindow) {
- const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = pWindow ? pWindow : Desktop::focusState()->window();
if (!validMapped(PWINDOW))
return;
@@ -985,14 +986,14 @@ void CHyprMasterLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
pWindow->m_monitor = PWINDOW2->m_monitor;
if (!silent) {
const auto pMonitor = pWindow->m_monitor.lock();
- g_pCompositor->setActiveMonitor(pMonitor);
+ Desktop::focusState()->rawMonitorFocus(pMonitor);
}
onWindowCreatedTiling(pWindow);
} else {
// if same monitor, switch windows
switchWindows(pWindow, PWINDOW2);
if (silent)
- g_pCompositor->focusWindow(PWINDOW2);
+ Desktop::focusState()->fullWindowFocus(PWINDOW2);
}
pWindow->updateGroupOutputs();
@@ -1083,18 +1084,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!validMapped(PWINDOWTOCHANGETO))
return;
- if (header.pWindow->isFullscreen()) {
- const auto PWORKSPACE = header.pWindow->m_workspace;
- const auto FSMODE = header.pWindow->m_fullscreenState.internal;
- static auto INHERITFULLSCREEN = CConfigValue<Hyprlang::INT>("master:inherit_fullscreen");
- g_pCompositor->setWindowFullscreenInternal(header.pWindow, FSMODE_NONE);
- g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
- if (*INHERITFULLSCREEN)
- g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, FSMODE);
- } else {
- g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
- g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle());
- }
+ Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO);
+ g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle());
g_pInputManager->m_forcedFocus = PWINDOWTOCHANGETO;
g_pInputManager->simulateMouseMovement();
@@ -1498,25 +1489,25 @@ void CHyprMasterLayout::replaceWindowDataWith(PHLWINDOW from, PHLWINDOW to) {
Vector2D CHyprMasterLayout::predictSizeForNewWindowTiled() {
static auto PNEWSTATUS = CConfigValue<std::string>("master:new_status");
- if (!g_pCompositor->m_lastMonitor)
+ if (!Desktop::focusState()->monitor())
return {};
- const int NODES = getNodesOnWorkspace(g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id);
+ const int NODES = getNodesOnWorkspace(Desktop::focusState()->monitor()->m_activeWorkspace->m_id);
if (NODES <= 0)
- return g_pCompositor->m_lastMonitor->m_size;
+ return Desktop::focusState()->monitor()->m_size;
- const auto MASTER = getMasterNodeOnWorkspace(g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id);
+ const auto MASTER = getMasterNodeOnWorkspace(Desktop::focusState()->monitor()->m_activeWorkspace->m_id);
if (!MASTER) // wtf
return {};
if (*PNEWSTATUS == "master") {
return MASTER->size;
} else {
- const auto SLAVES = NODES - getMastersOnWorkspace(g_pCompositor->m_lastMonitor->m_activeWorkspace->m_id);
+ const auto SLAVES = NODES - getMastersOnWorkspace(Desktop::focusState()->monitor()->m_activeWorkspace->m_id);
// TODO: make this better
- return {g_pCompositor->m_lastMonitor->m_size.x - MASTER->size.x, g_pCompositor->m_lastMonitor->m_size.y / (SLAVES + 1)};
+ return {Desktop::focusState()->monitor()->m_size.x - MASTER->size.x, Desktop::focusState()->monitor()->m_size.y / (SLAVES + 1)};
}
return {};
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index 3525f5b3..2fd7ba99 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -1,5 +1,6 @@
#include "../config/ConfigValue.hpp"
#include "../devices/IKeyboard.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../managers/SeatManager.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/ShortcutsInhibit.hpp"
@@ -53,7 +54,7 @@ static std::vector<std::pair<std::string, std::string>> getHyprlandLaunchEnv(PHL
if (!*PINITIALWSTRACKING || g_pConfigManager->m_isLaunchingExecOnce)
return {};
- const auto PMONITOR = g_pCompositor->m_lastMonitor;
+ const auto PMONITOR = Desktop::focusState()->monitor();
if (!PMONITOR || !PMONITOR->m_activeWorkspace)
return {};
@@ -336,15 +337,15 @@ static void updateRelativeCursorCoords() {
if (*PNOWARPS)
return;
- if (g_pCompositor->m_lastWindow)
- g_pCompositor->m_lastWindow->m_relativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - g_pCompositor->m_lastWindow->m_position;
+ if (Desktop::focusState()->window())
+ Desktop::focusState()->window()->m_relativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - Desktop::focusState()->window()->m_position;
}
bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
if (!monitor)
return false;
- const auto LASTMONITOR = g_pCompositor->m_lastMonitor.lock();
+ const auto LASTMONITOR = Desktop::focusState()->monitor();
if (!LASTMONITOR)
return false;
if (LASTMONITOR == monitor) {
@@ -355,7 +356,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps");
- const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
+ const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
const auto PNEWMAINWORKSPACE = monitor->m_activeWorkspace;
g_pInputManager->unconstrainMouse();
@@ -366,7 +367,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
const auto PNEWWINDOW = PNEWWORKSPACE->getLastFocusedWindow();
if (PNEWWINDOW) {
updateRelativeCursorCoords();
- g_pCompositor->focusWindow(PNEWWINDOW);
+ Desktop::focusState()->fullWindowFocus(PNEWWINDOW);
PNEWWINDOW->warpCursor();
if (*PNOWARPS == 0 || *PFOLLOWMOUSE < 2) {
@@ -375,19 +376,19 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
g_pInputManager->m_forcedFocus.reset();
}
} else {
- g_pCompositor->focusWindow(nullptr);
+ Desktop::focusState()->rawWindowFocus(nullptr);
g_pCompositor->warpCursorTo(monitor->middle());
}
- g_pCompositor->setActiveMonitor(monitor);
+ Desktop::focusState()->rawMonitorFocus(monitor);
return true;
}
-void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory) {
+void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory, bool forceFSCycle) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps");
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
if (PWINDOWTOCHANGETO == PLASTWINDOW || !PWINDOWTOCHANGETO)
return;
@@ -395,24 +396,11 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveF
// remove constraints
g_pInputManager->unconstrainMouse();
- if (PLASTWINDOW && PLASTWINDOW->m_workspace == PWINDOWTOCHANGETO->m_workspace && PLASTWINDOW->isFullscreen()) {
- const auto PWORKSPACE = PLASTWINDOW->m_workspace;
- const auto MODE = PWORKSPACE->m_fullscreenMode;
-
- if (!PWINDOWTOCHANGETO->m_pinned)
- g_pCompositor->setWindowFullscreenInternal(PLASTWINDOW, FSMODE_NONE);
-
- g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory);
-
- if (!PWINDOWTOCHANGETO->m_pinned)
- g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, MODE);
-
- // warp the position + size animation, otherwise it looks weird.
- PWINDOWTOCHANGETO->m_realPosition->warp();
- PWINDOWTOCHANGETO->m_realSize->warp();
- } else {
+ if (PLASTWINDOW && PLASTWINDOW->m_workspace == PWINDOWTOCHANGETO->m_workspace)
+ Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory, forceFSCycle);
+ else {
updateRelativeCursorCoords();
- g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory);
+ Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory, forceFSCycle);
PWINDOWTOCHANGETO->warpCursor();
// Move mouse focus to the new window if required by current follow_mouse and warp modes
@@ -426,7 +414,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveF
// event
const auto PNEWMON = PWINDOWTOCHANGETO->m_monitor.lock();
- g_pCompositor->setActiveMonitor(PNEWMON);
+ Desktop::focusState()->rawMonitorFocus(PNEWMON);
}
}
};
@@ -998,7 +986,7 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo
}
SDispatchResult CKeybindManager::killActive(std::string args) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) {
Debug::log(ERR, "killActive: no window found");
@@ -1011,10 +999,10 @@ SDispatchResult CKeybindManager::killActive(std::string args) {
}
SDispatchResult CKeybindManager::closeActive(std::string args) {
- if (g_pCompositor->m_lastWindow && g_pCompositor->m_lastWindow->m_closeableSince > Time::steadyNow())
+ if (Desktop::focusState()->window() && Desktop::focusState()->window()->m_closeableSince > Time::steadyNow())
return {.success = false, .error = "can't close window, it's not closeable yet (noclosefor)"};
- g_pCompositor->closeWindow(g_pCompositor->m_lastWindow.lock());
+ g_pCompositor->closeWindow(Desktop::focusState()->window());
return {};
}
@@ -1058,13 +1046,13 @@ SDispatchResult CKeybindManager::signalActive(std::string args) {
Debug::log(ERR, "signalActive: invalid signal number {}", SIGNALNUM);
return {.success = false, .error = std::format("signalActive: invalid signal number {}", SIGNALNUM)};
}
- kill(g_pCompositor->m_lastWindow.lock()->getPID(), SIGNALNUM);
+ kill(Desktop::focusState()->window()->getPID(), SIGNALNUM);
} catch (const std::exception& e) {
Debug::log(ERR, "signalActive: invalid signal format \"{}\"", args);
return {.success = false, .error = std::format("signalActive: invalid signal format \"{}\"", args)};
}
- kill(g_pCompositor->m_lastWindow.lock()->getPID(), std::stoi(args));
+ kill(Desktop::focusState()->window()->getPID(), std::stoi(args));
return {};
}
@@ -1108,7 +1096,7 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<
if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args);
else
- PWINDOW = g_pCompositor->m_lastWindow.lock();
+ PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@@ -1118,7 +1106,7 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<
// remove drag status
if (!g_pInputManager->m_currentlyDraggedWindow.expired())
- g_pKeybindManager->changeMouseBindMode(MBIND_INVALID);
+ CKeybindManager::changeMouseBindMode(MBIND_INVALID);
if (PWINDOW->m_groupData.pNextWindow.lock() && PWINDOW->m_groupData.pNextWindow.lock() != PWINDOW) {
const auto PCURRENT = PWINDOW->getGroupCurrent();
@@ -1161,7 +1149,7 @@ SDispatchResult CKeybindManager::setActiveTiled(std::string args) {
}
SDispatchResult CKeybindManager::centerWindow(std::string args) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW || !PWINDOW->m_isFloating || PWINDOW->isFullscreen())
return {.success = false, .error = "No floating window found"};
@@ -1184,7 +1172,7 @@ SDispatchResult CKeybindManager::toggleActivePseudo(std::string args) {
if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args);
else
- PWINDOW = g_pCompositor->m_lastWindow.lock();
+ PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@@ -1225,7 +1213,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
static auto PWORKSPACECENTERON = CConfigValue<Hyprlang::INT>("binds:workspace_center_on");
static auto PHIDESPECIALONWORKSPACECHANGE = CConfigValue<Hyprlang::INT>("binds:hide_special_on_workspace_change");
- const auto PMONITOR = g_pCompositor->m_lastMonitor.lock();
+ const auto PMONITOR = Desktop::focusState()->monitor();
if (!PMONITOR)
return {.success = false, .error = "Last monitor not found"};
@@ -1275,7 +1263,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
updateRelativeCursorCoords();
- g_pCompositor->setActiveMonitor(PMONITORWORKSPACEOWNER);
+ Desktop::focusState()->rawMonitorFocus(PMONITORWORKSPACEOWNER);
if (BISWORKSPACECURRENT) {
if (*PALLOWWORKSPACECYCLES)
@@ -1292,7 +1280,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
if (PMONITOR != PMONITORWORKSPACEOWNER) {
Vector2D middle = PMONITORWORKSPACEOWNER->middle();
if (const auto PLAST = pWorkspaceToChangeTo->getLastFocusedWindow(); PLAST) {
- g_pCompositor->focusWindow(PLAST);
+ Desktop::focusState()->fullWindowFocus(PLAST);
if (*PWORKSPACECENTERON == 1)
middle = PLAST->middle();
}
@@ -1300,7 +1288,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
}
if (!g_pInputManager->m_lastFocusOnLS) {
- if (g_pCompositor->m_lastFocus)
+ if (Desktop::focusState()->surface())
g_pInputManager->sendMotionEventsToFocused();
else
g_pInputManager->simulateMouseMovement();
@@ -1320,7 +1308,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
}
SDispatchResult CKeybindManager::fullscreenActive(std::string args) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
const auto ARGS = CConstVarList(args, 2, ' ');
if (!PWINDOW)
@@ -1344,7 +1332,7 @@ SDispatchResult CKeybindManager::fullscreenActive(std::string args) {
}
SDispatchResult CKeybindManager::fullscreenStateActive(std::string args) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
const auto ARGS = CVarList(args, 3, ' ');
if (!PWINDOW)
@@ -1390,7 +1378,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1));
args = args.substr(0, args.find_last_of(','));
} else {
- PWINDOW = g_pCompositor->m_lastWindow.lock();
+ PWINDOW = Desktop::focusState()->window();
}
if (!PWINDOW)
@@ -1420,7 +1408,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
const auto FULLSCREENMODE = PWINDOW->m_fullscreenState.internal;
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
pMonitor = pWorkspace->m_monitor.lock();
- g_pCompositor->setActiveMonitor(pMonitor);
+ Desktop::focusState()->rawMonitorFocus(pMonitor);
g_pCompositor->setWindowFullscreenInternal(PWINDOW, FULLSCREENMODE);
} else {
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->monitorID(), workspaceName, false);
@@ -1440,7 +1428,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
pMonitor->changeWorkspace(pWorkspace);
- g_pCompositor->focusWindow(PWINDOW);
+ Desktop::focusState()->fullWindowFocus(PWINDOW);
PWINDOW->warpCursor();
return {};
@@ -1453,7 +1441,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1));
args = args.substr(0, args.find_last_of(','));
} else {
- PWINDOW = g_pCompositor->m_lastWindow.lock();
+ PWINDOW = Desktop::focusState()->window();
}
if (!PWINDOW)
@@ -1480,9 +1468,9 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
}
- if (PWINDOW == g_pCompositor->m_lastWindow) {
+ if (PWINDOW == Desktop::focusState()->window()) {
if (const auto PATCOORDS = g_pCompositor->vectorToWindowUnified(OLDMIDDLE, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING, PWINDOW); PATCOORDS)
- g_pCompositor->focusWindow(PATCOORDS);
+ Desktop::focusState()->fullWindowFocus(PATCOORDS);
else
g_pInputManager->refocus();
}
@@ -1501,7 +1489,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
return {.success = false, .error = std::format("Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)};
}
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW) {
if (*PMONITORFALLBACK)
tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(arg));
@@ -1529,7 +1517,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
// Found window in direction, switch to it
if (PWINDOWTOCHANGETO) {
- switchToWindow(PWINDOWTOCHANGETO);
+ switchToWindow(PWINDOWTOCHANGETO, false, *PFULLCYCLE && PLASTWINDOW->isFullscreen());
return {};
}
@@ -1587,8 +1575,8 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
SDispatchResult CKeybindManager::focusUrgentOrLast(std::string args) {
const auto PWINDOWURGENT = g_pCompositor->getUrgentWindow();
- const auto PWINDOWPREV = g_pCompositor->m_lastWindow.lock() ? (g_pCompositor->m_windowFocusHistory.size() < 2 ? nullptr : g_pCompositor->m_windowFocusHistory[1].lock()) :
- (g_pCompositor->m_windowFocusHistory.empty() ? nullptr : g_pCompositor->m_windowFocusHistory[0].lock());
+ const auto PWINDOWPREV = Desktop::focusState()->window() ? (Desktop::focusState()->windowHistory().size() < 2 ? nullptr : Desktop::focusState()->windowHistory()[1].lock()) :
+ (Desktop::focusState()->windowHistory().empty() ? nullptr : Desktop::focusState()->windowHistory()[0].lock());
if (!PWINDOWURGENT && !PWINDOWPREV)
return {.success = false, .error = "Window not found"};
@@ -1599,8 +1587,8 @@ SDispatchResult CKeybindManager::focusUrgentOrLast(std::string args) {
}
SDispatchResult CKeybindManager::focusCurrentOrLast(std::string args) {
- const auto PWINDOWPREV = g_pCompositor->m_lastWindow.lock() ? (g_pCompositor->m_windowFocusHistory.size() < 2 ? nullptr : g_pCompositor->m_windowFocusHistory[1].lock()) :
- (g_pCompositor->m_windowFocusHistory.empty() ? nullptr : g_pCompositor->m_windowFocusHistory[0].lock());
+ const auto PWINDOWPREV = Desktop::focusState()->window() ? (Desktop::focusState()->windowHistory().size() < 2 ? nullptr : Desktop::focusState()->windowHistory()[1].lock()) :
+ (Desktop::focusState()->windowHistory().empty() ? nullptr : Desktop::focusState()->windowHistory()[0].lock());
if (!PWINDOWPREV)
return {.success = false, .error = "Window not found"};
@@ -1612,7 +1600,7 @@ SDispatchResult CKeybindManager::focusCurrentOrLast(std::string args) {
SDispatchResult CKeybindManager::swapActive(std::string args) {
char arg = args[0];
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
PHLWINDOW PWINDOWTOCHANGETO = nullptr;
if (!PLASTWINDOW)
@@ -1663,7 +1651,7 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) {
return {.success = false, .error = std::format("Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)};
}
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "Window to move not found"};
@@ -1729,7 +1717,7 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) {
}
SDispatchResult CKeybindManager::toggleGroup(std::string args) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@@ -1746,7 +1734,7 @@ SDispatchResult CKeybindManager::toggleGroup(std::string args) {
}
SDispatchResult CKeybindManager::changeGroupActive(std::string args) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@@ -1779,7 +1767,7 @@ SDispatchResult CKeybindManager::changeGroupActive(std::string args) {
SDispatchResult CKeybindManager::toggleSplit(std::string args) {
SLayoutMessageHeader header;
- header.pWindow = g_pCompositor->m_lastWindow.lock();
+ header.pWindow = Desktop::focusState()->window();
if (!header.pWindow)
return {.success = false, .error = "Window not found"};
@@ -1796,7 +1784,7 @@ SDispatchResult CKeybindManager::toggleSplit(std::string args) {
SDispatchResult CKeybindManager::swapSplit(std::string args) {
SLayoutMessageHeader header;
- header.pWindow = g_pCompositor->m_lastWindow.lock();
+ header.pWindow = Desktop::focusState()->window();
if (!header.pWindow)
return {.success = false, .error = "Window not found"};
@@ -1826,7 +1814,7 @@ SDispatchResult CKeybindManager::alterSplitRatio(std::string args) {
return {.success = false, .error = "Splitratio invalid in alterSplitRatio!"};
}
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "Window not found"};
@@ -1856,7 +1844,7 @@ SDispatchResult CKeybindManager::moveCursorToCorner(std::string arg) {
return {.success = false, .error = "moveCursorToCorner, corner not 0 - 3."};
}
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "Window not found"};
@@ -1918,7 +1906,7 @@ SDispatchResult CKeybindManager::moveCursor(std::string args) {
SDispatchResult CKeybindManager::workspaceOpt(std::string args) {
// current workspace
- const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
+ const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!PWORKSPACE)
return {.success = false, .error = "Workspace not found"}; // ????
@@ -1965,7 +1953,7 @@ SDispatchResult CKeybindManager::workspaceOpt(std::string args) {
}
// recalc mon
- g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_lastMonitor->m_id);
+ g_pLayoutManager->getCurrentLayout()->recalculateMonitor(Desktop::focusState()->monitor()->m_id);
return {};
}
@@ -2011,7 +1999,7 @@ SDispatchResult CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args)
}
// get the current workspace
- const auto PCURRENTWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
+ const auto PCURRENTWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!PCURRENTWORKSPACE) {
Debug::log(ERR, "moveCurrentWorkspaceToMonitor invalid workspace!");
return {.success = false, .error = "moveCurrentWorkspaceToMonitor invalid workspace!"};
@@ -2062,7 +2050,7 @@ SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args
return {.success = false, .error = "focusWorkspaceOnCurrentMonitor invalid workspace!"};
}
- const auto PCURRMONITOR = g_pCompositor->m_lastMonitor.lock();
+ const auto PCURRMONITOR = Desktop::focusState()->monitor();
if (!PCURRMONITOR) {
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor monitor doesn't exist!");
@@ -2117,7 +2105,7 @@ SDispatchResult CKeybindManager::toggleSpecialWorkspace(std::string args) {
}
bool requestedWorkspaceIsAlreadyOpen = false;
- const auto PMONITOR = g_pCompositor->m_lastMonitor;
+ const auto PMONITOR = Desktop::focusState()->monitor();
auto specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID();
for (auto const& m : g_pCompositor->m_monitors) {
@@ -2183,7 +2171,7 @@ SDispatchResult CKeybindManager::forceRendererReload(std::string args) {
}
SDispatchResult CKeybindManager::resizeActive(std::string args) {
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "No window found"};
@@ -2205,7 +2193,7 @@ SDispatchResult CKeybindManager::resizeActive(std::string args) {
}
SDispatchResult CKeybindManager::moveActive(std::string args) {
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "No window found"};
@@ -2271,9 +2259,9 @@ SDispatchResult CKeybindManager::resizeWindow(std::string args) {
}
SDispatchResult CKeybindManager::circleNext(std::string arg) {
- if (g_pCompositor->m_lastWindow.expired()) {
+ if (!Desktop::focusState()->window()) {
// if we have a clear focus, find the first window and get the next focusable.
- const auto PWS = g_pCompositor->m_lastMonitor->m_activeWorkspace;
+ const auto PWS = Desktop::focusState()->monitor()->m_activeWorkspace;
if (PWS && PWS->getWindows() > 0) {
const auto PWINDOW = PWS->getFirstWindow();
switchToWindow(PWINDOW);
@@ -2294,8 +2282,8 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) {
const auto PREV = args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l");
const auto NEXT = args.contains("next") || args.contains("n"); // prev is default in classic alt+tab
const auto HIST = args.contains("hist") || args.contains("h");
- const auto& w = HIST ? g_pCompositor->getWindowCycleHist(g_pCompositor->m_lastWindow, true, floatStatus, VISIBLE, NEXT) :
- g_pCompositor->getWindowCycle(g_pCompositor->m_lastWindow.lock(), true, floatStatus, VISIBLE, PREV);
+ const auto& w = HIST ? g_pCompositor->getWindowCycleHist(Desktop::focusState()->window(), true, floatStatus, VISIBLE, NEXT) :
+ g_pCompositor->getWindowCycle(Desktop::focusState()->window(), true, floatStatus, VISIBLE, PREV);
switchToWindow(w, HIST);
@@ -2318,40 +2306,13 @@ SDispatchResult CKeybindManager::focusWindow(std::string regexp) {
updateRelativeCursorCoords();
- if (g_pCompositor->m_lastMonitor && g_pCompositor->m_lastMonitor->m_activeWorkspace != PWINDOW->m_workspace &&
- g_pCompositor->m_lastMonitor->m_activeSpecialWorkspace != PWINDOW->m_workspace) {
+ if (Desktop::focusState()->monitor() && Desktop::focusState()->monitor()->m_activeWorkspace != PWINDOW->m_workspace &&
+ Desktop::focusState()->monitor()->m_activeSpecialWorkspace != PWINDOW->m_workspace) {
Debug::log(LOG, "Fake executing workspace to move focus");
changeworkspace(PWORKSPACE->getConfigName());
}
- if (PWORKSPACE->m_hasFullscreenWindow) {
- const auto FSWINDOW = PWORKSPACE->getFullscreenWindow();
- const auto FSMODE = PWORKSPACE->m_fullscreenMode;
-
- if (PWINDOW->m_isFloating) {
- // don't make floating implicitly fs
- if (!PWINDOW->m_createdOverFullscreen) {
- g_pCompositor->changeWindowZOrder(PWINDOW, true);
- g_pDesktopAnimationManager->setFullscreenFadeAnimation(
- PWORKSPACE, PWORKSPACE->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
- }
-
- g_pCompositor->focusWindow(PWINDOW);
- } else {
- if (FSWINDOW != PWINDOW && !PWINDOW->m_pinned)
- g_pCompositor->setWindowFullscreenClient(FSWINDOW, FSMODE_NONE);
-
- g_pCompositor->focusWindow(PWINDOW);
-
- if (FSWINDOW != PWINDOW && !PWINDOW->m_pinned)
- g_pCompositor->setWindowFullscreenClient(PWINDOW, FSMODE);
-
- // warp the position + size animation, otherwise it looks weird.
- PWINDOW->m_realPosition->warp();
- PWINDOW->m_realSize->warp();
- }
- } else
- g_pCompositor->focusWindow(PWINDOW);
+ Desktop::focusState()->fullWindowFocus(PWINDOW, nullptr, false);
PWINDOW->warpCursor();
@@ -2363,7 +2324,7 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) {
CVarList vars{args, 0, 's', true};
if (vars.size() == 1)
- PWINDOW = g_pCompositor->m_lastWindow.lock();
+ PWINDOW = Desktop::focusState()->window();
else if (vars.size() == 2)
PWINDOW = g_pCompositor->getWindowByRegex(vars[1]);
else
@@ -2378,7 +2339,7 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) {
}
SDispatchResult CKeybindManager::toggleSwallow(std::string args) {
- PHLWINDOWREF pWindow = g_pCompositor->m_lastWindow;
+ PHLWINDOWREF pWindow = Desktop::focusState()->window();
if (!valid(pWindow) || !valid(pWindow->m_swallowed))
return {};
@@ -2436,7 +2397,7 @@ SDispatchResult CKeybindManager::pass(std::string regexp) {
return {.success = false, .error = "No kb in pass?"};
}
- const auto XWTOXW = PWINDOW->m_isX11 && g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_isX11;
+ const auto XWTOXW = PWINDOW->m_isX11 && Desktop::focusState()->window() && Desktop::focusState()->window()->m_isX11;
const auto LASTMOUSESURF = g_pSeatManager->m_state.pointerFocus.lock();
const auto LASTKBSURF = g_pSeatManager->m_state.keyboardFocus.lock();
@@ -2573,7 +2534,7 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) {
const std::string regexp = ARGS[2];
PHLWINDOW PWINDOW = nullptr;
- const auto LASTSURFACE = g_pCompositor->m_lastFocus.lock();
+ const auto LASTSURFACE = Desktop::focusState()->surface();
//if regexp is not empty, send shortcut to current window
//else, don't change focus
@@ -2598,10 +2559,10 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) {
//copied the rest from pass and modified it
// if wl -> xwl, activate destination
- if (PWINDOW && PWINDOW->m_isX11 && g_pCompositor->m_lastWindow && !g_pCompositor->m_lastWindow->m_isX11)
+ if (PWINDOW && PWINDOW->m_isX11 && Desktop::focusState()->window() && !Desktop::focusState()->window()->m_isX11)
g_pXWaylandManager->activateSurface(PWINDOW->m_wlSurface->resource(), true);
// if xwl -> xwl, send to current. Timing issues make this not work.
- if (PWINDOW && PWINDOW->m_isX11 && g_pCompositor->m_lastWindow && g_pCompositor->m_lastWindow->m_isX11)
+ if (PWINDOW && PWINDOW->m_isX11 && Desktop::focusState()->window() && Desktop::focusState()->window()->m_isX11)
PWINDOW = nullptr;
g_pSeatManager->sendKeyboardMods(MOD, 0, 0, 0);
@@ -2653,7 +2614,7 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) {
}
SDispatchResult CKeybindManager::layoutmsg(std::string msg) {
- SLayoutMessageHeader hd = {g_pCompositor->m_lastWindow.lock()};
+ SLayoutMessageHeader hd = {Desktop::focusState()->window()};
g_pLayoutManager->getCurrentLayout()->layoutMessage(hd, msg);
return {};
@@ -2690,14 +2651,14 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) {
PHLWINDOW toSwap = nullptr;
- if (g_pCompositor->m_lastWindow.expired())
+ if (!Desktop::focusState()->window())
return {};
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
const auto PLASTCYCLED =
- validMapped(g_pCompositor->m_lastWindow->m_lastCycledWindow) && g_pCompositor->m_lastWindow->m_lastCycledWindow->m_workspace == PLASTWINDOW->m_workspace ?
- g_pCompositor->m_lastWindow->m_lastCycledWindow.lock() :
+ validMapped(Desktop::focusState()->window()->m_lastCycledWindow) && Desktop::focusState()->window()->m_lastCycledWindow->m_workspace == PLASTWINDOW->m_workspace ?
+ Desktop::focusState()->window()->m_lastCycledWindow.lock() :
nullptr;
const bool NEED_PREV = arg == "last" || arg == "l" || arg == "prev" || arg == "p";
@@ -2711,7 +2672,7 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) {
PLASTWINDOW->m_lastCycledWindow = toSwap;
- g_pCompositor->focusWindow(PLASTWINDOW);
+ Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
return {};
}
@@ -2741,7 +2702,7 @@ SDispatchResult CKeybindManager::pinActive(std::string args) {
if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args);
else
- PWINDOW = g_pCompositor->m_lastWindow.lock();
+ PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) {
Debug::log(ERR, "pin: window not found");
@@ -2827,8 +2788,8 @@ SDispatchResult CKeybindManager::changeMouseBindMode(const eMouseBindMode MODE)
}
SDispatchResult CKeybindManager::bringActiveToTop(std::string args) {
- if (g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_isFloating)
- g_pCompositor->changeWindowZOrder(g_pCompositor->m_lastWindow.lock(), true);
+ if (Desktop::focusState()->window() && Desktop::focusState()->window()->m_isFloating)
+ g_pCompositor->changeWindowZOrder(Desktop::focusState()->window(), true);
return {};
}
@@ -2838,8 +2799,8 @@ SDispatchResult CKeybindManager::alterZOrder(std::string args) {
const auto POSITION = args.substr(0, args.find_first_of(','));
auto PWINDOW = g_pCompositor->getWindowByRegex(WINDOWREGEX);
- if (!PWINDOW && g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_isFloating)
- PWINDOW = g_pCompositor->m_lastWindow.lock();
+ if (!PWINDOW && Desktop::focusState()->window() && Desktop::focusState()->window()->m_isFloating)
+ PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) {
Debug::log(ERR, "alterZOrder: no window");
@@ -2875,7 +2836,7 @@ SDispatchResult CKeybindManager::lockGroups(std::string args) {
}
SDispatchResult CKeybindManager::lockActiveGroup(std::string args) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "No window found"};
@@ -2916,7 +2877,7 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn
pWindowInDirection->setGroupCurrent(pWindow);
pWindow->updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
- g_pCompositor->focusWindow(pWindow);
+ Desktop::focusState()->fullWindowFocus(pWindow);
pWindow->warpCursor();
g_pEventManager->postEvent(SHyprIPCEvent{"moveintogroup", std::format("{:x}", rc<uintptr_t>(pWindow.get()))});
@@ -2953,10 +2914,10 @@ void CKeybindManager::moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string&
}
if (*BFOCUSREMOVEDWINDOW) {
- g_pCompositor->focusWindow(pWindow);
+ Desktop::focusState()->fullWindowFocus(pWindow);
pWindow->warpCursor();
} else {
- g_pCompositor->focusWindow(PWINDOWPREV);
+ Desktop::focusState()->fullWindowFocus(PWINDOWPREV);
PWINDOWPREV->warpCursor();
}
@@ -2976,7 +2937,7 @@ SDispatchResult CKeybindManager::moveIntoGroup(std::string args) {
return {.success = false, .error = std::format("Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)};
}
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW || PWINDOW->m_groupData.deny)
return {};
@@ -3006,7 +2967,7 @@ SDispatchResult CKeybindManager::moveOutOfGroup(std::string args) {
if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args);
else
- PWINDOW = g_pCompositor->m_lastWindow.lock();
+ PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "No window found"};
@@ -3029,7 +2990,7 @@ SDispatchResult CKeybindManager::moveWindowOrGroup(std::string args) {
return {.success = false, .error = std::format("Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg)};
}
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW)
return {.success = false, .error = "No window found"};
@@ -3088,7 +3049,7 @@ SDispatchResult CKeybindManager::setIgnoreGroupLock(std::string args) {
}
SDispatchResult CKeybindManager::denyWindowFromGroup(std::string args) {
- const auto PWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW || (PWINDOW && PWINDOW->m_groupData.pNextWindow.lock()))
return {};
@@ -3120,7 +3081,7 @@ SDispatchResult CKeybindManager::global(std::string args) {
SDispatchResult CKeybindManager::moveGroupWindow(std::string args) {
const auto BACK = args == "b" || args == "prev";
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "No window found"};
@@ -3186,7 +3147,7 @@ SDispatchResult CKeybindManager::setProp(std::string args) {
if (vars.size() < 3)
return {.success = false, .error = "Not enough args"};
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
+ const auto PLASTWINDOW = Desktop::focusState()->window();
const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[0]);
if (!PWINDOW)
@@ -3321,10 +3282,11 @@ SDispatchResult CKeybindManager::setProp(std::string args) {
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
- if (!(PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() == noFocus)) {
- g_pCompositor->focusWindow(nullptr);
- g_pCompositor->focusWindow(PWINDOW);
- g_pCompositor->focusWindow(PLASTWINDOW);
+ if (PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() != noFocus) {
+ // FIXME: what the fuck is going on here? -vax
+ Desktop::focusState()->rawWindowFocus(nullptr);
+ Desktop::focusState()->fullWindowFocus(PWINDOW);
+ Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
}
if (PROP == "no_vrr")
diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp
index b4100beb..b5b200db 100644
--- a/src/managers/KeybindManager.hpp
+++ b/src/managers/KeybindManager.hpp
@@ -163,7 +163,8 @@ class CKeybindManager {
static bool tryMoveFocusToMonitor(PHLMONITOR monitor);
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection);
- static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory = false);
+
+ static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory = false, bool forceFSCycle = false);
static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace, const std::string& execRuleToken = "");
static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);
diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp
index aeabe412..52efab0b 100644
--- a/src/managers/PointerManager.cpp
+++ b/src/managers/PointerManager.cpp
@@ -14,6 +14,7 @@
#include "../managers/HookSystemManager.hpp"
#include "../render/Renderer.hpp"
#include "../render/OpenGL.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "SeatManager.hpp"
#include "../helpers/time/Time.hpp"
#include <cstring>
@@ -799,7 +800,7 @@ void CPointerManager::warpAbsolute(Vector2D abs, SP<IHID> dev) {
auto outputMappedArea = [&mappedArea](const std::string& output) {
if (output == "current") {
- if (const auto PLASTMONITOR = g_pCompositor->m_lastMonitor.lock(); PLASTMONITOR)
+ if (const auto PLASTMONITOR = Desktop::focusState()->monitor(); PLASTMONITOR)
return PLASTMONITOR->logicalBox();
} else if (const auto PMONITOR = g_pCompositor->getMonitorFromString(output); PMONITOR)
return PMONITOR->logicalBox();
@@ -927,7 +928,7 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
listener->frame = pointer->m_pointerEvents.frame.listen([] {
bool shouldSkip = false;
if (!g_pSeatManager->m_mouse.expired() && g_pInputManager->isLocked()) {
- auto PMONITOR = g_pCompositor->m_lastMonitor.get();
+ auto PMONITOR = Desktop::focusState()->monitor().get();
shouldSkip = PMONITOR && PMONITOR->shouldSkipScheduleFrameOnMouseEvent();
}
g_pSeatManager->m_isPointerFrameSkipped = shouldSkip;
diff --git a/src/managers/SeatManager.cpp b/src/managers/SeatManager.cpp
index 3b3d8b04..6d49c97e 100644
--- a/src/managers/SeatManager.cpp
+++ b/src/managers/SeatManager.cpp
@@ -6,6 +6,7 @@
#include "../protocols/PrimarySelection.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../Compositor.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../devices/IKeyboard.hpp"
#include "../desktop/LayerSurface.hpp"
#include "../managers/input/InputManager.hpp"
@@ -659,7 +660,7 @@ void CSeatManager::setGrab(SP<CSeatGrab> grab) {
// If this was a popup grab, focus its parent window to maintain context
if (validMapped(parentWindow)) {
- g_pCompositor->focusWindow(parentWindow);
+ Desktop::focusState()->rawWindowFocus(parentWindow);
Debug::log(LOG, "[seatmgr] Refocused popup parent window {} (follow_mouse={})", parentWindow->m_title, *PFOLLOWMOUSE);
} else
g_pInputManager->refocusLastWindow(PMONITOR);
@@ -689,10 +690,10 @@ void CSeatManager::setGrab(SP<CSeatGrab> grab) {
refocus = layer->m_interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
if (refocus) {
- auto candidate = g_pCompositor->m_lastWindow.lock();
+ auto candidate = Desktop::focusState()->window();
if (candidate)
- g_pCompositor->focusWindow(candidate);
+ Desktop::focusState()->rawWindowFocus(candidate);
}
if (oldGrab->m_onEnd)
diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp
index 391b6dbb..f460e17e 100644
--- a/src/managers/SessionLockManager.cpp
+++ b/src/managers/SessionLockManager.cpp
@@ -4,6 +4,7 @@
#include "../protocols/FractionalScale.hpp"
#include "../protocols/SessionLock.hpp"
#include "../render/Renderer.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "./managers/SeatManager.hpp"
#include "./managers/input/InputManager.hpp"
#include "./managers/eventLoop/EventLoopManager.hpp"
@@ -25,8 +26,8 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
});
listeners.destroy = surface_->m_events.destroy.listen([this] {
- if (pWlrSurface == g_pCompositor->m_lastFocus)
- g_pCompositor->m_lastFocus.reset();
+ if (pWlrSurface == Desktop::focusState()->surface())
+ Desktop::focusState()->surface().reset();
g_pSessionLockManager->removeSessionLockSurface(this);
});
@@ -34,7 +35,7 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
listeners.commit = surface_->m_events.commit.listen([this] {
const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID);
- if (mapped && !g_pCompositor->m_lastFocus)
+ if (mapped && !Desktop::focusState()->surface())
g_pInputManager->simulateMouseMovement();
if (PMONITOR)
@@ -82,13 +83,13 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
m_sessionLock->listeners.destroy = pLock->m_events.destroyed.listen([this] {
m_sessionLock.reset();
- g_pCompositor->focusSurface(nullptr);
+ Desktop::focusState()->rawSurfaceFocus(nullptr);
for (auto const& m : g_pCompositor->m_monitors)
g_pHyprRenderer->damageMonitor(m);
});
- g_pCompositor->focusSurface(nullptr);
+ Desktop::focusState()->rawSurfaceFocus(nullptr);
g_pSeatManager->setGrab(nullptr);
const bool NOACTIVEMONS = std::ranges::all_of(g_pCompositor->m_monitors, [](const auto& m) { return !m->m_enabled || !m->m_dpmsStatus; });
@@ -196,14 +197,14 @@ void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) {
std::erase_if(m_sessionLock->vSessionLockSurfaces, [&](const auto& other) { return pSLS == other.get(); });
- if (g_pCompositor->m_lastFocus)
+ if (Desktop::focusState()->surface())
return;
for (auto const& sls : m_sessionLock->vSessionLockSurfaces) {
if (!sls->mapped)
continue;
- g_pCompositor->focusSurface(sls->surface->surface());
+ Desktop::focusState()->rawSurfaceFocus(sls->surface->surface());
break;
}
}
diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp
index 460e9ecd..38afe4ac 100644
--- a/src/managers/XWaylandManager.cpp
+++ b/src/managers/XWaylandManager.cpp
@@ -1,5 +1,6 @@
#include "XWaylandManager.hpp"
#include "../Compositor.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../events/Events.hpp"
#include "../config/ConfigValue.hpp"
#include "../helpers/Monitor.hpp"
@@ -69,8 +70,8 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) {
pWindow->m_xdgSurface->m_toplevel->setActive(activate);
if (activate) {
- g_pCompositor->m_lastFocus = getWindowSurface(pWindow);
- g_pCompositor->m_lastWindow = pWindow;
+ Desktop::focusState()->surface() = getWindowSurface(pWindow);
+ Desktop::focusState()->window() = pWindow;
}
if (!pWindow->m_pinned)
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index d1d8ec15..bc631ecd 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -9,6 +9,7 @@
#include "../../config/ConfigManager.hpp"
#include "../../desktop/Window.hpp"
#include "../../desktop/LayerSurface.hpp"
+#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/CursorShape.hpp"
#include "../../protocols/IdleInhibit.hpp"
#include "../../protocols/RelativePointer.hpp"
@@ -168,18 +169,18 @@ void CInputManager::simulateMouseMovement() {
}
void CInputManager::sendMotionEventsToFocused() {
- if (!g_pCompositor->m_lastFocus || isConstrained())
+ if (!Desktop::focusState()->surface() || isConstrained())
return;
// todo: this sucks ass
- const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_lastFocus.lock());
- const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_lastFocus.lock());
+ const auto PWINDOW = g_pCompositor->getWindowFromSurface(Desktop::focusState()->surface());
+ const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(Desktop::focusState()->surface());
const auto LOCAL = getMouseCoordsInternal() - (PWINDOW ? PWINDOW->m_realPosition->goal() : (PLS ? Vector2D{PLS->m_geometry.x, PLS->m_geometry.y} : Vector2D{}));
m_emptyFocusCursorSet = false;
- g_pSeatManager->setPointerFocus(g_pCompositor->m_lastFocus.lock(), LOCAL);
+ g_pSeatManager->setPointerFocus(Desktop::focusState()->surface(), LOCAL);
}
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, std::optional<Vector2D> overridePos) {
@@ -223,7 +224,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
m_lastCursorPosFloored = MOUSECOORDSFLOORED;
- const auto PMONITOR = isLocked() && g_pCompositor->m_lastMonitor ? g_pCompositor->m_lastMonitor.lock() : g_pCompositor->getMonitorFromCursor();
+ const auto PMONITOR = isLocked() && Desktop::focusState()->monitor() ? Desktop::focusState()->monitor() : g_pCompositor->getMonitorFromCursor();
// this can happen if there are no displays hooked up to Hyprland
if (PMONITOR == nullptr)
@@ -239,7 +240,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
// constraints
if (!g_pSeatManager->m_mouse.expired() && isConstrained()) {
- const auto SURF = CWLSurface::fromResource(g_pCompositor->m_lastFocus.lock());
+ const auto SURF = CWLSurface::fromResource(Desktop::focusState()->surface());
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
if (CONSTRAINT) {
@@ -263,8 +264,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
Debug::log(ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", rc<uintptr_t>(SURF.get()), rc<uintptr_t>(CONSTRAINT.get()));
}
- if (PMONITOR != g_pCompositor->m_lastMonitor && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
- g_pCompositor->setActiveMonitor(PMONITOR);
+ if (PMONITOR != Desktop::focusState()->monitor() && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
+ Desktop::focusState()->rawMonitorFocus(PMONITOR);
// check for windows that have focus priority like our permission popups
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, FOCUS_PRIORITY);
@@ -277,7 +278,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
const auto PSESSIONLOCKSURFACE = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->m_id);
const auto foundLockSurface = PSESSIONLOCKSURFACE ? PSESSIONLOCKSURFACE->surface->surface() : nullptr;
- g_pCompositor->focusSurface(foundLockSurface);
+ Desktop::focusState()->rawSurfaceFocus(foundLockSurface);
// search for interactable abovelock surfaces for pointer focus, or use session lock surface if not found
for (auto& lsl : PMONITOR->m_layerSurfaceLayers | std::views::reverse) {
@@ -317,7 +318,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
// if we are holding a pointer button,
// and we're not dnd-ing, don't refocus. Keep focus on last surface.
- if (!PROTO::data->dndActive() && !m_currentlyHeldButtons.empty() && g_pCompositor->m_lastFocus && g_pCompositor->m_lastFocus->m_mapped &&
+ if (!PROTO::data->dndActive() && !m_currentlyHeldButtons.empty() && Desktop::focusState()->surface() && Desktop::focusState()->surface()->m_mapped &&
g_pSeatManager->m_state.pointerFocus && !m_hardInput) {
foundSurface = g_pSeatManager->m_state.pointerFocus.lock();
@@ -339,7 +340,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
surfacePos = BOX->pos();
pFoundLayerSurface = HLSurface->getLayer();
if (!pFoundLayerSurface)
- pFoundWindow = !PWINDOW || PWINDOW->isHidden() ? g_pCompositor->m_lastWindow.lock() : PWINDOW;
+ pFoundWindow = !PWINDOW || PWINDOW->isHidden() ? Desktop::focusState()->window() : PWINDOW;
} else // reset foundSurface, find one normally
foundSurface = nullptr;
} else // reset foundSurface, find one normally
@@ -461,7 +462,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords, &pFoundLayerSurface);
if (g_pPointerManager->softwareLockedFor(PMONITOR->m_self.lock()) > 0 && !skipFrameSchedule)
- g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_lastMonitor.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
+ g_pCompositor->scheduleFrameForMonitor(Desktop::focusState()->monitor(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
// FIXME: This will be disabled during DnD operations because we do not exactly follow the spec
// xdg-popup grabs should be keyboard-only, while they are absolute in our case...
@@ -492,8 +493,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
g_pSeatManager->setPointerFocus(nullptr, {});
- if (refocus || g_pCompositor->m_lastWindow.expired()) // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
- g_pCompositor->focusWindow(nullptr);
+ if (refocus || !Desktop::focusState()->window()) // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
+ Desktop::focusState()->rawWindowFocus(nullptr);
return;
}
@@ -514,8 +515,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
bool allowKeyboardRefocus = true;
- if (!refocus && g_pCompositor->m_lastFocus) {
- const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_lastFocus.lock());
+ if (!refocus && Desktop::focusState()->surface()) {
+ const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(Desktop::focusState()->surface());
if (PLS && PLS->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
allowKeyboardRefocus = false;
@@ -556,19 +557,19 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
}
if (FOLLOWMOUSE != 1 && !refocus) {
- if (pFoundWindow != g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow.lock() &&
- ((pFoundWindow->m_isFloating && *PFLOATBEHAVIOR == 2) || (g_pCompositor->m_lastWindow->m_isFloating != pFoundWindow->m_isFloating && *PFLOATBEHAVIOR != 0))) {
+ if (pFoundWindow != Desktop::focusState()->window() && Desktop::focusState()->window() &&
+ ((pFoundWindow->m_isFloating && *PFLOATBEHAVIOR == 2) || (Desktop::focusState()->window()->m_isFloating != pFoundWindow->m_isFloating && *PFLOATBEHAVIOR != 0))) {
// enter if change floating style
if (FOLLOWMOUSE != 3 && allowKeyboardRefocus)
- g_pCompositor->focusWindow(pFoundWindow, foundSurface);
+ Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
} else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3)
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
- if (pFoundWindow == g_pCompositor->m_lastWindow)
+ if (pFoundWindow == Desktop::focusState()->window())
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
- if (FOLLOWMOUSE != 0 || pFoundWindow == g_pCompositor->m_lastWindow)
+ if (FOLLOWMOUSE != 0 || pFoundWindow == Desktop::focusState()->window())
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
if (g_pSeatManager->m_state.pointerFocus == foundSurface)
@@ -578,26 +579,26 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
return; // don't enter any new surfaces
} else {
if (allowKeyboardRefocus && ((FOLLOWMOUSE != 3 && (*PMOUSEREFOCUS || m_lastMouseFocus.lock() != pFoundWindow)) || refocus)) {
- if (m_lastMouseFocus.lock() != pFoundWindow || g_pCompositor->m_lastWindow.lock() != pFoundWindow || g_pCompositor->m_lastFocus != foundSurface || refocus) {
+ if (m_lastMouseFocus.lock() != pFoundWindow || Desktop::focusState()->window() != pFoundWindow || Desktop::focusState()->surface() != foundSurface || refocus) {
m_lastMouseFocus = pFoundWindow;
// TODO: this looks wrong. When over a popup, it constantly is switching.
// Temp fix until that's figured out. Otherwise spams windowrule lookups and other shit.
- if (m_lastMouseFocus.lock() != pFoundWindow || g_pCompositor->m_lastWindow.lock() != pFoundWindow) {
+ if (m_lastMouseFocus.lock() != pFoundWindow || Desktop::focusState()->window() != pFoundWindow) {
if (m_mousePosDelta > *PFOLLOWMOUSETHRESHOLD || refocus) {
const bool hasNoFollowMouse = pFoundWindow && pFoundWindow->m_ruleApplicator->noFollowMouse().valueOrDefault();
if (refocus || !hasNoFollowMouse)
- g_pCompositor->focusWindow(pFoundWindow, foundSurface);
+ Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
}
} else
- g_pCompositor->focusSurface(foundSurface, pFoundWindow);
+ Desktop::focusState()->rawSurfaceFocus(foundSurface, pFoundWindow);
}
}
}
if (g_pSeatManager->m_state.keyboardFocus == nullptr)
- g_pCompositor->focusWindow(pFoundWindow, foundSurface);
+ Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
m_lastFocusOnLS = false;
} else {
@@ -608,7 +609,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
if (pFoundLayerSurface && (pFoundLayerSurface->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) && FOLLOWMOUSE != 3 &&
(allowKeyboardRefocus || pFoundLayerSurface->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)) {
- g_pCompositor->focusSurface(foundSurface);
+ Desktop::focusState()->rawSurfaceFocus(foundSurface);
}
if (pFoundLayerSurface)
@@ -762,7 +763,7 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
break;
if ((g_pSeatManager->m_mouse.expired() || !isConstrained()) /* No constraints */
- && (w && g_pCompositor->m_lastWindow.lock() != w) /* window should change */) {
+ && (w && Desktop::focusState()->window() != w) /* window should change */) {
// a bit hacky
// if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus
if (m_currentlyHeldButtons.size() == 1) {
@@ -791,8 +792,8 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
// notify app if we didn't handle it
g_pSeatManager->sendPointerButton(e.timeMs, e.button, e.state);
- if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_lastMonitor && PMON)
- g_pCompositor->setActiveMonitor(PMON);
+ if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != Desktop::focusState()->monitor() && PMON)
+ Desktop::focusState()->rawMonitorFocus(PMON);
if (g_pSeatManager->m_seatGrab && e.state == WL_POINTER_BUTTON_STATE_PRESSED) {
m_hardInput = true;
@@ -1022,8 +1023,8 @@ void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
keeb->updateLEDs();
// in case m_lastFocus was set without a keyboard
- if (m_keyboards.size() == 1 && g_pCompositor->m_lastFocus)
- g_pSeatManager->setKeyboardFocus(g_pCompositor->m_lastFocus.lock());
+ if (m_keyboards.size() == 1 && Desktop::focusState()->surface())
+ g_pSeatManager->setKeyboardFocus(Desktop::focusState()->surface());
}
void CInputManager::setKeyboardLayout() {
@@ -1577,16 +1578,16 @@ bool CInputManager::refocusLastWindow(PHLMONITOR pMonitor) {
foundSurface = nullptr;
}
- if (!foundSurface && g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_workspace && g_pCompositor->m_lastWindow->m_workspace->isVisibleNotCovered()) {
+ if (!foundSurface && Desktop::focusState()->window() && Desktop::focusState()->window()->m_workspace && Desktop::focusState()->window()->m_workspace->isVisibleNotCovered()) {
// then the last focused window if we're on the same workspace as it
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
- g_pCompositor->focusWindow(PLASTWINDOW);
+ const auto PLASTWINDOW = Desktop::focusState()->window();
+ Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
} else {
// otherwise fall back to a normal refocus.
if (foundSurface && !foundSurface->m_hlSurface->keyboardFocusable()) {
- const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock();
- g_pCompositor->focusWindow(PLASTWINDOW);
+ const auto PLASTWINDOW = Desktop::focusState()->window();
+ Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
}
refocus();
@@ -1615,7 +1616,7 @@ void CInputManager::unconstrainMouse() {
bool CInputManager::isConstrained() {
return std::ranges::any_of(m_constraints, [](auto const& c) {
const auto constraint = c.lock();
- return constraint && constraint->isActive() && constraint->owner()->resource() == g_pCompositor->m_lastFocus;
+ return constraint && constraint->isActive() && constraint->owner()->resource() == Desktop::focusState()->surface();
});
}
@@ -1623,7 +1624,7 @@ bool CInputManager::isLocked() {
if (!isConstrained())
return false;
- const auto SURF = CWLSurface::fromResource(g_pCompositor->m_lastFocus.lock());
+ const auto SURF = CWLSurface::fromResource(Desktop::focusState()->surface());
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
return CONSTRAINT && CONSTRAINT->isLocked();
diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp
index c09d0624..0b434410 100644
--- a/src/managers/input/InputMethodRelay.cpp
+++ b/src/managers/input/InputMethodRelay.cpp
@@ -1,6 +1,5 @@
#include "InputMethodRelay.hpp"
-#include "InputManager.hpp"
-#include "../../Compositor.hpp"
+#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/TextInputV3.hpp"
#include "../../protocols/TextInputV1.hpp"
#include "../../protocols/InputMethodV2.hpp"
@@ -54,17 +53,17 @@ void CInputMethodRelay::onNewIME(SP<CInputMethodV2> pIME) {
Debug::log(LOG, "New input popup");
});
- if (!g_pCompositor->m_lastFocus)
+ if (!Desktop::focusState()->surface())
return;
for (auto const& ti : m_textInputs) {
- if (ti->client() != g_pCompositor->m_lastFocus->client())
+ if (ti->client() != Desktop::focusState()->surface()->client())
continue;
if (ti->isV3())
- ti->enter(g_pCompositor->m_lastFocus.lock());
+ ti->enter(Desktop::focusState()->surface());
else
- ti->onEnabled(g_pCompositor->m_lastFocus.lock());
+ ti->onEnabled(Desktop::focusState()->surface());
}
}
@@ -73,11 +72,11 @@ void CInputMethodRelay::removePopup(CInputPopup* pPopup) {
}
CTextInput* CInputMethodRelay::getFocusedTextInput() {
- if (!g_pCompositor->m_lastFocus)
+ if (!Desktop::focusState()->surface())
return nullptr;
for (auto const& ti : m_textInputs) {
- if (ti->focusedSurface() == g_pCompositor->m_lastFocus)
+ if (ti->focusedSurface() == Desktop::focusState()->surface())
return ti.get();
}
diff --git a/src/managers/input/TextInput.cpp b/src/managers/input/TextInput.cpp
index 5da5e47a..a2b37bb6 100644
--- a/src/managers/input/TextInput.cpp
+++ b/src/managers/input/TextInput.cpp
@@ -1,8 +1,7 @@
#include "TextInput.hpp"
-#include "../../defines.hpp"
#include "InputManager.hpp"
#include "../../protocols/TextInputV1.hpp"
-#include "../../Compositor.hpp"
+#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/TextInputV3.hpp"
#include "../../protocols/InputMethodV2.hpp"
#include "../../protocols/core/Compositor.hpp"
@@ -31,8 +30,8 @@ void CTextInput::initCallbacks() {
g_pInputManager->m_relay.deactivateIME(this);
});
- if (!g_pCompositor->m_lastFocus.expired() && g_pCompositor->m_lastFocus->client() == INPUT->client())
- enter(g_pCompositor->m_lastFocus.lock());
+ if (Desktop::focusState()->surface() && Desktop::focusState()->surface()->client() == INPUT->client())
+ enter(Desktop::focusState()->surface());
} else {
const auto INPUT = m_v1Input.lock();
@@ -60,7 +59,7 @@ void CTextInput::onEnabled(SP<CWLSurfaceResource> surfV1) {
// v1 only, map surface to PTI
if (!isV3()) {
- if (g_pCompositor->m_lastFocus != surfV1 || !m_v1Input->m_active)
+ if (Desktop::focusState()->surface() != surfV1 || !m_v1Input->m_active)
return;
enter(surfV1);
diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp
index 631bd569..e008b50c 100644
--- a/src/managers/input/Touch.cpp
+++ b/src/managers/input/Touch.cpp
@@ -3,11 +3,11 @@
#include "../../protocols/SessionLock.hpp"
#include "../../Compositor.hpp"
#include "../../desktop/LayerSurface.hpp"
+#include "../../desktop/state/FocusState.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../helpers/Monitor.hpp"
#include "../../devices/ITouch.hpp"
#include "../SeatManager.hpp"
-#include "managers/animation/AnimationManager.hpp"
#include "../HookSystemManager.hpp"
#include "debug/Log.hpp"
#include "UnifiedWorkspaceSwipeGesture.hpp"
@@ -26,7 +26,7 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
auto PMONITOR = g_pCompositor->getMonitorFromName(!e.device->m_boundOutput.empty() ? e.device->m_boundOutput : "");
- PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_lastMonitor.lock();
+ PMONITOR = PMONITOR ? PMONITOR : Desktop::focusState()->monitor();
const auto TOUCH_COORDS = PMONITOR->m_position + (e.pos * PMONITOR->m_size);
diff --git a/src/managers/input/UnifiedWorkspaceSwipeGesture.cpp b/src/managers/input/UnifiedWorkspaceSwipeGesture.cpp
index 01b92b48..6dae1e63 100644
--- a/src/managers/input/UnifiedWorkspaceSwipeGesture.cpp
+++ b/src/managers/input/UnifiedWorkspaceSwipeGesture.cpp
@@ -1,6 +1,7 @@
#include "UnifiedWorkspaceSwipeGesture.hpp"
#include "../../Compositor.hpp"
+#include "../../desktop/state/FocusState.hpp"
#include "../../render/Renderer.hpp"
#include "InputManager.hpp"
@@ -12,18 +13,18 @@ void CUnifiedWorkspaceSwipeGesture::begin() {
if (isGestureInProgress())
return;
- const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
+ const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
Debug::log(LOG, "CUnifiedWorkspaceSwipeGesture::begin: Starting a swipe from {}", PWORKSPACE->m_name);
m_workspaceBegin = PWORKSPACE;
m_delta = 0;
- m_monitor = g_pCompositor->m_lastMonitor;
+ m_monitor = Desktop::focusState()->monitor();
m_avgSpeed = 0;
m_speedPoints = 0;
if (PWORKSPACE->m_hasFullscreenWindow) {
- for (auto const& ls : g_pCompositor->m_lastMonitor->m_layerSurfaceLayers[2]) {
+ for (auto const& ls : Desktop::focusState()->monitor()->m_layerSurfaceLayers[2]) {
*ls->m_alpha = 1.f;
}
}
@@ -307,7 +308,7 @@ void CUnifiedWorkspaceSwipeGesture::end() {
g_pInputManager->refocus();
// apply alpha
- for (auto const& ls : g_pCompositor->m_lastMonitor->m_layerSurfaceLayers[2]) {
+ for (auto const& ls : Desktop::focusState()->monitor()->m_layerSurfaceLayers[2]) {
*ls->m_alpha = pSwitchedTo->m_hasFullscreenWindow && pSwitchedTo->m_fullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
}
} \ No newline at end of file
diff --git a/src/managers/input/trackpad/gestures/CloseGesture.cpp b/src/managers/input/trackpad/gestures/CloseGesture.cpp
index ad2d0f45..7beba563 100644
--- a/src/managers/input/trackpad/gestures/CloseGesture.cpp
+++ b/src/managers/input/trackpad/gestures/CloseGesture.cpp
@@ -7,6 +7,7 @@
#include "../../../../managers/eventLoop/EventLoopManager.hpp"
#include "../../../../managers/eventLoop/EventLoopTimer.hpp"
#include "../../../../config/ConfigValue.hpp"
+#include "../../../../desktop/state/FocusState.hpp"
constexpr const float MAX_DISTANCE = 200.F;
@@ -27,7 +28,7 @@ static float lerpVal(const float& from, const float& to, const float& t) {
void CCloseTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
- m_window = g_pCompositor->m_lastWindow;
+ m_window = Desktop::focusState()->window();
if (!m_window)
return;
diff --git a/src/managers/input/trackpad/gestures/FloatGesture.cpp b/src/managers/input/trackpad/gestures/FloatGesture.cpp
index bd8d65ea..ea330750 100644
--- a/src/managers/input/trackpad/gestures/FloatGesture.cpp
+++ b/src/managers/input/trackpad/gestures/FloatGesture.cpp
@@ -1,8 +1,9 @@
#include "FloatGesture.hpp"
-#include "../../../../Compositor.hpp"
#include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp"
+#include "../../../../desktop/state/FocusState.hpp"
+#include "../../../../desktop/Window.hpp"
constexpr const float MAX_DISTANCE = 250.F;
@@ -29,7 +30,7 @@ CFloatTrackpadGesture::CFloatTrackpadGesture(const std::string_view& data) {
void CFloatTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
- m_window = g_pCompositor->m_lastWindow;
+ m_window = Desktop::focusState()->window();
if (!m_window)
return;
diff --git a/src/managers/input/trackpad/gestures/FullscreenGesture.cpp b/src/managers/input/trackpad/gestures/FullscreenGesture.cpp
index 66d86e8b..31592f63 100644
--- a/src/managers/input/trackpad/gestures/FullscreenGesture.cpp
+++ b/src/managers/input/trackpad/gestures/FullscreenGesture.cpp
@@ -1,6 +1,7 @@
#include "FullscreenGesture.hpp"
#include "../../../../Compositor.hpp"
+#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp"
#include "../../../animation/DesktopAnimationManager.hpp"
@@ -29,7 +30,7 @@ CFullscreenTrackpadGesture::CFullscreenTrackpadGesture(const std::string_view& m
void CFullscreenTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
- m_window = g_pCompositor->m_lastWindow;
+ m_window = Desktop::focusState()->window();
if (!m_window)
return;
diff --git a/src/managers/input/trackpad/gestures/MoveGesture.cpp b/src/managers/input/trackpad/gestures/MoveGesture.cpp
index 6ceb02ec..e9338e8a 100644
--- a/src/managers/input/trackpad/gestures/MoveGesture.cpp
+++ b/src/managers/input/trackpad/gestures/MoveGesture.cpp
@@ -1,13 +1,14 @@
#include "MoveGesture.hpp"
-#include "../../../../Compositor.hpp"
+#include "../../../../desktop/state/FocusState.hpp"
+#include "../../../../desktop/Window.hpp"
#include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp"
void CMoveTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
- m_window = g_pCompositor->m_lastWindow;
+ m_window = Desktop::focusState()->window();
m_lastDelta = {};
}
diff --git a/src/managers/input/trackpad/gestures/ResizeGesture.cpp b/src/managers/input/trackpad/gestures/ResizeGesture.cpp
index d788257a..066ebe2a 100644
--- a/src/managers/input/trackpad/gestures/ResizeGesture.cpp
+++ b/src/managers/input/trackpad/gestures/ResizeGesture.cpp
@@ -1,13 +1,14 @@
#include "ResizeGesture.hpp"
-#include "../../../../Compositor.hpp"
+#include "../../../../desktop/state/FocusState.hpp"
+#include "../../../../desktop/Window.hpp"
#include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp"
void CResizeTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e);
- m_window = g_pCompositor->m_lastWindow;
+ m_window = Desktop::focusState()->window();
}
void CResizeTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
diff --git a/src/managers/input/trackpad/gestures/SpecialWorkspaceGesture.cpp b/src/managers/input/trackpad/gestures/SpecialWorkspaceGesture.cpp
index 06a18502..b3643c05 100644
--- a/src/managers/input/trackpad/gestures/SpecialWorkspaceGesture.cpp
+++ b/src/managers/input/trackpad/gestures/SpecialWorkspaceGesture.cpp
@@ -1,7 +1,7 @@
#include "SpecialWorkspaceGesture.hpp"
#include "../../../../Compositor.hpp"
-#include "../../../../managers/LayoutManager.hpp"
+#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp"
#include <hyprutils/memory/Casts.hpp>
@@ -36,7 +36,7 @@ void CSpecialWorkspaceGesture::begin(const ITrackpadGesture::STrackpadGestureBeg
if (m_specialWorkspace) {
m_animatingOut = m_specialWorkspace->isVisible();
- m_monitor = m_animatingOut ? m_specialWorkspace->m_monitor : g_pCompositor->m_lastMonitor;
+ m_monitor = m_animatingOut ? m_specialWorkspace->m_monitor : Desktop::focusState()->monitor();
if (!m_monitor)
return;
@@ -44,7 +44,7 @@ void CSpecialWorkspaceGesture::begin(const ITrackpadGesture::STrackpadGestureBeg
if (!m_animatingOut)
m_monitor->setSpecialWorkspace(m_specialWorkspace);
} else {
- m_monitor = g_pCompositor->m_lastMonitor;
+ m_monitor = Desktop::focusState()->monitor();
if (!m_monitor)
return;
diff --git a/src/managers/input/trackpad/gestures/WorkspaceSwipeGesture.cpp b/src/managers/input/trackpad/gestures/WorkspaceSwipeGesture.cpp
index 793bfd77..0ccd2462 100644
--- a/src/managers/input/trackpad/gestures/WorkspaceSwipeGesture.cpp
+++ b/src/managers/input/trackpad/gestures/WorkspaceSwipeGesture.cpp
@@ -1,7 +1,7 @@
#include "WorkspaceSwipeGesture.hpp"
#include "../../../../Compositor.hpp"
-#include "../../../../managers/input/InputManager.hpp"
+#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp"
#include "../../UnifiedWorkspaceSwipeGesture.hpp"
@@ -16,7 +16,7 @@ void CWorkspaceSwipeGesture::begin(const ITrackpadGesture::STrackpadGestureBegin
int onMonitor = 0;
for (auto const& w : g_pCompositor->getWorkspaces()) {
- if (w->m_monitor == g_pCompositor->m_lastMonitor && !g_pCompositor->isWorkspaceSpecial(w->m_id))
+ if (w->m_monitor == Desktop::focusState()->monitor() && !g_pCompositor->isWorkspaceSpecial(w->m_id))
onMonitor++;
}
diff --git a/src/protocols/FocusGrab.cpp b/src/protocols/FocusGrab.cpp
index c6530826..b761d264 100644
--- a/src/protocols/FocusGrab.cpp
+++ b/src/protocols/FocusGrab.cpp
@@ -3,6 +3,7 @@
#include <hyprland-focus-grab-v1.hpp>
#include "../managers/input/InputManager.hpp"
#include "../managers/SeatManager.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "core/Compositor.hpp"
#include <cstdint>
#include <wayland-server.h>
@@ -104,7 +105,7 @@ void CFocusGrab::refocusKeyboard() {
}
if (surface)
- g_pCompositor->focusSurface(surface);
+ Desktop::focusState()->rawSurfaceFocus(surface);
else
LOGM(ERR, "CFocusGrab::refocusKeyboard called with no committed surfaces. This should never happen.");
}
diff --git a/src/protocols/ForeignToplevelWlr.cpp b/src/protocols/ForeignToplevelWlr.cpp
index 86b68584..ebe8163a 100644
--- a/src/protocols/ForeignToplevelWlr.cpp
+++ b/src/protocols/ForeignToplevelWlr.cpp
@@ -1,9 +1,10 @@
#include "ForeignToplevelWlr.hpp"
+#include "core/Output.hpp"
#include <algorithm>
#include "../Compositor.hpp"
-#include "managers/input/InputManager.hpp"
-#include "protocols/core/Output.hpp"
-#include "render/Renderer.hpp"
+#include "../managers/input/InputManager.hpp"
+#include "../desktop/state/FocusState.hpp"
+#include "../render/Renderer.hpp"
#include "../managers/HookSystemManager.hpp"
#include "../managers/EventManager.hpp"
@@ -50,7 +51,7 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHand
if (PWINDOW->m_workspace != monitor->m_activeWorkspace) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, monitor->m_activeWorkspace);
- g_pCompositor->setActiveMonitor(monitor);
+ Desktop::focusState()->rawMonitorFocus(monitor);
}
}
}
@@ -178,7 +179,7 @@ void CForeignToplevelHandleWlr::sendState() {
wl_array state;
wl_array_init(&state);
- if (PWINDOW == g_pCompositor->m_lastWindow) {
+ if (PWINDOW == Desktop::focusState()->window()) {
auto p = sc<uint32_t*>(wl_array_add(&state, sizeof(uint32_t)));
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
}
@@ -216,7 +217,7 @@ CForeignToplevelWlrManager::CForeignToplevelWlrManager(SP<CZwlrForeignToplevelMa
onMap(w);
}
- m_lastFocus = g_pCompositor->m_lastWindow;
+ m_lastFocus = Desktop::focusState()->window();
}
void CForeignToplevelWlrManager::onMap(PHLWINDOW pWindow) {
diff --git a/src/protocols/InputMethodV2.cpp b/src/protocols/InputMethodV2.cpp
index d66d1f24..eaf7f141 100644
--- a/src/protocols/InputMethodV2.cpp
+++ b/src/protocols/InputMethodV2.cpp
@@ -1,7 +1,8 @@
#include "InputMethodV2.hpp"
-#include "../Compositor.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../managers/SeatManager.hpp"
#include "../devices/IKeyboard.hpp"
+#include "../helpers/MiscFunctions.hpp"
#include <sys/mman.h>
#include "core/Compositor.hpp"
#include <cstring>
@@ -96,8 +97,8 @@ CInputMethodPopupV2::CInputMethodPopupV2(SP<CZwpInputPopupSurfaceV2> resource_,
m_listeners.destroySurface.reset();
m_listeners.commitSurface.reset();
- if (g_pCompositor->m_lastFocus == m_surface)
- g_pCompositor->m_lastFocus.reset();
+ if (Desktop::focusState()->surface() == m_surface)
+ Desktop::focusState()->surface().reset();
m_surface.reset();
});
diff --git a/src/protocols/PointerConstraints.cpp b/src/protocols/PointerConstraints.cpp
index 24ccc980..5ecaa43b 100644
--- a/src/protocols/PointerConstraints.cpp
+++ b/src/protocols/PointerConstraints.cpp
@@ -1,6 +1,7 @@
#include "PointerConstraints.hpp"
#include "../desktop/WLSurface.hpp"
-#include "../Compositor.hpp"
+#include "../desktop/state/FocusState.hpp"
+#include "../desktop/Window.hpp"
#include "../config/ConfigValue.hpp"
#include "../managers/SeatManager.hpp"
#include "core/Compositor.hpp"
@@ -242,7 +243,7 @@ void CPointerConstraintsProtocol::onNewConstraint(SP<CPointerConstraint> constra
g_pInputManager->m_constraints.emplace_back(constraint);
- if (g_pCompositor->m_lastFocus == OWNER->resource())
+ if (Desktop::focusState()->surface() == OWNER->resource())
constraint->activate();
}
diff --git a/src/protocols/SessionLock.cpp b/src/protocols/SessionLock.cpp
index 6ff9171e..ab70a0d4 100644
--- a/src/protocols/SessionLock.cpp
+++ b/src/protocols/SessionLock.cpp
@@ -1,5 +1,4 @@
#include "SessionLock.hpp"
-#include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "FractionalScale.hpp"
#include "LockNotify.hpp"
@@ -7,6 +6,7 @@
#include "core/Output.hpp"
#include "../helpers/Monitor.hpp"
#include "../render/Renderer.hpp"
+#include "../desktop/state/FocusState.hpp"
CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_, SP<CWLSurfaceResource> surface_, PHLMONITOR pMonitor_, WP<CSessionLock> owner_) :
m_resource(resource_), m_sessionLock(owner_), m_surface(surface_), m_monitor(pMonitor_) {
@@ -51,8 +51,8 @@ CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_,
m_surface->unmap();
m_listeners.surfaceCommit.reset();
m_listeners.surfaceDestroy.reset();
- if (g_pCompositor->m_lastFocus == m_surface)
- g_pCompositor->m_lastFocus.reset();
+ if (Desktop::focusState()->surface() == m_surface)
+ Desktop::focusState()->surface().reset();
m_surface.reset();
});
diff --git a/src/protocols/ShortcutsInhibit.cpp b/src/protocols/ShortcutsInhibit.cpp
index 749390cd..e42bf172 100644
--- a/src/protocols/ShortcutsInhibit.cpp
+++ b/src/protocols/ShortcutsInhibit.cpp
@@ -1,6 +1,7 @@
#include "ShortcutsInhibit.hpp"
#include <algorithm>
#include "../Compositor.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "core/Compositor.hpp"
CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, SP<CWLSurfaceResource> surf) : m_resource(resource_), m_surface(surf) {
@@ -67,14 +68,14 @@ void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitMa
}
bool CKeyboardShortcutsInhibitProtocol::isInhibited() {
- if (!g_pCompositor->m_lastFocus)
+ if (!Desktop::focusState()->surface())
return false;
- if (const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_lastFocus.lock()); PWINDOW && PWINDOW->m_ruleApplicator->noShortcutsInhibit().valueOrDefault())
+ if (const auto PWINDOW = g_pCompositor->getWindowFromSurface(Desktop::focusState()->surface()); PWINDOW && PWINDOW->m_ruleApplicator->noShortcutsInhibit().valueOrDefault())
return false;
for (auto const& in : m_inhibitors) {
- if (in->surface() != g_pCompositor->m_lastFocus)
+ if (in->surface() != Desktop::focusState()->surface())
continue;
return true;
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index b2ec69f3..d93e7196 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -14,6 +14,7 @@
#include "../config/ConfigManager.hpp"
#include "../managers/PointerManager.hpp"
#include "../desktop/LayerSurface.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../protocols/ColorManagement.hpp"
@@ -424,7 +425,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmRenderNode.fd >
auto PMONITOR = g_pCompositor->getMonitorFromName(!E.device->m_boundOutput.empty() ? E.device->m_boundOutput : "");
- PMONITOR = PMONITOR ? PMONITOR : g_pCompositor->m_lastMonitor.lock();
+ PMONITOR = PMONITOR ? PMONITOR : Desktop::focusState()->monitor();
const auto TOUCH_COORDS = PMONITOR->m_position + (E.pos * PMONITOR->m_size);
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index c8c44ad0..3b811ce8 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -14,6 +14,7 @@
#include "../managers/LayoutManager.hpp"
#include "../desktop/Window.hpp"
#include "../desktop/LayerSurface.hpp"
+#include "../desktop/state/FocusState.hpp"
#include "../protocols/SessionLock.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/XDGShell.hpp"
@@ -168,7 +169,7 @@ CHyprRenderer::CHyprRenderer() {
w->m_wlSurface->resource()->frame(Time::steadyNow());
auto FEEDBACK = makeUnique<CQueuedPresentationData>(w->m_wlSurface->resource());
- FEEDBACK->attachMonitor(g_pCompositor->m_lastMonitor.lock());
+ FEEDBACK->attachMonitor(Desktop::focusState()->monitor());
FEEDBACK->discarded();
PROTO::presentation->queueData(std::move(FEEDBACK));
}
@@ -403,7 +404,7 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo
continue;
// render active window after all others of this pass
- if (w == g_pCompositor->m_lastWindow) {
+ if (w == Desktop::focusState()->window()) {
lastWindow = w.lock();
continue;
}
@@ -1407,7 +1408,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
renderLockscreen(pMonitor, NOW, renderBox);
- if (pMonitor == g_pCompositor->m_lastMonitor) {
+ if (pMonitor == Desktop::focusState()->monitor()) {
g_pHyprNotificationOverlay->draw(pMonitor);
g_pHyprError->draw();
}
@@ -1895,7 +1896,7 @@ void CHyprRenderer::arrangeLayersForMonitor(const MONITORID& monitor) {
CBox usableArea = {PMONITOR->m_position.x, PMONITOR->m_position.y, PMONITOR->m_size.x, PMONITOR->m_size.y};
- if (g_pHyprError->active() && g_pCompositor->m_lastMonitor == PMONITOR->m_self) {
+ if (g_pHyprError->active() && Desktop::focusState()->monitor() == PMONITOR->m_self) {
const auto HEIGHT = g_pHyprError->height();
if (*BAR_POSITION == 0) {
PMONITOR->m_reservedTopLeft.y = HEIGHT;
diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp
index 3b95d749..93a17341 100644
--- a/src/render/decorations/CHyprGroupBarDecoration.cpp
+++ b/src/render/decorations/CHyprGroupBarDecoration.cpp
@@ -1,6 +1,7 @@
#include "CHyprGroupBarDecoration.hpp"
#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
+#include "../../desktop/state/FocusState.hpp"
#include "managers/LayoutManager.hpp"
#include <ranges>
#include <pango/pangocairo.h>
@@ -160,7 +161,7 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
const auto* const PCOLACTIVE = GROUPLOCKED ? GROUPCOLACTIVELOCKED : GROUPCOLACTIVE;
const auto* const PCOLINACTIVE = GROUPLOCKED ? GROUPCOLINACTIVELOCKED : GROUPCOLINACTIVE;
- CHyprColor color = m_dwGroupMembers[WINDOWINDEX].lock() == g_pCompositor->m_lastWindow.lock() ? PCOLACTIVE->m_colors[0] : PCOLINACTIVE->m_colors[0];
+ CHyprColor color = m_dwGroupMembers[WINDOWINDEX].lock() == Desktop::focusState()->window() ? PCOLACTIVE->m_colors[0] : PCOLINACTIVE->m_colors[0];
color.a *= a;
if (!rect.empty()) {
@@ -195,8 +196,8 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
if (!rect.empty()) {
if (*PGRADIENTS) {
- const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_lastWindow ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
- (GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
+ const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == Desktop::focusState()->window() ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
+ (GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
if (GRADIENTTEX->m_texID) {
CTexPassElement::SRenderData data;
data.tex = GRADIENTTEX;
@@ -234,7 +235,7 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
.get();
SP<CTexture> titleTex;
- if (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_lastWindow)
+ if (m_dwGroupMembers[WINDOWINDEX] == Desktop::focusState()->window())
titleTex = GROUPLOCKED ? pTitleTex->m_texLockedActive : pTitleTex->m_texActive;
else
titleTex = GROUPLOCKED ? pTitleTex->m_texLockedInactive : pTitleTex->m_texInactive;
@@ -308,10 +309,10 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float
static void renderGradientTo(SP<CTexture> tex, CGradientValueData* grad) {
- if (!g_pCompositor->m_lastMonitor)
+ if (!Desktop::focusState()->monitor())
return;
- const Vector2D& bufferSize = g_pCompositor->m_lastMonitor->m_pixelSize;
+ const Vector2D& bufferSize = Desktop::focusState()->monitor()->m_pixelSize;
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
const auto CAIRO = cairo_create(CAIROSURFACE);
@@ -415,7 +416,7 @@ bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
g_pInputManager->m_currentlyDraggedWindow = pWindow;
if (!g_pCompositor->isWindowActive(pWindow))
- g_pCompositor->focusWindow(pWindow);
+ Desktop::focusState()->rawWindowFocus(pWindow);
return true;
}
@@ -529,7 +530,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
const auto STACKPAD = *PSTACKED && (BARRELATIVEY - (m_barHeight + *POUTERGAP) * WINDOWINDEX < *POUTERGAP);
if (TABPAD || STACKPAD) {
if (!g_pCompositor->isWindowActive(m_window.lock()))
- g_pCompositor->focusWindow(m_window.lock());
+ Desktop::focusState()->rawWindowFocus(m_window.lock());
return true;
}
@@ -539,7 +540,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
pWindow->setGroupCurrent(pWindow);
if (!g_pCompositor->isWindowActive(pWindow) && *PFOLLOWMOUSE != 3)
- g_pCompositor->focusWindow(pWindow);
+ Desktop::focusState()->rawWindowFocus(pWindow);
if (pWindow->m_isFloating)
g_pCompositor->changeWindowZOrder(pWindow, true);
diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp
index 3e14d787..8970e2af 100644
--- a/src/render/pass/Pass.cpp
+++ b/src/render/pass/Pass.cpp
@@ -2,12 +2,13 @@
#include "../OpenGL.hpp"
#include <algorithm>
#include <ranges>
+#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../desktop/WLSurface.hpp"
#include "../../managers/SeatManager.hpp"
#include "../../managers/eventLoop/EventLoopManager.hpp"
#include "../../render/Renderer.hpp"
-#include "../../Compositor.hpp"
+#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/core/Compositor.hpp"
bool CRenderPass::empty() const {
@@ -242,8 +243,8 @@ void CRenderPass::renderDebugData() {
renderHLSurface(m_debugData.keyboardFocusText, g_pSeatManager->m_state.keyboardFocus.lock(), Colors::PURPLE.modifyA(0.1F));
renderHLSurface(m_debugData.pointerFocusText, g_pSeatManager->m_state.pointerFocus.lock(), Colors::ORANGE.modifyA(0.1F));
- if (g_pCompositor->m_lastWindow)
- renderHLSurface(m_debugData.lastWindowText, g_pCompositor->m_lastWindow->m_wlSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F));
+ if (Desktop::focusState()->window())
+ renderHLSurface(m_debugData.lastWindowText, Desktop::focusState()->window()->m_wlSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F));
if (g_pSeatManager->m_state.pointerFocus) {
if (g_pSeatManager->m_state.pointerFocus->m_current.input.intersect(CBox{{}, g_pSeatManager->m_state.pointerFocus->m_current.size}).getExtents().size() !=
diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp
index 9abd955a..316a9788 100644
--- a/src/xwayland/XWM.cpp
+++ b/src/xwayland/XWM.cpp
@@ -20,6 +20,7 @@
#include "../managers/ANRManager.hpp"
#include "../protocols/XWaylandShell.hpp"
#include "../protocols/core/Compositor.hpp"
+#include "../desktop/state/FocusState.hpp"
using Hyprutils::Memory::CUniquePointer;
using namespace Hyprutils::OS;
@@ -1037,7 +1038,7 @@ void CXWM::activateSurface(SP<CXWaylandSurface> surf, bool activate) {
if ((surf == m_focusedSurface && activate) || (surf && surf->m_overrideRedirect))
return;
- if (!surf || (!activate && g_pCompositor->m_lastWindow && !g_pCompositor->m_lastWindow->m_isX11)) {
+ if (!surf || (!activate && Desktop::focusState()->window() && !Desktop::focusState()->window()->m_isX11)) {
setActiveWindow(XCB_WINDOW_NONE);
focusWindow(nullptr);
} else {