diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 0c65b67f..1c6b6561 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -710,7 +710,8 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert for (auto& w : m_vWindows | std::views::reverse) { const auto BB = w->getWindowBoxUnified(properties); CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; - if (w->m_bIsFloating && w->m_bIsMapped && !w->isHidden() && !w->m_bX11ShouldntFocus && w->m_bPinned && !w->m_bNoFocus && w.get() != pIgnoreWindow) { + if (w->m_bIsFloating && w->m_bIsMapped && !w->isHidden() && !w->m_bX11ShouldntFocus && w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && + w.get() != pIgnoreWindow) { if (box.containsPoint({m_sWLRCursor->x, m_sWLRCursor->y})) return w.get(); @@ -732,7 +733,8 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert const auto BB = w->getWindowBoxUnified(properties); CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; - if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_iWorkspaceID) && !w->isHidden() && !w->m_bPinned && !w->m_bNoFocus && w.get() != pIgnoreWindow) { + if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_iWorkspaceID) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && + w.get() != pIgnoreWindow) { // OR windows should add focus to parent if (w->m_bX11ShouldntFocus && w->m_iX11Type != 2) continue; @@ -770,8 +772,8 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert if (special != isWorkspaceSpecial(w->m_iWorkspaceID)) continue; - if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && !w->m_bNoFocus && - w.get() != pIgnoreWindow) { + if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && + !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow) { if (w->hasPopupAt(pos)) return w.get(); } @@ -782,8 +784,8 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert continue; CBox box = (properties & USE_PROP_TILED) ? w->getWindowBoxUnified(properties) : CBox{w->m_vPosition, w->m_vSize}; - if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && !w->m_bNoFocus && - w.get() != pIgnoreWindow) + if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->m_iWorkspaceID == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && + !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow) return w.get(); } @@ -928,7 +930,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { return; } - if (pWindow->m_bNoFocus) { + if (pWindow->m_sAdditionalConfigData.noFocus) { Debug::log(LOG, "Ignoring focus to nofocus window!"); return; } @@ -1646,7 +1648,7 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus)) + if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1654,7 +1656,7 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus)) + if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1675,7 +1677,7 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus)) + if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } @@ -1683,7 +1685,7 @@ CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow, bool focusableO if (floating.has_value() && w->m_bIsFloating != floating.value()) continue; - if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_bNoFocus)) + if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sAdditionalConfigData.noFocus)) return w.get(); } diff --git a/src/Window.hpp b/src/Window.hpp index b0689b61..d4a34c8d 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -143,6 +143,7 @@ struct SWindowAdditionalConfigData { CWindowOverridableVar forceNoBorder = false; CWindowOverridableVar forceNoShadow = false; CWindowOverridableVar forceNoDim = false; + CWindowOverridableVar noFocus = false; CWindowOverridableVar windowDanceCompat = false; CWindowOverridableVar noMaxSize = false; CWindowOverridableVar dimAround = false; @@ -260,7 +261,6 @@ class CWindow { // // For nofocus - bool m_bNoFocus = false; bool m_bNoInitialFocus = false; // Fullscreen and Maximize diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index de2aaeb8..08957750 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1084,7 +1084,8 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { if (vars.size() < 4) return "not enough args"; - const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[1]); + const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; + const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[1]); if (!PWINDOW) return "window not found"; @@ -1092,6 +1093,8 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { const auto PROP = vars[2]; const auto VAL = vars[3]; + auto noFocus = PWINDOW->m_sAdditionalConfigData.noFocus; + bool lock = false; if (vars.size() > 4) { @@ -1121,6 +1124,8 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { PWINDOW->m_sAdditionalConfigData.forceNoShadow.forceSetIgnoreLocked(configStringToInt(VAL), lock); } else if (PROP == "forcenodim") { PWINDOW->m_sAdditionalConfigData.forceNoDim.forceSetIgnoreLocked(configStringToInt(VAL), lock); + } else if (PROP == "nofocus") { + PWINDOW->m_sAdditionalConfigData.noFocus.forceSetIgnoreLocked(configStringToInt(VAL), lock); } else if (PROP == "windowdancecompat") { PWINDOW->m_sAdditionalConfigData.windowDanceCompat.forceSetIgnoreLocked(configStringToInt(VAL), lock); } else if (PROP == "nomaxsize") { @@ -1156,6 +1161,12 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { g_pCompositor->updateAllWindowsAnimatedDecorationValues(); + if (!(PWINDOW->m_sAdditionalConfigData.noFocus.toUnderlying() == noFocus.toUnderlying())) { + g_pCompositor->focusWindow(nullptr); + g_pCompositor->focusWindow(PWINDOW); + g_pCompositor->focusWindow(PLASTWINDOW); + } + for (auto& m : g_pCompositor->m_vMonitors) g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index cf5d0ab5..2df99284 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -173,7 +173,7 @@ void Events::listener_mapWindow(void* owner, void* data) { } else if (r.szRule.starts_with("pseudo")) { PWINDOW->m_bIsPseudotiled = true; } else if (r.szRule.starts_with("nofocus")) { - PWINDOW->m_bNoFocus = true; + PWINDOW->m_sAdditionalConfigData.noFocus = true; } else if (r.szRule.starts_with("noinitialfocus")) { PWINDOW->m_bNoInitialFocus = true; } else if (r.szRule.starts_with("nofullscreenrequest")) { @@ -443,9 +443,9 @@ void Events::listener_mapWindow(void* owner, void* data) { const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_pLastWindow; if (PWINDOW->m_sAdditionalConfigData.forceAllowsInput) { - PWINDOW->m_bNoFocus = false; - PWINDOW->m_bNoInitialFocus = false; - PWINDOW->m_bX11ShouldntFocus = false; + PWINDOW->m_sAdditionalConfigData.noFocus = false; + PWINDOW->m_bNoInitialFocus = false; + PWINDOW->m_bX11ShouldntFocus = false; } // check LS focus grab @@ -464,7 +464,7 @@ void Events::listener_mapWindow(void* owner, void* data) { requestsFullscreen = true; } - if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && + if (!PWINDOW->m_sAdditionalConfigData.noFocus && !PWINDOW->m_bNoInitialFocus && (PWINDOW->m_iX11Type != 2 || (PWINDOW->m_bIsX11 && wlr_xwayland_or_surface_wants_focus(PWINDOW->m_uSurface.xwayland))) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW)) { g_pCompositor->focusWindow(PWINDOW); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index cf3cf405..ee692178 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -530,7 +530,7 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { // find whether there is a floating window below this one for (auto& w : g_pCompositor->m_vWindows) { if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && !w->m_bX11ShouldntFocus && - !w->m_bNoFocus && w.get() != pWindow) { + !w->m_sAdditionalConfigData.noFocus && w.get() != pWindow) { if (VECINRECT((pWindow->m_vSize / 2.f + pWindow->m_vPosition), w->m_vPosition.x, w->m_vPosition.y, w->m_vPosition.x + w->m_vSize.x, w->m_vPosition.y + w->m_vSize.y)) { return w.get(); @@ -550,7 +550,7 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { // if not, floating window for (auto& w : g_pCompositor->m_vWindows) { if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && !w->m_bX11ShouldntFocus && - !w->m_bNoFocus && w.get() != pWindow) + !w->m_sAdditionalConfigData.noFocus && w.get() != pWindow) return w.get(); }