From 347b83903474ab9e95fa9d4ba123f6f78ab38d40 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 10:09:42 +0100 Subject: [PATCH] workspaces: add visible flag --- src/Compositor.cpp | 26 +++++------- src/Compositor.hpp | 2 +- src/desktop/Popup.cpp | 10 +++++ src/desktop/Subsurface.cpp | 2 +- src/desktop/Workspace.cpp | 7 ---- src/desktop/Workspace.hpp | 3 ++ src/events/Layers.cpp | 2 +- src/events/Windows.cpp | 59 ++++++++++++++-------------- src/helpers/Monitor.cpp | 15 +++++-- src/managers/AnimationManager.cpp | 2 +- src/managers/input/IdleInhibitor.cpp | 2 +- src/render/Renderer.cpp | 8 ++-- 12 files changed, 72 insertions(+), 66 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 001d7ca8..3b7b5d9b 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -764,7 +764,7 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert continue; 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->workspaceID()) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && + if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_pWorkspace) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && w.get() != pIgnoreWindow && (!aboveFullscreen || w->m_bCreatedOverFullscreen)) { // OR windows should add focus to parent if (w->m_bX11ShouldntFocus && w->m_iX11Type != 2) @@ -1001,7 +1001,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID); - if (!isWorkspaceVisible(pWindow->workspaceID())) { + if (!isWorkspaceVisible(pWindow->m_pWorkspace)) { const auto PWORKSPACE = pWindow->m_pWorkspace; // This is to fix incorrect feedback on the focus history. PWORKSPACE->m_pLastFocusedWindow = pWindow; @@ -1240,16 +1240,8 @@ CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) { return nullptr; } -bool CCompositor::isWorkspaceVisible(const int& w) { - for (auto& m : m_vMonitors) { - if (m->activeWorkspaceID() == w) - return true; - - if (m->activeSpecialWorkspaceID() == w) - return true; - } - - return false; +bool CCompositor::isWorkspaceVisible(PHLWORKSPACE w) { + return w->m_bVisible; } PHLWORKSPACE CCompositor::getWorkspaceByID(const int& id) { @@ -1280,7 +1272,7 @@ void CCompositor::sanityCheckWorkspaces() { const auto WINDOWSONWORKSPACE = getWindowsOnWorkspace(WORKSPACE->m_iID); if (WINDOWSONWORKSPACE == 0) { - if (!isWorkspaceVisible(WORKSPACE->m_iID)) { + if (!isWorkspaceVisible(WORKSPACE)) { if (WORKSPACE->m_bIsSpecialWorkspace) { if (WORKSPACE->m_fAlpha.value() > 0.f /* don't abruptly end the fadeout */) { @@ -1584,7 +1576,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { // for tiled windows, we calc edges for (auto& w : m_vWindows) { - if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && w->m_bIsFloating) || !isWorkspaceVisible(w->workspaceID())) + if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && w->m_bIsFloating) || !isWorkspaceVisible(w->m_pWorkspace)) continue; if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace) @@ -1673,7 +1665,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) { constexpr float THRESHOLD = 0.3 * M_PI; for (auto& w : m_vWindows) { - if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && !w->m_bIsFloating) || !isWorkspaceVisible(w->workspaceID())) + if (w.get() == pWindow || !w->m_bIsMapped || w->isHidden() || (!w->m_bIsFullscreen && !w->m_bIsFloating) || !isWorkspaceVisible(w->m_pWorkspace)) continue; if (pWindow->m_iMonitorID == w->m_iMonitorID && pWindow->m_pWorkspace != w->m_pWorkspace) @@ -2737,7 +2729,7 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, PHLWORKSPACE pWork CWindow* CCompositor::getForceFocus() { for (auto& w : m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || !isWorkspaceVisible(w->workspaceID())) + if (!w->m_bIsMapped || w->isHidden() || !isWorkspaceVisible(w->m_pWorkspace)) continue; if (!w->m_bStayFocused) @@ -2886,6 +2878,6 @@ void CCompositor::updateSuspendedStates() { if (!w->m_bIsMapped) continue; - w->setSuspended(w->isHidden() || !isWorkspaceVisible(w->workspaceID())); + w->setSuspended(w->isHidden() || !isWorkspaceVisible(w->m_pWorkspace)); } } diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 98bbe899..4604f687 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -144,7 +144,7 @@ class CCompositor { CWindow* getWindowFromSurface(wlr_surface*); CWindow* getWindowFromHandle(uint32_t); CWindow* getWindowFromZWLRHandle(wl_resource*); - bool isWorkspaceVisible(const int&); + bool isWorkspaceVisible(PHLWORKSPACE); PHLWORKSPACE getWorkspaceByID(const int&); PHLWORKSPACE getWorkspaceByName(const std::string&); PHLWORKSPACE getWorkspaceByString(const std::string&); diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 77e486fd..a32b28d6 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -1,4 +1,5 @@ #include "Popup.hpp" +#include "../config/ConfigValue.hpp" #include "../Compositor.hpp" CPopup::CPopup(CWindow* pOwner) : m_pWindowOwner(pOwner) { @@ -145,6 +146,15 @@ void CPopup::onCommit(bool ignoreSiblings) { return; } + if (m_pWindowOwner && (!m_pWindowOwner->m_bIsMapped || !m_pWindowOwner->m_pWorkspace->m_bVisible)) { + m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height}; + + static auto PLOGDAMAGE = CConfigValue("debug:log_damage"); + if (*PLOGDAMAGE) + Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowOwner); + return; + } + const auto COORDS = coordsGlobal(); const auto COORDSLOCAL = coordsRelativeToParent(); diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index c3538ee1..e337c798 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -117,7 +117,7 @@ void CSubsurface::recheckDamageForSubsurfaces() { void CSubsurface::onCommit() { // no damaging if it's not visible - if (m_pWindowParent && !g_pHyprRenderer->shouldRenderWindow(m_pWindowParent)) { + if (m_pWindowParent && (!m_pWindowParent->m_bIsMapped || !m_pWindowParent->m_pWorkspace->m_bVisible)) { m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}; static auto PLOGDAMAGE = CConfigValue("debug:log_damage"); diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 8e49c998..1df18c3b 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -9,13 +9,6 @@ PHLWORKSPACE CWorkspace::create(int id, int monitorID, std::string name, bool sp } CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) { - const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID); - - if (!PMONITOR) { - Debug::log(ERR, "Attempted a creation of CWorkspace with an invalid monitor?"); - return; - } - m_iMonitorID = monitorID; m_iID = id; m_szName = name; diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index 1630baf5..deb108ec 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -42,6 +42,9 @@ class CWorkspace { CAnimatedVariable m_fAlpha; bool m_bForceRendering = false; + // allows damage to propagate. + bool m_bVisible = false; + // "scratchpad" bool m_bIsSpecialWorkspace = false; diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index bd27004b..ab002ef6 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -237,7 +237,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) { foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface); - if (!foundSurface && g_pCompositor->m_pLastWindow && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->workspaceID())) { + if (!foundSurface && g_pCompositor->m_pLastWindow && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_pWorkspace)) { // if there isn't any, focus the last window const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; g_pCompositor->focusWindow(nullptr); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index eb876cf2..b1db5286 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -800,6 +800,35 @@ void Events::listener_commitWindow(void* owner, void* data) { PWINDOW->m_pPendingSizeAck.reset(); } + if (!PWINDOW->m_bIsX11 && !PWINDOW->m_bIsFullscreen && PWINDOW->m_bIsFloating) { + const auto MINSIZE = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->current.min_width, PWINDOW->m_uSurface.xdg->toplevel->current.min_height}; + const auto MAXSIZE = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->current.max_width, PWINDOW->m_uSurface.xdg->toplevel->current.max_height}; + + if (MAXSIZE > Vector2D{1, 1}) { + const auto REALSIZE = PWINDOW->m_vRealSize.goal(); + Vector2D newSize = REALSIZE; + + if (MAXSIZE.x < newSize.x) + newSize.x = MAXSIZE.x; + if (MAXSIZE.y < newSize.y) + newSize.y = MAXSIZE.y; + if (MINSIZE.x > newSize.x) + newSize.x = MINSIZE.x; + if (MINSIZE.y > newSize.y) + newSize.y = MINSIZE.y; + + const Vector2D DELTA = REALSIZE - newSize; + + PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + DELTA / 2.0; + PWINDOW->m_vRealSize = newSize; + g_pXWaylandManager->setWindowSize(PWINDOW, newSize, true); + g_pHyprRenderer->damageWindow(PWINDOW); + } + } + + if (!PWINDOW->m_pWorkspace->m_bVisible) + return; + g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface.wlr(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y, PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0); @@ -823,34 +852,6 @@ void Events::listener_commitWindow(void* owner, void* data) { } } } - - if (PWINDOW->m_bIsX11 || !PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen) - return; - - const auto MINSIZE = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->current.min_width, PWINDOW->m_uSurface.xdg->toplevel->current.min_height}; - const auto MAXSIZE = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->current.max_width, PWINDOW->m_uSurface.xdg->toplevel->current.max_height}; - - if (MAXSIZE < Vector2D{1, 1}) - return; - - const auto REALSIZE = PWINDOW->m_vRealSize.goal(); - Vector2D newSize = REALSIZE; - - if (MAXSIZE.x < newSize.x) - newSize.x = MAXSIZE.x; - if (MAXSIZE.y < newSize.y) - newSize.y = MAXSIZE.y; - if (MINSIZE.x > newSize.x) - newSize.x = MINSIZE.x; - if (MINSIZE.y > newSize.y) - newSize.y = MINSIZE.y; - - const Vector2D DELTA = REALSIZE - newSize; - - PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + DELTA / 2.0; - PWINDOW->m_vRealSize = newSize; - g_pXWaylandManager->setWindowSize(PWINDOW, newSize, true); - g_pHyprRenderer->damageWindow(PWINDOW); } void Events::listener_destroyWindow(void* owner, void* data) { @@ -1094,7 +1095,7 @@ void Events::listener_configureX11(void* owner, void* data) { PWINDOW->updateWindowDecos(); - if (!g_pCompositor->isWorkspaceVisible(PWINDOW->workspaceID())) + if (!g_pCompositor->isWorkspaceVisible(PWINDOW->m_pWorkspace)) return; // further things are only for visible windows PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 4018cc8b..152356e4 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -416,6 +416,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { activeWorkspace = PNEWWORKSPACE; PNEWWORKSPACE->setActive(true); + PNEWWORKSPACE->m_bVisible = true; PNEWWORKSPACE->m_szLastMonitor = ""; } @@ -547,7 +548,9 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo if (pWorkspace == activeWorkspace) return; - const auto POLDWORKSPACE = activeWorkspace; + const auto POLDWORKSPACE = activeWorkspace; + POLDWORKSPACE->m_bVisible = false; + pWorkspace->m_bVisible = true; activeWorkspace = pWorkspace; @@ -612,6 +615,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { if (!pWorkspace) { // remove special if exists if (activeSpecialWorkspace) { + activeSpecialWorkspace->m_bVisible = false; activeSpecialWorkspace->startAnim(false, false); g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", "," + szName}); } @@ -633,8 +637,10 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { return; } - if (activeSpecialWorkspace) + if (activeSpecialWorkspace) { + activeSpecialWorkspace->m_bVisible = false; activeSpecialWorkspace->startAnim(false, false); + } bool animate = true; //close if open elsewhere @@ -651,8 +657,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { } // open special - pWorkspace->m_iMonitorID = ID; - activeSpecialWorkspace = pWorkspace; + pWorkspace->m_iMonitorID = ID; + activeSpecialWorkspace = pWorkspace; + activeSpecialWorkspace->m_bVisible = true; if (animate) pWorkspace->startAnim(true, true); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index a9a72941..ac849b58 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -146,7 +146,7 @@ void CAnimationManager::tick() { animationsDisabled = animationsDisabled || PLAYER->noAnimations; } - const bool VISIBLE = PWINDOW && PWINDOW->m_pWorkspace ? g_pCompositor->isWorkspaceVisible(PWINDOW->workspaceID()) : true; + const bool VISIBLE = PWINDOW && PWINDOW->m_pWorkspace ? g_pCompositor->isWorkspaceVisible(PWINDOW->m_pWorkspace) : true; // beziers are with a switch unforto // TODO: maybe do something cleaner diff --git a/src/managers/input/IdleInhibitor.cpp b/src/managers/input/IdleInhibitor.cpp index 12d768f5..7e7ee3c9 100644 --- a/src/managers/input/IdleInhibitor.cpp +++ b/src/managers/input/IdleInhibitor.cpp @@ -65,7 +65,7 @@ void CInputManager::recheckIdleInhibitorStatus() { return; } - if (w->m_eIdleInhibitMode == IDLEINHIBIT_FULLSCREEN && w->m_bIsFullscreen && g_pCompositor->isWorkspaceVisible(w->workspaceID())) { + if (w->m_eIdleInhibitMode == IDLEINHIBIT_FULLSCREEN && w->m_bIsFullscreen && g_pCompositor->isWorkspaceVisible(w->m_pWorkspace)) { g_pCompositor->setIdleActivityInhibit(false); return; } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index cc682fad..446cb9bf 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -233,18 +233,18 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { pWindow->m_fAlpha.value() == 0) return false; - if (!PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() && !g_pCompositor->isWorkspaceVisible(pWindow->workspaceID())) + if (!PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() && !g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace)) return false; } if (pWindow->m_iMonitorID == pMonitor->ID) return true; - if (!g_pCompositor->isWorkspaceVisible(pWindow->workspaceID()) && pWindow->m_iMonitorID != pMonitor->ID) + if (!g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace) && pWindow->m_iMonitorID != pMonitor->ID) return false; // if not, check if it maybe is active on a different monitor. - if (g_pCompositor->isWorkspaceVisible(pWindow->workspaceID()) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) + if (g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors if (pMonitor->activeSpecialWorkspace == pWindow->m_pWorkspace) @@ -285,7 +285,7 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) { if (pWindow->m_bPinned || PWORKSPACE->m_bForceRendering) return true; - if (g_pCompositor->isWorkspaceVisible(pWindow->workspaceID())) + if (g_pCompositor->isWorkspaceVisible(pWindow->m_pWorkspace)) return true; for (auto& m : g_pCompositor->m_vMonitors) {