Skip to content

Commit

Permalink
Manually track click interval
Browse files Browse the repository at this point in the history
This lets us 'correctly' report click-count for mouse events on wasm.
Doing this 'actually correctly' would require finding some way
to determine what the user's current doubleclick delay is, and I
do not believe this is exposed by browsers, although I haven't looked
too hard and it wouldn't blow my mind?

- closes #1464
  • Loading branch information
cmyr committed Dec 14, 2020
1 parent 348a4ce commit a87cd5c
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion druid-shell/src/platform/web/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use std::cell::{Cell, RefCell};
use std::ffi::OsString;
use std::rc::{Rc, Weak};
use std::sync::{Arc, Mutex};
use std::time::Duration;

use instant::Instant;

Expand All @@ -44,6 +45,9 @@ use crate::region::Region;
use crate::window;
use crate::window::{FileDialogToken, IdleToken, TimerToken, WinHandler, WindowLevel};

// This is the default timing on windows.
const MULTI_CLICK_INTERVAL: Duration = Duration::from_millis(500);

// This is a macro instead of a function since KeyboardEvent and MouseEvent has identical functions
// to query modifier key states.
macro_rules! get_modifiers {
Expand Down Expand Up @@ -97,6 +101,13 @@ struct WindowState {
canvas: web_sys::HtmlCanvasElement,
context: web_sys::CanvasRenderingContext2d,
invalid: RefCell<Region>,
click_counter: ClickCounter,
}

#[derive(Debug, Clone)]
struct ClickCounter {
last_click: Cell<Instant>,
click_count: Cell<u8>,
}

// TODO: support custom cursors
Expand Down Expand Up @@ -162,16 +173,42 @@ impl WindowState {
}
}

impl ClickCounter {
fn new() -> ClickCounter {
ClickCounter {
// @cmyr: I had a weird panic here once?
last_click: Cell::new(
Instant::now()
.checked_sub(MULTI_CLICK_INTERVAL)
.unwrap_or_else(Instant::now),
),
click_count: Cell::new(0),
}
}

fn current_click_count(&self) -> u8 {
let click_time = Instant::now();
let last_time = self.last_click.replace(click_time);
if click_time - last_time > MULTI_CLICK_INTERVAL {
self.click_count.set(0);
}
let click_count = self.click_count.get().saturating_add(1);
self.click_count.set(click_count);
click_count
}
}

fn setup_mouse_down_callback(ws: &Rc<WindowState>) {
let state = ws.clone();
register_canvas_event_listener(ws, "mousedown", move |event: web_sys::MouseEvent| {
if let Some(button) = mouse_button(event.button()) {
let count = state.click_counter.current_click_count();
let buttons = mouse_buttons(event.buttons());
let event = MouseEvent {
pos: Point::new(event.offset_x() as f64, event.offset_y() as f64),
buttons,
mods: get_modifiers!(event),
count: 1,
count,
focus: false,
button,
wheel_delta: Vec2::ZERO,
Expand Down Expand Up @@ -416,6 +453,7 @@ impl WindowBuilder {
canvas,
context,
invalid: RefCell::new(Region::EMPTY),
click_counter: ClickCounter::new(),
});

setup_web_callbacks(&window);
Expand Down

0 comments on commit a87cd5c

Please sign in to comment.