aboutsummaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-05 03:46:16 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 03:46:16 +0300
commit8525503dba9029d0a5f24990e026d8164f0bf39c (patch)
tree43b902dfab49603c667ae016baa97aee27724073 /src/app
parenta08dfaef2f13873fc85dc9e1357235b8b0703a46 (diff)
fix: match ghostty pane default colors to host terminal theme
Diffstat (limited to 'src/app')
-rw-r--r--src/app/input.rs14
-rw-r--r--src/app/mod.rs42
-rw-r--r--src/app/state.rs4
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(),
}
}
}