From 34b7630a15986871fca98e4f8752311cd8688808 Mon Sep 17 00:00:00 2001 From: SakuraStar Date: Sun, 19 Apr 2026 12:35:49 +0800 Subject: [PATCH 1/2] feat: enhance environment filter with multiple profiles and desktop independent toggle --- src/BASpark.csproj | 1 + src/ConfigManager.cs | 112 +++++++++----- src/ControlPanelWindow.xaml | 118 ++++++++++++--- src/ControlPanelWindow.xaml.cs | 269 +++++++++++++++++++++++---------- src/MainWindow.xaml.cs | 31 ++-- 5 files changed, 386 insertions(+), 145 deletions(-) diff --git a/src/BASpark.csproj b/src/BASpark.csproj index 04b4b5e..ebb8860 100644 --- a/src/BASpark.csproj +++ b/src/BASpark.csproj @@ -8,6 +8,7 @@ enable true true + true app.ico 1.2.0 diff --git a/src/ConfigManager.cs b/src/ConfigManager.cs index 44f3837..7d43d1c 100644 --- a/src/ConfigManager.cs +++ b/src/ConfigManager.cs @@ -12,6 +12,14 @@ public enum ProcessFilterModeOption Whitelist } + public class FilterProfile + { + public string Id { get; set; } = Guid.NewGuid().ToString(); + public string Name { get; set; } = "新配置组"; + public ProcessFilterModeOption Mode { get; set; } = ProcessFilterModeOption.Blacklist; + public List Processes { get; set; } = new List(); + } + public static class ConfigManager { private const string RegPath = @"Software\BASpark"; @@ -32,10 +40,13 @@ public static class ConfigManager public static int TrailRefreshRate { get; set; } = 40; public static bool EnableEnvironmentFilter { get; set; } = false; public static bool HideInFullscreen { get; set; } = true; - public static ProcessFilterModeOption ProcessFilterMode { get; set; } = ProcessFilterModeOption.Disabled; - public static string ProcessFilterList { get; set; } = ""; + public static bool ShowEffectOnDesktop { get; set; } = true; + public static string FilterProfiles { get; set; } = ""; + public static string ActiveProfileId { get; set; } = ""; public static bool IsTouchscreenMode { get; set; } = false; + private static List _profiles = new List(); + public static void Load() { try @@ -61,23 +72,73 @@ public static void Load() TrailRefreshRate = Math.Clamp(Convert.ToInt32(key.GetValue("TrailRefreshRate", 40)), 10, 240); EnableEnvironmentFilter = Convert.ToBoolean(key.GetValue("EnableEnvironmentFilter", false)); HideInFullscreen = Convert.ToBoolean(key.GetValue("HideInFullscreen", true)); + ShowEffectOnDesktop = Convert.ToBoolean(key.GetValue("ShowEffectOnDesktop", true)); IsTouchscreenMode = Convert.ToBoolean(key.GetValue("IsTouchscreenMode", false)); - string processFilterModeRaw = key.GetValue("ProcessFilterMode", ProcessFilterModeOption.Disabled.ToString())?.ToString() - ?? ProcessFilterModeOption.Disabled.ToString(); - if (!Enum.TryParse(processFilterModeRaw, true, out ProcessFilterModeOption processFilterMode)) + FilterProfiles = key.GetValue("FilterProfiles", "")?.ToString() ?? ""; + ActiveProfileId = key.GetValue("ActiveProfileId", "")?.ToString() ?? ""; + + if (!string.IsNullOrEmpty(FilterProfiles)) + { + try + { + _profiles = System.Text.Json.JsonSerializer.Deserialize>(FilterProfiles) ?? new List(); + } + catch { _profiles = new List(); } + } + + // 向后兼容处理 + if (_profiles.Count == 0) { - processFilterMode = ProcessFilterModeOption.Disabled; + string processFilterModeRaw = key.GetValue("ProcessFilterMode", "Disabled")?.ToString() ?? "Disabled"; + ProcessFilterModeOption oldMode; + if (!Enum.TryParse(processFilterModeRaw, true, out oldMode)) + { + oldMode = ProcessFilterModeOption.Disabled; + } + string oldListRaw = key.GetValue("ProcessFilterList", "")?.ToString() ?? ""; + var oldList = oldListRaw + .Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + .Select(s => s.ToLowerInvariant()) + .Distinct() + .ToList(); + + var defaultProfile = new FilterProfile + { + Name = "默认配置", + Mode = oldMode == ProcessFilterModeOption.Disabled ? ProcessFilterModeOption.Blacklist : oldMode, + Processes = oldList + }; + _profiles.Add(defaultProfile); + ActiveProfileId = defaultProfile.Id; } - ProcessFilterMode = processFilterMode; - ProcessFilterList = NormalizeProcessFilterList(key.GetValue("ProcessFilterList", "")?.ToString() ?? ""); + if (string.IsNullOrEmpty(ActiveProfileId) && _profiles.Count > 0) + { + ActiveProfileId = _profiles[0].Id; + } } } } catch { } } + public static List GetProfiles() => _profiles; + + public static FilterProfile? GetActiveProfile() + { + return _profiles.FirstOrDefault(p => p.Id == ActiveProfileId) ?? _profiles.FirstOrDefault(); + } + + public static void SaveProfiles(List profiles, string activeId) + { + _profiles = profiles; + ActiveProfileId = activeId; + string json = System.Text.Json.JsonSerializer.Serialize(_profiles); + Save("FilterProfiles", json); + Save("ActiveProfileId", activeId); + } + public static void Save(string name, object value) { try @@ -116,34 +177,12 @@ public static void Save(string name, object value) catch { } } - public static string NormalizeProcessFilterList(string rawValue) - { - if (string.IsNullOrWhiteSpace(rawValue)) - { - return string.Empty; - } - - var normalizedLines = rawValue - .Replace("\r\n", "\n") - .Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) - .Select(line => line.Trim().ToLowerInvariant()) - .Where(line => !string.IsNullOrWhiteSpace(line)) - .Distinct(StringComparer.OrdinalIgnoreCase); - - return string.Join(Environment.NewLine, normalizedLines); - } - public static IReadOnlySet GetProcessFilterEntries() { - string normalized = NormalizeProcessFilterList(ProcessFilterList); - if (string.IsNullOrEmpty(normalized)) - { - return new HashSet(StringComparer.OrdinalIgnoreCase); - } + var profile = GetActiveProfile(); + if (profile == null) return new HashSet(StringComparer.OrdinalIgnoreCase); - return normalized - .Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) - .ToHashSet(StringComparer.OrdinalIgnoreCase); + return profile.Processes.ToHashSet(StringComparer.OrdinalIgnoreCase); } public static void ResetAndClear() @@ -152,7 +191,6 @@ public static void ResetAndClear() { Registry.CurrentUser.DeleteSubKeyTree(RegPath, false); - // 适配 264100 版本之前的配置存储逻辑 string oldJson = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json"); if (System.IO.File.Exists(oldJson)) { @@ -175,8 +213,10 @@ public static void ResetAndClear() TrailRefreshRate = 40; EnableEnvironmentFilter = false; HideInFullscreen = true; - ProcessFilterMode = ProcessFilterModeOption.Disabled; - ProcessFilterList = ""; + ShowEffectOnDesktop = true; + FilterProfiles = ""; + ActiveProfileId = ""; + _profiles.Clear(); IsTouchscreenMode = false; } catch { } diff --git a/src/ControlPanelWindow.xaml b/src/ControlPanelWindow.xaml index 1273eab..946a3dc 100644 --- a/src/ControlPanelWindow.xaml +++ b/src/ControlPanelWindow.xaml @@ -313,40 +313,73 @@ - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + - - + + - - - - - - - - - - - - - @@ -395,5 +428,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ControlPanelWindow.xaml.cs b/src/ControlPanelWindow.xaml.cs index 132b89e..7176e53 100644 --- a/src/ControlPanelWindow.xaml.cs +++ b/src/ControlPanelWindow.xaml.cs @@ -34,16 +34,17 @@ public partial class ControlPanelWindow : Window private DispatcherTimer _noticeTimer; private bool _isCheckingUpdate = false; - public ObservableCollection ProcessList { get; set; } = new ObservableCollection(); + public ObservableCollection Profiles { get; set; } = new ObservableCollection(); + public ObservableCollection CurrentProfileProcesses { get; set; } = new ObservableCollection(); + public ObservableCollection RunningProcessList { get; set; } = new ObservableCollection(); public ControlPanelWindow() { InitializeComponent(); - if (ListProcessSelection != null) - { - ListProcessSelection.ItemsSource = ProcessList; - } + ComboProfiles.ItemsSource = Profiles; + ListConfiguredProcesses.ItemsSource = CurrentProfileProcesses; + ListRunningProcesses.ItemsSource = RunningProcessList; LoadVersion(); LoadSettings(); @@ -88,10 +89,10 @@ private void TextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) if (textBox != null) { System.Windows.Input.Keyboard.ClearFocus(); - var binding = System.Windows.Data.BindingOperations.GetBindingExpression(textBox, System.Windows.Controls.TextBox.TextProperty); - binding?.UpdateSource(); + var binding = System.Windows.Data.BindingOperations.GetBindingExpression(textBox, System.Windows.Controls.TextBox.TextProperty); + binding?.UpdateSource(); } - e.Handled = true; + e.Handled = true; } } @@ -289,15 +290,9 @@ private void RefreshTimer_Tick(object? sender, EventArgs e) } } - private void RefreshProcessList_Click(object sender, RoutedEventArgs e) - { - RefreshProcessList(); - } - - private void RefreshProcessList() + private void RefreshRunningProcessList() { - var currentlySelected = ProcessList.Where(p => p.IsSelected).Select(p => p.ProcessName).ToList(); - ProcessList.Clear(); + RunningProcessList.Clear(); try { var processes = Process.GetProcesses() @@ -307,7 +302,7 @@ private void RefreshProcessList() foreach (var p in processes) { string pName = p.ProcessName + ".exe"; - if (ProcessList.Any(item => item.ProcessName.Equals(pName, StringComparison.OrdinalIgnoreCase))) continue; + if (RunningProcessList.Any(item => item.ProcessName.Equals(pName, StringComparison.OrdinalIgnoreCase))) continue; string dName = pName; try @@ -317,21 +312,21 @@ private void RefreshProcessList() } catch { } - ProcessList.Add(new ProcessItem + RunningProcessList.Add(new ProcessItem { DisplayName = dName, ProcessName = pName, - IsSelected = currentlySelected.Contains(pName, StringComparer.OrdinalIgnoreCase) + IsSelected = false }); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } - private void SearchProcess_TextChanged(object sender, TextChangedEventArgs e) + private void SearchRunningProcess_TextChanged(object sender, TextChangedEventArgs e) { string? filter = (sender as System.Windows.Controls.TextBox)?.Text; - ICollectionView view = CollectionViewSource.GetDefaultView(ProcessList); + ICollectionView view = CollectionViewSource.GetDefaultView(RunningProcessList); if (view == null) return; if (string.IsNullOrWhiteSpace(filter)) @@ -361,29 +356,15 @@ private void LoadSettings() CheckAlwaysTrailEffectSwitch.IsChecked = ConfigManager.EnableAlwaysTrailEffect; CheckEnvironmentFilter.IsChecked = ConfigManager.EnableEnvironmentFilter; CheckHideInFullscreen.IsChecked = ConfigManager.HideInFullscreen; + CheckShowEffectOnDesktop.IsChecked = ConfigManager.ShowEffectOnDesktop; CheckRunAsAdmin.IsChecked = ConfigManager.RunAsAdmin; CheckTouchscreenMode.IsChecked = ConfigManager.IsTouchscreenMode; - SelectProcessFilterMode(ConfigManager.ProcessFilterMode); - - string savedList = ConfigManager.ProcessFilterList ?? ""; - var savedNames = savedList.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries) - .Select(s => s.Trim()).ToList(); + Profiles.Clear(); + foreach (var p in ConfigManager.GetProfiles()) Profiles.Add(p); - RefreshProcessList(); - - foreach (var name in savedNames) - { - var existing = ProcessList.FirstOrDefault(p => p.ProcessName.Equals(name, StringComparison.OrdinalIgnoreCase)); - if (existing == null) - { - ProcessList.Insert(0, new ProcessItem { DisplayName = name, ProcessName = name, IsSelected = true }); - } - else - { - existing.IsSelected = true; - } - } + var active = ConfigManager.GetActiveProfile(); + ComboProfiles.SelectedItem = active; UpdateColorPreview(ConfigManager.ParticleColor); UpdateStartSilentInterlock(); @@ -393,7 +374,6 @@ private void LoadSettings() SliderOpacity.Value = ConfigManager.EffectOpacity * 100; SliderSpeed.Value = ConfigManager.EffectSpeed; SliderTrailRefresh.Value = ConfigManager.TrailRefreshRate; - UpdateEffectValueTexts(); } private void CheckAutoStart_Changed(object sender, RoutedEventArgs e) @@ -427,6 +407,10 @@ private void EnvironmentFilterSetting_Changed(object sender, RoutedEventArgs e) private void ProcessFilterMode_Changed(object sender, SelectionChangedEventArgs e) { if (!IsLoaded) return; + if (ComboProfiles.SelectedItem is FilterProfile active) + { + active.Mode = GetSelectedProcessFilterMode(); + } UpdateEnvironmentFilterInterlock(); } @@ -437,13 +421,16 @@ private void UpdateEnvironmentFilterInterlock() bool processFilterEnabled = environmentFilterEnabled && selectedMode != ProcessFilterModeOption.Disabled; CheckHideInFullscreen.IsEnabled = environmentFilterEnabled; + CheckShowEffectOnDesktop.IsEnabled = environmentFilterEnabled; + ComboProfiles.IsEnabled = environmentFilterEnabled; ComboProcessFilterMode.IsEnabled = environmentFilterEnabled; - if (ListProcessSelection != null) + if (ListConfiguredProcesses != null) { - ListProcessSelection.IsEnabled = processFilterEnabled; - ListProcessSelection.Opacity = processFilterEnabled ? 1.0 : 0.65; + ListConfiguredProcesses.IsEnabled = processFilterEnabled; + ListConfiguredProcesses.Opacity = processFilterEnabled ? 1.0 : 0.65; } + ManualProcessInput.IsEnabled = processFilterEnabled; } private void SelectProcessFilterMode(ProcessFilterModeOption mode) @@ -465,13 +452,36 @@ private ProcessFilterModeOption GetSelectedProcessFilterMode() return ProcessFilterModeOption.Disabled; } - private void UpdateEffectValueTexts() + private void Tab_Click(object sender, RoutedEventArgs e) { + if (PageWelcome == null) return; + PageWelcome.Visibility = Visibility.Collapsed; + PageSettings.Visibility = Visibility.Collapsed; + PageAbout.Visibility = Visibility.Collapsed; + + if (TabWelcome.IsChecked == true) PageWelcome.Visibility = Visibility.Visible; + else if (TabSettings.IsChecked == true) PageSettings.Visibility = Visibility.Visible; + else if (TabAbout.IsChecked == true) PageAbout.Visibility = Visibility.Visible; } - private void EffectSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + private void PickColor_Click(object sender, RoutedEventArgs e) { - if (!IsLoaded) return; + using var dialog = new System.Windows.Forms.ColorDialog(); + dialog.FullOpen = true; + try + { + var parts = ConfigManager.ParticleColor.Split(','); + dialog.Color = System.Drawing.Color.FromArgb( + byte.Parse(parts[0]), byte.Parse(parts[1]), byte.Parse(parts[2])); + } + catch { } + + if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + string newColor = $"{dialog.Color.R},{dialog.Color.G},{dialog.Color.B}"; + ConfigManager.ParticleColor = newColor; + UpdateColorPreview(newColor); + } } private void UpdateColorPreview(string rgbString) @@ -494,46 +504,144 @@ private void UpdateColorPreview(string rgbString) } } - private void Tab_Click(object sender, RoutedEventArgs e) + private void OpenLink_Click(object sender, RoutedEventArgs e) { - if (PageWelcome == null) return; - PageWelcome.Visibility = Visibility.Collapsed; - PageSettings.Visibility = Visibility.Collapsed; - PageAbout.Visibility = Visibility.Collapsed; + if (sender is System.Windows.Controls.Button btn && btn.Tag is string url) + { + try { Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); } + catch (Exception ex) + { + System.Windows.MessageBox.Show("无法打开链接: " + ex.Message); + } + } + } - if (TabWelcome.IsChecked == true) PageWelcome.Visibility = Visibility.Visible; - else if (TabSettings.IsChecked == true) PageSettings.Visibility = Visibility.Visible; - else if (TabAbout.IsChecked == true) PageAbout.Visibility = Visibility.Visible; + // --- 配置组管理 --- + private void ComboProfiles_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (ComboProfiles.SelectedItem is FilterProfile selected) + { + CurrentProfileProcesses.Clear(); + foreach (var p in selected.Processes) CurrentProfileProcesses.Add(p); + SelectProcessFilterMode(selected.Mode); + UpdateEnvironmentFilterInterlock(); + } } - private void PickColor_Click(object sender, RoutedEventArgs e) + private void AddProfile_Click(object sender, RoutedEventArgs e) { - using var dialog = new System.Windows.Forms.ColorDialog(); - dialog.FullOpen = true; - try + var newProfile = new FilterProfile { Name = "新配置组 " + (Profiles.Count + 1) }; + Profiles.Add(newProfile); + ComboProfiles.SelectedItem = newProfile; + } + + private void RenameProfile_Click(object sender, RoutedEventArgs e) + { + if (ComboProfiles.SelectedItem is FilterProfile active) { - var parts = ConfigManager.ParticleColor.Split(','); - dialog.Color = System.Drawing.Color.FromArgb( - byte.Parse(parts[0]), byte.Parse(parts[1]), byte.Parse(parts[2])); + // 简易重命名逻辑,实际项目中可使用自定义输入框 + string newName = Microsoft.VisualBasic.Interaction.InputBox("输入新名称:", "重命名配置组", active.Name); + if (!string.IsNullOrWhiteSpace(newName)) + { + active.Name = newName; + // 刷新 ComboBox 显示 + int index = Profiles.IndexOf(active); + Profiles.RemoveAt(index); + Profiles.Insert(index, active); + ComboProfiles.SelectedItem = active; + } } - catch { } + } - if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + private void DeleteProfile_Click(object sender, RoutedEventArgs e) + { + if (Profiles.Count <= 1) { - string newColor = $"{dialog.Color.R},{dialog.Color.G},{dialog.Color.B}"; - ConfigManager.ParticleColor = newColor; - UpdateColorPreview(newColor); + System.Windows.MessageBox.Show("至少需要保留一个配置组。", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + return; + } + + if (ComboProfiles.SelectedItem is FilterProfile active) + { + if (System.Windows.MessageBox.Show($"确定要删除 '{active.Name}' 吗?", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) + { + Profiles.Remove(active); + ComboProfiles.SelectedIndex = 0; + } } } - private void OpenLink_Click(object sender, RoutedEventArgs e) + // --- 进程管理 --- + private void RemoveProcess_Click(object sender, RoutedEventArgs e) { - if (sender is System.Windows.Controls.Button btn && btn.Tag is string url) + if (sender is System.Windows.Controls.Button btn && btn.DataContext is string processName) { - try { Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); } - catch (Exception ex) + CurrentProfileProcesses.Remove(processName); + if (ComboProfiles.SelectedItem is FilterProfile active) { - System.Windows.MessageBox.Show("无法打开链接: " + ex.Message); + active.Processes.Remove(processName); + } + } + } + + private void AddManualProcess_Click(object sender, RoutedEventArgs e) + { + string input = ManualProcessInput.Text.Trim().ToLowerInvariant(); + if (string.IsNullOrEmpty(input)) return; + if (!input.EndsWith(".exe")) input += ".exe"; + + AddProcessToActiveProfile(input); + ManualProcessInput.Clear(); + } + + private void BrowseProcess_Click(object sender, RoutedEventArgs e) + { + var dialog = new Microsoft.Win32.OpenFileDialog + { + Filter = "可执行文件 (*.exe)|*.exe", + Title = "选择应用进程" + }; + + if (dialog.ShowDialog() == true) + { + string fileName = System.IO.Path.GetFileName(dialog.FileName).ToLowerInvariant(); + AddProcessToActiveProfile(fileName); + } + } + + private void SelectRunningProcess_Click(object sender, RoutedEventArgs e) + { + RefreshRunningProcessList(); + RunningProcessOverlay.Visibility = Visibility.Visible; + } + + private void CloseRunningProcessOverlay_Click(object sender, RoutedEventArgs e) + { + RunningProcessOverlay.Visibility = Visibility.Collapsed; + } + + private void ConfirmAddRunningProcesses_Click(object sender, RoutedEventArgs e) + { + var selected = RunningProcessList.Where(p => p.IsSelected).Select(p => p.ProcessName).ToList(); + foreach (var p in selected) + { + AddProcessToActiveProfile(p); + } + RunningProcessOverlay.Visibility = Visibility.Collapsed; + } + + private void AddProcessToActiveProfile(string processName) + { + if (ComboProfiles.SelectedItem is FilterProfile active) + { + if (!active.Processes.Contains(processName, StringComparer.OrdinalIgnoreCase)) + { + active.Processes.Add(processName); + CurrentProfileProcesses.Add(processName); + } + else + { + // 已存在,不重复添加 } } } @@ -548,11 +656,10 @@ private void SaveSettings_Click(object sender, RoutedEventArgs e) bool startSilentEnabled = CheckStartSilent.IsChecked ?? false; bool runAsAdminEnabled = CheckRunAsAdmin.IsChecked ?? false; bool isTouchscreenEnabled = CheckTouchscreenMode?.IsChecked ?? false; - ProcessFilterModeOption processFilterMode = GetSelectedProcessFilterMode(); - string selectedProcesses = string.Join(Environment.NewLine, - ProcessList.Where(p => p.IsSelected).Select(p => p.ProcessName)); - string normalizedProcessFilterList = ConfigManager.NormalizeProcessFilterList(selectedProcesses); + // 保存配置组 + string activeId = (ComboProfiles.SelectedItem as FilterProfile)?.Id ?? ""; + ConfigManager.SaveProfiles(Profiles.ToList(), activeId); ConfigManager.Save("RunAsAdmin", runAsAdminEnabled); ConfigManager.Save("IsTouchscreenMode", isTouchscreenEnabled); @@ -569,8 +676,7 @@ private void SaveSettings_Click(object sender, RoutedEventArgs e) ConfigManager.Save("StartSilent", startSilentEnabled); ConfigManager.Save("EnableEnvironmentFilter", CheckEnvironmentFilter.IsChecked ?? false); ConfigManager.Save("HideInFullscreen", CheckHideInFullscreen.IsChecked ?? true); - ConfigManager.Save("ProcessFilterMode", processFilterMode.ToString()); - ConfigManager.Save("ProcessFilterList", normalizedProcessFilterList); + ConfigManager.Save("ShowEffectOnDesktop", CheckShowEffectOnDesktop.IsChecked ?? true); App.SetAutoStart(ConfigManager.AutoStart); ApplyAutoStartSettings(); @@ -710,6 +816,11 @@ protected override void OnClosing(System.ComponentModel.CancelEventArgs e) base.OnClosing(e); } + private void EffectSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { + if (!IsLoaded) return; + } + private void ResetConfig_Click(object sender, RoutedEventArgs e) { var result = System.Windows.MessageBox.Show( @@ -732,4 +843,4 @@ private void ResetConfig_Click(object sender, RoutedEventArgs e) } } } -} \ No newline at end of file +} diff --git a/src/MainWindow.xaml.cs b/src/MainWindow.xaml.cs index 41569dd..a3675d3 100644 --- a/src/MainWindow.xaml.cs +++ b/src/MainWindow.xaml.cs @@ -396,6 +396,23 @@ private bool ShouldSuppressEffects(bool forceRefresh = false) return _isSuppressedByEnvironment; } + // 桌面判断逻辑 + string className = GetWindowClassName(targetWindow); + if (string.IsNullOrEmpty(className)) + { + className = GetWindowClassName(GetForegroundWindow()); + } + + bool isDesktop = string.Equals(className, "Progman", StringComparison.OrdinalIgnoreCase) || + string.Equals(className, "WorkerW", StringComparison.OrdinalIgnoreCase) || + string.Equals(className, "SHELLDLL_DefView", StringComparison.OrdinalIgnoreCase); + + if (isDesktop) + { + UpdateSuppressionState(nowTicks, !ConfigManager.ShowEffectOnDesktop); + return _isSuppressedByEnvironment; + } + if (!TryGetForegroundProcessName(targetWindow, out string processName)) { if (!TryGetForegroundProcessName(GetForegroundWindow(), out processName)) @@ -426,20 +443,14 @@ private void UpdateSuppressionState(long nowTicks, bool isSuppressed) private bool IsSuppressedByProcessFilter(string processName) { - ProcessFilterModeOption mode = ConfigManager.ProcessFilterMode; - if (mode == ProcessFilterModeOption.Disabled) - { - return false; - } - - var filterEntries = ConfigManager.GetProcessFilterEntries(); - if (filterEntries.Count == 0) + var profile = ConfigManager.GetActiveProfile(); + if (profile == null || profile.Mode == ProcessFilterModeOption.Disabled) { return false; } - bool isListed = filterEntries.Contains(processName); - return mode switch + bool isListed = profile.Processes.Contains(processName, StringComparer.OrdinalIgnoreCase); + return profile.Mode switch { ProcessFilterModeOption.Blacklist => isListed, ProcessFilterModeOption.Whitelist => !isListed, From 75965aaaa89835c94316be58cffebae9c54ddaac Mon Sep 17 00:00:00 2001 From: DoomVoss Date: Sun, 19 Apr 2026 15:33:41 +0800 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E9=85=8D=E7=BD=AE=E9=A1=B5=E9=9D=A2=20UI=20=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E4=B8=8E=E9=87=8D=E5=91=BD=E5=90=8D=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ControlPanelWindow.xaml | 68 ++++++++++++++++++++-------------- src/ControlPanelWindow.xaml.cs | 30 ++++++++++++--- 2 files changed, 65 insertions(+), 33 deletions(-) diff --git a/src/ControlPanelWindow.xaml b/src/ControlPanelWindow.xaml index 946a3dc..8005c20 100644 --- a/src/ControlPanelWindow.xaml +++ b/src/ControlPanelWindow.xaml @@ -1,7 +1,7 @@ @@ -151,7 +151,25 @@ - + + + + + + + + + + @@ -189,14 +207,6 @@ - - - @@ -286,15 +296,7 @@ - - - - + @@ -382,14 +384,6 @@ - - - @@ -473,5 +467,25 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ControlPanelWindow.xaml.cs b/src/ControlPanelWindow.xaml.cs index 7176e53..62358aa 100644 --- a/src/ControlPanelWindow.xaml.cs +++ b/src/ControlPanelWindow.xaml.cs @@ -539,18 +539,36 @@ private void RenameProfile_Click(object sender, RoutedEventArgs e) { if (ComboProfiles.SelectedItem is FilterProfile active) { - // 简易重命名逻辑,实际项目中可使用自定义输入框 - string newName = Microsoft.VisualBasic.Interaction.InputBox("输入新名称:", "重命名配置组", active.Name); - if (!string.IsNullOrWhiteSpace(newName)) + // 使用自定义输入框 + NewProfileNameInput.Text = active.Name; + RenameProfileOverlay.Visibility = Visibility.Visible; + NewProfileNameInput.Focus(); + NewProfileNameInput.SelectAll(); + } + } + + private void ConfirmRenameProfile_Click(object sender, RoutedEventArgs e) + { + string newName = NewProfileNameInput.Text.Trim(); + + if (!string.IsNullOrWhiteSpace(newName) && ComboProfiles.SelectedItem is FilterProfile active) + { + active.Name = newName; + // 刷新 ComboBox 显示 + int index = Profiles.IndexOf(active); + if (index != -1) { - active.Name = newName; - // 刷新 ComboBox 显示 - int index = Profiles.IndexOf(active); Profiles.RemoveAt(index); Profiles.Insert(index, active); ComboProfiles.SelectedItem = active; } } + RenameProfileOverlay.Visibility = Visibility.Collapsed; + } + + private void CloseRenameOverlay_Click(object sender, RoutedEventArgs e) + { + RenameProfileOverlay.Visibility = Visibility.Collapsed; } private void DeleteProfile_Click(object sender, RoutedEventArgs e)