Stufe 3 (#764): Avalonia-Fenster entfernt
- Views, ViewModels, Controls, Converters, Styles, Services, Desktop-i18n, Schriften und App.axaml raus; Avalonia- und Mvvm-Pakete raus - ClawdDotNet ohne Schalter: Manager starten (unter systemd ueber den Dienst, nie doppelt) und WebUI oeffnen (LauncherRun) - bis die Huelle kommt - Instanzen laufen immer kopflos; instanceWindows wird gelesen, nicht mehr ausgewertet; die Kette 'Fenster nach vorn holen' ist entfernt - Telegram-Anmeldung nur noch ueber die WebUI (tote Dialog-Rueckrufe raus) - systemd-Vorlagen im Linux-Paket; Oberflaechen-Leitfaden ins Archiv Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8ec7896417
commit
6d81693041
@@ -186,16 +186,4 @@ internal sealed class FakeChannel : IInstanceChannel
|
||||
OnStopRequest?.Invoke(instanceDirectory);
|
||||
return Task.FromResult(StopRequestArrives);
|
||||
}
|
||||
|
||||
/// <summary>Welche Instanzen gebeten wurden, ihr Fenster nach vorn zu holen.</summary>
|
||||
public List<string> FocusRequests { get; } = [];
|
||||
|
||||
/// <summary>Ob die Instanz ein Fenster hat, das nach vorn kommen kann.</summary>
|
||||
public bool HasWindow { get; set; } = true;
|
||||
|
||||
public Task<bool> RequestFocusAsync(string instanceDirectory, CancellationToken ct = default)
|
||||
{
|
||||
FocusRequests.Add(Path.GetFullPath(instanceDirectory));
|
||||
return Task.FromResult(HasWindow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,98 +222,3 @@ public sealed class ManagerCoreTests : IAsyncDisposable
|
||||
(await manager.StartInstanceAsync(pfad)).ShouldBe(StartRefusal.DidNotStart);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Der Wechsel, wie E-M2 ihn meint (#528, Stufe 5).
|
||||
///
|
||||
/// <para><b>Vorher hiess „Instanz wechseln":</b> Der laufende Prozess fährt sich herunter
|
||||
/// und startet sich mit einer anderen Instanz neu. Wer wechselte, beendete zwangsläufig
|
||||
/// die Instanz, aus der heraus er es tat — und genau dabei hat sich am 2026-09-08 die
|
||||
/// Anwendung aufgehängt (#529). Jetzt laufen alle, und es kommt nur eine nach vorn.</para>
|
||||
/// </summary>
|
||||
public sealed class InstanceFocusTests : IAsyncDisposable
|
||||
{
|
||||
private readonly string _root = Path.Combine(
|
||||
Path.GetTempPath(), "clawd-tests", "focus-" + Guid.NewGuid().ToString("N")[..8]);
|
||||
|
||||
private readonly FakeLauncher _launcher = new();
|
||||
private readonly FakeChannel _kanal = new();
|
||||
private readonly InstanceDirectoryManager _verzeichnisse;
|
||||
|
||||
private static readonly SupervisionOptions Options = new(
|
||||
ProbeInterval: TimeSpan.FromMilliseconds(50),
|
||||
StartTimeout: TimeSpan.FromMilliseconds(600),
|
||||
SilentChecksBeforeAlarm: 3,
|
||||
StopGrace: TimeSpan.FromMilliseconds(300),
|
||||
SilentKillGrace: TimeSpan.FromMilliseconds(300),
|
||||
MaxDrainWait: TimeSpan.FromSeconds(2));
|
||||
|
||||
public InstanceFocusTests()
|
||||
{
|
||||
Directory.CreateDirectory(_root);
|
||||
_verzeichnisse = new InstanceDirectoryManager(Path.Combine(_root, "Instances"));
|
||||
// Der Socket antwortet nur, wenn wirklich ein Prozess laeuft - genau wie im
|
||||
// Betrieb (siehe FakeChannel.Launcher).
|
||||
_kanal.Launcher = _launcher;
|
||||
}
|
||||
|
||||
private InstanceRegistry Register() => new(
|
||||
_verzeichnisse, _launcher, _kanal, NullLoggerFactory.Instance, Options);
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
try { Directory.Delete(_root, recursive: true); }
|
||||
catch { /* Ein liegengebliebener Testordner faerbt keinen Lauf rot. */ }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Eine_laufende_Instanz_wird_nach_vorn_geholt()
|
||||
{
|
||||
await using var register = Register();
|
||||
var pfad = register.Create("Alpha");
|
||||
|
||||
_kanal.AnswerFor[Path.GetFullPath(pfad)] = new InstanceIdentity("i-1", "Alpha", "0.1.2");
|
||||
await register.StartAsync(pfad);
|
||||
|
||||
(await register.FocusAsync(pfad)).ShouldBeTrue();
|
||||
|
||||
_kanal.FocusRequests.ShouldBe([Path.GetFullPath(pfad)]);
|
||||
|
||||
// Und vor allem: Es wurde nichts beendet und nichts neu gestartet.
|
||||
_launcher.Starts.ShouldBe(1);
|
||||
_kanal.StopRequests.ShouldBe(0);
|
||||
_launcher.Last!.HasExited.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Eine_Instanz_die_nicht_laeuft_hat_kein_Fenster()
|
||||
{
|
||||
await using var register = Register();
|
||||
var pfad = register.Create("Alpha");
|
||||
|
||||
(await register.FocusAsync(pfad)).ShouldBeFalse();
|
||||
|
||||
// Nicht einmal gefragt: Wer nicht laeuft, antwortet auch nicht.
|
||||
_kanal.FocusRequests.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eine kopflose Instanz hat nichts nach vorn zu holen — und sagt das, statt Erfolg
|
||||
/// zu melden.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Eine_kopflose_Instanz_meldet_dass_sie_kein_Fenster_hat()
|
||||
{
|
||||
await using var register = Register();
|
||||
var pfad = register.Create("Alpha");
|
||||
|
||||
_kanal.AnswerFor[Path.GetFullPath(pfad)] = new InstanceIdentity("i-1", "Alpha", "0.1.2");
|
||||
await register.StartAsync(pfad);
|
||||
|
||||
_kanal.HasWindow = false;
|
||||
|
||||
(await register.FocusAsync(pfad)).ShouldBeFalse();
|
||||
_kanal.FocusRequests.ShouldHaveSingleItem();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user