From f624e3078637e1698b1885d197b72bea25623ed5 Mon Sep 17 00:00:00 2001 From: rustbasic <127506429+rustbasic@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:53:57 +0900 Subject: [PATCH] **fix(web): prevent entire page from scrolling out of view in Chrome (WASM)** (#7888) **fix(web): prevent entire page from scrolling out of view in Chrome (WASM)** * Closes #7887 **Problem** When using `egui` on the web, the browser (especially Chrome) occasionally triggers an unwanted page-level scroll. This happens because the hidden input element (text agent) used for IME/text input is sometimes positioned outside the visible bounds of the canvas, causing the browser to "scroll it into view." **Solution** I modified the `move_to` function in the web's `text_agent` to ensure the input element's position stays within the canvas height. By clamping the `top` property between `0.0` and `canvas_height`, we prevent the browser from incorrectly scrolling the entire page when the text agent moves. - **Specific change:** Applied `clamp(0.0, canvas_height)` to the `clamped_y` value before setting the CSS `top` property. --- crates/eframe/src/web/text_agent.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/crates/eframe/src/web/text_agent.rs b/crates/eframe/src/web/text_agent.rs index 20b904244..1da7525ce 100644 --- a/crates/eframe/src/web/text_agent.rs +++ b/crates/eframe/src/web/text_agent.rs @@ -38,6 +38,8 @@ impl TextAgent { style.set_property("position", "absolute")?; style.set_property("top", "0")?; style.set_property("left", "0")?; + // Prevent auto-zoom on mobile browsers (requires at least 16px). + style.set_property("font-size", "16px")?; if root.has_type::() { // root object is a document, append to its body @@ -151,16 +153,21 @@ impl TextAgent { let cursor_rect = ime.cursor_rect.translate(canvas_rect.min.to_vec2()); let style = self.input.style(); + let native_ppp = super::native_pixels_per_point(); + + // Clamp the input position within the canvas width to prevent unwanted horizontal scrolling. + let logical_canvas_width = canvas.width() as f32 / native_ppp; + let visible_x = cursor_rect.center().x * zoom_factor; + let clamped_x = visible_x.clamp(0.0, logical_canvas_width); + + // Clamp the input position within the canvas height to prevent unwanted vertical scrolling. + let logical_canvas_height = canvas.height() as f32 / native_ppp; + let visible_y = cursor_rect.center().y * zoom_factor; + let clamped_y = visible_y.clamp(0.0, logical_canvas_height); // This is where the IME input will point to: - style.set_property( - "left", - &format!("{}px", cursor_rect.center().x * zoom_factor), - )?; - style.set_property( - "top", - &format!("{}px", cursor_rect.center().y * zoom_factor), - )?; + style.set_property("left", &format!("{clamped_x}px"))?; + style.set_property("top", &format!("{clamped_y}px"))?; Ok(()) }