internal: new shared_ptr and weak_ptr implementation (#5883)

moves std::shared_ptrs to a new implementation

Advantages:
- you can dereference a weak_ptr directly. This will obviously segfault on a nullptr deref if it's expired.
   - this is useful to avoid the .lock() hell where we are 100% sure the pointer _should_ be valid. (and if it isn't, it should throw.)
- weak_ptrs are still valid while the SP is being destroyed.
   - reasoning: while an object (e.g. CWindow) is being destroyed, its `weak_ptr self` should be accessible (the sp is still alive, and so is CWindow), but it's not because by stl it's already expired (to prevent resurrection)
   - this impl solves it differently. w_p is expired, but can still be dereferenced and used. Creating `s_p`s is not possible anymore, though.
   - this is useful in destructors and callbacks.
This commit is contained in:
Vaxry 2024-05-05 17:16:00 +01:00 committed by GitHub
parent 589f758d94
commit 1ed1ce9506
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
88 changed files with 899 additions and 414 deletions

View file

@ -1,6 +1,20 @@
#pragma once
#include <memory>
#include "../macros.hpp"
class CWorkspace;
class CWindow;
class CLayerSurface;
typedef std::shared_ptr<CWorkspace> PHLWORKSPACE;
/* Shared pointer to a workspace */
typedef SP<CWorkspace> PHLWORKSPACE;
/* Weak pointer to a workspace */
typedef WP<CWorkspace> PHLWORKSPACEREF;
/* Shared pointer to a window */
typedef SP<CWindow> PHLWINDOW;
/* Weak pointer to a window */
typedef WP<CWindow> PHLWINDOWREF;
/* Shared pointer to a layer surface */
typedef SP<CLayerSurface> PHLLS;
/* Weak pointer to a layer surface */
typedef WP<CLayerSurface> PHLLSREF;

View file

@ -58,7 +58,7 @@ static void onDestroy(void* owner, void* data) {
// IMPL
PHLLS CLayerSurface::create(wlr_layer_surface_v1* pWLRLS) {
PHLLS pLS = std::shared_ptr<CLayerSurface>(new CLayerSurface);
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface);
auto PMONITOR = g_pCompositor->getMonitorFromOutput(pWLRLS->output);
@ -176,7 +176,7 @@ void CLayerSurface::onMap() {
if ((uint64_t)monitorID != PMONITOR->ID) {
const auto POLDMON = g_pCompositor->getMonitorFromID(monitorID);
for (auto it = POLDMON->m_aLayerSurfaceLayers[layer].begin(); it != POLDMON->m_aLayerSurfaceLayers[layer].end(); it++) {
if (*it == self.lock()) {
if (*it == self) {
PMONITOR->m_aLayerSurfaceLayers[layer].emplace_back(std::move(*it));
POLDMON->m_aLayerSurfaceLayers[layer].erase(it);
break;
@ -235,7 +235,7 @@ void CLayerSurface::onUnmap() {
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
if (!g_pInputManager->m_dExclusiveLSes.empty())
g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0].lock()->layerSurface->surface);
g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0]->layerSurface->surface);
if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) {
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
@ -284,7 +284,7 @@ void CLayerSurface::onUnmap() {
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
&surfaceCoords, &pFoundLayerSurface);
if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow.lock()->m_pWorkspace)) {
if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && 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.lock();
g_pCompositor->focusWindow(nullptr);
@ -325,7 +325,7 @@ void CLayerSurface::onCommit() {
const auto POLDMON = g_pCompositor->getMonitorFromID(monitorID);
for (auto it = POLDMON->m_aLayerSurfaceLayers[layer].begin(); it != POLDMON->m_aLayerSurfaceLayers[layer].end(); it++) {
if (*it == self.lock()) {
if (*it == self) {
PMONITOR->m_aLayerSurfaceLayers[layer].emplace_back(std::move(*it));
POLDMON->m_aLayerSurfaceLayers[layer].erase(it);
break;
@ -341,7 +341,7 @@ void CLayerSurface::onCommit() {
if (layer != layerSurface->current.layer) {
for (auto it = PMONITOR->m_aLayerSurfaceLayers[layer].begin(); it != PMONITOR->m_aLayerSurfaceLayers[layer].end(); it++) {
if (*it == self.lock()) {
if (*it == self) {
PMONITOR->m_aLayerSurfaceLayers[layerSurface->current.layer].emplace_back(std::move(*it));
PMONITOR->m_aLayerSurfaceLayers[layer].erase(it);
break;

View file

@ -70,9 +70,9 @@ void CPopup::initAllSignals() {
if (!m_pWLR) {
if (!m_pWindowOwner.expired())
hyprListener_newPopup.initCallback(&m_pWindowOwner.lock()->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head");
hyprListener_newPopup.initCallback(&m_pWindowOwner->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head");
else if (!m_pLayerOwner.expired())
hyprListener_newPopup.initCallback(&m_pLayerOwner.lock()->layerSurface->events.new_popup, ::onNewPopup, this, "CPopup Head");
hyprListener_newPopup.initCallback(&m_pLayerOwner->layerSurface->events.new_popup, ::onNewPopup, this, "CPopup Head");
else
ASSERT(false);
@ -119,8 +119,8 @@ void CPopup::onMap() {
unconstrain();
sendScale();
if (!m_pLayerOwner.expired() && m_pLayerOwner.lock()->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner.lock()->layer));
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
}
void CPopup::onUnmap() {
@ -136,8 +136,8 @@ void CPopup::onUnmap() {
g_pInputManager->simulateMouseMovement();
if (!m_pLayerOwner.expired() && m_pLayerOwner.lock()->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner.lock()->layer));
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
}
void CPopup::onCommit(bool ignoreSiblings) {
@ -146,7 +146,7 @@ void CPopup::onCommit(bool ignoreSiblings) {
return;
}
if (!m_pWindowOwner.expired() && (!m_pWindowOwner.lock()->m_bIsMapped || !m_pWindowOwner.lock()->m_pWorkspace->m_bVisible)) {
if (!m_pWindowOwner.expired() && (!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<Hyprlang::INT>("debug:log_damage");
@ -178,8 +178,8 @@ void CPopup::onCommit(bool ignoreSiblings) {
m_bRequestedReposition = false;
if (!m_pLayerOwner.expired() && m_pLayerOwner.lock()->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner.lock()->layer));
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
}
void CPopup::onReposition() {
@ -231,9 +231,9 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) {
Vector2D CPopup::t1ParentCoords() {
if (!m_pWindowOwner.expired())
return m_pWindowOwner.lock()->m_vRealPosition.value();
return m_pWindowOwner->m_vRealPosition.value();
if (!m_pLayerOwner.expired())
return m_pLayerOwner.lock()->realPosition.value();
return m_pLayerOwner->realPosition.value();
ASSERT(false);
return {};
@ -261,9 +261,9 @@ Vector2D CPopup::size() {
void CPopup::sendScale() {
if (!m_pWindowOwner.expired())
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner.lock()->m_pWLSurface.m_fLastScale);
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner->m_pWLSurface.m_fLastScale);
else if (!m_pLayerOwner.expired())
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner.lock()->surface.m_fLastScale);
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner->surface.m_fLastScale);
else
UNREACHABLE();
}

View file

@ -74,7 +74,7 @@ void CSubsurface::initSignals() {
hyprListener_unmapSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface");
} else {
if (!m_pWindowParent.expired())
hyprListener_newSubsurface.initCallback(&m_pWindowParent.lock()->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
hyprListener_newSubsurface.initCallback(&m_pWindowParent->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.lock() && m_pWindowParent.lock()->m_bIsX11 ? 1.0 / m_pWindowParent.lock()->m_fX11SurfaceScaledBy : 1.0;
const double SCALE = m_pWindowParent.lock() && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
for (auto& n : m_pParent->m_vChildren) {
if (n.get() == this)
@ -106,7 +106,7 @@ void CSubsurface::recheckDamageForSubsurfaces() {
void CSubsurface::onCommit() {
// no damaging if it's not visible
if (!m_pWindowParent.expired() && (!m_pWindowParent.lock()->m_bIsMapped || !m_pWindowParent.lock()->m_pWorkspace->m_bVisible)) {
if (!m_pWindowParent.expired() && (!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<Hyprlang::INT>("debug:log_damage");
@ -122,7 +122,7 @@ void CSubsurface::onCommit() {
if (m_pPopupParent)
m_pPopupParent->recheckTree();
if (!m_pWindowParent.expired()) // I hate you firefox why are you doing this
m_pWindowParent.lock()->m_pPopupHead->recheckTree();
m_pWindowParent->m_pPopupHead->recheckTree();
// I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
checkSiblingDamage();
@ -170,7 +170,7 @@ void CSubsurface::onMap() {
g_pHyprRenderer->damageBox(&box);
if (!m_pWindowParent.expired())
m_pWindowParent.lock()->updateSurfaceScaleTransformDetails();
m_pWindowParent->updateSurfaceScaleTransformDetails();
}
void CSubsurface::onUnmap() {
@ -207,7 +207,7 @@ Vector2D CSubsurface::coordsGlobal() {
Vector2D coords = coordsRelativeToParent();
if (!m_pWindowParent.expired())
coords += m_pWindowParent.lock()->m_vRealPosition.value();
coords += m_pWindowParent->m_vRealPosition.value();
else if (m_pPopupParent)
coords += m_pPopupParent->coordsGlobal();

View file

@ -175,9 +175,9 @@ std::optional<CBox> CWLSurface::getSurfaceBoxGlobal() {
return {};
if (!m_pWindowOwner.expired())
return m_pWindowOwner.lock()->getWindowMainSurfaceBox();
return m_pWindowOwner->getWindowMainSurfaceBox();
if (!m_pLayerOwner.expired())
return m_pLayerOwner.lock()->geometry;
return m_pLayerOwner->geometry;
if (m_pPopupOwner)
return CBox{m_pPopupOwner->coordsGlobal(), m_pPopupOwner->size()};
if (m_pSubsurfaceOwner)
@ -186,7 +186,7 @@ std::optional<CBox> CWLSurface::getSurfaceBoxGlobal() {
return {};
}
void CWLSurface::appendConstraint(std::weak_ptr<CPointerConstraint> constraint) {
void CWLSurface::appendConstraint(WP<CPointerConstraint> constraint) {
m_pConstraint = constraint;
}
@ -194,7 +194,7 @@ void CWLSurface::onCommit() {
;
}
std::shared_ptr<CPointerConstraint> CWLSurface::constraint() {
SP<CPointerConstraint> CWLSurface::constraint() {
return m_pConstraint.lock();
}

View file

@ -42,9 +42,9 @@ class CWLSurface {
CSubsurface* getSubsurface();
// desktop components misc utils
std::optional<CBox> getSurfaceBoxGlobal();
void appendConstraint(std::weak_ptr<CPointerConstraint> constraint);
std::shared_ptr<CPointerConstraint> constraint();
std::optional<CBox> getSurfaceBoxGlobal();
void appendConstraint(WP<CPointerConstraint> constraint);
SP<CPointerConstraint> constraint();
// allow stretching. Useful for plugins.
bool m_bFillIgnoreSmall = false;
@ -99,11 +99,11 @@ class CWLSurface {
CSubsurface* m_pSubsurfaceOwner = nullptr;
//
std::weak_ptr<CPointerConstraint> m_pConstraint;
WP<CPointerConstraint> m_pConstraint;
void destroy();
void init();
bool desktopComponent();
void destroy();
void init();
bool desktopComponent();
DYNLISTENER(destroy);
DYNLISTENER(commit);

View file

@ -8,7 +8,7 @@
#include "../managers/TokenManager.hpp"
PHLWINDOW CWindow::create() {
PHLWINDOW pWindow = std::shared_ptr<CWindow>(new CWindow);
PHLWINDOW pWindow = SP<CWindow>(new CWindow);
pWindow->m_pSelf = pWindow;
@ -894,7 +894,7 @@ PHLWINDOW CWindow::getGroupHead() {
PHLWINDOW CWindow::getGroupTail() {
PHLWINDOW curr = m_pSelf.lock();
while (!curr->m_sGroupData.pNextWindow.lock()->m_sGroupData.head)
while (!curr->m_sGroupData.pNextWindow->m_sGroupData.head)
curr = curr->m_sGroupData.pNextWindow.lock();
return curr;
}

View file

@ -467,7 +467,7 @@ inline bool valid(PHLWINDOW w) {
}
inline bool valid(PHLWINDOWREF w) {
return w.lock().get();
return !w.expired();
}
inline bool validMapped(PHLWINDOW w) {
@ -479,7 +479,7 @@ inline bool validMapped(PHLWINDOW w) {
inline bool validMapped(PHLWINDOWREF w) {
if (!valid(w))
return false;
return w.lock()->m_bIsMapped;
return w->m_bIsMapped;
}
/**

View file

@ -3,7 +3,7 @@
#include "../config/ConfigValue.hpp"
PHLWORKSPACE CWorkspace::create(int id, int monitorID, std::string name, bool special) {
PHLWORKSPACE workspace = std::make_shared<CWorkspace>(id, monitorID, name, special);
PHLWORKSPACE workspace = makeShared<CWorkspace>(id, monitorID, name, special);
workspace->init(workspace);
return workspace;
}
@ -183,7 +183,7 @@ void CWorkspace::moveToMonitor(const int& id) {
}
PHLWINDOW CWorkspace::getLastFocusedWindow() {
if (!validMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow.lock()->workspaceID() != m_iID)
if (!validMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow->workspaceID() != m_iID)
return nullptr;
return m_pLastFocusedWindow.lock();

View file

@ -78,11 +78,11 @@ class CWorkspace {
void markInert();
private:
void init(PHLWORKSPACE self);
void init(PHLWORKSPACE self);
std::shared_ptr<HOOK_CALLBACK_FN> m_pFocusedWindowHook;
bool m_bInert = true;
std::weak_ptr<CWorkspace> m_pSelf;
SP<HOOK_CALLBACK_FN> m_pFocusedWindowHook;
bool m_bInert = true;
WP<CWorkspace> m_pSelf;
};
inline bool valid(const PHLWORKSPACE& ref) {