aboutsummaryrefslogtreecommitdiff
path: root/src/server/clients.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-18 02:52:35 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-18 02:53:31 +0300
commit36b4001f4526b60f1c9b67a4a34596e5ad2bcca1 (patch)
tree520ab28a0a3f3f798e6e655fc83529e8617720e9 /src/server/clients.rs
parentaca35ea76f3df15ec68fd07959d939f5e7a78a6c (diff)
feat: sync theme with host appearance
refs #675
Diffstat (limited to 'src/server/clients.rs')
-rw-r--r--src/server/clients.rs48
1 files changed, 43 insertions, 5 deletions
diff --git a/src/server/clients.rs b/src/server/clients.rs
index 611d87eb..eb823cfc 100644
--- a/src/server/clients.rs
+++ b/src/server/clients.rs
@@ -33,6 +33,10 @@ pub(crate) struct ClientConnection {
pub(crate) cell_size: crate::kitty_graphics::HostCellSize,
/// Last known host terminal default colors for this client.
pub(crate) host_terminal_theme: crate::terminal_theme::TerminalTheme,
+ /// Last known host terminal appearance for this client.
+ pub(crate) host_terminal_appearance: Option<crate::terminal_theme::HostAppearance>,
+ /// True when appearance came from an explicit host color-scheme report.
+ pub(crate) host_terminal_appearance_explicit: bool,
/// Last reported focus state for this client's outer terminal.
pub(crate) outer_terminal_focus: Option<bool>,
/// Stateful parser for app-client input split across transport reads.
@@ -98,6 +102,10 @@ impl ClientConnection {
keybindings,
terminal_size,
cell_size,
+ host_terminal_appearance: host_terminal_theme
+ .background
+ .map(crate::terminal_theme::RgbColor::inferred_appearance),
+ host_terminal_appearance_explicit: false,
host_terminal_theme,
outer_terminal_focus,
raw_input: crate::raw_input::RawInputFramer::default(),
@@ -130,17 +138,47 @@ impl ClientConnection {
events: &[crate::raw_input::RawInputEvent],
) -> bool {
let mut next_theme = self.host_terminal_theme;
+ let mut changed = false;
for event in events {
- if let crate::raw_input::RawInputEvent::HostDefaultColor { kind, color } = event {
- next_theme = next_theme.with_color(*kind, *color);
+ match event {
+ crate::raw_input::RawInputEvent::HostDefaultColor { kind, color } => {
+ next_theme = next_theme.with_color(*kind, *color);
+ if matches!(kind, crate::terminal_theme::DefaultColorKind::Background)
+ && !self.host_terminal_appearance_explicit
+ {
+ changed |=
+ self.set_host_appearance(Some(color.inferred_appearance()), false);
+ }
+ }
+ crate::raw_input::RawInputEvent::HostColorSchemeChanged(appearance) => {
+ changed |= self.set_host_appearance(Some(*appearance), true);
+ }
+ _ => {}
}
}
- if next_theme == self.host_terminal_theme {
- return false;
+ if next_theme != self.host_terminal_theme {
+ self.host_terminal_theme = next_theme;
+ changed = true;
}
+ changed
+ }
- self.host_terminal_theme = next_theme;
+ fn set_host_appearance(
+ &mut self,
+ appearance: Option<crate::terminal_theme::HostAppearance>,
+ explicit: bool,
+ ) -> bool {
+ if self.host_terminal_appearance_explicit && !explicit {
+ return false;
+ }
+ if self.host_terminal_appearance == appearance
+ && self.host_terminal_appearance_explicit == explicit
+ {
+ return false;
+ }
+ self.host_terminal_appearance = appearance;
+ self.host_terminal_appearance_explicit = explicit;
true
}