Centralize retained node teardown

This commit is contained in:
2026-06-12 16:15:43 +02:00
parent 9ac2c541dc
commit adb61795a6
7 changed files with 31 additions and 10 deletions

View File

@@ -555,6 +555,12 @@ agent or engineer to remove them without reconstructing context from chat.
`src/legacy_ui_overlay_services.*`, and brush/grid progress or recovery `src/legacy_ui_overlay_services.*`, and brush/grid progress or recovery
message dialogs now use the retained dialog close helper instead of direct message dialogs now use the retained dialog close helper instead of direct
`destroy()` calls. Checked handles and scoped callback ownership remain open. `destroy()` calls. Checked handles and scoped callback ownership remain open.
- 2026-06-12: DEBT-0063 was narrowed again. Floating-panel placeholder detach/
destroy, cloud-loading alignment cleanup, brush-preset item removal, and
retained popup-panel parent detach now route through named retained node
helpers in `src/legacy_ui_overlay_services.*`. Floating-panel dock/drop
reparenting still uses legacy child-vector ownership until checked handles
land.
- 2026-06-05: DEBT-0011 was narrowed. The Windows app package smoke target now - 2026-06-05: DEBT-0011 was narrowed. The Windows app package smoke target now
passes the configure-time CMake executable into `package-smoke.ps1`, so VS passes the configure-time CMake executable into `package-smoke.ps1`, so VS
2026 generator validation does not depend on an older `cmake` on PATH, and 2026 generator validation does not depend on an older `cmake` on PATH, and

View File

@@ -521,6 +521,9 @@ helper while drag reparenting remains legacy-owned.
Layer-row, animation-timeline, and heightmap-overlay drag release paths now use Layer-row, animation-timeline, and heightmap-overlay drag release paths now use
the same retained mouse-capture release helper, and brush/grid progress or the same retained mouse-capture release helper, and brush/grid progress or
recovery message dialogs now route through the retained dialog close helper. recovery message dialogs now route through the retained dialog close helper.
Floating-panel placeholder detach/destroy, cloud-loading alignment cleanup,
brush-preset item removal, and retained popup-panel parent detach now use named
retained node helpers; dock/drop reparenting remains legacy-owned.
Raw popup callback captures and full close/capture ownership remain part of Raw popup callback captures and full close/capture ownership remain part of
`DEBT-0063`. `DEBT-0063`.
`pano_cli inspect-image` exposes PNG IHDR metadata as JSON, `pano_cli inspect-image` exposes PNG IHDR metadata as JSON,

View File

@@ -15,11 +15,21 @@ void initialize_legacy_overlay_node(App& app, Node& node)
node.loaded(); node.loaded();
} }
void close_legacy_dialog_node(Node& node) void destroy_legacy_node(Node& node)
{ {
node.destroy(); node.destroy();
} }
void detach_legacy_node_from_parent(Node& node)
{
node.remove_from_parent();
}
void close_legacy_dialog_node(Node& node)
{
destroy_legacy_node(node);
}
void release_legacy_mouse_capture(Node& node) noexcept void release_legacy_mouse_capture(Node& node) noexcept
{ {
node.mouse_release(); node.mouse_release();
@@ -41,7 +51,7 @@ void activate_legacy_popup_overlay(Node& node) noexcept
void close_legacy_popup_overlay(Node& node) noexcept void close_legacy_popup_overlay(Node& node) noexcept
{ {
release_legacy_mouse_capture(node); release_legacy_mouse_capture(node);
node.destroy(); destroy_legacy_node(node);
} }
void close_legacy_dialog_and_hide_keyboard(App& app, Node& node) void close_legacy_dialog_and_hide_keyboard(App& app, Node& node)
@@ -56,7 +66,7 @@ void close_legacy_popup_panel(
{ {
release_legacy_mouse_capture(node); release_legacy_mouse_capture(node);
if (node.m_parent) { if (node.m_parent) {
node.m_parent->remove_child(&node); detach_legacy_node_from_parent(node);
} }
if (on_close) { if (on_close) {
on_close(&node); on_close(&node);

View File

@@ -13,6 +13,8 @@ namespace pp::panopainter {
void initialize_legacy_overlay_node(App& app, Node& node); void initialize_legacy_overlay_node(App& app, Node& node);
void destroy_legacy_node(Node& node);
void detach_legacy_node_from_parent(Node& node);
void close_legacy_dialog_node(Node& node); void close_legacy_dialog_node(Node& node);
void release_legacy_mouse_capture(Node& node) noexcept; void release_legacy_mouse_capture(Node& node) noexcept;
void configure_legacy_popup_overlay(Node& node) noexcept; void configure_legacy_popup_overlay(Node& node) noexcept;

View File

@@ -77,7 +77,7 @@ void NodeDialogCloud::load_thumbs_thread()
return; return;
} }
align->destroy(); pp::panopainter::destroy_legacy_node(*align);
LOG("CLOUD LIST: %s", res.c_str()); LOG("CLOUD LIST: %s", res.c_str());

View File

@@ -437,7 +437,7 @@ public:
} }
const bool new_current = !p->m_current || p->m_container->get_child_index(p->m_current) == current_index; const bool new_current = !p->m_current || p->m_container->get_child_index(p->m_current) == current_index;
p->m_container->m_children[current_index]->destroy(); pp::panopainter::destroy_legacy_node(*p->m_container->m_children[current_index]);
if (clears_selection) { if (clears_selection) {
p->m_current = nullptr; p->m_current = nullptr;
} else if (new_current && selects_target) { } else if (new_current && selects_target) {

View File

@@ -127,7 +127,7 @@ kEventResult NodePanelFloating::handle_event(Event* e)
{ {
m_outline->SetPosition(c->m_pos); m_outline->SetPosition(c->m_pos);
m_outline->SetSize(c->m_size); m_outline->SetSize(c->m_size);
m_drop_placeholder->remove_from_parent(); pp::panopainter::detach_legacy_node_from_parent(*m_drop_placeholder);
int i = 0; int i = 0;
float y = 0; float y = 0;
for (; i < c->m_children.size(); i++) for (; i < c->m_children.size(); i++)
@@ -154,7 +154,7 @@ kEventResult NodePanelFloating::handle_event(Event* e)
} }
} }
if (!docked && m_drop_placeholder->m_parent) if (!docked && m_drop_placeholder->m_parent)
m_drop_placeholder->remove_from_parent(); pp::panopainter::detach_legacy_node_from_parent(*m_drop_placeholder);
} }
else if (m_action == kDragAction::Reheight) else if (m_action == kDragAction::Reheight)
{ {
@@ -184,8 +184,8 @@ kEventResult NodePanelFloating::handle_event(Event* e)
{ {
if (m_drop_placeholder->m_parent) if (m_drop_placeholder->m_parent)
drop_pos = std::max(0, m_drop_placeholder->m_parent->get_child_index(m_drop_placeholder.get())); drop_pos = std::max(0, m_drop_placeholder->m_parent->get_child_index(m_drop_placeholder.get()));
m_drop_placeholder->destroy(); pp::panopainter::destroy_legacy_node(*m_drop_placeholder);
m_drop_placeholder->remove_from_parent(); pp::panopainter::detach_legacy_node_from_parent(*m_drop_placeholder);
} }
bool docked = false; bool docked = false;
if (m_droppable) if (m_droppable)
@@ -226,7 +226,7 @@ kEventResult NodePanelFloating::handle_event(Event* e)
m_outline = nullptr; m_outline = nullptr;
m_drop_placeholder = nullptr; m_drop_placeholder = nullptr;
} }
mouse_release(); pp::panopainter::release_legacy_mouse_capture(*this);
ret = kEventResult::Consumed; ret = kEventResult::Consumed;
break; break;
default: default: