Skip to content

Commit 68a4560

Browse files
committed
Poll for responses to feature queries
Some terminals don't respond to queries (even primary device attributes request) at all. In that case we can wait for a while but should eventually give up and use default capabilities.
1 parent 4a1e10e commit 68a4560

File tree

1 file changed

+39
-28
lines changed

1 file changed

+39
-28
lines changed

helix-tui/src/backend/termina.rs

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl TerminaBackend {
116116
terminal: &mut PlatformTerminal,
117117
config: &Config,
118118
) -> io::Result<(Capabilities, String)> {
119-
use std::time::Instant;
119+
use std::time::{Duration, Instant};
120120

121121
// Colibri "midnight"
122122
const TEST_COLOR: RgbColor = RgbColor::new(59, 34, 76);
@@ -151,36 +151,47 @@ impl TerminaBackend {
151151
)?;
152152
terminal.flush()?;
153153

154-
loop {
155-
match terminal.read(Event::is_escape)? {
156-
Event::Csi(Csi::Keyboard(csi::Keyboard::ReportFlags(_))) => {
157-
capabilities.kitty_keyboard = KittyKeyboardSupport::Some;
158-
}
159-
Event::Csi(Csi::Mode(csi::Mode::ReportDecPrivateMode {
160-
mode: csi::DecPrivateMode::Code(csi::DecPrivateModeCode::SynchronizedOutput),
161-
setting: csi::DecModeSetting::Set | csi::DecModeSetting::Reset,
162-
})) => {
163-
capabilities.synchronized_output = true;
164-
}
165-
Event::Dcs(dcs::Dcs::Response {
166-
value: dcs::DcsResponse::GraphicRendition(sgrs),
167-
..
168-
}) => {
169-
capabilities.true_color =
170-
sgrs.contains(&csi::Sgr::Background(TEST_COLOR.into()));
171-
capabilities.extended_underlines =
172-
sgrs.contains(&csi::Sgr::UnderlineColor(TEST_COLOR.into()));
154+
// TODO: tune this poll constant?
155+
let device_attributes = |event: &Event| {
156+
matches!(
157+
event,
158+
Event::Csi(Csi::Device(csi::Device::DeviceAttributes(_)))
159+
)
160+
};
161+
if terminal.poll(device_attributes, Some(Duration::from_millis(20)))? {
162+
loop {
163+
match terminal.read(Event::is_escape)? {
164+
Event::Csi(Csi::Keyboard(csi::Keyboard::ReportFlags(_))) => {
165+
capabilities.kitty_keyboard = KittyKeyboardSupport::Some;
166+
}
167+
Event::Csi(Csi::Mode(csi::Mode::ReportDecPrivateMode {
168+
mode: csi::DecPrivateMode::Code(csi::DecPrivateModeCode::SynchronizedOutput),
169+
setting: csi::DecModeSetting::Set | csi::DecModeSetting::Reset,
170+
})) => {
171+
capabilities.synchronized_output = true;
172+
}
173+
Event::Dcs(dcs::Dcs::Response {
174+
value: dcs::DcsResponse::GraphicRendition(sgrs),
175+
..
176+
}) => {
177+
capabilities.true_color =
178+
sgrs.contains(&csi::Sgr::Background(TEST_COLOR.into()));
179+
capabilities.extended_underlines =
180+
sgrs.contains(&csi::Sgr::UnderlineColor(TEST_COLOR.into()));
181+
}
182+
Event::Csi(Csi::Device(csi::Device::DeviceAttributes(_))) => break,
183+
_ => (),
173184
}
174-
Event::Csi(Csi::Device(csi::Device::DeviceAttributes(_))) => break,
175-
_ => (),
176185
}
177-
}
178186

179-
let end = Instant::now();
180-
log::debug!(
181-
"Detected terminal capabilities in {:?}: {capabilities:?}",
182-
end.duration_since(start)
183-
);
187+
let end = Instant::now();
188+
log::debug!(
189+
"Detected terminal capabilities in {:?}: {capabilities:?}",
190+
end.duration_since(start)
191+
);
192+
} else {
193+
log::debug!("Failed to detect terminal capabilities within 20ms. Using default capabilities only");
194+
}
184195

185196
capabilities.extended_underlines |= config.force_enable_extended_underlines;
186197

0 commit comments

Comments
 (0)