aboutsummaryrefslogtreecommitdiff
path: root/src/server/client_shell.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/client_shell.rs')
-rw-r--r--src/server/client_shell.rs115
1 files changed, 87 insertions, 28 deletions
diff --git a/src/server/client_shell.rs b/src/server/client_shell.rs
index 554e8167..d542896a 100644
--- a/src/server/client_shell.rs
+++ b/src/server/client_shell.rs
@@ -276,6 +276,12 @@ pub(super) struct RenderedPaneSurface {
pub(super) graphics_delivery: crate::kitty_graphics::surface::DeliveryCache,
}
+#[derive(Debug)]
+pub(super) enum SurfaceRenderDeferred {
+ Synchronized,
+ Changed,
+}
+
pub(super) fn render_pane_surface(
app: &mut app::App,
target: Option<crate::ui::TabSurfaceTarget>,
@@ -285,36 +291,54 @@ pub(super) fn render_pane_surface(
cell_size: crate::kitty_graphics::HostCellSize,
graphics_delivery: &crate::kitty_graphics::surface::DeliveryCache,
client_id: u64,
-) -> RenderedPaneSurface {
- let content_revisions_before = target
- .and_then(|target| {
- let workspace = app.state.workspaces.get(target.workspace_index)?;
- let tab = workspace.tabs.get(target.tab_index)?;
- Some(
- tab.layout
- .pane_ids()
- .into_iter()
- .filter_map(|pane_id| {
- app.state
- .runtime_for_pane_in_workspace(
- &app.terminal_runtimes,
- target.workspace_index,
- pane_id,
- )
- .map(|runtime| (pane_id, runtime.content_seq()))
- })
- .collect::<std::collections::HashMap<_, _>>(),
- )
- })
- .unwrap_or_default();
+) -> Result<RenderedPaneSurface, SurfaceRenderDeferred> {
+ let layout = crate::ui::compute_tab_surface_for(
+ &app.state,
+ &app.terminal_runtimes,
+ target,
+ area,
+ resize_panes,
+ cell_size,
+ );
+ let mut content_revisions_before = std::collections::HashMap::new();
+ if let Some(target) = target {
+ for pane in &layout.pane_infos {
+ if let Some(runtime) = app.state.runtime_for_pane_in_workspace(
+ &app.terminal_runtimes,
+ target.workspace_index,
+ pane.id,
+ ) {
+ let (synchronized, epoch) = runtime.synchronized_output_state();
+ if synchronized {
+ return Err(SurfaceRenderDeferred::Synchronized);
+ }
+ let revision = runtime.content_seq();
+ content_revisions_before.insert(pane.id, (epoch, revision));
+ }
+ }
+ }
+ let popup_revision_before = if show_popup {
+ app.state
+ .popup_pane
+ .as_ref()
+ .and_then(|popup| app.terminal_runtimes.get(&popup.terminal_id))
+ .map(|runtime| {
+ let (synchronized, epoch) = runtime.synchronized_output_state();
+ if synchronized {
+ return Err(SurfaceRenderDeferred::Synchronized);
+ }
+ Ok(epoch)
+ })
+ .transpose()?
+ } else {
+ None
+ };
let (buffer, cursor, hyperlinks, layout) =
crate::server::render_stream::render_tab_surface_virtual(
&app.state,
&app.terminal_runtimes,
- target,
+ layout,
area,
- resize_panes,
- cell_size,
);
let panes = target
.map(|target| {
@@ -343,7 +367,9 @@ pub(super) fn render_pane_surface(
};
let content_revision = runtime.map_or(0, |runtime| {
let after = runtime.content_seq();
- if content_revisions_before.get(&pane.id).copied() == Some(after)
+ if content_revisions_before
+ .get(&pane.id)
+ .is_some_and(|&(_, before)| before == after)
&& after.is_multiple_of(2)
{
after
@@ -422,14 +448,47 @@ pub(super) fn render_pane_surface(
graphics_delivery,
client_id,
);
- RenderedPaneSurface {
+ if let Some(target) = target {
+ for (&pane_id, &(epoch, _)) in &content_revisions_before {
+ if let Some(runtime) = app.state.runtime_for_pane_in_workspace(
+ &app.terminal_runtimes,
+ target.workspace_index,
+ pane_id,
+ ) {
+ let (synchronized, after_epoch) = runtime.synchronized_output_state();
+ if synchronized {
+ return Err(SurfaceRenderDeferred::Synchronized);
+ }
+ if after_epoch != epoch {
+ return Err(SurfaceRenderDeferred::Changed);
+ }
+ }
+ }
+ }
+ if let Some(before) = popup_revision_before {
+ if let Some(runtime) = app
+ .state
+ .popup_pane
+ .as_ref()
+ .and_then(|popup| app.terminal_runtimes.get(&popup.terminal_id))
+ {
+ let (synchronized, after_epoch) = runtime.synchronized_output_state();
+ if synchronized {
+ return Err(SurfaceRenderDeferred::Synchronized);
+ }
+ if after_epoch != before {
+ return Err(SurfaceRenderDeferred::Changed);
+ }
+ }
+ }
+ Ok(RenderedPaneSurface {
frame: FrameData::from_ratatui_buffer_with_hyperlinks(&buffer, cursor, &hyperlinks),
panes,
splits,
popup,
graphics,
graphics_delivery: next_graphics_delivery,
- }
+ })
}
fn render_popup_surface(