diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2024-04-27 12:43:12 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-27 12:43:12 +0100 |
| commit | bca7804bb6e1bf5ce5a99b9ae4806be25e36993c (patch) | |
| tree | ebd3a578de1dfe11b54f9440cfc3a408ffa6a620 /src/desktop | |
| parent | 25aec3ac8ce65ed224f025f8f6dfef73780577a4 (diff) | |
internal: Window storage rework - part 1 (#5762)
* Window storage rework - part 1
* format
* remove useless include
* fix pch
* format
* fix crash in dwindle
* fix vram leak
* prefer .expired() for bool checks
Diffstat (limited to 'src/desktop')
| -rw-r--r-- | src/desktop/Popup.cpp | 18 | ||||
| -rw-r--r-- | src/desktop/Popup.hpp | 6 | ||||
| -rw-r--r-- | src/desktop/Subsurface.cpp | 30 | ||||
| -rw-r--r-- | src/desktop/Subsurface.hpp | 9 | ||||
| -rw-r--r-- | src/desktop/WLSurface.cpp | 34 | ||||
| -rw-r--r-- | src/desktop/WLSurface.hpp | 6 | ||||
| -rw-r--r-- | src/desktop/Window.cpp | 244 | ||||
| -rw-r--r-- | src/desktop/Window.hpp | 90 | ||||
| -rw-r--r-- | src/desktop/Workspace.cpp | 14 | ||||
| -rw-r--r-- | src/desktop/Workspace.hpp | 4 |
10 files changed, 246 insertions, 209 deletions
diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 6a2aca7e..527c0b38 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -2,7 +2,7 @@ #include "../config/ConfigValue.hpp" #include "../Compositor.hpp" -CPopup::CPopup(CWindow* pOwner) : m_pWindowOwner(pOwner) { +CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) { initAllSignals(); } @@ -69,8 +69,8 @@ static void onRepositionPopup(void* owner, void* data) { void CPopup::initAllSignals() { if (!m_pWLR) { - if (m_pWindowOwner) - hyprListener_newPopup.initCallback(&m_pWindowOwner->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head"); + if (!m_pWindowOwner.expired()) + hyprListener_newPopup.initCallback(&m_pWindowOwner.lock()->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head"); else if (m_pLayerOwner) hyprListener_newPopup.initCallback(&m_pLayerOwner->layerSurface->events.new_popup, ::onNewPopup, this, "CPopup Head"); else @@ -146,12 +146,12 @@ void CPopup::onCommit(bool ignoreSiblings) { return; } - if (m_pWindowOwner && (!m_pWindowOwner->m_bIsMapped || !m_pWindowOwner->m_pWorkspace->m_bVisible)) { + if (!m_pWindowOwner.expired() && (!m_pWindowOwner.lock()->m_bIsMapped || !m_pWindowOwner.lock()->m_pWorkspace->m_bVisible)) { m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height}; static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage"); if (*PLOGDAMAGE) - Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowOwner); + Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowOwner.lock()); return; } @@ -230,8 +230,8 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) { } Vector2D CPopup::t1ParentCoords() { - if (m_pWindowOwner) - return m_pWindowOwner->m_vRealPosition.value(); + if (!m_pWindowOwner.expired()) + return m_pWindowOwner.lock()->m_vRealPosition.value(); if (m_pLayerOwner) return m_pLayerOwner->realPosition.value(); @@ -260,8 +260,8 @@ Vector2D CPopup::size() { } void CPopup::sendScale() { - if (m_pWindowOwner) - g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner->m_pWLSurface.m_fLastScale); + if (!m_pWindowOwner.expired()) + g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner.lock()->m_pWLSurface.m_fLastScale); else if (m_pLayerOwner) g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner->surface.m_fLastScale); else diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index 5f7af085..26e4bda5 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -9,7 +9,7 @@ struct SLayerSurface; class CPopup { public: // dummy head nodes - CPopup(CWindow* pOwner); + CPopup(PHLWINDOW pOwner); CPopup(SLayerSurface* pOwner); // real nodes @@ -35,8 +35,8 @@ class CPopup { private: // T1 owners, each popup has to have one of these - CWindow* m_pWindowOwner = nullptr; - SLayerSurface* m_pLayerOwner = nullptr; + PHLWINDOWREF m_pWindowOwner; + SLayerSurface* m_pLayerOwner = nullptr; // T2 owners CPopup* m_pParent = nullptr; diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index fd9d1899..b2c9f8bd 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -5,7 +5,7 @@ static void onNewSubsurface(void* owner, void* data); -CSubsurface::CSubsurface(CWindow* pOwner) : m_pWindowParent(pOwner) { +CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) { initSignals(); initExistingSubsurfaces(pOwner->m_pWLSurface.wlr()); } @@ -15,7 +15,7 @@ CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) { initExistingSubsurfaces(pOwner->m_sWLSurface.wlr()); } -CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) { +CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) { m_sWLSurface.assign(pSubsurface->surface, this); initSignals(); initExistingSubsurfaces(pSubsurface->surface); @@ -73,8 +73,8 @@ void CSubsurface::initSignals() { hyprListener_mapSubsurface.initCallback(&m_pSubsurface->surface->events.map, &onMapSubsurface, this, "CSubsurface"); hyprListener_unmapSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface"); } else { - if (m_pWindowParent) - hyprListener_newSubsurface.initCallback(&m_pWindowParent->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head"); + if (!m_pWindowParent.expired()) + hyprListener_newSubsurface.initCallback(&m_pWindowParent.lock()->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head"); else if (m_pPopupParent) hyprListener_newSubsurface.initCallback(&m_pPopupParent->m_sWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head"); else @@ -86,7 +86,7 @@ void CSubsurface::checkSiblingDamage() { if (!m_pParent) return; // ?????????? - const double SCALE = m_pWindowParent && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0; + const double SCALE = m_pWindowParent.lock() && m_pWindowParent.lock()->m_bIsX11 ? 1.0 / m_pWindowParent.lock()->m_fX11SurfaceScaledBy : 1.0; for (auto& n : m_pParent->m_vChildren) { if (n.get() == this) @@ -106,12 +106,12 @@ void CSubsurface::recheckDamageForSubsurfaces() { void CSubsurface::onCommit() { // no damaging if it's not visible - if (m_pWindowParent && (!m_pWindowParent->m_bIsMapped || !m_pWindowParent->m_pWorkspace->m_bVisible)) { + if (!m_pWindowParent.expired() && (!m_pWindowParent.lock()->m_bIsMapped || !m_pWindowParent.lock()->m_pWorkspace->m_bVisible)) { m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}; static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage"); if (*PLOGDAMAGE) - Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowParent); + Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowParent.lock()); return; } @@ -121,8 +121,8 @@ void CSubsurface::onCommit() { if (m_pPopupParent) m_pPopupParent->recheckTree(); - if (m_pWindowParent) // I hate you firefox why are you doing this - m_pWindowParent->m_pPopupHead->recheckTree(); + if (!m_pWindowParent.expired()) // I hate you firefox why are you doing this + m_pWindowParent.lock()->m_pPopupHead->recheckTree(); // I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox) checkSiblingDamage(); @@ -152,8 +152,8 @@ void CSubsurface::onDestroy() { void CSubsurface::onNewSubsurface(wlr_subsurface* pSubsurface) { CSubsurface* PSUBSURFACE = nullptr; - if (m_pWindowParent) - PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent)).get(); + if (!m_pWindowParent.expired()) + PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent.lock())).get(); else if (m_pPopupParent) PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get(); PSUBSURFACE->m_pParent = this; @@ -169,8 +169,8 @@ void CSubsurface::onMap() { box.expand(4); g_pHyprRenderer->damageBox(&box); - if (m_pWindowParent) - m_pWindowParent->updateSurfaceScaleTransformDetails(); + if (!m_pWindowParent.expired()) + m_pWindowParent.lock()->updateSurfaceScaleTransformDetails(); } void CSubsurface::onUnmap() { @@ -206,8 +206,8 @@ Vector2D CSubsurface::coordsRelativeToParent() { Vector2D CSubsurface::coordsGlobal() { Vector2D coords = coordsRelativeToParent(); - if (m_pWindowParent) - coords += m_pWindowParent->m_vRealPosition.value(); + if (!m_pWindowParent.expired()) + coords += m_pWindowParent.lock()->m_vRealPosition.value(); else if (m_pPopupParent) coords += m_pPopupParent->coordsGlobal(); diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp index b7c0a397..e5094041 100644 --- a/src/desktop/Subsurface.hpp +++ b/src/desktop/Subsurface.hpp @@ -4,17 +4,16 @@ #include <vector> #include "WLSurface.hpp" -class CWindow; class CPopup; class CSubsurface { public: // root dummy nodes - CSubsurface(CWindow* pOwner); + CSubsurface(PHLWINDOW pOwner); CSubsurface(CPopup* pOwner); // real nodes - CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner); + CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner); CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner); ~CSubsurface(); @@ -46,8 +45,8 @@ class CSubsurface { // if nullptr, means it's a dummy node CSubsurface* m_pParent = nullptr; - CWindow* m_pWindowParent = nullptr; - CPopup* m_pPopupParent = nullptr; + PHLWINDOWREF m_pWindowParent; + CPopup* m_pPopupParent = nullptr; std::vector<std::unique_ptr<CSubsurface>> m_vChildren; diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp index 4c2f6c84..55601a99 100644 --- a/src/desktop/WLSurface.cpp +++ b/src/desktop/WLSurface.cpp @@ -7,7 +7,7 @@ void CWLSurface::assign(wlr_surface* pSurface) { m_bInert = false; } -void CWLSurface::assign(wlr_surface* pSurface, CWindow* pOwner) { +void CWLSurface::assign(wlr_surface* pSurface, PHLWINDOW pOwner) { m_pWindowOwner = pOwner; m_pWLRSurface = pSurface; init(); @@ -52,20 +52,22 @@ wlr_surface* CWLSurface::wlr() const { } bool CWLSurface::small() const { - if (!m_pWindowOwner || !exists()) + if (!validMapped(m_pWindowOwner) || !exists()) return false; - return m_pWindowOwner->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || m_pWindowOwner->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1; + const auto O = m_pWindowOwner.lock(); + + return O->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || O->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1; } Vector2D CWLSurface::correctSmallVec() const { - if (!m_pWindowOwner || !exists() || !small() || m_bFillIgnoreSmall) + if (!validMapped(m_pWindowOwner) || !exists() || !small() || m_bFillIgnoreSmall) return {}; const auto SIZE = getViewporterCorrectedSize(); + const auto O = m_pWindowOwner.lock(); - 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.value() / m_pWindowOwner->m_vReportedSize); + 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::getViewporterCorrectedSize() const { @@ -110,11 +112,11 @@ void CWLSurface::destroy() { hyprListener_destroy.removeCallback(); hyprListener_commit.removeCallback(); m_pWLRSurface->data = nullptr; - m_pWindowOwner = nullptr; - m_pLayerOwner = nullptr; - m_pPopupOwner = nullptr; - m_pSubsurfaceOwner = nullptr; - m_bInert = true; + m_pWindowOwner.reset(); + 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; @@ -148,8 +150,8 @@ void CWLSurface::init() { Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this); } -CWindow* CWLSurface::getWindow() { - return m_pWindowOwner; +PHLWINDOW CWLSurface::getWindow() { + return m_pWindowOwner.lock(); } SLayerSurface* CWLSurface::getLayer() { @@ -165,15 +167,15 @@ CSubsurface* CWLSurface::getSubsurface() { } bool CWLSurface::desktopComponent() { - return m_pLayerOwner || m_pWindowOwner || m_pSubsurfaceOwner || m_pPopupOwner; + return m_pLayerOwner || !m_pWindowOwner.expired() || m_pSubsurfaceOwner || m_pPopupOwner; } std::optional<CBox> CWLSurface::getSurfaceBoxGlobal() { if (!desktopComponent()) return {}; - if (m_pWindowOwner) - return m_pWindowOwner->getWindowMainSurfaceBox(); + if (!m_pWindowOwner.expired()) + return m_pWindowOwner.lock()->getWindowMainSurfaceBox(); if (m_pLayerOwner) return m_pLayerOwner->geometry; if (m_pPopupOwner) diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index d018d11f..ffb81cc0 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -17,7 +17,7 @@ class 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, PHLWINDOW pOwner); void assign(wlr_surface* pSurface, SLayerSurface* pOwner); void assign(wlr_surface* pSurface, CSubsurface* pOwner); void assign(wlr_surface* pSurface, CPopup* pOwner); @@ -37,7 +37,7 @@ class CWLSurface { void onCommit(); // getters for owners. - CWindow* getWindow(); + PHLWINDOW getWindow(); SLayerSurface* getLayer(); CPopup* getPopup(); CSubsurface* getSubsurface(); @@ -94,7 +94,7 @@ class CWLSurface { wlr_surface* m_pWLRSurface = nullptr; - CWindow* m_pWindowOwner = nullptr; + PHLWINDOWREF m_pWindowOwner; SLayerSurface* m_pLayerOwner = nullptr; CPopup* m_pPopupOwner = nullptr; CSubsurface* m_pSubsurfaceOwner = nullptr; diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index b469102f..bf40f908 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -7,24 +7,34 @@ #include <any> #include "../managers/TokenManager.hpp" -CWindow::CWindow() { - m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), this, AVARDAMAGE_ENTIRE); - m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), this, AVARDAMAGE_ENTIRE); - m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), this, AVARDAMAGE_BORDER); - m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), this, AVARDAMAGE_BORDER); - m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), this, AVARDAMAGE_ENTIRE); - m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), this, AVARDAMAGE_ENTIRE); - m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), this, AVARDAMAGE_SHADOW); - m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), this, AVARDAMAGE_ENTIRE); +PHLWINDOW CWindow::create() { + PHLWINDOW pWindow = std::shared_ptr<CWindow>(new CWindow); + + pWindow->m_pSelf = pWindow; + + pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); + pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); + pWindow->m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER); + pWindow->m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER); + pWindow->m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); + pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE); + pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); + pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); + + pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow)); + pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow)); - addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(this)); - addWindowDeco(std::make_unique<CHyprBorderDecoration>(this)); + return pWindow; +} + +CWindow::CWindow() { + ; } CWindow::~CWindow() { - if (g_pCompositor->isWindowActive(this)) { - g_pCompositor->m_pLastFocus = nullptr; - g_pCompositor->m_pLastWindow = nullptr; + if (g_pCompositor->m_pLastWindow.lock().get() == this) { + g_pCompositor->m_pLastFocus = nullptr; + g_pCompositor->m_pLastWindow.reset(); } events.destroy.emit(); @@ -33,7 +43,7 @@ CWindow::~CWindow() { return; g_pHyprRenderer->makeEGLCurrent(); - std::erase_if(g_pHyprOpenGL->m_mWindowFramebuffers, [&](const auto& other) { return other.first == this; }); + std::erase_if(g_pHyprOpenGL->m_mWindowFramebuffers, [&](const auto& other) { return !other.first.lock() || other.first.lock().get() == this; }); } SWindowDecorationExtents CWindow::getFullWindowExtents() { @@ -50,7 +60,7 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() { SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}}; - const auto EXTENTS = g_pDecorationPositioner->getWindowDecorationExtents(this); + const auto EXTENTS = g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock()); if (EXTENTS.topLeft.x > maxExtents.topLeft.x) maxExtents.topLeft.x = EXTENTS.topLeft.x; @@ -153,11 +163,11 @@ CBox CWindow::getWindowBoxUnified(uint64_t properties) { SWindowDecorationExtents EXTENTS = {{0, 0}, {0, 0}}; if (properties & RESERVED_EXTENTS) - EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationReserved(this)); + EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationReserved(m_pSelf.lock())); if (properties & INPUT_EXTENTS) - EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(this, true)); + EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock(), true)); if (properties & FULL_EXTENTS) - EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(this, false)); + EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock(), false)); CBox box = {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y}; box.addExtents(EXTENTS); @@ -170,7 +180,7 @@ CBox CWindow::getWindowMainSurfaceBox() { } SWindowDecorationExtents CWindow::getFullWindowReservedArea() { - return g_pDecorationPositioner->getWindowDecorationReserved(this); + return g_pDecorationPositioner->getWindowDecorationReserved(m_pSelf.lock()); } void CWindow::updateWindowDecos() { @@ -191,10 +201,10 @@ void CWindow::updateWindowDecos() { } } - g_pDecorationPositioner->onWindowUpdate(this); + g_pDecorationPositioner->onWindowUpdate(m_pSelf.lock()); if (recalc) - g_pLayoutManager->getCurrentLayout()->recalculateWindow(this); + g_pLayoutManager->getCurrentLayout()->recalculateWindow(m_pSelf.lock()); m_vDecosToRemove.clear(); @@ -206,22 +216,22 @@ void CWindow::updateWindowDecos() { } for (auto& wd : decos) { - wd->updateWindow(this); + wd->updateWindow(m_pSelf.lock()); } } void CWindow::addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco) { m_dWindowDecorations.emplace_back(std::move(deco)); - g_pDecorationPositioner->forceRecalcFor(this); + g_pDecorationPositioner->forceRecalcFor(m_pSelf.lock()); updateWindowDecos(); - g_pLayoutManager->getCurrentLayout()->recalculateWindow(this); + g_pLayoutManager->getCurrentLayout()->recalculateWindow(m_pSelf.lock()); } void CWindow::removeWindowDeco(IHyprWindowDecoration* deco) { m_vDecosToRemove.push_back(deco); - g_pDecorationPositioner->forceRecalcFor(this); + g_pDecorationPositioner->forceRecalcFor(m_pSelf.lock()); updateWindowDecos(); - g_pLayoutManager->getCurrentLayout()->recalculateWindow(this); + g_pLayoutManager->getCurrentLayout()->recalculateWindow(m_pSelf.lock()); } void CWindow::uncacheWindowDecos() { @@ -335,7 +345,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { if (*PINITIALWSTRACKING == 2) { // persistent SInitialWorkspaceToken token = std::any_cast<SInitialWorkspaceToken>(TOKEN->data); - if (token.primaryOwner == this) { + if (token.primaryOwner.lock().get() == this) { token.workspace = pWorkspace->getConfigName(); TOKEN->data = token; } @@ -364,16 +374,16 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { if (valid(pWorkspace)) { g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", std::format("{:x},{}", (uintptr_t)this, pWorkspace->m_szName)}); g_pEventManager->postEvent(SHyprIPCEvent{"movewindowv2", std::format("{:x},{},{}", (uintptr_t)this, pWorkspace->m_iID, pWorkspace->m_szName)}); - EMIT_HOOK_EVENT("moveWindow", (std::vector<std::any>{this, pWorkspace})); + EMIT_HOOK_EVENT("moveWindow", (std::vector<std::any>{m_pSelf.lock(), pWorkspace})); } - if (m_pSwallowed) { - m_pSwallowed->moveToWorkspace(pWorkspace); - m_pSwallowed->m_iMonitorID = m_iMonitorID; + if (const auto SWALLOWED = m_pSwallowed.lock()) { + SWALLOWED->moveToWorkspace(pWorkspace); + SWALLOWED->m_iMonitorID = m_iMonitorID; } // update xwayland coords - g_pXWaylandManager->setWindowSize(this, m_vRealSize.value()); + g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.value()); if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && g_pCompositor->getWindowsOnWorkspace(OLDWORKSPACE->m_iID) == 0 && *PCLOSEONLASTSPECIAL) { if (const auto PMONITOR = g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID); PMONITOR) @@ -381,7 +391,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { } } -CWindow* CWindow::X11TransientFor() { +PHLWINDOW CWindow::X11TransientFor() { if (!m_bIsX11) return nullptr; @@ -390,11 +400,11 @@ CWindow* CWindow::X11TransientFor() { auto PPARENT = g_pCompositor->getWindowFromSurface(m_uSurface.xwayland->parent->surface); - while (g_pCompositor->windowValidMapped(PPARENT) && PPARENT->m_uSurface.xwayland->parent) { + while (validMapped(PPARENT) && PPARENT->m_uSurface.xwayland->parent) { PPARENT = g_pCompositor->getWindowFromSurface(PPARENT->m_uSurface.xwayland->parent->surface); } - if (!g_pCompositor->windowValidMapped(PPARENT)) + if (!validMapped(PPARENT)) return nullptr; return PPARENT; @@ -416,10 +426,10 @@ void unregisterVar(void* ptr) { void CWindow::onUnmap() { static auto PCLOSEONLASTSPECIAL = CConfigValue<Hyprlang::INT>("misc:close_special_on_empty"); - if (g_pCompositor->m_pLastWindow == this) - g_pCompositor->m_pLastWindow = nullptr; - if (g_pInputManager->currentlyDraggedWindow == this) - g_pInputManager->currentlyDraggedWindow = nullptr; + if (g_pCompositor->m_pLastWindow.lock().get() == this) + g_pCompositor->m_pLastWindow.reset(); + if (g_pInputManager->currentlyDraggedWindow.lock().get() == this) + g_pInputManager->currentlyDraggedWindow.reset(); static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking"); @@ -429,7 +439,7 @@ void CWindow::onUnmap() { if (*PINITIALWSTRACKING == 2) { // persistent token, but the first window got removed so the token is gone SInitialWorkspaceToken token = std::any_cast<SInitialWorkspaceToken>(TOKEN->data); - if (token.primaryOwner == this) + if (token.primaryOwner.lock().get() == this) g_pTokenManager->removeToken(TOKEN); } } @@ -448,7 +458,7 @@ void CWindow::onUnmap() { m_vRealSize.setCallbackOnBegin(nullptr); - std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other == this; }); + std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other.expired() || other.lock().get() == this; }); hyprListener_unmapWindow.removeCallback(); @@ -460,8 +470,8 @@ void CWindow::onUnmap() { const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); - if (PMONITOR && PMONITOR->solitaryClient == this) - PMONITOR->solitaryClient = nullptr; + if (PMONITOR && PMONITOR->solitaryClient.lock().get() == this) + PMONITOR->solitaryClient.reset(); g_pCompositor->updateWorkspaceWindows(workspaceID()); g_pCompositor->updateWorkspaceSpecialRenderData(workspaceID()); @@ -502,7 +512,7 @@ void CWindow::onMap() { m_fBorderAngleAnimationProgress.setValueAndWarp(0.f); m_fBorderAngleAnimationProgress = 1.f; - g_pCompositor->m_vWindowFocusHistory.push_back(this); + g_pCompositor->m_vWindowFocusHistory.push_back(m_pSelf); hyprListener_unmapWindow.initCallback(m_bIsX11 ? &m_uSurface.xwayland->surface->events.unmap : &m_uSurface.xdg->surface->events.unmap, &Events::listener_unmapWindow, this, "CWindow"); @@ -513,8 +523,8 @@ void CWindow::onMap() { if (m_bIsX11) return; - m_pSubsurfaceHead = std::make_unique<CSubsurface>(this); - m_pPopupHead = std::make_unique<CPopup>(this); + m_pSubsurfaceHead = std::make_unique<CSubsurface>(m_pSelf.lock()); + m_pPopupHead = std::make_unique<CPopup>(m_pSelf.lock()); } void CWindow::onBorderAngleAnimEnd(void* ptr) { @@ -536,8 +546,8 @@ void CWindow::onBorderAngleAnimEnd(void* ptr) { void CWindow::setHidden(bool hidden) { m_bHidden = hidden; - if (hidden && g_pCompositor->m_pLastWindow == this) { - g_pCompositor->m_pLastWindow = nullptr; + if (hidden && g_pCompositor->m_pLastWindow.lock().get() == this) { + g_pCompositor->m_pLastWindow.reset(); } setSuspended(hidden); @@ -696,7 +706,7 @@ void CWindow::applyDynamicRule(const SWindowRule& r) { m_sAdditionalConfigData.maxSize = VEC; m_vRealSize = Vector2D(std::min((double)m_sAdditionalConfigData.maxSize.toUnderlying().x, m_vRealSize.goal().x), std::min((double)m_sAdditionalConfigData.maxSize.toUnderlying().y, m_vRealSize.goal().y)); - g_pXWaylandManager->setWindowSize(this, m_vRealSize.goal()); + g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal()); setHidden(false); } catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r.szRule, e.what()); } } else if (r.szRule.starts_with("minsize")) { @@ -712,7 +722,7 @@ void CWindow::applyDynamicRule(const SWindowRule& r) { m_sAdditionalConfigData.minSize = VEC; m_vRealSize = Vector2D(std::max((double)m_sAdditionalConfigData.minSize.toUnderlying().x, m_vRealSize.goal().x), std::max((double)m_sAdditionalConfigData.minSize.toUnderlying().y, m_vRealSize.goal().y)); - g_pXWaylandManager->setWindowSize(this, m_vRealSize.goal()); + g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal()); setHidden(false); } catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); } } @@ -743,7 +753,7 @@ void CWindow::updateDynamicRules() { m_sAdditionalConfigData.nearestNeighbor = false; m_eIdleInhibitMode = IDLEINHIBIT_NONE; - const auto WINDOWRULES = g_pConfigManager->getMatchingRules(this); + const auto WINDOWRULES = g_pConfigManager->getMatchingRules(m_pSelf.lock()); for (auto& r : WINDOWRULES) { applyDynamicRule(r); } @@ -807,7 +817,7 @@ void CWindow::applyGroupRules() { if ((m_eGroupRules & GROUP_SET && m_bFirstMap) || m_eGroupRules & GROUP_SET_ALWAYS) createGroup(); - if (m_sGroupData.pNextWindow && ((m_eGroupRules & GROUP_LOCK && m_bFirstMap) || m_eGroupRules & GROUP_LOCK_ALWAYS)) + if (m_sGroupData.pNextWindow.lock() && ((m_eGroupRules & GROUP_LOCK && m_bFirstMap) || m_eGroupRules & GROUP_LOCK_ALWAYS)) getGroupHead()->m_sGroupData.locked = true; } @@ -817,13 +827,13 @@ void CWindow::createGroup() { return; } - if (!m_sGroupData.pNextWindow) { - m_sGroupData.pNextWindow = this; + if (m_sGroupData.pNextWindow.expired()) { + m_sGroupData.pNextWindow = m_pSelf; m_sGroupData.head = true; m_sGroupData.locked = false; m_sGroupData.deny = false; - addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(this)); + addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(m_pSelf.lock())); g_pCompositor->updateWorkspaceWindows(workspaceID()); g_pCompositor->updateWorkspaceSpecialRenderData(workspaceID()); @@ -833,13 +843,13 @@ void CWindow::createGroup() { } void CWindow::destroyGroup() { - if (m_sGroupData.pNextWindow == this) { + if (m_sGroupData.pNextWindow.lock().get() == this) { if (m_eGroupRules & GROUP_SET_ALWAYS) { Debug::log(LOG, "destoryGroup: window:{:x},title:{} has rule [group set always], ignored", (uintptr_t)this, this->m_szTitle); return; } - m_sGroupData.pNextWindow = nullptr; - m_sGroupData.head = false; + m_sGroupData.pNextWindow.reset(); + m_sGroupData.head = false; updateWindowDecos(); g_pCompositor->updateWorkspaceWindows(workspaceID()); g_pCompositor->updateWorkspaceSpecialRenderData(workspaceID()); @@ -848,15 +858,15 @@ void CWindow::destroyGroup() { return; } - CWindow* curr = this; - std::vector<CWindow*> members; + PHLWINDOW curr = m_pSelf.lock(); + std::vector<PHLWINDOW> members; do { - const auto PLASTWIN = curr; - curr = curr->m_sGroupData.pNextWindow; - PLASTWIN->m_sGroupData.pNextWindow = nullptr; + const auto PLASTWIN = curr; + curr = curr->m_sGroupData.pNextWindow.lock(); + PLASTWIN->m_sGroupData.pNextWindow.reset(); curr->setHidden(false); members.push_back(curr); - } while (curr != this); + } while (curr.get() != this); for (auto& w : members) { if (w->m_sGroupData.head) @@ -878,69 +888,69 @@ void CWindow::destroyGroup() { g_pCompositor->updateAllWindowsAnimatedDecorationValues(); } -CWindow* CWindow::getGroupHead() { - CWindow* curr = this; +PHLWINDOW CWindow::getGroupHead() { + PHLWINDOW curr = m_pSelf.lock(); while (!curr->m_sGroupData.head) - curr = curr->m_sGroupData.pNextWindow; + curr = curr->m_sGroupData.pNextWindow.lock(); return curr; } -CWindow* CWindow::getGroupTail() { - CWindow* curr = this; - while (!curr->m_sGroupData.pNextWindow->m_sGroupData.head) - curr = curr->m_sGroupData.pNextWindow; +PHLWINDOW CWindow::getGroupTail() { + PHLWINDOW curr = m_pSelf.lock(); + while (!curr->m_sGroupData.pNextWindow.lock()->m_sGroupData.head) + curr = curr->m_sGroupData.pNextWindow.lock(); return curr; } -CWindow* CWindow::getGroupCurrent() { - CWindow* curr = this; +PHLWINDOW CWindow::getGroupCurrent() { + PHLWINDOW curr = m_pSelf.lock(); while (curr->isHidden()) - curr = curr->m_sGroupData.pNextWindow; + curr = curr->m_sGroupData.pNextWindow.lock(); return curr; } int CWindow::getGroupSize() { - int size = 1; - CWindow* curr = this; - while (curr->m_sGroupData.pNextWindow != this) { - curr = curr->m_sGroupData.pNextWindow; + int size = 1; + PHLWINDOW curr = m_pSelf.lock(); + while (curr->m_sGroupData.pNextWindow.lock().get() != this) { + curr = curr->m_sGroupData.pNextWindow.lock(); size++; } return size; } -bool CWindow::canBeGroupedInto(CWindow* pWindow) { - return !g_pKeybindManager->m_bGroupsLocked // global group lock disengaged - && ((m_eGroupRules & GROUP_INVADE && m_bFirstMap) // window ignore local group locks, or - || (!pWindow->getGroupHead()->m_sGroupData.locked // target unlocked - && !(m_sGroupData.pNextWindow && getGroupHead()->m_sGroupData.locked))) // source unlocked or isn't group - && !m_sGroupData.deny // source is not denied entry - && !(m_eGroupRules & GROUP_BARRED && m_bFirstMap); // group rule doesn't prevent adding window +bool CWindow::canBeGroupedInto(PHLWINDOW pWindow) { + return !g_pKeybindManager->m_bGroupsLocked // global group lock disengaged + && ((m_eGroupRules & GROUP_INVADE && m_bFirstMap) // window ignore local group locks, or + || (!pWindow->getGroupHead()->m_sGroupData.locked // target unlocked + && !(m_sGroupData.pNextWindow.lock() && getGroupHead()->m_sGroupData.locked))) // source unlocked or isn't group + && !m_sGroupData.deny // source is not denied entry + && !(m_eGroupRules & GROUP_BARRED && m_bFirstMap); // group rule doesn't prevent adding window } -CWindow* CWindow::getGroupWindowByIndex(int index) { +PHLWINDOW CWindow::getGroupWindowByIndex(int index) { const int SIZE = getGroupSize(); index = ((index % SIZE) + SIZE) % SIZE; - CWindow* curr = getGroupHead(); + PHLWINDOW curr = getGroupHead(); while (index > 0) { - curr = curr->m_sGroupData.pNextWindow; + curr = curr->m_sGroupData.pNextWindow.lock(); index--; } return curr; } -void CWindow::setGroupCurrent(CWindow* pWindow) { - CWindow* curr = this->m_sGroupData.pNextWindow; - bool isMember = false; - while (curr != this) { +void CWindow::setGroupCurrent(PHLWINDOW pWindow) { + PHLWINDOW curr = m_sGroupData.pNextWindow.lock(); + bool isMember = false; + while (curr.get() != this) { if (curr == pWindow) { isMember = true; break; } - curr = curr->m_sGroupData.pNextWindow; + curr = curr->m_sGroupData.pNextWindow.lock(); } - if (!isMember && pWindow != this) + if (!isMember && pWindow.get() != this) return; const auto PCURRENT = getGroupCurrent(); @@ -950,7 +960,7 @@ void CWindow::setGroupCurrent(CWindow* pWindow) { const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal(); const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal(); - const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_pLastWindow; + const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_pLastWindow.lock(); if (FULLSCREEN) g_pCompositor->setWindowFullscreen(PCURRENT, false, WORKSPACE->m_efFullscreenMode); @@ -978,14 +988,14 @@ void CWindow::setGroupCurrent(CWindow* pWindow) { pWindow->updateWindowDecos(); } -void CWindow::insertWindowToGroup(CWindow* pWindow) { - const auto BEGINAT = this; - const auto ENDAT = m_sGroupData.pNextWindow; +void CWindow::insertWindowToGroup(PHLWINDOW pWindow) { + const auto BEGINAT = m_pSelf.lock(); + const auto ENDAT = m_sGroupData.pNextWindow.lock(); if (!pWindow->getDecorationByType(DECORATION_GROUPBAR)) pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow)); - if (!pWindow->m_sGroupData.pNextWindow) { + if (!pWindow->m_sGroupData.pNextWindow.lock()) { BEGINAT->m_sGroupData.pNextWindow = pWindow; pWindow->m_sGroupData.pNextWindow = ENDAT; pWindow->m_sGroupData.head = false; @@ -1000,26 +1010,26 @@ void CWindow::insertWindowToGroup(CWindow* pWindow) { STAIL->m_sGroupData.pNextWindow = ENDAT; } -CWindow* CWindow::getGroupPrevious() { - CWindow* curr = m_sGroupData.pNextWindow; +PHLWINDOW CWindow::getGroupPrevious() { + PHLWINDOW curr = m_sGroupData.pNextWindow.lock(); - while (curr != this && curr->m_sGroupData.pNextWindow != this) - curr = curr->m_sGroupData.pNextWindow; + while (curr != m_pSelf.lock() && curr->m_sGroupData.pNextWindow.lock().get() != this) + curr = curr->m_sGroupData.pNextWindow.lock(); return curr; } -void CWindow::switchWithWindowInGroup(CWindow* pWindow) { - if (!m_sGroupData.pNextWindow || !pWindow->m_sGroupData.pNextWindow) +void CWindow::switchWithWindowInGroup(PHLWINDOW pWindow) { + if (!m_sGroupData.pNextWindow.lock() || !pWindow->m_sGroupData.pNextWindow.lock()) return; - if (m_sGroupData.pNextWindow == pWindow) { // A -> this -> pWindow -> B >> A -> pWindow -> this -> B + if (m_sGroupData.pNextWindow.lock() == pWindow) { // A -> this -> pWindow -> B >> A -> pWindow -> this -> B getGroupPrevious()->m_sGroupData.pNextWindow = pWindow; m_sGroupData.pNextWindow = pWindow->m_sGroupData.pNextWindow; - pWindow->m_sGroupData.pNextWindow = this; + pWindow->m_sGroupData.pNextWindow = m_pSelf; - } else if (pWindow->m_sGroupData.pNextWindow == this) { // A -> pWindow -> this -> B >> A -> this -> pWindow -> B - pWindow->getGroupPrevious()->m_sGroupData.pNextWindow = this; + } else if (pWindow->m_sGroupData.pNextWindow.lock().get() == this) { // A -> pWindow -> this -> B >> A -> this -> pWindow -> B + pWindow->getGroupPrevious()->m_sGroupData.pNextWindow = m_pSelf; pWindow->m_sGroupData.pNextWindow = m_sGroupData.pNextWindow; m_sGroupData.pNextWindow = pWindow; @@ -1033,21 +1043,21 @@ void CWindow::switchWithWindowInGroup(CWindow* pWindow) { } void CWindow::updateGroupOutputs() { - if (!m_sGroupData.pNextWindow) + if (m_sGroupData.pNextWindow.expired()) return; - CWindow* curr = m_sGroupData.pNextWindow; + PHLWINDOW curr = m_sGroupData.pNextWindow.lock(); const auto WS = m_pWorkspace; - while (curr != this) { + while (curr.get() != this) { curr->m_iMonitorID = m_iMonitorID; curr->moveToWorkspace(WS); curr->m_vRealPosition = m_vRealPosition.goal(); curr->m_vRealSize = m_vRealSize.goal(); - curr = curr->m_sGroupData.pNextWindow; + curr = curr->m_sGroupData.pNextWindow.lock(); } } @@ -1258,7 +1268,7 @@ void CWindow::activate() { static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate"); g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)this)}); - EMIT_HOOK_EVENT("urgent", this); + EMIT_HOOK_EVENT("urgent", m_pSelf.lock()); m_bIsUrgent = true; @@ -1266,8 +1276,8 @@ void CWindow::activate() { return; if (m_bIsFloating) - g_pCompositor->changeWindowZOrder(this, true); + g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true); - g_pCompositor->focusWindow(this); + g_pCompositor->focusWindow(m_pSelf.lock()); g_pCompositor->warpCursorTo(middle()); } diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index b101700a..dd7d2e1e 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -14,8 +14,6 @@ #include "DesktopTypes.hpp" #include "../helpers/signal/Signal.hpp" -class CWindow; - enum eIdleInhibitMode { IDLEINHIBIT_NONE = 0, IDLEINHIBIT_ALWAYS, @@ -191,13 +189,18 @@ struct SWindowRule { }; struct SInitialWorkspaceToken { - CWindow* primaryOwner = nullptr; - std::string workspace; + PHLWINDOWREF primaryOwner; + std::string workspace; }; class CWindow { public: + static PHLWINDOW create(); + + private: CWindow(); + + public: ~CWindow(); DYNLISTENER(commitWindow); @@ -279,13 +282,13 @@ class CWindow { bool m_bCreatedOverFullscreen = false; // XWayland stuff - bool m_bIsX11 = false; - CWindow* m_pX11Parent = nullptr; - uint64_t m_iX11Type = 0; - bool m_bIsModal = false; - bool m_bX11DoesntWantBorders = false; - bool m_bX11ShouldntFocus = false; - float m_fX11SurfaceScaledBy = 1.f; + bool m_bIsX11 = false; + PHLWINDOWREF m_pX11Parent; + uint64_t m_iX11Type = 0; + bool m_bIsModal = false; + bool m_bX11DoesntWantBorders = false; + bool m_bX11ShouldntFocus = false; + float m_fX11SurfaceScaledBy = 1.f; // // For nofocus @@ -326,7 +329,7 @@ class CWindow { bool m_bFakeFullscreenState = false; // for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window. - CWindow* m_pLastCycledWindow = nullptr; + PHLWINDOWREF m_pLastCycledWindow; // Window decorations std::deque<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations; @@ -349,7 +352,7 @@ class CWindow { CAnimatedVariable<float> m_fDimPercent; // swallowing - CWindow* m_pSwallowed = nullptr; + PHLWINDOWREF m_pSwallowed; // focus stuff bool m_bStayFocused = false; @@ -366,10 +369,10 @@ class CWindow { // for groups struct SGroupData { - CWindow* pNextWindow = nullptr; // nullptr means no grouping. Self means single group. - bool head = false; - bool locked = false; // per group lock - bool deny = false; // deny window from enter a group or made a group + PHLWINDOWREF pNextWindow; // nullptr means no grouping. Self means single group. + bool head = false; + bool locked = false; // per group lock + bool deny = false; // deny window from enter a group or made a group } m_sGroupData; uint16_t m_eGroupRules = GROUP_NONE; @@ -398,7 +401,7 @@ class CWindow { void updateToplevel(); void updateSurfaceScaleTransformDetails(); void moveToWorkspace(PHLWORKSPACE); - CWindow* X11TransientFor(); + PHLWINDOW X11TransientFor(); void onUnmap(); void onMap(); void setHidden(bool hidden); @@ -429,23 +432,26 @@ class CWindow { void applyGroupRules(); void createGroup(); void destroyGroup(); - CWindow* getGroupHead(); - CWindow* getGroupTail(); - CWindow* getGroupCurrent(); - CWindow* getGroupPrevious(); - CWindow* getGroupWindowByIndex(int); + PHLWINDOW getGroupHead(); + PHLWINDOW getGroupTail(); + PHLWINDOW getGroupCurrent(); + PHLWINDOW getGroupPrevious(); + PHLWINDOW getGroupWindowByIndex(int); int getGroupSize(); - bool canBeGroupedInto(CWindow* pWindow); - void setGroupCurrent(CWindow* pWindow); - void insertWindowToGroup(CWindow* pWindow); + bool canBeGroupedInto(PHLWINDOW pWindow); + void setGroupCurrent(PHLWINDOW pWindow); + void insertWindowToGroup(PHLWINDOW pWindow); void updateGroupOutputs(); - void switchWithWindowInGroup(CWindow* pWindow); + void switchWithWindowInGroup(PHLWINDOW pWindow); void setAnimationsToMove(); void onWorkspaceAnimUpdate(); // std::unordered_map<std::string, std::string> getEnv(); + // + PHLWINDOWREF m_pSelf; + private: // For hidden windows and stuff bool m_bHidden = false; @@ -453,6 +459,26 @@ class CWindow { int m_iLastWorkspace = WORKSPACE_INVALID; }; +inline bool valid(PHLWINDOW w) { + return w.get(); +} + +inline bool valid(PHLWINDOWREF w) { + return w.lock().get(); +} + +inline bool validMapped(PHLWINDOW w) { + if (!valid(w)) + return false; + return w->m_bIsMapped; +} + +inline bool validMapped(PHLWINDOWREF w) { + if (!valid(w)) + return false; + return w.lock()->m_bIsMapped; +} + /** format specification - 'x', only address, equivalent of (uintpr_t)CWindow* @@ -462,7 +488,7 @@ class CWindow { */ template <typename CharT> -struct std::formatter<CWindow*, CharT> : std::formatter<CharT> { +struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> { bool formatAddressOnly = false; bool formatWorkspace = false; bool formatMonitor = false; @@ -472,18 +498,18 @@ struct std::formatter<CWindow*, CharT> : std::formatter<CharT> { FORMAT_FLAG('m', formatMonitor) // FORMAT_FLAG('w', formatWorkspace) // FORMAT_FLAG('c', formatClass), - CWindow*) + PHLWINDOW) template <typename FormatContext> - auto format(CWindow* const& w, FormatContext& ctx) const { + auto format(PHLWINDOW const& w, FormatContext& ctx) const { auto&& out = ctx.out(); if (formatAddressOnly) - return std::format_to(out, "{:x}", (uintptr_t)w); + return std::format_to(out, "{:x}", (uintptr_t)w.get()); if (!w) return std::format_to(out, "[Window nullptr]"); std::format_to(out, "["); - std::format_to(out, "Window {:x}: title: \"{}\"", (uintptr_t)w, w->m_szTitle); + std::format_to(out, "Window {:x}: title: \"{}\"", (uintptr_t)w.get(), w->m_szTitle); if (formatWorkspace) std::format_to(out, ", workspace: {}", w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID); if (formatMonitor) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index e9b155a4..cc43d221 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -33,10 +33,10 @@ void CWorkspace::init(PHLWORKSPACE self) { m_szName = RULEFORTHIS.defaultName.value(); m_pFocusedWindowHook = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any param) { - const auto PWINDOW = std::any_cast<CWindow*>(param); + const auto PWINDOW = std::any_cast<PHLWINDOW>(param); - if (PWINDOW == m_pLastFocusedWindow) - m_pLastFocusedWindow = nullptr; + if (PWINDOW == m_pLastFocusedWindow.lock()) + m_pLastFocusedWindow.reset(); }); m_bInert = false; @@ -75,7 +75,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) { // set floating windows offset callbacks m_vRenderOffset.setUpdateCallback([&](void*) { for (auto& w : g_pCompositor->m_vWindows) { - if (!g_pCompositor->windowValidMapped(w.get()) || w->workspaceID() != m_iID) + if (!validMapped(w) || w->workspaceID() != m_iID) continue; w->onWorkspaceAnimUpdate(); @@ -182,11 +182,11 @@ void CWorkspace::moveToMonitor(const int& id) { ; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40 } -CWindow* CWorkspace::getLastFocusedWindow() { - if (!g_pCompositor->windowValidMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow->workspaceID() != m_iID) +PHLWINDOW CWorkspace::getLastFocusedWindow() { + if (!validMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow.lock()->workspaceID() != m_iID) return nullptr; - return m_pLastFocusedWindow; + return m_pLastFocusedWindow.lock(); } void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) { diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index 0008699b..8789fab4 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -49,7 +49,7 @@ class CWorkspace { bool m_bIsSpecialWorkspace = false; // last window - CWindow* m_pLastFocusedWindow = nullptr; + PHLWINDOWREF m_pLastFocusedWindow; // user-set bool m_bDefaultFloating = false; @@ -68,7 +68,7 @@ class CWorkspace { void moveToMonitor(const int&); - CWindow* getLastFocusedWindow(); + PHLWINDOW getLastFocusedWindow(); void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace); std::string getConfigName(); |
