diff --git a/src/kitty.rs b/src/kitty.rs index 6be9672..c805b67 100644 --- a/src/kitty.rs +++ b/src/kitty.rs @@ -20,6 +20,12 @@ use ratatui::prelude::Rect; use crate::converter::MaybeTransferred; +pub enum KittyDisplay<'tui> { + NoChange, + ClearImages, + DisplayImages(Vec<(usize, &'tui mut MaybeTransferred, Rect)>) +} + pub struct DbgWriter { w: W, #[cfg(debug_assertions)] @@ -82,7 +88,7 @@ pub async fn do_shms_work(ev_stream: &mut EventStream) -> bool { } pub async fn display_kitty_images<'es>( - images: Vec<(usize, &mut MaybeTransferred, Rect)>, + display: KittyDisplay<'_>, ev_stream: &'es mut EventStream ) -> Result< (), @@ -92,15 +98,26 @@ pub async fn display_kitty_images<'es>( TransmitError<<&'es mut EventStream as AsyncInputReader>::Error> ) > { - run_action( - Action::Delete(DeleteConfig { - effect: ClearOrDelete::Clear, - which: WhichToDelete::All - }), - ev_stream - ) - .await - .map_err(|e| (vec![], "Couldn't clear previous images", e))?; + let images = match display { + KittyDisplay::NoChange => return Ok(()), + KittyDisplay::DisplayImages(_) | KittyDisplay::ClearImages => { + run_action( + Action::Delete(DeleteConfig { + effect: ClearOrDelete::Clear, + which: WhichToDelete::All + }), + ev_stream + ) + .await + .map_err(|e| (vec![], "Couldn't clear previous images", e))?; + + let KittyDisplay::DisplayImages(images) = display else { + return Ok(()); + }; + + images + } + }; let mut err = None; for (page_num, img, area) in images { diff --git a/src/main.rs b/src/main.rs index 95a6c81..80acbf7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,7 +29,7 @@ use ratatui_image::picker::{Picker, ProtocolType}; use tdf::{ PrerenderLimit, converter::{ConvertedPage, ConverterMsg, run_conversion_loop}, - kitty::{display_kitty_images, do_shms_work, run_action}, + kitty::{KittyDisplay, display_kitty_images, do_shms_work, run_action}, renderer::{self, RenderError, RenderInfo, RenderNotif}, tui::{BottomMessage, InputAction, MessageSetting, Tui} }; @@ -422,34 +422,32 @@ async fn enter_redraw_loop( } if needs_redraw { - let mut to_display = vec![]; + let mut to_display = KittyDisplay::NoChange; term.draw(|f| { to_display = tui.render(f, &main_area); })?; - if !to_display.is_empty() { - let maybe_err = display_kitty_images(to_display, &mut ev_stream).await; + let maybe_err = display_kitty_images(to_display, &mut ev_stream).await; - if let Err((to_replace, err_desc, enum_err)) = maybe_err { - match enum_err { - // This is the error that kitty & ghostty provide us when they delete an - // image due to memory constraints, so if we get it, we just fix it by - // re-rendering so it don't display it to the user - // - // [TODO] maybe when we detect that an image was deleted, we probe the - // terminal for the pages around it to see if they were deleted too and if - // they were, we re-render them? idk - TransmitError::Terminal(TerminalError::NoEntity(_)) => (), - _ => tui.set_msg(MessageSetting::Some(BottomMessage::Error(format!( - "{err_desc}: {enum_err}" - )))) - } + if let Err((to_replace, err_desc, enum_err)) = maybe_err { + match enum_err { + // This is the error that kitty & ghostty provide us when they delete an + // image due to memory constraints, so if we get it, we just fix it by + // re-rendering so it don't display it to the user + // + // [TODO] maybe when we detect that an image was deleted, we probe the + // terminal for the pages around it to see if they were deleted too and if + // they were, we re-render them? idk + TransmitError::Terminal(TerminalError::NoEntity(_)) => (), + _ => tui.set_msg(MessageSetting::Some(BottomMessage::Error(format!( + "{err_desc}: {enum_err}" + )))) + } - for page_num in to_replace { - tui.page_failed_display(page_num); - // So that they get re-rendered and sent over again - to_renderer.send(RenderNotif::PageNeedsReRender(page_num))?; - } + for page_num in to_replace { + tui.page_failed_display(page_num); + // So that they get re-rendered and sent over again + to_renderer.send(RenderNotif::PageNeedsReRender(page_num))?; } } diff --git a/src/tui.rs b/src/tui.rs index 2224cff..d232863 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -24,6 +24,7 @@ use ratatui_image::Image; use crate::{ converter::{ConvertedImage, MaybeTransferred}, + kitty::KittyDisplay, renderer::{RenderError, fill_default}, skip::Skip }; @@ -133,10 +134,10 @@ impl Tui { &'s mut self, frame: &mut Frame<'_>, full_layout: &RenderLayout - ) -> Vec<(usize, &'s mut MaybeTransferred, Rect)> { + ) -> KittyDisplay<'s> { if self.showing_help_msg { self.render_help_msg(frame); - return vec![]; + return KittyDisplay::ClearImages; } if let Some((top_area, bottom_area)) = full_layout.top_and_bottom { @@ -243,7 +244,7 @@ impl Tui { // be written and set to skip it so that ratatui doesn't spend a lot of time diffing it // each re-render frame.render_widget(Skip::new(true), img_area); - vec![] + KittyDisplay::NoChange } else { // here we calculate how many pages can fit in the available area. let mut test_area_w = img_area.width; @@ -279,7 +280,7 @@ impl Tui { if page_widths.is_empty() { // If none are ready to render, just show the loading thing Self::render_loading_in(frame, img_area); - vec![] + KittyDisplay::ClearImages } else { execute!(stdout(), BeginSynchronizedUpdate).unwrap(); @@ -306,7 +307,7 @@ impl Tui { // then the whole diffing thing messes it up self.last_render.rect = size; - to_display + KittyDisplay::DisplayImages(to_display) } } }