From ddcf12231f46206d23557c05b072ba0b65d9ab1d Mon Sep 17 00:00:00 2001 From: wuyangfan <1102042793@qq.com> Date: Mon, 18 May 2026 00:15:20 +0800 Subject: [PATCH] feat(ui): add option to disable menu popup animations (#3737) Expose EnableMenuAnimations in Display settings (defaults to the OS preference). When disabled, menu and submenu popups open instantly without fade animation via SystemParameters.MenuPopupAnimation. --- ILSpy/App.xaml.cs | 2 ++ ILSpy/Options/DisplaySettings.cs | 9 ++++++ ILSpy/Options/DisplaySettingsPanel.xaml | 1 + ILSpy/Properties/Resources.Designer.cs | 9 ++++++ ILSpy/Properties/Resources.resx | 3 ++ ILSpy/Util/MenuPopupAnimationHelper.cs | 41 +++++++++++++++++++++++++ ILSpy/Util/SettingsService.cs | 7 +++++ 7 files changed, 72 insertions(+) create mode 100644 ILSpy/Util/MenuPopupAnimationHelper.cs diff --git a/ILSpy/App.xaml.cs b/ILSpy/App.xaml.cs index 66f81e7a49..f6dce89104 100644 --- a/ILSpy/App.xaml.cs +++ b/ILSpy/App.xaml.cs @@ -29,6 +29,7 @@ using ICSharpCode.ILSpy.AppEnv; using ICSharpCode.ILSpy.AssemblyTree; +using ICSharpCode.ILSpy.Util; using ICSharpCode.ILSpyX.Analyzers; using Medo.Application; @@ -109,6 +110,7 @@ public App() Resources.MergedDictionaries.Add(DataTemplateManager.CreateDynamicDataTemplates(ExportProvider)); var sessionSettings = settingsService.SessionSettings; + MenuPopupAnimationHelper.Apply(settingsService.DisplaySettings.EnableMenuAnimations); ThemeManager.Current.Theme = sessionSettings.Theme; if (!string.IsNullOrEmpty(sessionSettings.CurrentCulture)) { diff --git a/ILSpy/Options/DisplaySettings.cs b/ILSpy/Options/DisplaySettings.cs index a65748446e..bbbf2499da 100644 --- a/ILSpy/Options/DisplaySettings.cs +++ b/ILSpy/Options/DisplaySettings.cs @@ -19,6 +19,7 @@ using System.Windows.Media; using System.Xml.Linq; +using ICSharpCode.ILSpy.Util; using ICSharpCode.ILSpyX.Settings; using TomsToolbox.Wpf; @@ -156,6 +157,12 @@ public bool EnableSmoothScrolling { set => SetProperty(ref enableSmoothScrolling, value); } + private bool enableMenuAnimations; + public bool EnableMenuAnimations { + get => enableMenuAnimations; + set => SetProperty(ref enableMenuAnimations, value); + } + private bool decodeCustomAttributeBlobs; public bool DecodeCustomAttributeBlobs { get => decodeCustomAttributeBlobs; @@ -187,6 +194,7 @@ public void LoadFromXml(XElement section) ShowRawOffsetsAndBytesBeforeInstruction = (bool?)section.Attribute("ShowRawOffsetsAndBytesBeforeInstruction") ?? false; StyleWindowTitleBar = (bool?)section.Attribute("StyleWindowTitleBar") ?? false; EnableSmoothScrolling = (bool?)section.Attribute("EnableSmoothScrolling") ?? true; + EnableMenuAnimations = (bool?)section.Attribute("EnableMenuAnimations") ?? MenuPopupAnimationHelper.DefaultFromSystem(); DecodeCustomAttributeBlobs = (bool?)section.Attribute("DecodeCustomAttributeBlobs") ?? false; } @@ -215,6 +223,7 @@ public XElement SaveToXml() section.SetAttributeValue("ShowRawOffsetsAndBytesBeforeInstruction", ShowRawOffsetsAndBytesBeforeInstruction); section.SetAttributeValue("StyleWindowTitleBar", StyleWindowTitleBar); section.SetAttributeValue("EnableSmoothScrolling", EnableSmoothScrolling); + section.SetAttributeValue("EnableMenuAnimations", EnableMenuAnimations); section.SetAttributeValue("DecodeCustomAttributeBlobs", DecodeCustomAttributeBlobs); return section; diff --git a/ILSpy/Options/DisplaySettingsPanel.xaml b/ILSpy/Options/DisplaySettingsPanel.xaml index 58c7ae3161..ffc5e3bd2e 100644 --- a/ILSpy/Options/DisplaySettingsPanel.xaml +++ b/ILSpy/Options/DisplaySettingsPanel.xaml @@ -80,6 +80,7 @@ + diff --git a/ILSpy/Properties/Resources.Designer.cs b/ILSpy/Properties/Resources.Designer.cs index b96523d852..1dfcf69de2 100644 --- a/ILSpy/Properties/Resources.Designer.cs +++ b/ILSpy/Properties/Resources.Designer.cs @@ -1830,6 +1830,15 @@ public static string EnableSmoothScrolling { } } + /// + /// Looks up a localized string similar to Enable menu animations. + /// + public static string EnableMenuAnimations { + get { + return ResourceManager.GetString("EnableMenuAnimations", resourceCulture); + } + } + /// /// Looks up a localized string similar to Enable word wrap. /// diff --git a/ILSpy/Properties/Resources.resx b/ILSpy/Properties/Resources.resx index aa5fff5fd0..c7bfd90af7 100644 --- a/ILSpy/Properties/Resources.resx +++ b/ILSpy/Properties/Resources.resx @@ -627,6 +627,9 @@ Are you sure you want to continue? Enable smooth scrolling + + Enable menu animations + Enable word wrap diff --git a/ILSpy/Util/MenuPopupAnimationHelper.cs b/ILSpy/Util/MenuPopupAnimationHelper.cs new file mode 100644 index 0000000000..d7d54cc3e1 --- /dev/null +++ b/ILSpy/Util/MenuPopupAnimationHelper.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2026 ILSpy contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System.Windows; +using System.Windows.Controls.Primitives; + +namespace ICSharpCode.ILSpy.Util +{ + internal static class MenuPopupAnimationHelper + { + private static readonly PopupAnimation SystemMenuPopupAnimation = SystemParameters.MenuPopupAnimation; + + public static bool DefaultFromSystem() + { + return SystemMenuPopupAnimation != PopupAnimation.None; + } + + public static void Apply(bool enableMenuAnimations) + { + var animation = enableMenuAnimations ? SystemMenuPopupAnimation : PopupAnimation.None; + SystemParameters.OverrideMetadata( + SystemParameters.MenuPopupAnimationKey, + new FrameworkPropertyMetadata(animation)); + } + } +} diff --git a/ILSpy/Util/SettingsService.cs b/ILSpy/Util/SettingsService.cs index 289d097464..d2b0493e83 100644 --- a/ILSpy/Util/SettingsService.cs +++ b/ILSpy/Util/SettingsService.cs @@ -99,6 +99,7 @@ public void Reload() finally { reloading = false; + MenuPopupAnimationHelper.Apply(DisplaySettings.EnableMenuAnimations); } } @@ -129,6 +130,12 @@ protected override void Section_PropertyChanged(object? sender, PropertyChangedE assemblyListManager.UseDebugSymbols = decompilerSettings.UseDebugSymbols; } + if (sender is DisplaySettings displaySettings + && e.PropertyName == nameof(DisplaySettings.EnableMenuAnimations)) + { + MenuPopupAnimationHelper.Apply(displaySettings.EnableMenuAnimations); + } + MessageBus.Send(sender, new SettingsChangedEventArgs(e)); }