Public Access
The indeterminate bar did not move, and it was never going to. Composition is a synchronous block and DodoSshApp posts it to the very dispatcher that would have to animate it: Background priority buys the splash its first paint and nothing after it, because once composition starts the UI thread is inside it until the main window is ready, and a ProgressBar's indeterminate animation is driven by that thread's clock. One frame, then ~2.4 seconds of stillness — the whole of the time the window is on screen. A frozen indeterminate bar does not read as indeterminate. It reads as a determinate bar stuck at zero, which is worse than no bar at all: it says the work has stalled at the moment the application is busiest, which is the one thing a splash must never say. Freeing the UI thread would have been the other fix, and it is a real one — the I/O in Compose has no business on that thread. It is also a rework of startup for the sake of an ornament. There is nothing here that can honestly be measured anyway: a SQLite open, a loopback bind, a TPM probe and an install-layout read report no progress between them. So the bar goes. "Starting…" was already on the card, it is true for as long as the card is up, it needs no clock to stay true, and the window closing is what says it finished. CouldNotStart is one assignment now — it used to have to stop the bar as well, so that nothing went on claiming to work over a process that had died, and there is no longer anything on the card that could. The window keeps its MinHeight, which is what stops two lines of content collapsing it, and the failure path keeps SizeToContent for the same reason it always had it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
55 lines
3.1 KiB
XML
55 lines
3.1 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
x:Class="DodoSSH.Client.App.Views.SplashCard">
|
|
|
|
<!--
|
|
What is on screen while the application composes itself.
|
|
|
|
── WHY THIS IS ITS OWN CONTROL ────────────────────────────────────────────────────────────────────────
|
|
|
|
The same reason UpdateBanner is: a Window cannot be laid out by the headless suite when it contains a
|
|
WebView, and while this one does not, a UserControl is what LayoutHarness can host and measure. See
|
|
SplashCardTests. It also keeps the window itself down to a frame and a size.
|
|
|
|
── AND WHY THERE IS NO VIEW MODEL ─────────────────────────────────────────────────────────────────────
|
|
|
|
There is nothing to observe. Composition is one synchronous block — see DodoSshApp.ComposeBehind — so
|
|
this control has exactly two states, both of them set by the one caller: starting, and could not. Two
|
|
methods on the code-behind is the whole of it, and a view model would be an observable object with a
|
|
lifetime and a test of its own standing in for two assignments.
|
|
-->
|
|
<Border Background="{StaticResource Chrome}"
|
|
BorderBrush="{StaticResource Border}"
|
|
BorderThickness="1">
|
|
|
|
<StackPanel Margin="28" Spacing="12" VerticalAlignment="Center">
|
|
|
|
<TextBlock Classes="heading" Text="DodoSSH" />
|
|
|
|
<TextBlock x:Name="Line" Classes="hint" Text="Starting…" />
|
|
|
|
<!--
|
|
── AND NO PROGRESS BAR, WHICH IS A REMOVAL RATHER THAN AN OMISSION ─────────────────────────────────
|
|
|
|
There was an indeterminate one here, and on screen it did not move. The reason is the same fact this
|
|
whole window exists for: composition is a synchronous block, and DodoSshApp posts it to the very
|
|
dispatcher that would have to animate the bar. Background priority buys the splash its first paint
|
|
and nothing after it — once composition starts, the UI thread is inside it until the main window is
|
|
ready, and an indeterminate bar's animation is driven by that thread's clock. So it painted one
|
|
frame and froze.
|
|
|
|
A frozen indeterminate bar does not read as "indeterminate". It reads as a determinate bar stuck at
|
|
zero, which is the one thing worse than no bar at all: it says the work has stalled at the exact
|
|
moment the application is busiest. Nothing here can honestly be measured either — a SQLite open, a
|
|
loopback bind, a TPM probe and an install-layout read report no progress between them.
|
|
|
|
So the line above is the whole of it. "Starting…" is true for as long as it is on screen, it needs
|
|
no clock to stay true, and the window closing is what says it finished.
|
|
-->
|
|
|
|
</StackPanel>
|
|
|
|
</Border>
|
|
|
|
</UserControl>
|