eframe web: only cosume copy/cut events if the canvas has focus (#7270)

Previously eframe would "steal" these events (by calling
`stop_propagation/prevent_default`) even when the eframe canvas did not
have focus.
This commit is contained in:
Emil Ernerfeldt 2025-06-27 10:25:47 +02:00 committed by GitHub
parent 78a8de2e8f
commit ae8363ddb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 27 additions and 19 deletions

View File

@ -311,13 +311,17 @@ pub(crate) fn on_keyup(event: web_sys::KeyboardEvent, runner: &mut AppRunner) {
fn install_copy_cut_paste(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
runner_ref.add_event_listener(target, "paste", |event: web_sys::ClipboardEvent, runner| {
if !runner.input.raw.focused {
return; // The eframe app is not interested
}
if let Some(data) = event.clipboard_data() {
if let Ok(text) = data.get_data("text") {
let text = text.replace("\r\n", "\n");
let mut should_stop_propagation = true;
let mut should_prevent_default = true;
if !text.is_empty() && runner.input.raw.focused {
if !text.is_empty() {
let egui_event = egui::Event::Paste(text);
should_stop_propagation =
(runner.web_options.should_stop_propagation)(&egui_event);
@ -340,17 +344,19 @@ fn install_copy_cut_paste(runner_ref: &WebRunner, target: &EventTarget) -> Resul
})?;
runner_ref.add_event_listener(target, "cut", |event: web_sys::ClipboardEvent, runner| {
if runner.input.raw.focused {
runner.input.raw.events.push(egui::Event::Cut);
// 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();
if !runner.input.raw.focused {
return; // The eframe app is not interested
}
runner.input.raw.events.push(egui::Event::Cut);
// 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();
// Use web options to tell if the web event should be propagated to parent elements based on the egui event.
if (runner.web_options.should_stop_propagation)(&egui::Event::Cut) {
event.stop_propagation();
@ -362,17 +368,19 @@ fn install_copy_cut_paste(runner_ref: &WebRunner, target: &EventTarget) -> Resul
})?;
runner_ref.add_event_listener(target, "copy", |event: web_sys::ClipboardEvent, runner| {
if runner.input.raw.focused {
runner.input.raw.events.push(egui::Event::Copy);
// 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();
if !runner.input.raw.focused {
return; // The eframe app is not interested
}
runner.input.raw.events.push(egui::Event::Copy);
// 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();
// Use web options to tell if the web event should be propagated to parent elements based on the egui event.
if (runner.web_options.should_stop_propagation)(&egui::Event::Copy) {
event.stop_propagation();