Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ is not part of this repository.
restart of the machine.
- The JSON of a plan carries `delayedAuto` next to `startType`, the same way `bws list --json`
does, and `alsoStop` for a plan that also stops.
- A Help button in the top right corner, also opened with F1. It lists the keyboard shortcuts -
each item does what its key does - opens the query language page and the project's website in
your browser, and shows the version of the program, which you can copy.
- A Help button in the top right corner, also opened with F1. It opens the query language page
on the project's website in your browser.
- After the list is exported, the foot of the window says how many entries went into which file.
The sentence goes away as soon as you change the search.
- "Set startup type" in the row menu, with the same four settings as the action bar.
Expand Down Expand Up @@ -72,6 +71,14 @@ is not part of this repository.
both, and rows narrow each other. The row labels no longer repeat the same tooltip.
- The row menu names its actions the way the action bar does: "Stop...", "Start...",
"Restart...", "Force stop..." and "Force restart...". Each still opens a plan first.
- "Show the list" on the machine overview is a blue button, so it is easy to find the first time
the window opens.
- In the plan panel, the name of the entry stands out in bold in the title and in every step.

### Removed

- "Copy display name" and "Copy description" from the row menu. Both are still copied by "Copy
everything".

### Fixed

Expand Down
18 changes: 5 additions & 13 deletions src/Bws.Gui/ExternalLinks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
namespace Bws.Gui;

/// <summary>
/// The addresses this window hands to a browser, and the two ways it hands them over. One until
/// 2026-09-24 - the support page - and three since the help menu (UX-GUI-014) offered the project's
/// website and its query language page.
/// The addresses this window hands to a browser, and the two ways it hands them over: the support
/// page and the query language page. The help menu (UX-GUI-014) offered the project's website as a
/// third for one day, 2026-09-24.
///
/// <b>THE SECOND FILE IN THIS WINDOW ALLOWED TO START SOMETHING, and that is the owner's decision
/// of 2026-09-23 rather than an arrangement of mine.</b> <see cref="Elevation"/> was the only one
Expand Down Expand Up @@ -88,29 +88,21 @@ internal static class ExternalLinks
/// </summary>
internal static Task<string?> OpenSupportAsync() => Supporting.Ask();

/// <summary>The project's website, from the help menu - UX-GUI-014, 2026-09-24.</summary>
internal const string ProjectPage = "https://betterwindowsservices.donislawdev.com/";

/// <summary>
/// The page describing the query language, from the help menu. The same address the README
/// gives, so a person who found it there finds the same page here.
/// </summary>
internal const string QueryLanguagePage = "https://betterwindowsservices.donislawdev.com/query-language/";

/// <summary>
/// The two pages the help menu offers, each with a hand-over of its own for the reason
/// The page the help menu offers, with a hand-over of its own for the reason
/// <see cref="Supporting"/> has one: a second press while the shell still has the first joins
/// it rather than starting another. THE SAME TWO WAYS AS THE SUPPORT PAGE AND NO THIRD - an
/// elevated window hands the address to the desktop, and this adds no call into the shell.
/// The project's website had one beside it until 2026-09-24, when it left the menu.
/// </summary>
private static readonly ShellHandover Project = Page(ProjectPage);

/// <inheritdoc cref="Project"/>
private static readonly ShellHandover QueryLanguage = Page(QueryLanguagePage);

/// <summary>Hands the project's website to a browser, or says why it did not.</summary>
internal static Task<string?> OpenProjectPageAsync() => Project.Ask();

/// <summary>Hands the query language page to a browser, or says why it did not.</summary>
internal static Task<string?> OpenQueryLanguagePageAsync() => QueryLanguage.Ask();

Expand Down
76 changes: 19 additions & 57 deletions src/Bws.Gui/HelpMenu.cs
Original file line number Diff line number Diff line change
@@ -1,72 +1,34 @@
namespace Bws.Gui;

/// <summary>
/// What the Help button offers: the keyboard shortcuts, the two pages on the project's website, and
/// the version of this program. UX-GUI-014 with the shortcut half of UX-GUI-010, owner's decision
/// 2026-09-24 - until that day the window named Ctrl+F, Ctrl+C and Ctrl+A nowhere and said its own
/// version nowhere.
/// What the Help button offers: the query language page on the project's website, and nothing
/// else since 2026-09-24 - owner's decision.
///
/// <b>A LIST OF DATA BUILT BY <see cref="RowMenu.Build"/>, NOT A SECOND MENU WRITTEN OUT</b> - GUI
/// rules 2 and 8. An item here has exactly the shape of an item on a row: words, a key written
/// beside them, and what a press does. So it is the row menu's entry and the row menu's item style,
/// and the name "row" on them is the one place this reuse shows.
/// <b>IT HELD NINE ITEMS FOR ONE DAY.</b> UX-GUI-014 built it earlier the same day with the six
/// keyboard shortcuts, the project's website and the version of this program, and the owner cut it
/// to this one. The price is said rather than left for somebody to find: F5, Ctrl+F,
/// Ctrl+A and Esc are named in no text of the window again (the half of UX-GUI-010 this menu had
/// answered), and the window no longer says its own version - `bws --version` does. Ctrl+C and
/// Enter are still written beside their items in the row menu.
///
/// <b>STILL A MENU WITH ONE ITEM RATHER THAN A BUTTON THAT OPENS THE PAGE</b> - owner's choice
/// between the two. A press on "Help" that leaves the program for a browser with nothing in between
/// would be a surprise, and a menu can take a second item back without the button changing what
/// it does.
///
/// <b>EVERY SHORTCUT ITEM DOES WHAT IT NAMES, through the same <see cref="MainWindow.Act"/> the key
/// goes through.</b> A menu that described the keys while a second road carried them out would be
/// two answers to one question, which this window was caught by on 2026-09-02. The one exception is
/// Ctrl+A, which is the grid's own key rather than one of ours, and the item asks the grid for the
/// same thing.
/// <b>A LIST OF DATA BUILT BY <see cref="RowMenu.Build"/>, NOT A SECOND MENU WRITTEN OUT</b> - GUI
/// rules 2 and 8, and the item is the row menu's entry for that reason.
///
/// <b>The two pages go out through <see cref="ExternalLinks"/> and nothing else</b>, exactly as
/// Donate does - an elevated window hands the address to the desktop, and this program still
/// connects to nothing (`ADR-19`).
/// <b>The page goes out through <see cref="ExternalLinks"/> and nothing else</b>, exactly as Donate
/// does - an elevated window hands the address to the desktop, and this program still connects to
/// nothing (`ADR-19`).
/// </summary>
internal static class HelpMenu
{
internal static IReadOnlyList<IReadOnlyList<RowMenuEntry>> GroupsFor(MainWindow window) =>
[
[
new RowMenuEntry("gui.help.find", "gui.help.find.gesture", () => Pressed(window, Shortcut.FocusQuery)),
new RowMenuEntry("gui.help.refresh", "gui.help.refresh.gesture", () => Pressed(window, Shortcut.Refresh)),
new RowMenuEntry("gui.help.details", "gui.menu.details.gesture", () => Pressed(window, Shortcut.OpenDetails)),
new RowMenuEntry("gui.help.copy", "gui.menu.copyAll.gesture", () => Pressed(window, Shortcut.CopyRow)),
new RowMenuEntry("gui.help.selectAll", "gui.help.selectAll.gesture", () => Task.FromResult(window.SelectEverything())),
new RowMenuEntry("gui.help.back", "gui.help.back.gesture", () => Pressed(window, Shortcut.Back))
],
[
new RowMenuEntry("gui.help.queryLanguage", null, () => window.OpenPage(ExternalLinks.OpenQueryLanguagePageAsync)),
new RowMenuEntry("gui.help.projectPage", null, () => window.OpenPage(ExternalLinks.OpenProjectPageAsync))
],
[
new RowMenuEntry("gui.help.version", null, () => Copied(window), () => VersionNumber)
new RowMenuEntry("gui.help.queryLanguage", null, () => window.OpenPage(ExternalLinks.OpenQueryLanguagePageAsync))
]
];

/// <summary>
/// What the version item says and copies: the stamped number, or words saying there is none -
/// rule 8 of CLAUDE.md applied to one number rather than a guess that looks like one.
/// </summary>
internal static string VersionNumber => Release.Number ?? Texts.Of("gui.help.versionUnknown");

/// <summary>
/// A press of the key the item names. The work the key starts travels with it, so an item
/// that reads the machine again is awaited as the key's own press is.
/// </summary>
private static Task Pressed(MainWindow window, Shortcut shortcut)
{
window.Act(shortcut, out var work);

return work;
}

/// <summary>
/// The version on the clipboard, for somebody reporting a fault. A refusal from the clipboard is
/// said in the status line by <see cref="MainWindow.Put"/>, as it is for a copied row.
/// </summary>
private static Task Copied(MainWindow window)
{
window.Put(VersionNumber);

return Task.CompletedTask;
}
}
18 changes: 3 additions & 15 deletions src/Bws.Gui/MainWindow.Help.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
namespace Bws.Gui;

/// <summary>
/// The window's half of the Help button: the menu under it, F1, and the two things the menu does
/// that are not a key press already - UX-GUI-014, owner's decision 2026-09-24.
/// The window's half of the Help button: the menu under it, F1, and opening the page the menu
/// offers - UX-GUI-014, owner's decision 2026-09-24.
///
/// <b>A partial of its own because the constructor is at the analyser's length</b>, the reason
/// MainWindow.Overview.cs gives for the same shape: one line there, and the wiring here. What the
Expand All @@ -15,8 +15,7 @@ public partial class MainWindow
/// <summary>
/// Hangs the help menu under its button. Called once, from the constructor.
///
/// <b>Built with the row menu's builder and the row menu's item style</b>, which is what makes
/// the key beside each shortcut appear - the style binds InputGestureText, and HelpMenu says why
/// <b>Built with the row menu's builder and the row menu's item style</b>, and HelpMenu says why
/// the entry is the row's.
/// </summary>
private void IntroduceTheHelp()
Expand All @@ -31,17 +30,6 @@ private void IntroduceTheHelp()
/// </summary>
internal bool OpenHelp() => ButtonMenu.OpenUnder(Scope.Help);

/// <summary>
/// Picks every entry in the list - what Ctrl+A does in the grid, asked of the grid rather than
/// done a second way, so the menu item and the key are the same act.
/// </summary>
internal bool SelectEverything()
{
Entries.SelectAll();

return true;
}

/// <summary>
/// Hands one of the project's pages to a browser through <see cref="ExternalLinks"/>, and says
/// in the status line why it did not when it did not - the same shape as the Donate button.
Expand Down
17 changes: 9 additions & 8 deletions src/Bws.Gui/OverviewView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,7 @@
ending at three heights read as a mistake rather than as three independent things.
A row of equal cards is a row, a ragged one is a pile.
-->
<Border Background="{StaticResource SurfacePanel}"
BorderBrush="{StaticResource SurfacePanelEdge}"
BorderThickness="{StaticResource BorderAllSides}"
CornerRadius="{StaticResource CornerTile}"
Margin="{StaticResource MarginTile}"
Padding="{StaticResource PadTile}">
<Border Style="{StaticResource OverviewCard}">
<StackPanel>

<Button Style="{StaticResource OverviewNumber}"
Expand Down Expand Up @@ -223,8 +218,13 @@
The exit must not depend on the height of anything, and the top of a scroll is
the one place that holds at every size. Wrapping arrived after, as 277.

AND IT DOES NOT WEAR THE ACCENT, backlog 270, truer up here rather than less:
this is the way OFF the screen, not its action.
AND IT WEARS THE ACCENT AGAIN SINCE 2026-09-24, on the owner's words that on a
first run it was hidden in the background. Backlog 270 took the accent off on
2026-09-01 for two reasons. One was a fault - the accent was a local Background
that the library's template beat under the pointer - and PrimaryAction, which
owns its template, cannot repeat it. The other was that the cards are the
content and the way off should be quieter. A first-time user who cannot find
the way to the list is the answer to that.
-->
<!--
THE GRID STRETCHES AND THE TITLE INSIDE IT DOES NOT, which is how the exit ends
Expand Down Expand Up @@ -252,6 +252,7 @@
Content="{DynamicResource gui.overview.dismiss}"
ToolTip="{DynamicResource gui.overview.dismiss.hint}"
VerticalAlignment="Center"
Style="{StaticResource PrimaryAction}"
Click="Dismiss" />
</Grid>

Expand Down
15 changes: 13 additions & 2 deletions src/Bws.Gui/PlanView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,22 @@
203.
-->
<StackPanel Grid.Column="0" Margin="{StaticResource MarginGroup}">
<!--
THE NAME SET APART SINCE 2026-09-24 - three runs, the middle one wearing
NameInSentence, on one line because whitespace between inlines is a space
on screen. Themes/PlanLines.xaml says the same about the steps.

AND THE NAME FOR A SCREEN READER IS BOUND, BECAUSE RUNS TAKE IT AWAY. A
TextBlock built from runs answers Text with an empty string - measured on
the first build of this, where every test reading the title read nothing -
and its automation peer names it from Text. Without this line the title
would be silent to Narrator and to every probe reading it by name.
-->
<TextBlock x:Name="PlanHeading"
AutomationProperties.AutomationId="planHeading"
Text="{Binding Heading}"
AutomationProperties.Name="{Binding Heading.Text}"
TextWrapping="Wrap"
Style="{StaticResource PlanTitleText}" />
Style="{StaticResource PlanTitleText}"><Run Text="{Binding Heading.Before, Mode=OneWay}" /><Run Text="{Binding Heading.Name, Mode=OneWay}" Style="{StaticResource NameInSentence}" /><Run Text="{Binding Heading.After, Mode=OneWay}" /></TextBlock>

<!--
THE MANAGER'S OWN NAME IN THE FIXED FACE SINCE 2026-09-02: this is the
Expand Down
38 changes: 0 additions & 38 deletions src/Bws.Gui/Release.cs

This file was deleted.

17 changes: 1 addition & 16 deletions src/Bws.Gui/Resources/gui.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,6 @@
"gui.menu.details": "Show details",
"gui.menu.details.gesture": "Enter",
"gui.menu.copyName": "Copy name",
"gui.menu.copyDisplayName": "Copy display name",
"gui.menu.copyDescription": "Copy description",
"gui.menu.copyAll": "Copy everything",
"gui.menu.copyAll.gesture": "Ctrl+C",

Expand All @@ -368,21 +366,8 @@
"gui.support.slow": "Windows has not finished opening the support page, so it may still open by itself. It is at {0}, and any browser you open yourself will show it.",

"gui.help.button": "Help",
"gui.help.hint": "The keyboard shortcuts, the query language, the project's website and the version of this program. F1 opens this too. This tool itself connects to nothing, and the two pages open in your browser.",
"gui.help.find": "Search the list",
"gui.help.find.gesture": "Ctrl+F",
"gui.help.refresh": "Read the machine again",
"gui.help.refresh.gesture": "F5",
"gui.help.details": "Show details of the selected entry",
"gui.help.copy": "Copy everything about the selected entries",
"gui.help.selectAll": "Select every entry in the list",
"gui.help.selectAll.gesture": "Ctrl+A",
"gui.help.back": "Close what is open, or clear the search",
"gui.help.back.gesture": "Esc",
"gui.help.hint": "The query language, on the project's website. F1 opens this too. This tool itself connects to nothing, and the page opens in your browser.",
"gui.help.queryLanguage": "The query language, on the project's website",
"gui.help.projectPage": "The project's website",
"gui.help.version": "Version {0} - copy it",
"gui.help.versionUnknown": "not stamped on this build",
"gui.link.failed": "The page did not open. {0} It is at {1}, and any browser you open yourself will show it.",
"gui.link.slow": "Windows has not finished opening the page, so it may still open by itself. It is at {0}, and any browser you open yourself will show it.",

Expand Down
Loading
Loading