mirror of
https://github.com/itsjunetime/tdf.git
synced 2026-06-02 08:01:47 -04:00
fall back to stdout if shms don't work
This commit is contained in:
+3
-1
@@ -122,7 +122,9 @@ pub fn start_converting_loop(
|
|||||||
to_main_tx,
|
to_main_tx,
|
||||||
from_main_rx,
|
from_main_rx,
|
||||||
picker,
|
picker,
|
||||||
prerender
|
prerender,
|
||||||
|
// just assume shms work for now, who cares
|
||||||
|
true
|
||||||
));
|
));
|
||||||
|
|
||||||
let from_converter_rx = from_converter_rx.into_stream();
|
let from_converter_rx = from_converter_rx.into_stream();
|
||||||
|
|||||||
+15
-20
@@ -52,7 +52,8 @@ pub async fn run_conversion_loop(
|
|||||||
sender: Sender<Result<ConvertedPage, RenderError>>,
|
sender: Sender<Result<ConvertedPage, RenderError>>,
|
||||||
receiver: Receiver<ConverterMsg>,
|
receiver: Receiver<ConverterMsg>,
|
||||||
mut picker: Picker,
|
mut picker: Picker,
|
||||||
prerender: usize
|
prerender: usize,
|
||||||
|
shms_work: bool
|
||||||
) -> Result<(), SendError<Result<ConvertedPage, RenderError>>> {
|
) -> Result<(), SendError<Result<ConvertedPage, RenderError>>> {
|
||||||
let mut images = vec![];
|
let mut images = vec![];
|
||||||
let mut page: usize = 0;
|
let mut page: usize = 0;
|
||||||
@@ -64,7 +65,8 @@ pub async fn run_conversion_loop(
|
|||||||
page: usize,
|
page: usize,
|
||||||
iteration: &mut usize,
|
iteration: &mut usize,
|
||||||
prerender: usize,
|
prerender: usize,
|
||||||
pid: u32
|
pid: u32,
|
||||||
|
shms_work: bool
|
||||||
) -> Result<Option<ConvertedPage>, RenderError> {
|
) -> Result<Option<ConvertedPage>, RenderError> {
|
||||||
if images.is_empty() || *iteration >= prerender {
|
if images.is_empty() || *iteration >= prerender {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
@@ -117,10 +119,6 @@ pub async fn run_conversion_loop(
|
|||||||
y: 0
|
y: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// We don't actually want to Crop this image, but we've already
|
|
||||||
// verified (with the ImageSurface stuff) that the image is the correct
|
|
||||||
// size for the area given, so to save ratatui the work of having to
|
|
||||||
// resize it, we tell them to crop it to fit.
|
|
||||||
let txt_img = match picker.protocol_type() {
|
let txt_img = match picker.protocol_type() {
|
||||||
ProtocolType::Kitty => {
|
ProtocolType::Kitty => {
|
||||||
let area = ratatui_image::protocol::ImageSource::round_pixel_size_to_cells(
|
let area = ratatui_image::protocol::ImageSource::round_pixel_size_to_cells(
|
||||||
@@ -129,26 +127,22 @@ pub async fn run_conversion_loop(
|
|||||||
picker.font_size()
|
picker.font_size()
|
||||||
);
|
);
|
||||||
|
|
||||||
match kittage::image::Image::shm_from(
|
let mut img = if shms_work {
|
||||||
|
kittage::image::Image::shm_from(
|
||||||
dyn_img,
|
dyn_img,
|
||||||
&format!("__tdf_kittage_{pid}_page_{page_num}")
|
&format!("__tdf_kittage_{pid}_page_{page_num}")
|
||||||
) {
|
)
|
||||||
Ok(mut img) => {
|
.map_err(|e| RenderError::Converting(format!("Couldn't write to shm: {e}")))?
|
||||||
img.num_or_id =
|
} else {
|
||||||
NumberOrId::Id(NonZeroU32::new(page_num as u32 + 1).unwrap());
|
kittage::image::Image::from(dyn_img)
|
||||||
|
};
|
||||||
|
|
||||||
|
img.num_or_id = NumberOrId::Id(NonZeroU32::new(page_num as u32 + 1).unwrap());
|
||||||
ConvertedImage::Kitty {
|
ConvertedImage::Kitty {
|
||||||
img: MaybeTransferred::NotYet(img),
|
img: MaybeTransferred::NotYet(img),
|
||||||
area
|
area
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// todo: fallback to non-shm image here without cloning dyn_img above
|
|
||||||
// Err(_) => ConvertedImage::Kitty(dyn_img.into())
|
|
||||||
Err(e) =>
|
|
||||||
return Err(RenderError::Converting(format!(
|
|
||||||
"Couldn't write to shm: {e}"
|
|
||||||
))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => ConvertedImage::Generic(
|
_ => ConvertedImage::Generic(
|
||||||
picker
|
picker
|
||||||
.new_protocol(dyn_img, img_area, Resize::None)
|
.new_protocol(dyn_img, img_area, Resize::None)
|
||||||
@@ -203,7 +197,8 @@ pub async fn run_conversion_loop(
|
|||||||
page,
|
page,
|
||||||
&mut iteration,
|
&mut iteration,
|
||||||
prerender,
|
prerender,
|
||||||
pid
|
pid,
|
||||||
|
shms_work
|
||||||
) {
|
) {
|
||||||
Ok(None) => break,
|
Ok(None) => break,
|
||||||
Ok(Some(img)) => sender.send(Ok(img))?,
|
Ok(Some(img)) => sender.send(Ok(img))?,
|
||||||
|
|||||||
+29
-3
@@ -1,8 +1,14 @@
|
|||||||
use std::io::Write;
|
use std::{io::Write, num::NonZeroU32};
|
||||||
|
|
||||||
use crossterm::{cursor::MoveTo, event::EventStream, execute};
|
use crossterm::{
|
||||||
|
cursor::MoveTo,
|
||||||
|
event::EventStream,
|
||||||
|
execute,
|
||||||
|
terminal::{disable_raw_mode, enable_raw_mode}
|
||||||
|
};
|
||||||
|
use image::DynamicImage;
|
||||||
use kittage::{
|
use kittage::{
|
||||||
AsyncInputReader, ImageDimensions, ImageId, PixelFormat,
|
AsyncInputReader, ImageDimensions, ImageId, NumberOrId, PixelFormat,
|
||||||
action::Action,
|
action::Action,
|
||||||
delete::{ClearOrDelete, DeleteConfig, WhichToDelete},
|
delete::{ClearOrDelete, DeleteConfig, WhichToDelete},
|
||||||
display::DisplayConfig,
|
display::DisplayConfig,
|
||||||
@@ -55,6 +61,26 @@ pub async fn run_action<'image, 'data, 'es>(
|
|||||||
.map(|(_, i)| i)
|
.map(|(_, i)| i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn do_shms_work(ev_stream: &mut EventStream) -> bool {
|
||||||
|
let img = DynamicImage::new_rgb8(1, 1);
|
||||||
|
let pid = std::process::id();
|
||||||
|
let Ok(mut k_img) = kittage::image::Image::shm_from(img, &format!("__tdf_kittage_test_{pid}"))
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// apparently the terminal won't respond to queries unless they have an Id instead of a number
|
||||||
|
k_img.num_or_id = NumberOrId::Id(NonZeroU32::new(u32::MAX).unwrap());
|
||||||
|
|
||||||
|
enable_raw_mode().unwrap();
|
||||||
|
|
||||||
|
let res = run_action(Action::Query(&k_img), ev_stream).await;
|
||||||
|
|
||||||
|
disable_raw_mode().unwrap();
|
||||||
|
|
||||||
|
res.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn display_kitty_images<'es>(
|
pub async fn display_kitty_images<'es>(
|
||||||
images: Vec<(usize, &mut MaybeTransferred, Rect)>,
|
images: Vec<(usize, &mut MaybeTransferred, Rect)>,
|
||||||
ev_stream: &'es mut EventStream
|
ev_stream: &'es mut EventStream
|
||||||
|
|||||||
+11
-2
@@ -29,7 +29,7 @@ use ratatui_image::picker::{Picker, ProtocolType};
|
|||||||
use tdf::{
|
use tdf::{
|
||||||
PrerenderLimit,
|
PrerenderLimit,
|
||||||
converter::{ConvertedPage, ConverterMsg, run_conversion_loop},
|
converter::{ConvertedPage, ConverterMsg, run_conversion_loop},
|
||||||
kitty::{display_kitty_images, run_action},
|
kitty::{display_kitty_images, do_shms_work, run_action},
|
||||||
renderer::{self, RenderError, RenderInfo, RenderNotif},
|
renderer::{self, RenderError, RenderInfo, RenderNotif},
|
||||||
tui::{BottomMessage, InputAction, MessageSetting, Tui}
|
tui::{BottomMessage, InputAction, MessageSetting, Tui}
|
||||||
};
|
};
|
||||||
@@ -254,7 +254,12 @@ async fn main() -> Result<(), WrappedErr> {
|
|||||||
let (to_main, from_converter) = flume::unbounded();
|
let (to_main, from_converter) = flume::unbounded();
|
||||||
|
|
||||||
let is_kitty = picker.protocol_type() == ProtocolType::Kitty;
|
let is_kitty = picker.protocol_type() == ProtocolType::Kitty;
|
||||||
tokio::spawn(run_conversion_loop(to_main, from_main, picker, 20));
|
|
||||||
|
let shms_work = is_kitty && do_shms_work(&mut ev_stream).await;
|
||||||
|
|
||||||
|
tokio::spawn(run_conversion_loop(
|
||||||
|
to_main, from_main, picker, 20, shms_work
|
||||||
|
));
|
||||||
|
|
||||||
let file_name = path.file_name().map_or_else(
|
let file_name = path.file_name().map_or_else(
|
||||||
|| "Unknown file".into(),
|
|| "Unknown file".into(),
|
||||||
@@ -430,6 +435,10 @@ async fn enter_redraw_loop(
|
|||||||
// This is the error that kitty & ghostty provide us when they delete an
|
// 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
|
// 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
|
// 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(_)) => (),
|
TransmitError::Terminal(TerminalError::NoEntity(_)) => (),
|
||||||
_ => tui.set_msg(MessageSetting::Some(BottomMessage::Error(format!(
|
_ => tui.set_msg(MessageSetting::Some(BottomMessage::Error(format!(
|
||||||
"{err_desc}: {enum_err}"
|
"{err_desc}: {enum_err}"
|
||||||
|
|||||||
Reference in New Issue
Block a user