mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 01:59:34 +02:00
fix(settings-ui): prevent update checks from resetting modules (#50018)
## Summary of the Pull Request Prevents update checks from resetting enabled module states when Settings UI holds stale or default general settings. The update check now sends the existing action-only IPC shape from `src/settings-ui/Settings.UI/ViewModels/UpdateViewModel.cs`. Runner handles that command without applying its payload as general settings in `src/runner/settings_window.cpp`. ## PR Checklist - [x] Closes: #48907 - [x] **Communication:** Root cause analysis was posted on the linked issue - [x] **Tests:** Added/updated and all pass ## Detailed Description of the Pull Request / Additional comments Previously, `CheckForUpdates()` embedded the complete mutable `GeneralSettings` object in a custom-action message. Runner then called `apply_general_settings` on that action payload. If Settings UI had loaded fallback defaults, merely checking for an update could persist those defaults and overwrite the user's enabled module choices. This change: - sends only `{ "action": { "general": { "action_name": "check_for_updates" } } }`; - prevents Runner from treating an update action as a general-settings update; - preserves prerelease behavior because changing that setting already sends normal general-settings IPC before starting the update check; and - updates `src/settings-ui/Settings.UI.UnitTests/ViewModelTests/Update.cs` to verify non-default module states are neither transmitted nor mutated. No persisted settings schema, localization, documentation, or binary changes are required. ## Validation Steps Performed - Built `src/settings-ui/Settings.UI.UnitTests/Settings.UI.UnitTests.csproj` for x64 Debug. - Ran `ViewModelTests.Update` with `vstest.console.exe`: 26 passed. - Built `src/runner/runner.vcxproj` for x64 Debug. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -111,7 +111,6 @@ std::optional<std::wstring> dispatch_json_action_to_module(const json::JsonObjec
|
||||
}
|
||||
else if (action == L"check_for_updates")
|
||||
{
|
||||
apply_general_settings(value);
|
||||
bool expected_isUpdateCheckThreadRunning = false;
|
||||
if (isUpdateCheckThreadRunning.compare_exchange_strong(expected_isUpdateCheckThreadRunning, true))
|
||||
{
|
||||
|
||||
@@ -58,13 +58,17 @@ namespace ViewModelTests
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckForUpdatesShouldShowProgressAndSendCurrentSettings()
|
||||
public void CheckForUpdatesShouldShowProgressAndSendActionOnly()
|
||||
{
|
||||
string sentMessage = null;
|
||||
var generalSettings = new GeneralSettings
|
||||
{
|
||||
IncludePrereleaseUpdates = true,
|
||||
};
|
||||
generalSettings.Enabled.AlwaysOnTop = false;
|
||||
generalSettings.Enabled.FancyZones = false;
|
||||
generalSettings.Enabled.PowerLauncher = true;
|
||||
var settingsBeforeCheck = generalSettings.ToJsonString();
|
||||
var viewModel = CreateViewModel(
|
||||
new TestSettingsRepository(generalSettings),
|
||||
new UpdatingSettings(),
|
||||
@@ -80,9 +84,12 @@ namespace ViewModelTests
|
||||
Assert.IsTrue(viewModel.IsActivityVisible);
|
||||
Assert.IsFalse(viewModel.CanStartAction);
|
||||
|
||||
var action = JsonSerializer.Deserialize<GeneralSettingsCustomAction>(sentMessage);
|
||||
Assert.IsTrue(action.GeneralSettingsAction.GeneralSettings.IncludePrereleaseUpdates);
|
||||
Assert.AreEqual("check_for_updates", action.GeneralSettingsAction.GeneralSettings.CustomActionName);
|
||||
using var message = JsonDocument.Parse(sentMessage);
|
||||
var generalAction = message.RootElement.GetProperty("action").GetProperty("general");
|
||||
Assert.AreEqual("check_for_updates", generalAction.GetProperty("action_name").GetString());
|
||||
Assert.IsFalse(generalAction.TryGetProperty("enabled", out _));
|
||||
Assert.IsFalse(generalAction.TryGetProperty("include_prerelease_updates", out _));
|
||||
Assert.AreEqual(settingsBeforeCheck, generalSettings.ToJsonString());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
@@ -13,6 +14,7 @@ using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.SerializationContext;
|
||||
using Microsoft.UI.Dispatching;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
@@ -314,15 +316,15 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
var generalSettings = _settingsRepository.SettingsConfig;
|
||||
generalSettings.CustomActionName = "check_for_updates";
|
||||
var customAction = new GeneralSettingsCustomAction(new OutGoingGeneralSettings(generalSettings));
|
||||
var checkForUpdatesAction = JsonSerializer.Serialize(
|
||||
ActionMessage.Create("check_for_updates"),
|
||||
SourceGenerationContextContext.Default.ActionMessage);
|
||||
|
||||
RequestActivity();
|
||||
StartTransientOperation(TransientUpdateOperation.Checking);
|
||||
try
|
||||
{
|
||||
if (_sendCheckForUpdatesConfigMessage(customAction.ToString()) != 0)
|
||||
if (_sendCheckForUpdatesConfigMessage(checkForUpdatesAction) != 0)
|
||||
{
|
||||
FailTransientOperation(UpdateUIState.NetworkError, "Failed to send the update check request.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user