From 63257e928d9ba5e5efdc6d72cfbf1b8a702fb23f Mon Sep 17 00:00:00 2001 From: Shuai Yuan Date: Mon, 7 Jul 2025 15:27:06 +0800 Subject: [PATCH] Fixed mouse utils crash issue. Signed-off-by: Shuai Yuan --- .../SettingsXAML/Panels/MouseJumpPanel.xaml | 6 +- .../SettingsXAML/Views/MouseUtilsPage.xaml | 6 +- .../SettingsXAML/Views/MouseUtilsPage.xaml.cs | 1 + .../ViewModels/MouseUtilsViewModel.cs | 76 +++++++++++-------- .../MouseUtilsViewModel_MouseJump.cs | 31 +++++++- 5 files changed, 87 insertions(+), 33 deletions(-) diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Panels/MouseJumpPanel.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Panels/MouseJumpPanel.xaml index 22d996efb2..959603fcd9 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Panels/MouseJumpPanel.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Panels/MouseJumpPanel.xaml @@ -45,7 +45,11 @@ x:Uid="MouseUtils_MouseJump_ActivationShortcut" HeaderIcon="{ui:FontIcon Glyph=}" IsEnabled="{x:Bind ViewModel.IsMouseJumpEnabled, Mode=OneWay}"> - + + @@ -153,7 +157,7 @@ IsClosable="False" IsOpen="True" Severity="Informational" - Visibility="{x:Bind ViewModel.IsAnimationEnabledBySystem, Mode=OneWay, Converter={StaticResource BoolToReverseVisibilityConverter}}"> + Visibility="{x:Bind ViewModel.IsAnimationEnabledBySystem, Mode=OneWay, Converter={StaticResource BoolToInvertedVisibilityConverter}}"> diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml.cs index 9af644482d..ab3e8192ac 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml.cs @@ -48,6 +48,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views InitializeComponent(); this.MouseUtils_MouseJump_Panel.ViewModel = ViewModel; + Loaded += (s, e) => ViewModel.OnPageLoaded(); } diff --git a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs index b8ff12e3d0..ee08a533fe 100644 --- a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel.cs @@ -5,11 +5,13 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using System.Runtime.CompilerServices; - +using System.Threading.Tasks; using global::PowerToys.GPOWrapper; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; +using Microsoft.PowerToys.Settings.UI.Library.HotkeyConflicts; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.Utilities; @@ -197,7 +199,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } - /* private bool GetHotkeyConflictStatus(string hotkeyName) { return _hotkeyConflictStatus.ContainsKey(hotkeyName) && _hotkeyConflictStatus[hotkeyName]; @@ -208,30 +209,43 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels _hotkeyConflictStatus.Clear(); _hotkeyConflictTooltips.Clear(); - var moduleRelatedConflicts = GetModuleRelatedConflicts(allConflicts); - - if (moduleRelatedConflicts.HasConflicts) + // Define the four MouseUtils submodule names + var mouseUtilsModules = new HashSet { - var conflictData = moduleRelatedConflicts.InAppConflicts - .Concat(moduleRelatedConflicts.SystemConflicts) - .Where(conflict => conflict.Modules != null) - .SelectMany(conflict => conflict.Modules.Select(module => new { Conflict = conflict, Module = module })) - .Where(item => string.Equals(item.Module.ModuleName, FindMyMouseSettings.ModuleName, StringComparison.OrdinalIgnoreCase) || - string.Equals(item.Module.ModuleName, MouseHighlighterSettings.ModuleName, StringComparison.OrdinalIgnoreCase) || - string.Equals(item.Module.ModuleName, MousePointerCrosshairsSettings.ModuleName, StringComparison.OrdinalIgnoreCase)) - .GroupBy(item => item.Module.HotkeyName) - .ToDictionary(g => g.Key, g => g.First()); + FindMyMouseSettings.ModuleName, // "FindMyMouse" + MouseHighlighterSettings.ModuleName, // "MouseHighlighter" + MousePointerCrosshairsSettings.ModuleName, // "MousePointerCrosshairs" + MouseJumpSettings.ModuleName, // "MouseJump" + }; - foreach (var conflictGroup in conflictData) + // Process in-app conflicts + foreach (var conflict in allConflicts.InAppConflicts) + { + ProcessConflictGroup(conflict, mouseUtilsModules); + } + + // Process system conflicts + foreach (var conflict in allConflicts.SystemConflicts) + { + ProcessConflictGroup(conflict, mouseUtilsModules); + } + } + + private void ProcessConflictGroup(HotkeyConflictGroupData conflict, HashSet mouseUtilsModules) + { + // Check if any of the modules in this conflict are MouseUtils submodules + var involvedMouseUtilsModules = conflict.Modules + .Where(module => mouseUtilsModules.Contains(module.ModuleName)) + .ToList(); + + if (involvedMouseUtilsModules.Count != 0) + { + // For each involved MouseUtils module, mark the hotkey as having a conflict + foreach (var module in involvedMouseUtilsModules) { - var hotkeyName = conflictGroup.Key; - var conflictItem = conflictGroup.Value; - - _hotkeyConflictStatus[hotkeyName] = true; - - // Generate tooltip text based on conflict type - var tooltip = GenerateConflictTooltip(conflictItem.Conflict, conflictItem.Module); - _hotkeyConflictTooltips[hotkeyName] = tooltip; + string hotkeyKey = $"{module.ModuleName}_{module.HotkeyName}"; + _hotkeyConflictStatus[hotkeyKey] = true; + _hotkeyConflictTooltips[hotkeyKey] = GenerateConflictTooltip(conflict, module); } } } @@ -267,13 +281,15 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels // Update properties using setters to trigger PropertyChanged void UpdateConflictProperties() { - FindMyMouseActivationShortcutHasConflict = GetHotkeyConflictStatus("ActivationShortcut"); - MouseHighlighterActivationShortcutHasConflict = GetHotkeyConflictStatus("ActivationShortcut"); - MousePointerCrosshairsActivationShortcutHasConflict = GetHotkeyConflictStatus("ActivationShortcut"); + FindMyMouseActivationShortcutHasConflict = GetHotkeyConflictStatus($"{FindMyMouseSettings.ModuleName}_ActivationShortcut"); + MouseHighlighterActivationShortcutHasConflict = GetHotkeyConflictStatus($"{MouseHighlighterSettings.ModuleName}_ActivationShortcut"); + MousePointerCrosshairsActivationShortcutHasConflict = GetHotkeyConflictStatus($"{MousePointerCrosshairsSettings.ModuleName}_ActivationShortcut"); + MouseJumpActivationShortcutHasConflict = GetHotkeyConflictStatus($"{MouseJumpSettings.ModuleName}_ActivationShortcut"); - FindMyMouseActivationShortcutTooltip = GetHotkeyConflictTooltip("ActivationShortcut"); - MouseHighlighterActivationShortcutTooltip = GetHotkeyConflictTooltip("ActivationShortcut"); - MousePointerCrosshairsActivationShortcutTooltip = GetHotkeyConflictTooltip("ActivationShortcut"); + FindMyMouseActivationShortcutTooltip = GetHotkeyConflictTooltip($"{FindMyMouseSettings.ModuleName}_ActivationShortcut"); + MouseHighlighterActivationShortcutTooltip = GetHotkeyConflictTooltip($"{MouseHighlighterSettings.ModuleName}_ActivationShortcut"); + MousePointerCrosshairsActivationShortcutTooltip = GetHotkeyConflictTooltip($"{MousePointerCrosshairsSettings.ModuleName}_ActivationShortcut"); + MouseJumpActivationShortcutTooltip = GetHotkeyConflictTooltip($"{MouseJumpSettings.ModuleName}_ActivationShortcut"); } _ = Task.Run(() => @@ -295,7 +311,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels UpdateConflictProperties(); } }); - }*/ + } public bool FindMyMouseActivationShortcutHasConflict { diff --git a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel_MouseJump.cs b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel_MouseJump.cs index 39565b668c..8aa17990a2 100644 --- a/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel_MouseJump.cs +++ b/src/settings-ui/Settings.UI/ViewModels/MouseUtilsViewModel_MouseJump.cs @@ -25,12 +25,15 @@ using MouseJump.Common.Models.Styles; namespace Microsoft.PowerToys.Settings.UI.ViewModels { - public partial class MouseUtilsViewModel + public partial class MouseUtilsViewModel : PageViewModelBase { private GpoRuleConfigured _jumpEnabledGpoRuleConfiguration; private bool _jumpEnabledStateIsGPOConfigured; private bool _isMouseJumpEnabled; + private bool _mouseJumpActivationShortcutHasConflict; + private string _mouseJumpActivationShortcutTooltip; + internal MouseJumpSettings MouseJumpSettingsConfig { get; set; } private void InitializeMouseJumpSettings(ISettingsRepository mouseJumpSettingsRepository) @@ -111,6 +114,32 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public bool MouseJumpActivationShortcutHasConflict + { + get => _mouseJumpActivationShortcutHasConflict; + set + { + if (_mouseJumpActivationShortcutHasConflict != value) + { + _mouseJumpActivationShortcutHasConflict = value; + OnPropertyChanged(nameof(MouseJumpActivationShortcutHasConflict)); + } + } + } + + public string MouseJumpActivationShortcutTooltip + { + get => _mouseJumpActivationShortcutTooltip; + set + { + if (_mouseJumpActivationShortcutTooltip != value) + { + _mouseJumpActivationShortcutTooltip = value; + OnPropertyChanged(nameof(MouseJumpActivationShortcutTooltip)); + } + } + } + public MouseJumpThumbnailSize MouseJumpThumbnailSize { get