Skip to content

Commit 30707d6

Browse files
authored
Fix: Fixed ArgumentException in CommandManager.OverwriteKeyBindings (#15582)
1 parent 0997045 commit 30707d6

File tree

1 file changed

+63
-8
lines changed

1 file changed

+63
-8
lines changed

src/Files.App/Data/Commands/Manager/CommandManager.cs

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Frozen;
55
using System.Collections.Immutable;
66
using Files.App.Actions;
7+
using Microsoft.Extensions.Logging;
78

89
namespace Files.App.Data.Commands
910
{
@@ -391,25 +392,26 @@ public IEnumerator<IRichCommand> GetEnumerator() =>
391392
/// </summary>
392393
private void OverwriteKeyBindings()
393394
{
395+
var allCommands = commands.Values.OfType<ActionCommand>();
396+
394397
if (ActionsSettingsService.ActionsV2 is null)
395398
{
396-
foreach (var command in commands.Values.OfType<ActionCommand>())
397-
{
398-
command.RestoreKeyBindings();
399-
}
399+
allCommands.ForEach(x => x.RestoreKeyBindings());
400400
}
401401
else
402402
{
403-
foreach (var command in commands.Values.OfType<ActionCommand>())
403+
foreach (var command in allCommands)
404404
{
405405
var customizedKeyBindings = ActionsSettingsService.ActionsV2.FindAll(x => x.CommandCode == command.Code.ToString());
406406

407407
if (customizedKeyBindings.IsEmpty())
408408
{
409+
// Could not find customized key bindings for the command
409410
command.RestoreKeyBindings();
410411
}
411412
else if (customizedKeyBindings.Count == 1 && customizedKeyBindings[0].KeyBinding == string.Empty)
412413
{
414+
// Do not assign any key binding even though there're default keys pre-defined
413415
command.OverwriteKeyBindings(HotKeyCollection.Empty);
414416
}
415417
else
@@ -420,9 +422,62 @@ private void OverwriteKeyBindings()
420422
}
421423
}
422424

423-
_allKeyBindings = commands.Values
424-
.SelectMany(command => command.HotKeys, (command, hotKey) => (Command: command, HotKey: hotKey))
425-
.ToImmutableDictionary(item => item.HotKey, item => item.Command);
425+
try
426+
{
427+
// Set collection of a set of command code and key bindings to dictionary
428+
_allKeyBindings = commands.Values
429+
.SelectMany(command => command.HotKeys, (command, hotKey) => (Command: command, HotKey: hotKey))
430+
.ToImmutableDictionary(item => item.HotKey, item => item.Command);
431+
}
432+
catch (ArgumentException ex)
433+
{
434+
// The keys are not necessarily all different because they can be set manually in text editor
435+
// ISSUE: https://github.com/files-community/Files/issues/15331
436+
437+
var flat = commands.Values.SelectMany(x => x.HotKeys).Select(x => x.LocalizedLabel);
438+
var duplicates = flat.GroupBy(x => x).Where(x => x.Count() > 1).Select(group => group.Key);
439+
440+
foreach (var item in duplicates)
441+
{
442+
if (!string.IsNullOrEmpty(item))
443+
{
444+
var occurrences = allCommands.Where(x => x.HotKeys.Select(x => x.LocalizedLabel).Contains(item));
445+
446+
// Restore the defaults for all occurrences in our cache
447+
occurrences.ForEach(x => x.RestoreKeyBindings());
448+
449+
// Get all customized key bindings from user settings json
450+
var actions =
451+
ActionsSettingsService.ActionsV2 is not null
452+
? new List<ActionWithParameterItem>(ActionsSettingsService.ActionsV2)
453+
: [];
454+
455+
// Remove the duplicated key binding from user settings JSON file
456+
actions.RemoveAll(x => x.KeyBinding.Contains(item));
457+
458+
// Reset
459+
ActionsSettingsService.ActionsV2 = actions;
460+
}
461+
}
462+
463+
// Set collection of a set of command code and key bindings to dictionary
464+
_allKeyBindings = commands.Values
465+
.SelectMany(command => command.HotKeys, (command, hotKey) => (Command: command, HotKey: hotKey))
466+
.ToImmutableDictionary(item => item.HotKey, item => item.Command);
467+
468+
App.Logger.LogWarning(ex, "The app found some keys in different commands are duplicated and are using default key bindings for those commands.");
469+
}
470+
catch (Exception ex)
471+
{
472+
allCommands.ForEach(x => x.RestoreKeyBindings());
473+
474+
// Set collection of a set of command code and key bindings to dictionary
475+
_allKeyBindings = commands.Values
476+
.SelectMany(command => command.HotKeys, (command, hotKey) => (Command: command, HotKey: hotKey))
477+
.ToImmutableDictionary(item => item.HotKey, item => item.Command);
478+
479+
App.Logger.LogWarning(ex, "The app is temporarily using default key bindings for all because of a serious error of assigning custom keys.");
480+
}
426481
}
427482

428483
public static HotKeyCollection GetDefaultKeyBindings(IAction action)

0 commit comments

Comments
 (0)