Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
5d0a656 to
3b99fde
Compare
a6b5bde to
0068ae0
Compare
0068ae0 to
9cb377e
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
zadjii-msft
left a comment
There was a problem hiding this comment.
I only really have the one main question that I want answered. Otherwise, the rest seems pretty straightforward.
We should make sure to add a test for #9926 (comment) as well, because it's a good edge case
zadjii-msft
left a comment
There was a problem hiding this comment.
🙌 on the ACTION_TO_SERIALIZERS_PAIR thing, and thanks for adding the test!
This bug was caused by the list of |
| #undef ON_ALL_ACTIONS | ||
| }; | ||
|
|
||
| static const std::map<ShortcutAction, std::string_view, std::less<>> ActionToStringMap{ |
There was a problem hiding this comment.
We have got to stop it with the globally initialized maps. Sorry. This looks like a case for til::static_map or til::presorted_static_map. I'd rather do that than have yet another static initializer 😄
There was a problem hiding this comment.
Should I do what we did with GeneratedActionNames in ActionAndArgs::GenerateName? Define these in the function they're used as static lambda functions. Or does that not make this any better?
There was a problem hiding this comment.
@DHowett Can you explain the problem with static initializers for the uninitiated? 🙂
There was a problem hiding this comment.
Sure!
Initializing a static non-constexpr value at file scope generates a block of code that must be executed when the library is loaded, every time it is loaded. For something like the settings model, that cost is paid once on startup, but it is still a cost that must be paid before any of the actual settings model code is run.
constexpr is a different story: those are evaluated at compile time and stored permanently in the binary.
For a really, really good example of the cost of a static initializer (or something very similar) and the payback you get from replacing it with a fully-constexpr data store, look at commit 16e1e29.
There was a problem hiding this comment.
This seems fairly solid - it even offers perfect hash functions: https://github.com/serge-sans-paille/frozen
There was a problem hiding this comment.
Leonard and I couldn't get this to work, unfortunately. We kept running into til::presorted_static_map saying that it couldn't find the static_map in the ctor or something like that. Sorry!
|
The problem is the static map, not the functions.
|
## Summary of the Pull Request This PR lays the foundation for a new Actions page in the Settings UI as designed in #6900. The Actions page now leverages the `ActionMap` to display all of the key bindings and allow the user to modify the associated key chord or delete the key binding entirely. ## References #9621 - ActionMap #9926 - ActionMap serialization #9428 - ActionMap Spec #6900 - Actions page #9427 - Actions page design doc ## Detailed Description of the Pull Request / Additional comments ### Settings Model Changes - `Command::Copy()` now copies the `ActionAndArgs` - `ActionMap::RebindKeys()` handles changing the key chord of a key binding. If a conflict occurs, the conflicting key chord is overwritten. - `ActionMap::DeleteKeyBinding()` "deletes" a key binding by binding "unbound" to the given key chord. - `ActionMap::KeyBindings()` presents another view (similar to `NameMap`) of the `ActionMap`. It specifically presents a map of key chords to commands. It is generated similar to how `NameMap` is generated. ### Editor Changes - `Actions.xaml` is mainly split into two parts: - `ListView` (as before) holds the list of key bindings. We _could_ explore the idea of an items repeater, but the `ListView` seems to provide some niceties with regards to navigating the list via the key board (though none are selectable). - `DataTemplate` is used to represent each key binding inside the `ListView`. This is tricky because it is bound to a `KeyBindingViewModel` which must provide _all_ context necessary to modify the UI and the settings model. We cannot use names to target UI elements inside this template, so we must make the view model smart and force updates to the UI via changes in the view model. - `KeyBindingViewModel` is a view model object that controls the UI and the settings model. There are a number of TODOs in Actions.cpp will be long-term follow-ups and would be nice to have. This includes... - a binary search by name on `Actions::KeyBindingList` - presenting an error when the provided key chord is invalid. ## Demo 
|
Hello @carlos-zamora! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
|
🎉 Handy links: |
Summary of the Pull Request
This PR builds on the
ActionMapPR (#6900) by leveragingActionMapto serialize actions. From the top down, the process is now as follows:CascadiaSettings: remove the hack of copying whatever we had for actions before.GlobalAppSettings: serialize theActionMapto"actions": []ActionMap: iterate over the internal_ActionMap(list of actions) and serialize eachCommandCommand: THIS IS WHERE THE MAGIC HAPPENS! For each key mapping, serialize an action. Only the first one needs to include the name and icon.ActionAndArgs: Find the relevantIActionArgsparser and serialize theActionAndArgs.ActionArgs: ANNOYING CHANGE Serialize any args that are set. We need each setting to be saved as astd::optional. As with inheritance, this allows us to distinguish an explicit setting to the default value (sometimesnull) vs an implicit "give me the default value". This allows us to serialize only the relevant details of each action, rather than writing all of the args.References
Validation Steps Performed
Tests added!