Skip to content

Commit

Permalink
Fix canvas/text input focus on iOS web browsers
Browse files Browse the repository at this point in the history
  • Loading branch information
BKSalman committed Jul 18, 2024
1 parent b2d74ea commit 7d4775d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/eframe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ web-sys = { workspace = true, features = [
"Storage",
"Touch",
"TouchEvent",
"PointerEvent",
"TouchList",
"WebGl2RenderingContext",
"WebglDebugRendererInfo",
Expand Down
35 changes: 35 additions & 0 deletions crates/eframe/src/web/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub(crate) fn install_event_handlers(runner_ref: &WebRunner) -> Result<(), JsVal
install_copy_cut_paste(runner_ref, &document)?;

install_mousedown(runner_ref, &canvas)?;
install_pointerdown(runner_ref, &canvas)?;
// Use `document` here to notice if the user releases a drag outside of the canvas:
// See https://github.com/emilk/egui/issues/3157
install_mousemove(runner_ref, &document)?;
Expand Down Expand Up @@ -420,6 +421,40 @@ fn install_mousedown(runner_ref: &WebRunner, target: &EventTarget) -> Result<(),
)
}

fn install_pointerdown(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
runner_ref.add_event_listener(
target,
"pointerdown",
|event: web_sys::PointerEvent, runner: &mut AppRunner| {
let modifiers = modifiers_from_mouse_event(&event);
runner.input.raw.modifiers = modifiers;
if let Some(button) = button_from_mouse_event(&event) {
let pos = pos_from_mouse_event(runner.canvas(), &event, runner.egui_ctx());
let modifiers = runner.input.raw.modifiers;
runner.input.raw.events.push(egui::Event::PointerButton {
pos,
button,
pressed: true,
modifiers,
});

// force the canvas focus for iOS browsers
// since it doesn't count canvas as focusable by touch
runner.canvas().focus().ok();

// In Safari we are only allowed to write to the clipboard during the
// event callback, which is why we run the app logic here and now:
runner.logic();

// Make sure we paint the output of the above logic call asap:
runner.needs_repaint.repaint_asap();
}
event.stop_propagation();
// Note: prevent_default breaks VSCode tab focusing, hence why we don't call it here.
},
)
}

/// Returns true if the cursor is above the canvas, or if we're dragging something.
/// Pass in the position in browser viewport coordinates (usually event.clientX/Y).
fn is_interested_in_pointer_event(runner: &AppRunner, pos: egui::Pos2) -> bool {
Expand Down

0 comments on commit 7d4775d

Please sign in to comment.