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.
This commit is contained in:
Nikolai Nechaev 2025-11-26 07:44:26 +09:00 committed by GitHub
parent 1c1746de61
commit 40d8fa8491
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 1003 additions and 694 deletions

View file

@ -14,6 +14,7 @@
#include <src/desktop/rule/windowRule/WindowRuleEffectContainer.hpp> #include <src/desktop/rule/windowRule/WindowRuleEffectContainer.hpp>
#include <src/desktop/rule/windowRule/WindowRuleApplicator.hpp> #include <src/desktop/rule/windowRule/WindowRuleApplicator.hpp>
#include <src/Compositor.hpp> #include <src/Compositor.hpp>
#include <src/desktop/state/FocusState.hpp>
#undef private #undef private
#include <hyprutils/utils/ScopeGuard.hpp> #include <hyprutils/utils/ScopeGuard.hpp>
@ -45,7 +46,7 @@ static SDispatchResult test(std::string in) {
// Trigger a snap move event for the active window // Trigger a snap move event for the active window
static SDispatchResult snapMove(std::string in) { static SDispatchResult snapMove(std::string in) {
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW->m_isFloating) if (!PLASTWINDOW->m_isFloating)
return {.success = false, .error = "Window must be floating"}; return {.success = false, .error = "Window must be floating"};
@ -259,13 +260,15 @@ static SDispatchResult addRule(std::string in) {
} }
static SDispatchResult checkRule(std::string in) { static SDispatchResult checkRule(std::string in) {
if (!g_pCompositor->m_lastWindow) const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW)
return {.success = false, .error = "No window"}; return {.success = false, .error = "No window"};
if (!g_pCompositor->m_lastWindow->m_ruleApplicator->m_otherProps.props.contains(ruleIDX)) if (!PLASTWINDOW->m_ruleApplicator->m_otherProps.props.contains(ruleIDX))
return {.success = false, .error = "No rule"}; return {.success = false, .error = "No rule"};
if (g_pCompositor->m_lastWindow->m_ruleApplicator->m_otherProps.props[ruleIDX]->effect != "effect") if (PLASTWINDOW->m_ruleApplicator->m_otherProps.props[ruleIDX]->effect != "effect")
return {.success = false, .error = "Effect isn't \"effect\""}; return {.success = false, .error = "Effect isn't \"effect\""};
return {}; return {};

View file

@ -53,7 +53,7 @@ static bool test() {
NLog::log("{}Testing new_window_takes_over_fullscreen", Colors::YELLOW); NLog::log("{}Testing new_window_takes_over_fullscreen", Colors::YELLOW);
OK(getFromSocket("/keyword misc:new_window_takes_over_fullscreen 0")); OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 0"));
Tests::spawnKitty("kitty_A"); Tests::spawnKitty("kitty_A");
@ -73,7 +73,16 @@ static bool test() {
EXPECT_CONTAINS(str, "kitty_A"); EXPECT_CONTAINS(str, "kitty_A");
} }
OK(getFromSocket("/keyword misc:new_window_takes_over_fullscreen 1")); OK(getFromSocket("/dispatch focuswindow class:kitty_B"));
{
// should be ignored as per focus_under_fullscreen 0
auto str = getFromSocket("/activewindow");
EXPECT_CONTAINS(str, "fullscreen: 2");
EXPECT_CONTAINS(str, "kitty_A");
}
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 1"));
Tests::spawnKitty("kitty_C"); Tests::spawnKitty("kitty_C");
@ -83,7 +92,7 @@ static bool test() {
EXPECT_CONTAINS(str, "kitty_C"); EXPECT_CONTAINS(str, "kitty_C");
} }
OK(getFromSocket("/keyword misc:new_window_takes_over_fullscreen 2")); OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 2"));
Tests::spawnKitty("kitty_D"); Tests::spawnKitty("kitty_D");
@ -93,7 +102,7 @@ static bool test() {
EXPECT_CONTAINS(str, "kitty_D"); EXPECT_CONTAINS(str, "kitty_D");
} }
OK(getFromSocket("/keyword misc:new_window_takes_over_fullscreen 0")); OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 0"));
Tests::killAllWindows(); Tests::killAllWindows();
@ -138,6 +147,7 @@ static bool test() {
Tests::spawnKitty("kitty_A"); Tests::spawnKitty("kitty_A");
Tests::spawnKitty("kitty_B"); Tests::spawnKitty("kitty_B");
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set")); OK(getFromSocket("/dispatch fullscreen 0 set"));
{ {

View file

@ -1,6 +1,9 @@
#include <cmath> #include <cmath>
#include <thread>
#include <chrono> #include <chrono>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <thread>
#include <hyprutils/os/Process.hpp> #include <hyprutils/os/Process.hpp>
#include <hyprutils/memory/WeakPtr.hpp> #include <hyprutils/memory/WeakPtr.hpp>
@ -11,9 +14,9 @@
static int ret = 0; static int ret = 0;
static bool spawnKitty(const std::string& class_) { static bool spawnKitty(const std::string& class_, const std::vector<std::string>& args = {}) {
NLog::log("{}Spawning {}", Colors::YELLOW, class_); NLog::log("{}Spawning {}", Colors::YELLOW, class_);
if (!Tests::spawnKitty(class_)) { if (!Tests::spawnKitty(class_, args)) {
NLog::log("{}Error: {} did not spawn", Colors::RED, class_); NLog::log("{}Error: {} did not spawn", Colors::RED, class_);
return false; return false;
} }
@ -193,6 +196,153 @@ static void testGroupRules() {
Tests::killAllWindows(); Tests::killAllWindows();
} }
static bool isActiveWindow(const std::string& class_, char fullscreen, bool log = true) {
std::string activeWin = getFromSocket("/activewindow");
auto winClass = getWindowAttribute(activeWin, "class:");
auto winFullscreen = getWindowAttribute(activeWin, "fullscreen:").back();
if (winClass.substr(strlen("class: ")) == class_ && winFullscreen == fullscreen)
return true;
else {
if (log)
NLog::log("{}Wrong active window: expected class {} fullscreen '{}', found class {}, fullscreen '{}'", Colors::RED, class_, fullscreen, winClass, winFullscreen);
return false;
}
}
static bool waitForActiveWindow(const std::string& class_, char fullscreen, int maxTries = 50) {
int cnt = 0;
while (!isActiveWindow(class_, fullscreen, false)) {
++cnt;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (cnt > maxTries) {
return isActiveWindow(class_, fullscreen, true);
}
}
return true;
}
/// Tests behavior of a window being focused when on that window's workspace
/// another fullscreen window exists.
static bool testWindowFocusOnFullscreenConflict() {
if (!spawnKitty("kitty_A"))
return false;
if (!spawnKitty("kitty_B"))
return false;
OK(getFromSocket("/keyword misc:focus_on_activate true"));
auto spawnKittyActivating = [] -> std::string {
// `XXXXXX` is what `mkstemp` expects to find in the string
std::string tmpFilename = (std::filesystem::temp_directory_path() / "XXXXXX").string();
int fd = mkstemp(tmpFilename.data());
if (fd < 0) {
NLog::log("{}Error: could not create tmp file: errno {}", Colors::RED, errno);
return "";
}
(void)close(fd);
bool ok = spawnKitty("kitty_activating",
{"-o", "allow_remote_control=yes", "--", "/bin/sh", "-c", "while [ -f \"" + tmpFilename + "\" ]; do :; done; kitten @ focus-window; sleep infinity"});
if (!ok) {
NLog::log("{}Error: failed to spawn kitty", Colors::RED);
return "";
}
return tmpFilename;
};
// Unfullscreen on conflict
{
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 2"));
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus the same window
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus a different window
OK(getFromSocket("/dispatch focuswindow class:kitty_B"));
EXPECT(isActiveWindow("kitty_B", '0'), true);
// Make a window that will request focus
const std::string removeToActivate = spawnKittyActivating();
if (removeToActivate.empty())
return false;
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
std::filesystem::remove(removeToActivate);
EXPECT(waitForActiveWindow("kitty_activating", '0'), true);
OK(getFromSocket("/dispatch forcekillactive"));
Tests::waitUntilWindowsN(2);
}
// Take over on conflict
{
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 1"));
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus the same window
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus a different window
OK(getFromSocket("/dispatch focuswindow class:kitty_B"));
EXPECT(isActiveWindow("kitty_B", '2'), true);
OK(getFromSocket("/dispatch fullscreenstate 0 0"));
// Make a window that will request focus
const std::string removeToActivate = spawnKittyActivating();
if (removeToActivate.empty())
return false;
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
std::filesystem::remove(removeToActivate);
EXPECT(waitForActiveWindow("kitty_activating", '2'), true);
OK(getFromSocket("/dispatch forcekillactive"));
Tests::waitUntilWindowsN(2);
}
// Keep the old focus on conflict
{
OK(getFromSocket("/keyword misc:on_focus_under_fullscreen 0"));
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Dispatch-focus the same window
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
// Make a window that will request focus - the setting is treated normally
const std::string removeToActivate = spawnKittyActivating();
if (removeToActivate.empty())
return false;
OK(getFromSocket("/dispatch focuswindow class:kitty_A"));
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(isActiveWindow("kitty_A", '2'), true);
std::filesystem::remove(removeToActivate);
EXPECT(waitForActiveWindow("kitty_A", '2'), true);
}
NLog::log("{}Reloading config", Colors::YELLOW);
OK(getFromSocket("/reload"));
NLog::log("{}Killing all windows", Colors::YELLOW);
Tests::killAllWindows();
NLog::log("{}Expecting 0 windows", Colors::YELLOW);
EXPECT(Tests::windowCount(), 0);
return true;
}
static bool test() { static bool test() {
NLog::log("{}Testing windows", Colors::GREEN); NLog::log("{}Testing windows", Colors::GREEN);
@ -256,16 +406,7 @@ static bool test() {
getFromSocket("/dispatch exec xeyes"); getFromSocket("/dispatch exec xeyes");
NLog::log("{}Keep checking if xeyes spawned", Colors::YELLOW); NLog::log("{}Keep checking if xeyes spawned", Colors::YELLOW);
int counter = 0; Tests::waitUntilWindowsN(3);
while (Tests::windowCount() != 3) {
counter++;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (counter > 50) {
EXPECT(Tests::windowCount(), 3);
return !ret;
}
}
NLog::log("{}Expecting 3 windows", Colors::YELLOW); NLog::log("{}Expecting 3 windows", Colors::YELLOW);
EXPECT(Tests::windowCount(), 3); EXPECT(Tests::windowCount(), 3);
@ -292,6 +433,36 @@ static bool test() {
getFromSocket("/dispatch workspace 1"); getFromSocket("/dispatch workspace 1");
if (!testWindowFocusOnFullscreenConflict()) {
ret = 1;
return false;
}
NLog::log("{}Testing spawning a floating window over a fullscreen window", Colors::YELLOW);
{
if (!spawnKitty("kitty_A"))
return false;
OK(getFromSocket("/dispatch fullscreen 0 set"));
EXPECT(Tests::windowCount(), 1);
OK(getFromSocket("/dispatch exec [float] kitty"));
Tests::waitUntilWindowsN(2);
OK(getFromSocket("/dispatch focuswindow class:^kitty$"));
const auto focused1 = getFromSocket("/activewindow");
EXPECT_CONTAINS(focused1, "class: kitty\n");
OK(getFromSocket("/dispatch killwindow activewindow"));
Tests::waitUntilWindowsN(1);
// The old window should be focused again
const auto focused2 = getFromSocket("/activewindow");
EXPECT_CONTAINS(focused2, "class: kitty_A\n");
NLog::log("{}Killing all windows", Colors::YELLOW);
Tests::killAllWindows();
}
NLog::log("{}Testing minsize/maxsize rules for tiled windows", Colors::YELLOW); NLog::log("{}Testing minsize/maxsize rules for tiled windows", Colors::YELLOW);
{ {
// Enable the config for testing, test max/minsize for tiled windows and centering // Enable the config for testing, test max/minsize for tiled windows and centering

View file

@ -4,6 +4,7 @@
#include "Compositor.hpp" #include "Compositor.hpp"
#include "debug/Log.hpp" #include "debug/Log.hpp"
#include "desktop/DesktopTypes.hpp" #include "desktop/DesktopTypes.hpp"
#include "desktop/state/FocusState.hpp"
#include "helpers/Splashes.hpp" #include "helpers/Splashes.hpp"
#include "config/ConfigValue.hpp" #include "config/ConfigValue.hpp"
#include "config/ConfigWatcher.hpp" #include "config/ConfigWatcher.hpp"
@ -560,9 +561,6 @@ void CCompositor::cleanup() {
// still in a normal working state. // still in a normal working state.
g_pPluginSystem->unloadAllPlugins(); g_pPluginSystem->unloadAllPlugins();
m_lastFocus.reset();
m_lastWindow.reset();
m_workspaces.clear(); m_workspaces.clear();
m_windows.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()) { if (w->m_isX11 && w->isX11OverrideRedirect() && !w->m_xwaylandSurface->wantsFocus()) {
// Override Redirect // 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. // 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; 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) { 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& lsl : monitor->m_layerSurfaceLayers | std::views::reverse) {
for (auto const& ls : lsl | std::views::reverse) { for (auto const& ls : lsl | std::views::reverse) {
@ -1390,7 +1193,7 @@ PHLWINDOW CCompositor::getUrgentWindow() {
} }
bool CCompositor::isWindowActive(PHLWINDOW pWindow) { bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
if (m_lastWindow.expired() && !m_lastFocus) if (!Desktop::focusState()->window() && !Desktop::focusState()->surface())
return false; return false;
if (!pWindow->m_isMapped) if (!pWindow->m_isMapped)
@ -1398,7 +1201,7 @@ bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
const auto PSURFACE = pWindow->m_wlSurface->resource(); 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) { void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) {
@ -1627,14 +1430,15 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
// get idx // get idx
int windowIDX = -1; int windowIDX = -1;
for (size_t i = 0; i < g_pCompositor->m_windowFocusHistory.size(); ++i) { const auto& HISTORY = Desktop::focusState()->windowHistory();
if (g_pCompositor->m_windowFocusHistory[i].lock() == w) { for (size_t i = 0; i < HISTORY.size(); ++i) {
if (HISTORY[i] == w) {
windowIDX = i; windowIDX = i;
break; break;
} }
} }
windowIDX = g_pCompositor->m_windowFocusHistory.size() - windowIDX; windowIDX = Desktop::focusState()->windowHistory().size() - windowIDX;
if (windowIDX > leaderValue) { if (windowIDX > leaderValue) {
leaderValue = windowIDX; 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) { 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); }; 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 // 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) : return next ? getWeakWindowPred(std::ranges::find(Desktop::focusState()->windowHistory() | std::views::reverse, cur), Desktop::focusState()->windowHistory().rend(),
getWeakWindowPred(std::ranges::find(m_windowFocusHistory, cur), m_windowFocusHistory.end(), m_windowFocusHistory.begin(), FINDER); 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) { 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) { 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) { PHLMONITOR CCompositor::getMonitorInDirection(PHLMONITOR pSourceMonitor, const char& dir) {
@ -1997,12 +1803,12 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
g_pDesktopAnimationManager->setFullscreenFadeAnimation( g_pDesktopAnimationManager->setFullscreenFadeAnimation(
PWORKSPACEA, PWORKSPACEA->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT); 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) { if (pMonitorA->m_id == Desktop::focusState()->monitor()->m_id || pMonitorB->m_id == Desktop::focusState()->monitor()->m_id) {
const auto LASTWIN = pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow(); const auto LASTWIN = pMonitorA->m_id == Desktop::focusState()->monitor()->m_id ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow();
g_pCompositor->focusWindow(LASTWIN ? LASTWIN : Desktop::focusState()->fullWindowFocus(
(g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING))); 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 = "workspace", .data = PNEWWORKSPACE->m_name});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspacev2", .data = std::format("{},{}", PNEWWORKSPACE->m_id, PNEWWORKSPACE->m_name)}); g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspacev2", .data = std::format("{},{}", PNEWWORKSPACE->m_id, PNEWWORKSPACE->m_name)});
EMIT_HOOK_EVENT("workspace", PNEWWORKSPACE); EMIT_HOOK_EVENT("workspace", PNEWWORKSPACE);
@ -2020,7 +1826,7 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) { PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
if (name == "current") if (name == "current")
return g_pCompositor->m_lastMonitor.lock(); return Desktop::focusState()->monitor();
else if (isDirection(name)) else if (isDirection(name))
return getMonitorInDirection(name[0]); return getMonitorInDirection(name[0]);
else if (name[0] == '+' || name[0] == '-') { else if (name[0] == '+' || name[0] == '-') {
@ -2041,7 +1847,7 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) {
int currentPlace = 0; int currentPlace = 0;
for (int i = 0; i < sc<int>(m_monitors.size()); i++) { 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; currentPlace = i;
break; 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); Debug::log(LOG, "moveWorkspaceToMonitor: SWITCHINGISACTIVE, active {} -> {}", pMonitor->activeWorkspaceID(), pWorkspace->m_id);
if (valid(pMonitor->m_activeWorkspace)) { if (valid(pMonitor->m_activeWorkspace)) {
@ -2186,7 +1992,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
if (*PHIDESPECIALONWORKSPACECHANGE) if (*PHIDESPECIALONWORKSPACECHANGE)
pMonitor->setSpecialWorkspace(nullptr); pMonitor->setSpecialWorkspace(nullptr);
setActiveMonitor(pMonitor); Desktop::focusState()->rawMonitorFocus(pMonitor);
auto oldWorkspace = pMonitor->m_activeWorkspace; auto oldWorkspace = pMonitor->m_activeWorkspace;
pMonitor->m_activeWorkspace = pWorkspace; 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)))); 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) { void CCompositor::setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE) {
if (PWINDOW->m_ruleApplicator->syncFullscreen().valueOrDefault()) if (PWINDOW->m_ruleApplicator->syncFullscreen().valueOrDefault())
setWindowFullscreenState(PWINDOW, SFullscreenState{.internal = MODE, .client = MODE}); setWindowFullscreenState(PWINDOW, SFullscreenState{.internal = MODE, .client = MODE});
@ -2387,16 +2194,16 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) {
auto regexp = trim(regexp_); auto regexp = trim(regexp_);
if (regexp.starts_with("active")) if (regexp.starts_with("active"))
return m_lastWindow.lock(); return Desktop::focusState()->window();
else if (regexp.starts_with("floating") || regexp.starts_with("tiled")) { else if (regexp.starts_with("floating") || regexp.starts_with("tiled")) {
// first floating on the current ws // first floating on the current ws
if (!valid(m_lastWindow)) if (!Desktop::focusState()->window())
return nullptr; return nullptr;
const bool FLOAT = regexp.starts_with("floating"); const bool FLOAT = regexp.starts_with("floating");
for (auto const& w : m_windows) { 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; continue;
return w; return w;
@ -2502,16 +2309,14 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
if (*PNOWARPS && !force) { if (*PNOWARPS && !force) {
const auto PMONITORNEW = getMonitorFromVector(pos); const auto PMONITORNEW = getMonitorFromVector(pos);
if (PMONITORNEW != m_lastMonitor) Desktop::focusState()->rawMonitorFocus(PMONITORNEW);
setActiveMonitor(PMONITORNEW);
return; return;
} }
g_pPointerManager->warpTo(pos); g_pPointerManager->warpTo(pos);
const auto PMONITORNEW = getMonitorFromVector(pos); const auto PMONITORNEW = getMonitorFromVector(pos);
if (PMONITORNEW != m_lastMonitor) Desktop::focusState()->rawMonitorFocus(PMONITORNEW);
setActiveMonitor(PMONITORNEW);
} }
void CCompositor::closeWindow(PHLWINDOW pWindow) { void CCompositor::closeWindow(PHLWINDOW pWindow) {
@ -2550,7 +2355,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con
if (!args.contains(' ') && !args.contains('\t')) if (!args.contains(' ') && !args.contains('\t'))
return relativeTo; return relativeTo;
const auto PMONITOR = m_lastMonitor; const auto PMONITOR = Desktop::focusState()->monitor();
bool xIsPercent = false; bool xIsPercent = false;
bool yIsPercent = false; bool yIsPercent = false;
@ -2618,27 +2423,6 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITO
return PWORKSPACE; 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) { bool CCompositor::isWorkspaceSpecial(const WORKSPACEID& id) {
return id >= SPECIAL_WORKSPACE_START && id <= -2; return id >= SPECIAL_WORKSPACE_START && id <= -2;
} }
@ -2952,7 +2736,7 @@ void CCompositor::enterUnsafeState() {
m_unsafeState = true; m_unsafeState = true;
setActiveMonitor(m_unsafeOutput.lock()); Desktop::focusState()->rawMonitorFocus(m_unsafeOutput.lock());
} }
void CCompositor::leaveUnsafeState() { void CCompositor::leaveUnsafeState() {
@ -3116,7 +2900,7 @@ bool CCompositor::shouldChangePreferredImageDescription() {
} }
void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules, PHLWORKSPACE pWorkspace) { void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules, PHLWORKSPACE pWorkspace) {
if (!m_lastMonitor) if (!Desktop::focusState()->monitor())
return; return;
std::vector<PHLWORKSPACE> persistentFound; std::vector<PHLWORKSPACE> persistentFound;
@ -3154,7 +2938,7 @@ void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspace
} }
PWORKSPACE = getWorkspaceByID(id); PWORKSPACE = getWorkspaceByID(id);
if (!PMONITOR) if (!PMONITOR)
PMONITOR = m_lastMonitor.lock(); PMONITOR = Desktop::focusState()->monitor();
if (!PWORKSPACE) if (!PWORKSPACE)
PWORKSPACE = createNewWorkspace(id, PMONITOR->m_id, wsname, false); PWORKSPACE = createNewWorkspace(id, PMONITOR->m_id, wsname, false);

View file

@ -66,12 +66,6 @@ class CCompositor {
void bumpNofile(); void bumpNofile();
void restoreNofile(); 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_readyToProcess = false;
bool m_sessionActive = true; bool m_sessionActive = true;
bool m_dpmsStateOn = true; bool m_dpmsStateOn = true;
@ -99,8 +93,6 @@ class CCompositor {
PHLMONITOR getMonitorFromCursor(); PHLMONITOR getMonitorFromCursor();
PHLMONITOR getMonitorFromVector(const Vector2D&); PHLMONITOR getMonitorFromVector(const Vector2D&);
void removeWindowFromVectorSafe(PHLWINDOW); void removeWindowFromVectorSafe(PHLWINDOW);
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr, bool preserveFocusHistory = false);
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
bool monitorExists(PHLMONITOR); bool monitorExists(PHLMONITOR);
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr); PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*, bool aboveLockscreen = false); 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&); Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
[[nodiscard]] PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "", [[nodiscard]] PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
bool isEmpty = true); // will be deleted next frame if left empty and unfocused! bool isEmpty = true); // will be deleted next frame if left empty and unfocused!
void setActiveMonitor(PHLMONITOR);
bool isWorkspaceSpecial(const WORKSPACEID&); bool isWorkspaceSpecial(const WORKSPACEID&);
WORKSPACEID getNewSpecialID(); WORKSPACEID getNewSpecialID();
void performUserChecks(); void performUserChecks();

View file

@ -1279,11 +1279,11 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.data = SConfigOptionDescription::SBoolData{true}, .data = SConfigOptionDescription::SBoolData{true},
}, },
SConfigOptionDescription{ SConfigOptionDescription{
.value = "misc:new_window_takes_over_fullscreen", .value = "misc:on_focus_under_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 " .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 "
"state. 0 - behind, 1 - takes over, 2 - unfullscreen/unmaxize [0/1/2]", "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, .type = CONFIG_OPTION_INT,
.data = SConfigOptionDescription::SRangeData{0, 0, 2}, .data = SConfigOptionDescription::SRangeData{2, 0, 2},
}, },
SConfigOptionDescription{ SConfigOptionDescription{
.value = "misc:exit_window_retains_fullscreen", .value = "misc:exit_window_retains_fullscreen",
@ -1946,12 +1946,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.type = CONFIG_OPTION_STRING_SHORT, .type = CONFIG_OPTION_STRING_SHORT,
.data = SConfigOptionDescription::SStringData{"left"}, .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{ SConfigOptionDescription{
.value = "master:slave_count_for_center_master", .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)", .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)",

View file

@ -17,6 +17,7 @@
#include "../desktop/rule/windowRule/WindowRule.hpp" #include "../desktop/rule/windowRule/WindowRule.hpp"
#include "../desktop/rule/layerRule/LayerRule.hpp" #include "../desktop/rule/layerRule/LayerRule.hpp"
#include "../debug/HyprCtl.hpp" #include "../debug/HyprCtl.hpp"
#include "../desktop/state/FocusState.hpp"
#include "defaultConfig.hpp" #include "defaultConfig.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
@ -490,7 +491,7 @@ CConfigManager::CConfigManager() {
registerConfigVar("misc:session_lock_xray", Hyprlang::INT{0}); registerConfigVar("misc:session_lock_xray", Hyprlang::INT{0});
registerConfigVar("misc:close_special_on_empty", Hyprlang::INT{1}); registerConfigVar("misc:close_special_on_empty", Hyprlang::INT{1});
registerConfigVar("misc:background_color", Hyprlang::INT{0xff111111}); 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:exit_window_retains_fullscreen", Hyprlang::INT{0});
registerConfigVar("misc:initial_workspace_tracking", Hyprlang::INT{1}); registerConfigVar("misc:initial_workspace_tracking", Hyprlang::INT{1});
registerConfigVar("misc:middle_click_paste", 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_active", {"none"});
registerConfigVar("master:new_on_top", Hyprlang::INT{0}); registerConfigVar("master:new_on_top", Hyprlang::INT{0});
registerConfigVar("master:orientation", {"left"}); registerConfigVar("master:orientation", {"left"});
registerConfigVar("master:inherit_fullscreen", Hyprlang::INT{1});
registerConfigVar("master:allow_small_split", Hyprlang::INT{0}); registerConfigVar("master:allow_small_split", Hyprlang::INT{0});
registerConfigVar("master:smart_resizing", Hyprlang::INT{1}); registerConfigVar("master:smart_resizing", Hyprlang::INT{1});
registerConfigVar("master:drop_at_cursor", Hyprlang::INT{1}); registerConfigVar("master:drop_at_cursor", Hyprlang::INT{1});

View file

@ -45,6 +45,7 @@ using namespace Hyprutils::OS;
#include "helpers/MiscFunctions.hpp" #include "helpers/MiscFunctions.hpp"
#include "../desktop/LayerSurface.hpp" #include "../desktop/LayerSurface.hpp"
#include "../desktop/rule/Engine.hpp" #include "../desktop/rule/Engine.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../version.h" #include "../version.h"
#include "../Compositor.hpp" #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(), 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(), (!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), 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"), sc<int>(m->m_reservedBottomRight.x), sc<int>(m->m_reservedBottomRight.y), m->m_scale, sc<int>(m->m_transform),
(m->m_dpmsStatus ? "true" : "false"), (m->m_output->state->state().adaptiveSync ? "true" : "false"), rc<uint64_t>(m->m_solitaryClient.get()), (m == Desktop::focusState()->monitor() ? "true" : "false"), (m->m_dpmsStatus ? "true" : "false"), (m->m_output->state->state().adaptiveSync ? "true" : "false"),
getSolitaryBlockedReason(m, format), (m->m_tearingState.activelyTearing ? "true" : "false"), getTearingBlockedReason(m, format), rc<uint64_t>(m->m_lastScanout.get()), rc<uint64_t>(m->m_solitaryClient.get()), getSolitaryBlockedReason(m, format), (m->m_tearingState.activelyTearing ? "true" : "false"),
getDSBlockedReason(m, format), (m->m_enabled ? "false" : "true"), formatToString(m->m_output->state->state().drmFormat), getTearingBlockedReason(m, format), rc<uint64_t>(m->m_lastScanout.get()), getDSBlockedReason(m, format), (m->m_enabled ? "false" : "true"),
m->m_mirrorOf ? std::format("{}", m->m_mirrorOf->m_id) : "none", availableModesForOutput(m, format), (NCMType::toString(m->m_cmType)), (m->m_sdrBrightness), formatToString(m->m_output->state->state().drmFormat), m->m_mirrorOf ? std::format("{}", m->m_mirrorOf->m_id) : "none", availableModesForOutput(m, format),
(m->m_sdrSaturation), (m->m_sdrMinLuminance), (m->m_sdrMaxLuminance)); (NCMType::toString(m->m_cmType)), (m->m_sdrBrightness), (m->m_sdrSaturation), (m->m_sdrMinLuminance), (m->m_sdrMaxLuminance));
} else { } else {
result += std::format( 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_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 : ""), (!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_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_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), 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), 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) { std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
auto getFocusHistoryID = [](PHLWINDOW wnd) -> int { auto getFocusHistoryID = [](PHLWINDOW wnd) -> int {
for (size_t i = 0; i < g_pCompositor->m_windowFocusHistory.size(); ++i) { for (size_t i = 0; i < Desktop::focusState()->windowHistory().size(); ++i) {
if (g_pCompositor->m_windowFocusHistory[i].lock() == wnd) if (Desktop::focusState()->windowHistory()[i].lock() == wnd)
return i; return i;
} }
return -1; return -1;
@ -524,11 +525,11 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF
} }
static std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string request) { static std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string request) {
if (!g_pCompositor->m_lastMonitor) if (!Desktop::focusState()->monitor())
return "unsafe state"; return "unsafe state";
std::string result = ""; std::string result = "";
auto w = g_pCompositor->m_lastMonitor->m_activeWorkspace; auto w = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!valid(w)) if (!valid(w))
return "internal error"; return "internal error";
@ -578,7 +579,7 @@ static std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::strin
} }
static std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string request) { 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)) if (!validMapped(PWINDOW))
return format == eHyprCtlOutputFormat::FORMAT_JSON ? "{}" : "Invalid"; return format == eHyprCtlOutputFormat::FORMAT_JSON ? "{}" : "Invalid";

View file

@ -5,6 +5,7 @@
#include "../render/pass/TexPassElement.hpp" #include "../render/pass/TexPassElement.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../managers/animation/AnimationManager.hpp" #include "../managers/animation/AnimationManager.hpp"
#include "../desktop/state/FocusState.hpp"
CHyprDebugOverlay::CHyprDebugOverlay() { CHyprDebugOverlay::CHyprDebugOverlay() {
m_texture = makeShared<CTexture>(); m_texture = makeShared<CTexture>();
@ -57,7 +58,7 @@ void CHyprMonitorDebugOverlay::frameData(PHLMONITOR pMonitor) {
m_monitor = pMonitor; m_monitor = pMonitor;
// anim data too // 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 (PMONITORFORTICKS == pMonitor) {
if (m_lastAnimationTicks.size() > sc<long unsigned int>(PMONITORFORTICKS->m_refreshRate)) if (m_lastAnimationTicks.size() > sc<long unsigned int>(PMONITORFORTICKS->m_refreshRate))
m_lastAnimationTicks.pop_front(); m_lastAnimationTicks.pop_front();

View file

@ -1,4 +1,5 @@
#include "LayerSurface.hpp" #include "LayerSurface.hpp"
#include "state/FocusState.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../events/Events.hpp" #include "../events/Events.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
@ -16,7 +17,7 @@
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) { PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(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); pLS->m_surface->assign(resource->m_surface.lock(), pLS);
@ -173,7 +174,7 @@ void CLayerSurface::onMap() {
g_pSeatManager->setGrab(nullptr); g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons(); 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); 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); g_pSeatManager->setPointerFocus(m_surface->resource(), LOCAL);
@ -244,11 +245,12 @@ void CLayerSurface::onUnmap() {
// refocus if needed // refocus if needed
// vvvvvvvvvvvvv if there is a last focus and the last focus is not keyboard focusable, fallback to window // 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)) if (!g_pInputManager->refocusLastWindow(PMONITOR))
g_pInputManager->refocus(); g_pInputManager->refocus();
} else if (g_pCompositor->m_lastFocus && g_pCompositor->m_lastFocus != m_surface->resource()) } else if (Desktop::focusState()->surface() && Desktop::focusState()->surface() != m_surface->resource())
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_lastFocus.lock()); 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}; 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); 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) { 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, // moveMouseUnified won't focus non interactive layers but it won't unfocus them either,
// so unfocus the surface here. // so unfocus the surface here.
g_pCompositor->focusSurface(nullptr); Desktop::focusState()->rawSurfaceFocus(nullptr);
g_pInputManager->refocusLastWindow(m_monitor.lock()); g_pInputManager->refocusLastWindow(m_monitor.lock());
} else if (WASLASTFOCUS && WASEXCLUSIVE && m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) { } else if (WASLASTFOCUS && WASEXCLUSIVE && m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
g_pInputManager->simulateMouseMovement(); g_pInputManager->simulateMouseMovement();
@ -382,7 +384,7 @@ void CLayerSurface::onCommit() {
// if now exclusive and not previously // if now exclusive and not previously
g_pSeatManager->setGrab(nullptr); g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons(); 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); 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); g_pSeatManager->setPointerFocus(m_surface->resource(), LOCAL);

View file

@ -1,6 +1,7 @@
#include "Subsurface.hpp" #include "Subsurface.hpp"
#include "../events/Events.hpp" #include "../events/Events.hpp"
#include "../Compositor.hpp" #include "../desktop/state/FocusState.hpp"
#include "../desktop/Window.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/core/Compositor.hpp" #include "../protocols/core/Compositor.hpp"
#include "../protocols/core/Subcompositor.hpp" #include "../protocols/core/Subcompositor.hpp"
@ -163,7 +164,7 @@ void CSubsurface::onMap() {
void CSubsurface::onUnmap() { void CSubsurface::onUnmap() {
damageLastArea(); damageLastArea();
if (m_wlSurface->resource() == g_pCompositor->m_lastFocus) if (m_wlSurface->resource() == Desktop::focusState()->surface())
g_pInputManager->releaseAllMouseButtons(); g_pInputManager->releaseAllMouseButtons();
g_pInputManager->simulateMouseMovement(); g_pInputManager->simulateMouseMovement();

View file

@ -7,6 +7,7 @@
#include <bit> #include <bit>
#include <string_view> #include <string_view>
#include "Window.hpp" #include "Window.hpp"
#include "state/FocusState.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../render/decorations/CHyprDropShadowDecoration.hpp" #include "../render/decorations/CHyprDropShadowDecoration.hpp"
#include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp"
@ -121,9 +122,9 @@ CWindow::CWindow(SP<CXWaylandSurface> surface) : m_xwaylandSurface(surface) {
} }
CWindow::~CWindow() { CWindow::~CWindow() {
if (g_pCompositor->m_lastWindow == m_self) { if (Desktop::focusState()->window() == m_self) {
g_pCompositor->m_lastFocus.reset(); Desktop::focusState()->surface().reset();
g_pCompositor->m_lastWindow.reset(); Desktop::focusState()->window().reset();
} }
m_events.destroy.emit(); m_events.destroy.emit();
@ -528,8 +529,6 @@ void CWindow::onUnmap() {
if (m_workspace->m_isSpecialWorkspace && m_workspace->getWindows() == 0) if (m_workspace->m_isSpecialWorkspace && m_workspace->getWindows() == 0)
m_lastWorkspace = m_monitor->activeWorkspaceID(); 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()) { if (*PCLOSEONLASTSPECIAL && m_workspace && m_workspace->getWindows() == 0 && onSpecialWorkspace()) {
const auto PMONITOR = m_monitor.lock(); const auto PMONITOR = m_monitor.lock();
if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace == m_workspace) if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace == m_workspace)
@ -594,8 +593,6 @@ void CWindow::onMap() {
m_movingFromWorkspaceAlpha->setValueAndWarp(1.F); m_movingFromWorkspaceAlpha->setValueAndWarp(1.F);
g_pCompositor->m_windowFocusHistory.push_back(m_self);
m_reportedSize = m_pendingReportedSize; m_reportedSize = m_pendingReportedSize;
m_animatingIn = true; m_animatingIn = true;
@ -629,8 +626,8 @@ void CWindow::onBorderAngleAnimEnd(WP<CBaseAnimatedVariable> pav) {
void CWindow::setHidden(bool hidden) { void CWindow::setHidden(bool hidden) {
m_hidden = hidden; m_hidden = hidden;
if (hidden && g_pCompositor->m_lastWindow == m_self) if (hidden && Desktop::focusState()->window() == m_self)
g_pCompositor->m_lastWindow.reset(); Desktop::focusState()->window().reset();
setSuspended(hidden); setSuspended(hidden);
} }
@ -862,7 +859,7 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
const auto WORKSPACE = PCURRENT->m_workspace; const auto WORKSPACE = PCURRENT->m_workspace;
const auto MODE = PCURRENT->m_fullscreenState.internal; 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 PWINDOWSIZE = PCURRENT->m_realSize->value();
const auto PWINDOWPOS = PCURRENT->m_realPosition->value(); const auto PWINDOWPOS = PCURRENT->m_realPosition->value();
@ -897,7 +894,7 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
g_pCompositor->updateAllWindowsAnimatedDecorationValues(); g_pCompositor->updateAllWindowsAnimatedDecorationValues();
if (CURRENTISFOCUS) if (CURRENTISFOCUS)
g_pCompositor->focusWindow(pWindow); Desktop::focusState()->rawWindowFocus(pWindow);
g_pHyprRenderer->damageWindow(pWindow); g_pHyprRenderer->damageWindow(pWindow);
@ -1240,7 +1237,7 @@ std::unordered_map<std::string, std::string> CWindow::getEnv() {
} }
void CWindow::activate(bool force) { void CWindow::activate(bool force) {
if (g_pCompositor->m_lastWindow == m_self) if (Desktop::focusState()->window() == m_self)
return; return;
static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate"); static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
@ -1262,7 +1259,7 @@ void CWindow::activate(bool force) {
if (m_isFloating) if (m_isFloating)
g_pCompositor->changeWindowZOrder(m_self.lock(), true); g_pCompositor->changeWindowZOrder(m_self.lock(), true);
g_pCompositor->focusWindow(m_self.lock()); Desktop::focusState()->fullWindowFocus(m_self.lock());
warpCursor(); warpCursor();
} }
@ -1276,7 +1273,7 @@ void CWindow::onUpdateState() {
if (m_isMapped) { if (m_isMapped) {
const auto monitor = g_pCompositor->getMonitorFromID(requestsID.value()); const auto monitor = g_pCompositor->getMonitorFromID(requestsID.value());
g_pCompositor->moveWindowToWorkspaceSafe(m_self.lock(), monitor->m_activeWorkspace); g_pCompositor->moveWindowToWorkspaceSafe(m_self.lock(), monitor->m_activeWorkspace);
g_pCompositor->setActiveMonitor(monitor); Desktop::focusState()->rawMonitorFocus(monitor);
} }
if (!m_isMapped) 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)}); g_pEventManager->postEvent(SHyprIPCEvent{.event = "windowtitlev2", .data = std::format("{:x},{}", rc<uintptr_t>(this), m_title)});
EMIT_HOOK_EVENT("windowTitle", m_self.lock()); 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 = "activewindow", .data = m_class + "," + m_title});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(this))}); g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(this))});
EMIT_HOOK_EVENT("activeWindow", m_self.lock()); EMIT_HOOK_EVENT("activeWindow", m_self.lock());
@ -1325,7 +1322,7 @@ void CWindow::onUpdateMeta() {
if (m_class != NEWCLASS) { if (m_class != NEWCLASS) {
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 = "activewindow", .data = m_class + "," + m_title});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(this))}); g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", rc<uintptr_t>(this))});
EMIT_HOOK_EVENT("activeWindow", m_self.lock()); EMIT_HOOK_EVENT("activeWindow", m_self.lock());
@ -1502,7 +1499,7 @@ PHLWINDOW CWindow::getSwallower() {
return candidates[0]; return candidates[0];
// walk up the focus history and find the last focused // 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) if (!w)
continue; continue;
@ -1781,7 +1778,7 @@ void CWindow::updateDecorationValues() {
setBorderColor(*RENDERDATA.borderGradient); setBorderColor(*RENDERDATA.borderGradient);
else { else {
const bool GROUPLOCKED = m_groupData.pNextWindow.lock() ? getGroupHead()->m_groupData.locked : false; 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 = const auto* const ACTIVECOLOR =
!m_groupData.pNextWindow.lock() ? (!m_groupData.deny ? ACTIVECOL : NOGROUPACTIVECOL) : (GROUPLOCKED ? GROUPACTIVELOCKEDCOL : GROUPACTIVECOL); !m_groupData.pNextWindow.lock() ? (!m_groupData.deny ? ACTIVECOL : NOGROUPACTIVECOL) : (GROUPLOCKED ? GROUPACTIVELOCKEDCOL : GROUPACTIVECOL);
setBorderColor(m_ruleApplicator->activeBorderColor().valueOr(*ACTIVECOLOR)); setBorderColor(m_ruleApplicator->activeBorderColor().valueOr(*ACTIVECOLOR));
@ -1797,7 +1794,7 @@ void CWindow::updateDecorationValues() {
if (isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) { if (isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) {
*m_activeInactiveAlpha = m_ruleApplicator->alphaFullscreen().valueOrDefault().applyAlpha(*PFULLSCREENALPHA); *m_activeInactiveAlpha = m_ruleApplicator->alphaFullscreen().valueOrDefault().applyAlpha(*PFULLSCREENALPHA);
} else { } else {
if (m_self == g_pCompositor->m_lastWindow) if (m_self == Desktop::focusState()->window())
*m_activeInactiveAlpha = m_ruleApplicator->alpha().valueOrDefault().applyAlpha(*PACTIVEALPHA); *m_activeInactiveAlpha = m_ruleApplicator->alpha().valueOrDefault().applyAlpha(*PACTIVEALPHA);
else else
*m_activeInactiveAlpha = m_ruleApplicator->alphaInactive().valueOrDefault().applyAlpha(*PINACTIVEALPHA); *m_activeInactiveAlpha = m_ruleApplicator->alphaInactive().valueOrDefault().applyAlpha(*PINACTIVEALPHA);
@ -1805,7 +1802,7 @@ void CWindow::updateDecorationValues() {
// dim // dim
float goalDim = 1.F; 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; goalDim = 0;
else else
goalDim = *PDIMSTRENGTH; goalDim = *PDIMSTRENGTH;
@ -1817,7 +1814,7 @@ void CWindow::updateDecorationValues() {
// shadow // shadow
if (!isX11OverrideRedirect() && !m_X11DoesntWantBorders) { if (!isX11OverrideRedirect() && !m_X11DoesntWantBorders) {
if (m_self == g_pCompositor->m_lastWindow) if (m_self == Desktop::focusState()->window())
*m_realShadowColor = CHyprColor(*PSHADOWCOL); *m_realShadowColor = CHyprColor(*PSHADOWCOL);
else else
*m_realShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != -1 ? *PSHADOWCOLINACTIVE : *PSHADOWCOL); *m_realShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != -1 ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
@ -1828,7 +1825,7 @@ void CWindow::updateDecorationValues() {
} }
std::optional<double> CWindow::calculateSingleExpr(const std::string& s) { 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{}); const auto CURSOR_LOCAL = g_pInputManager->getMouseCoordsInternal() - (PMONITOR ? PMONITOR->m_position : Vector2D{});
Math::CExpression expr; Math::CExpression expr;

View file

@ -3,6 +3,7 @@
#include "../../../helpers/Monitor.hpp" #include "../../../helpers/Monitor.hpp"
#include "../../../Compositor.hpp" #include "../../../Compositor.hpp"
#include "../../../managers/TokenManager.hpp" #include "../../../managers/TokenManager.hpp"
#include "../../../desktop/state/FocusState.hpp"
using namespace Desktop; using namespace Desktop;
using namespace Desktop::Rule; using namespace Desktop::Rule;
@ -72,7 +73,7 @@ bool CWindowRule::matches(PHLWINDOW w, bool allowEnvLookup) {
return false; return false;
break; break;
case RULE_PROP_FOCUS: case RULE_PROP_FOCUS:
if (!engine->match(g_pCompositor->m_lastWindow == w)) if (!engine->match(Desktop::focusState()->window() == w))
return false; return false;
break; break;
case RULE_PROP_GROUP: case RULE_PROP_GROUP:

View file

@ -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);
}

View file

@ -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();
};

View file

@ -20,6 +20,7 @@
#include "managers/animation/DesktopAnimationManager.hpp" #include "managers/animation/DesktopAnimationManager.hpp"
#include "managers/PointerManager.hpp" #include "managers/PointerManager.hpp"
#include "../desktop/LayerSurface.hpp" #include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../managers/LayoutManager.hpp" #include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp" #include "../managers/EventManager.hpp"
#include "../managers/animation/AnimationManager.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 PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity"); static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength"); 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"); static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
auto PMONITOR = g_pCompositor->m_lastMonitor.lock(); auto PMONITOR = Desktop::focusState()->monitor();
if (!g_pCompositor->m_lastMonitor) { if (!Desktop::focusState()->monitor()) {
g_pCompositor->setActiveMonitor(g_pCompositor->getMonitorFromVector({})); Desktop::focusState()->rawMonitorFocus(g_pCompositor->getMonitorFromVector({}));
PMONITOR = g_pCompositor->m_lastMonitor.lock(); PMONITOR = Desktop::focusState()->monitor();
} }
auto PWORKSPACE = PMONITOR->m_activeSpecialWorkspace ? PMONITOR->m_activeSpecialWorkspace : PMONITOR->m_activeWorkspace; auto PWORKSPACE = PMONITOR->m_activeSpecialWorkspace ? PMONITOR->m_activeSpecialWorkspace : PMONITOR->m_activeWorkspace;
PWINDOW->m_monitor = PMONITOR; PWINDOW->m_monitor = PMONITOR;
@ -323,7 +324,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
else if (PMONITOR->activeWorkspaceID() != requestedWorkspaceID && !PWINDOW->m_noInitialFocus) else if (PMONITOR->activeWorkspaceID() != requestedWorkspaceID && !PWINDOW->m_noInitialFocus)
g_pKeybindManager->m_dispatchers["workspace"](requestedWorkspaceName); g_pKeybindManager->m_dispatchers["workspace"](requestedWorkspaceName);
PMONITOR = g_pCompositor->m_lastMonitor.lock(); PMONITOR = Desktop::focusState()->monitor();
} }
requestedFSMonitor = MONITOR_INVALID; 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 // 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)}); 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) { if (PWINDOW->m_isFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); 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); 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 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())); 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 // check LS focus grab
const auto PFORCEFOCUS = g_pCompositor->getForceFocus(); 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) if (PLSFROMFOCUS && PLSFROMFOCUS->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE)
PWINDOW->m_noInitialFocus = true; 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 && if (!PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() && !PWINDOW->m_noInitialFocus &&
(!PWINDOW->isX11OverrideRedirect() || (PWINDOW->m_isX11 && PWINDOW->m_xwaylandSurface->wantsFocus())) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) && (!PWINDOW->isX11OverrideRedirect() || (PWINDOW->m_isX11 && PWINDOW->m_xwaylandSurface->wantsFocus())) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) &&
!g_pInputManager->isConstrained()) { !g_pInputManager->isConstrained()) {
g_pCompositor->focusWindow(PWINDOW); Desktop::focusState()->fullWindowFocus(PWINDOW);
PWINDOW->m_activeInactiveAlpha->setValueAndWarp(*PACTIVEALPHA); PWINDOW->m_activeInactiveAlpha->setValueAndWarp(*PACTIVEALPHA);
PWINDOW->m_dimPercent->setValueAndWarp(PWINDOW->m_ruleApplicator->noDim().valueOrDefault() ? 0.f : *PDIMSTRENGTH); PWINDOW->m_dimPercent->setValueAndWarp(PWINDOW->m_ruleApplicator->noDim().valueOrDefault() ? 0.f : *PDIMSTRENGTH);
} else { } else {
@ -488,10 +490,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (workspaceSilent) { if (workspaceSilent) {
if (validMapped(PFOCUSEDWINDOWPREV)) { if (validMapped(PFOCUSEDWINDOWPREV)) {
g_pCompositor->focusWindow(PFOCUSEDWINDOWPREV); Desktop::focusState()->rawWindowFocus(PFOCUSEDWINDOWPREV);
PFOCUSEDWINDOWPREV->updateWindowDecos(); // need to for some reason i cba to find out why PFOCUSEDWINDOWPREV->updateWindowDecos(); // need to for some reason i cba to find out why
} else if (!PFOCUSEDWINDOWPREV) } else if (!PFOCUSEDWINDOWPREV)
g_pCompositor->focusWindow(nullptr); Desktop::focusState()->rawWindowFocus(nullptr);
} }
// swallow // swallow
@ -601,10 +603,10 @@ void Events::listener_unmapWindow(void* owner, void* data) {
bool wasLastWindow = false; bool wasLastWindow = false;
if (PWINDOW == g_pCompositor->m_lastWindow.lock()) { if (PWINDOW == Desktop::focusState()->window()) {
wasLastWindow = true; wasLastWindow = true;
g_pCompositor->m_lastWindow.reset(); Desktop::focusState()->window().reset();
g_pCompositor->m_lastFocus.reset(); Desktop::focusState()->surface().reset();
g_pInputManager->releaseAllMouseButtons(); 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); Debug::log(LOG, "On closed window, new focused candidate is {}", PWINDOWCANDIDATE);
if (PWINDOWCANDIDATE != g_pCompositor->m_lastWindow.lock() && PWINDOWCANDIDATE) { if (PWINDOWCANDIDATE != Desktop::focusState()->window() && PWINDOWCANDIDATE) {
g_pCompositor->focusWindow(PWINDOWCANDIDATE); Desktop::focusState()->fullWindowFocus(PWINDOWCANDIDATE);
if (*PEXITRETAINSFS && CURRENTWINDOWFSSTATE) if (*PEXITRETAINSFS && CURRENTWINDOWFSSTATE)
g_pCompositor->setWindowFullscreenInternal(PWINDOWCANDIDATE, CURRENTFSMODE); g_pCompositor->setWindowFullscreenInternal(PWINDOWCANDIDATE, CURRENTFSMODE);
} }
@ -648,7 +650,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
g_pInputManager->sendMotionEventsToFocused(); g_pInputManager->sendMotionEventsToFocused();
// CWindow::onUnmap will remove this window's active status, but we can't really do it above. // 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{"activewindow", ","});
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
EMIT_HOOK_EVENT("activeWindow", PHLWINDOW{nullptr}); 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); Debug::log(LOG, "{:c} destroyed, queueing.", PWINDOW);
if (PWINDOW == g_pCompositor->m_lastWindow.lock()) { if (PWINDOW == Desktop::focusState()->window()) {
g_pCompositor->m_lastWindow.reset(); Desktop::focusState()->window().reset();
g_pCompositor->m_lastFocus.reset(); Desktop::focusState()->surface().reset();
} }
PWINDOW->m_wlSurface->unassign(); PWINDOW->m_wlSurface->unassign();
@ -786,17 +788,17 @@ void Events::listener_activateX11(void* owner, void* data) {
Debug::log(LOG, "Unmanaged X11 {} requests activate", PWINDOW); 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; return;
if (!PWINDOW->m_xwaylandSurface->wantsFocus()) if (!PWINDOW->m_xwaylandSurface->wantsFocus())
return; return;
g_pCompositor->focusWindow(PWINDOW); Desktop::focusState()->fullWindowFocus(PWINDOW);
return; return;
} }
if (PWINDOW == g_pCompositor->m_lastWindow.lock() || (PWINDOW->m_suppressedEvents & SUPPRESS_ACTIVATE)) if (PWINDOW == Desktop::focusState()->window() || (PWINDOW->m_suppressedEvents & SUPPRESS_ACTIVATE))
return; return;
PWINDOW->activate(); PWINDOW->activate();

View file

@ -3,6 +3,7 @@
#include <algorithm> #include <algorithm>
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/TokenManager.hpp" #include "../managers/TokenManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "Monitor.hpp" #include "Monitor.hpp"
#include "../config/ConfigManager.hpp" #include "../config/ConfigManager.hpp"
#include "fs/FsUtils.hpp" #include "fs/FsUtils.hpp"
@ -146,7 +147,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else if (in.starts_with("empty")) { } else if (in.starts_with("empty")) {
const bool same_mon = in.substr(5).contains("m"); const bool same_mon = in.substr(5).contains("m");
const bool next = in.substr(5).contains("n"); 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!"); Debug::log(ERR, "Empty monitor workspace on monitor null!");
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};
} }
@ -155,12 +156,12 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
if (same_mon) { if (same_mon) {
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) { for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
const auto PMONITOR = g_pCompositor->getMonitorFromString(rule.monitor); 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); 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) { while (++id < LONG_MAX) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
if (!invalidWSes.contains(id) && (!PWORKSPACE || PWORKSPACE->getWindows() == 0)) { if (!invalidWSes.contains(id) && (!PWORKSPACE || PWORKSPACE->getWindows() == 0)) {
@ -169,10 +170,10 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} }
} }
} else if (in.starts_with("prev")) { } else if (in.starts_with("prev")) {
if (!g_pCompositor->m_lastMonitor) if (!Desktop::focusState()->monitor())
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace; const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!valid(PWORKSPACE)) if (!valid(PWORKSPACE))
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};
@ -191,12 +192,12 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
return {PLASTWORKSPACE->m_id, PLASTWORKSPACE->m_name}; return {PLASTWORKSPACE->m_id, PLASTWORKSPACE->m_name};
} else if (in == "next") { } 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'"); Debug::log(ERR, "no active monitor or workspace for 'next'");
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};
} }
auto PCURRENTWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace; auto PCURRENTWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
WORKSPACEID nextId = PCURRENTWORKSPACE->m_id + 1; WORKSPACEID nextId = PCURRENTWORKSPACE->m_id + 1;
@ -209,7 +210,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else { } else {
if (in[0] == 'r' && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) { if (in[0] == 'r' && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) {
bool absolute = in[1] == '~'; bool absolute = in[1] == '~';
if (!g_pCompositor->m_lastMonitor) { if (!Desktop::focusState()->monitor()) {
Debug::log(ERR, "Relative monitor workspace on monitor null!"); Debug::log(ERR, "Relative monitor workspace on monitor null!");
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};
} }
@ -227,14 +228,14 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
// Collect all the workspaces we can't jump to. // Collect all the workspaces we can't jump to.
for (auto const& ws : g_pCompositor->getWorkspaces()) { 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 // Can't jump to this workspace
invalidWSes.insert(ws->m_id); invalidWSes.insert(ws->m_id);
} }
} }
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) { for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
const auto PMONITOR = g_pCompositor->getMonitorFromString(rule.monitor); 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 // Can't be invalid
continue; continue;
} }
@ -245,7 +246,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
// Prepare all named workspaces in case when we need them // Prepare all named workspaces in case when we need them
std::vector<WORKSPACEID> namedWSes; std::vector<WORKSPACEID> namedWSes;
for (auto const& ws : g_pCompositor->getWorkspaces()) { 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; continue;
namedWSes.push_back(ws->m_id); namedWSes.push_back(ws->m_id);
@ -272,7 +273,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
} else { } else {
// Just take a blind guess at where we'll probably end up // 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; WORKSPACEID predictedWSID = activeWSID + remains;
int remainingWSes = 0; int remainingWSes = 0;
char walkDir = in[1]; char walkDir = in[1];
@ -371,7 +372,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
bool onAllMonitors = in[0] == 'e'; bool onAllMonitors = in[0] == 'e';
bool absolute = in[1] == '~'; bool absolute = in[1] == '~';
if (!g_pCompositor->m_lastMonitor) { if (!Desktop::focusState()->monitor()) {
Debug::log(ERR, "Relative monitor workspace on monitor null!"); Debug::log(ERR, "Relative monitor workspace on monitor null!");
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};
} }
@ -389,7 +390,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
std::vector<WORKSPACEID> validWSes; std::vector<WORKSPACEID> validWSes;
for (auto const& ws : g_pCompositor->getWorkspaces()) { 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; continue;
validWSes.push_back(ws->m_id); 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(); remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size();
// get the current item // 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++) { for (ssize_t i = 0; i < sc<ssize_t>(validWSes.size()); i++) {
if (validWSes[i] == activeWSID) { if (validWSes[i] == activeWSID) {
currentItem = i; currentItem = i;
@ -437,8 +438,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
result.name = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_name; result.name = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_name;
} else { } else {
if (in[0] == '+' || in[0] == '-') { if (in[0] == '+' || in[0] == '-') {
if (g_pCompositor->m_lastMonitor) { if (Desktop::focusState()->monitor()) {
const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, g_pCompositor->m_lastMonitor->activeWorkspaceID()); const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, Desktop::focusState()->monitor()->activeWorkspaceID());
if (!PLUSMINUSRESULT.has_value()) if (!PLUSMINUSRESULT.has_value())
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};

View file

@ -31,6 +31,7 @@
#include "sync/SyncTimeline.hpp" #include "sync/SyncTimeline.hpp"
#include "time/Time.hpp" #include "time/Time.hpp"
#include "../desktop/LayerSurface.hpp" #include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include <aquamarine/output/Output.hpp> #include <aquamarine/output/Output.hpp>
#include "debug/Log.hpp" #include "debug/Log.hpp"
#include "debug/HyprNotificationOverlay.hpp" #include "debug/HyprNotificationOverlay.hpp"
@ -298,8 +299,8 @@ void CMonitor::onConnect(bool noRule) {
if (!m_activeMonitorRule.mirrorOf.empty()) if (!m_activeMonitorRule.mirrorOf.empty())
setMirror(m_activeMonitorRule.mirrorOf); setMirror(m_activeMonitorRule.mirrorOf);
if (!g_pCompositor->m_lastMonitor) // set the last monitor if it isn't set yet if (!Desktop::focusState()->monitor()) // set the last monitor if it isn't set yet
g_pCompositor->setActiveMonitor(m_self.lock()); Desktop::focusState()->rawMonitorFocus(m_self.lock());
g_pHyprRenderer->arrangeLayersForMonitor(m_id); g_pHyprRenderer->arrangeLayersForMonitor(m_id);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
@ -310,7 +311,7 @@ void CMonitor::onConnect(bool noRule) {
// verify last mon valid // verify last mon valid
bool found = false; bool found = false;
for (auto const& m : g_pCompositor->m_monitors) { for (auto const& m : g_pCompositor->m_monitors) {
if (m == g_pCompositor->m_lastMonitor) { if (m == Desktop::focusState()->monitor()) {
found = true; found = true;
break; break;
} }
@ -330,7 +331,7 @@ void CMonitor::onConnect(bool noRule) {
Debug::log(LOG, "Monitor {} was not on any workspace", m_name); Debug::log(LOG, "Monitor {} was not on any workspace", m_name);
if (!found) 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); 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); g_pDesktopAnimationManager->startAnimation(w, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
} }
} else { } else {
g_pCompositor->m_lastFocus.reset(); Desktop::focusState()->surface().reset();
g_pCompositor->m_lastWindow.reset(); Desktop::focusState()->window().reset();
g_pCompositor->m_lastMonitor.reset(); Desktop::focusState()->monitor().reset();
} }
if (m_activeWorkspace) if (m_activeWorkspace)
@ -453,8 +454,8 @@ void CMonitor::onDisconnect(bool destroy) {
if (!m_state.commit()) if (!m_state.commit())
Debug::log(WARN, "state.commit() failed in CMonitor::onDisconnect"); Debug::log(WARN, "state.commit() failed in CMonitor::onDisconnect");
if (g_pCompositor->m_lastMonitor == m_self) if (Desktop::focusState()->monitor() == m_self)
g_pCompositor->setActiveMonitor(BACKUPMON ? BACKUPMON : g_pCompositor->m_unsafeOutput.lock()); Desktop::focusState()->rawMonitorFocus(BACKUPMON ? BACKUPMON : g_pCompositor->m_unsafeOutput.lock());
if (g_pHyprRenderer->m_mostHzMonitor == m_self) { if (g_pHyprRenderer->m_mostHzMonitor == m_self) {
int mostHz = 0; int mostHz = 0;
@ -1203,7 +1204,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
g_pCompositor->scheduleMonitorStateRecheck(); g_pCompositor->scheduleMonitorStateRecheck();
g_pCompositor->setActiveMonitor(g_pCompositor->m_monitors.front()); Desktop::focusState()->rawMonitorFocus(g_pCompositor->m_monitors.front());
// Software lock mirrored monitor // Software lock mirrored monitor
g_pPointerManager->lockSoftwareForMonitor(PMIRRORMON); g_pPointerManager->lockSoftwareForMonitor(PMIRRORMON);
@ -1286,8 +1287,8 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
w->moveToWorkspace(pWorkspace); w->moveToWorkspace(pWorkspace);
} }
if (!noFocus && !g_pCompositor->m_lastMonitor->m_activeSpecialWorkspace && if (!noFocus && !Desktop::focusState()->monitor()->m_activeSpecialWorkspace &&
!(g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_pinned && g_pCompositor->m_lastWindow->m_monitor == m_self)) { !(Desktop::focusState()->window() && Desktop::focusState()->window()->m_pinned && Desktop::focusState()->window()->m_monitor == m_self)) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
auto pWindow = pWorkspace->m_hasFullscreenWindow ? pWorkspace->getFullscreenWindow() : pWorkspace->getLastFocusedWindow(); 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(); pWindow = pWorkspace->getFirstWindow();
} }
g_pCompositor->focusWindow(pWindow); Desktop::focusState()->fullWindowFocus(pWindow);
} }
if (!noMouseMove) if (!noMouseMove)
@ -1361,9 +1362,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id); 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) if (const auto PLAST = m_activeWorkspace->getLastFocusedWindow(); PLAST)
g_pCompositor->focusWindow(PLAST); Desktop::focusState()->fullWindowFocus(PLAST);
else else
g_pInputManager->refocus(); g_pInputManager->refocus();
} }
@ -1443,9 +1444,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id); 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) if (const auto PLAST = pWorkspace->getLastFocusedWindow(); PLAST)
g_pCompositor->focusWindow(PLAST); Desktop::focusState()->fullWindowFocus(PLAST);
else else
g_pInputManager->refocus(); g_pInputManager->refocus();
} }
@ -1553,7 +1554,7 @@ uint32_t CMonitor::isSolitaryBlocked(bool full) {
return reasons; return reasons;
} }
if (g_pHyprError->active() && g_pCompositor->m_lastMonitor == m_self) { if (g_pHyprError->active() && Desktop::focusState()->monitor() == m_self) {
reasons |= SC_ERRORBAR; reasons |= SC_ERRORBAR;
if (!full) if (!full)
return reasons; return reasons;

View file

@ -7,6 +7,7 @@
#include "../managers/animation/AnimationManager.hpp" #include "../managers/animation/AnimationManager.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../managers/HookSystemManager.hpp" #include "../managers/HookSystemManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include <hyprutils/utils/ScopeGuard.hpp> #include <hyprutils/utils/ScopeGuard.hpp>
using namespace Hyprutils::Animation; using namespace Hyprutils::Animation;
@ -18,7 +19,7 @@ CHyprError::CHyprError() {
if (!m_isCreated) if (!m_isCreated)
return; return;
g_pHyprRenderer->damageMonitor(g_pCompositor->m_lastMonitor.lock()); g_pHyprRenderer->damageMonitor(Desktop::focusState()->monitor());
m_monitorChanged = true; m_monitorChanged = true;
}); });

View file

@ -7,6 +7,7 @@
#include "../managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
#include "../managers/LayoutManager.hpp" #include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp" #include "../managers/EventManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "xwayland/XWayland.hpp" #include "xwayland/XWayland.hpp"
void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) { 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); OPENINGON = getClosestNodeOnWorkspace(PNODE->workspaceID, MOUSECOORDS);
} else if (*PUSEACTIVE) { } else if (*PUSEACTIVE) {
if (g_pCompositor->m_lastWindow.lock() && !g_pCompositor->m_lastWindow->m_isFloating && g_pCompositor->m_lastWindow.lock() != pWindow && if (Desktop::focusState()->window() && !Desktop::focusState()->window()->m_isFloating && Desktop::focusState()->window() != pWindow &&
g_pCompositor->m_lastWindow->m_workspace == pWindow->m_workspace && g_pCompositor->m_lastWindow->m_isMapped) { Desktop::focusState()->window()->m_workspace == pWindow->m_workspace && Desktop::focusState()->window()->m_isMapped) {
OPENINGON = getNodeFromWindow(g_pCompositor->m_lastWindow.lock()); OPENINGON = getNodeFromWindow(Desktop::focusState()->window());
} else { } else {
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS)); 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) { 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)) if (!validMapped(PWINDOW))
return; return;
@ -922,7 +923,7 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
if (silent) { if (silent) {
const auto PNODETOFOCUS = getClosestNodeOnWorkspace(originalWorkspaceID, originalPos); const auto PNODETOFOCUS = getClosestNodeOnWorkspace(originalWorkspaceID, originalPos);
if (PNODETOFOCUS && PNODETOFOCUS->pWindow.lock()) 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() { Vector2D CHyprDwindleLayout::predictSizeForNewWindowTiled() {
if (!g_pCompositor->m_lastMonitor) if (!Desktop::focusState()->monitor())
return {}; return {};
// get window candidate // get window candidate
PHLWINDOW candidate = g_pCompositor->m_lastWindow.lock(); PHLWINDOW candidate = Desktop::focusState()->window();
if (!candidate) if (!candidate)
candidate = g_pCompositor->m_lastMonitor->m_activeWorkspace->getFirstWindow(); candidate = Desktop::focusState()->monitor()->m_activeWorkspace->getFirstWindow();
// create a fake node // create a fake node
SDwindleNodeData node; SDwindleNodeData node;
if (!candidate) if (!candidate)
return g_pCompositor->m_lastMonitor->m_size; return Desktop::focusState()->monitor()->m_size;
else { else {
const auto PNODE = getNodeFromWindow(candidate); const auto PNODE = getNodeFromWindow(candidate);

View file

@ -5,6 +5,7 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../config/ConfigManager.hpp" #include "../config/ConfigManager.hpp"
#include "../desktop/Window.hpp" #include "../desktop/Window.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../protocols/XDGShell.hpp" #include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp" #include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp" #include "../xwayland/XSurface.hpp"
@ -208,8 +209,8 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) { bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) {
static auto PAUTOGROUP = CConfigValue<Hyprlang::INT>("group:auto_group"); 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 ? const PHLWINDOW OPENINGON = Desktop::focusState()->window() && Desktop::focusState()->window()->m_workspace == pWindow->m_workspace ?
g_pCompositor->m_lastWindow.lock() : Desktop::focusState()->window() :
(pWindow->m_workspace ? pWindow->m_workspace->getFirstWindow() : nullptr); (pWindow->m_workspace ? pWindow->m_workspace->getFirstWindow() : nullptr);
const bool FLOATEDINTOTILED = pWindow->m_isFloating && OPENINGON && !OPENINGON->m_isFloating; const bool FLOATEDINTOTILED = pWindow->m_isFloating && OPENINGON && !OPENINGON->m_isFloating;
const bool SWALLOWING = pWindow->m_swallowed || pWindow->m_groupSwallowed; const bool SWALLOWING = pWindow->m_swallowed || pWindow->m_groupSwallowed;
@ -304,7 +305,7 @@ void IHyprLayout::onBeginDragWindow() {
g_pKeybindManager->shadowKeybinds(); g_pKeybindManager->shadowKeybinds();
g_pCompositor->focusWindow(DRAGGINGWINDOW); Desktop::focusState()->rawWindowFocus(DRAGGINGWINDOW);
g_pCompositor->changeWindowZOrder(DRAGGINGWINDOW, true); g_pCompositor->changeWindowZOrder(DRAGGINGWINDOW, true);
} }
@ -394,7 +395,7 @@ void IHyprLayout::onEndDragWindow() {
} }
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW); g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
g_pCompositor->focusWindow(DRAGGINGWINDOW); Desktop::focusState()->fullWindowFocus(DRAGGINGWINDOW);
g_pInputManager->m_wasDraggingWindow = false; g_pInputManager->m_wasDraggingWindow = false;
} }
@ -785,7 +786,7 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
// fix pseudo leaving artifacts // fix pseudo leaving artifacts
g_pHyprRenderer->damageMonitor(pWindow->m_monitor.lock()); g_pHyprRenderer->damageMonitor(pWindow->m_monitor.lock());
if (pWindow == g_pCompositor->m_lastWindow) if (pWindow == Desktop::focusState()->window())
m_lastTiledWindow = pWindow; m_lastTiledWindow = pWindow;
} else { } else {
onWindowRemovedTiling(pWindow); onWindowRemovedTiling(pWindow);
@ -852,7 +853,7 @@ void IHyprLayout::fitFloatingWindowOnMonitor(PHLWINDOW w, std::optional<CBox> tb
} }
void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) { 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)) if (!validMapped(PWINDOW))
return; return;
@ -927,7 +928,7 @@ PHLWINDOW IHyprLayout::getNextWindowCandidate(PHLWINDOW pWindow) {
pWindowCandidate = PWORKSPACE->getFirstWindow(); pWindowCandidate = PWORKSPACE->getFirstWindow();
if (!pWindowCandidate || pWindow == pWindowCandidate || !pWindowCandidate->m_isMapped || pWindowCandidate->isHidden() || pWindowCandidate->m_X11ShouldntFocus || 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 nullptr;
return pWindowCandidate; return pWindowCandidate;
@ -949,13 +950,13 @@ void IHyprLayout::bringWindowToTop(PHLWINDOW pWindow) {
void IHyprLayout::requestFocusForWindow(PHLWINDOW pWindow) { void IHyprLayout::requestFocusForWindow(PHLWINDOW pWindow) {
bringWindowToTop(pWindow); bringWindowToTop(pWindow);
g_pCompositor->focusWindow(pWindow); Desktop::focusState()->fullWindowFocus(pWindow);
g_pCompositor->warpCursorTo(pWindow->middle()); g_pCompositor->warpCursorTo(pWindow->middle());
} }
Vector2D IHyprLayout::predictSizeForNewWindowFloating(PHLWINDOW pWindow) { // get all rules, see if we have any size overrides. Vector2D IHyprLayout::predictSizeForNewWindowFloating(PHLWINDOW pWindow) { // get all rules, see if we have any size overrides.
Vector2D sizeOverride = {}; Vector2D sizeOverride = {};
if (g_pCompositor->m_lastMonitor) { if (Desktop::focusState()->monitor()) {
// If `persistentsize` is set, use the stored size if available. // If `persistentsize` is set, use the stored size if available.
const bool HASPERSISTENTSIZE = pWindow->m_ruleApplicator->persistentSize().valueOrDefault(); const bool HASPERSISTENTSIZE = pWindow->m_ruleApplicator->persistentSize().valueOrDefault();

View file

@ -9,6 +9,7 @@
#include "../managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
#include "../managers/LayoutManager.hpp" #include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp" #include "../managers/EventManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "xwayland/XWayland.hpp" #include "xwayland/XWayland.hpp"
SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) { SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) {
@ -93,7 +94,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
const auto PNODE = [&]() { const auto PNODE = [&]() {
if (*PNEWONACTIVE != "none" && !BNEWISMASTER) { 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"))) { if (pLastNode && !(pLastNode->isMaster && (getMastersOnWorkspace(pWindow->workspaceID()) == 1 || *PNEWSTATUS == "slave"))) {
auto it = std::ranges::find(m_masterNodesData, *pLastNode); auto it = std::ranges::find(m_masterNodesData, *pLastNode);
if (!BNEWBEFOREACTIVE) if (!BNEWBEFOREACTIVE)
@ -111,8 +112,8 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
static auto PMFACT = CConfigValue<Hyprlang::FLOAT>("master:mfact"); static auto PMFACT = CConfigValue<Hyprlang::FLOAT>("master:mfact");
float lastSplitPercent = *PMFACT; float lastSplitPercent = *PMFACT;
auto OPENINGON = isWindowTiled(g_pCompositor->m_lastWindow.lock()) && g_pCompositor->m_lastWindow->m_workspace == pWindow->m_workspace ? auto OPENINGON = isWindowTiled(Desktop::focusState()->window()) && Desktop::focusState()->window()->m_workspace == pWindow->m_workspace ?
getNodeFromWindow(g_pCompositor->m_lastWindow.lock()) : getNodeFromWindow(Desktop::focusState()->window()) :
getMasterNodeOnWorkspace(pWindow->workspaceID()); getMasterNodeOnWorkspace(pWindow->workspaceID());
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal(); 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) { 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)) if (!validMapped(PWINDOW))
return; return;
@ -985,14 +986,14 @@ void CHyprMasterLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir,
pWindow->m_monitor = PWINDOW2->m_monitor; pWindow->m_monitor = PWINDOW2->m_monitor;
if (!silent) { if (!silent) {
const auto pMonitor = pWindow->m_monitor.lock(); const auto pMonitor = pWindow->m_monitor.lock();
g_pCompositor->setActiveMonitor(pMonitor); Desktop::focusState()->rawMonitorFocus(pMonitor);
} }
onWindowCreatedTiling(pWindow); onWindowCreatedTiling(pWindow);
} else { } else {
// if same monitor, switch windows // if same monitor, switch windows
switchWindows(pWindow, PWINDOW2); switchWindows(pWindow, PWINDOW2);
if (silent) if (silent)
g_pCompositor->focusWindow(PWINDOW2); Desktop::focusState()->fullWindowFocus(PWINDOW2);
} }
pWindow->updateGroupOutputs(); pWindow->updateGroupOutputs();
@ -1083,18 +1084,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!validMapped(PWINDOWTOCHANGETO)) if (!validMapped(PWINDOWTOCHANGETO))
return; return;
if (header.pWindow->isFullscreen()) { Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO);
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()); g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle());
}
g_pInputManager->m_forcedFocus = PWINDOWTOCHANGETO; g_pInputManager->m_forcedFocus = PWINDOWTOCHANGETO;
g_pInputManager->simulateMouseMovement(); g_pInputManager->simulateMouseMovement();
@ -1498,25 +1489,25 @@ void CHyprMasterLayout::replaceWindowDataWith(PHLWINDOW from, PHLWINDOW to) {
Vector2D CHyprMasterLayout::predictSizeForNewWindowTiled() { Vector2D CHyprMasterLayout::predictSizeForNewWindowTiled() {
static auto PNEWSTATUS = CConfigValue<std::string>("master:new_status"); static auto PNEWSTATUS = CConfigValue<std::string>("master:new_status");
if (!g_pCompositor->m_lastMonitor) if (!Desktop::focusState()->monitor())
return {}; 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) 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 if (!MASTER) // wtf
return {}; return {};
if (*PNEWSTATUS == "master") { if (*PNEWSTATUS == "master") {
return MASTER->size; return MASTER->size;
} else { } 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 // 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 {}; return {};

View file

@ -1,5 +1,6 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../devices/IKeyboard.hpp" #include "../devices/IKeyboard.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
#include "../protocols/ShortcutsInhibit.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) if (!*PINITIALWSTRACKING || g_pConfigManager->m_isLaunchingExecOnce)
return {}; return {};
const auto PMONITOR = g_pCompositor->m_lastMonitor; const auto PMONITOR = Desktop::focusState()->monitor();
if (!PMONITOR || !PMONITOR->m_activeWorkspace) if (!PMONITOR || !PMONITOR->m_activeWorkspace)
return {}; return {};
@ -336,15 +337,15 @@ static void updateRelativeCursorCoords() {
if (*PNOWARPS) if (*PNOWARPS)
return; return;
if (g_pCompositor->m_lastWindow) if (Desktop::focusState()->window())
g_pCompositor->m_lastWindow->m_relativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - g_pCompositor->m_lastWindow->m_position; Desktop::focusState()->window()->m_relativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - Desktop::focusState()->window()->m_position;
} }
bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) { bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
if (!monitor) if (!monitor)
return false; return false;
const auto LASTMONITOR = g_pCompositor->m_lastMonitor.lock(); const auto LASTMONITOR = Desktop::focusState()->monitor();
if (!LASTMONITOR) if (!LASTMONITOR)
return false; return false;
if (LASTMONITOR == monitor) { if (LASTMONITOR == monitor) {
@ -355,7 +356,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps"); 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; const auto PNEWMAINWORKSPACE = monitor->m_activeWorkspace;
g_pInputManager->unconstrainMouse(); g_pInputManager->unconstrainMouse();
@ -366,7 +367,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
const auto PNEWWINDOW = PNEWWORKSPACE->getLastFocusedWindow(); const auto PNEWWINDOW = PNEWWORKSPACE->getLastFocusedWindow();
if (PNEWWINDOW) { if (PNEWWINDOW) {
updateRelativeCursorCoords(); updateRelativeCursorCoords();
g_pCompositor->focusWindow(PNEWWINDOW); Desktop::focusState()->fullWindowFocus(PNEWWINDOW);
PNEWWINDOW->warpCursor(); PNEWWINDOW->warpCursor();
if (*PNOWARPS == 0 || *PFOLLOWMOUSE < 2) { if (*PNOWARPS == 0 || *PFOLLOWMOUSE < 2) {
@ -375,19 +376,19 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
g_pInputManager->m_forcedFocus.reset(); g_pInputManager->m_forcedFocus.reset();
} }
} else { } else {
g_pCompositor->focusWindow(nullptr); Desktop::focusState()->rawWindowFocus(nullptr);
g_pCompositor->warpCursorTo(monitor->middle()); g_pCompositor->warpCursorTo(monitor->middle());
} }
g_pCompositor->setActiveMonitor(monitor); Desktop::focusState()->rawMonitorFocus(monitor);
return true; 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 PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps"); 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) if (PWINDOWTOCHANGETO == PLASTWINDOW || !PWINDOWTOCHANGETO)
return; return;
@ -395,24 +396,11 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveF
// remove constraints // remove constraints
g_pInputManager->unconstrainMouse(); g_pInputManager->unconstrainMouse();
if (PLASTWINDOW && PLASTWINDOW->m_workspace == PWINDOWTOCHANGETO->m_workspace && PLASTWINDOW->isFullscreen()) { if (PLASTWINDOW && PLASTWINDOW->m_workspace == PWINDOWTOCHANGETO->m_workspace)
const auto PWORKSPACE = PLASTWINDOW->m_workspace; Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory, forceFSCycle);
const auto MODE = PWORKSPACE->m_fullscreenMode; else {
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 {
updateRelativeCursorCoords(); updateRelativeCursorCoords();
g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory); Desktop::focusState()->fullWindowFocus(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory, forceFSCycle);
PWINDOWTOCHANGETO->warpCursor(); PWINDOWTOCHANGETO->warpCursor();
// Move mouse focus to the new window if required by current follow_mouse and warp modes // 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 // event
const auto PNEWMON = PWINDOWTOCHANGETO->m_monitor.lock(); 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) { SDispatchResult CKeybindManager::killActive(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) { if (!PWINDOW) {
Debug::log(ERR, "killActive: no window found"); Debug::log(ERR, "killActive: no window found");
@ -1011,10 +999,10 @@ SDispatchResult CKeybindManager::killActive(std::string args) {
} }
SDispatchResult CKeybindManager::closeActive(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)"}; 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 {}; return {};
} }
@ -1058,13 +1046,13 @@ SDispatchResult CKeybindManager::signalActive(std::string args) {
Debug::log(ERR, "signalActive: invalid signal number {}", SIGNALNUM); Debug::log(ERR, "signalActive: invalid signal number {}", SIGNALNUM);
return {.success = false, .error = std::format("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) { } catch (const std::exception& e) {
Debug::log(ERR, "signalActive: invalid signal format \"{}\"", args); Debug::log(ERR, "signalActive: invalid signal format \"{}\"", args);
return {.success = false, .error = std::format("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 {}; return {};
} }
@ -1108,7 +1096,7 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<
if (args != "active" && args.length() > 1) if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args); PWINDOW = g_pCompositor->getWindowByRegex(args);
else else
PWINDOW = g_pCompositor->m_lastWindow.lock(); PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) if (!PWINDOW)
return {.success = false, .error = "Window not found"}; return {.success = false, .error = "Window not found"};
@ -1118,7 +1106,7 @@ static SDispatchResult toggleActiveFloatingCore(std::string args, std::optional<
// remove drag status // remove drag status
if (!g_pInputManager->m_currentlyDraggedWindow.expired()) 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) { if (PWINDOW->m_groupData.pNextWindow.lock() && PWINDOW->m_groupData.pNextWindow.lock() != PWINDOW) {
const auto PCURRENT = PWINDOW->getGroupCurrent(); const auto PCURRENT = PWINDOW->getGroupCurrent();
@ -1161,7 +1149,7 @@ SDispatchResult CKeybindManager::setActiveTiled(std::string args) {
} }
SDispatchResult CKeybindManager::centerWindow(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()) if (!PWINDOW || !PWINDOW->m_isFloating || PWINDOW->isFullscreen())
return {.success = false, .error = "No floating window found"}; return {.success = false, .error = "No floating window found"};
@ -1184,7 +1172,7 @@ SDispatchResult CKeybindManager::toggleActivePseudo(std::string args) {
if (args != "active" && args.length() > 1) if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args); PWINDOW = g_pCompositor->getWindowByRegex(args);
else else
PWINDOW = g_pCompositor->m_lastWindow.lock(); PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) if (!PWINDOW)
return {.success = false, .error = "Window not found"}; 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 PWORKSPACECENTERON = CConfigValue<Hyprlang::INT>("binds:workspace_center_on");
static auto PHIDESPECIALONWORKSPACECHANGE = CConfigValue<Hyprlang::INT>("binds:hide_special_on_workspace_change"); 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) if (!PMONITOR)
return {.success = false, .error = "Last monitor not found"}; return {.success = false, .error = "Last monitor not found"};
@ -1275,7 +1263,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
updateRelativeCursorCoords(); updateRelativeCursorCoords();
g_pCompositor->setActiveMonitor(PMONITORWORKSPACEOWNER); Desktop::focusState()->rawMonitorFocus(PMONITORWORKSPACEOWNER);
if (BISWORKSPACECURRENT) { if (BISWORKSPACECURRENT) {
if (*PALLOWWORKSPACECYCLES) if (*PALLOWWORKSPACECYCLES)
@ -1292,7 +1280,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
if (PMONITOR != PMONITORWORKSPACEOWNER) { if (PMONITOR != PMONITORWORKSPACEOWNER) {
Vector2D middle = PMONITORWORKSPACEOWNER->middle(); Vector2D middle = PMONITORWORKSPACEOWNER->middle();
if (const auto PLAST = pWorkspaceToChangeTo->getLastFocusedWindow(); PLAST) { if (const auto PLAST = pWorkspaceToChangeTo->getLastFocusedWindow(); PLAST) {
g_pCompositor->focusWindow(PLAST); Desktop::focusState()->fullWindowFocus(PLAST);
if (*PWORKSPACECENTERON == 1) if (*PWORKSPACECENTERON == 1)
middle = PLAST->middle(); middle = PLAST->middle();
} }
@ -1300,7 +1288,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
} }
if (!g_pInputManager->m_lastFocusOnLS) { if (!g_pInputManager->m_lastFocusOnLS) {
if (g_pCompositor->m_lastFocus) if (Desktop::focusState()->surface())
g_pInputManager->sendMotionEventsToFocused(); g_pInputManager->sendMotionEventsToFocused();
else else
g_pInputManager->simulateMouseMovement(); g_pInputManager->simulateMouseMovement();
@ -1320,7 +1308,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
} }
SDispatchResult CKeybindManager::fullscreenActive(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, ' '); const auto ARGS = CConstVarList(args, 2, ' ');
if (!PWINDOW) if (!PWINDOW)
@ -1344,7 +1332,7 @@ SDispatchResult CKeybindManager::fullscreenActive(std::string args) {
} }
SDispatchResult CKeybindManager::fullscreenStateActive(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, ' '); const auto ARGS = CVarList(args, 3, ' ');
if (!PWINDOW) if (!PWINDOW)
@ -1390,7 +1378,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1)); PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1));
args = args.substr(0, args.find_last_of(',')); args = args.substr(0, args.find_last_of(','));
} else { } else {
PWINDOW = g_pCompositor->m_lastWindow.lock(); PWINDOW = Desktop::focusState()->window();
} }
if (!PWINDOW) if (!PWINDOW)
@ -1420,7 +1408,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
const auto FULLSCREENMODE = PWINDOW->m_fullscreenState.internal; const auto FULLSCREENMODE = PWINDOW->m_fullscreenState.internal;
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace); g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
pMonitor = pWorkspace->m_monitor.lock(); pMonitor = pWorkspace->m_monitor.lock();
g_pCompositor->setActiveMonitor(pMonitor); Desktop::focusState()->rawMonitorFocus(pMonitor);
g_pCompositor->setWindowFullscreenInternal(PWINDOW, FULLSCREENMODE); g_pCompositor->setWindowFullscreenInternal(PWINDOW, FULLSCREENMODE);
} else { } else {
pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->monitorID(), workspaceName, false); pWorkspace = g_pCompositor->createNewWorkspace(WORKSPACEID, PWINDOW->monitorID(), workspaceName, false);
@ -1440,7 +1428,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
pMonitor->changeWorkspace(pWorkspace); pMonitor->changeWorkspace(pWorkspace);
g_pCompositor->focusWindow(PWINDOW); Desktop::focusState()->fullWindowFocus(PWINDOW);
PWINDOW->warpCursor(); PWINDOW->warpCursor();
return {}; return {};
@ -1453,7 +1441,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1)); PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1));
args = args.substr(0, args.find_last_of(',')); args = args.substr(0, args.find_last_of(','));
} else { } else {
PWINDOW = g_pCompositor->m_lastWindow.lock(); PWINDOW = Desktop::focusState()->window();
} }
if (!PWINDOW) if (!PWINDOW)
@ -1480,9 +1468,9 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace); 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) 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 else
g_pInputManager->refocus(); 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)}; 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 (!PLASTWINDOW) {
if (*PMONITORFALLBACK) if (*PMONITORFALLBACK)
tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(arg)); tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(arg));
@ -1529,7 +1517,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
// Found window in direction, switch to it // Found window in direction, switch to it
if (PWINDOWTOCHANGETO) { if (PWINDOWTOCHANGETO) {
switchToWindow(PWINDOWTOCHANGETO); switchToWindow(PWINDOWTOCHANGETO, false, *PFULLCYCLE && PLASTWINDOW->isFullscreen());
return {}; return {};
} }
@ -1587,8 +1575,8 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
SDispatchResult CKeybindManager::focusUrgentOrLast(std::string args) { SDispatchResult CKeybindManager::focusUrgentOrLast(std::string args) {
const auto PWINDOWURGENT = g_pCompositor->getUrgentWindow(); 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()) : const auto PWINDOWPREV = Desktop::focusState()->window() ? (Desktop::focusState()->windowHistory().size() < 2 ? nullptr : Desktop::focusState()->windowHistory()[1].lock()) :
(g_pCompositor->m_windowFocusHistory.empty() ? nullptr : g_pCompositor->m_windowFocusHistory[0].lock()); (Desktop::focusState()->windowHistory().empty() ? nullptr : Desktop::focusState()->windowHistory()[0].lock());
if (!PWINDOWURGENT && !PWINDOWPREV) if (!PWINDOWURGENT && !PWINDOWPREV)
return {.success = false, .error = "Window not found"}; return {.success = false, .error = "Window not found"};
@ -1599,8 +1587,8 @@ SDispatchResult CKeybindManager::focusUrgentOrLast(std::string args) {
} }
SDispatchResult CKeybindManager::focusCurrentOrLast(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()) : const auto PWINDOWPREV = Desktop::focusState()->window() ? (Desktop::focusState()->windowHistory().size() < 2 ? nullptr : Desktop::focusState()->windowHistory()[1].lock()) :
(g_pCompositor->m_windowFocusHistory.empty() ? nullptr : g_pCompositor->m_windowFocusHistory[0].lock()); (Desktop::focusState()->windowHistory().empty() ? nullptr : Desktop::focusState()->windowHistory()[0].lock());
if (!PWINDOWPREV) if (!PWINDOWPREV)
return {.success = false, .error = "Window not found"}; return {.success = false, .error = "Window not found"};
@ -1612,7 +1600,7 @@ SDispatchResult CKeybindManager::focusCurrentOrLast(std::string args) {
SDispatchResult CKeybindManager::swapActive(std::string args) { SDispatchResult CKeybindManager::swapActive(std::string args) {
char arg = args[0]; char arg = args[0];
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PLASTWINDOW = Desktop::focusState()->window();
PHLWINDOW PWINDOWTOCHANGETO = nullptr; PHLWINDOW PWINDOWTOCHANGETO = nullptr;
if (!PLASTWINDOW) 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)}; 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) if (!PLASTWINDOW)
return {.success = false, .error = "Window to move not found"}; 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) { SDispatchResult CKeybindManager::toggleGroup(std::string args) {
const auto PWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) if (!PWINDOW)
return {.success = false, .error = "Window not found"}; return {.success = false, .error = "Window not found"};
@ -1746,7 +1734,7 @@ SDispatchResult CKeybindManager::toggleGroup(std::string args) {
} }
SDispatchResult CKeybindManager::changeGroupActive(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) if (!PWINDOW)
return {.success = false, .error = "Window not found"}; return {.success = false, .error = "Window not found"};
@ -1779,7 +1767,7 @@ SDispatchResult CKeybindManager::changeGroupActive(std::string args) {
SDispatchResult CKeybindManager::toggleSplit(std::string args) { SDispatchResult CKeybindManager::toggleSplit(std::string args) {
SLayoutMessageHeader header; SLayoutMessageHeader header;
header.pWindow = g_pCompositor->m_lastWindow.lock(); header.pWindow = Desktop::focusState()->window();
if (!header.pWindow) if (!header.pWindow)
return {.success = false, .error = "Window not found"}; return {.success = false, .error = "Window not found"};
@ -1796,7 +1784,7 @@ SDispatchResult CKeybindManager::toggleSplit(std::string args) {
SDispatchResult CKeybindManager::swapSplit(std::string args) { SDispatchResult CKeybindManager::swapSplit(std::string args) {
SLayoutMessageHeader header; SLayoutMessageHeader header;
header.pWindow = g_pCompositor->m_lastWindow.lock(); header.pWindow = Desktop::focusState()->window();
if (!header.pWindow) if (!header.pWindow)
return {.success = false, .error = "Window not found"}; 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!"}; return {.success = false, .error = "Splitratio invalid in alterSplitRatio!"};
} }
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW) if (!PLASTWINDOW)
return {.success = false, .error = "Window not found"}; 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."}; 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) if (!PWINDOW)
return {.success = false, .error = "Window not found"}; return {.success = false, .error = "Window not found"};
@ -1918,7 +1906,7 @@ SDispatchResult CKeybindManager::moveCursor(std::string args) {
SDispatchResult CKeybindManager::workspaceOpt(std::string args) { SDispatchResult CKeybindManager::workspaceOpt(std::string args) {
// current workspace // current workspace
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace; const auto PWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!PWORKSPACE) if (!PWORKSPACE)
return {.success = false, .error = "Workspace not found"}; // ???? return {.success = false, .error = "Workspace not found"}; // ????
@ -1965,7 +1953,7 @@ SDispatchResult CKeybindManager::workspaceOpt(std::string args) {
} }
// recalc mon // recalc mon
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_lastMonitor->m_id); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(Desktop::focusState()->monitor()->m_id);
return {}; return {};
} }
@ -2011,7 +1999,7 @@ SDispatchResult CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args)
} }
// get the current workspace // get the current workspace
const auto PCURRENTWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace; const auto PCURRENTWORKSPACE = Desktop::focusState()->monitor()->m_activeWorkspace;
if (!PCURRENTWORKSPACE) { if (!PCURRENTWORKSPACE) {
Debug::log(ERR, "moveCurrentWorkspaceToMonitor invalid workspace!"); Debug::log(ERR, "moveCurrentWorkspaceToMonitor invalid workspace!");
return {.success = false, .error = "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!"}; return {.success = false, .error = "focusWorkspaceOnCurrentMonitor invalid workspace!"};
} }
const auto PCURRMONITOR = g_pCompositor->m_lastMonitor.lock(); const auto PCURRMONITOR = Desktop::focusState()->monitor();
if (!PCURRMONITOR) { if (!PCURRMONITOR) {
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor monitor doesn't exist!"); Debug::log(ERR, "focusWorkspaceOnCurrentMonitor monitor doesn't exist!");
@ -2117,7 +2105,7 @@ SDispatchResult CKeybindManager::toggleSpecialWorkspace(std::string args) {
} }
bool requestedWorkspaceIsAlreadyOpen = false; bool requestedWorkspaceIsAlreadyOpen = false;
const auto PMONITOR = g_pCompositor->m_lastMonitor; const auto PMONITOR = Desktop::focusState()->monitor();
auto specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID(); auto specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID();
for (auto const& m : g_pCompositor->m_monitors) { for (auto const& m : g_pCompositor->m_monitors) {
@ -2183,7 +2171,7 @@ SDispatchResult CKeybindManager::forceRendererReload(std::string args) {
} }
SDispatchResult CKeybindManager::resizeActive(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) if (!PLASTWINDOW)
return {.success = false, .error = "No window found"}; return {.success = false, .error = "No window found"};
@ -2205,7 +2193,7 @@ SDispatchResult CKeybindManager::resizeActive(std::string args) {
} }
SDispatchResult CKeybindManager::moveActive(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) if (!PLASTWINDOW)
return {.success = false, .error = "No window found"}; return {.success = false, .error = "No window found"};
@ -2271,9 +2259,9 @@ SDispatchResult CKeybindManager::resizeWindow(std::string args) {
} }
SDispatchResult CKeybindManager::circleNext(std::string arg) { 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. // 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) { if (PWS && PWS->getWindows() > 0) {
const auto PWINDOW = PWS->getFirstWindow(); const auto PWINDOW = PWS->getFirstWindow();
switchToWindow(PWINDOW); 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 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 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 HIST = args.contains("hist") || args.contains("h");
const auto& w = HIST ? g_pCompositor->getWindowCycleHist(g_pCompositor->m_lastWindow, true, floatStatus, VISIBLE, NEXT) : const auto& w = HIST ? g_pCompositor->getWindowCycleHist(Desktop::focusState()->window(), true, floatStatus, VISIBLE, NEXT) :
g_pCompositor->getWindowCycle(g_pCompositor->m_lastWindow.lock(), true, floatStatus, VISIBLE, PREV); g_pCompositor->getWindowCycle(Desktop::focusState()->window(), true, floatStatus, VISIBLE, PREV);
switchToWindow(w, HIST); switchToWindow(w, HIST);
@ -2318,40 +2306,13 @@ SDispatchResult CKeybindManager::focusWindow(std::string regexp) {
updateRelativeCursorCoords(); updateRelativeCursorCoords();
if (g_pCompositor->m_lastMonitor && g_pCompositor->m_lastMonitor->m_activeWorkspace != PWINDOW->m_workspace && if (Desktop::focusState()->monitor() && Desktop::focusState()->monitor()->m_activeWorkspace != PWINDOW->m_workspace &&
g_pCompositor->m_lastMonitor->m_activeSpecialWorkspace != PWINDOW->m_workspace) { Desktop::focusState()->monitor()->m_activeSpecialWorkspace != PWINDOW->m_workspace) {
Debug::log(LOG, "Fake executing workspace to move focus"); Debug::log(LOG, "Fake executing workspace to move focus");
changeworkspace(PWORKSPACE->getConfigName()); changeworkspace(PWORKSPACE->getConfigName());
} }
if (PWORKSPACE->m_hasFullscreenWindow) { Desktop::focusState()->fullWindowFocus(PWINDOW, nullptr, false);
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);
PWINDOW->warpCursor(); PWINDOW->warpCursor();
@ -2363,7 +2324,7 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) {
CVarList vars{args, 0, 's', true}; CVarList vars{args, 0, 's', true};
if (vars.size() == 1) if (vars.size() == 1)
PWINDOW = g_pCompositor->m_lastWindow.lock(); PWINDOW = Desktop::focusState()->window();
else if (vars.size() == 2) else if (vars.size() == 2)
PWINDOW = g_pCompositor->getWindowByRegex(vars[1]); PWINDOW = g_pCompositor->getWindowByRegex(vars[1]);
else else
@ -2378,7 +2339,7 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) {
} }
SDispatchResult CKeybindManager::toggleSwallow(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)) if (!valid(pWindow) || !valid(pWindow->m_swallowed))
return {}; return {};
@ -2436,7 +2397,7 @@ SDispatchResult CKeybindManager::pass(std::string regexp) {
return {.success = false, .error = "No kb in pass?"}; 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 LASTMOUSESURF = g_pSeatManager->m_state.pointerFocus.lock();
const auto LASTKBSURF = g_pSeatManager->m_state.keyboardFocus.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]; const std::string regexp = ARGS[2];
PHLWINDOW PWINDOW = nullptr; 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 //if regexp is not empty, send shortcut to current window
//else, don't change focus //else, don't change focus
@ -2598,10 +2559,10 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) {
//copied the rest from pass and modified it //copied the rest from pass and modified it
// if wl -> xwl, activate destination // 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); g_pXWaylandManager->activateSurface(PWINDOW->m_wlSurface->resource(), true);
// if xwl -> xwl, send to current. Timing issues make this not work. // 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; PWINDOW = nullptr;
g_pSeatManager->sendKeyboardMods(MOD, 0, 0, 0); g_pSeatManager->sendKeyboardMods(MOD, 0, 0, 0);
@ -2653,7 +2614,7 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) {
} }
SDispatchResult CKeybindManager::layoutmsg(std::string msg) { SDispatchResult CKeybindManager::layoutmsg(std::string msg) {
SLayoutMessageHeader hd = {g_pCompositor->m_lastWindow.lock()}; SLayoutMessageHeader hd = {Desktop::focusState()->window()};
g_pLayoutManager->getCurrentLayout()->layoutMessage(hd, msg); g_pLayoutManager->getCurrentLayout()->layoutMessage(hd, msg);
return {}; return {};
@ -2690,14 +2651,14 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) {
PHLWINDOW toSwap = nullptr; PHLWINDOW toSwap = nullptr;
if (g_pCompositor->m_lastWindow.expired()) if (!Desktop::focusState()->window())
return {}; return {};
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PLASTWINDOW = Desktop::focusState()->window();
const auto PLASTCYCLED = const auto PLASTCYCLED =
validMapped(g_pCompositor->m_lastWindow->m_lastCycledWindow) && g_pCompositor->m_lastWindow->m_lastCycledWindow->m_workspace == PLASTWINDOW->m_workspace ? validMapped(Desktop::focusState()->window()->m_lastCycledWindow) && Desktop::focusState()->window()->m_lastCycledWindow->m_workspace == PLASTWINDOW->m_workspace ?
g_pCompositor->m_lastWindow->m_lastCycledWindow.lock() : Desktop::focusState()->window()->m_lastCycledWindow.lock() :
nullptr; nullptr;
const bool NEED_PREV = arg == "last" || arg == "l" || arg == "prev" || arg == "p"; 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; PLASTWINDOW->m_lastCycledWindow = toSwap;
g_pCompositor->focusWindow(PLASTWINDOW); Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
return {}; return {};
} }
@ -2741,7 +2702,7 @@ SDispatchResult CKeybindManager::pinActive(std::string args) {
if (args != "active" && args.length() > 1) if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args); PWINDOW = g_pCompositor->getWindowByRegex(args);
else else
PWINDOW = g_pCompositor->m_lastWindow.lock(); PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) { if (!PWINDOW) {
Debug::log(ERR, "pin: window not found"); Debug::log(ERR, "pin: window not found");
@ -2827,8 +2788,8 @@ SDispatchResult CKeybindManager::changeMouseBindMode(const eMouseBindMode MODE)
} }
SDispatchResult CKeybindManager::bringActiveToTop(std::string args) { SDispatchResult CKeybindManager::bringActiveToTop(std::string args) {
if (g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_isFloating) if (Desktop::focusState()->window() && Desktop::focusState()->window()->m_isFloating)
g_pCompositor->changeWindowZOrder(g_pCompositor->m_lastWindow.lock(), true); g_pCompositor->changeWindowZOrder(Desktop::focusState()->window(), true);
return {}; return {};
} }
@ -2838,8 +2799,8 @@ SDispatchResult CKeybindManager::alterZOrder(std::string args) {
const auto POSITION = args.substr(0, args.find_first_of(',')); const auto POSITION = args.substr(0, args.find_first_of(','));
auto PWINDOW = g_pCompositor->getWindowByRegex(WINDOWREGEX); auto PWINDOW = g_pCompositor->getWindowByRegex(WINDOWREGEX);
if (!PWINDOW && g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow->m_isFloating) if (!PWINDOW && Desktop::focusState()->window() && Desktop::focusState()->window()->m_isFloating)
PWINDOW = g_pCompositor->m_lastWindow.lock(); PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) { if (!PWINDOW) {
Debug::log(ERR, "alterZOrder: no window"); Debug::log(ERR, "alterZOrder: no window");
@ -2875,7 +2836,7 @@ SDispatchResult CKeybindManager::lockGroups(std::string args) {
} }
SDispatchResult CKeybindManager::lockActiveGroup(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) if (!PWINDOW)
return {.success = false, .error = "No window found"}; return {.success = false, .error = "No window found"};
@ -2916,7 +2877,7 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn
pWindowInDirection->setGroupCurrent(pWindow); pWindowInDirection->setGroupCurrent(pWindow);
pWindow->updateWindowDecos(); pWindow->updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow); g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
g_pCompositor->focusWindow(pWindow); Desktop::focusState()->fullWindowFocus(pWindow);
pWindow->warpCursor(); pWindow->warpCursor();
g_pEventManager->postEvent(SHyprIPCEvent{"moveintogroup", std::format("{:x}", rc<uintptr_t>(pWindow.get()))}); 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) { if (*BFOCUSREMOVEDWINDOW) {
g_pCompositor->focusWindow(pWindow); Desktop::focusState()->fullWindowFocus(pWindow);
pWindow->warpCursor(); pWindow->warpCursor();
} else { } else {
g_pCompositor->focusWindow(PWINDOWPREV); Desktop::focusState()->fullWindowFocus(PWINDOWPREV);
PWINDOWPREV->warpCursor(); 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)}; 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) if (!PWINDOW || PWINDOW->m_groupData.deny)
return {}; return {};
@ -3006,7 +2967,7 @@ SDispatchResult CKeybindManager::moveOutOfGroup(std::string args) {
if (args != "active" && args.length() > 1) if (args != "active" && args.length() > 1)
PWINDOW = g_pCompositor->getWindowByRegex(args); PWINDOW = g_pCompositor->getWindowByRegex(args);
else else
PWINDOW = g_pCompositor->m_lastWindow.lock(); PWINDOW = Desktop::focusState()->window();
if (!PWINDOW) if (!PWINDOW)
return {.success = false, .error = "No window found"}; 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)}; 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) if (!PWINDOW)
return {.success = false, .error = "No window found"}; return {.success = false, .error = "No window found"};
@ -3088,7 +3049,7 @@ SDispatchResult CKeybindManager::setIgnoreGroupLock(std::string args) {
} }
SDispatchResult CKeybindManager::denyWindowFromGroup(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())) if (!PWINDOW || (PWINDOW && PWINDOW->m_groupData.pNextWindow.lock()))
return {}; return {};
@ -3120,7 +3081,7 @@ SDispatchResult CKeybindManager::global(std::string args) {
SDispatchResult CKeybindManager::moveGroupWindow(std::string args) { SDispatchResult CKeybindManager::moveGroupWindow(std::string args) {
const auto BACK = args == "b" || args == "prev"; const auto BACK = args == "b" || args == "prev";
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PLASTWINDOW = Desktop::focusState()->window();
if (!PLASTWINDOW) if (!PLASTWINDOW)
return {.success = false, .error = "No window found"}; return {.success = false, .error = "No window found"};
@ -3186,7 +3147,7 @@ SDispatchResult CKeybindManager::setProp(std::string args) {
if (vars.size() < 3) if (vars.size() < 3)
return {.success = false, .error = "Not enough args"}; 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]); const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[0]);
if (!PWINDOW) if (!PWINDOW)
@ -3321,10 +3282,11 @@ SDispatchResult CKeybindManager::setProp(std::string args) {
g_pCompositor->updateAllWindowsAnimatedDecorationValues(); g_pCompositor->updateAllWindowsAnimatedDecorationValues();
if (!(PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() == noFocus)) { if (PWINDOW->m_ruleApplicator->noFocus().valueOrDefault() != noFocus) {
g_pCompositor->focusWindow(nullptr); // FIXME: what the fuck is going on here? -vax
g_pCompositor->focusWindow(PWINDOW); Desktop::focusState()->rawWindowFocus(nullptr);
g_pCompositor->focusWindow(PLASTWINDOW); Desktop::focusState()->fullWindowFocus(PWINDOW);
Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
} }
if (PROP == "no_vrr") if (PROP == "no_vrr")

View file

@ -163,7 +163,8 @@ class CKeybindManager {
static bool tryMoveFocusToMonitor(PHLMONITOR monitor); static bool tryMoveFocusToMonitor(PHLMONITOR monitor);
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = ""); static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection); 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 spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace, const std::string& execRuleToken = "");
static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace); static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);

View file

@ -14,6 +14,7 @@
#include "../managers/HookSystemManager.hpp" #include "../managers/HookSystemManager.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../render/OpenGL.hpp" #include "../render/OpenGL.hpp"
#include "../desktop/state/FocusState.hpp"
#include "SeatManager.hpp" #include "SeatManager.hpp"
#include "../helpers/time/Time.hpp" #include "../helpers/time/Time.hpp"
#include <cstring> #include <cstring>
@ -799,7 +800,7 @@ void CPointerManager::warpAbsolute(Vector2D abs, SP<IHID> dev) {
auto outputMappedArea = [&mappedArea](const std::string& output) { auto outputMappedArea = [&mappedArea](const std::string& output) {
if (output == "current") { if (output == "current") {
if (const auto PLASTMONITOR = g_pCompositor->m_lastMonitor.lock(); PLASTMONITOR) if (const auto PLASTMONITOR = Desktop::focusState()->monitor(); PLASTMONITOR)
return PLASTMONITOR->logicalBox(); return PLASTMONITOR->logicalBox();
} else if (const auto PMONITOR = g_pCompositor->getMonitorFromString(output); PMONITOR) } else if (const auto PMONITOR = g_pCompositor->getMonitorFromString(output); PMONITOR)
return PMONITOR->logicalBox(); return PMONITOR->logicalBox();
@ -927,7 +928,7 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
listener->frame = pointer->m_pointerEvents.frame.listen([] { listener->frame = pointer->m_pointerEvents.frame.listen([] {
bool shouldSkip = false; bool shouldSkip = false;
if (!g_pSeatManager->m_mouse.expired() && g_pInputManager->isLocked()) { 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(); shouldSkip = PMONITOR && PMONITOR->shouldSkipScheduleFrameOnMouseEvent();
} }
g_pSeatManager->m_isPointerFrameSkipped = shouldSkip; g_pSeatManager->m_isPointerFrameSkipped = shouldSkip;

View file

@ -6,6 +6,7 @@
#include "../protocols/PrimarySelection.hpp" #include "../protocols/PrimarySelection.hpp"
#include "../protocols/core/Compositor.hpp" #include "../protocols/core/Compositor.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../devices/IKeyboard.hpp" #include "../devices/IKeyboard.hpp"
#include "../desktop/LayerSurface.hpp" #include "../desktop/LayerSurface.hpp"
#include "../managers/input/InputManager.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 this was a popup grab, focus its parent window to maintain context
if (validMapped(parentWindow)) { 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); Debug::log(LOG, "[seatmgr] Refocused popup parent window {} (follow_mouse={})", parentWindow->m_title, *PFOLLOWMOUSE);
} else } else
g_pInputManager->refocusLastWindow(PMONITOR); 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; refocus = layer->m_interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
if (refocus) { if (refocus) {
auto candidate = g_pCompositor->m_lastWindow.lock(); auto candidate = Desktop::focusState()->window();
if (candidate) if (candidate)
g_pCompositor->focusWindow(candidate); Desktop::focusState()->rawWindowFocus(candidate);
} }
if (oldGrab->m_onEnd) if (oldGrab->m_onEnd)

View file

@ -4,6 +4,7 @@
#include "../protocols/FractionalScale.hpp" #include "../protocols/FractionalScale.hpp"
#include "../protocols/SessionLock.hpp" #include "../protocols/SessionLock.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../desktop/state/FocusState.hpp"
#include "./managers/SeatManager.hpp" #include "./managers/SeatManager.hpp"
#include "./managers/input/InputManager.hpp" #include "./managers/input/InputManager.hpp"
#include "./managers/eventLoop/EventLoopManager.hpp" #include "./managers/eventLoop/EventLoopManager.hpp"
@ -25,8 +26,8 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
}); });
listeners.destroy = surface_->m_events.destroy.listen([this] { listeners.destroy = surface_->m_events.destroy.listen([this] {
if (pWlrSurface == g_pCompositor->m_lastFocus) if (pWlrSurface == Desktop::focusState()->surface())
g_pCompositor->m_lastFocus.reset(); Desktop::focusState()->surface().reset();
g_pSessionLockManager->removeSessionLockSurface(this); g_pSessionLockManager->removeSessionLockSurface(this);
}); });
@ -34,7 +35,7 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
listeners.commit = surface_->m_events.commit.listen([this] { listeners.commit = surface_->m_events.commit.listen([this] {
const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID);
if (mapped && !g_pCompositor->m_lastFocus) if (mapped && !Desktop::focusState()->surface())
g_pInputManager->simulateMouseMovement(); g_pInputManager->simulateMouseMovement();
if (PMONITOR) if (PMONITOR)
@ -82,13 +83,13 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
m_sessionLock->listeners.destroy = pLock->m_events.destroyed.listen([this] { m_sessionLock->listeners.destroy = pLock->m_events.destroyed.listen([this] {
m_sessionLock.reset(); m_sessionLock.reset();
g_pCompositor->focusSurface(nullptr); Desktop::focusState()->rawSurfaceFocus(nullptr);
for (auto const& m : g_pCompositor->m_monitors) for (auto const& m : g_pCompositor->m_monitors)
g_pHyprRenderer->damageMonitor(m); g_pHyprRenderer->damageMonitor(m);
}); });
g_pCompositor->focusSurface(nullptr); Desktop::focusState()->rawSurfaceFocus(nullptr);
g_pSeatManager->setGrab(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; }); 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(); }); std::erase_if(m_sessionLock->vSessionLockSurfaces, [&](const auto& other) { return pSLS == other.get(); });
if (g_pCompositor->m_lastFocus) if (Desktop::focusState()->surface())
return; return;
for (auto const& sls : m_sessionLock->vSessionLockSurfaces) { for (auto const& sls : m_sessionLock->vSessionLockSurfaces) {
if (!sls->mapped) if (!sls->mapped)
continue; continue;
g_pCompositor->focusSurface(sls->surface->surface()); Desktop::focusState()->rawSurfaceFocus(sls->surface->surface());
break; break;
} }
} }

View file

@ -1,5 +1,6 @@
#include "XWaylandManager.hpp" #include "XWaylandManager.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../events/Events.hpp" #include "../events/Events.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../helpers/Monitor.hpp" #include "../helpers/Monitor.hpp"
@ -69,8 +70,8 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) {
pWindow->m_xdgSurface->m_toplevel->setActive(activate); pWindow->m_xdgSurface->m_toplevel->setActive(activate);
if (activate) { if (activate) {
g_pCompositor->m_lastFocus = getWindowSurface(pWindow); Desktop::focusState()->surface() = getWindowSurface(pWindow);
g_pCompositor->m_lastWindow = pWindow; Desktop::focusState()->window() = pWindow;
} }
if (!pWindow->m_pinned) if (!pWindow->m_pinned)

View file

@ -9,6 +9,7 @@
#include "../../config/ConfigManager.hpp" #include "../../config/ConfigManager.hpp"
#include "../../desktop/Window.hpp" #include "../../desktop/Window.hpp"
#include "../../desktop/LayerSurface.hpp" #include "../../desktop/LayerSurface.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../protocols/CursorShape.hpp" #include "../../protocols/CursorShape.hpp"
#include "../../protocols/IdleInhibit.hpp" #include "../../protocols/IdleInhibit.hpp"
#include "../../protocols/RelativePointer.hpp" #include "../../protocols/RelativePointer.hpp"
@ -168,18 +169,18 @@ void CInputManager::simulateMouseMovement() {
} }
void CInputManager::sendMotionEventsToFocused() { void CInputManager::sendMotionEventsToFocused() {
if (!g_pCompositor->m_lastFocus || isConstrained()) if (!Desktop::focusState()->surface() || isConstrained())
return; return;
// todo: this sucks ass // todo: this sucks ass
const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_lastFocus.lock()); const auto PWINDOW = g_pCompositor->getWindowFromSurface(Desktop::focusState()->surface());
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_lastFocus.lock()); 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{})); const auto LOCAL = getMouseCoordsInternal() - (PWINDOW ? PWINDOW->m_realPosition->goal() : (PLS ? Vector2D{PLS->m_geometry.x, PLS->m_geometry.y} : Vector2D{}));
m_emptyFocusCursorSet = false; 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) { 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; 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 // this can happen if there are no displays hooked up to Hyprland
if (PMONITOR == nullptr) if (PMONITOR == nullptr)
@ -239,7 +240,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
// constraints // constraints
if (!g_pSeatManager->m_mouse.expired() && isConstrained()) { 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; const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
if (CONSTRAINT) { 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())); 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()) if (PMONITOR != Desktop::focusState()->monitor() && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
g_pCompositor->setActiveMonitor(PMONITOR); Desktop::focusState()->rawMonitorFocus(PMONITOR);
// check for windows that have focus priority like our permission popups // check for windows that have focus priority like our permission popups
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, FOCUS_PRIORITY); 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 PSESSIONLOCKSURFACE = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->m_id);
const auto foundLockSurface = PSESSIONLOCKSURFACE ? PSESSIONLOCKSURFACE->surface->surface() : nullptr; 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 // 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) { 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, // if we are holding a pointer button,
// and we're not dnd-ing, don't refocus. Keep focus on last surface. // 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) { g_pSeatManager->m_state.pointerFocus && !m_hardInput) {
foundSurface = g_pSeatManager->m_state.pointerFocus.lock(); 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(); surfacePos = BOX->pos();
pFoundLayerSurface = HLSurface->getLayer(); pFoundLayerSurface = HLSurface->getLayer();
if (!pFoundLayerSurface) 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 } else // reset foundSurface, find one normally
foundSurface = nullptr; foundSurface = nullptr;
} else // reset foundSurface, find one normally } 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); 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) 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 // 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... // 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, {}); 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! if (refocus || !Desktop::focusState()->window()) // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
g_pCompositor->focusWindow(nullptr); Desktop::focusState()->rawWindowFocus(nullptr);
return; return;
} }
@ -514,8 +515,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
bool allowKeyboardRefocus = true; bool allowKeyboardRefocus = true;
if (!refocus && g_pCompositor->m_lastFocus) { if (!refocus && Desktop::focusState()->surface()) {
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_lastFocus.lock()); const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(Desktop::focusState()->surface());
if (PLS && PLS->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) if (PLS && PLS->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
allowKeyboardRefocus = false; allowKeyboardRefocus = false;
@ -556,19 +557,19 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
} }
if (FOLLOWMOUSE != 1 && !refocus) { if (FOLLOWMOUSE != 1 && !refocus) {
if (pFoundWindow != g_pCompositor->m_lastWindow.lock() && g_pCompositor->m_lastWindow.lock() && if (pFoundWindow != Desktop::focusState()->window() && Desktop::focusState()->window() &&
((pFoundWindow->m_isFloating && *PFLOATBEHAVIOR == 2) || (g_pCompositor->m_lastWindow->m_isFloating != pFoundWindow->m_isFloating && *PFLOATBEHAVIOR != 0))) { ((pFoundWindow->m_isFloating && *PFLOATBEHAVIOR == 2) || (Desktop::focusState()->window()->m_isFloating != pFoundWindow->m_isFloating && *PFLOATBEHAVIOR != 0))) {
// enter if change floating style // enter if change floating style
if (FOLLOWMOUSE != 3 && allowKeyboardRefocus) if (FOLLOWMOUSE != 3 && allowKeyboardRefocus)
g_pCompositor->focusWindow(pFoundWindow, foundSurface); Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal); g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
} else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3) } else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3)
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal); g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
if (pFoundWindow == g_pCompositor->m_lastWindow) if (pFoundWindow == Desktop::focusState()->window())
g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal); 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); g_pSeatManager->setPointerFocus(foundSurface, surfaceLocal);
if (g_pSeatManager->m_state.pointerFocus == foundSurface) 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 return; // don't enter any new surfaces
} else { } else {
if (allowKeyboardRefocus && ((FOLLOWMOUSE != 3 && (*PMOUSEREFOCUS || m_lastMouseFocus.lock() != pFoundWindow)) || refocus)) { 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; m_lastMouseFocus = pFoundWindow;
// TODO: this looks wrong. When over a popup, it constantly is switching. // 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. // 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) { if (m_mousePosDelta > *PFOLLOWMOUSETHRESHOLD || refocus) {
const bool hasNoFollowMouse = pFoundWindow && pFoundWindow->m_ruleApplicator->noFollowMouse().valueOrDefault(); const bool hasNoFollowMouse = pFoundWindow && pFoundWindow->m_ruleApplicator->noFollowMouse().valueOrDefault();
if (refocus || !hasNoFollowMouse) if (refocus || !hasNoFollowMouse)
g_pCompositor->focusWindow(pFoundWindow, foundSurface); Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
} }
} else } else
g_pCompositor->focusSurface(foundSurface, pFoundWindow); Desktop::focusState()->rawSurfaceFocus(foundSurface, pFoundWindow);
} }
} }
} }
if (g_pSeatManager->m_state.keyboardFocus == nullptr) if (g_pSeatManager->m_state.keyboardFocus == nullptr)
g_pCompositor->focusWindow(pFoundWindow, foundSurface); Desktop::focusState()->rawWindowFocus(pFoundWindow, foundSurface);
m_lastFocusOnLS = false; m_lastFocusOnLS = false;
} else { } 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 && 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)) { (allowKeyboardRefocus || pFoundLayerSurface->m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)) {
g_pCompositor->focusSurface(foundSurface); Desktop::focusState()->rawSurfaceFocus(foundSurface);
} }
if (pFoundLayerSurface) if (pFoundLayerSurface)
@ -762,7 +763,7 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
break; break;
if ((g_pSeatManager->m_mouse.expired() || !isConstrained()) /* No constraints */ 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 // a bit hacky
// if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus // if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus
if (m_currentlyHeldButtons.size() == 1) { if (m_currentlyHeldButtons.size() == 1) {
@ -791,8 +792,8 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
// notify app if we didn't handle it // notify app if we didn't handle it
g_pSeatManager->sendPointerButton(e.timeMs, e.button, e.state); g_pSeatManager->sendPointerButton(e.timeMs, e.button, e.state);
if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != g_pCompositor->m_lastMonitor && PMON) if (const auto PMON = g_pCompositor->getMonitorFromVector(mouseCoords); PMON != Desktop::focusState()->monitor() && PMON)
g_pCompositor->setActiveMonitor(PMON); Desktop::focusState()->rawMonitorFocus(PMON);
if (g_pSeatManager->m_seatGrab && e.state == WL_POINTER_BUTTON_STATE_PRESSED) { if (g_pSeatManager->m_seatGrab && e.state == WL_POINTER_BUTTON_STATE_PRESSED) {
m_hardInput = true; m_hardInput = true;
@ -1022,8 +1023,8 @@ void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
keeb->updateLEDs(); keeb->updateLEDs();
// in case m_lastFocus was set without a keyboard // in case m_lastFocus was set without a keyboard
if (m_keyboards.size() == 1 && g_pCompositor->m_lastFocus) if (m_keyboards.size() == 1 && Desktop::focusState()->surface())
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_lastFocus.lock()); g_pSeatManager->setKeyboardFocus(Desktop::focusState()->surface());
} }
void CInputManager::setKeyboardLayout() { void CInputManager::setKeyboardLayout() {
@ -1577,16 +1578,16 @@ bool CInputManager::refocusLastWindow(PHLMONITOR pMonitor) {
foundSurface = nullptr; 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 // then the last focused window if we're on the same workspace as it
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PLASTWINDOW = Desktop::focusState()->window();
g_pCompositor->focusWindow(PLASTWINDOW); Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
} else { } else {
// otherwise fall back to a normal refocus. // otherwise fall back to a normal refocus.
if (foundSurface && !foundSurface->m_hlSurface->keyboardFocusable()) { if (foundSurface && !foundSurface->m_hlSurface->keyboardFocusable()) {
const auto PLASTWINDOW = g_pCompositor->m_lastWindow.lock(); const auto PLASTWINDOW = Desktop::focusState()->window();
g_pCompositor->focusWindow(PLASTWINDOW); Desktop::focusState()->fullWindowFocus(PLASTWINDOW);
} }
refocus(); refocus();
@ -1615,7 +1616,7 @@ void CInputManager::unconstrainMouse() {
bool CInputManager::isConstrained() { bool CInputManager::isConstrained() {
return std::ranges::any_of(m_constraints, [](auto const& c) { return std::ranges::any_of(m_constraints, [](auto const& c) {
const auto constraint = c.lock(); 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()) if (!isConstrained())
return false; 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; const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
return CONSTRAINT && CONSTRAINT->isLocked(); return CONSTRAINT && CONSTRAINT->isLocked();

View file

@ -1,6 +1,5 @@
#include "InputMethodRelay.hpp" #include "InputMethodRelay.hpp"
#include "InputManager.hpp" #include "../../desktop/state/FocusState.hpp"
#include "../../Compositor.hpp"
#include "../../protocols/TextInputV3.hpp" #include "../../protocols/TextInputV3.hpp"
#include "../../protocols/TextInputV1.hpp" #include "../../protocols/TextInputV1.hpp"
#include "../../protocols/InputMethodV2.hpp" #include "../../protocols/InputMethodV2.hpp"
@ -54,17 +53,17 @@ void CInputMethodRelay::onNewIME(SP<CInputMethodV2> pIME) {
Debug::log(LOG, "New input popup"); Debug::log(LOG, "New input popup");
}); });
if (!g_pCompositor->m_lastFocus) if (!Desktop::focusState()->surface())
return; return;
for (auto const& ti : m_textInputs) { for (auto const& ti : m_textInputs) {
if (ti->client() != g_pCompositor->m_lastFocus->client()) if (ti->client() != Desktop::focusState()->surface()->client())
continue; continue;
if (ti->isV3()) if (ti->isV3())
ti->enter(g_pCompositor->m_lastFocus.lock()); ti->enter(Desktop::focusState()->surface());
else 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() { CTextInput* CInputMethodRelay::getFocusedTextInput() {
if (!g_pCompositor->m_lastFocus) if (!Desktop::focusState()->surface())
return nullptr; return nullptr;
for (auto const& ti : m_textInputs) { for (auto const& ti : m_textInputs) {
if (ti->focusedSurface() == g_pCompositor->m_lastFocus) if (ti->focusedSurface() == Desktop::focusState()->surface())
return ti.get(); return ti.get();
} }

View file

@ -1,8 +1,7 @@
#include "TextInput.hpp" #include "TextInput.hpp"
#include "../../defines.hpp"
#include "InputManager.hpp" #include "InputManager.hpp"
#include "../../protocols/TextInputV1.hpp" #include "../../protocols/TextInputV1.hpp"
#include "../../Compositor.hpp" #include "../../desktop/state/FocusState.hpp"
#include "../../protocols/TextInputV3.hpp" #include "../../protocols/TextInputV3.hpp"
#include "../../protocols/InputMethodV2.hpp" #include "../../protocols/InputMethodV2.hpp"
#include "../../protocols/core/Compositor.hpp" #include "../../protocols/core/Compositor.hpp"
@ -31,8 +30,8 @@ void CTextInput::initCallbacks() {
g_pInputManager->m_relay.deactivateIME(this); g_pInputManager->m_relay.deactivateIME(this);
}); });
if (!g_pCompositor->m_lastFocus.expired() && g_pCompositor->m_lastFocus->client() == INPUT->client()) if (Desktop::focusState()->surface() && Desktop::focusState()->surface()->client() == INPUT->client())
enter(g_pCompositor->m_lastFocus.lock()); enter(Desktop::focusState()->surface());
} else { } else {
const auto INPUT = m_v1Input.lock(); const auto INPUT = m_v1Input.lock();
@ -60,7 +59,7 @@ void CTextInput::onEnabled(SP<CWLSurfaceResource> surfV1) {
// v1 only, map surface to PTI // v1 only, map surface to PTI
if (!isV3()) { if (!isV3()) {
if (g_pCompositor->m_lastFocus != surfV1 || !m_v1Input->m_active) if (Desktop::focusState()->surface() != surfV1 || !m_v1Input->m_active)
return; return;
enter(surfV1); enter(surfV1);

View file

@ -3,11 +3,11 @@
#include "../../protocols/SessionLock.hpp" #include "../../protocols/SessionLock.hpp"
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../desktop/LayerSurface.hpp" #include "../../desktop/LayerSurface.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../config/ConfigValue.hpp" #include "../../config/ConfigValue.hpp"
#include "../../helpers/Monitor.hpp" #include "../../helpers/Monitor.hpp"
#include "../../devices/ITouch.hpp" #include "../../devices/ITouch.hpp"
#include "../SeatManager.hpp" #include "../SeatManager.hpp"
#include "managers/animation/AnimationManager.hpp"
#include "../HookSystemManager.hpp" #include "../HookSystemManager.hpp"
#include "debug/Log.hpp" #include "debug/Log.hpp"
#include "UnifiedWorkspaceSwipeGesture.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 : ""); 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); const auto TOUCH_COORDS = PMONITOR->m_position + (e.pos * PMONITOR->m_size);

View file

@ -1,6 +1,7 @@
#include "UnifiedWorkspaceSwipeGesture.hpp" #include "UnifiedWorkspaceSwipeGesture.hpp"
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "../../render/Renderer.hpp" #include "../../render/Renderer.hpp"
#include "InputManager.hpp" #include "InputManager.hpp"
@ -12,18 +13,18 @@ void CUnifiedWorkspaceSwipeGesture::begin() {
if (isGestureInProgress()) if (isGestureInProgress())
return; 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); Debug::log(LOG, "CUnifiedWorkspaceSwipeGesture::begin: Starting a swipe from {}", PWORKSPACE->m_name);
m_workspaceBegin = PWORKSPACE; m_workspaceBegin = PWORKSPACE;
m_delta = 0; m_delta = 0;
m_monitor = g_pCompositor->m_lastMonitor; m_monitor = Desktop::focusState()->monitor();
m_avgSpeed = 0; m_avgSpeed = 0;
m_speedPoints = 0; m_speedPoints = 0;
if (PWORKSPACE->m_hasFullscreenWindow) { 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; *ls->m_alpha = 1.f;
} }
} }
@ -307,7 +308,7 @@ void CUnifiedWorkspaceSwipeGesture::end() {
g_pInputManager->refocus(); g_pInputManager->refocus();
// apply alpha // 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; *ls->m_alpha = pSwitchedTo->m_hasFullscreenWindow && pSwitchedTo->m_fullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
} }
} }

View file

@ -7,6 +7,7 @@
#include "../../../../managers/eventLoop/EventLoopManager.hpp" #include "../../../../managers/eventLoop/EventLoopManager.hpp"
#include "../../../../managers/eventLoop/EventLoopTimer.hpp" #include "../../../../managers/eventLoop/EventLoopTimer.hpp"
#include "../../../../config/ConfigValue.hpp" #include "../../../../config/ConfigValue.hpp"
#include "../../../../desktop/state/FocusState.hpp"
constexpr const float MAX_DISTANCE = 200.F; 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) { void CCloseTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e); ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow; m_window = Desktop::focusState()->window();
if (!m_window) if (!m_window)
return; return;

View file

@ -1,8 +1,9 @@
#include "FloatGesture.hpp" #include "FloatGesture.hpp"
#include "../../../../Compositor.hpp"
#include "../../../../managers/LayoutManager.hpp" #include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp" #include "../../../../render/Renderer.hpp"
#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../desktop/Window.hpp"
constexpr const float MAX_DISTANCE = 250.F; 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) { void CFloatTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e); ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow; m_window = Desktop::focusState()->window();
if (!m_window) if (!m_window)
return; return;

View file

@ -1,6 +1,7 @@
#include "FullscreenGesture.hpp" #include "FullscreenGesture.hpp"
#include "../../../../Compositor.hpp" #include "../../../../Compositor.hpp"
#include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp" #include "../../../../render/Renderer.hpp"
#include "../../../animation/DesktopAnimationManager.hpp" #include "../../../animation/DesktopAnimationManager.hpp"
@ -29,7 +30,7 @@ CFullscreenTrackpadGesture::CFullscreenTrackpadGesture(const std::string_view& m
void CFullscreenTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) { void CFullscreenTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e); ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow; m_window = Desktop::focusState()->window();
if (!m_window) if (!m_window)
return; return;

View file

@ -1,13 +1,14 @@
#include "MoveGesture.hpp" #include "MoveGesture.hpp"
#include "../../../../Compositor.hpp" #include "../../../../desktop/state/FocusState.hpp"
#include "../../../../desktop/Window.hpp"
#include "../../../../managers/LayoutManager.hpp" #include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp" #include "../../../../render/Renderer.hpp"
void CMoveTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) { void CMoveTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e); ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow; m_window = Desktop::focusState()->window();
m_lastDelta = {}; m_lastDelta = {};
} }

View file

@ -1,13 +1,14 @@
#include "ResizeGesture.hpp" #include "ResizeGesture.hpp"
#include "../../../../Compositor.hpp" #include "../../../../desktop/state/FocusState.hpp"
#include "../../../../desktop/Window.hpp"
#include "../../../../managers/LayoutManager.hpp" #include "../../../../managers/LayoutManager.hpp"
#include "../../../../render/Renderer.hpp" #include "../../../../render/Renderer.hpp"
void CResizeTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) { void CResizeTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
ITrackpadGesture::begin(e); ITrackpadGesture::begin(e);
m_window = g_pCompositor->m_lastWindow; m_window = Desktop::focusState()->window();
} }
void CResizeTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) { void CResizeTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {

View file

@ -1,7 +1,7 @@
#include "SpecialWorkspaceGesture.hpp" #include "SpecialWorkspaceGesture.hpp"
#include "../../../../Compositor.hpp" #include "../../../../Compositor.hpp"
#include "../../../../managers/LayoutManager.hpp" #include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp" #include "../../../../render/Renderer.hpp"
#include <hyprutils/memory/Casts.hpp> #include <hyprutils/memory/Casts.hpp>
@ -36,7 +36,7 @@ void CSpecialWorkspaceGesture::begin(const ITrackpadGesture::STrackpadGestureBeg
if (m_specialWorkspace) { if (m_specialWorkspace) {
m_animatingOut = m_specialWorkspace->isVisible(); 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) if (!m_monitor)
return; return;
@ -44,7 +44,7 @@ void CSpecialWorkspaceGesture::begin(const ITrackpadGesture::STrackpadGestureBeg
if (!m_animatingOut) if (!m_animatingOut)
m_monitor->setSpecialWorkspace(m_specialWorkspace); m_monitor->setSpecialWorkspace(m_specialWorkspace);
} else { } else {
m_monitor = g_pCompositor->m_lastMonitor; m_monitor = Desktop::focusState()->monitor();
if (!m_monitor) if (!m_monitor)
return; return;

View file

@ -1,7 +1,7 @@
#include "WorkspaceSwipeGesture.hpp" #include "WorkspaceSwipeGesture.hpp"
#include "../../../../Compositor.hpp" #include "../../../../Compositor.hpp"
#include "../../../../managers/input/InputManager.hpp" #include "../../../../desktop/state/FocusState.hpp"
#include "../../../../render/Renderer.hpp" #include "../../../../render/Renderer.hpp"
#include "../../UnifiedWorkspaceSwipeGesture.hpp" #include "../../UnifiedWorkspaceSwipeGesture.hpp"
@ -16,7 +16,7 @@ void CWorkspaceSwipeGesture::begin(const ITrackpadGesture::STrackpadGestureBegin
int onMonitor = 0; int onMonitor = 0;
for (auto const& w : g_pCompositor->getWorkspaces()) { 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++; onMonitor++;
} }

View file

@ -3,6 +3,7 @@
#include <hyprland-focus-grab-v1.hpp> #include <hyprland-focus-grab-v1.hpp>
#include "../managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "../desktop/state/FocusState.hpp"
#include "core/Compositor.hpp" #include "core/Compositor.hpp"
#include <cstdint> #include <cstdint>
#include <wayland-server.h> #include <wayland-server.h>
@ -104,7 +105,7 @@ void CFocusGrab::refocusKeyboard() {
} }
if (surface) if (surface)
g_pCompositor->focusSurface(surface); Desktop::focusState()->rawSurfaceFocus(surface);
else else
LOGM(ERR, "CFocusGrab::refocusKeyboard called with no committed surfaces. This should never happen."); LOGM(ERR, "CFocusGrab::refocusKeyboard called with no committed surfaces. This should never happen.");
} }

View file

@ -1,9 +1,10 @@
#include "ForeignToplevelWlr.hpp" #include "ForeignToplevelWlr.hpp"
#include "core/Output.hpp"
#include <algorithm> #include <algorithm>
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
#include "protocols/core/Output.hpp" #include "../desktop/state/FocusState.hpp"
#include "render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../managers/HookSystemManager.hpp" #include "../managers/HookSystemManager.hpp"
#include "../managers/EventManager.hpp" #include "../managers/EventManager.hpp"
@ -50,7 +51,7 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHand
if (PWINDOW->m_workspace != monitor->m_activeWorkspace) { if (PWINDOW->m_workspace != monitor->m_activeWorkspace) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, 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 state;
wl_array_init(&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))); auto p = sc<uint32_t*>(wl_array_add(&state, sizeof(uint32_t)));
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED; *p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
} }
@ -216,7 +217,7 @@ CForeignToplevelWlrManager::CForeignToplevelWlrManager(SP<CZwlrForeignToplevelMa
onMap(w); onMap(w);
} }
m_lastFocus = g_pCompositor->m_lastWindow; m_lastFocus = Desktop::focusState()->window();
} }
void CForeignToplevelWlrManager::onMap(PHLWINDOW pWindow) { void CForeignToplevelWlrManager::onMap(PHLWINDOW pWindow) {

View file

@ -1,7 +1,8 @@
#include "InputMethodV2.hpp" #include "InputMethodV2.hpp"
#include "../Compositor.hpp" #include "../desktop/state/FocusState.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "../devices/IKeyboard.hpp" #include "../devices/IKeyboard.hpp"
#include "../helpers/MiscFunctions.hpp"
#include <sys/mman.h> #include <sys/mman.h>
#include "core/Compositor.hpp" #include "core/Compositor.hpp"
#include <cstring> #include <cstring>
@ -96,8 +97,8 @@ CInputMethodPopupV2::CInputMethodPopupV2(SP<CZwpInputPopupSurfaceV2> resource_,
m_listeners.destroySurface.reset(); m_listeners.destroySurface.reset();
m_listeners.commitSurface.reset(); m_listeners.commitSurface.reset();
if (g_pCompositor->m_lastFocus == m_surface) if (Desktop::focusState()->surface() == m_surface)
g_pCompositor->m_lastFocus.reset(); Desktop::focusState()->surface().reset();
m_surface.reset(); m_surface.reset();
}); });

View file

@ -1,6 +1,7 @@
#include "PointerConstraints.hpp" #include "PointerConstraints.hpp"
#include "../desktop/WLSurface.hpp" #include "../desktop/WLSurface.hpp"
#include "../Compositor.hpp" #include "../desktop/state/FocusState.hpp"
#include "../desktop/Window.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "core/Compositor.hpp" #include "core/Compositor.hpp"
@ -242,7 +243,7 @@ void CPointerConstraintsProtocol::onNewConstraint(SP<CPointerConstraint> constra
g_pInputManager->m_constraints.emplace_back(constraint); g_pInputManager->m_constraints.emplace_back(constraint);
if (g_pCompositor->m_lastFocus == OWNER->resource()) if (Desktop::focusState()->surface() == OWNER->resource())
constraint->activate(); constraint->activate();
} }

View file

@ -1,5 +1,4 @@
#include "SessionLock.hpp" #include "SessionLock.hpp"
#include "../Compositor.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "FractionalScale.hpp" #include "FractionalScale.hpp"
#include "LockNotify.hpp" #include "LockNotify.hpp"
@ -7,6 +6,7 @@
#include "core/Output.hpp" #include "core/Output.hpp"
#include "../helpers/Monitor.hpp" #include "../helpers/Monitor.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../desktop/state/FocusState.hpp"
CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_, SP<CWLSurfaceResource> surface_, PHLMONITOR pMonitor_, WP<CSessionLock> owner_) : 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_) { 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_surface->unmap();
m_listeners.surfaceCommit.reset(); m_listeners.surfaceCommit.reset();
m_listeners.surfaceDestroy.reset(); m_listeners.surfaceDestroy.reset();
if (g_pCompositor->m_lastFocus == m_surface) if (Desktop::focusState()->surface() == m_surface)
g_pCompositor->m_lastFocus.reset(); Desktop::focusState()->surface().reset();
m_surface.reset(); m_surface.reset();
}); });

View file

@ -1,6 +1,7 @@
#include "ShortcutsInhibit.hpp" #include "ShortcutsInhibit.hpp"
#include <algorithm> #include <algorithm>
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
#include "core/Compositor.hpp" #include "core/Compositor.hpp"
CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, SP<CWLSurfaceResource> surf) : m_resource(resource_), m_surface(surf) { 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() { bool CKeyboardShortcutsInhibitProtocol::isInhibited() {
if (!g_pCompositor->m_lastFocus) if (!Desktop::focusState()->surface())
return false; 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; return false;
for (auto const& in : m_inhibitors) { for (auto const& in : m_inhibitors) {
if (in->surface() != g_pCompositor->m_lastFocus) if (in->surface() != Desktop::focusState()->surface())
continue; continue;
return true; return true;

View file

@ -14,6 +14,7 @@
#include "../config/ConfigManager.hpp" #include "../config/ConfigManager.hpp"
#include "../managers/PointerManager.hpp" #include "../managers/PointerManager.hpp"
#include "../desktop/LayerSurface.hpp" #include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
#include "../protocols/core/Compositor.hpp" #include "../protocols/core/Compositor.hpp"
#include "../protocols/ColorManagement.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 : ""); 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); const auto TOUCH_COORDS = PMONITOR->m_position + (E.pos * PMONITOR->m_size);

View file

@ -14,6 +14,7 @@
#include "../managers/LayoutManager.hpp" #include "../managers/LayoutManager.hpp"
#include "../desktop/Window.hpp" #include "../desktop/Window.hpp"
#include "../desktop/LayerSurface.hpp" #include "../desktop/LayerSurface.hpp"
#include "../desktop/state/FocusState.hpp"
#include "../protocols/SessionLock.hpp" #include "../protocols/SessionLock.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
#include "../protocols/XDGShell.hpp" #include "../protocols/XDGShell.hpp"
@ -168,7 +169,7 @@ CHyprRenderer::CHyprRenderer() {
w->m_wlSurface->resource()->frame(Time::steadyNow()); w->m_wlSurface->resource()->frame(Time::steadyNow());
auto FEEDBACK = makeUnique<CQueuedPresentationData>(w->m_wlSurface->resource()); auto FEEDBACK = makeUnique<CQueuedPresentationData>(w->m_wlSurface->resource());
FEEDBACK->attachMonitor(g_pCompositor->m_lastMonitor.lock()); FEEDBACK->attachMonitor(Desktop::focusState()->monitor());
FEEDBACK->discarded(); FEEDBACK->discarded();
PROTO::presentation->queueData(std::move(FEEDBACK)); PROTO::presentation->queueData(std::move(FEEDBACK));
} }
@ -403,7 +404,7 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo
continue; continue;
// render active window after all others of this pass // render active window after all others of this pass
if (w == g_pCompositor->m_lastWindow) { if (w == Desktop::focusState()->window()) {
lastWindow = w.lock(); lastWindow = w.lock();
continue; continue;
} }
@ -1407,7 +1408,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
renderLockscreen(pMonitor, NOW, renderBox); renderLockscreen(pMonitor, NOW, renderBox);
if (pMonitor == g_pCompositor->m_lastMonitor) { if (pMonitor == Desktop::focusState()->monitor()) {
g_pHyprNotificationOverlay->draw(pMonitor); g_pHyprNotificationOverlay->draw(pMonitor);
g_pHyprError->draw(); 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}; 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(); const auto HEIGHT = g_pHyprError->height();
if (*BAR_POSITION == 0) { if (*BAR_POSITION == 0) {
PMONITOR->m_reservedTopLeft.y = HEIGHT; PMONITOR->m_reservedTopLeft.y = HEIGHT;

View file

@ -1,6 +1,7 @@
#include "CHyprGroupBarDecoration.hpp" #include "CHyprGroupBarDecoration.hpp"
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp" #include "../../config/ConfigValue.hpp"
#include "../../desktop/state/FocusState.hpp"
#include "managers/LayoutManager.hpp" #include "managers/LayoutManager.hpp"
#include <ranges> #include <ranges>
#include <pango/pangocairo.h> #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 PCOLACTIVE = GROUPLOCKED ? GROUPCOLACTIVELOCKED : GROUPCOLACTIVE;
const auto* const PCOLINACTIVE = GROUPLOCKED ? GROUPCOLINACTIVELOCKED : GROUPCOLINACTIVE; 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; color.a *= a;
if (!rect.empty()) { if (!rect.empty()) {
@ -195,7 +196,7 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
if (!rect.empty()) { if (!rect.empty()) {
if (*PGRADIENTS) { if (*PGRADIENTS) {
const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_lastWindow ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) : const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == Desktop::focusState()->window() ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) :
(GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive)); (GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive));
if (GRADIENTTEX->m_texID) { if (GRADIENTTEX->m_texID) {
CTexPassElement::SRenderData data; CTexPassElement::SRenderData data;
@ -234,7 +235,7 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) {
.get(); .get();
SP<CTexture> titleTex; 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; titleTex = GROUPLOCKED ? pTitleTex->m_texLockedActive : pTitleTex->m_texActive;
else else
titleTex = GROUPLOCKED ? pTitleTex->m_texLockedInactive : pTitleTex->m_texInactive; 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) { static void renderGradientTo(SP<CTexture> tex, CGradientValueData* grad) {
if (!g_pCompositor->m_lastMonitor) if (!Desktop::focusState()->monitor())
return; 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 CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
const auto CAIRO = cairo_create(CAIROSURFACE); const auto CAIRO = cairo_create(CAIROSURFACE);
@ -415,7 +416,7 @@ bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
g_pInputManager->m_currentlyDraggedWindow = pWindow; g_pInputManager->m_currentlyDraggedWindow = pWindow;
if (!g_pCompositor->isWindowActive(pWindow)) if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow); Desktop::focusState()->rawWindowFocus(pWindow);
return true; return true;
} }
@ -529,7 +530,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
const auto STACKPAD = *PSTACKED && (BARRELATIVEY - (m_barHeight + *POUTERGAP) * WINDOWINDEX < *POUTERGAP); const auto STACKPAD = *PSTACKED && (BARRELATIVEY - (m_barHeight + *POUTERGAP) * WINDOWINDEX < *POUTERGAP);
if (TABPAD || STACKPAD) { if (TABPAD || STACKPAD) {
if (!g_pCompositor->isWindowActive(m_window.lock())) if (!g_pCompositor->isWindowActive(m_window.lock()))
g_pCompositor->focusWindow(m_window.lock()); Desktop::focusState()->rawWindowFocus(m_window.lock());
return true; return true;
} }
@ -539,7 +540,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo
pWindow->setGroupCurrent(pWindow); pWindow->setGroupCurrent(pWindow);
if (!g_pCompositor->isWindowActive(pWindow) && *PFOLLOWMOUSE != 3) if (!g_pCompositor->isWindowActive(pWindow) && *PFOLLOWMOUSE != 3)
g_pCompositor->focusWindow(pWindow); Desktop::focusState()->rawWindowFocus(pWindow);
if (pWindow->m_isFloating) if (pWindow->m_isFloating)
g_pCompositor->changeWindowZOrder(pWindow, true); g_pCompositor->changeWindowZOrder(pWindow, true);

View file

@ -2,12 +2,13 @@
#include "../OpenGL.hpp" #include "../OpenGL.hpp"
#include <algorithm> #include <algorithm>
#include <ranges> #include <ranges>
#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp" #include "../../config/ConfigValue.hpp"
#include "../../desktop/WLSurface.hpp" #include "../../desktop/WLSurface.hpp"
#include "../../managers/SeatManager.hpp" #include "../../managers/SeatManager.hpp"
#include "../../managers/eventLoop/EventLoopManager.hpp" #include "../../managers/eventLoop/EventLoopManager.hpp"
#include "../../render/Renderer.hpp" #include "../../render/Renderer.hpp"
#include "../../Compositor.hpp" #include "../../desktop/state/FocusState.hpp"
#include "../../protocols/core/Compositor.hpp" #include "../../protocols/core/Compositor.hpp"
bool CRenderPass::empty() const { 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.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)); renderHLSurface(m_debugData.pointerFocusText, g_pSeatManager->m_state.pointerFocus.lock(), Colors::ORANGE.modifyA(0.1F));
if (g_pCompositor->m_lastWindow) if (Desktop::focusState()->window())
renderHLSurface(m_debugData.lastWindowText, g_pCompositor->m_lastWindow->m_wlSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F)); 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) {
if (g_pSeatManager->m_state.pointerFocus->m_current.input.intersect(CBox{{}, g_pSeatManager->m_state.pointerFocus->m_current.size}).getExtents().size() != if (g_pSeatManager->m_state.pointerFocus->m_current.input.intersect(CBox{{}, g_pSeatManager->m_state.pointerFocus->m_current.size}).getExtents().size() !=

View file

@ -20,6 +20,7 @@
#include "../managers/ANRManager.hpp" #include "../managers/ANRManager.hpp"
#include "../protocols/XWaylandShell.hpp" #include "../protocols/XWaylandShell.hpp"
#include "../protocols/core/Compositor.hpp" #include "../protocols/core/Compositor.hpp"
#include "../desktop/state/FocusState.hpp"
using Hyprutils::Memory::CUniquePointer; using Hyprutils::Memory::CUniquePointer;
using namespace Hyprutils::OS; 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)) if ((surf == m_focusedSurface && activate) || (surf && surf->m_overrideRedirect))
return; 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); setActiveWindow(XCB_WINDOW_NONE);
focusWindow(nullptr); focusWindow(nullptr);
} else { } else {