Public Access
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ee2aacdc9 | ||
|
|
dec2cf164a |
No files matched your search
@@ -256,8 +256,8 @@ registered in the capture phase, that no native menu is drawn once it is prevent
|
||||
|
||||
Close DodoSSH and start it again. Watch the first second.
|
||||
|
||||
**Pass:** a small panel — about 420 pixels wide, no titlebar — appears saying **DodoSSH** and *Starting…*
|
||||
with a bar moving under it, and is then replaced by the main window. Measured on a debug build against a cold
|
||||
**Pass:** a small panel — about 420 pixels wide, no titlebar — appears saying **DodoSSH** and *Starting…*,
|
||||
and is then replaced by the main window. Measured on a debug build against a cold
|
||||
profile: the panel at 668 ms, the window at 3.1 s. A release install is quicker and the shape is the same.
|
||||
What must never come back is the old behaviour, which was nothing at all on screen for the whole of it.
|
||||
|
||||
@@ -270,8 +270,12 @@ over whatever you gave up and went back to.
|
||||
*directory* where `cache.db` should be — `%LOCALAPPDATA%\DodoSSH.Nightly\cache.db` for the nightly — and
|
||||
start the application.
|
||||
|
||||
**Pass:** the panel stays, the bar stops moving, and it reads *DodoSSH could not start:* followed by the
|
||||
reason and *Press Escape to close.* Escape closes it. Remove the directory afterwards.
|
||||
**Pass:** the panel stays and the line becomes *DodoSSH could not start:* followed by the reason and
|
||||
*Press Escape to close.* Escape closes it. Remove the directory afterwards.
|
||||
|
||||
There is deliberately nothing else on the card to contradict that line — the progress bar this check used to
|
||||
describe was taken off in "Take the frozen bar off the splash, and leave the line that is true", because an
|
||||
indeterminate bar over a composition that had stopped was the one thing a splash must never do.
|
||||
|
||||
**Failure means:** a panel left saying *Starting…* is the main window having failed to show with nothing
|
||||
catching it, which is the one outcome worse than the crash it replaced — `DodoSshApp.ComposeBehind` exists to
|
||||
|
||||
@@ -111,13 +111,33 @@
|
||||
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Spacing="18" MaxWidth="460"
|
||||
Margin="24">
|
||||
|
||||
<!--
|
||||
Which machine, and at what address. Both selectable, for the reason the session column's own address
|
||||
is — see SessionSidebar.axaml: a TextBlock in Avalonia is a drawing of a string rather than a string,
|
||||
and this pair is the one place the shell says what it is dialling *before* anything has answered.
|
||||
That is exactly when the value is wanted somewhere else: in a ticket, in a message to whoever owns
|
||||
the host, in the ssh command being written in the window beside this one. It is also the moment it is
|
||||
least available anywhere else, because there is no prompt yet and may never be one — a refused
|
||||
connection leaves this card holding the only copy on screen.
|
||||
|
||||
Both rather than only the name. They are two lines of one identifier, and a pair where the first can
|
||||
be taken and the second cannot is a worse answer than either.
|
||||
|
||||
The trimming stays, and the tooltips are what make it safe rather than a trap. A drag reaches only
|
||||
the glyphs that were drawn, so a name or an address wearing an ellipsis has to be taken with
|
||||
select-all — Ctrl+A, then Ctrl+C — which takes the whole value, because the ellipsis is a drawing and
|
||||
not a shorter string. The hover says what the whole value is, so nobody copies half of one without
|
||||
having been told there is a half. Same argument, same shape, as the sidebar's.
|
||||
-->
|
||||
<StackPanel Spacing="6" HorizontalAlignment="Center">
|
||||
<TextBlock Classes="mono" Text="{Binding SelectedTab.Label}" FontSize="16" FontWeight="Medium"
|
||||
Foreground="{StaticResource Text}" HorizontalAlignment="Center"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock Classes="mono" Text="{Binding SelectedTab.Address}" FontSize="11.5"
|
||||
Foreground="{StaticResource TextFaint}" HorizontalAlignment="Center"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<SelectableTextBlock Classes="mono" Text="{Binding SelectedTab.Label}" FontSize="16"
|
||||
FontWeight="Medium" Foreground="{StaticResource Text}"
|
||||
HorizontalAlignment="Center" TextTrimming="CharacterEllipsis"
|
||||
ToolTip.Tip="{Binding SelectedTab.Label}" />
|
||||
<SelectableTextBlock Classes="mono" Text="{Binding SelectedTab.Address}" FontSize="11.5"
|
||||
Foreground="{StaticResource TextFaint}" HorizontalAlignment="Center"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
ToolTip.Tip="{Binding SelectedTab.Address}" />
|
||||
</StackPanel>
|
||||
|
||||
<!--
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
CanResize="False"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Background="{StaticResource Chrome}"
|
||||
SystemDecorations="None">
|
||||
WindowDecorations="None">
|
||||
|
||||
<!--
|
||||
── WHY THERE IS A SPLASH AT ALL ───────────────────────────────────────────────────────────────────────
|
||||
@@ -30,8 +30,10 @@
|
||||
look to find out whether anything is happening says nothing. It is a window, briefly, and behaves like
|
||||
one.
|
||||
|
||||
SystemDecorations="None" rather than BorderOnly, which the main window uses: this cannot be resized, has
|
||||
no titlebar of its own to drag by, and lives for about a second. What replaces the frame is the card's
|
||||
WindowDecorations="None" rather than the BorderOnly the main window asks for: this cannot be resized, has
|
||||
no titlebar of its own to drag by, and lives for about a second. (The main window still says
|
||||
SystemDecorations, which Avalonia 12 has deprecated in favour of this property; that one is not this
|
||||
change's to move.) What replaces the frame is the card's
|
||||
own one-pixel border. Escape closes it only once there is nothing left to wait for — see the code-behind.
|
||||
|
||||
── SizeToContent, WHICH IS ABOUT THE FAILURE AND NOT ABOUT THE SPLASH ─────────────────────────────────
|
||||
|
||||
@@ -942,6 +942,49 @@ public sealed class ScreenLayoutTests : IAsyncLifetime
|
||||
await MeasureConnectingAsync(faults => faults.ShouldBeEmpty("with a refusal to explain"), tab);
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The card is the one place the shell says what it is dialling <em>before</em> anything answers, and on a
|
||||
/// refusal it is the only copy of that on screen — so both lines are there to be taken away, and a
|
||||
/// <c>TextBlock</c> in Avalonia is a drawing of a string rather than a string. Same change, same argument,
|
||||
/// as the session column's own address; see <c>SessionSidebarTests</c>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Asserted on values long enough to be trimmed, which is the half that could quietly break: an ellipsis
|
||||
/// is a drawing and not a shorter string, so select-all has to reach the whole name and the whole address
|
||||
/// rather than the part that happened to fit inside the card's 460 pixels. Values that fit would pass
|
||||
/// whether that were true or not.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
[Fact]
|
||||
public async Task TheConnectingCardsNameAndAddressSelectAndCopyWhole()
|
||||
{
|
||||
const string label = "customer-production-database-01.eu-west-1.internal.example.company";
|
||||
const string address = "a-very-long-deploy-account@db-primary.eu-west-1.internal.example:22022";
|
||||
|
||||
await OnTheConnectingCardAsync(
|
||||
card =>
|
||||
{
|
||||
// Found by their text rather than by position: the order is the visual tree's, and a third
|
||||
// selectable block is already in there — the refusal reason, hidden while this tab is only
|
||||
// connecting. Single rather than First, so a duplicate would be a question rather than a
|
||||
// silent pick.
|
||||
var takeable = card.GetVisualDescendants().OfType<SelectableTextBlock>().ToList();
|
||||
|
||||
var name = takeable.Single(block => block.Text == label);
|
||||
var endpoint = takeable.Single(block => block.Text == address);
|
||||
|
||||
name.SelectAll();
|
||||
name.SelectedText.ShouldBe(label, "the ellipsis is a drawing, not a shorter string");
|
||||
name.CanCopy.ShouldBeTrue("Ctrl+C and the right-click Copy item are both gated on this");
|
||||
|
||||
endpoint.SelectAll();
|
||||
endpoint.SelectedText.ShouldBe(address, "the ellipsis is a drawing, not a shorter string");
|
||||
endpoint.CanCopy.ShouldBeTrue("Ctrl+C and the right-click Copy item are both gated on this");
|
||||
},
|
||||
new TerminalTabViewModel(label, address));
|
||||
}
|
||||
|
||||
// ---- The logs screen ----
|
||||
|
||||
[Fact]
|
||||
@@ -2043,6 +2086,40 @@ public sealed class ScreenLayoutTests : IAsyncLifetime
|
||||
},
|
||||
Token);
|
||||
|
||||
/// <summary>Lays the connecting card out and hands it over, rather than measuring it.</summary>
|
||||
/// <remarks>
|
||||
/// The same rectangle <see cref="MeasureConnectingAsync"/> uses and for the same reasons — see its
|
||||
/// remark. Separate because the claim is about a control's own state rather than about where anything was
|
||||
/// arranged, and threading an assertion over the card through a method whose parameter is a fault list
|
||||
/// would make both callers harder to read than two methods are.
|
||||
/// </remarks>
|
||||
private Task OnTheConnectingCardAsync(Action<ConnectingCard> body, TerminalTabViewModel tab) =>
|
||||
LayoutHarness.OnTheUiThreadAsync(
|
||||
() =>
|
||||
{
|
||||
shell.State = ShellState.Unlocked;
|
||||
shell.Tabs.Clear();
|
||||
shell.Tabs.Add(tab);
|
||||
shell.SelectedTab = tab;
|
||||
|
||||
var card = new ConnectingCard { DataContext = shell };
|
||||
|
||||
var window = LayoutHarness.HostAtMinimumSize(
|
||||
card,
|
||||
LayoutHarness.SessionScreenWidth(sidebarVisible: true),
|
||||
LayoutHarness.SessionScreenHeight);
|
||||
|
||||
try
|
||||
{
|
||||
body(card);
|
||||
}
|
||||
finally
|
||||
{
|
||||
window.Close();
|
||||
}
|
||||
},
|
||||
Token);
|
||||
|
||||
/// <summary>Lays the host-key decision out in the rectangle it is drawn over.</summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
|
||||
Reference in new issue
Block a user