feat: add per-pane default foreground/background color support (#4737)

* feat: add per-pane default foreground/background color support

Add per-pane default foreground and background colors, configurable
through four surfaces:

- OSC 10/11 escape sequences (set/query) and OSC 110/111 (reset)
- CLI action: zellij action set-pane-color --pane-id <id> --fg/--bg
- Layout config: default_fg/default_bg properties on pane nodes
- Plugin API: set_pane_color() SDK function and PaneInfo read-side

Colors are applied at render time as a fallback when cells have no
explicit foreground/background, without mutating stored grid data.

Closes #4712

* refactor: address review feedback for pane color support

- Extract adjust_styles_for_custom_bg_fg in output/mod.rs
- Move color parsing (xparse_color) from tab into Grid
- Move color serialization (ansi_code_to_color_string) into Grid
- Pane trait now uses Option<String> for color getters/setters
- Add colors to session serialization (dump-layout)
- Add default_fg/default_bg to protobuf IPC schema to fix
  layout-in-session color loss
- Update example layout with tab-bar and status-bar

* fix stack overflow and ordering

* rustfmt

* update e2e snapshots

---------

Co-authored-by: Karl Bunch <[email protected]>
Co-authored-by: Aram Drevekenin <[email protected]>
This commit is contained in:
Karl Bunch
2026-03-04 14:26:26 +01:00
committed by GitHub
co-authored by Karl Bunch Aram Drevekenin
parent d7a5de9eae
commit f77cdec298
84 changed files with 1825 additions and 163 deletions
+13
View File
@@ -2392,6 +2392,19 @@ pub fn set_pane_borderless(pane_id: PaneId, borderless: bool) {
unsafe { host_run_plugin_command() };
}
/// Set the default foreground and/or background color of a pane
///
/// # Arguments
/// * `pane_id` - The ID of the pane (PaneId::Terminal or PaneId::Plugin)
/// * `fg` - Optional foreground color string (e.g. "#00e000"), None to leave unchanged
/// * `bg` - Optional background color string (e.g. "#001a3a"), None to leave unchanged
pub fn set_pane_color(pane_id: PaneId, fg: Option<String>, bg: Option<String>) {
let plugin_command = PluginCommand::SetPaneColor(pane_id, fg, bg);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() };
}
pub fn start_web_server() {
let plugin_command = PluginCommand::StartWebServer;
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();