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 /include/cru/ui/controls/Window.h | |
| parent | c9f31440d65a867e2316e9a19ee3f5db2d0e53a7 (diff) | |
| download | cru-f7c4d19df66c602d74795e98ce2ee4390d06fbb4.tar.gz cru-f7c4d19df66c602d74795e98ce2ee4390d06fbb4.tar.bz2 cru-f7c4d19df66c602d74795e98ce2ee4390d06fbb4.zip | |
Harden delete after free.
Diffstat (limited to 'include/cru/ui/controls/Window.h')
| -rw-r--r-- | include/cru/ui/controls/Window.h | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/include/cru/ui/controls/Window.h b/include/cru/ui/controls/Window.h index e25694ba..88320219 100644 --- a/include/cru/ui/controls/Window.h +++ b/include/cru/ui/controls/Window.h @@ -13,6 +13,8 @@ namespace cru::ui::controls { class CRU_UI_API Window : public LayoutControl<render::StackLayoutRenderObject> { CRU_DEFINE_CLASS_LOG_TAG("cru::ui::controls::Window") + friend Control; + public: static constexpr std::string_view kControlType = "Window"; @@ -58,7 +60,6 @@ class CRU_UI_API Window void SetOverrideCursor(std::shared_ptr<platform::gui::ICursor> cursor); bool IsInEventHandling(); - void UpdateCursor(); CRU_DEFINE_EVENT(AfterLayout, std::nullptr_t) @@ -104,7 +105,8 @@ class CRU_UI_API Window if (original_sender == nullptr || original_sender == last_receiver) return; std::string log = "Begin dispatching routed event " + - (original_sender->*event_ptr)()->GetName() + ":\n\tTunnel:"; + (original_sender->*event_ptr)()->GetName() + + ":\n\tTunnel:"; Guard logging_guard([&] { log += "\nEnd dispatching routed event " + @@ -112,11 +114,11 @@ class CRU_UI_API Window CRU_LOG_TAG_DEBUG("{}", log); }); - std::vector<Control*> receive_list; + std::vector<ObjectResolver<Control>> receive_list; auto parent = original_sender; while (parent != last_receiver) { - receive_list.push_back(parent); + receive_list.push_back(parent->CreateResolver()); parent = parent->GetParent(); } @@ -124,8 +126,12 @@ class CRU_UI_API Window // tunnel for (auto i = receive_list.crbegin(); i != receive_list.crend(); ++i) { - auto control = *i; + auto control = i->Resolve(); log += " "; + if (!control) { + log += "(deleted)"; + continue; + } log += control->GetDebugId(); EventArgs event_args(control, original_sender, std::forward<Args>(args)...); @@ -140,8 +146,13 @@ class CRU_UI_API Window // bubble if (!handled) { log += "\n\tBubble:"; - for (auto control : receive_list) { + for (auto resolver : receive_list) { + auto control = resolver.Resolve(); log += " "; + if (!control) { + log += "(deleted)"; + continue; + } log += control->GetDebugId(); EventArgs event_args(control, original_sender, std::forward<Args>(args)...); @@ -155,8 +166,13 @@ class CRU_UI_API Window log += "\n\tDirect:"; // direct - for (auto control : receive_list) { + for (auto resolver : receive_list) { + auto control = resolver.Resolve(); log += " "; + if (!control) { + log += "(deleted)"; + continue; + } log += control->GetDebugId(); EventArgs event_args(control, original_sender, std::forward<Args>(args)...); @@ -164,6 +180,9 @@ class CRU_UI_API Window } } + void UpdateCursor(); + void NotifyControlDestroyed(Control* control); + private: int event_handling_count_; |
