mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-02-14 01:07:42 +01:00
fix(border): release resources before destroying window to prevent access violations
When a border is destroyed, the main thread was forcefully releasing D2D resources, while the border window thread might still be trying to use them in its message loop. Releasing the RenderTarget on one thread while another is calling EndDraw on it leads to a use-after-free scenario or invalid state for the COM object, resulting in the crash. This commit applies a fix that moves the resource cleanup logic from the main thread to the window thread. Now, resources are only released during the WM_DESTROY message processing, which guarantees synchronization with other window messages like WM_PAINT.
This commit is contained in:
@@ -548,7 +548,12 @@ impl Border {
|
||||
LRESULT(0)
|
||||
}
|
||||
WM_DESTROY => {
|
||||
SetWindowLongPtrW(window, GWLP_USERDATA, 0);
|
||||
let border_pointer: *mut Border = GetWindowLongPtrW(window, GWLP_USERDATA) as _;
|
||||
if !border_pointer.is_null() {
|
||||
(*border_pointer).render_target = None;
|
||||
(*border_pointer).brushes.clear();
|
||||
SetWindowLongPtrW(window, GWLP_USERDATA, 0);
|
||||
}
|
||||
PostQuitMessage(0);
|
||||
LRESULT(0)
|
||||
}
|
||||
|
||||
@@ -767,12 +767,6 @@ fn remove_border(
|
||||
fn destroy_border(border: Box<Border>) -> color_eyre::Result<()> {
|
||||
let raw_pointer = Box::into_raw(border);
|
||||
unsafe {
|
||||
// release d2d resources **BEFORE** destroying window
|
||||
// this drops render_target and brushes while HWND is still valid
|
||||
// prevents EndDraw() from accessing freed HWND resources
|
||||
(*raw_pointer).render_target = None;
|
||||
(*raw_pointer).brushes.clear();
|
||||
|
||||
// Now safe to destroy window
|
||||
(*raw_pointer).destroy()?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user