diff --git a/src/DiffEngineTray.Tests/OwnedInlineHostTest.cs b/src/DiffEngineTray.Tests/OwnedInlineHostTest.cs
index 61529c66..b6a31f7c 100644
--- a/src/DiffEngineTray.Tests/OwnedInlineHostTest.cs
+++ b/src/DiffEngineTray.Tests/OwnedInlineHostTest.cs
@@ -315,7 +315,7 @@ public async Task DiscardAllEmptiesTheQueue()
owner.Queue();
owner.Queue(@"c:\repo\OtherTests.cs", 7);
- owner.Host.DiscardAll();
+ owner.Host.DiscardAll(out _);
await Assert.That(owner.Host.List()).IsEmpty();
}
diff --git a/src/DiffEngineTray.Tests/StubInlineHost.cs b/src/DiffEngineTray.Tests/StubInlineHost.cs
index 3f6c0f89..852a1cd1 100644
--- a/src/DiffEngineTray.Tests/StubInlineHost.cs
+++ b/src/DiffEngineTray.Tests/StubInlineHost.cs
@@ -59,8 +59,10 @@ public bool AcceptAll(out string? message)
return AcceptAllSucceeds;
}
- public void DiscardAll()
+ public bool DiscardAll(out string? message)
{
+ message = null;
+ return true;
}
public void Focus(PendingSnapshot snapshot)
diff --git a/src/DiffEngineTray/IInlineHost.cs b/src/DiffEngineTray/IInlineHost.cs
index 8ceec101..ca9c5156 100644
--- a/src/DiffEngineTray/IInlineHost.cs
+++ b/src/DiffEngineTray/IInlineHost.cs
@@ -26,7 +26,11 @@ interface IInlineHost
bool Discard(PendingSnapshot snapshot, out string? message);
bool AcceptAll(out string? message);
- void DiscardAll();
+ ///
+ /// False when the queue owner could not be asked, so a caller clearing its own state knows not
+ /// to.
+ ///
+ bool DiscardAll(out string? message);
///
/// Bring the window forward on this item, launching one if there is none.
diff --git a/src/DiffEngineTray/OwnedInlineHost.cs b/src/DiffEngineTray/OwnedInlineHost.cs
index 4b394629..997b6c53 100644
--- a/src/DiffEngineTray/OwnedInlineHost.cs
+++ b/src/DiffEngineTray/OwnedInlineHost.cs
@@ -143,8 +143,12 @@ public bool AcceptAll(out string? message)
}
}
- public void DiscardAll() =>
- ((IQueueOwner) this).DiscardAll();
+ public bool DiscardAll(out string? message)
+ {
+ message = ((IQueueOwner) this).DiscardAll();
+ // Owned in this process, so there is nobody to fail to reach
+ return true;
+ }
public void Focus(PendingSnapshot snapshot) =>
Show(WindowCommand.Focus, snapshot.Key);
diff --git a/src/DiffEngineTray/RemoteInlineHost.cs b/src/DiffEngineTray/RemoteInlineHost.cs
index 26397e5b..f89c8152 100644
--- a/src/DiffEngineTray/RemoteInlineHost.cs
+++ b/src/DiffEngineTray/RemoteInlineHost.cs
@@ -96,8 +96,14 @@ public AcceptOutcome Accept(PendingSnapshot snapshot, out string? message)
: AcceptOutcome.Applied;
}
+ ///
+ /// On , not the short timeout. Discarding is not a clock driven call
+ /// - it comes from the menu or a hot key - and the owner answering it may be busy inside
+ /// InlineApplier, which waits up to ten seconds on its cross process mutex. Half a second
+ /// turned a busy owner into "The snapshot viewer is not running."
+ ///
public bool Discard(PendingSnapshot snapshot, out string? message) =>
- Send(ViewerVerb.Discard, snapshot.Key, ViewerClient.ShortTimeout, out message);
+ Send(ViewerVerb.Discard, snapshot.Key, acceptWait, out message);
///
/// True only when the queue is empty afterwards, for the reason gives —
@@ -110,8 +116,14 @@ public bool AcceptAll(out string? message) =>
Send(ViewerVerb.AcceptAll, null, acceptWait, out message) &&
List().Count == 0;
- public void DiscardAll() =>
- Send(ViewerVerb.DiscardAll, null, ViewerClient.ShortTimeout, out _);
+ ///
+ /// As , and the outcome is returned rather than dropped. Discarded on a
+ /// busy owner used to do nothing at all while Tracker.Clear went ahead and emptied its own
+ /// snapshot list, so "Discard (n)" reported success and everything reappeared on the next
+ /// scan two seconds later.
+ ///
+ public bool DiscardAll(out string? message) =>
+ Send(ViewerVerb.DiscardAll, null, acceptWait, out message);
public void Focus(PendingSnapshot snapshot) =>
Send(ViewerVerb.Focus, snapshot.Key, ViewerClient.ShortTimeout, out _);
diff --git a/src/DiffEngineTray/Tracker.cs b/src/DiffEngineTray/Tracker.cs
index 5ab19434..fc9aba8f 100644
--- a/src/DiffEngineTray/Tracker.cs
+++ b/src/DiffEngineTray/Tracker.cs
@@ -671,8 +671,17 @@ public void Clear()
{
((ITrackedFiles) this).DiscardAll();
- inline.DiscardAll();
- snapshots = [];
+ // Only forget the cached snapshots when the owner actually discarded them. It used to be
+ // cleared regardless, so a discard the owner never received still emptied the menu - and
+ // everything came back on the next scan two seconds later
+ if (inline.DiscardAll(out var message))
+ {
+ snapshots = [];
+ }
+ else
+ {
+ Log.Error(message ?? "Could not discard the pending snapshots.");
+ }
}
///