From 6916d0a6a316d602ff766abe5abffacf929b6801 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 29 Feb 2024 15:07:11 +0000 Subject: [PATCH] surface: unify owners --- src/Window.cpp | 3 +- src/desktop/Popup.cpp | 6 ++- src/desktop/Popup.hpp | 2 + src/desktop/Subsurface.cpp | 10 +++-- src/desktop/Subsurface.hpp | 2 + src/desktop/WLSurface.cpp | 86 +++++++++++++++++++++++++++++++++----- src/desktop/WLSurface.hpp | 35 ++++++++++++---- src/render/Renderer.cpp | 8 ++-- 8 files changed, 124 insertions(+), 28 deletions(-) diff --git a/src/Window.cpp b/src/Window.cpp index 6742be60..df357212 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -481,8 +481,7 @@ void CWindow::onUnmap() { void CWindow::onMap() { - m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(this)); - m_pWLSurface.m_pOwner = this; + m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(this), this); // JIC, reset the callbacks. If any are set, we'll make sure they are cleared so we don't accidentally unset them. (In case a window got remapped) m_vRealPosition.resetAllCallbacks(); diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index a4b63826..ad0a1a25 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -10,7 +10,7 @@ CPopup::CPopup(SLayerSurface* pOwner) : m_pLayerOwner(pOwner) { CPopup::CPopup(wlr_xdg_popup* popup, CPopup* pOwner) : m_pParent(pOwner), m_pWLR(popup) { m_pWLR->base->data = this; - m_sWLSurface.assign(popup->base->surface); + m_sWLSurface.assign(popup->base->surface, this); m_pLayerOwner = pOwner->m_pLayerOwner; m_pWindowOwner = pOwner->m_pWindowOwner; @@ -222,4 +222,8 @@ void CPopup::recheckChildrenRecursive() { c->onCommit(); c->recheckChildrenRecursive(); } +} + +Vector2D CPopup::size() { + return m_vLastSize; } \ No newline at end of file diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index 8279f7ed..48dae088 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -20,6 +20,8 @@ class CPopup { Vector2D coordsRelativeToParent(); Vector2D coordsGlobal(); + Vector2D size(); + void onNewPopup(wlr_xdg_popup* popup); void onDestroy(); void onMap(); diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index dde8d532..ab43f3c3 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -29,13 +29,13 @@ CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) { } CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) { - m_sWLSurface.assign(pSubsurface->surface); + m_sWLSurface.assign(pSubsurface->surface, this); initSignals(); initExistingSubsurfaces(); } CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) { - m_sWLSurface.assign(pSubsurface->surface); + m_sWLSurface.assign(pSubsurface->surface, this); initSignals(); initExistingSubsurfaces(); } @@ -254,4 +254,8 @@ void CSubsurface::initExistingSubsurfaces() { wl_list_for_each(wlrSubsurface, &m_sWLSurface.wlr()->current.subsurfaces_above, current.link) { ::onNewSubsurface(this, wlrSubsurface); } -} \ No newline at end of file +} + +Vector2D CSubsurface::size() { + return {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}; +} diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp index a8babd70..ca02a6d5 100644 --- a/src/desktop/Subsurface.hpp +++ b/src/desktop/Subsurface.hpp @@ -22,6 +22,8 @@ class CSubsurface { Vector2D coordsRelativeToParent(); Vector2D coordsGlobal(); + Vector2D size(); + void onCommit(); void onDestroy(); void onNewSubsurface(wlr_subsurface* pSubsurface); diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp index 25f11feb..6773d761 100644 --- a/src/desktop/WLSurface.cpp +++ b/src/desktop/WLSurface.cpp @@ -1,14 +1,38 @@ #include "WLSurface.hpp" #include "../Compositor.hpp" -CWLSurface::CWLSurface(wlr_surface* pSurface) { - m_pWLRSurface = pSurface; - init(); -} - void CWLSurface::assign(wlr_surface* pSurface) { m_pWLRSurface = pSurface; init(); + m_bInert = false; +} + +void CWLSurface::assign(wlr_surface* pSurface, CWindow* pOwner) { + m_pWindowOwner = pOwner; + m_pWLRSurface = pSurface; + init(); + m_bInert = false; +} + +void CWLSurface::assign(wlr_surface* pSurface, SLayerSurface* pOwner) { + m_pLayerOwner = pOwner; + m_pWLRSurface = pSurface; + init(); + m_bInert = false; +} + +void CWLSurface::assign(wlr_surface* pSurface, CSubsurface* pOwner) { + m_pSubsurfaceOwner = pOwner; + m_pWLRSurface = pSurface; + init(); + m_bInert = false; +} + +void CWLSurface::assign(wlr_surface* pSurface, CPopup* pOwner) { + m_pPopupOwner = pOwner; + m_pWLRSurface = pSurface; + init(); + m_bInert = false; } void CWLSurface::unassign() { @@ -28,20 +52,20 @@ wlr_surface* CWLSurface::wlr() const { } bool CWLSurface::small() const { - if (!m_pOwner || !exists()) + if (!m_pWindowOwner || !exists()) return false; - return m_pOwner->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || m_pOwner->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1; + return m_pWindowOwner->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || m_pWindowOwner->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1; } Vector2D CWLSurface::correctSmallVec() const { - if (!m_pOwner || !exists() || !small() || m_bFillIgnoreSmall) + if (!m_pWindowOwner || !exists() || !small() || m_bFillIgnoreSmall) return {}; const auto SIZE = getViewporterCorrectedSize(); - return Vector2D{(m_pOwner->m_vReportedSize.x - SIZE.x) / 2, (m_pOwner->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * - (m_pOwner->m_vRealSize.vec() / m_pOwner->m_vReportedSize); + return Vector2D{(m_pWindowOwner->m_vReportedSize.x - SIZE.x) / 2, (m_pWindowOwner->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * + (m_pWindowOwner->m_vRealSize.vec() / m_pWindowOwner->m_vReportedSize); } Vector2D CWLSurface::getViewporterCorrectedSize() const { @@ -81,7 +105,11 @@ void CWLSurface::destroy() { hyprListener_destroy.removeCallback(); m_pWLRSurface->data = nullptr; - m_pOwner = nullptr; + m_pWindowOwner = nullptr; + m_pLayerOwner = nullptr; + m_pPopupOwner = nullptr; + m_pSubsurfaceOwner = nullptr; + m_bInert = true; if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface) g_pCompositor->m_pLastFocus = nullptr; @@ -107,4 +135,40 @@ void CWLSurface::init() { &m_pWLRSurface->events.destroy, [&](void* owner, void* data) { destroy(); }, this, "CWLSurface"); Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this); +} + +CWindow* CWLSurface::getWindow() { + return m_pWindowOwner; +} + +SLayerSurface* CWLSurface::getLayer() { + return m_pLayerOwner; +} + +CPopup* CWLSurface::getPopup() { + return m_pPopupOwner; +} + +CSubsurface* CWLSurface::getSubsurface() { + return m_pSubsurfaceOwner; +} + +bool CWLSurface::desktopComponent() { + return m_pLayerOwner || m_pWindowOwner || m_pSubsurfaceOwner || m_pPopupOwner; +} + +std::optional CWLSurface::getSurfaceBoxGlobal() { + if (!desktopComponent()) + return {}; + + if (m_pWindowOwner) + return m_pWindowOwner->getWindowMainSurfaceBox(); + if (m_pLayerOwner) + return m_pLayerOwner->geometry; + if (m_pPopupOwner) + return CBox{m_pPopupOwner->coordsGlobal(), m_pPopupOwner->size()}; + if (m_pSubsurfaceOwner) + return CBox{m_pSubsurfaceOwner->coordsGlobal(), m_pSubsurfaceOwner->size()}; + + return {}; } \ No newline at end of file diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index 15debd56..3e04b4b2 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -4,14 +4,21 @@ #include "../helpers/Region.hpp" class CWindow; +struct SLayerSurface; +class CSubsurface; +class CPopup; class CWLSurface { public: CWLSurface() = default; - CWLSurface(wlr_surface* pSurface); ~CWLSurface(); + // anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD void assign(wlr_surface* pSurface); + void assign(wlr_surface* pSurface, CWindow* pOwner); + void assign(wlr_surface* pSurface, SLayerSurface* pOwner); + void assign(wlr_surface* pSurface, CSubsurface* pOwner); + void assign(wlr_surface* pSurface, CPopup* pOwner); void unassign(); CWLSurface(const CWLSurface&) = delete; @@ -26,12 +33,18 @@ class CWLSurface { Vector2D getViewporterCorrectedSize() const; CRegion logicalDamage() const; + // getters for owners. + CWindow* getWindow(); + SLayerSurface* getLayer(); + CPopup* getPopup(); + CSubsurface* getSubsurface(); + + // desktop components misc utils + std::optional getSurfaceBoxGlobal(); + // allow stretching. Useful for plugins. bool m_bFillIgnoreSmall = false; - // if present, means this is a base surface of a window. Cleaned on unassign() - CWindow* m_pOwner = nullptr; - // track surface data and avoid dupes float m_fLastScale = 0; int m_iLastScale = 0; @@ -63,10 +76,18 @@ class CWLSurface { } private: - wlr_surface* m_pWLRSurface = nullptr; + bool m_bInert = true; - void destroy(); - void init(); + wlr_surface* m_pWLRSurface = nullptr; + + CWindow* m_pWindowOwner = nullptr; + SLayerSurface* m_pLayerOwner = nullptr; + CPopup* m_pPopupOwner = nullptr; + CSubsurface* m_pSubsurfaceOwner = nullptr; + + void destroy(); + void init(); + bool desktopComponent(); DYNLISTENER(destroy); }; \ No newline at end of file diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 4ffdecb4..fd1c3434 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -70,7 +70,7 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) // however, if surface buffer w / h < box, we need to adjust them auto* const PSURFACE = CWLSurface::surfaceFromWlr(surface); - if (PSURFACE && !PSURFACE->m_bFillIgnoreSmall && PSURFACE->small() /* guarantees m_pOwner */) { + if (PSURFACE && !PSURFACE->m_bFillIgnoreSmall && PSURFACE->small() /* guarantees m_pWindowOwner */) { const auto CORRECT = PSURFACE->correctSmallVec(); const auto SIZE = PSURFACE->getViewporterCorrectedSize(); @@ -78,8 +78,8 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data) windowBox.x += CORRECT.x; windowBox.y += CORRECT.y; - windowBox.width = SIZE.x * (PSURFACE->m_pOwner->m_vRealSize.vec().x / PSURFACE->m_pOwner->m_vReportedSize.x); - windowBox.height = SIZE.y * (PSURFACE->m_pOwner->m_vRealSize.vec().y / PSURFACE->m_pOwner->m_vReportedSize.y); + windowBox.width = SIZE.x * (PSURFACE->getWindow()->m_vRealSize.vec().x / PSURFACE->getWindow()->m_vReportedSize.x); + windowBox.height = SIZE.y * (PSURFACE->getWindow()->m_vRealSize.vec().y / PSURFACE->getWindow()->m_vReportedSize.y); } else { windowBox.width = SIZE.x; windowBox.height = SIZE.y; @@ -1590,7 +1590,7 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou return; auto* const PSURFACE = CWLSurface::surfaceFromWlr(pSurface); - if (PSURFACE && PSURFACE->m_pOwner && PSURFACE->small()) { + if (PSURFACE && PSURFACE->small()) { const auto CORRECTION = PSURFACE->correctSmallVec(); x += CORRECTION.x; y += CORRECTION.y;