Settings: Add pending changes tracking and apply confirmation dialog#14425
Settings: Add pending changes tracking and apply confirmation dialog#14425dabhattimsft wants to merge 13 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an “Apply changes” workflow to the WinUI-based WSL Settings app by tracking configuration edits as pending, and only committing them to disk after explicit user confirmation (optionally followed by wsl --shutdown).
Changes:
- Introduces pending-changes tracking in
IWslConfigService/WslConfigService, with a newPendingChangesChangedevent and commit/clear APIs. - Updates Settings view models/pages to react to pending state (
HasPendingChanges) and show an “Apply changes” button. - Adds an apply confirmation dialog that summarizes pending edits and offers “Shutdown WSL now” vs “Later”.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs | New helper that builds and shows the apply/confirm dialog and triggers commit + optional shutdown. |
| src/windows/wslsettings/Views/Settings/DeveloperPage.xaml(.cs) | Adds “Apply changes” button and hooks pending-changes notifications. |
| src/windows/wslsettings/Views/Settings/FileSystemPage.xaml(.cs) | Adds “Apply changes” button and hooks pending-changes notifications. |
| src/windows/wslsettings/Views/Settings/MemAndProcPage.xaml(.cs) | Adds “Apply changes” button and hooks pending-changes notifications. |
| src/windows/wslsettings/Views/Settings/NetworkingPage.xaml(.cs) | Adds “Apply changes” button and hooks pending-changes notifications. |
| src/windows/wslsettings/Views/Settings/OptionalFeaturesPage.xaml(.cs) | Adds “Apply changes” button and hooks pending-changes notifications. |
| src/windows/wslsettings/ViewModels/Settings/WslConfigSettingViewModel.cs | Adds HasPendingChanges property + handler to update UI when pending state changes. |
| src/windows/wslsettings/Services/WslConfigService.cs | Implements pending dictionary, commit/clear APIs, and new pending-changes event. |
| src/windows/wslsettings/Contracts/Services/IWslConfigService.cs | Extends contract with pending-changes APIs and WslConfigPendingChange model. |
| src/windows/wslsettings/CMakeLists.txt | Adds the new helper source file to the build. |
| localization/strings/en-US/Resources.resw | Adds localized strings for apply dialog/buttons and error messages. |
|
This seems like a lot of code to handle this. Instead could we just keep track of the config struct when we launch and compare it to the current config (and then update that initial struct when we click apply / shutdown / whatever). |
| var changeLines = new List<string>(pendingChanges.Count); | ||
| foreach (var change in pendingChanges) | ||
| { | ||
| changeLines.Add($"- {GetSettingDisplayName(change.ConfigEntry)}: {FormatSettingValue(change.PendingSetting)}"); |
There was a problem hiding this comment.
The pending-changes lines are constructed with hardcoded punctuation/formatting ("- {name}: {value}"). This makes part of the user-facing dialog content non-localizable and may not read well in all locales. Consider using a localized format string/resource (or a structured UI like a ListView) to format each entry.
| changeLines.Add($"- {GetSettingDisplayName(change.ConfigEntry)}: {FormatSettingValue(change.PendingSetting)}"); | |
| changeLines.Add(string.Format( | |
| "Settings_ApplyChangesDialogChangeLineFormat".GetLocalized(), | |
| GetSettingDisplayName(change.ConfigEntry), | |
| FormatSettingValue(change.PendingSetting))); |
There was a problem hiding this comment.
The name and value are both already localized. The only hardcoded pieces are the bullet dash and colon. Won't fix for now unless reviewers say otherwise.
| @@ -27,41 +33,147 @@ public WslConfigService() | |||
| _wslConfigFileSystemWatcher.Renamed += OnWslConfigFileChanged; | |||
|
|
|||
| _wslConfigFileSystemWatcher!.EnableRaisingEvents = true; | |||
|
|
|||
| // Read all current config values into both snapshots so they start in sync | |||
| lock (_wslCoreConfigInterfaceLockObj!) | |||
| { | |||
| RefreshSnapshots_NoLock(); | |||
| } | |||
| } | |||
|
|
|||
| ~WslConfigService() | |||
| { | |||
| DisposeSnapshot(_baselineSnapshot); | |||
| DisposeSnapshot(_workingSnapshot); | |||
| WslCoreConfigInterface.FreeWslConfig(_wslConfig); | |||
| WslCoreConfigInterface.FreeWslConfig(_wslConfigDefaults); | |||
| } | |||
There was a problem hiding this comment.
WslConfigService creates a FileSystemWatcher but never disposes it. Since this service is a singleton, the watcher will keep OS handles for the app lifetime; and even at shutdown the finalizer currently doesn't dispose it. Consider implementing IDisposable and disposing/unsubscribing the watcher (and disabling events) when the app shuts down.
…/microsoft/WSL into user/dabhatti/wslSettingsRestart
| public required IWslConfigSetting PendingSetting { get; init; } | ||
| } | ||
|
|
||
| public interface IWslConfigSetting |
There was a problem hiding this comment.
GetPendingChanges() returns WslConfigPendingChange objects containing IWslConfigSetting instances that wrap unmanaged allocations (LibWsl.WslConfigSetting implements IDisposable). Since IWslConfigSetting doesn’t expose disposal, callers (like the Apply dialog) can’t deterministically free these clones, which can lead to avoidable unmanaged-memory growth. Consider changing WslConfigPendingChange to carry managed value snapshots (e.g., entry + strongly-typed value fields), or expose a disposable type (e.g., WslConfigSettingManaged / IDisposable) with clear ownership semantics.
| public interface IWslConfigSetting | |
| public interface IWslConfigSetting : System.IDisposable |
There was a problem hiding this comment.
Pre-existing. Can take it up in future PR
Summary of the Pull Request
Adds "Apply Changes" workflow to the WSL Settings app. Settings changes are now tracked as pending and only written to disk when the user confirms, giving clear visibility into what will change.
PR Checklist
Detailed Description of the Pull Request / Additional comments
SetWslConfigSetting no longer writes to disk immediately. Instead it records changes in a pending dictionary, comparing against the persisted value to auto-remove no-op edits.
New PendingChangesChanged event so the UI can react when the pending set becomes non-empty or empty.
Validation Steps Performed
Manually tested