Repository navigation
feat(qt): add bounded system paste entries - #324
Merged
JavaZeroo merged 16 commits intoNov 11, 2026
Merged
Conversation
Add Ctrl+Shift+V, Shift+Insert and an actual Paste context-menu action for the normal main screen. The default Windows clipboard reader reads bounded CF_UNICODETEXT off the Qt thread; TextSelection-independent paste preparation reuses the existing UTF-16/UTF-8 limits, CR normalization and multiline confirmation policy. Transfer reuses the fixed ConPTY input queue in bounded chunks, retains the initiating session identity, retries a rejected chunk without duplication, cancels on target close, and reports empty/failure/busy/ cancelled/limit distinctly. Add a local fake-reader regression with a real child that records received bytes, plus a hosted Windows QPA/default-reader paste scenario covering the three public entries, Unicode/NFD, multiline cancel/confirm, real owner-held failure and release followed by a second action. No bracketed paste, TUI policy or new grapheme rules are introduced. Co-authored-by: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com>
Shift+Insert is now an implemented paste shortcut and must be accepted without falling through as an Insert byte. Disable the reader in this local test so it never touches a personal clipboard; the existing literal receiver bytes stay unchanged.
…er in hosted confirm Activate the owner window, raise it, set focus and process events after the multiline dialog; use the product paste trigger for the hosted confirmation branch because modal teardown in the test harness loses focus. The three public entries remain exercised earlier in the hosted scenario.
Remove the flaky hosted multiline-dialog branch and its debug logs; multiline cancel/confirm remains covered by the local fake-reader regression. The hosted real-CF scenario keeps keyboard/menu/Shift+Insert entries and the real owner-held failure/release path, and reports the skipped multiline scope explicitly.
Document the three public paste entries, default CF reader, bounded chunked transfer, target binding, multiline dialog policy, local fake-reader child-byte regression and the hosted Windows QPA real-CF result (three entries plus real owner-held failure/release). State that hosted multiline confirmation and second-session switch/close reuse remain outside the verified scope. Co-authored-by: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com>
5 tasks
Open
Capture the initiating child PID before starting the asynchronous clipboard read, and reject the read/transfer if the target has closed or changed by the time preparation or sending proceeds. This prevents a delayed paste from a closed session from reaching a newly started session in the same widget. Add local isolation coverage with two independent children and controlled fake readers: focus switch keeps the task with its origin, close during the read sends nothing to the old or new target, and the second session remains usable.
…erage Keep the failed hosted multiline attempts as history instead of deleting them: record the first failure, the focus/trigger fix and its failed retry, the diagnostic-only head, and the recovery-budget conclusion. Add the offline diagnostic hypotheses and the one-retry minimal plan without claiming a pass. Also document the local isolation coverage added with the initiation-time target binding fix: focus switch, close during read, and a new session receiving no old paste bytes.
This was referenced Nov 6, 2026
This was referenced Nov 7, 2026
4 tasks
6 of 10 tasks
…-hidden-retention-2e7373117ea0 # Conflicts: # .github/workflows/qt-cpp.yml # CMakeLists.txt # docs/EVIDENCE.md # docs/FEATURES.md # src/qt/terminal_widget.hpp
QMessageBox::exec() returns the clicked standard button value, not a QDialog::DialogCode (measured: accept=2, escape=3 on the pinned Qt 6.10.3). Comparing it against QDialog::Accepted made every confirmed multiline paste record as cancelled with no transfer, which is the hosted failure fingerprint. Classify the real user choice via clickedButton() and its AcceptRole instead. The temporary PASTE_* stderr traces around this path serve the single authorized hosted recovery run and are removed after it. Co-authored-by: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com>
Bring the hosted real-CF multiline branch back behind a test-only TERMFORGE_QT_HOSTED_MULTILINE gate so the default qt-cpp.yml lane keeps its historical single-line scope while the new branch-scoped recovery workflow executes the multiline dialog path exactly once per enabling push. The dialog helper now selects buttons by QMessageBox role with full stderr logging (box source, every button text/role, match basis, click delivery, and bounded not-found reporting), so a rejected dialog is attributed instead of silently read as a user cancellation. The confirm action uses the real Paste menu entry; the cancel action keeps the real Ctrl+Shift+V entry; the default product CF reader and the real QMessageBox stay in place. Locally, qt_paste confirms through the real dialog with a role-selected Paste click and drops the auto-confirm shortcut; cancel zero-byte and confirm-CR-once assertions are unchanged and strengthened with a Pasted notice check. Co-authored-by: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com>
Separate facts from hypotheses in the attempt ledger: the offline probe and the strengthened local run prove QMessageBox::exec() never returned QDialog::Accepted, which fully explains the historical hosted failures. Add the pre-written bounded action plan for the single authorized recovery run (stop on first failure, no diagnostic copies, unique run/job recorded), the dialog probe source as evidence, and refresh the README and validation identity to keep local fake-reader success and hosted real-CF status listed separately. Attempt 3 stays unclosed until its hosted run is recorded. Co-authored-by: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com>
Record attempt 3 results in the ledger, README and validation identity: the single authorized opt-in run 43101420107 / job 130793595825 passed with multiline_cancel/multiline_confirm true and hosted-real-cf scope, cancel zero bytes, confirm CRLF-to-CR exactly once, occupied failure and release success, and zero active owned processes. Remove the temporary PASTE_* stderr traces from the product path and make the recovery workflow dispatch-only so no later push can re-execute the real hosted path. Local offscreen regression re-verified at this head (qt_paste 1/1). Co-authored-by: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com>
JavaZeroo-Bot
added a commit
that referenced
this pull request
Nov 12, 2026
…ecord-hidden-retention-2e7373117ea0 Union both sides: keep the bounded autoscroll Qt target/CTest entry and the #324 system paste, #333 BCD fixtures, #330/#331 packaging and #328 eight-session capabilities with their assertions. Co-authored-by: JavaZeroo <71128095+JavaZeroo@users.noreply.github.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.
背景
正式 Qt 已有系统复制、历史/重排选择与固定 ConPTY 输入队列。本切片接入正常主屏的有界系统粘贴:
Ctrl+Shift+V、Shift+Insert与实际终端 Paste 上下文菜单;默认 Windows 读取器读取CF_UNICODETEXT,复用现有 UTF-16/UTF-8 容量、CR 归一化、多行确认与回压策略,不新增 bracketed paste/TUI 政策/字素规则。内容
ClipboardReader/SystemClipboardReader:Windows CF 读取、1 Mi UTF-16 上限、无界拒绝、短重试;读取在 Qt 线程外进行,结果回投。TerminalWidget:三个公开入口;读取/准备/确认/分块发送状态;绑定发起会话 PID,目标关闭/变化即失败,不发送到复用会话;输入队列拒绝时不确认、不重复,10ms 后重试同一 chunk;空/失败/忙/取消/超限分开报告;多行真实QMessageBoxPaste/Cancel,完成后焦点回终端。QMessageBox::exec()返回被点击按钮的标准按钮值而非QDialog::DialogCode(本 Qt 6.10.3 实测 accept=2/escape=3),原比较对真实确认恒为假;改为按clickedButton()的AcceptRole判定。离线探针与加强版本地测试证明(见账本)。qt_paste:fake reader + 真实 child 记录接收字节,覆盖 Ctrl+Shift+V 单行一次、Shift+Insert 多行取消零发送、真实对话框 Paste 确认一次(role 选择点击,无 auto-confirm)、实际 Paste 菜单中文+NFD、忙、目标关闭、CR 归一化;不触个人 CF。--hosted-windows-paste:默认产品读取器、真实控件 HWND、三个公开入口、真实 CF 内容、独立 child 接收字节、真实自有 owner 占用失败与释放后第二次动作;多行分支由测试内TERMFORGE_QT_HOSTED_MULTILINE门控,仅在 opt-in 单次恢复 workflow 执行。验证
qt_paste1/1);系统 CF 未在本地触碰。42183487961/ job127778260596:三入口真实 CF 与 child 字节、真实占用失败/释放后第二次动作通过。43101420107/ job130793595825通过——真实 Ctrl+Shift+V 取消零字节(PASTE_CONFIRM accepted=0,child 字节不变),真实 Paste 菜单确认后PASTE_CONFIRM accepted=1+PASTE_TRANSFER total=5(L1\rL2CRLF→CR 恰好一次),占用/释放保留,exit 0、owned job active=0;sample 全项真(multiline_scope=hosted-real-cf)。过程与日志证据见 attempt-ledger.md。边界