diff options
| author | Alvaro Parker <64918109+AlvaroParker@users.noreply.github.com> | 2025-11-05 21:06:31 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-06 00:06:31 +0000 |
| commit | c757fd375cce299e3da922190ddf1a0622ce807c (patch) | |
| tree | f1908b8ca0e2c0ff29f3afb03862a7c5d2f1a26f /src/Compositor.cpp | |
| parent | 46b71eda6423cc9c3b19cb310c3344e81ac624c5 (diff) | |
compositor: block parent window interaction when modal dialog children window is open (#12057)
Diffstat (limited to 'src/Compositor.cpp')
| -rw-r--r-- | src/Compositor.cpp | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 3c7ad6a2..3d0b5173 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -881,13 +881,18 @@ bool CCompositor::monitorExists(PHLMONITOR pMonitor) { } PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t properties, PHLWINDOW pIgnoreWindow) { - const auto PMONITOR = getMonitorFromVector(pos); - static auto PRESIZEONBORDER = CConfigValue<Hyprlang::INT>("general:resize_on_border"); - static auto PBORDERSIZE = CConfigValue<Hyprlang::INT>("general:border_size"); - static auto PBORDERGRABEXTEND = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area"); - static auto PSPECIALFALLTHRU = CConfigValue<Hyprlang::INT>("input:special_fallthrough"); - const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0; - const bool ONLY_PRIORITY = properties & FOCUS_PRIORITY; + const auto PMONITOR = getMonitorFromVector(pos); + static auto PRESIZEONBORDER = CConfigValue<Hyprlang::INT>("general:resize_on_border"); + static auto PBORDERSIZE = CConfigValue<Hyprlang::INT>("general:border_size"); + static auto PBORDERGRABEXTEND = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area"); + static auto PSPECIALFALLTHRU = CConfigValue<Hyprlang::INT>("input:special_fallthrough"); + static auto PMODALPARENTBLOCKING = CConfigValue<Hyprlang::INT>("general:modal_parent_blocking"); + const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0; + const bool ONLY_PRIORITY = properties & FOCUS_PRIORITY; + + const auto isShadowedByModal = [](PHLWINDOW w) -> bool { + return *PMODALPARENTBLOCKING && w->m_xdgSurface && w->m_xdgSurface->m_toplevel && w->m_xdgSurface->m_toplevel->anyChildModal(); + }; // pinned windows on top of floating regardless if (properties & ALLOW_FLOATING) { @@ -895,7 +900,8 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper if (ONLY_PRIORITY && !w->priorityFocus()) continue; - if (w->m_isFloating && w->m_isMapped && !w->isHidden() && !w->m_X11ShouldntFocus && w->m_pinned && !w->m_windowData.noFocus.valueOrDefault() && w != pIgnoreWindow) { + if (w->m_isFloating && w->m_isMapped && !w->isHidden() && !w->m_X11ShouldntFocus && w->m_pinned && !w->m_windowData.noFocus.valueOrDefault() && w != pIgnoreWindow && + !isShadowedByModal(w)) { const auto BB = w->getWindowBoxUnified(properties); CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0); if (box.containsPoint(g_pPointerManager->position())) @@ -933,7 +939,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper } if (w->m_isFloating && w->m_isMapped && w->m_workspace->isVisible() && !w->isHidden() && !w->m_pinned && !w->m_windowData.noFocus.valueOrDefault() && - w != pIgnoreWindow && (!aboveFullscreen || w->m_createdOverFullscreen)) { + w != pIgnoreWindow && (!aboveFullscreen || w->m_createdOverFullscreen) && !isShadowedByModal(w)) { // OR windows should add focus to parent if (w->m_X11ShouldntFocus && !w->isX11OverrideRedirect()) continue; @@ -993,7 +999,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper continue; if (!w->m_isX11 && !w->m_isFloating && w->m_isMapped && w->workspaceID() == WSPID && !w->isHidden() && !w->m_X11ShouldntFocus && - !w->m_windowData.noFocus.valueOrDefault() && w != pIgnoreWindow) { + !w->m_windowData.noFocus.valueOrDefault() && w != pIgnoreWindow && !isShadowedByModal(w)) { if (w->hasPopupAt(pos)) return w; } @@ -1010,7 +1016,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper continue; if (!w->m_isFloating && w->m_isMapped && w->workspaceID() == WSPID && !w->isHidden() && !w->m_X11ShouldntFocus && !w->m_windowData.noFocus.valueOrDefault() && - w != pIgnoreWindow) { + w != pIgnoreWindow && !isShadowedByModal(w)) { CBox box = (properties & USE_PROP_TILED) ? w->getWindowBoxUnified(properties) : CBox{w->m_position, w->m_size}; if (box.containsPoint(pos)) return w; @@ -1110,8 +1116,14 @@ PHLMONITOR CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) { 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 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()) { |
