fix(Window): 修复主题切换时窗口内容背景未更新 (#496)

This commit is contained in:
chinboy
2026-10-09 22:08:27 +08:00
parent e82b36cfbc
commit d0aa66d0c5
3 changed files with 31 additions and 0 deletions
@@ -2,6 +2,13 @@
本文档记录 Window 控件级设计、API、主题契约、Token 和实现结构的变化。它不替代仓库根目录 `CHANGELOG.md`,也不作为正式版本发布说明。
## 2026-10-09
- Theme
- Keep the opaque surface fallback background synchronized with runtime theme and explicit `TransparencyBackgroundFallback` changes, preserving Avalonia's transparency transitions.
- Lifecycle
- Scope the fallback Border reference to the current template and release it when the Window closes.
## 2026-09-04
- Integration
@@ -227,6 +227,17 @@ Resolve owner ThemeContext
回归验证至少覆盖:根 Dark 主题在 `WindowOpenedEvent` 前的背景、owner 局部 ThemeContext、用户显式背景不被覆盖、关闭后 lease/资源桥释放,以及失败显示的回滚。Headless 测试只能证明 managed 状态顺序;Windows、macOS 和 Linux 的最终首帧必须通过各平台实机显示或录屏验证。
### 7.2 不透明表面的动态 fallback 背景
`WindowTheme` 负责通过 Token 资源更新 `Background` 和 `TransparencyBackgroundFallback`,用户 local value
继续优先。实际透明度为 `None` 时,`PART_TransparencyFallback` 必须同步当前有效的
`TransparencyBackgroundFallback`;透明表面仍由 Avalonia 清空该部件背景。
Avalonia `TopLevel` 在应用模板和透明度变化时以 local value 写入该 Border 的 `Background`,普通
ControlTheme Setter 和 `TemplateBinding` 无法覆盖这条赋值路径。`Window` 因此只补充 fallback 属性变化时
的同步,不新增资源订阅,不参与 Token 解析,也不接管透明度切换。部件引用在模板重套用时替换、关闭时释放;
没有该部件的自定义模板保持自身绘制行为。
## 8. 资源、性能与 AOT 边界
资源和 AOT 约束:
@@ -578,6 +578,7 @@ public partial class Window : AvaloniaWindow,
private readonly WindowCaptionButtonCommand _captionButtonCommand;
private FullscreenPopoverLayer? _fullscreenPopoverLayer;
private WindowResizer? _windowResizer;
private Border? _transparencyFallbackBorder;
private MediaBreakPointIndicator? _mediaBreakPointIndicator;
private CompositeDisposable? _defaultTitleBarBindings;
private Window? _mainWindowLogoFallbackSource;
@@ -910,7 +911,9 @@ public partial class Window : AvaloniaWindow,
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
_transparencyFallbackBorder = null;
base.OnApplyTemplate(e);
_transparencyFallbackBorder = e.NameScope.Find<Border>("PART_TransparencyFallback");
HandleCreateTitleBar();
EnsureWindowsCsdMinimumHeight();
@@ -1513,6 +1516,7 @@ public partial class Window : AvaloniaWindow,
protected override void OnClosed(EventArgs e)
{
_isOpened = false;
_transparencyFallbackBorder = null;
StopMacOsWindowButtonObserver();
if (_titleBar != null)
{
@@ -1649,6 +1653,15 @@ public partial class Window : AvaloniaWindow,
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == TransparencyBackgroundFallbackProperty &&
ActualTransparencyLevel == WindowTransparencyLevel.None &&
_transparencyFallbackBorder is not null)
{
// TopLevel writes this part's Background as a local value when applying the template
// or changing transparency, overriding ControlTheme setters and TemplateBinding.
// Mirror later fallback changes here; TopLevel still owns transparency transitions.
_transparencyFallbackBorder.Background = TransparencyBackgroundFallback;
}
if (change.Property == WindowStateProperty)
{
var (oldState, newState) = change.GetOldAndNewValue<WindowState>();