Skip to content

Settings: Add pending changes tracking and apply confirmation dialog#14425

Merged
benhillis merged 17 commits into
masterfrom
user/dabhatti/wslSettingsRestart
Apr 21, 2026
Merged

Settings: Add pending changes tracking and apply confirmation dialog#14425
benhillis merged 17 commits into
masterfrom
user/dabhatti/wslSettingsRestart

Conversation

@dabhattimsft

@dabhattimsft dabhattimsft commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

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

  • Closes: Link to issue #xxx
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

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.

  • "Apply changes" button appears at the bottom of each settings page (Developer, FileSystem, MemAndProc, Networking, OptionalFeatures) when there are pending changes.
    • "Shutdown WSL now" — commits all pending changes to disk and runs wsl --shutdown so they take effect on next launch.
    • "Later" — commits changes to disk without shutting down; settings apply on the next WSL start.
    • Dismiss / close — leaves changes pending (nothing is written).
image

Validation Steps Performed

Manually tested

Darshak Bhatti added 3 commits March 5, 2026 17:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 new PendingChangesChanged event 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.
Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs Outdated
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs
Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs
@benhillis

Copy link
Copy Markdown
Member

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).

@dabhattimsft dabhattimsft requested a review from OneBlue March 13, 2026 17:15
Darshak Bhatti added 2 commits March 13, 2026 13:39
@dabhattimsft dabhattimsft requested a review from Copilot March 18, 2026 20:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs Outdated
@dabhattimsft dabhattimsft requested a review from Copilot March 18, 2026 23:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs
@dabhattimsft dabhattimsft requested a review from Copilot March 18, 2026 23:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.

Comment thread src/windows/wslsettings/Views/Settings/FileSystemPage.xaml.cs
Comment thread src/windows/wslsettings/Views/Settings/DeveloperPage.xaml.cs Outdated
Comment thread src/windows/wslsettings/Views/Settings/OptionalFeaturesPage.xaml.cs
Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Views/Settings/NetworkingPage.xaml.cs
Comment thread src/windows/wslsettings/Views/Settings/MemAndProcPage.xaml.cs
@dabhattimsft dabhattimsft requested a review from Copilot March 19, 2026 00:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

var changeLines = new List<string>(pendingChanges.Count);
foreach (var change in pendingChanges)
{
changeLines.Add($"- {GetSettingDisplayName(change.ConfigEntry)}: {FormatSettingValue(change.PendingSetting)}");

Copilot AI Mar 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
changeLines.Add($"- {GetSettingDisplayName(change.ConfigEntry)}: {FormatSettingValue(change.PendingSetting)}");
changeLines.Add(string.Format(
"Settings_ApplyChangesDialogChangeLineFormat".GetLocalized(),
GetSettingDisplayName(change.ConfigEntry),
FormatSettingValue(change.PendingSetting)));
Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs
Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs
Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs Outdated
Comment on lines 21 to 50
@@ -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);
}

Copilot AI Mar 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings March 21, 2026 00:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.

Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
public required IWslConfigSetting PendingSetting { get; init; }
}

public interface IWslConfigSetting

Copilot AI Mar 21, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
public interface IWslConfigSetting
public interface IWslConfigSetting : System.IDisposable
Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing. Can take it up in future PR

Darshak Bhatti added 2 commits March 20, 2026 17:16
Copilot AI review requested due to automatic review settings March 28, 2026 02:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment on lines +118 to +132
public IReadOnlyList<WslConfigPendingChange> GetPendingChanges()
{
lock (_wslCoreConfigInterfaceLockObj!)
{
var changes = new List<WslConfigPendingChange>(_pendingValues.Count);
foreach (var (entry, value) in _pendingValues)
{
changes.Add(new WslConfigPendingChange
{
ConfigEntry = entry,
PendingValue = value,
});
}
return changes;
}

Copilot AI Mar 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetPendingChanges() builds the UI list by iterating _pendingValues directly. Dictionary enumeration order isn’t a contractual UI ordering, so the apply dialog can show changes in a surprising order across runs/edits. Consider returning the list in a stable order (e.g., by WslConfigEntry or by localized display name) so the dialog content is predictable.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is a real issue.

Comment on lines 26 to +27
event WslConfigChangedEventHandler WslConfigChanged;
public delegate void PendingChangesChangedEventHandler();

Copilot AI Mar 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new PendingChangesChanged event doesn’t document what “changed” means (e.g., any edit to the pending set vs only empty/non-empty transitions). Since consumers may rely on this for more than button visibility later, add an XML doc comment clarifying the exact semantics (and/or consider a more specific name like HasPendingChangesChanged).

Suggested change
event WslConfigChangedEventHandler WslConfigChanged;
public delegate void PendingChangesChangedEventHandler();
event WslConfigChangedEventHandler WslConfigChanged;
/// <summary>
/// Raised whenever the in-memory collection of pending changes is modified.
/// </summary>
/// <remarks>
/// This event is fired after a pending change has been added, updated, or removed. It includes
/// transitions where <see cref="HasPendingChanges"/> changes value, as well as modifications to
/// the contents returned by <see cref="GetPendingChanges"/> while remaining non-empty. Handlers
/// should query <see cref="HasPendingChanges"/> and/or <see cref="GetPendingChanges"/> to
/// observe the new state.
/// </remarks>
public delegate void PendingChangesChangedEventHandler();
/// <summary>
/// Occurs when the in-memory collection of pending changes is modified.
/// </summary>
Copilot uses AI. Check for mistakes.
Comment on lines +24 to +28
var changeLines = new List<string>(pendingChanges.Count);
foreach (var change in pendingChanges)
{
changeLines.Add($"- {GetSettingDisplayName(change.ConfigEntry)}: {FormatValue(change.ConfigEntry, change.PendingValue)}");
}

Copilot AI Mar 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pending-changes list is displayed in whatever order GetPendingChanges() returns. If that order isn’t stable, the dialog text can jump around between edits, making it harder to review changes. Consider sorting pendingChanges (or sorting in the service) before building changeLines so the dialog always shows a consistent order.

Copilot uses AI. Check for mistakes.

@benhillis benhillis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple high level comments:

  • The apply button code is copy / pasted a bunch of times
  • I think it would be cleaner to use a second native config handle to keep track of the pending config changes, and when the user clicks save write that data.
@benhillis benhillis self-requested a review April 20, 2026 17:36
benhillis
benhillis previously approved these changes Apr 20, 2026

@benhillis benhillis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay in getting this review. I think this looks like a good improvement to the settings app.

@dabhattimsft

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

…ttingsRestart

# Conflicts:
#	src/windows/wslsettings/Services/WslConfigService.cs

Co-authored-by: dabhattimsft <47045043+dabhattimsft@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 20, 2026 22:06
@dabhattimsft dabhattimsft removed the request for review from Copilot April 20, 2026 22:06

Copilot AI commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved in ccf2f77. Merged master into the PR branch; the only conflict was in WslConfigService.cs where master added the IDisposable pattern and the PR branch added pending-changes tracking. The merged result preserves both: the IDisposable/Dispose(bool) pattern for proper FileSystemWatcher cleanup, and all the pending-changes infrastructure (_pendingValues, CommitPendingChanges, PendingChangesChanged, etc.).

Comment thread src/windows/wslsettings/Views/Settings/SettingsApplyHelper.cs Dismissed
@benhillis benhillis merged commit 37a3aa5 into master Apr 21, 2026
9 checks passed
benhillis pushed a commit that referenced this pull request Apr 21, 2026
…14425)

* initial commit

* cp

* cp

* pr feedback

* cp

* pr feedback

* pr feedback

* cp

* pr feedback

* refactor

* pr feedback

* cp

* Move Apply Changes button to ShellPage to deduplicate across settings pages

* PR feedback 1

---------

Co-authored-by: Darshak Bhatti <dabhatti@micorsoft.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants