Skip to content

gpui: Add support for NSWindow's representedFilename#48029

Merged
ChristopherBiscardi merged 3 commits intozed-industries:mainfrom
MrMage:add-represented-filename-support
Apr 24, 2026
Merged

gpui: Add support for NSWindow's representedFilename#48029
ChristopherBiscardi merged 3 commits intozed-industries:mainfrom
MrMage:add-represented-filename-support

Conversation

@MrMage
Copy link
Copy Markdown
Contributor

@MrMage MrMage commented Jan 30, 2026

This sets the accessibility document property (AXDocument) of the window, which other apps can use to understand what file the current window represents. Document-based apps on macOS are generally expected to set this property.

The document path is set via Window::set_document_path() which calls setRepresentedFilename: on the underlying NSWindow. The workspace updates this path in update_window_title() whenever the active item or project structure changes. For tests, instead of trying to somehow assemble a proper NSWindow, we store the document path on the window mock used for testing and check its value.

Motivation: I am the developer of Timing, an automatic time tracking app for Mac. Timing uses the AXDocument property (a standard property of most document-based app windows on macOS) to understand what document the user is working on. With this change, Timing is able to understand which directory the user is working in. Without this, Timing would only record the window title, i.e. the filename without information about the containing directory. I've had several users ask for better support for Zed.

Here's a screenshot of the macOS Accessibility Inspector showing the AXDocument property with this change. The UI of Zed itself does not change. However, in my dev build of Zed, the traffic lights are a bit too large and misaligned. However, this happens even when building main, so I assume it’s unrelated to my changes.

Screenshot 2026-01-30 at 16 18 25

Release Notes:

  • Set the represented filename property of windows on macOS

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Jan 30, 2026

We require contributors to sign our Contributor License Agreement, and we don't have @MrMage on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'.

@zed-community-bot zed-community-bot Bot added the first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions label Jan 30, 2026
@MrMage
Copy link
Copy Markdown
Contributor Author

MrMage commented Jan 30, 2026

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Jan 30, 2026
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Jan 30, 2026

The cla-bot has been summoned, and re-checked this pull request!

@strickvl
Copy link
Copy Markdown

Thanks for opening up this PR! I'm a user of Timing and this feature / change would be useful to me as currently my work in Zed (amazing IDE, btw!) doesn't get logged properly in Timing.app. Thanks again @MrMage!

@MrMage
Copy link
Copy Markdown
Contributor Author

MrMage commented Feb 3, 2026

Is there anything I can do to help get this reviewed?

@MrMage
Copy link
Copy Markdown
Contributor Author

MrMage commented Feb 9, 2026

Friendly ping :-)

@MrMage MrMage force-pushed the add-represented-filename-support branch from f77f360 to 2e0efa4 Compare February 10, 2026 12:34
@MrMage
Copy link
Copy Markdown
Contributor Author

MrMage commented Feb 10, 2026

@SomeoneToIgnore thank you for triggering CI! I have now addressed the formatting issues and rebased on main.

This sets the accessibility document property (AXDocument) of the
window, which other apps can use to understand what file the current
window represents.

The document path is set via `Window::set_document_path()` which calls
`setRepresentedFilename:` on the underlying NSWindow. The workspace
updates this path in `update_window_title()` whenever the active item
or project structure changes.
@MrMage MrMage force-pushed the add-represented-filename-support branch from 2e0efa4 to 5eb1784 Compare February 10, 2026 16:06
@SomeoneToIgnore SomeoneToIgnore added the area:gpui GPUI rendering framework support label Mar 17, 2026
@MrMage
Copy link
Copy Markdown
Contributor Author

MrMage commented Mar 27, 2026

Friendly ping :-)

@ChristopherBiscardi
Copy link
Copy Markdown
Contributor

Friendly ping :-)

I started taking a look here!

I have to wrestle with accessibility inspector being able to select my local zed a bit. If you have a suggestion for that, since you did it for the screenshot, I'd appreciate it as it would help me validate this.

@MrMage
Copy link
Copy Markdown
Contributor Author

MrMage commented Mar 30, 2026

I have to wrestle with accessibility inspector being able to select my local zed a bit. If you have a suggestion for that, since you did it for the screenshot, I'd appreciate it as it would help me validate this.

Right, sorry! If I remember correctly, the issue was that Accessibility Inspector would not be able to select the window when run directly from a zed CLI executable, but would be able to select it when run from an app bundle. I've had Claude assemble and follow the instructions below for this:

Building Zed as a macOS App Bundle (Debug)

Running the bare binary (target/debug/zed) doesn't get proper macOS integration (e.g. Accessibility permissions). You need an app bundle for that.

The official script/bundle-mac (-d for debug, -o to open) requires rustup. If using Homebrew Rust, use the manual approach below.

Prerequisites

Install Zed's fork of cargo-bundle (one-time setup):

cargo install cargo-bundle --git https://github.com/zed-industries/cargo-bundle.git --branch zed-deploy

Steps

  1. Rename bundle metadata, build, and bundle:

    cargo bundle expects package.metadata.bundle, but the dev config uses package.metadata.bundle-dev:

    cd crates/zed
    sed -i.backup 's/package.metadata.bundle-dev/package.metadata.bundle/' Cargo.toml
    ZED_BUNDLE=true cargo bundle --select-workspace-root
    /bin/mv -f Cargo.toml.backup Cargo.toml
    cd ../..
  2. Run the app:

    open target/debug/bundle/osx/Zed\ Dev.app

P.S.: I'm happy to rebase this PR on top of the latest main branch, but would like to wait with that until the review has largely concluded, to avoid having to do it repeatedly.

@MrMage
Copy link
Copy Markdown
Contributor Author

MrMage commented Apr 10, 2026

@ChristopherBiscardi Were you able to access Zed debug builds in Accessibility Inspector using the steps I provided?

Copilot AI review requested due to automatic review settings April 24, 2026 03:34
@ChristopherBiscardi ChristopherBiscardi self-requested a review April 24, 2026 03:35
Copy link
Copy Markdown
Contributor

@ChristopherBiscardi ChristopherBiscardi left a comment

Choose a reason for hiding this comment

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

@MrMage I was able to confirm the behavior using the release scripts in the repo, yes. I've also merged main in here and kicked off the tests.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a cross-platform Window::set_document_path() API and wires it up on macOS to set NSWindow’s representedFilename, allowing external tools (via AXDocument) to identify the file/directory represented by the window.

Changes:

  • Update Workspace::update_window_title() to compute an active document path and call window.set_document_path(...).
  • Add Window::set_document_path() and a PlatformWindow::set_document_path(...) hook with implementations for macOS and the test platform.
  • Extend test infrastructure to record document_path on the mock window and add a workspace test asserting updates/clearing.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/workspace/src/workspace.rs Sets document path during window title updates; adds a test asserting document path follows active item changes.
crates/gpui_macos/src/window.rs Implements PlatformWindow::set_document_path by calling setRepresentedFilename:.
crates/gpui/src/window.rs Exposes new Window::set_document_path() API delegating to the platform window.
crates/gpui/src/platform/test/window.rs Stores document_path in the test window mock for assertions.
crates/gpui/src/platform.rs Adds a new PlatformWindow::set_document_path trait method (default no-op).
crates/gpui/src/app/test_context.rs Adds VisualTestContext::document_path() accessor for tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +5867 to +5869
let document_path = active_project_path
.as_ref()
.and_then(|path| project.absolute_path(path, cx));
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

project.absolute_path will also return paths for remote/collab worktrees (built from the remote abs_path). Exposing that via AXDocument can leak a collaborator’s filesystem path to other local apps and also points at a path that doesn’t exist locally. Consider only setting document_path when project.is_local() (or when the target worktree is local), and otherwise clear it (None).

Suggested change
let document_path = active_project_path
.as_ref()
.and_then(|path| project.absolute_path(path, cx));
let document_path = if project.is_local() {
active_project_path
.as_ref()
.and_then(|path| project.absolute_path(path, cx))
} else {
None
};

Copilot uses AI. Check for mistakes.
Comment on lines +15417 to +15423
let item = TestProjectItem::new(id, path, cx);
item.update(cx, |item, _| {
if let Some(ref mut project_path) = item.project_path {
project_path.worktree_id = worktree_id;
}
});
item
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

This helper mutates TestProjectItem’s internal project_path.worktree_id after construction. Since TestProjectItem already provides new_in_worktree(...), prefer using that constructor directly (or wrap it) to avoid reaching into internal fields and duplicating behavior.

Suggested change
let item = TestProjectItem::new(id, path, cx);
item.update(cx, |item, _| {
if let Some(ref mut project_path) = item.project_path {
project_path.worktree_id = worktree_id;
}
});
item
TestProjectItem::new_in_worktree(id, path, worktree_id, cx)

Copilot uses AI. Check for mistakes.
@ChristopherBiscardi ChristopherBiscardi added this pull request to the merge queue Apr 24, 2026
Merged via the queue into zed-industries:main with commit 385f613 Apr 24, 2026
35 checks passed
@ChristopherBiscardi
Copy link
Copy Markdown
Contributor

Thank you for the work here @MrMage 🙏🏼

@agu-z agu-z mentioned this pull request Apr 28, 2026
5 tasks
strank pushed a commit to strank/zed that referenced this pull request Apr 28, 2026
zed-industries#48029 introduced `set_document_path` which is frequently (we are also
working on a PR to make it less frequent) called as tabs and panes
update. Apparently, the AppKit function it uses
(`NSWindow::setRepresentedFilename`) can cause the current cursor style
to be reset, producing flicker as the cursor would change to `Arrow`
temporarily until the right cursor style is set again in the next frame.

This PR reworks how we set the cursor to use AppKit's
`resetCursorRects`, giving us a chance to re-set the cursor when the OS
decides to invalidate it.

Finally, it fixes a separate bug introduced in zed-industries#50827 where moving the
mouse while typing in an editor would cause to the cursor to flicker
between `None` (hidden) -> `Arrow` -> `IBeam`. This was caused by
incorrectly resetting the cursor to `Arrow` when the last input came
from the keyboard.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
tahayvr pushed a commit to tahayvr/zed that referenced this pull request Apr 28, 2026
zed-industries#48029 introduced `set_document_path` which is frequently (we are also
working on a PR to make it less frequent) called as tabs and panes
update. Apparently, the AppKit function it uses
(`NSWindow::setRepresentedFilename`) can cause the current cursor style
to be reset, producing flicker as the cursor would change to `Arrow`
temporarily until the right cursor style is set again in the next frame.

This PR reworks how we set the cursor to use AppKit's
`resetCursorRects`, giving us a chance to re-set the cursor when the OS
decides to invalidate it.

Finally, it fixes a separate bug introduced in zed-industries#50827 where moving the
mouse while typing in an editor would cause to the cursor to flicker
between `None` (hidden) -> `Arrow` -> `IBeam`. This was caused by
incorrectly resetting the cursor to `Arrow` when the last input came
from the keyboard.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
pull Bot pushed a commit to kp-forks/zed that referenced this pull request Apr 30, 2026
…d-industries#55310)

Regression introduced in zed-industries#48029, applying the same workaround here that
we seem to use for `setDocumentEdited`

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- (Preview only) Fixed an issue on macOS where the traffic light
position would be wrong when opening the project search
ebaah46 pushed a commit to ebaah46/zed that referenced this pull request May 6, 2026
zed-industries#48029 introduced `set_document_path` which is frequently (we are also
working on a PR to make it less frequent) called as tabs and panes
update. Apparently, the AppKit function it uses
(`NSWindow::setRepresentedFilename`) can cause the current cursor style
to be reset, producing flicker as the cursor would change to `Arrow`
temporarily until the right cursor style is set again in the next frame.

This PR reworks how we set the cursor to use AppKit's
`resetCursorRects`, giving us a chance to re-set the cursor when the OS
decides to invalidate it.

Finally, it fixes a separate bug introduced in zed-industries#50827 where moving the
mouse while typing in an editor would cause to the cursor to flicker
between `None` (hidden) -> `Arrow` -> `IBeam`. This was caused by
incorrectly resetting the cursor to `Arrow` when the last input came
from the keyboard.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
ebaah46 pushed a commit to ebaah46/zed that referenced this pull request May 6, 2026
…d-industries#55310)

Regression introduced in zed-industries#48029, applying the same workaround here that
we seem to use for `setDocumentEdited`

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- (Preview only) Fixed an issue on macOS where the traffic light
position would be wrong when opening the project search
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:gpui GPUI rendering framework support cla-signed The user has signed the Contributor License Agreement first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants