Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ rls/
*.js
#*#
.DS_Store
.idea/
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ And please only add new entries to the top of this list, right below the `# Unre
- **Breaking:** `CursorIcon` is now used from the `cursor-icon` crate.
- **Breaking:** `CursorIcon::Hand` is now named `CursorIcon::Pointer`.
- **Breaking:** `CursorIcon::Arrow` was removed.
- **Breaking:** Web: Canvases will now capture the contextmenu if prevent_default is enabled so they don't interfere with right click pointer events.
- **Breaking:** Web: Canvases will now have `user-select: none` to prevent double clicks from selecting text outside the canvas.
- On Wayland, fix maximized startup not taking full size on GNOME.
- On Wayland, fix initial window size not restored for maximized/fullscreened on startup window.
- On Wayland, `Window::outer_size` now accounts for **client side** decorations.
Expand Down
2 changes: 2 additions & 0 deletions src/platform_impl/web/event_loop/window_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ impl<T> EventLoopWindowTarget<T> {
});
});

canvas.on_contextmenu(prevent_default);

let runner = self.runner.clone();
canvas.on_keyboard_press(
move |scancode, virtual_keycode, modifiers| {
Expand Down
22 changes: 22 additions & 0 deletions src/platform_impl/web/web_sys/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct Canvas {
on_touch_end: Option<EventListenerHandle<dyn FnMut(Event)>>,
on_focus: Option<EventListenerHandle<dyn FnMut(FocusEvent)>>,
on_blur: Option<EventListenerHandle<dyn FnMut(FocusEvent)>>,
on_contextmenu: Option<EventListenerHandle<dyn FnMut(Event)>>,
on_keyboard_release: Option<EventListenerHandle<dyn FnMut(KeyboardEvent)>>,
on_keyboard_press: Option<EventListenerHandle<dyn FnMut(KeyboardEvent)>>,
on_received_character: Option<EventListenerHandle<dyn FnMut(KeyboardEvent)>>,
Expand Down Expand Up @@ -72,6 +73,12 @@ impl Canvas {
.map_err(|_| os_error!(OsError("Failed to set a tabindex".to_owned())))?;
}

// Prevent double clicks on the canvas from causing text selections elsewhere on the page
// Calling preventDefault within a dblclick/pointerdown handler on the canvas does not work.
for prefix in ["", "-webkit-", "-moz-", "-ms-"] {
super::set_canvas_style_property(&canvas, &format!("{}user-select", prefix), "none");
}

let mouse_state = if has_pointer_event() {
MouseState::HasPointerEvent(pointer_handler::PointerHandler::new())
} else {
Expand All @@ -87,6 +94,7 @@ impl Canvas {
on_touch_end: None,
on_blur: None,
on_focus: None,
on_contextmenu: None,
on_keyboard_release: None,
on_keyboard_press: None,
on_received_character: None,
Expand Down Expand Up @@ -172,6 +180,19 @@ impl Canvas {
}));
}

pub fn on_contextmenu(&mut self, prevent_default: bool) {
// Setup a handler to prevent the default context menu from appearing.
//
// contextmenu events normally occur on right click and can interfere with the sequence of
// pointer events, e.g. https://github.com/rust-windowing/winit/issues/2608.
self.on_contextmenu = Some(self.common.add_event("contextmenu", move |event: Event| {
if prevent_default {
trace!("contextmenu event ignored because prevent_default is true");
event.prevent_default();
}
}));
}

pub fn on_keyboard_release<F>(&mut self, mut handler: F, prevent_default: bool)
where
F: 'static + FnMut(ScanCode, Option<VirtualKeyCode>, ModifiersState),
Expand Down Expand Up @@ -364,6 +385,7 @@ impl Canvas {
pub fn remove_listeners(&mut self) {
self.on_focus = None;
self.on_blur = None;
self.on_contextmenu = None;
self.on_keyboard_release = None;
self.on_keyboard_press = None;
self.on_received_character = None;
Expand Down