gpui: Add support for NSWindow's representedFilename#48029
gpui: Add support for NSWindow's representedFilename#48029ChristopherBiscardi merged 3 commits intozed-industries:mainfrom
Conversation
|
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'. |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
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! |
|
Is there anything I can do to help get this reviewed? |
|
Friendly ping :-) |
f77f360 to
2e0efa4
Compare
|
@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.
2e0efa4 to
5eb1784
Compare
|
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. |
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 ( The official PrerequisitesInstall Zed's fork of cargo install cargo-bundle --git https://github.com/zed-industries/cargo-bundle.git --branch zed-deploySteps
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. |
|
@ChristopherBiscardi Were you able to access Zed debug builds in Accessibility Inspector using the steps I provided? |
ChristopherBiscardi
left a comment
There was a problem hiding this comment.
@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.
There was a problem hiding this comment.
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 callwindow.set_document_path(...). - Add
Window::set_document_path()and aPlatformWindow::set_document_path(...)hook with implementations for macOS and the test platform. - Extend test infrastructure to record
document_pathon 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.
| let document_path = active_project_path | ||
| .as_ref() | ||
| .and_then(|path| project.absolute_path(path, cx)); |
There was a problem hiding this comment.
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).
| 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 | |
| }; |
| 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 |
There was a problem hiding this comment.
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.
| 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) |
|
Thank you for the work here @MrMage 🙏🏼 |
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>
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>
…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
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>
…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
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 callssetRepresentedFilename:on the underlying NSWindow. The workspace updates this path inupdate_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
AXDocumentproperty (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
AXDocumentproperty 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 buildingmain, so I assume it’s unrelated to my changes.Release Notes: