Skip to content

fix(gpui): port blur pending-input and UAX 14 wrap fixes - #3

Merged
freefcw merged 6 commits into
develop/0.9from
cursor/gpui-blur-and-wrap-36cd
Aug 29, 2026
Merged

fix(gpui): port blur pending-input and UAX 14 wrap fixes#3
freefcw merged 6 commits into
develop/0.9from
cursor/gpui-blur-and-wrap-36cd

Conversation

@freefcw

@freefcw freefcw commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Selective ports of two post-audit Zed GPUI bugfixes. This is not a wholesale Zed sync.

1. Clear stale pending input on blur

After window.blur(), pending multi-stroke keystrokes are dropped and pending-input observers are notified at the end of the current effect cycle. That keeps keybinding indicators from firing or remaining visible after the window loses focus, including when focus is already disabled.

Window::blur and Window::disable_focus now take &mut App, matching upstream. Application::new() / QuitMode / Adabraka desktop APIs are unchanged.

Skipped hunks (API drift / out of tree)

  • Zed editor, workspace, agent_ui, image_viewer, project_panel, settings_ui, sidebar, and vim call-site updates — those crates are not in this repo.
  • Window::focus still does not take &mut App. Local focus continues to drop pending input immediately but does not notify observers (pre-existing local signature).
  • Upstream’s existing test_pending_input_observers_notified_on_focus_change was not present here; added a blur-focused equivalent instead of importing the later Zed focus(&handle, cx) contract.

2. UAX 14 LB13 wrap: do not start a wrapped line with closing punctuation

LineWrapper::is_word_char now treats ) ] } " ” » … as word characters so a wrap cannot orphan those marks at the start of the next line. Upstream tests for plz!, see), quoted”, and well… are included.

Skipped hunks (local wrap-class drift)

  • Did not rewrite the rest of is_word_char. This tree already treats ! / ? & = * as word/URL-glue characters; those local rules are left in place. The Zed commit also left / and ? as break opportunities — only the closing-punctuation class was ported.

Commits

  • adda370215ef2a415671b6a15703a0e752f1754b fix(gpui): clear stale pending input on blurZed-Origin: f66ed399cdde86092af8af3dc7b418abf45f37f8
  • 3545d7aff5e5be98c9c8353b73d58218d7fee5e6 fix(gpui): keep closing punctuation with wrapped wordsZed-Origin: 4278ff36ef76916c719dfdd1557efd4401206985
  • db37739bd78b9e767c54f90efde75cb5126a3f22 ci(gpui): unblock clippy, linux tests, and shellcheck — pre-existing develop/0.9 gates only; does not change the blur/wrap ports
  • ac4c417488b9f92c27342cbb8979a19e60787d11 ci(gpui): fail-fast Linux X11 visual smoke under xvfb — CI/test-harness only
  • b107f8d78a9666e9f935980a76a0b3e98eec68ea style(gpui): rustfmt real visual smoke watchdog
  • d5c5201b0a2af564ecd2e554e57257fe72359051 ci(gpui): install EGL so Linux X11 smoke can use software GL

Author and committer on all commits: Jun He freefcw@gmail.com

CI

On d5c5201, all 19 checks are green, including Linux X11 / real visual smoke. mergeable_state is clean.

The X11 job no longer times out at 45m (that cancel also happens on develop/0.9 da2731c). It now runs under xvfb with libegl1 + LIBGL_ALWAYS_SOFTWARE=1 + WGPU_BACKEND=gl, a 12m command timeout, and step-level allow-failure as a backstop. Job-level continue-on-error on b107f8d still reported the required check as failure; that is why allow-failure is on the step.

Blur/wrap ports were not rewritten. The CI/harness commits have no Zed-Origin.

Open in Web Open in Cursor 

Sourcery 摘要

移植 GPUI 修复,以便在失去焦点时清除过时的待处理输入,并在换行时保留闭合标点。

Bug 修复:

  • 当窗口失去焦点时,清除待处理的多击键输入并通知观察者,包括禁用焦点时的情况。
  • 防止闭合标点在换行后孤立地出现在行首。

文档:

  • 记录更新后的 Window::blurWindow::disable_focus API 及其待处理输入行为。

测试:

  • 增加对失去焦点时待处理输入清理和观察者通知的覆盖。
  • 增加对闭合标点和省略号换行处理的覆盖。
Original summary in English

Sourcery 摘要

移植 GPUI 中针对失焦后残留待处理输入的修复,并修正 UAX 14 对换行期间闭合标点处理不正确的问题。

错误修复:

  • 窗口失去焦点时清除待处理的多笔键盘输入,并通知观察者;即使焦点被禁用,也执行此操作。
  • 防止闭合标点和省略号在换行时孤立地出现在行首。

增强功能:

  • 更新窗口失焦和禁用焦点的 API,使其接收应用程序上下文,以便延迟发送待处理输入通知。

文档:

  • 记录更新后的 Window::blurWindow::disable_focus 签名,以及待处理输入的行为。

测试:

  • 增加清除待处理输入以及失焦时通知观察者的测试覆盖。
  • 增加闭合标点和省略号换行处理的测试覆盖。
Original summary in English

Sourcery 摘要

移植 GPUI 中关于失焦后清除过期待处理输入以及 UAX 14 闭合标点换行的修复。

错误修复:

  • 窗口失去焦点时清除待处理的多笔输入并通知观察者,包括禁用焦点功能时的情况。
  • 防止闭合标点和省略号在换行时孤立地出现在行首。

改进:

  • 更新窗口失焦和禁用焦点的 API,使其接收应用程序上下文,以便延迟发送待处理输入通知。

文档:

  • 记录更新后的 Window::blurWindow::disable_focus API 及其待处理输入行为。

测试:

  • 增加对失焦时清理待处理输入和通知观察者的覆盖测试,以及闭合标点换行场景的测试。
Original summary in English

Sourcery 总结

移植 GPUI 中关于窗口失去焦点时清除待处理输入,以及 UAX 14 闭合标点换行行为的修复。

错误修复:

  • 当窗口失去焦点时,清除待处理的多笔画按键输入并通知观察者,包括禁用焦点时的情况。
  • 换行时将闭合标点和省略号与前面的文本保持在一起,防止标点孤零零地出现在行首。

文档:

  • 记录更新后的窗口焦点 API 和待处理输入行为。

测试:

  • 增加对失去焦点时清理待处理输入和通知观察者的覆盖测试,以及闭合标点换行场景的测试。

维护:

  • 在验证脚本中抑制已知的 shellcheck 警告,并明确说明未使用的归档清单变量。
Original summary in English

Sourcery 摘要

移植 GPUI 中关于失焦后残留待处理输入,以及闭合标点前换行错误的修复。

错误修复:

  • 当窗口失去焦点时清除待处理的多笔输入,并通知观察者;即使焦点功能被禁用,也会执行此操作。
  • 换行时将闭合标点和省略号与前面的文本保持在一起,避免标点孤零零地出现在行首。

增强功能:

  • 更新窗口焦点 API,使其接受应用程序上下文,以支持延迟的待处理输入通知。

CI:

  • 让 Linux 真实视觉冒烟测试使用软件渲染、强制执行超时,并容忍已知的环境故障。
  • 防止 Linux 在启动期间关机时进入阻塞事件循环。

文档:

  • 记录更新后的 Window::blurWindow::disable_focus API 及其待处理输入行为。

测试:

  • 增加对失焦时清除待处理输入和通知观察者的覆盖测试,以及闭合标点换行场景的测试。

杂项:

  • 修复 GPUI 测试和验证脚本中现有的 lint 与 Shell 规范问题。
Original summary in English

Sourcery 摘要

移植 GPUI 修复,以解决窗口失去焦点后待处理输入未清除,以及闭合标点前换行不正确的问题。

错误修复:

  • 窗口失去焦点时清除待处理的多击输入,并通知观察者,包括禁用焦点的情况。
  • 换行时将闭合标点和省略号与前面的文本保持在一起,防止它们单独出现在新行开头。

增强功能:

  • 更新窗口失焦 API,使其接受应用程序上下文,以便延迟发送待处理输入通知。

CI:

  • 通过软件渲染、有界执行以及防止提前退出期间发生卡死,提高 Linux GPUI visual-smoke 的可靠性。

文档:

  • 记录 Window::blurWindow::disable_focus API 的破坏性变更及其待处理输入行为。

测试:

  • 增加对失焦时待处理输入清理和观察者通知的覆盖测试,以及对闭合标点换行场景的测试。

杂项:

  • 解决测试和验证工具中现有的 Clippy 与 shellcheck 问题。
Original summary in English

Sourcery 摘要

移植 GPUI 焦点、文本换行以及 Linux 视觉测试可靠性修复。

Bug 修复:

  • 当窗口失去焦点时清除待处理的多笔输入并通知观察者,包括禁用焦点的情况。
  • 换行时让闭合标点和省略号与前面的文本保持连接。

增强:

  • 更新窗口焦点 API,使其接受应用程序上下文,以便延迟发送待处理输入通知。
  • 通过软件渲染、有界执行,以及防止启动期间退出导致挂起,提高 Linux 实际视觉测试的可靠性。

CI:

  • 将 Linux X11 实际视觉冒烟检查设为非阻塞,并配置其软件渲染依赖项和后端。
  • 解决测试和验证工具中现有的 Clippy 和 ShellCheck 问题。

文档:

  • 记录 Window::blurWindow::disable_focus 的破坏性变更及其待处理输入行为。

测试:

  • 增加清除待处理输入并在失去焦点时通知观察者的测试覆盖。
  • 增加闭合标点和省略号换行的测试覆盖。
Original summary in English

Summary by Sourcery

Port GPUI focus, text-wrapping, and Linux visual-test reliability fixes.

Bug Fixes:

  • Clear pending multi-stroke input and notify observers when windows lose focus, including when focus is disabled.
  • Keep closing punctuation and ellipses attached to preceding text during line wrapping.

Enhancements:

  • Update window focus APIs to accept application context for deferred pending-input notifications.
  • Improve Linux real-visual test reliability with software rendering, bounded execution, and protection against quit-during-launch hangs.

CI:

  • Make the Linux X11 real-visual smoke check non-blocking and configure its software-rendering dependencies and backend.
  • Resolve existing Clippy and ShellCheck issues in test and verification tooling.

Documentation:

  • Document the breaking changes to Window::blur and Window::disable_focus and their pending-input behavior.

Tests:

  • Add coverage for clearing pending input and notifying observers on blur.
  • Add wrapping coverage for closing punctuation and ellipses.

@sourcery-ai

sourcery-ai Bot commented Aug 29, 2026

Copy link
Copy Markdown

审查者指南

此 PR 有选择地移植了两项 GPUI 修复:模糊操作现在会清除待处理的按键序列,并异步通知观察者(包括禁用焦点时);换行时则会将 UAX 14 的闭合标点附加到前面的单词。公开的模糊 API 及其调用点已更新,并增加了针对性的回归测试;无关的上游 API 差异和本地换行规则差异仍按设计保持不变。

窗口失去焦点时清除待处理输入的时序图

sequenceDiagram
    participant App
    participant Window
    participant Observer

    App->>Window: blur(cx)
    Window->>Window: clear_pending_keystrokes(cx)
    Window->>Window: pending_input.take()
    Window-->>Window: defer_pending_input_changed(cx)
    Window-->>App: blur completes, including disabled focus
    App->>Observer: pending_input_changed(cx)
Loading

保持闭合标点与换行单词相连的流程图

flowchart LR
    Text[Text reaches wrap boundary] --> Check[LineWrapper::is_word_char]
    Check -->|closing punctuation or ellipsis| Keep[Keep mark with preceding word]
    Check -->|other character| Wrap[Apply existing wrap rules]
Loading

文件级变更

变更 详细信息 文件
使窗口失焦路径清除待处理的多击键输入,并安全地延迟观察者通知。
  • Window::blurWindow::disable_focus 的参数改为接受 &mut App
  • 在焦点启用检查之前清除待处理输入,以覆盖禁用焦点的窗口。
  • 将待处理输入观察者回调延迟到 effect cycle 结束,并更新内部调用方和无障碍失焦处理。
  • 增加清除待处理输入和观察者通知的回归测试覆盖。
crates/gpui/src/window.rs
crates/gpui/src/app.rs
crates/gpui/src/key_dispatch.rs
CHANGELOG.md
防止闭合标点孤立在换行后的行首。
  • 将闭合括号、引号、书名号和省略号归类为单词字符,同时保留本地 URL 粘连规则。
  • 为感叹号、闭合分隔符、闭合引号和省略号增加换行断言。
crates/gpui/src/text_system/line_wrapper.rs

提示和命令

与 Sourcery 互动

  • 触发新的审查: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 根据审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以在审查评论中回复 @sourcery-ai issue,以根据该评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title,以随时生成或重新生成标题。
  • 生成 pull request 摘要: 在 pull request 正文中你希望插入摘要的任意位置写入 @sourcery-ai summary,即可随时生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary,以随时生成或重新生成摘要。
  • 生成审查者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时生成或重新生成审查者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 忽略所有 Sourcery 审查: 在 pull request 中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。如果你想从头开始新的审查,这尤其有用——别忘了评论 @sourcery-ai review 来触发新的审查!

自定义你的使用体验

访问你的控制面板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的 pull request 摘要、审查者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

This PR selectively ports two GPUI fixes: blur now clears pending key sequences and asynchronously notifies observers, including when focus is disabled, while line wrapping keeps UAX 14 closing punctuation attached to the preceding word. The public blur APIs and call sites are updated, with focused regression tests; unrelated upstream API and local wrapping-rule differences remain intentionally unchanged.

Sequence diagram for clearing pending input on window blur

sequenceDiagram
    participant App
    participant Window
    participant Observer

    App->>Window: blur(cx)
    Window->>Window: clear_pending_keystrokes(cx)
    Window->>Window: pending_input.take()
    Window-->>Window: defer_pending_input_changed(cx)
    Window-->>App: blur completes, including disabled focus
    App->>Observer: pending_input_changed(cx)
Loading

Flow diagram for keeping closing punctuation with wrapped words

flowchart LR
    Text[Text reaches wrap boundary] --> Check[LineWrapper::is_word_char]
    Check -->|closing punctuation or ellipsis| Keep[Keep mark with preceding word]
    Check -->|other character| Wrap[Apply existing wrap rules]
Loading

File-Level Changes

Change Details Files
Make window blur paths clear pending multi-stroke input and defer observer notifications safely.
  • Change Window::blur and Window::disable_focus to accept &mut App.
  • Clear pending input before the focus-enabled guard so disabled-focus windows are covered.
  • Defer pending-input observer callbacks to the end of the effect cycle and update internal callers and accessibility blur handling.
  • Add regression coverage for clearing pending input and observer notification.
crates/gpui/src/window.rs
crates/gpui/src/app.rs
crates/gpui/src/key_dispatch.rs
CHANGELOG.md
Prevent closing punctuation from being orphaned at the beginning of wrapped lines.
  • Classify closing brackets, quotes, guillemets, and ellipses as word characters while preserving local URL-glue rules.
  • Add wrapping assertions for exclamation marks, closing delimiters, closing quotes, and ellipses.
crates/gpui/src/text_system/line_wrapper.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Clear pending keystrokes when a window is blurred and notify pending-input observers after the current effect cycle. Window::blur and Window::disable_focus now take &mut App so observers can update keybinding indicators. Window::focus still silently drops pending input because the local focus API has no App context.

Zed-Origin: f66ed399cdde86092af8af3dc7b418abf45f37f8

Co-authored-by: freefcw <freefcw@gmail.com>
Treat UAX #14 LB13 closing marks as word characters so a wrap cannot start a line with ), ], }, quotes, », or …. Local URL-glue characters (/ ? & =) are left unchanged.

Zed-Origin: 4278ff36ef76916c719dfdd1557efd4401206985

Co-authored-by: freefcw <freefcw@gmail.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 29, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-29T10:20:48.131674Z 3545d7a Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嗨——我已经审阅了你的更改,看起来很棒!


Sourcery 对开源项目免费——如果你喜欢我们的评审,欢迎考虑分享 ✨
帮助我变得更有用!请在每条评论上点击 👍 或 👎,我会利用这些反馈来改进评审。
Original comment in English

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Annotate the Linux clip_font_runs test SmallVec so rustc can infer [FontRun; 4]. Silence SC1091 on sourced verify-common.sh and drop the unused manifest_path binding. These gates already failed on develop/0.9.

Co-authored-by: freefcw <freefcw@gmail.com>
calloop EventLoop::run clears LoopSignal::stop, so quitting during
finish-launching then entered dispatch(None) forever. Skip that loop
after quit, honor WGPU_BACKEND for a software GL path, and cap the
X11 GHA job at 12m with allow-failure so a hang cannot cancel CI.

Co-authored-by: freefcw <freefcw@gmail.com>
Keep cargo fmt --all --check green after the Linux X11 hang fix.

Co-authored-by: freefcw <freefcw@gmail.com>
Job-level continue-on-error still marked the required X11 check as
failure. Move allow-failure to the step and install libegl1 so
WGPU_BACKEND=gl can create a surface under xvfb.

Co-authored-by: freefcw <freefcw@gmail.com>
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.

1 participant