Focus Trapping: canvas.set_onblur(fn) is respected, but focus() is not. #3003
-
Problem: Solution: {
let onblur = Closure::wrap(Box::new(move |e: web_sys::FocusEvent| {
log::info!("A Focus Event.");
if let Some(target) = e.current_target() {
log::info!("Had a target.");
if let Some(canvas) = target.clone().dyn_ref::<HtmlCanvasElement>() {
if let Ok(res) = canvas.clone().focus() {
log::info!("Focused canvas.");
} else {
log::info!("Could not focus canvas.");
}
} else {
log::error!("Could not get canvas from target");
}
} else {
log::error!("Could not get current target");
}
}) as Box<dyn FnMut(web_sys::FocusEvent)>);
// Attach winit canvas to body element
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| doc.get_element_by_id("canvas"))
.and_then(|canvas_div: Element| {
let canvas: HtmlCanvasElement = window.canvas();
canvas.set_class_name("game");
canvas.set_id("rrr");
canvas.set_width(WIDTH);
canvas.set_height(HEIGHT);
let res = canvas_div
.append_child(&web_sys::Element::from(window.canvas()))
.ok();
canvas.set_onblur(Some(onblur.as_ref().unchecked_ref()));
canvas.set_tab_index(1);
canvas.focus().ok();
res
});
onblur.forget();
} Expectation: Am I missing something critical? Is it an order of operations problem? Thanks! |
Beta Was this translation helpful? Give feedback.
Answered by
Liamolucko
Jul 23, 2022
Replies: 1 comment 1 reply
-
This looks to be a quirk of the web APIs themselves. This equivalent javascript has the same problem: <canvas tabindex="0"></canvas>
<script>
const canvas = document.querySelector("canvas");
canvas.addEventListener("focus", () => console.log("focused"));
canvas.addEventListener("blur", () => console.log("unfocused"));
canvas.addEventListener("blur", () => canvas.focus());
</script> It works if you add a timeout: <canvas tabindex="0"></canvas>
<script>
const canvas = document.querySelector("canvas");
canvas.addEventListener("focus", () => console.log("focused"));
canvas.addEventListener("blur", () => console.log("unfocused"));
canvas.addEventListener("blur", () => setTimeout(() => canvas.focus(), 0));
</script> |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
Zageron
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This looks to be a quirk of the web APIs themselves. This equivalent javascript has the same problem:
It works if you add a timeout: