Conversation
The tool window that covers the terminal during a drag now has a real drop target. Over the item rows of the panel that is not the source it offers copy, or move with Shift; elsewhere nothing. On the drop Burlak copies nothing itself: it hands the point to Far's thread, which re-reads the panels, and replays Far's own panel-to-panel mouse drag through the console input - a left press at the cell the gesture started on and a release at the drop cell - so Far's KEY_DRAGCOPY / KEY_DRAGMOVE path does the copy with its own progress and conflicts, plugin panels included. Far's native mouse drag between panels, which Burlak had been swallowing since 1.0, works again through this. Version 1.3.0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Before writing the two records Far's thread checks that the panels are still the current window, that the source is the same visible file panel with the same directory and the same selected paths, and that the destination is a visible file panel in the directory the drop point was mapped to; a macro or a timer can change any of that during the drag. A partial write is completed with a release so Far's drag state is not left armed. BURLAK_NO_DESKTOP=1 skips the tests that need the desktop. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The identity compared before the replay now includes the current and top items of both panels, the cell mapped at the drop must map the same with fresh geometry, the host is found from the recorded drop point rather than the live cursor, and a drag whose paths do not all parse into the shell namespace does not start at all, so the advertised payload and the selection Far will copy are always the same set. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An archive, FTP or any other plugin panel has no paths on disk, so the drag starts with zero-byte placeholders carrying the item names in a temp folder of this run, and when the button is released over a willing target Far's thread extracts the real files over them by calling the owning plugin's GetFilesW the way Far itself does for a plugin-to-plugin copy (OPM_SILENT into a temp directory), while the tool thread waits with COM pumping. A refusal or a crash under the SEH guard cancels the drop with a message naming the plugin. A drop onto the other panel of the same Far still goes through Far's own copy and extracts nothing. Temp runs are removed after the drag when the target lets go, and swept at start and exit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The items go to GetFilesW as the buffers Far returned, every field intact; the plan is checked against the panel again right before the call; a rewritten DestPath cancels the drop; the waiter on the tool thread is signalled from an RAII completer so an exception on Far's thread cannot leave it waiting; run directories advance past leftovers; duplicate names refuse the drag up front; placeholder drags offer no link. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Stopping the tool window waited three seconds and then destroyed the drag state while OLE could still be unwinding through a drop target: a use-after-free that the CI runner hit in the e2e drag. Shutdown now cancels a pending extraction, then pumps until the thread has exited. Along the way: absolute item names (TmpPanel) are advertised as they are, a rewritten DestPath is copied inside the SEH guard, duplicate detection is n log n, the sweep never throws, and BURLAK_TRACE_TESTS names each test case on stderr so a crash on CI says where. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A drag announces itself to every other Burlak with a registered window message; each answers with its terminal window (the console window under conhost, its owner under Windows Terminal) and the tick of its last console focus, so among several Fars in one terminal window the one shown last wins. When the button comes up over such a window the source extracts first if the files are placeholders, asks with a small menu on a right-button drag, cancels the OLE drop so the terminal pastes nothing, and hands the peer the paths, the point and the effect over WM_COPYDATA. The peer maps the point to a panel of its own, copies with IFileOperation into that directory and redraws, or says in one line why it cannot. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Equal integrity only (no UIPI allowance), a single-use nonce per drag that Hellos and Drops must echo, a class and process check on every window a message goes to, bounded sizes and counts before any allocation, timed sends that abort on a hung window, a registry that lives for one drag and holds at most 64 peers, drops queued on the receiver, and the extracted run handed to the receiver by rename so the source can forget it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A timed-out Drop send leaves the run for the sweep; a receiver that refuses the drop still adopts and deletes the run; a message target must match the expected pid as well as the class; the desktop preconditions are real doctest skips and the OLE-entry probe reports a warning. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The tool window lives from startup now, so any process can send its WM_USER messages; the payload travels in a guarded slot of the window state and the message itself is empty. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replayed console records now carry Far's window-mode buffer delta, as console::WriteInput does, so a drop onto the other panel no longer lands on row 0 and opens the F9 menu. Placeholder-backed data objects publish CFSTR_PREFERREDDROPEFFECT = COPY so Explorer stops showing a move on the same volume. An extracted run survives a completed drop for a ten-minute grace period (targets such as Telegram read the files after the drop) and is swept with the dead-owner runs at startup, before each drag and at exit; the grace clock starts at retention, and the tool window stays active until the run is retained. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Far is now an OLE drop target: while an external drag is over the host, the tool window covers the panels backed by real directories and takes the drop, copying (Shift: moving) with the shell's own progress in this Far's window, following the optimized-move protocol so the source never deletes what was moved. A drop from another Far is that same path, so the private Far-to-Far protocol (announce/hello/drop over WM_COPYDATA, the nonce registry, temp-run adoption) is gone. In a shared Windows Terminal window the last-focused Far receives, marked by a window property on the host. Temp runs for foreign targets are swept from a tool-thread timer: three-minute grace, runs with a file open elsewhere are skipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The export-level drop test compared the runner's 8.3 temp spelling with the canonical paths the shell hands back through CF_HDROP; both sides are canonical now. The real-OLE receive test releases only once OLE's hover has reached the overlay, warns honestly when it never does, and collects its helper threads' exceptions on the main thread; the test main names the test case and the active exception on abort or terminate so a fast-fail on the runner is diagnosable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A fast-fail on the runner leaves no stack; the test job now enables local crash dumps, reruns every failed test executable under cdb with !analyze and a full thread dump when ctest fails, and uploads the dumps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The class was registered under the executable's module handle with its result ignored and never unregistered, so a copy of the code in an unloaded DLL left a class whose window procedure no longer existed and the next window of that name died in USER32's control-flow-guard check. The class now belongs to the module holding the procedure, a foreign class of the same name fails the start, and the last tool thread unregisters it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A plugin-panel release revalidates the panel and its archive location instead of the live selection, which is the cursor item and moves with the drag. The drag starts after two cells sideways or one row down, so a right-button release no longer falls back to Far's context menu. An optimized move and every drop Burlak declined after accepting the hover answer COPY: on a NONE answer ole32 delivers WM_DROPFILES along the owner chain and the console pastes the path. Temp runs are kept for one minute and swept every fifteen seconds. Co-Authored-By: Claude Opus 5 (1M context) <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.
Draft: CI only. Not to be merged or released until Roma has tested the DLL by hand.
Feature 2 of docs/ARCHITECTURE.md §0 is in: a drop onto the other panel of the same Far replays Far's own mouse drag through the console input. Features 1 (plugin panels) and 3 (another Far) follow on this branch.
🤖 Generated with Claude Code