diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 03:46:16 +0300 |
|---|---|---|
| committer | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 03:46:16 +0300 |
| commit | 8525503dba9029d0a5f24990e026d8164f0bf39c (patch) | |
| tree | 43b902dfab49603c667ae016baa97aee27724073 /src/app | |
| parent | a08dfaef2f13873fc85dc9e1357235b8b0703a46 (diff) | |
fix: match ghostty pane default colors to host terminal theme
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/input.rs | 14 | ||||
| -rw-r--r-- | src/app/mod.rs | 42 | ||||
| -rw-r--r-- | src/app/state.rs | 4 |
3 files changed, 54 insertions, 6 deletions
diff --git a/src/app/input.rs b/src/app/input.rs index 688a2a05..baa46e4c 100644 --- a/src/app/input.rs +++ b/src/app/input.rs @@ -2080,9 +2080,12 @@ impl AppState { } } - MouseEventKind::Up(MouseButton::Middle) | MouseEventKind::Up(MouseButton::Right) + MouseEventKind::Up(MouseButton::Middle) + | MouseEventKind::Up(MouseButton::Right) | MouseEventKind::Drag(MouseButton::Middle) - | MouseEventKind::Drag(MouseButton::Right) if !in_sidebar => { + | MouseEventKind::Drag(MouseButton::Right) + if !in_sidebar => + { if let Some(info) = self.pane_mouse_target(mouse.column, mouse.row).cloned() { let _ = self.forward_pane_mouse_button(&info, mouse); } @@ -2390,7 +2393,8 @@ impl AppState { } fn pane_mouse_target(&self, col: u16, row: u16) -> Option<&PaneInfo> { - self.pane_at(col, row).or_else(|| self.pane_frame_at(col, row)) + self.pane_at(col, row) + .or_else(|| self.pane_frame_at(col, row)) } fn pane_frame_at(&self, col: u16, row: u16) -> Option<&PaneInfo> { @@ -2613,7 +2617,9 @@ impl AppState { .and_then(|rt| rt.cwd()); if let Some(ws) = self.active.and_then(|i| self.workspaces.get_mut(i)) { - if let Ok(new_id) = ws.split_focused(direction, new_rows, new_cols, cwd) { + if let Ok(new_id) = + ws.split_focused(direction, new_rows, new_cols, cwd, self.host_terminal_theme) + { ws.layout.focus_pane(new_id); self.mode = Mode::Terminal; } diff --git a/src/app/mod.rs b/src/app/mod.rs index b53024b1..064b153a 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -256,6 +256,7 @@ impl App { original_theme: None, }, global_menu: state::MenuListState::new(0), + host_terminal_theme: crate::terminal_theme::TerminalTheme::default(), }; for ws in &mut state.workspaces { @@ -308,6 +309,7 @@ impl App { if self.input_rx.is_none() { self.input_rx = Some(crate::raw_input::spawn_input_reader()); } + self.query_host_terminal_theme(); let mut needs_render = true; @@ -494,10 +496,44 @@ impl App { self.handle_mouse(mouse); true } + crate::raw_input::RawInputEvent::HostDefaultColor { kind, color } => { + let next_theme = self.state.host_terminal_theme.with_color(kind, color); + if next_theme == self.state.host_terminal_theme { + return false; + } + self.state.host_terminal_theme = next_theme; + self.apply_host_terminal_theme_to_panes(); + true + } crate::raw_input::RawInputEvent::Unsupported => false, } } + fn query_host_terminal_theme(&self) { + use std::io::Write; + + let _ = std::io::stdout() + .write_all(crate::terminal_theme::HOST_COLOR_QUERY_SEQUENCE.as_bytes()); + let _ = std::io::stdout().flush(); + } + + fn apply_host_terminal_theme_to_panes(&self) { + if self.state.host_terminal_theme.is_empty() { + return; + } + + for workspace in &self.state.workspaces { + for tab in &workspace.tabs { + for runtime in tab.runtimes.values() { + runtime.apply_host_terminal_theme(self.state.host_terminal_theme); + } + } + } + + self.render_dirty.store(true, Ordering::Release); + self.render_notify.notify_one(); + } + fn handle_resize_poll(&mut self) -> bool { let Ok(size) = terminal::size() else { return false; @@ -1179,7 +1215,7 @@ impl App { .workspaces .get_mut(ws_idx) .ok_or_else(|| std::io::Error::other("workspace disappeared")) - .and_then(|ws| ws.create_tab(rows, cols, cwd)); + .and_then(|ws| ws.create_tab(rows, cols, cwd, self.state.host_terminal_theme)); match result { Ok(tab_idx) => { if params.focus { @@ -1378,6 +1414,7 @@ impl App { rows, cols, params.cwd.map(std::path::PathBuf::from), + self.state.host_terminal_theme, ) { Ok(new_pane_id) => new_pane_id, Err(err) => { @@ -1907,7 +1944,7 @@ impl App { }; let (rows, cols) = self.state.estimate_pane_size(); let ws = &mut self.state.workspaces[ws_idx]; - let idx = ws.create_tab(rows, cols, initial_cwd)?; + let idx = ws.create_tab(rows, cols, initial_cwd, self.state.host_terminal_theme)?; if focus { ws.switch_tab(idx); self.state.mode = Mode::Terminal; @@ -1925,6 +1962,7 @@ impl App { initial_cwd, rows, cols, + self.state.host_terminal_theme, self.event_tx.clone(), self.render_notify.clone(), self.render_dirty.clone(), diff --git a/src/app/state.rs b/src/app/state.rs index 6708ef65..c55b5cd8 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -5,6 +5,7 @@ use ratatui::style::Color; use crate::layout::{PaneInfo, SplitBorder}; use crate::selection::Selection; +use crate::terminal_theme::TerminalTheme; use crate::workspace::Workspace; // --------------------------------------------------------------------------- @@ -595,6 +596,8 @@ pub struct AppState { pub settings: SettingsState, /// Highlight state for the bottom-right global launcher menu. pub global_menu: MenuListState, + /// Resolved host terminal default colors for theming embedded panes. + pub host_terminal_theme: TerminalTheme, } impl AppState { @@ -740,6 +743,7 @@ impl AppState { original_theme: None, }, global_menu: MenuListState::new(0), + host_terminal_theme: TerminalTheme::default(), } } } |
