diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp index 97335d27..a7a2e5aa 100644 --- a/src/desktop/WLSurface.cpp +++ b/src/desktop/WLSurface.cpp @@ -74,6 +74,16 @@ Vector2D CWLSurface::correctSmallVec() const { return Vector2D{(O->m_vReportedSize.x - SIZE.x) / 2, (O->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_vRealSize.value() / O->m_vReportedSize); } +Vector2D CWLSurface::correctSmallVecBuf() const { + if (!exists() || !small() || m_bFillIgnoreSmall || !m_pResource->current.buffer) + return {}; + + const auto SIZE = getViewporterCorrectedSize(); + const auto BS = m_pResource->current.buffer->size; + + return Vector2D{(BS.x - SIZE.x) / 2, (BS.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}); +} + Vector2D CWLSurface::getViewporterCorrectedSize() const { if (!exists() || !m_pResource->current.buffer) return {}; @@ -81,16 +91,15 @@ Vector2D CWLSurface::getViewporterCorrectedSize() const { return m_pResource->current.viewport.hasDestination ? m_pResource->current.viewport.destination : m_pResource->current.buffer->size; } -CRegion CWLSurface::logicalDamage() const { +CRegion CWLSurface::computeDamage() const { if (!m_pResource->current.buffer) return {}; CRegion damage = m_pResource->accumulateCurrentBufferDamage(); damage.transform(wlTransformToHyprutils(m_pResource->current.transform), m_pResource->current.buffer->size.x, m_pResource->current.buffer->size.y); - damage.scale(1.0 / m_pResource->current.scale); - const auto VPSIZE = getViewporterCorrectedSize(); - const auto CORRECTVEC = correctSmallVec(); + const auto BUFSIZE = m_pResource->current.buffer->size; + const auto CORRECTVEC = correctSmallVecBuf(); if (m_pResource->current.viewport.hasSource) damage.intersect(m_pResource->current.viewport.source); @@ -98,9 +107,17 @@ CRegion CWLSurface::logicalDamage() const { const auto SCALEDSRCSIZE = m_pResource->current.viewport.hasSource ? m_pResource->current.viewport.source.size() * m_pResource->current.scale : m_pResource->current.buffer->size; - damage.scale({VPSIZE.x / SCALEDSRCSIZE.x, VPSIZE.y / SCALEDSRCSIZE.y}); + damage.scale({BUFSIZE.x / SCALEDSRCSIZE.x, BUFSIZE.y / SCALEDSRCSIZE.y}); damage.translate(CORRECTVEC); + // go from buffer coords in the damage to hl logical + + const auto BOX = getSurfaceBoxGlobal(); + const Vector2D SCALE = BOX.has_value() ? BOX->size() / m_pResource->current.buffer->size : + Vector2D{1.0 / m_pResource->current.scale, 1.0 / m_pResource->current.scale /* Wrong... but we can't really do better */}; + + damage.scale(SCALE); + return damage; } @@ -141,27 +158,27 @@ void CWLSurface::init() { Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this); } -PHLWINDOW CWLSurface::getWindow() { +PHLWINDOW CWLSurface::getWindow() const { return m_pWindowOwner.lock(); } -PHLLS CWLSurface::getLayer() { +PHLLS CWLSurface::getLayer() const { return m_pLayerOwner.lock(); } -CPopup* CWLSurface::getPopup() { +CPopup* CWLSurface::getPopup() const { return m_pPopupOwner; } -CSubsurface* CWLSurface::getSubsurface() { +CSubsurface* CWLSurface::getSubsurface() const { return m_pSubsurfaceOwner; } -bool CWLSurface::desktopComponent() { +bool CWLSurface::desktopComponent() const { return !m_pLayerOwner.expired() || !m_pWindowOwner.expired() || m_pSubsurfaceOwner || m_pPopupOwner; } -std::optional CWLSurface::getSurfaceBoxGlobal() { +std::optional CWLSurface::getSurfaceBoxGlobal() const { if (!desktopComponent()) return {}; @@ -181,7 +198,7 @@ void CWLSurface::appendConstraint(WP constraint) { m_pConstraint = constraint; } -SP CWLSurface::constraint() { +SP CWLSurface::constraint() const { return m_pConstraint.lock(); } diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index 447f4582..bb476e0f 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -33,22 +33,23 @@ class CWLSurface { SP resource() const; bool exists() const; - bool small() const; // means surface is smaller than the requested size - Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces + bool small() const; // means surface is smaller than the requested size + Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces + Vector2D correctSmallVecBuf() const; // returns a corrective vector for small() surfaces, in BL coords Vector2D getViewporterCorrectedSize() const; - CRegion logicalDamage() const; + CRegion computeDamage() const; // logical coordinates. May be wrong if the surface is unassigned bool visible(); // getters for owners. - PHLWINDOW getWindow(); - PHLLS getLayer(); - CPopup* getPopup(); - CSubsurface* getSubsurface(); + PHLWINDOW getWindow() const; + PHLLS getLayer() const; + CPopup* getPopup() const; + CSubsurface* getSubsurface() const; // desktop components misc utils - std::optional getSurfaceBoxGlobal(); + std::optional getSurfaceBoxGlobal() const; void appendConstraint(WP constraint); - SP constraint(); + SP constraint() const; // allow stretching. Useful for plugins. bool m_bFillIgnoreSmall = false; @@ -107,7 +108,7 @@ class CWLSurface { void destroy(); void init(); - bool desktopComponent(); + bool desktopComponent() const; struct { CHyprSignalListener destroy; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 84d607b8..835fed91 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1693,7 +1693,7 @@ void CHyprRenderer::damageSurface(SP pSurface, double x, dou return; const auto WLSURF = CWLSurface::fromResource(pSurface); - CRegion damageBox = WLSURF ? WLSURF->logicalDamage() : CRegion{}; + CRegion damageBox = WLSURF ? WLSURF->computeDamage() : CRegion{}; if (!WLSURF) { Debug::log(ERR, "BUG THIS: No CWLSurface for surface in damageSurface!!!"); return;