-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor ActionMap and Command to use ActionIDs #17162
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits, and 1 bug.
I'm not sure I understood how all the changes fit together in the grand scheme of things. I'm not so deep into the ActionMap code. 🙈
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one is much scarier
@@ -1023,7 +1023,8 @@ namespace winrt::TerminalApp::implementation | |||
// NewTab(ProfileIndex=N) action | |||
NewTerminalArgs newTerminalArgs{ profileIndex }; | |||
NewTabArgs newTabArgs{ newTerminalArgs }; | |||
auto profileKeyChord{ _settings.ActionMap().GetKeyBindingForAction(ShortcutAction::NewTab, newTabArgs) }; | |||
const auto id = fmt::format(FMT_COMPILE(L"Terminal.OpenNewTabProfile{}"), profileIndex); | |||
const auto profileKeyChord{ _settings.ActionMap().GetKeyBindingForAction(id) }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There 100% is a issue right now for "I rebound keys for new tab profile N, but the dropdown still has the old ones" and I'm guessing this will solve that (because people can rebind the key for the literal Terminal.OpenNewTabProfile5
rather than just making a new Command
for it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#13943 I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep this fixes that! Also fixes it in the cmd palette
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PankajBhojwani should this PR close that bug?
{ "command": "paste", "keys": "ctrl+v" }, | ||
{ "command": "find", "keys": "ctrl+shift+f" }, | ||
{ "command": { "action": "splitPane", "split": "auto", "splitMode": "duplicate" }, "keys": "alt+shift+d" } | ||
{ "id": "Terminal.CopySelectedText", "keys": "ctrl+c" }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay so, if I want to
- Remove the ctrl+shift+c keybinding set in the defaults
- AND add a keybinding to alt+c
how do I do that now?
Does this add a ctrl+c keybinding to Terminal.CopySelectedText
, or replace the original ctrl+shift+c?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this add a ctrl+c keybinding to Terminal.CopySelectedText, or replace the original ctrl+shift+c?
It only adds!
Remove the ctrl+shift+c keybinding set in the defaults
Then you add {"id": null, "keys": "ctrl+shift+c"}
into the keybindings
array
AND add a keybinding to alt+c
Add {"id": "<id of the command>", "keys": "alt+c"}
into keybindings
{ "command": "copy", "keys": ["ctrl+c"] }, | ||
{ "command": { "action": "copy", "singleLine": false }, "keys": ["ctrl+shift+c"] }, | ||
{ "command": { "action": "copy", "singleLine": true }, "keys": ["alt+shift+c"] }, | ||
{ "command": "copy", "id": "Test.CopyNoArgs", "keys": ["ctrl+c"] }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for my own notes: the commands in this test needed id
's because the JSON was getting parsed as origin::none? if it was origin::user, they wouldn't need id
's, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, since they are Origin::None
we will not generate id
s for them and so the ActionMap
will refuse to add them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 nit left. I think it's worth addressing, but otherwise LGTM from my side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
12/17
@@ -20,14 +20,6 @@ namespace winrt | |||
namespace WUX = Windows::UI::Xaml; | |||
} | |||
|
|||
static constexpr std::string_view NameKey{ "name" }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 moved to the header, so that these can be used in ActionMapSerialization
_fixUpsAppliedDuringLoad = true; | ||
} | ||
|
||
if (origin == OriginTag::User && !jsonBlock.isMember(JsonKey(IDKey))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 do we enforce ID's present for fragment actions now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep! This is as specced (docs will need to be updated as well, I've got a todo item for that once these have been reviewed so I can do it all at once)
|
||
// if these keys are already bound to some command, | ||
// we need to update that command to erase these keys as we are about to overwrite them | ||
if (const auto foundCommand = _GetActionByKeyChordInternal(keys); foundCommand && *foundCommand) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm not gonna overindex on this, cause #17215 is right there and gets rid of this whole thing
// This command has a name, check if it's new. | ||
if (newName != maskingCmd.Name()) | ||
// only add to the _ActionMap if there is an ID | ||
if (auto cmdID = cmd.ID(); !cmdID.empty() && cmd.ActionAndArgs().Action() != ShortcutAction::Invalid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: may be cleaner to read if we do a early return for cmdID.empty() || cmd.ActionAndArgs().Action() == ShortcutAction::Invalid
instead of another level of indenting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree. look at all that nesting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was actually just a mistake - was checking for Invalid
twice! Removed the excess check and this should be much more readable now. Also we cannot early return on cmdID.empty()
because if it's a user command we should generate an ID for it.
// { "command": "copy", "keys": "ctrl+c" } --> register "ctrl+c" (section above) | ||
// { "command": "copy", "keys": "ctrl+shift+c" } --> also register "ctrl+shift+c" to the same Command (oldCmd) | ||
if (oldCmd) | ||
if (const auto foundCommand = _GetActionByKeyChordInternal(keys); foundCommand && *foundCommand) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 this block is gone in #17215 (the next follow up PR)
// in this case, we do _not_ want to use the id they provided, we want to use an empty id | ||
// (empty id in the _KeyMap indicates the keychord was explicitly unbound) | ||
const auto action = cmd.ActionAndArgs().Action(); | ||
const auto id = action == ShortcutAction::Invalid ? hstring{} : cmd.ID(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh okay so if we unbind a key, then it's still in the keymap, but bound to the action ID ""
, which then doesn't resolve to an actual action
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep! So previously an unbound key was bound to an actual Command
object with action type Invalid
, now the keybinding is just bound to an empty ID
@@ -431,7 +450,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation | |||
// invalidate caches | |||
_NameMapCache = nullptr; | |||
_GlobalHotkeysCache = nullptr; | |||
_KeyBindingMapCache = nullptr; | |||
_CumulativeKeyMapCache = nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔖 read from here down, need to read the top again
"name": "foo", | ||
"icon": "myCoolIconPath.png", | ||
"command": { "action": "sendInput", "input": "just some input" }, | ||
"id": "User.sendInput.)" SEND_INPUT_ARCH_SPECIFIC_ACTION_HASH R"(" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is hilarious to me
@@ -826,7 +826,7 @@ namespace winrt::TerminalApp::implementation | |||
newTabFlyout.Items().Append(settingsItem); | |||
|
|||
auto actionMap = _settings.ActionMap(); | |||
const auto settingsKeyChord{ actionMap.GetKeyBindingForAction(ShortcutAction::OpenSettings, OpenSettingsArgs{ SettingsTarget::SettingsUI }) }; | |||
const auto settingsKeyChord{ actionMap.GetKeyBindingForAction(L"Terminal.OpenSettingsUI") }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh i really like how clean this feels now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6/17 one block so far - reviewing still
As outlined in #16816, refactor
ActionMap
to use the new action IDs added in #16904Validation steps performed
Refs #16816
Closes #17133