Repository navigation
Make the launches of one Explorer selection one donut - #1128
Open
KnifeLemon wants to merge 2 commits into
Open
KnifeLemon wants to merge 2 commits into
KnifeLemon wants to merge 2 commits into
Conversation
Explorer's classic verb ("%1", MultiSelectModel Player, the entry on Windows 10) starts one Filee per selected file.
They arrive out of order and over many seconds: 100 files had 15 gaps above the 350 ms debounce on a fast computer,
and every time the debounce ran out the donut's files were replaced, so a conversion got a few files or just one.
The first launch now reads the file manager's selection, so the donut has all of it at once and the launches still on
their way add nothing. When the selection can't be read, later launches join the donut that is open for earlier ones
instead of replacing its files; once a conversion took its files, they get a donut of their own.
Refs #767
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Unix all NamedPipeServerStreams of a name share one listening socket, which .NET closes and unlinks when the last of them is disposed. The listener kept one pipe at a time, so after every launch the socket closed, and the launches already queued on it went with it, though their connect and send had succeeded and they reported Delivered. 200 launches at once: 135-161 arrived. Even two launches close together could lose one. The next pipe is now made before the connected one is closed, so the socket stays open. Windows gets the same order, which closes the moment there was no pipe at all between two launches. Refs #767 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #767 (the reporter still owes a log, so this doesn't close it)
Mechanism
Measured by building the shell's own default context menu (
SHCreateDefaultContextMenu) over a private registry key, so Explorer's real menu wasn't touched, and invoking a classic verb on a multi-selection. Windows 11 26200, Explorer's classic-verb code; not run on Windows 10."%1"withMultiSelectModel=Player: one process per selected file, also with noMultiSelectModeland withDocument.%*brings nothing extra: it comes out empty.f004 f001 f003 f002 f005), so the first to arrive needn't be the clicked file.Playershows the entry up to 100 files and hides it at 101.Documentand no model hide it above 15.Filee.exestarted this way against a listener with the same pipe code, 100 files: all 100 delivered, median gap 159 ms, longest 723 ms, 15 gaps over the 350 ms debounce. With 30 files: 1 gap. A slower computer will have more.The loss is in the app, not the pipe. When the debounce ran out,
ShowForFilescalledLoad, which replaces the donut's files. So a slow burst leaves the donut with the last few files, or one, and a quick click converts only the first arrival. On WindowsSingleInstancelost nothing: 200 parallel forwards all delivered, with no access-denied answers.Fix
No wait can tell which launch is the last, and they can span many seconds, so:
SelectionLaunches: the first launch reads the file manager's selection (GetFileManagerSelection, as the selection shortcut does; Windows only). If its file is part of it, the donut gets all of it at once, and the launches still on their way add nothing. So a click at any moment converts everything, as one job.RadialController.TryAddFiles: for when the selection can't be read (another file manager, Explorer not in front). Later launches join the donut open for earlier ones instead of replacing its files.%1andPlayerstay:%*doesn't help, andPlayeris what lifts the 15-file limit.A log line (
A launch for one file found N selected file(s) in <window>) tells which path a report took.Also fixed: launches lost on macOS and Linux
The new burst test found a separate, silent loss on Unix. All pipes of a name share one listening socket, which .NET closes and unlinks when the last of them is disposed. The listener kept one pipe at a time, so after every launch the socket closed and took the queued launches with it, though their sends had succeeded and they reported
Delivered.StartListeningnow makes the next pipe before closing the connected one (two instances at most), so the socket stays open.This doesn't change #767's Windows report. The Linux menu entries pass all files in one launch (
%F), so it takes separate launches close together to hit it.For a decision
ExplorerCommandHandlerpointing atFileeExplorerMenu.dll. That needs no selection read, but it loads an in-process DLL into Explorer on Windows 10, and I can't test that here, so it isn't in this PR.Tests
SelectionLaunchesTestsis new.RadialControllerTestshas 2 new tests: makingTryAddFilesalways decline failsA_later_launch_joins_the_donut_open_for_earlier_ones.SingleInstanceTestshas a 200-launch burst test. It passes on Windows without the listener change and failed on all four macOS and Linux jobs (135-161 of 200 arrived). Those three classes: all passed.dotnet format --verify-no-changesclean on the changed files.Not tested: a real right-click in Explorer on Windows 10, and the selection read in that exact moment (it needs Explorer in the foreground).
🤖 Generated with Claude Code