From b735295d2b0025b26f88852c06f65514a963c711 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 17 Nov 2024 19:31:54 +0000 Subject: [PATCH] windows/xdg: minor cleanup of min/max size calculations fixes #8495 --- src/desktop/Window.cpp | 26 ++++++++++++++++++++++++++ src/desktop/Window.hpp | 19 +++++++++---------- src/events/Windows.cpp | 8 ++++---- src/layout/DwindleLayout.cpp | 2 +- src/layout/IHyprLayout.cpp | 8 ++++---- src/layout/MasterLayout.cpp | 4 ++-- src/managers/XWaylandManager.cpp | 30 ------------------------------ src/managers/XWaylandManager.hpp | 2 -- src/protocols/XDGShell.cpp | 8 ++++++++ src/protocols/XDGShell.hpp | 3 +++ 10 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 20fed565..e74e13a2 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1601,3 +1601,29 @@ bool CWindow::isX11OverrideRedirect() { bool CWindow::isModal() { return (m_pXWaylandSurface && m_pXWaylandSurface->modal); } + +Vector2D CWindow::requestedMinSize() { + if ((m_bIsX11 && !m_pXWaylandSurface->sizeHints) || (!m_bIsX11 && !m_pXDGSurface->toplevel)) + return Vector2D(1, 1); + + Vector2D minSize = m_bIsX11 ? Vector2D(m_pXWaylandSurface->sizeHints->min_width, m_pXWaylandSurface->sizeHints->min_height) : m_pXDGSurface->toplevel->layoutMinSize(); + + minSize = minSize.clamp({1, 1}); + + return minSize; +} + +Vector2D CWindow::requestedMaxSize() { + constexpr int NO_MAX_SIZE_LIMIT = 99999; + if (((m_bIsX11 && !m_pXWaylandSurface->sizeHints) || (!m_bIsX11 && !m_pXDGSurface->toplevel) || m_sWindowData.noMaxSize.valueOrDefault())) + return Vector2D(NO_MAX_SIZE_LIMIT, NO_MAX_SIZE_LIMIT); + + Vector2D maxSize = m_bIsX11 ? Vector2D(m_pXWaylandSurface->sizeHints->max_width, m_pXWaylandSurface->sizeHints->max_height) : m_pXDGSurface->toplevel->layoutMaxSize(); + + if (maxSize.x < 5) + maxSize.x = NO_MAX_SIZE_LIMIT; + if (maxSize.y < 5) + maxSize.y = NO_MAX_SIZE_LIMIT; + + return maxSize; +} diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index b8dd3cf7..ac81e5ef 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -403,12 +403,9 @@ class CWindow { } // methods - CBox getFullWindowBoundingBox(); - SBoxExtents getFullWindowExtents(); - CBox getWindowBoxUnified(uint64_t props); - inline CBox getWindowMainSurfaceBox() const { - return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y}; - } + CBox getFullWindowBoundingBox(); + SBoxExtents getFullWindowExtents(); + CBox getWindowBoxUnified(uint64_t props); CBox getWindowIdealBoundingBoxIgnoreReserved(); void addWindowDeco(std::unique_ptr deco); void updateWindowDecos(); @@ -441,19 +438,15 @@ class CWindow { void activate(bool force = false); int surfacesCount(); void clampWindowSize(const std::optional minSize, const std::optional maxSize); - bool isFullscreen(); bool isEffectiveInternalFSMode(const eFullscreenMode); - int getRealBorderSize(); void updateWindowData(); void updateWindowData(const struct SWorkspaceRule&); - void onBorderAngleAnimEnd(void* ptr); bool isInCurvedCorner(double x, double y); bool hasPopupAt(const Vector2D& pos); int popupsCount(); - void applyGroupRules(); void createGroup(); void destroyGroup(); @@ -481,6 +474,12 @@ class CWindow { void unsetWindowData(eOverridePriority priority); bool isX11OverrideRedirect(); bool isModal(); + Vector2D requestedMinSize(); + Vector2D requestedMaxSize(); + + inline CBox getWindowMainSurfaceBox() const { + return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y}; + } // listeners void onAck(uint32_t serial); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 77df7373..73ab45c1 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -346,7 +346,7 @@ void Events::listener_mapWindow(void* owner, void* data) { const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' ')); const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1); - const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW); + const auto MAXSIZE = PWINDOW->requestedMaxSize(); const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, PMONITOR->vecSize.x) : stringToFloatClamp(SIZEXSTR, PWINDOW->m_vRealSize.goal().x, PMONITOR->vecSize.x); @@ -469,7 +469,7 @@ void Events::listener_mapWindow(void* owner, void* data) { const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' ')); const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1); - const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW); + const auto MAXSIZE = PWINDOW->requestedMaxSize(); const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, PMONITOR->vecSize.x) : stringToPercentage(SIZEXSTR, PMONITOR->vecSize.x); @@ -753,8 +753,8 @@ void Events::listener_commitWindow(void* owner, void* data) { PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged. if (!PWINDOW->m_bIsX11 && !PWINDOW->isFullscreen() && PWINDOW->m_bIsFloating) { - const auto MINSIZE = PWINDOW->m_pXDGSurface->toplevel->current.minSize; - const auto MAXSIZE = PWINDOW->m_pXDGSurface->toplevel->current.maxSize; + const auto MINSIZE = PWINDOW->m_pXDGSurface->toplevel->layoutMinSize(); + const auto MAXSIZE = PWINDOW->m_pXDGSurface->toplevel->layoutMaxSize(); PWINDOW->clampWindowSize(MINSIZE, MAXSIZE > Vector2D{1, 1} ? std::optional{MAXSIZE} : std::nullopt); g_pHyprRenderer->damageWindow(PWINDOW); diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index e6e9090f..c3e394f3 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -283,7 +283,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir // first, check if OPENINGON isn't too big. const auto PREDSIZEMAX = OPENINGON ? Vector2D(OPENINGON->box.w, OPENINGON->box.h) : PMONITOR->vecSize; - if (const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); MAXSIZE.x < PREDSIZEMAX.x || MAXSIZE.y < PREDSIZEMAX.y) { + if (const auto MAXSIZE = pWindow->requestedMaxSize(); MAXSIZE.x < PREDSIZEMAX.x || MAXSIZE.y < PREDSIZEMAX.y) { // we can't continue. make it floating. pWindow->m_bIsFloating = true; m_lDwindleNodesData.remove(*PNODE); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index a312555f..af8b907c 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -597,12 +597,12 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { } else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) { if (DRAGGINGWINDOW->m_bIsFloating) { - Vector2D MINSIZE = g_pXWaylandManager->getMinSizeForWindow(DRAGGINGWINDOW).clamp(DRAGGINGWINDOW->m_sWindowData.minSize.valueOr(Vector2D(20, 20))); + Vector2D MINSIZE = DRAGGINGWINDOW->requestedMinSize().clamp(DRAGGINGWINDOW->m_sWindowData.minSize.valueOr(Vector2D(20, 20))); Vector2D MAXSIZE; if (DRAGGINGWINDOW->m_sWindowData.maxSize.hasValue()) - MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW).clamp({}, DRAGGINGWINDOW->m_sWindowData.maxSize.value()); + MAXSIZE = DRAGGINGWINDOW->requestedMaxSize().clamp({}, DRAGGINGWINDOW->m_sWindowData.maxSize.value()); else - MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW).clamp({}, Vector2D(std::numeric_limits::max(), std::numeric_limits::max())); + MAXSIZE = DRAGGINGWINDOW->requestedMaxSize().clamp({}, Vector2D(std::numeric_limits::max(), std::numeric_limits::max())); Vector2D newSize = m_vBeginDragSizeXY; Vector2D newPos = m_vBeginDragPositionXY; @@ -884,7 +884,7 @@ Vector2D IHyprLayout::predictSizeForNewWindowFloating(PHLWINDOW pWindow) { // ge const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' ')); const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1); - const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); + const auto MAXSIZE = pWindow->requestedMaxSize(); const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, g_pCompositor->m_pLastMonitor->vecSize.x) : stringToPercentage(SIZEXSTR, g_pCompositor->m_pLastMonitor->vecSize.x); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index b8b3efea..695dcc99 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -200,7 +200,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire PNODE->percMaster = lastSplitPercent; // first, check if it isn't too big. - if (const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); MAXSIZE.x < PMONITOR->vecSize.x * lastSplitPercent || MAXSIZE.y < PMONITOR->vecSize.y) { + if (const auto MAXSIZE = pWindow->requestedMaxSize(); MAXSIZE.x < PMONITOR->vecSize.x * lastSplitPercent || MAXSIZE.y < PMONITOR->vecSize.y) { // we can't continue. make it floating. pWindow->m_bIsFloating = true; m_lMasterNodesData.remove(*PNODE); @@ -212,7 +212,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire PNODE->percMaster = lastSplitPercent; // first, check if it isn't too big. - if (const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow); + if (const auto MAXSIZE = pWindow->requestedMaxSize(); MAXSIZE.x < PMONITOR->vecSize.x * (1 - lastSplitPercent) || MAXSIZE.y < PMONITOR->vecSize.y * (1.f / (WINDOWSONWORKSPACE - 1))) { // we can't continue. make it floating. pWindow->m_bIsFloating = true; diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index d0dda8e6..832173eb 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -213,36 +213,6 @@ void CHyprXWaylandManager::setWindowFullscreen(PHLWINDOW pWindow, bool fullscree pWindow->m_pXDGSurface->toplevel->setFullscreen(fullscreen); } -Vector2D CHyprXWaylandManager::getMaxSizeForWindow(PHLWINDOW pWindow) { - constexpr int NO_MAX_SIZE_LIMIT = 99999; - if (!validMapped(pWindow) || - ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel) || - pWindow->m_sWindowData.noMaxSize.valueOrDefault())) - return Vector2D(NO_MAX_SIZE_LIMIT, NO_MAX_SIZE_LIMIT); - - Vector2D maxSize = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->max_width, pWindow->m_pXWaylandSurface->sizeHints->max_height) : - pWindow->m_pXDGSurface->toplevel->current.maxSize; - - if (maxSize.x < 5) - maxSize.x = NO_MAX_SIZE_LIMIT; - if (maxSize.y < 5) - maxSize.y = NO_MAX_SIZE_LIMIT; - - return maxSize; -} - -Vector2D CHyprXWaylandManager::getMinSizeForWindow(PHLWINDOW pWindow) { - if (!validMapped(pWindow) || ((pWindow->m_bIsX11 && !pWindow->m_pXWaylandSurface->sizeHints) || (!pWindow->m_bIsX11 && !pWindow->m_pXDGSurface->toplevel))) - return Vector2D(0, 0); - - Vector2D minSize = pWindow->m_bIsX11 ? Vector2D(pWindow->m_pXWaylandSurface->sizeHints->min_width, pWindow->m_pXWaylandSurface->sizeHints->min_height) : - pWindow->m_pXDGSurface->toplevel->current.minSize; - - minSize = minSize.clamp({1, 1}); - - return minSize; -} - Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) { static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); diff --git a/src/managers/XWaylandManager.hpp b/src/managers/XWaylandManager.hpp index a9f95974..508a20d6 100644 --- a/src/managers/XWaylandManager.hpp +++ b/src/managers/XWaylandManager.hpp @@ -21,8 +21,6 @@ class CHyprXWaylandManager { void setWindowFullscreen(PHLWINDOW, bool); bool shouldBeFloated(PHLWINDOW, bool pending = false); void checkBorders(PHLWINDOW); - Vector2D getMaxSizeForWindow(PHLWINDOW); - Vector2D getMinSizeForWindow(PHLWINDOW); Vector2D xwaylandToWaylandCoords(const Vector2D&); }; diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index 25d8b1ba..932882e9 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -323,6 +323,14 @@ void CXDGToplevelResource::close() { resource->sendClose(); } +Vector2D CXDGToplevelResource::layoutMinSize() { + return owner ? current.minSize + owner->current.geometry.pos() : current.minSize; +} + +Vector2D CXDGToplevelResource::layoutMaxSize() { + return owner ? current.maxSize + owner->current.geometry.pos() : current.maxSize; +} + CXDGSurfaceResource::CXDGSurfaceResource(SP resource_, SP owner_, SP surface_) : owner(owner_), surface(surface_), resource(resource_) { if (!good()) diff --git a/src/protocols/XDGShell.hpp b/src/protocols/XDGShell.hpp index 9c766c20..ef847f3b 100644 --- a/src/protocols/XDGShell.hpp +++ b/src/protocols/XDGShell.hpp @@ -99,6 +99,9 @@ class CXDGToplevelResource { bool good(); + Vector2D layoutMinSize(); + Vector2D layoutMaxSize(); + // schedule a configure event uint32_t setSize(const Vector2D& size); uint32_t setMaximized(bool maximized);