mirror of
https://github.com/itsjunetime/tdf.git
synced 2026-06-01 23:51:46 -04:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f9df806a8f | |||
| 5e7ec97b43 | |||
| 1aa26b8e8c |
+90
@@ -61,3 +61,93 @@ 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"
|
||||
|
||||
+42
-5
@@ -1,11 +1,14 @@
|
||||
use std::{
|
||||
future::poll_fn,
|
||||
io::{stdout, Read, Write},
|
||||
num::NonZeroUsize,
|
||||
path::PathBuf
|
||||
path::PathBuf,
|
||||
task::Poll
|
||||
};
|
||||
|
||||
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,
|
||||
@@ -14,7 +17,7 @@ use crossterm::{
|
||||
};
|
||||
use futures_util::{stream::StreamExt, FutureExt};
|
||||
use glib::{LogField, LogLevel, LogWriterOutput};
|
||||
use notify::{Event, EventKind, RecursiveMode, Watcher};
|
||||
use notify::{EventKind, RecursiveMode, Watcher};
|
||||
use ratatui::{backend::CrosstermBackend, Terminal};
|
||||
use ratatui_image::picker::Picker;
|
||||
use renderer::{RenderError, RenderInfo, RenderNotif};
|
||||
@@ -123,7 +126,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,
|
||||
@@ -132,7 +135,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 = crossterm::event::EventStream::new();
|
||||
let mut ev_stream = EventStream::new();
|
||||
|
||||
let (to_converter, from_main) = flume::unbounded();
|
||||
let (to_main, from_converter) = flume::unbounded();
|
||||
@@ -175,6 +178,8 @@ 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 {
|
||||
@@ -244,7 +249,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<Event>) {
|
||||
) -> impl Fn(notify::Result<notify::Event>) {
|
||||
move |res| match res {
|
||||
// If we get an error here, and then an error sending, everything's going wrong. Just give
|
||||
// up lol.
|
||||
@@ -267,3 +272,35 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user