Skip to content

Clear a connection's paste bars when it ends, and let X close any bar - #82

Merged
dhh merged 2 commits into
omacom:mainfrom
TechLuddite:transfer-bars-per-session
Oct 24, 2026
Merged

dhh merged 2 commits into
omacom:mainfrom
TechLuddite:transfer-bars-per-session

Conversation

@TechLuddite

@TechLuddite TechLuddite commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

When a connection ends while a paste from the server is in flight, its progress bar stays on screen for good, reading "Pasting text: 0 B", and its X button does nothing. I hit this on a laptop client after closing the lid: a process on the laptop read the desktop's text as the lid closed (the clipboard history watcher or the lock screen, which I have not pinned down), the laptop suspended before any bytes arrived, and the reconnect after resume left both bars behind until gliff was restarted.

Three things combine:

  1. A paste job runs as a task on its connection's LocalSet. When the worker ends, the LocalSet is dropped with the task still parked, so Jobs::finish never runs and no final Progress reaches the UI.
  2. TransferBars is one widget per window, keyed by the bare job id. Every connection numbers its jobs from 1, and nothing removed rows when a connection ended, so rows from different connections or tabs share keys.
  3. X sent CancelTransfer(id) to whatever worker the session had at click time and left the row for the job's final report to remove. After a reconnect the new worker has no such job, so nothing happens, or it has a different job with that id and cancels it.

Every worker now has a number (App::connections, Session::conn), and bars are keyed by that number and the job id. A connection's bars are removed when it fails, closes or is replaced, and when its tab is closed. X removes its row at once and cancels only through the worker that ran the job. A closed row stays closed until its job reports an end, so a progress report already queued cannot bring it back. The bookkeeping lives in a small Bars<R> without GTK, so it is unit tested without a display. Jobs, the status messages and the protocol are unchanged.

Validation:

  • Live, laptop client (AMD Radeon 840M) against an RTX 3090 desktop, both on 0.4.0, with temporary logging (not part of this PR). With text on the desktop's clipboard, I closed the lid for 24 minutes. On resume the old connection failed, both of its bars were removed, and the client reconnected. On v0.4.0, a 12-hour sleep in the same setup left two such bars on screen, and X did not remove them.
  • Five new unit tests cover two connections sharing a job id, clearing one connection without touching another, a closed row staying closed while reports are queued, closing a row whose job is gone, and closing marks going with their connection.
  • scripts/check.sh passes.

#47 moves the Linux client out of crates/gliff/src/main.rs. If it lands first, I am happy to move these lines to its new file.

Opus 5.5 high, on behalf of TechLuddite.
Implemented with Claude Opus 5.5 at high effort, with the diagnosis and the patch reviewed by GPT-6.1 (Codex) and Grok 4.7, both at high reasoning effort, then re-reviewed on 2026-10-19 by Claude, GPT-6.1 and Grok 4.7 at medium effort.

TechLuddite and others added 2 commits October 17, 2026 17:56
A paste job runs on its connection's LocalSet. When the connection ends,
the task is dropped before it can report an end, so its bar stayed on
"Pasting text: 0 B" for good. Bars were keyed by job id alone, which
every connection numbers from 1, and X only asked the current worker to
cancel that id: after a reconnect it cancelled nothing, or another job.

Number every worker, key bars by that number and the job id, and remove
a connection's bars when it fails, closes, restarts or its tab closes.
X now removes its bar at once and only cancels through the worker that
ran the job. A closed bar stays closed until its job reports an end.
@dhh
dhh merged commit 654f2d0 into omacom:main Oct 24, 2026
3 checks passed
@greptile-apps

greptile-apps Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] This PR appears safe to merge.

Summary

This PR ties paste progress bars to the connection that owns each job.

  • Paste bars stay tied to the worker that started them.

No actionable issues were found. Checks were not run during this review.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    P[Paste progress] --> K["Look up (connection, job ID)"]
    K --> D{User closed row?}
    D -->|No| U[Show or update row]
    D -->|Yes| I[Ignore running report]
    U --> X[User clicks X]
    X --> R[Remove row and remember dismissal]
    X --> C[Cancel only if original worker is current]
    E[Connection ends or is replaced] --> A[Clear its rows and dismissal marks]
    F[Job ends] --> M[Remove row and dismissal mark]
Loading

Reviews (1) · Last reviewed commit: "Merge main and preserve the validated tr..." · Reviewed by Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants