font browser
Time the double-click window on a wall clock, not tick's dt
`click_timer` was set to 0.35 and counted down by tick's `dt`, which
the runner clamps to one frame per idle wake — and between two clicks
the app is idle. Past the ~200 ms warm window the remaining 0.15 s of
`dt` took about nine seconds of wall clock, so a thoroughly leisurely
second click still confirmed as a double-click in --select mode.
Record the `Instant` of the last click and compare its elapsed time
against DOUBLE_CLICK; the countdown leaves `tick` entirely.
Co-Authored-By: Claude Opus 5 <[email protected]>
src/main.rs | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index 10156b2..869bc7e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,6 +9,9 @@ use cce_ui::widget::{
};
+/// How long after a click on a family row a second click on the same row
+/// still counts as a double-click (and, in `--select` mode, confirms).
+const DOUBLE_CLICK: std::time::Duration = std::time::Duration::from_millis(350);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BrowseNavigation {
@@ -100,7 +103,11 @@ struct TypefaceApp {
select_confirm_btn: cce_ui::widget::Adapted<cce_ui::widget::Button>,
select_mode: bool,
last_click_idx: Option<usize>,
- click_timer: f32,
+ /// When that click landed. A wall clock, not a `dt` countdown: `dt` is
+ /// animation time, clamped to one frame after an idle sleep, and the app
+ /// idles between clicks — so the 0.35 s window stayed open for seconds
+ /// and a leisurely second click confirmed as a double-click.
+ last_click_at: Option<std::time::Instant>,
// State
all_fonts: Vec<pages::FontEntry>,
@@ -504,7 +511,7 @@ impl Application for TypefaceApp {
select_confirm_btn,
select_mode,
last_click_idx: None,
- click_timer: 0.0,
+ last_click_at: None,
all_fonts: all_fonts.clone(),
families: Vec::new(),
filtered: Vec::new(),
@@ -714,9 +721,6 @@ impl Application for TypefaceApp {
self.needs_rebuild = true;
}
- if self.click_timer > 0.0 {
- self.click_timer -= dt;
- }
}
fn display_list(&mut self, size: LogicalSize, scale: f64) -> Option<cce_ui::scene::paint::DisplayList> {
@@ -1157,7 +1161,8 @@ impl Application for TypefaceApp {
for (idx, btn) in self.font_buttons.iter_mut().enumerate() {
if btn.rect().0 > -9000.0 && btn.take_click() {
- if self.select_mode && self.last_click_idx == Some(idx) && self.click_timer > 0.0 {
+ let double = self.last_click_at.is_some_and(|t| t.elapsed() < DOUBLE_CLICK);
+ if self.select_mode && self.last_click_idx == Some(idx) && double {
let selected = self.filtered[idx].clone();
print!("{} {}", selected, self.size_spinbox.value);
use std::io::Write;
@@ -1165,7 +1170,7 @@ impl Application for TypefaceApp {
std::process::exit(0);
}
self.last_click_idx = Some(idx);
- self.click_timer = 0.35;
+ self.last_click_at = Some(std::time::Instant::now());
msg_out = Some(AppMessage::SelectFamily(idx));
break;
}