diff options
| author | Yuqian Yang <crupest@crupest.life> | 2025-11-17 13:52:52 +0800 |
|---|---|---|
| committer | Yuqian Yang <crupest@crupest.life> | 2025-11-17 13:52:52 +0800 |
| commit | f7c4d19df66c602d74795e98ce2ee4390d06fbb4 (patch) | |
| tree | 5d91dc18ae8129652d4c5b88234d0bb7b93dcf13 /src/ui/controls | |
| parent | c9f31440d65a867e2316e9a19ee3f5db2d0e53a7 (diff) | |
| download | cru-f7c4d19df66c602d74795e98ce2ee4390d06fbb4.tar.gz cru-f7c4d19df66c602d74795e98ce2ee4390d06fbb4.tar.bz2 cru-f7c4d19df66c602d74795e98ce2ee4390d06fbb4.zip | |
Harden delete after free.
Diffstat (limited to 'src/ui/controls')
| -rw-r--r-- | src/ui/controls/Control.cpp | 17 | ||||
| -rw-r--r-- | src/ui/controls/Window.cpp | 33 |
2 files changed, 38 insertions, 12 deletions
diff --git a/src/ui/controls/Control.cpp b/src/ui/controls/Control.cpp index e903b5b3..9c0fc537 100644 --- a/src/ui/controls/Control.cpp +++ b/src/ui/controls/Control.cpp @@ -1,4 +1,5 @@ #include "cru/ui/controls/Control.h" +#include "cru/base/log/Logger.h" #include "cru/ui/controls/Window.h" #include "cru/platform/gui/Cursor.h" @@ -27,11 +28,14 @@ Control::Control() { Control::~Control() { if (auto window = GetWindow()) { if (window->IsInEventHandling()) { - // Don't delete control during event handling. Use DeleteLater. - std::terminate(); + CRU_LOG_TAG_WARN( + "Better use delete later to delete control during event handling."); } } + if (auto window = GetWindow()) { + window->NotifyControlDestroyed(this); + } RemoveFromParent(); } @@ -58,6 +62,15 @@ void Control::SetParent(Control* parent) { OnParentChanged(old_parent, parent); } +bool Control::HasAncestor(Control* control) { + auto parent = this; + while (parent) { + if (parent == control) return true; + parent = parent->GetParent(); + } + return false; +} + void Control::RemoveFromParent() { if (parent_) { parent_->RemoveChild(this); diff --git a/src/ui/controls/Window.cpp b/src/ui/controls/Window.cpp index e6abc48d..c82b2485 100644 --- a/src/ui/controls/Window.cpp +++ b/src/ui/controls/Window.cpp @@ -265,16 +265,6 @@ void Window::SetOverrideCursor(std::shared_ptr<platform::gui::ICursor> cursor) { bool Window::IsInEventHandling() { return event_handling_count_; } -void Window::UpdateCursor() { - if (override_cursor_) { - native_window_->SetCursor(override_cursor_); - } else { - const auto capture = GetMouseCaptureControl(); - native_window_->SetCursor( - (capture ? capture : GetMouseHoverControl())->GetInheritedCursor()); - } -} - void Window::OnNativeDestroy(platform::gui::INativeWindow* window, std::nullptr_t) { CRU_UNUSED(window) @@ -428,4 +418,27 @@ void Window::DispatchMouseHoverControlChangeEvent(Control* old_control, } } +void Window::UpdateCursor() { + if (override_cursor_) { + native_window_->SetCursor(override_cursor_); + } else { + const auto capture = GetMouseCaptureControl(); + native_window_->SetCursor( + (capture ? capture : GetMouseHoverControl())->GetInheritedCursor()); + } +} + +void Window::NotifyControlDestroyed(Control* control) { + if (focus_control_->HasAncestor(control)) { + focus_control_ = control->GetParent(); + } + + if (mouse_captured_control_->HasAncestor(control)) { + mouse_captured_control_ = control->GetParent(); + } + + if (mouse_hover_control_->HasAncestor(control)) { + mouse_hover_control_ = control->GetParent(); + } +} } // namespace cru::ui::controls |
