diff --git a/crates/aether-win32/src/render/chrome.rs b/crates/aether-win32/src/render/chrome.rs index aab4ff2..6b84734 100644 --- a/crates/aether-win32/src/render/chrome.rs +++ b/crates/aether-win32/src/render/chrome.rs @@ -372,6 +372,9 @@ impl EditorState { let width = region.width; let height = region.height; + // 冰冻恢复后图标缓存为空,需先重建几何再绘制 + self.icons.ensure_created_from_target(target); + unsafe { // 标题栏背景 — 玻璃模式下使用半透明暗色 let bg_color = if self.theme.glass_enabled { @@ -1136,6 +1139,9 @@ impl EditorState { let width = region.width; let height = region.height; + // 冰冻恢复后图标缓存为空,需先重建几何再绘制 + self.icons.ensure_created_from_target(target); + unsafe { let bg_color = if self.theme.glass_enabled { self.theme.activity_bar_bg diff --git a/crates/aether-win32/src/window/mouse_handler/mouse_move.rs b/crates/aether-win32/src/window/mouse_handler/mouse_move.rs index a615100..007f6d6 100644 --- a/crates/aether-win32/src/window/mouse_handler/mouse_move.rs +++ b/crates/aether-win32/src/window/mouse_handler/mouse_move.rs @@ -250,8 +250,19 @@ pub(crate) unsafe fn on_mouse_move( if any_hover_changed || tooltip_changed { // 标记 hover 相关脏区域,避免全窗口重绘 let mut st = state.borrow_mut(); - if titlebar_changed || tab_changed { - // 标题栏 + 活动栏区域 + if titlebar_changed { + // 标题栏 hover 变化:标记标题栏区域脏,确保窗控按钮 hover 高亮即时刷新 + let tb = layout.title_bar_region(); + st.dirty_tracker.mark_region( + tb.x, + tb.y, + tb.width, + tb.height, + crate::dirty_rect::DirtyRegionType::TitleBar, + ); + } + if tab_changed { + // 活动栏 + 标签栏区域 let ar = layout.activity_bar_region(); st.dirty_tracker.mark_region( ar.x, diff --git a/crates/aether-win32/src/window/window_messages.rs b/crates/aether-win32/src/window/window_messages.rs index d5e35ce..2113e57 100644 --- a/crates/aether-win32/src/window/window_messages.rs +++ b/crates/aether-win32/src/window/window_messages.rs @@ -747,23 +747,26 @@ pub(crate) unsafe fn on_size(hwnd: HWND, _msg: u32, wparam: WPARAM, _lparam: LPA // 按 hwnd 取状态(而非线程局部活跃状态), // 避免多窗口/启动最大化时把尺寸更新到错误的窗口状态上 if let Some(state) = get_and_set_state(hwnd) { - let mut st = state.borrow_mut(); - st.is_maximized = is_max; - if is_min { - // 最小化:立即进入冰冻态释放内存(AI/Agent 经无头泵保活) - st.power.minimized = true; - st.enter_frozen(); - } else { - st.power.minimized = false; - st.resize(width, height); - // 从最小化恢复:解冻(全量重绘 + 懒重建 D2D 资源) - if st.power.frozen { - st.exit_frozen(); + let was_frozen; + { + let mut st = state.borrow_mut(); + st.is_maximized = is_max; + was_frozen = st.power.frozen && !is_min; + if is_min { + // 最小化:立即进入冰冻态释放内存(AI/Agent 经无头泵保活) + st.power.minimized = true; + st.enter_frozen(); + } else { + st.power.minimized = false; + st.resize(width, height); + // 从最小化恢复:解冻(全量重绘 + 懒重建 D2D 资源) + if st.power.frozen { + st.exit_frozen(); + } } } // 若最大化且用户设置了显示任务栏,调整窗口为工作区大小 - let need_adjust = is_max && st.app_settings.ui.show_taskbar_when_maximized; - drop(st); + let need_adjust = is_max && state.borrow().app_settings.ui.show_taskbar_when_maximized; if need_adjust { use windows::Win32::Graphics::Gdi::{ GetMonitorInfoW, MonitorFromWindow, MONITORINFO, MONITOR_DEFAULTTONEAREST, @@ -790,6 +793,11 @@ pub(crate) unsafe fn on_size(hwnd: HWND, _msg: u32, wparam: WPARAM, _lparam: LPA } if !is_min { invalidate_window(hwnd); + // 从最小化恢复时:同步触发 WM_PAINT 完成首帧渲染, + // 避免 D2D 渲染目标重建期间标题栏按钮等区域短暂空白 + if was_frozen { + let _ = windows::Win32::Graphics::Gdi::UpdateWindow(hwnd); + } } } }