Compare commits

..

2 Commits

Author SHA1 Message Date
itsjunetime 9e9053acbc Add note to README that contributions will be licensed as MPL-2.0 2024-12-01 11:30:08 -07:00
itsjunetime e67a2ec421 Relicense to GPLv3 since poppler is GPL and we must not violate that license 2024-11-15 23:14:53 -07:00
4 changed files with 682 additions and 506 deletions
+1 -91
View File
@@ -7,7 +7,7 @@ description = "A terminal viewer for PDFs"
readme = "README.md"
homepage = "https://github.com/itsjunetime/tdf"
repository = "https://github.com/itsjunetime/tdf"
license = "MPL-2.0"
license = "GPL-3.0-or-later"
keywords = ["pdf", "tui", "cli", "terminal"]
categories = ["command-line-utilities", "text-processing", "visualization"]
default-run = "tdf"
@@ -61,93 +61,3 @@ harness = false
[[bin]]
name = "for_profiling"
path = "./benches/for_profiling.rs"
[lints.clippy]
uninlined_format_args = "warn"
redundant_closure_for_method_calls = "warn"
cast_lossless = "warn"
single_char_pattern = "warn"
manual_let_else = "warn"
ignored_unit_patterns = "warn"
range_plus_one = "warn"
unreadable_literal = "warn"
redundant_else = "warn"
assigning_clones = "warn"
bool_to_int_with_if = "warn"
borrow_as_ptr = "warn"
cast_ptr_alignment = "warn"
checked_conversions = "warn"
copy_iterator = "warn"
default_trait_access = "warn"
doc_link_with_quotes = "warn"
empty_enum = "warn"
explicit_into_iter_loop = "warn"
explicit_iter_loop = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
fn_params_excessive_bools = "warn"
from_iter_instead_of_collect = "warn"
implicit_clone = "warn"
index_refutable_slice = "warn"
inefficient_to_string = "warn"
invalid_upcast_comparisons = "warn"
iter_filter_is_ok = "warn"
iter_filter_is_some = "warn"
iter_not_returning_iterator = "warn"
large_futures = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
linkedlist = "warn"
macro_use_imports = "warn"
manual_assert = "warn"
manual_instant_elapsed = "warn"
manual_is_power_of_two = "warn"
manual_is_variant_and = "warn"
manual_ok_or = "warn"
manual_string_new = "warn"
many_single_char_names = "warn"
manual_unwrap_or = "warn"
match_on_vec_items = "warn"
match_same_arms = "warn"
match_wildcard_for_single_variants = "warn"
maybe_infinite_iter = "warn"
mismatching_type_param_order = "warn"
missing_fields_in_debug = "warn"
mut_mut = "warn"
needless_bitwise_bool = "warn"
needless_continue = "warn"
needless_for_each = "warn"
needless_pass_by_value = "warn"
needless_raw_string_hashes = "warn"
no_effect_underscore_binding = "warn"
no_mangle_with_rust_abi = "warn"
option_as_ref_cloned = "warn"
option_option = "warn"
ptr_as_ptr = "warn"
ptr_cast_constness = "warn"
range_minus_one = "warn"
ref_as_ptr = "warn"
ref_binding_to_reference = "warn"
ref_option = "warn"
ref_option_ref = "warn"
return_self_not_must_use = "warn"
same_functions_in_if_condition = "warn"
should_panic_without_expect = "warn"
similar_names = "warn"
stable_sort_primitive = "warn"
str_split_at_newline = "warn"
struct_excessive_bools = "warn"
struct_field_names = "warn"
transmute_ptr_to_ptr = "warn"
trivially_copy_pass_by_ref = "warn"
unicode_not_nfc = "warn"
unnecessary_box_returns = "warn"
unnecessary_join = "warn"
unnecessary_literal_bound = "warn"
unnecessary_wraps = "warn"
unnested_or_patterns = "warn"
unused_async = "warn"
unused_self = "warn"
used_underscore_binding = "warn"
used_underscore_items = "warn"
zero_sized_map_values = "warn"
+674 -373
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -29,3 +29,5 @@ I dunno. Just for fun, mostly.
## Can I contribute?
Yeah, sure. Please do.
Please note, though, that all contributions will be treated as licensed under MPL-2.0. This is so that we can relicense to MPL-2.0 at some point in the future if we manage to move away from poppler as a backend (since that is the only dependency, at time of writing, which requires the GPLv3 license).
+5 -42
View File
@@ -1,14 +1,11 @@
use std::{
future::poll_fn,
io::{stdout, Read, Write},
num::NonZeroUsize,
path::PathBuf,
task::Poll
path::PathBuf
};
use converter::{run_conversion_loop, ConvertedPage, ConverterMsg};
use crossterm::{
event::{Event, EventStream, MouseEvent, MouseEventKind},
execute,
terminal::{
disable_raw_mode, enable_raw_mode, window_size, EndSynchronizedUpdate,
@@ -17,7 +14,7 @@ use crossterm::{
};
use futures_util::{stream::StreamExt, FutureExt};
use glib::{LogField, LogLevel, LogWriterOutput};
use notify::{EventKind, RecursiveMode, Watcher};
use notify::{Event, EventKind, RecursiveMode, Watcher};
use ratatui::{backend::CrosstermBackend, Terminal};
use ratatui_image::picker::Picker;
use renderer::{RenderError, RenderInfo, RenderNotif};
@@ -126,7 +123,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// We need to create `picker` on this thread because if we create it on the `renderer` thread,
// it messes up something with user input. Input never makes it to the crossterm thing
let picker = Picker::from_query_stdio()?;
let picker = Picker::from_query_stdio()?;
// then we want to spawn off the rendering task
// We need to use the thread::spawn API so that this exists in a thread not owned by tokio,
@@ -135,7 +132,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
renderer::start_rendering(&file_path, render_tx, render_rx, window_size)
});
let mut ev_stream = EventStream::new();
let mut ev_stream = crossterm::event::EventStream::new();
let (to_converter, from_main) = flume::unbounded();
let (to_main, from_converter) = flume::unbounded();
@@ -178,8 +175,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// If we can't get user input, just crash.
let ev = ev.expect("Couldn't get any user input");
flush_if_mouse(&ev, &mut ev_stream).await;
match tui.handle_event(&ev) {
None => needs_redraw = false,
Some(action) => match action {
@@ -249,7 +244,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
fn on_notify_ev(
to_tui_tx: flume::Sender<Result<RenderInfo, RenderError>>,
to_render_tx: flume::Sender<RenderNotif>
) -> impl Fn(notify::Result<notify::Event>) {
) -> impl Fn(notify::Result<Event>) {
move |res| match res {
// If we get an error here, and then an error sending, everything's going wrong. Just give
// up lol.
@@ -272,35 +267,3 @@ fn on_notify_ev(
fn noop(_: LogLevel, _: &[LogField<'_>]) -> LogWriterOutput {
LogWriterOutput::Handled
}
async fn flush_if_mouse(ev: &Event, ev_stream: &mut EventStream) {
// If you have a high scroll sensitivity, on some platforms, crossterm sends 2+ mouse events per
// scroll. However, because tdf scrolls pages once per mouse event, that means that they can't
// scroll the pages of their PDF as they would expect - it jumps multiple pages per one scroll.
// So this just flushes the event queue once we detect a scroll event to make sure those extra
// scrolls are ignored.
//
// Theoretically, this introduces a race condition where events that arrive in between the
// processing of `ev` and the time we call `poll_next_unpin` can get ignored, but that's a very
// very small amount of time, so unlikely to happen. However, if that does become an issue, we
// can just flush the event queue until we see a non-scroll event, then store that event in a
// future that will return it next time we call `tokio::select!` in the main loop. That'll make
// sure we don't miss anything.
if let Event::Mouse(MouseEvent {
kind:
MouseEventKind::ScrollUp
| MouseEventKind::ScrollDown
| MouseEventKind::ScrollLeft
| MouseEventKind::ScrollRight,
..
}) = ev
{
poll_fn(|ctx| {
while ev_stream.poll_next_unpin(ctx).is_ready() {
println!("got another mouse event!");
}
Poll::Ready(())
})
.await;
}
}