Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/next/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- Experimental pane graphics now support bounded named layers, acknowledged full-RGBA primary-layer direct file frames on audited local terminals, owned BGRA fallback, exact pixel mouse input, and placement-only resize replay.

### Fixed
- Herdr no longer sends the full OSC 4 palette query burst under WSL, preventing reply fragments from leaking into the shell through ConPTY. (#2440)
- Qwen Code panes now use locale-independent terminal-title states and localized confirmation fallbacks, preventing active or blocked turns from appearing idle. (#2756)
- Closing a terminal running `herdr --remote` no longer produces a local client core dump while the remote session stays alive. (#2424)
- Active Space and Agent rows now use dedicated theme colors that remain visible when the host terminal background matches the selected Herdr theme. (#2792)
Expand Down
4 changes: 3 additions & 1 deletion src/app/theme_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ impl App {
pub(super) fn query_host_terminal_theme(&self) {
use std::io::Write;

let query = crate::terminal_theme::host_terminal_theme_query_sequence();
let query = crate::terminal_theme::host_terminal_theme_query_sequence(
crate::platform::should_query_host_terminal_palette(),
);
let _ = std::io::stdout().write_all(query.as_bytes());
let _ = std::io::stdout().flush();
}
Expand Down
9 changes: 7 additions & 2 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2571,7 +2571,9 @@ fn should_query_host_terminal_theme() -> bool {
}

fn write_host_terminal_theme_query(mut writer: impl io::Write) -> io::Result<()> {
let query = crate::terminal_theme::host_terminal_theme_query_sequence();
let query = crate::terminal_theme::host_terminal_theme_query_sequence(
crate::platform::should_query_host_terminal_palette(),
);
writer.write_all(query.as_bytes())?;
writer.flush()
}
Expand Down Expand Up @@ -2999,7 +3001,10 @@ mod tests {
write_host_terminal_theme_query(&mut output).unwrap();
assert_eq!(
output,
crate::terminal_theme::host_terminal_theme_query_sequence().as_bytes()
crate::terminal_theme::host_terminal_theme_query_sequence(
crate::platform::should_query_host_terminal_palette(),
)
.as_bytes()
);
assert!(!output
.windows(crate::terminal_theme::HOST_COLOR_SCHEME_QUERY_SEQUENCE.len())
Expand Down
4 changes: 4 additions & 0 deletions src/platform/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ pub(crate) fn should_draw_host_cursor_by_default() -> bool {
false
}

pub(crate) fn should_query_host_terminal_palette() -> bool {
false
}

pub(crate) fn hostname() -> Option<String> {
None
}
Expand Down
4 changes: 4 additions & 0 deletions src/platform/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub(crate) fn should_draw_host_cursor_by_default() -> bool {
running_inside_wsl()
}

pub(crate) fn should_query_host_terminal_palette() -> bool {
!running_inside_wsl()
}

fn running_inside_wsl() -> bool {
proc_file_indicates_wsl("/proc/sys/kernel/osrelease")
|| proc_file_indicates_wsl("/proc/version")
Expand Down
4 changes: 4 additions & 0 deletions src/platform/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ pub(crate) fn should_draw_host_cursor_by_default() -> bool {
false
}

pub(crate) fn should_query_host_terminal_palette() -> bool {
true
}

fn raw_command_argv(command: &str, flag: &str) -> Vec<std::ffi::OsString> {
vec!["/bin/sh".into(), flag.into(), command.into()]
}
Expand Down
4 changes: 4 additions & 0 deletions src/platform/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ pub(crate) fn should_draw_host_cursor_by_default() -> bool {
true
}

pub(crate) fn should_query_host_terminal_palette() -> bool {
false
}

/// The machine's node name, as shown by tmux's `#h`.
pub(crate) fn hostname() -> Option<String> {
std::env::var("COMPUTERNAME")
Expand Down
15 changes: 11 additions & 4 deletions src/terminal_theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,14 @@ impl TerminalTheme {
}
}

pub fn host_terminal_theme_query_sequence() -> String {
pub fn host_terminal_theme_query_sequence(include_palette: bool) -> String {
use std::fmt::Write as _;

let mut sequence = String::from(HOST_COLOR_QUERY_SEQUENCE);
for index in 0..=u8::MAX {
let _ = write!(sequence, "\x1b]4;{index};?\x1b\\");
if include_palette {
for index in 0..=u8::MAX {
let _ = write!(sequence, "\x1b]4;{index};?\x1b\\");
}
}
sequence
}
Expand Down Expand Up @@ -218,11 +220,16 @@ mod tests {
))
);

let query = host_terminal_theme_query_sequence();
let query = host_terminal_theme_query_sequence(true);
assert!(query.starts_with(HOST_COLOR_QUERY_SEQUENCE));
assert!(query.contains("\x1b]4;0;?\x1b\\"));
assert!(query.ends_with("\x1b]4;255;?\x1b\\"));
assert_eq!(query.matches("\x1b]4;").count(), 256);

assert_eq!(
host_terminal_theme_query_sequence(false),
HOST_COLOR_QUERY_SEQUENCE
);
}

#[test]
Expand Down
Loading