[PR #17678] Track and log changes to settings #31318

Open
opened 2026-01-31 09:46:32 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/17678

State: closed
Merged: Yes


Adds functionality throughout the settings model to keep track of which settings have been set.

There are two entry points:

  • AppLogic.cpp: this is where we perform a settings reload by loading the JSON
  • MainPage.cpp: this is where the Save button is clicked in the settings UI

Both of these entry points call into CascadiaSettings::LogSettingChanges() where we aggregate the list of changes (specifically, which settings changed, not what their value is).

Just about all of the settings model objects now have a LogSettingChanges(std::set& changes, std::string_view context) on them.

  • changes is where we aggregate all of the changes to. In it being a set, we don't need to worry about duplicates and can do things like iterate across all of the profiles.
  • context prepends a string to the setting. This'll allow us to better identify where a setting was changes (i.e. "global.X" are global settings). We also use this to distinguish between settings set in the base layer profile defaults vs individual profiles.

The change log in each object is modified via two ways:

  • LayerJson() changes: this is useful for detecting JSON changes! All we're doing is checking if the setting has a value (due to inheritance, just about everything is an optional here!). If the value is set, we add the json key to the change log
  • INHERITABLE_SETTING_WITH_LOGGING in IInheritable.h: we already use this macro to define getters and setters. This new macro updates the setter to check if the value was set to something different. If so, log it!

Other notes:

  • We're not distinguishing between defaultAppearance and unfocusedAppearance
  • We are distinguishing between profileDefaults and profile (any other profile)
  • New Tab Menu Customization:
    • we really just care about the entry types. Handled in GlobalAppSettings
  • Font:
    • We still have support for legacy values here. We still want to track them, but just use the modern keys.
  • Theme:
    • We don't do inheritance here, so we have to approach it differently. During the JSON load, we log each setting. However, we don't have LayerJson! So instead, do the work in CascadiaSettings and store the changes there. Note that we don't track any changes made via setters. This is fine for now since themes aren't even in the settings UI, so we wouldn't get much use out of it anyways.
  • Actions:
    • Actions are weird because we can have nested and iterable actions too, but ActionsAndArgs as a whole add a ton of functionality. I handled it over in Command::LogSettingChanges and we generally just serialize it to JSON to get the keys. It's a lot easier than dealing with the object model.

Epic: #10000
Auto-Save (ish): #12424

**Original Pull Request:** https://github.com/microsoft/terminal/pull/17678 **State:** closed **Merged:** Yes --- Adds functionality throughout the settings model to keep track of which settings have been set. There are two entry points: - AppLogic.cpp: this is where we perform a settings reload by loading the JSON - MainPage.cpp: this is where the Save button is clicked in the settings UI Both of these entry points call into `CascadiaSettings::LogSettingChanges()` where we aggregate the list of changes (specifically, _which_ settings changed, not _what_ their value is). Just about all of the settings model objects now have a `LogSettingChanges(std::set& changes, std::string_view context)` on them. - `changes` is where we aggregate all of the changes to. In it being a set, we don't need to worry about duplicates and can do things like iterate across all of the profiles. - `context` prepends a string to the setting. This'll allow us to better identify where a setting was changes (i.e. "global.X" are global settings). We also use this to distinguish between settings set in the ~base layer~ profile defaults vs individual profiles. The change log in each object is modified via two ways: - `LayerJson()` changes: this is useful for detecting JSON changes! All we're doing is checking if the setting has a value (due to inheritance, just about everything is an optional here!). If the value is set, we add the json key to the change log - `INHERITABLE_SETTING_WITH_LOGGING` in IInheritable.h: we already use this macro to define getters and setters. This new macro updates the setter to check if the value was set to something different. If so, log it! Other notes: - We're not distinguishing between `defaultAppearance` and `unfocusedAppearance` - We are distinguishing between `profileDefaults` and `profile` (any other profile) - New Tab Menu Customization: - we really just care about the entry types. Handled in `GlobalAppSettings` - Font: - We still have support for legacy values here. We still want to track them, but just use the modern keys. - `Theme`: - We don't do inheritance here, so we have to approach it differently. During the JSON load, we log each setting. However, we don't have `LayerJson`! So instead, do the work in `CascadiaSettings` and store the changes there. Note that we don't track any changes made via setters. This is fine for now since themes aren't even in the settings UI, so we wouldn't get much use out of it anyways. - Actions: - Actions are weird because we can have nested and iterable actions too, but `ActionsAndArgs` as a whole add a ton of functionality. I handled it over in `Command::LogSettingChanges` and we generally just serialize it to JSON to get the keys. It's a lot easier than dealing with the object model. Epic: #10000 Auto-Save (ish): #12424
claunia added the pull-request label 2026-01-31 09:46:32 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#31318