Compare commits

..

1 Commits

Author SHA1 Message Date
itsjunetime 8dedf62cbd Actually query terminals and fix terminals if we fail initialization 2025-09-06 11:32:27 -05:00
8 changed files with 573 additions and 463 deletions
-9
View File
@@ -1,15 +1,6 @@
# Unreleased # Unreleased
- Switched simd base64 crate for one that works on stable (from `vb64` to `base64_simd`)
- Allow boolean arguments to function as flags, without a `true` or `false` argument following the flag itself
- Fix cropping issues when zooming out too much while using kitty protocol
# v0.4.3
- Fix issue with some terminals hanging on startup
- Fix issues with some iterm2-backend terminals not displaying anything
- Allow using ctrl+scroll to zoom in/out while zoomed using kitty backend - Allow using ctrl+scroll to zoom in/out while zoomed using kitty backend
- (Internal) run CI with `--locked` flag to ensure lockfile is always in-sync
# v0.4.2 # v0.4.2
Generated
+542 -422
View File
File diff suppressed because it is too large Load Diff
+5 -4
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "tdf-viewer" name = "tdf-viewer"
version = "0.4.3" version = "0.4.2"
authors = ["June Welker <junewelker@gmail.com>"] authors = ["June Welker <junewelker@gmail.com>"]
edition = "2024" edition = "2024"
description = "A terminal viewer for PDFs" description = "A terminal viewer for PDFs"
@@ -49,7 +49,7 @@ log = "0.4.27"
flexi_logger = "0.31" flexi_logger = "0.31"
# for tracing with tokio-console # for tracing with tokio-console
console-subscriber = { version = "0.5.0", optional = true } console-subscriber = { version = "0.4.0", optional = true }
csscolorparser = { version = "0.7.0" } csscolorparser = { version = "0.7.0" }
[profile.production] [profile.production]
@@ -57,7 +57,8 @@ inherits = "release"
lto = "fat" lto = "fat"
[features] [features]
default = [] default = ["nightly"]
nightly = ["ratatui-image/vb64"]
tracing = ["tokio/tracing", "dep:console-subscriber"] tracing = ["tokio/tracing", "dep:console-subscriber"]
epub = ["mupdf/epub"] epub = ["mupdf/epub"]
cbz = ["mupdf/cbz"] cbz = ["mupdf/cbz"]
@@ -92,7 +93,7 @@ checked_conversions = "warn"
copy_iterator = "warn" copy_iterator = "warn"
default_trait_access = "warn" default_trait_access = "warn"
doc_link_with_quotes = "warn" doc_link_with_quotes = "warn"
empty_enums = "warn" empty_enum = "warn"
explicit_into_iter_loop = "warn" explicit_into_iter_loop = "warn"
explicit_iter_loop = "warn" explicit_iter_loop = "warn"
filter_map_next = "warn" filter_map_next = "warn"
+2 -4
View File
@@ -16,9 +16,7 @@ Designed to be performant, very responsive, and work well with even very large P
## Installation ## Installation
1. Get the rust toolchain from [rustup.rs](https://rustup.rs) 1. Get the rust toolchain from [rustup.rs](https://rustup.rs)
2. Run `cargo install --git https://github.com/itsjunetime/tdf.git` 2. Run `rustup install nightly && cargo +nightly install --git https://github.com/itsjunetime/tdf.git`
If you want to use this with `epub`s or `cbz`s, add `--features epub` or `--features cbz` to the command line (or `--features cbz,epub` for both)
## To Build ## To Build
First, you need to install the system dependencies. This will generally only include `libfontconfig` and `clang`. If you're on linux, these will probably show up in your package manager as something like `libfontconfig1-devel` or `libfontconfig-dev` and just `clang`. First, you need to install the system dependencies. This will generally only include `libfontconfig` and `clang`. If you're on linux, these will probably show up in your package manager as something like `libfontconfig1-devel` or `libfontconfig-dev` and just `clang`.
@@ -27,7 +25,7 @@ If it turns out that you're missing one of these, it will fail to compile and te
1. Get the rust toolchain from [rustup.rs](https://rustup.rs) 1. Get the rust toolchain from [rustup.rs](https://rustup.rs)
2. Clone the repo and `cd` into it 2. Clone the repo and `cd` into it
3. Run `cargo build --release` 3. Run `cargo +nightly build --release`
The binary should then be found at `./target/release/tdf`. The binary should then be found at `./target/release/tdf`.
+1 -1
Submodule ratatui updated: 6a0b8ddf76...47c200fb7f
+9 -4
View File
@@ -83,11 +83,11 @@ async fn inner_main() -> Result<(), WrappedErr> {
let flags = xflags::parse_or_exit! { let flags = xflags::parse_or_exit! {
/// Display the pdf with the pages starting at the right hand size and moving left and /// Display the pdf with the pages starting at the right hand size and moving left and
/// adjust input keys to match /// adjust input keys to match
optional -r,--r-to-l optional -r,--r-to-l r_to_l: bool
/// The maximum number of pages to display together, horizontally, at a time /// The maximum number of pages to display together, horizontally, at a time
optional -m,--max-wide max_wide: NonZeroUsize optional -m,--max-wide max_wide: NonZeroUsize
/// Fullscreen the pdf (hide document name, page count, etc) /// Fullscreen the pdf (hide document name, page count, etc)
optional -f,--fullscreen optional -f,--fullscreen fullscreen: bool
/// The number of pages to prerender surrounding the currently-shown page; 0 means no /// The number of pages to prerender surrounding the currently-shown page; 0 means no
/// limit. By default, there is no limit. /// limit. By default, there is no limit.
optional -p,--prerender prerender: usize optional -p,--prerender prerender: usize
@@ -267,7 +267,12 @@ async fn inner_main() -> Result<(), WrappedErr> {
|| "Unknown file".into(), || "Unknown file".into(),
|n| n.to_string_lossy().to_string() |n| n.to_string_lossy().to_string()
); );
let tui = Tui::new(file_name, flags.max_wide, flags.r_to_l, is_kitty); let tui = Tui::new(
file_name,
flags.max_wide,
flags.r_to_l.unwrap_or_default(),
is_kitty
);
let backend = CrosstermBackend::new(std::io::stdout()); let backend = CrosstermBackend::new(std::io::stdout());
let mut term = Terminal::new(backend).map_err(|e| { let mut term = Terminal::new(backend).map_err(|e| {
@@ -295,7 +300,7 @@ async fn inner_main() -> Result<(), WrappedErr> {
})?; })?;
} }
let fullscreen = flags.fullscreen; let fullscreen = flags.fullscreen.unwrap_or_default();
let main_area = Tui::main_layout(&term.get_frame(), fullscreen); let main_area = Tui::main_layout(&term.get_frame(), fullscreen);
to_renderer to_renderer
.send(RenderNotif::Area(main_area.page_area)) .send(RenderNotif::Area(main_area.page_area))
+10 -15
View File
@@ -205,28 +205,23 @@ impl Tui {
log::debug!("zoom is now {zoom:#?}"); log::debug!("zoom is now {zoom:#?}");
log::debug!("img_area is {img_area:#?}"); log::debug!("img_area is {img_area:#?}");
log::debug!("img dimensions are {cell_w}x{cell_h}");
let img_width = f32::from(cell_w);
let img_height = f32::from(cell_h);
let img_aspect_ratio = img_width / img_height;
if zoom.level < 0 { if zoom.level < 0 {
let old_width = img_area.width; img_area = Rect {
img_area.width = img_area width: img_area
.width .width
.saturating_sub((zoom.level * 2).unsigned_abs()) .saturating_sub((zoom.level * 2).unsigned_abs())
.max((f32::from(img_area.height) * img_aspect_ratio) as u16); .max(1),
img_area.x += (old_width - img_area.width) / 2; x: img_area.x + (zoom.level.unsigned_abs().min(img_area.width / 2)),
..img_area
}
}
log::debug!("after adjustment, img_area is {img_area:#?}"); log::debug!("after adjustment, img_area is {img_area:#?}");
// TODO: Find a way to detect when we've hit the maximum zoom-out and stop
// more zooming out
}
// Ugh I don't like this logic. I wish we could simplify it. // Ugh I don't like this logic. I wish we could simplify it.
let img_width = f32::from(cell_w);
let img_height = f32::from(cell_h);
let img_area_width = f32::from(img_area.width); let img_area_width = f32::from(img_area.width);
let img_area_height = f32::from(img_area.height); let img_area_height = f32::from(img_area.height);
let available_to_real_width_ratio = img_area_width / img_width; let available_to_real_width_ratio = img_area_width / img_width;
@@ -792,7 +787,7 @@ impl Tui {
} }
} }
// I want this to always return an option 'cause I just use it to return from `Self::handle_event` // I want this to always return 0 'cause I just use it to return from `Self::handle_event`]
#[expect(clippy::unnecessary_wraps)] #[expect(clippy::unnecessary_wraps)]
fn update_zoom(&mut self, f: impl FnOnce(&mut Zoom)) -> Option<InputAction> { fn update_zoom(&mut self, f: impl FnOnce(&mut Zoom)) -> Option<InputAction> {
if let Some(z) = &mut self.zoom { if let Some(z) = &mut self.zoom {