From e05d2de6d6c4bcd360c67d46788a5c8a0bb8533b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E7=8B=84=E9=98=B3?= <2128533242@qq.com> Date: Thu, 13 Aug 2026 09:51:09 +0800 Subject: [PATCH] =?UTF-8?q?fix(render):=20=E4=BF=AE=E5=A4=8D=E5=86=B0?= =?UTF-8?q?=E5=86=BB=E6=81=A2=E5=A4=8D=E5=90=8E=E6=A0=87=E9=A2=98=E6=A0=8F?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E5=92=8C=E6=B4=BB=E5=8A=A8=E6=A0=8F=E5=9B=BE?= =?UTF-8?q?=E6=A0=87=E4=B8=8D=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - mouse_move.rs: 标题栏 hover 变化时标记 TitleBar 脏区域(原合并到 ActivityBar/TabBar 分支中漏掉了标题栏本身) - window_messages.rs: 从最小化恢复时同步触发 UpdateWindow 完成首帧 渲染,避免 D2D 渲染目标重建期间 UI 短暂空白 - chrome.rs: render_title_bar 和 render_activity_bar 入口添加 ensure_created_from_target,冰冻恢复后 icons.clear() 清空了 SVG 几何缓存,需先重建再绘制 --- crates/aether-win32/src/render/chrome.rs | 6 ++++ .../src/window/mouse_handler/mouse_move.rs | 15 ++++++-- .../src/window/window_messages.rs | 36 +++++++++++-------- 3 files changed, 41 insertions(+), 16 deletions(-) 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); + } } } }