From fcac3268ad05cb94a1d6f531609d8116e9e42282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sun, 10 May 2026 00:23:55 -0400 Subject: [PATCH] Stop hijacking omnibar typing when an external web tab is active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real bug found by reading capture_key_down semantics: the web keyboard handler was registered as `capture_key_down` on the root div, which fires from root → focused element. So when the user is on an external tab (https://google.com) and clicks the omnibar to type a new URL, every keystroke was intercepted at the root, the text was forwarded to Servo, and `cx.stop_propagation()` killed the event before it could reach the focused Input. The omnibar appeared dead. Gate the handler on `self.focus_handle.is_focused(window)`. The shell's root handle is only focused when nothing deeper is — clicks on the web viewport call `focus_handle.focus(window)`, which makes the root focused; clicks on any Input transfer focus to the Input's handle and `is_focused` returns false on the root. Now keystrokes reach the Input untouched while still flowing to Servo when the user is interacting with the page itself. cargo test --workspace: 440 passed, 0 failed. --- crates/ely_app/src/shell/web_surface_keyboard.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/ely_app/src/shell/web_surface_keyboard.rs b/crates/ely_app/src/shell/web_surface_keyboard.rs index ae45a06..64b44c0 100644 --- a/crates/ely_app/src/shell/web_surface_keyboard.rs +++ b/crates/ely_app/src/shell/web_surface_keyboard.rs @@ -7,9 +7,22 @@ impl ElyShell { pub(super) fn on_external_web_key_down( &mut self, event: &KeyDownEvent, - _window: &mut Window, + window: &mut Window, cx: &mut Context, ) { + // Only forward keys to the web viewport when the shell's root + // focus handle is the one that's actually focused. If the user + // has clicked the omnibar Input (or any other Input — plugin + // search, bookmark editor, etc.), focus has moved to that + // Input's handle and the user expects keystrokes to reach it. + // Without this guard, capture_key_down on the root would + // intercept every keystroke and forward it to Servo, leaving + // the omnibar permanently dead while any external tab is + // active. + if !self.focus_handle.is_focused(window) { + return; + } + let Some((tab_id, requested_url)) = self.active_external_tab_target() else { return; };