Fix 5 deferred performance/UX issues from audit
M8: Pre-compile regex once before rename preview loop instead of recompiling per file. Adds apply_simple_compiled() to RenameConfig. M9: Cache font data in watermark module using OnceLock (default font) and Mutex<HashMap> (named fonts) to avoid repeated filesystem walks during preview updates. M12: Add 150ms debounce to watermark opacity, rotation, margin, and scale sliders to avoid spawning preview threads on every pixel of slider movement. M13: Add 150ms debounce to compress per-format quality sliders (JPEG, PNG, WebP, AVIF) for the same reason. M14: Move thumbnail loading to background threads instead of blocking the GTK main loop. Each thumbnail is decoded via image crate in a spawned thread and delivered to the main thread via channel polling.
This commit is contained in:
@@ -702,18 +702,31 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
});
|
||||
}
|
||||
|
||||
// Per-format slider handlers: update config, set preview to that format, refresh
|
||||
// Per-slider debounce counters (separate to avoid cross-slider cancellation)
|
||||
let jpeg_debounce: Rc<Cell<u32>> = Rc::new(Cell::new(0));
|
||||
let png_debounce: Rc<Cell<u32>> = Rc::new(Cell::new(0));
|
||||
let webp_debounce: Rc<Cell<u32>> = Rc::new(Cell::new(0));
|
||||
let avif_debounce: Rc<Cell<u32>> = Rc::new(Cell::new(0));
|
||||
|
||||
// Per-format slider handlers: update config, set preview to that format, refresh (debounced)
|
||||
{
|
||||
let jc = state.job_config.clone();
|
||||
let row = jpeg_row.clone();
|
||||
let pc = preview_comp.clone();
|
||||
let up = update_preview.clone();
|
||||
let did = jpeg_debounce.clone();
|
||||
jpeg_scale.connect_value_changed(move |scale| {
|
||||
let val = scale.value().round() as u8;
|
||||
jc.borrow_mut().jpeg_quality = val;
|
||||
row.set_subtitle(&format!("{}", val));
|
||||
pc.set(PreviewCompression::Jpeg(val));
|
||||
up(false);
|
||||
let up = up.clone();
|
||||
let did = did.clone();
|
||||
let id = did.get().wrapping_add(1);
|
||||
did.set(id);
|
||||
glib::timeout_add_local_once(std::time::Duration::from_millis(150), move || {
|
||||
if did.get() == id { up(false); }
|
||||
});
|
||||
});
|
||||
}
|
||||
{
|
||||
@@ -721,12 +734,19 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
let row = png_row.clone();
|
||||
let pc = preview_comp.clone();
|
||||
let up = update_preview.clone();
|
||||
let did = png_debounce.clone();
|
||||
png_scale.connect_value_changed(move |scale| {
|
||||
let val = scale.value().round() as u8;
|
||||
jc.borrow_mut().png_level = val;
|
||||
row.set_subtitle(&format!("{}", val));
|
||||
pc.set(PreviewCompression::Png(val));
|
||||
up(false);
|
||||
let up = up.clone();
|
||||
let did = did.clone();
|
||||
let id = did.get().wrapping_add(1);
|
||||
did.set(id);
|
||||
glib::timeout_add_local_once(std::time::Duration::from_millis(150), move || {
|
||||
if did.get() == id { up(false); }
|
||||
});
|
||||
});
|
||||
}
|
||||
{
|
||||
@@ -734,12 +754,19 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
let row = webp_row.clone();
|
||||
let pc = preview_comp.clone();
|
||||
let up = update_preview.clone();
|
||||
let did = webp_debounce.clone();
|
||||
webp_scale.connect_value_changed(move |scale| {
|
||||
let val = scale.value().round() as u8;
|
||||
jc.borrow_mut().webp_quality = val;
|
||||
row.set_subtitle(&format!("{}", val));
|
||||
pc.set(PreviewCompression::WebP(val));
|
||||
up(false);
|
||||
let up = up.clone();
|
||||
let did = did.clone();
|
||||
let id = did.get().wrapping_add(1);
|
||||
did.set(id);
|
||||
glib::timeout_add_local_once(std::time::Duration::from_millis(150), move || {
|
||||
if did.get() == id { up(false); }
|
||||
});
|
||||
});
|
||||
}
|
||||
{
|
||||
@@ -756,12 +783,19 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
let row = avif_row.clone();
|
||||
let pc = preview_comp.clone();
|
||||
let up = update_preview.clone();
|
||||
let did = avif_debounce.clone();
|
||||
avif_scale.connect_value_changed(move |scale| {
|
||||
let val = scale.value().round() as u8;
|
||||
jc.borrow_mut().avif_quality = val;
|
||||
row.set_subtitle(&format!("{}", val));
|
||||
pc.set(PreviewCompression::Avif(val));
|
||||
up(false);
|
||||
let up = up.clone();
|
||||
let did = did.clone();
|
||||
let id = did.get().wrapping_add(1);
|
||||
did.set(id);
|
||||
glib::timeout_add_local_once(std::time::Duration::from_millis(150), move || {
|
||||
if did.get() == id { up(false); }
|
||||
});
|
||||
});
|
||||
}
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user