Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AutomaticUpdateVersionControl.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.8.0.0
1.8.0.5
36 changes: 16 additions & 20 deletions Ink Canvas/InkCanvasForClass.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@
<None Include="app.manifest" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Costura.Fody" Version="6.0.0">
<PackageReference Include="Costura.Fody" Version="6.2.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="gong-wpf-dragdrop" Version="4.0.0" />
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.0.131" />
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.4.1" />
<PackageReference Include="iNKORE.UI.WPF.Modern" Version="0.10.2.1" />
<PackageReference Include="iNKORE.UI.WPF" Version="1.2.8" />
<PackageReference Include="MdXaml" Version="1.27.0" />
Expand All @@ -137,17 +137,17 @@
<PackageReference Include="Microsoft.International.Converters.PinYinConverter" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.ComponentModel.Composition" Version="10.0.5" />
<PackageReference Include="System.Composition.AttributedModel" Version="10.0.5" />
<PackageReference Include="System.ComponentModel.Composition" Version="10.0.11" />
<PackageReference Include="System.Composition.AttributedModel" Version="10.0.11" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.Management" Version="6.0.2" />
<PackageReference Include="System.Management" Version="10.0.11" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<!-- UInk 1.0 规范:主文件为 MessagePack 对象流(Header/HeaderExtension/Canvas/Ink/Shape/Media),由 UInk/ 下的读写器使用 -->
<PackageReference Include="MessagePack" Version="3.1.8" />
<PackageReference Include="NHotkey.Wpf" Version="4.0.0" />
<PackageReference Include="OSVersionExt" Version="4.1.0" />
<!-- PDFsharp 6.1.x 是最后一个以 net6.0 为目标框架的版本;用于插件「背景 + 墨迹」导出 PDF -->
<PackageReference Include="PDFsharp" Version="6.1.1" />
<PackageReference Include="PDFsharp" Version="6.2.4" />
<!-- AForge.Imaging / AForge.Math 仅用于照片校正(Grayscale/CannyEdgeDetector/BlobCounter/QuadrilateralTransformation);摄像头采集已切换到 DirectShow(DirectShowLib) -->
<PackageReference Include="AForge.Imaging" Version="2.2.5" />
<PackageReference Include="AForge.Math" Version="2.2.5" />
Expand All @@ -156,12 +156,12 @@
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.13.0.20260627" />

<PackageReference Include="WebDav.Client" Version="2.9.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Vortice.Direct2D1" Version="3.2.0" />
<PackageReference Include="Vortice.Direct3D11" Version="3.2.0" />
<PackageReference Include="Vortice.DirectComposition" Version="3.2.0" />
<PackageReference Include="Vortice.DXGI" Version="3.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.11" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
<PackageReference Include="Vortice.Direct2D1" Version="3.8.3" />
<PackageReference Include="Vortice.Direct3D11" Version="3.8.3" />
<PackageReference Include="Vortice.DirectComposition" Version="3.8.3" />
<PackageReference Include="Vortice.DXGI" Version="3.8.3" />
<!-- 视频展台:DirectShow + VMR9 Renderless + D3DImage 零拷贝 GPU 渲染 -->
<PackageReference Include="WPFMediaKit" Version="3.0.1" />
</ItemGroup>
Expand Down Expand Up @@ -619,20 +619,16 @@
CI 的 AnyCPU(=x64 产物)/x86 构建都能带上辅助 exe;单文件发布走 Publish 分支。 -->
<Target Name="CopyLiquidGlassMagHost" AfterTargets="Build" Condition="'$(PublishSingleFile)' != 'true'">
<ItemGroup>
<LiquidGlassMagHostFiles Include="$(MSBuildProjectDirectory)\..\InkCanvas.LiquidGlassMagHost\bin\$(Platform)\$(Configuration)\$(TargetFramework)\InkCanvas.LiquidGlassMagHost.*"
Condition="'$(Platform)' != 'AnyCPU'" />
<LiquidGlassMagHostFiles Include="$(MSBuildProjectDirectory)\..\InkCanvas.LiquidGlassMagHost\bin\$(Configuration)\$(TargetFramework)\InkCanvas.LiquidGlassMagHost.*"
Condition="'$(Platform)' == 'AnyCPU'" />
<LiquidGlassMagHostFiles Include="$(MSBuildProjectDirectory)\..\InkCanvas.LiquidGlassMagHost\bin\$(Platform)\$(Configuration)\$(TargetFramework)\InkCanvas.LiquidGlassMagHost.*" Condition="'$(Platform)' != 'AnyCPU'" />
<LiquidGlassMagHostFiles Include="$(MSBuildProjectDirectory)\..\InkCanvas.LiquidGlassMagHost\bin\$(Configuration)\$(TargetFramework)\InkCanvas.LiquidGlassMagHost.*" Condition="'$(Platform)' == 'AnyCPU'" />
</ItemGroup>
<Copy SourceFiles="@(LiquidGlassMagHostFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" Condition="'@(LiquidGlassMagHostFiles)' != ''" />
</Target>

<Target Name="CopyLiquidGlassMagHostToPublishDirectory" AfterTargets="Publish" Condition="'$(PublishSingleFile)' == 'true'">
<ItemGroup>
<LiquidGlassMagHostPublishFiles Include="$(MSBuildProjectDirectory)\..\InkCanvas.LiquidGlassMagHost\bin\$(Platform)\$(Configuration)\$(TargetFramework)\InkCanvas.LiquidGlassMagHost.*"
Condition="'$(Platform)' != 'AnyCPU'" />
<LiquidGlassMagHostPublishFiles Include="$(MSBuildProjectDirectory)\..\InkCanvas.LiquidGlassMagHost\bin\$(Configuration)\$(TargetFramework)\InkCanvas.LiquidGlassMagHost.*"
Condition="'$(Platform)' == 'AnyCPU'" />
<LiquidGlassMagHostPublishFiles Include="$(MSBuildProjectDirectory)\..\InkCanvas.LiquidGlassMagHost\bin\$(Platform)\$(Configuration)\$(TargetFramework)\InkCanvas.LiquidGlassMagHost.*" Condition="'$(Platform)' != 'AnyCPU'" />
<LiquidGlassMagHostPublishFiles Include="$(MSBuildProjectDirectory)\..\InkCanvas.LiquidGlassMagHost\bin\$(Configuration)\$(TargetFramework)\InkCanvas.LiquidGlassMagHost.*" Condition="'$(Platform)' == 'AnyCPU'" />
</ItemGroup>
<Copy SourceFiles="@(LiquidGlassMagHostPublishFiles)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="true" Condition="'@(LiquidGlassMagHostPublishFiles)' != ''" />
</Target>
Expand Down
12 changes: 11 additions & 1 deletion Ink Canvas/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1564,7 +1564,8 @@ private void Window_Loaded(object sender, RoutedEventArgs e)
SetTheme("Dark");
break;
case 2: // 跟随系统
if (ThemeHelper.IsSystemThemeLight())
_lastFollowedSystemThemeLight = ThemeHelper.IsSystemThemeLight();
if (_lastFollowedSystemThemeLight.Value)
{
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
SetTheme("Light");
Expand Down Expand Up @@ -1946,6 +1947,8 @@ private void Window_Closed(object sender, EventArgs e)
{
RealtimeInkFrameScheduler.Clear();
SystemEvents.DisplaySettingsChanged -= SystemEventsOnDisplaySettingsChanged;
SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged;
_systemThemeRetryTimer?.Stop();
// 玻璃浮动栏刻意不设 Owner,必须显式关闭,否则残留窗口会挡住进程退出
HideLiquidGlassBar();

Expand Down Expand Up @@ -3616,26 +3619,33 @@ internal void ApplyTheme(int themeIndex)
{
try
{
// 手动切换主题时基线失效,运行时系统深浅色切换需要重新建立
_lastFollowedSystemThemeLight = null;

@augmentcode augmentcode Bot Sep 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Ink Canvas/MainWindow.xaml.cs:3623] When a running instance changes from a fixed theme to Follow system, this clears the baseline and case 2 never establishes it. CheckSystemThemeSwitch then treats the first subsequent OS light/dark transition solely as baseline initialization and returns, so the application misses that transition and remains on the prior theme until another system preference event occurs.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


switch (themeIndex)
{
case 0: // 浅色主题
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
SetTheme("Light", true);
// 浅色主题下设置浮动栏为完全不透明
ViewboxFloatingBar.Opacity = 1.0;
break;
case 1: // 深色主题
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark;
SetTheme("Dark", true);
// 深色主题下设置浮动栏为完全不透明
ViewboxFloatingBar.Opacity = 1.0;
break;
case 2: // 跟随系统
if (ThemeHelper.IsSystemThemeLight())
{
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
SetTheme("Light", true);
ViewboxFloatingBar.Opacity = 1.0;
}
else
{
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark;
SetTheme("Dark", true);
ViewboxFloatingBar.Opacity = 1.0;
}
Expand Down
84 changes: 72 additions & 12 deletions Ink Canvas/MainWindow_cs/MW_AutoTheme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,22 +282,82 @@ void SetFloatingBarButtonBrush(ToolbarImageButton btn)
SetFloatingBarButtonBrush(Exit_Icon);
}

// 跟随系统模式下最近一次应用的系统深浅色;null 表示尚未建立基线
private bool? _lastFollowedSystemThemeLight;
private DispatcherTimer _systemThemeRetryTimer;
private int _systemThemeRetryCount;
private const int SystemThemeRetryLimit = 10;
private static readonly TimeSpan SystemThemeRetryInterval = TimeSpan.FromMilliseconds(300);

private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
switch (Settings.Appearance.Theme)
// 只关心外观类偏好变化;键盘/鼠标/电源等类别与主题无关
if (e.Category != UserPreferenceCategory.General) return;
// SystemEvents 的事件不保证在 UI 线程触发,统一调度回 UI 线程
Dispatcher.BeginInvoke(new Action(CheckSystemThemeSwitch));
}

/// <summary>
/// 系统深浅色切换检测:AppsUseLightTheme 注册表的写入可能晚于系统广播,
/// 首次读到旧值时延迟重试,确认真正翻转后再走完整主题管线。
/// </summary>
private void CheckSystemThemeSwitch()
{
// 仅「跟随系统」需要响应;固定主题重复应用反而会打断黑板/PPT 模式的深色覆盖
if (Settings.Appearance.Theme != 2) return;

bool systemLight = ThemeHelper.IsSystemThemeLight();

if (_lastFollowedSystemThemeLight == null)
{
case 0:
SetTheme(ThemeLight);
break;
case 1:
SetTheme(ThemeDark);
break;
case 2:
// 与 IsCurrentThemeDark / GetEffectiveTheme / 浮动栏一致,统一读 AppsUseLightTheme,
// 否则 SystemUsesLightTheme 与 AppsUseLightTheme 可独立取值时主题会混搭
SetTheme(ThemeHelper.IsSystemThemeLight() ? ThemeLight : ThemeDark);
break;
// 首次只建立基线,不重复应用当前主题
_lastFollowedSystemThemeLight = systemLight;
return;
}

if (systemLight == _lastFollowedSystemThemeLight)
{
// 广播先于注册表写入的情况:延迟重读,确认值确实没变再放弃
StartSystemThemeRetry();
return;
}

StopSystemThemeRetry();
_lastFollowedSystemThemeLight = systemLight;
ApplyFollowedSystemTheme(systemLight);
}

private void StartSystemThemeRetry()
{
if (_systemThemeRetryCount >= SystemThemeRetryLimit) return;

_systemThemeRetryCount++;
if (_systemThemeRetryTimer == null)
{
_systemThemeRetryTimer = new DispatcherTimer { Interval = SystemThemeRetryInterval };
_systemThemeRetryTimer.Tick += (s, args) =>
{
_systemThemeRetryTimer.Stop();
CheckSystemThemeSwitch();
};
}
_systemThemeRetryTimer.Start();
}

private void StopSystemThemeRetry()
{
_systemThemeRetryTimer?.Stop();
_systemThemeRetryCount = 0;
}

private void ApplyFollowedSystemTheme(bool systemLight)
{
// 应用级主题(App 级 ThemeResources / Default 主题控件与 Popup)必须与
// 窗口级 RequestedTheme 同步翻转,否则切换后会出现深浅混搭
ThemeManager.Current.ApplicationTheme = systemLight ? ApplicationTheme.Light : ApplicationTheme.Dark;
SetTheme(systemLight ? ThemeLight : ThemeDark, autoSwitchIcon: true);
ViewboxFloatingBar.Opacity = 1.0;
RefreshNotificationColors();
}

private void AutoSwitchFloatingBarIconForTheme(string theme)
Expand Down
11 changes: 2 additions & 9 deletions Ink Canvas/Windows/SettingsViews/Pages/ToolbarPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ private void ListViewItem_Loaded(object sender, RoutedEventArgs e)
private bool _isLoaded;
private bool _suppressConfigChange;
private bool _suppressSave;
private bool _suppressSelectedEntrySync;

public ObservableCollection<ToolbarComponentEntry> AddedComponents { get; } = new();
public ObservableCollection<ToolbarComponentEntry> GroupChildren { get; } = new();
Expand All @@ -58,7 +57,6 @@ public ToolbarComponentEntry SelectedEntry
private static void OnSelectedEntryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var page = (ToolbarPage)d;
if (page._suppressSelectedEntrySync) return;
page.SelectedGroupChild = null;
// 选中分组时自动展开"分组内组件"面板;选中非分组时不自动收起(由关闭按钮控制)
if (page.SelectedEntry?.IsGroup == true)
Expand Down Expand Up @@ -92,13 +90,8 @@ public ToolbarComponentEntry SelectedGroupChild
private static void OnSelectedGroupChildChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var page = (ToolbarPage)d;
// 选中分组内组件时,取消"已添加组件"列表的选中,避免两处同时高亮
if (page.SelectedGroupChild != null && page.SelectedEntry != null)
{
page._suppressSelectedEntrySync = true;
page.AddedList.SelectedItem = null;
page._suppressSelectedEntrySync = false;
}
// 分组的选中是"分组内组件"面板的数据来源,选中分组内组件时保留分组选中,
// 否则 SyncGroupChildrenBack 会因 SelectedEntry 为空而不回写,分组编辑全部丢失
page.UpdatePropertiesPanel();
}

Expand Down
Loading