aboutsummaryrefslogtreecommitdiff
path: root/src/pane
diff options
context:
space:
mode:
Diffstat (limited to 'src/pane')
-rw-r--r--src/pane/terminal.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/pane/terminal.rs b/src/pane/terminal.rs
index c9d0b90a..e2005a8f 100644
--- a/src/pane/terminal.rs
+++ b/src/pane/terminal.rs
@@ -195,6 +195,7 @@ pub(crate) struct GhosttyPaneCore {
#[cfg(test)]
pub dirty_collection_hook: Option<Box<dyn FnOnce() + Send>>,
pub terminal: crate::ghostty::Terminal,
+ synchronized_output_epoch: u64,
#[cfg(windows)]
recent_fallback: windows_recent_fallback::Cache,
pub render_state: crate::ghostty::RenderState,
@@ -482,6 +483,10 @@ impl PaneTerminal {
self.ghostty.synchronized_output_active()
}
+ pub(crate) fn synchronized_output_state(&self) -> (bool, u64) {
+ self.ghostty.synchronized_output_state()
+ }
+
pub fn visible_text(&self) -> String {
self.ghostty.visible_text()
}
@@ -1167,6 +1172,7 @@ impl GhosttyPaneTerminal {
#[cfg(test)]
dirty_collection_hook: None,
terminal,
+ synchronized_output_epoch: 0,
#[cfg(windows)]
recent_fallback: windows_recent_fallback::Cache::default(),
render_state,
@@ -1387,6 +1393,10 @@ impl GhosttyPaneTerminal {
core.decscusr_tracker.observe(bytes);
let in_progress_default_color_event = core.default_color_event_tracker.in_progress_event();
let default_color_events = core.default_color_event_tracker.drain_pending();
+ let synchronized_output_before = core
+ .terminal
+ .mode_get(crate::ghostty::MODE_SYNCHRONIZED_OUTPUT)
+ .unwrap_or(false);
let write_started = crate::render_prof::timer();
self.write_pty_bytes_with_ordered_responses(
&mut core,
@@ -1420,6 +1430,9 @@ impl GhosttyPaneTerminal {
.terminal
.mode_get(crate::ghostty::MODE_SYNCHRONIZED_OUTPUT)
.unwrap_or(false);
+ if synchronized_output != synchronized_output_before {
+ core.synchronized_output_epoch = core.synchronized_output_epoch.wrapping_add(1);
+ }
// Intermediate synchronized-frame positions must not become settled cursors.
if CURSOR_POSITION_SETTLE_ENABLED && !synchronized_output {
let cursor_started = crate::render_prof::timer();
@@ -1660,6 +1673,10 @@ impl GhosttyPaneTerminal {
cell_height_px: u32,
) -> Vec<Bytes> {
if let Ok(mut core) = self.core.lock() {
+ let synchronized_output_before = core
+ .terminal
+ .mode_get(crate::ghostty::MODE_SYNCHRONIZED_OUTPUT)
+ .unwrap_or(false);
#[cfg(windows)]
windows_recent_fallback::refresh_if_needed(&mut core);
let offset_from_bottom = core
@@ -1698,6 +1715,13 @@ impl GhosttyPaneTerminal {
let _ = core
.terminal
.resize(cols, rows, cell_width_px, cell_height_px);
+ let synchronized_output_after = core
+ .terminal
+ .mode_get(crate::ghostty::MODE_SYNCHRONIZED_OUTPUT)
+ .unwrap_or(false);
+ if synchronized_output_after != synchronized_output_before {
+ core.synchronized_output_epoch = core.synchronized_output_epoch.wrapping_add(1);
+ }
let terminal_responses = self.drain_pending_pty_responses();
let bottom_is_blank = ghostty_detection_text(&mut core)
@@ -1971,6 +1995,20 @@ impl GhosttyPaneTerminal {
.unwrap_or(false)
}
+ pub(crate) fn synchronized_output_state(&self) -> (bool, u64) {
+ self.core
+ .lock()
+ .map(|core| {
+ (
+ core.terminal
+ .mode_get(crate::ghostty::MODE_SYNCHRONIZED_OUTPUT)
+ .unwrap_or(false),
+ core.synchronized_output_epoch,
+ )
+ })
+ .unwrap_or((true, 0))
+ }
+
pub fn encode_terminal_key(
&self,
key: crate::input::TerminalKey,
@@ -2308,6 +2346,13 @@ impl GhosttyPaneTerminal {
let Ok(mut core) = self.core.lock() else {
return;
};
+ if core
+ .terminal
+ .mode_get(crate::ghostty::MODE_SYNCHRONIZED_OUTPUT)
+ .unwrap_or(false)
+ {
+ return;
+ }
let host_theme = core.host_terminal_theme;
let initial_default_foreground = core.initial_default_foreground;
let initial_default_background = core.initial_default_background;
@@ -2425,6 +2470,13 @@ impl GhosttyPaneTerminal {
.lock()
.ok()
.map(|mut core| {
+ if core
+ .terminal
+ .mode_get(crate::ghostty::MODE_SYNCHRONIZED_OUTPUT)
+ .unwrap_or(false)
+ {
+ return TerminalDirtyPatchOutcome::Fallback;
+ }
#[cfg(test)]
if let Some(hook) = core.dirty_collection_hook.take() {
hook();
@@ -5947,14 +5999,21 @@ mod tests {
let pane_terminal = GhosttyPaneTerminal::new(terminal, tx.clone()).unwrap();
let pane_id = PaneId::from_raw(1);
+ assert_eq!(pane_terminal.synchronized_output_state(), (false, 0));
+ pane_terminal.process_pty_bytes(pane_id, 0, b"ordinary output", &tx);
+ assert_eq!(pane_terminal.synchronized_output_state(), (false, 0));
+
let begin = pane_terminal.process_pty_bytes(pane_id, 0, b"\x1b[?2026h", &tx);
assert!(!begin.request_render);
+ assert_eq!(pane_terminal.synchronized_output_state(), (true, 1));
let body = pane_terminal.process_pty_bytes(pane_id, 0, b"hello", &tx);
assert!(!body.request_render);
+ assert_eq!(pane_terminal.synchronized_output_state(), (true, 1));
let end = pane_terminal.process_pty_bytes(pane_id, 0, b"\x1b[?2026l", &tx);
assert!(end.request_render);
+ assert_eq!(pane_terminal.synchronized_output_state(), (false, 2));
}
#[test]