mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Web: don't scroll host page when text agent or canvas grabs focus (#8296)
* Closes <https://github.com/emilk/egui/issues/8295> * [x] I have followed the instructions in the PR template When an eframe app is embedded in a scrollable host page, the host page jumped to the top whenever the app booted or grabbed keyboard focus. Cause: the hidden text-agent `<input>` sat at (0,0) of `<body>` with the `autofocus` attribute, and all focus calls (text agent and canvas) used plain `focus()`, so the browser scrolled the focused element into view — i.e. to the top of the page. Changes: * All focus calls in `eframe` web (text agent, canvas, Gboard blur/refocus workaround) now go through a new `focus_without_scroll()` helper that uses `focus_with_options` with `preventScroll: true` (supported by all evergreen browsers). * The `autofocus` attribute is replaced with an explicit focus call after DOM insertion — the browser-internal autofocus path always scrolls the element into view and cannot be prevented by any focus option. Boot-focus behavior is preserved. * The text-agent input is initially parked at the canvas origin instead of (0,0) of the page, so any residual scroll-into-view would target the canvas rather than the top of the host page. (`move_to` keeps repositioning it for IME as before.) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -84,6 +84,17 @@ pub(crate) fn has_focus<T: JsCast>(element: &T) -> bool {
|
||||
try_has_focus(element).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Focus the given element without scrolling it into view.
|
||||
///
|
||||
/// Scrolling the element into view would scroll the whole page when
|
||||
/// the app is embedded in a larger scrollable page,
|
||||
/// see <https://github.com/emilk/egui/issues/8295>.
|
||||
pub(crate) fn focus_without_scroll(element: &web_sys::HtmlElement) -> Result<(), JsValue> {
|
||||
let options = web_sys::FocusOptions::new();
|
||||
options.set_prevent_scroll(true);
|
||||
element.focus_with_options(&options)
|
||||
}
|
||||
|
||||
/// Current time in seconds (since undefined point in time).
|
||||
///
|
||||
/// Monotonically increasing.
|
||||
|
||||
Reference in New Issue
Block a user