diff --git a/src/picker.rs b/src/picker.rs
index df9057a..05e09c2 100644
--- a/src/picker.rs
+++ b/src/picker.rs
@@ -117,27 +117,28 @@ impl Picker {
capabilities: Vec::new(),
};
+ let mut options_with_blacklist = options;
+ let is_wezterm = env::var("WEZTERM_EXECUTABLE").is_ok_and(|s| !s.is_empty());
+ let is_konsole = env::var("KONSOLE_VERSION").is_ok_and(|s| !s.is_empty());
+ if is_wezterm || is_konsole {
+ // WezTerm could use Sixel, but iTerm2 (detected later is better).
+ // Konsole's Sixel implementation is buggy: https://github.com/benjajaja/ratatui-image?tab=readme-ov-file#compatibility-matrix
+ // Neither implement the placeholder part of kitty correctly.
+ options_with_blacklist
+ .blacklist_protocols(vec![ProtocolType::Kitty, ProtocolType::Sixel]);
+ }
+
// Write and read to stdin to query protocol capabilities and font-size.
- match query_with_timeout(is_tmux, options) {
+ match query_with_timeout(is_tmux, options_with_blacklist) {
Ok((capability_proto, font_size, caps)) => {
let iterm2_proto = iterm2_from_env();
- // Wezterm reports kitty support but its implementation is incomplete.
- // Suppress kitty and default to iterm2 (which wezterm fully supports).
- let is_wezterm = env::var("WEZTERM_EXECUTABLE").is_ok_and(|s| !s.is_empty());
-
// IO-based detection is authoritative; env-based hints are fallbacks
// (env vars like KITTY_WINDOW_ID can be stale in tmux sessions).
- let protocol_type = if is_wezterm {
- capability_proto
- .filter(|p| *p != ProtocolType::Kitty)
- .unwrap_or(ProtocolType::Iterm2)
- } else {
- capability_proto
- .or(tmux_proto)
- .or(iterm2_proto)
- .unwrap_or(ProtocolType::Halfblocks)
- };
+ let protocol_type = capability_proto
+ .or(tmux_proto)
+ .or(iterm2_proto)
+ .unwrap_or(ProtocolType::Halfblocks);
if let Some(font_size) = font_size {
Ok(Self {
diff --git a/src/picker/cap_parser.rs b/src/picker/cap_parser.rs
index ea3fa7a..fd51575 100644
--- a/src/picker/cap_parser.rs
+++ b/src/picker/cap_parser.rs
@@ -1,7 +1,7 @@
//! Terminal stdio query parser module.
use std::{fmt::Write, time::Duration};
-use crate::picker::STDIN_READ_TIMEOUT_MILLIS;
+use crate::picker::{ProtocolType, STDIN_READ_TIMEOUT_MILLIS};
pub struct Parser {
data: String,
@@ -27,13 +27,22 @@ pub enum Response {
/// Extra query options
pub struct QueryStdioOptions {
- // Timeout for the stdio query.
+ /// Timeout for the stdio query.
pub timeout: Duration,
/// Query for [Text Sizing Protocol]. The result can be checked by searching for
/// [crate::picker::Capability::TextSizingProtocol] in [crate::picker::Picker::capabilities].
///
/// [Text Sizing Protocol]
pub text_sizing_protocol: bool,
+ /// Blacklist protocols from the detection query. Currently only kitty can be detected, so that
+ /// is the only ProtocolType that can have any effect here.
+ /// [`crate::picker::Picker`] currently sets ProtocolType::Kitty for WezTerm and Konsole.
+ blacklist_protocols: Vec,
+}
+impl QueryStdioOptions {
+ pub(crate) fn blacklist_protocols(&mut self, protocol_types: Vec) {
+ self.blacklist_protocols = protocol_types;
+ }
}
impl Default for QueryStdioOptions {
@@ -41,6 +50,7 @@ impl Default for QueryStdioOptions {
Self {
timeout: Duration::from_millis(STDIN_READ_TIMEOUT_MILLIS),
text_sizing_protocol: false,
+ blacklist_protocols: Vec::new(),
}
}
}
@@ -74,11 +84,15 @@ impl Parser {
let mut buf = String::with_capacity(100);
buf.push_str(start);
- // Kitty graphics
- write!(buf, "{escape}_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA{escape}\\").unwrap();
+ if !options.blacklist_protocols.contains(&ProtocolType::Kitty) {
+ // Kitty graphics
+ write!(buf, "{escape}_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA{escape}\\").unwrap();
+ }
- // Device Attributes Report 1 (sixel support)
- write!(buf, "{escape}[c").unwrap();
+ if !options.blacklist_protocols.contains(&ProtocolType::Sixel) {
+ // Device Attributes Report 1 (sixel support)
+ write!(buf, "{escape}[c").unwrap();
+ }
// Font size in pixels
write!(buf, "{escape}[16t").unwrap();