From 6130d2ad398d0aedf04e985b394c3c2d50a099e7 Mon Sep 17 00:00:00 2001 From: Mohammed Saalim K Date: Tue, 19 Aug 2025 00:58:10 -0500 Subject: [PATCH 1/9] =?UTF-8?q?Hosts:=20add=20=E2=80=9CNo=20leading=20spac?= =?UTF-8?q?es=E2=80=9D=20option=20and=20honor=20it=20when=20saving=20(#412?= =?UTF-8?q?06)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary of the Pull Request Adds a new Hosts File Editor setting “No leading spaces” that prevents prepending spaces to active lines when saving the hosts file (when any entry is disabled). Default is Off to preserve current behavior. ## PR Checklist - [x] Closes: #36386   - [ ] Communication: N/A (small, scoped option) - [x] Tests: Added/updated and all pass - [x] Localization: New en-US strings added; other locales handled by loc pipeline - [ ] Dev docs: N/A - [x] New binaries: None - [x] Documentation updated: N/A ## Detailed Description of the Pull Request / Additional comments - Settings surface:   - `src/settings-ui/Settings.UI.Library/HostsProperties.cs`: add `NoLeadingSpaces`   - `src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs`: add `NoLeadingSpaces`   - `src/modules/Hosts/Hosts/Settings/UserSettings.cs`: load/save value from settings.json   - `src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs`: expose `NoLeadingSpaces`   - `src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml`: new SettingsCard toggle   - `src/settings-ui/Settings.UI/Strings/en-us/Resources.resw`: add `Hosts_NoLeadingSpaces.Header/Description` - Writer change:   - `src/modules/Hosts/HostsUILib/Helpers/HostsService.cs`: gate indent with `anyDisabled && !_userSettings.NoLeadingSpaces` - Tests:   - `src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs`: `NoLeadingSpaces_Disabled_RemovesIndent` Backward compatibility: default Off, current formatting unchanged unless the user enables the option. ## Validation Steps Performed - Automated: `HostsEditor.UnitTests` including `NoLeadingSpaces_Disabled_RemovesIndent` passing. - Manual:   1. Run PowerToys (runner) as Admin.   2. Settings → Hosts File Editor → enable “No leading spaces”.   3. In editor, add active `127.0.0.10 example1` and disabled `127.0.0.11 example2`; Save.   4. Open `C:\Windows\System32\drivers\etc\hosts` in Notepad.      - ON: active line starts at column 0; disabled is `# 127...`.      - OFF: active line begins with two spaces when a disabled entry exists. --- .../Hosts/Hosts.Tests/HostsServiceTest.cs | 29 +++++++++++++++++++ .../Hosts/Hosts/Settings/UserSettings.cs | 3 ++ .../Hosts/HostsUILib/Helpers/HostsService.cs | 2 +- .../HostsUILib/Settings/IUserSettings.cs | 2 ++ .../Settings.UI.Library/HostsProperties.cs | 4 +++ .../SettingsXAML/Views/HostsPage.xaml | 3 ++ .../Settings.UI/Strings/en-us/Resources.resw | 6 ++++ .../Settings.UI/ViewModels/HostsViewModel.cs | 13 +++++++++ 8 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs b/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs index 8eaa37a348..81052fd101 100644 --- a/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs +++ b/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs @@ -298,5 +298,34 @@ namespace Hosts.Tests var hidden = fileSystem.FileInfo.New(service.HostsFilePath).Attributes.HasFlag(FileAttributes.Hidden); Assert.IsTrue(hidden); } + + [TestMethod] + public async Task NoLeadingSpaces_Disabled_RemovesIndent() + { + var content = + @"10.1.1.1 host host.local # comment +10.1.1.2 host2 host2.local # another comment +"; + + var expected = + @"10.1.1.1 host host.local # comment +10.1.1.2 host2 host2.local # another comment +# 10.1.1.30 host30 host30.local # new entry +"; + + var fs = new CustomMockFileSystem(); + var settings = new Mock(); + settings.Setup(s => s.NoLeadingSpaces).Returns(true); + var svc = new HostsService(fs, settings.Object, _elevationHelper.Object); + fs.AddFile(svc.HostsFilePath, new MockFileData(content)); + + var data = await svc.ReadAsync(); + var entries = data.Entries.ToList(); + entries.Add(new Entry(0, "10.1.1.30", "host30 host30.local", "new entry", false)); + await svc.WriteAsync(data.AdditionalLines, entries); + + var result = fs.GetFile(svc.HostsFilePath); + Assert.AreEqual(expected, result.TextContents); + } } } diff --git a/src/modules/Hosts/Hosts/Settings/UserSettings.cs b/src/modules/Hosts/Hosts/Settings/UserSettings.cs index 3530a3f74b..75da5d214d 100644 --- a/src/modules/Hosts/Hosts/Settings/UserSettings.cs +++ b/src/modules/Hosts/Hosts/Settings/UserSettings.cs @@ -26,6 +26,8 @@ namespace Hosts.Settings private bool _loopbackDuplicates; + public bool NoLeadingSpaces { get; private set; } + public bool LoopbackDuplicates { get => _loopbackDuplicates; @@ -88,6 +90,7 @@ namespace Hosts.Settings AdditionalLinesPosition = (HostsAdditionalLinesPosition)settings.Properties.AdditionalLinesPosition; Encoding = (HostsEncoding)settings.Properties.Encoding; LoopbackDuplicates = settings.Properties.LoopbackDuplicates; + NoLeadingSpaces = settings.Properties.NoLeadingSpaces; } retry = false; diff --git a/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs b/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs index b07eb8f93c..83aa3544b1 100644 --- a/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs @@ -157,7 +157,7 @@ namespace HostsUILib.Helpers { lineBuilder.Append('#').Append(' '); } - else if (anyDisabled) + else if (anyDisabled && !_userSettings.NoLeadingSpaces) { lineBuilder.Append(' ').Append(' '); } diff --git a/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs b/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs index 21a8e6fa36..46c7a7dab5 100644 --- a/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs +++ b/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs @@ -19,5 +19,7 @@ namespace HostsUILib.Settings event EventHandler LoopbackDuplicatesChanged; public delegate void OpenSettingsFunction(); + + public bool NoLeadingSpaces { get; } } } diff --git a/src/settings-ui/Settings.UI.Library/HostsProperties.cs b/src/settings-ui/Settings.UI.Library/HostsProperties.cs index 90a576601d..6ec9924049 100644 --- a/src/settings-ui/Settings.UI.Library/HostsProperties.cs +++ b/src/settings-ui/Settings.UI.Library/HostsProperties.cs @@ -24,6 +24,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library public HostsEncoding Encoding { get; set; } + [JsonConverter(typeof(BoolPropertyJsonConverter))] + public bool NoLeadingSpaces { get; set; } + public HostsProperties() { ShowStartupWarning = true; @@ -31,6 +34,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library LoopbackDuplicates = false; AdditionalLinesPosition = HostsAdditionalLinesPosition.Top; Encoding = HostsEncoding.Utf8; + NoLeadingSpaces = false; } } } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml index 2d0a6d0c2d..6ceffa96d4 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/HostsPage.xaml @@ -56,6 +56,9 @@ + + + diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index 76f15a390c..c31076bb83 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -5127,4 +5127,10 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m Back key + + No leading spaces + + + Do not prepend spaces to active lines when saving the hosts file + \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs index d2bfb989e7..34b6157d63 100644 --- a/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/HostsViewModel.cs @@ -105,6 +105,19 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public bool NoLeadingSpaces + { + get => Settings.Properties.NoLeadingSpaces; + set + { + if (value != Settings.Properties.NoLeadingSpaces) + { + Settings.Properties.NoLeadingSpaces = value; + NotifyPropertyChanged(); + } + } + } + public int AdditionalLinesPosition { get => (int)Settings.Properties.AdditionalLinesPosition; From 7b06fb3bdb609f1147aa87dd8b18588765d2f855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Pol=C3=A1=C5=A1ek?= Date: Tue, 19 Aug 2025 08:32:16 +0200 Subject: [PATCH 2/9] CmdPal: Remove constrain that keeps the context menu flyout in the bounds of the window (#41133) ## Summary of the Pull Request Added `ShouldConstrainToRootBounds="False"` to the Flyout element, allowing it to extend beyond the bounds of its parent container. This allows the menu to always open with top-left corner at the cursor position as is common for the context menus. This affects the menu only when opened as a context menu on the list item (e.g. mouse right-click), not when opened from the Command Bar (that opens same as before). After screenshot: image ## PR Checklist - [x] Closes: #41131 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml index 107db49939..49fef61ecb 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml @@ -47,7 +47,8 @@ + Opened="ContextMenuFlyout_Opened" + ShouldConstrainToRootBounds="False"> From a0a8ce9f6926edf13dce885569da0dde85bf46a8 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Tue, 19 Aug 2025 11:32:28 +0200 Subject: [PATCH 3/9] Adding Office / Copilot templates to KeyVisual (#41167) Small change for #41161. For shortcuts in Settings, I guess we need to figure out later how the Copilot/Office keys are mapped in our shortcuts, but at least we have the right visual templates available. --- .../Controls/KeyVisual/KeyCharPresenter.xaml | 34 +++++++++++++++++++ .../Controls/KeyVisual/KeyVisual.xaml.cs | 18 ++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyCharPresenter.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyCharPresenter.xaml index c45f1ba0d2..a28874b4ee 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyCharPresenter.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyCharPresenter.xaml @@ -49,6 +49,40 @@ + +