Add per-window theme overrides#58755
Open
42piratas wants to merge 1 commit into
Open
Conversation
|
We require contributors to sign our Contributor License Agreement, and we don't have @42piratas 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'. |
Author
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
1 task
Allow each window to use its own theme, chosen by the user and stored user-side keyed by workspace, without changing the app-wide `theme` setting or writing any project file. Windows without an override render the configured theme as before. - gpui: add `App::observe_window_draw` hook (runs at the start of each window's draw) and `App::update_global_quietly` for per-frame global updates that must not notify observers. - theme: add `WindowThemeOverrides` registry keyed by `WindowId`; split `GlobalTheme` into the per-frame active theme and the configured fallback; swap the active theme per window in a draw hook; drop a window's override when it closes. - theme_selector: add `theme: project` and `theme: clear project` actions that scope theme selection to the current project's window. - workspace: persist overrides in a new `window_theme_overrides` table and restore them on launch.
61a068a to
02b16b5
Compare
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.
What
Let each window use its own theme, chosen by the user, so multiple open projects are visually distinguishable at a glance (e.g. prod vs staging, frontend vs backend). The choice is stored user-side, keyed by workspace, and never written to project settings or
settings.json.Addresses #22370, #19510, and the discussion in #32293.
How it works
The active theme is a single app global read at ~155
cx.theme()call sites, so rather than thread a per-window theme through all of them, the active theme is swapped per window at the start of its render pass:App::observe_window_drawruns a callback at the top of eachWindow::draw;App::update_global_quietlymutates a global without scheduling an observer notification (a per-frame notify would cause an unbounded redraw loop).WindowThemeOverridesregistry keyed byWindowId.GlobalThemenow distinguishes the per-frame active theme from the configured fallback. A draw hook sets the active theme to the window's override, or the configured theme if none. Because editors build their style (including syntax) live inrender, this restyles the whole UI per window with no call-site changes.theme: project(scopes the picker to the current project's window) andtheme: clear project.window_theme_overridestable (keyed by workspace) persists the choice; it is restored inload_workspaceon launch.Out of scope
Reading a theme from a project's
.zed/settings.json(intentionally excluded — keeps the "user decides, an untrusted repo can't restyle the editor" property); per-pane theming.Known tradeoff
Theme reads that happen outside a render pass (rare — some event handlers) observe the last-drawn window's theme. Everything rendered is correct per window.
Testing
Open two windows on different folders → command palette → theme selector: toggle window in each → pick different themes. Confirm no
themekey is written to any settings file; clear window theme reverts to global; quit + relaunch restores each window's theme.