@@ -77,11 +77,16 @@ pub(crate) fn install_event_handlers(runner_ref: &WebRunner) -> Result<(), JsVal
77
77
// so we check if we have focus inside of the handler.
78
78
install_copy_cut_paste ( runner_ref, & document) ?;
79
79
80
- install_mousedown ( runner_ref, & canvas) ?;
81
80
// Use `document` here to notice if the user releases a drag outside of the canvas:
82
81
// See https://github.com/emilk/egui/issues/3157
83
82
install_mousemove ( runner_ref, & document) ?;
84
- install_mouseup ( runner_ref, & document) ?;
83
+ if is_mobile ( ) {
84
+ install_pointerup ( runner_ref, & canvas) ?;
85
+ install_pointerdown ( runner_ref, & canvas) ?;
86
+ } else {
87
+ install_mouseup ( runner_ref, & document) ?;
88
+ install_mousedown ( runner_ref, & canvas) ?;
89
+ }
85
90
install_mouseleave ( runner_ref, & canvas) ?;
86
91
87
92
install_touchstart ( runner_ref, & canvas) ?;
@@ -420,6 +425,83 @@ fn install_mousedown(runner_ref: &WebRunner, target: &EventTarget) -> Result<(),
420
425
)
421
426
}
422
427
428
+ fn install_pointerdown ( runner_ref : & WebRunner , target : & EventTarget ) -> Result < ( ) , JsValue > {
429
+ runner_ref. add_event_listener (
430
+ target,
431
+ "pointerdown" ,
432
+ |event : web_sys:: PointerEvent , runner : & mut AppRunner | {
433
+ let modifiers = modifiers_from_mouse_event ( & event) ;
434
+ runner. input . raw . modifiers = modifiers;
435
+ if let Some ( button) = button_from_mouse_event ( & event) {
436
+ let pos = pos_from_mouse_event ( runner. canvas ( ) , & event, runner. egui_ctx ( ) ) ;
437
+ let modifiers = runner. input . raw . modifiers ;
438
+ runner. input . raw . events . push ( egui:: Event :: PointerButton {
439
+ pos,
440
+ button,
441
+ pressed : true ,
442
+ modifiers,
443
+ } ) ;
444
+
445
+ // In Safari we are only allowed to write to the clipboard during the
446
+ // event callback, which is why we run the app logic here and now:
447
+ runner. logic ( ) ;
448
+
449
+ // Make sure we paint the output of the above logic call asap:
450
+ runner. needs_repaint . repaint_asap ( ) ;
451
+ }
452
+ event. stop_propagation ( ) ;
453
+ // Note: prevent_default breaks VSCode tab focusing, hence why we don't call it here.
454
+ } ,
455
+ )
456
+ }
457
+
458
+ fn install_pointerup ( runner_ref : & WebRunner , target : & EventTarget ) -> Result < ( ) , JsValue > {
459
+ runner_ref. add_event_listener (
460
+ target,
461
+ "pointerup" ,
462
+ |event : web_sys:: PointerEvent , runner| {
463
+ let modifiers = modifiers_from_mouse_event ( & event) ;
464
+ runner. input . raw . modifiers = modifiers;
465
+
466
+ let pos = pos_from_mouse_event ( runner. canvas ( ) , & event, runner. egui_ctx ( ) ) ;
467
+
468
+ if is_interested_in_pointer_event (
469
+ runner,
470
+ egui:: pos2 ( event. client_x ( ) as f32 , event. client_y ( ) as f32 ) ,
471
+ ) {
472
+ if let Some ( button) = button_from_mouse_event ( & event) {
473
+ let modifiers = runner. input . raw . modifiers ;
474
+ runner. input . raw . events . push ( egui:: Event :: PointerButton {
475
+ pos,
476
+ button,
477
+ pressed : false ,
478
+ modifiers,
479
+ } ) ;
480
+
481
+ // Previously on iOS, the canvas would not receive focus on
482
+ // any touch event, which resulted in the on-screen keyboard
483
+ // not working when focusing on a text field in an egui app.
484
+ // This attempts to fix that by forcing the focus on any
485
+ // click on the canvas.
486
+ runner. canvas ( ) . focus ( ) . ok ( ) ;
487
+
488
+ // In Safari we are only allowed to do certain things
489
+ // (like playing audio, start a download, etc)
490
+ // on user action, such as a click.
491
+ // So we need to run the app logic here and now:
492
+ runner. logic ( ) ;
493
+
494
+ // Make sure we paint the output of the above logic call asap:
495
+ runner. needs_repaint . repaint_asap ( ) ;
496
+
497
+ event. prevent_default ( ) ;
498
+ event. stop_propagation ( ) ;
499
+ }
500
+ }
501
+ } ,
502
+ )
503
+ }
504
+
423
505
/// Returns true if the cursor is above the canvas, or if we're dragging something.
424
506
/// Pass in the position in browser viewport coordinates (usually event.clientX/Y).
425
507
fn is_interested_in_pointer_event ( runner : & AppRunner , pos : egui:: Pos2 ) -> bool {
0 commit comments