Problem
Mutating an entry in Application.DefaultKeyBindings (e.g. remapping Command.Quit to a different key) doesn't actually take effect because the dictionary indexer bypasses the property setter. The setter fires DefaultKeyBindingsChanged, which ApplicationKeyboard subscribes to in order to call AddKeyBindings(). A dictionary mutation never triggers that path.
// This looks correct but the new binding never takes effect:
Application.DefaultKeyBindings![Command.Quit] = Bind.All(Key.C.WithCtrl);
The workaround is to read the dictionary out, mutate it, then reassign the whole thing:
var bindings = Application.DefaultKeyBindings!;
bindings[Command.Quit] = Bind.All(Key.C.WithCtrl);
Application.DefaultKeyBindings = bindings;
This works but it's a footgun. The existing test in KeyboardSetterTests.QuitKey_SetValue_UpdatesKeyBindings documents the quirk (comment: "dict mutation doesn't fire the event") and works around it by calling the internal method keyboard.AddKeyBindings() directly, which external consumers can't do.
Expected behavior
Setting a key binding for a command should update the actual key bindings used by the application.
Possible fix
Replace the mutable dictionary property with a method that controls the semantics:
// Make the dictionary property read-only (or keep it for bulk reads),
// and add a method that handles mutation + notification in one shot:
Application.OverrideKeyBinding(Command.Quit, Bind.All(Key.C.WithCtrl));
This way the notification logic lives inside the method, callers can't accidentally bypass it, and the API communicates intent clearly.
Environment
- Terminal.Gui version:
2.0.0-develop.5211
- .NET 10
Problem
Mutating an entry in
Application.DefaultKeyBindings(e.g. remappingCommand.Quitto a different key) doesn't actually take effect because the dictionary indexer bypasses the property setter. The setter firesDefaultKeyBindingsChanged, whichApplicationKeyboardsubscribes to in order to callAddKeyBindings(). A dictionary mutation never triggers that path.The workaround is to read the dictionary out, mutate it, then reassign the whole thing:
This works but it's a footgun. The existing test in
KeyboardSetterTests.QuitKey_SetValue_UpdatesKeyBindingsdocuments the quirk (comment: "dict mutation doesn't fire the event") and works around it by calling theinternalmethodkeyboard.AddKeyBindings()directly, which external consumers can't do.Expected behavior
Setting a key binding for a command should update the actual key bindings used by the application.
Possible fix
Replace the mutable dictionary property with a method that controls the semantics:
This way the notification logic lives inside the method, callers can't accidentally bypass it, and the API communicates intent clearly.
Environment
2.0.0-develop.5211