Fix multiple major keyboard focus issues on linux/X11(fix issue #2026)#4120
Fix multiple major keyboard focus issues on linux/X11(fix issue #2026)#4120JCYang wants to merge 1 commit into
Conversation
JCYang
commented
Mar 11, 2026
- Mouse crossing into Cef browser view will take the keyboard focus, credits partitally goes to original patches by Jiří Janoušek here tiliado/cef@f9a1cbe
- In X11 world, CefFocusHandler can not properly report OnGotFocus(), this hurts for X11 backends when other native widgets need to compete with focus. Not properly fix this can result in multiple input carets blinking in different widgets. Fix it by monitor via WebContentsObserver::DidGetUserInteraction()
…iumembedded#2026) 1. Mouse crossing into Cef browser view will take the keyboard focus, credits partitally goes to original patches by Jiří Janoušek here tiliado/cef@f9a1cbe 2. In X11 world, CefFocusHandler can not properly report OnGotFocus(), this hurts for X11 backends when other native widgets need to compete with focus. Not properly fix this can result in multiple input carets blinking in different widgets. Fix it by monitor via WebContentsObserver::DidGetUserInteraction()
|
We’re using a variation of this backported to 7778 to address focus issues for our Linux users. Without it, focus handling breaks. It this being considered for adoption? |
magreenblatt
left a comment
There was a problem hiding this comment.
Patch file (views_widget.patch) concerns:
-
~600 lines of unrelated style changes (brace additions, namespace comments, return-type reformatting) in
render_widget_host_view_base.cc,render_widget_host_view_event_handler.cc,window_tree_host_platform.cc. These increase rebase burden and obscure the functional fix. Should be dropped from this PR. -
HasExternalParent/SetHasExternalParentduplicated at the wrong layer. The patch adds these toPlatformWindowDelegateandWindowTreeHostPlatform, but CEF already tracks this concept onRenderWidgetHostViewBaseandCefBrowserPlatformDelegate. Consider using the existing mechanism instead of adding new virtuals to Chromium base classes. -
Menu window parenting is a separate behavioral change. The existing patch unconditionally parents menus to
x_root_window_. This PR conditionally parents toparent_widgetand setsHasExternalParent(true). This changes popup positioning for all external-parent scenarios and deserves its own discussion.
| SkColor background_color) | ||
| : CefBrowserPlatformDelegateNativeAura(window_info, background_color) {} | ||
| : CefBrowserPlatformDelegateNativeAura(window_info, background_color) { | ||
| connection_ = x11::Connection::Get(); |
There was a problem hiding this comment.
connection_ = x11::Connection::Get() runs unconditionally, outside any #if BUILDFLAG(SUPPORTS_OZONE_X11) guard. On a Wayland-only runtime this will crash or return null.
| return; | ||
| } | ||
|
|
||
| if (not IsWindowVisible(connection_, host_x11_win)) { |
There was a problem hiding this comment.
Use ! instead of not — not is a valid C++ alternative token but unconventional in Chromium/CEF. Same on the other occurrence in chromeRuntimeBrowserUnfocus().
| return; | ||
| } | ||
|
|
||
| const auto focused = connection_->GetInputFocus().Sync().reply->focus; |
There was a problem hiding this comment.
Crash risk: if Sync() fails, reply is null and this dereferences it. Needs a guard like the GetWindowAttributes calls elsewhere in this PR. Same issue at the other GetInputFocus().Sync().reply->focus in chromeRuntimeBrowserUnfocus().
| return false; | ||
| } | ||
|
|
||
| void CefBrowserPlatformDelegateNativeLinux::chromeRuntimeBrowserFocus() { |
There was a problem hiding this comment.
This and chromeRuntimeBrowserUnfocus each make multiple synchronous X11 round-trips (GetInputFocus, GetWindowAttributes, QueryTree) on every focus/unfocus. Worth documenting the perf tradeoff or considering async alternatives.
|
|
||
| void CefBrowserPlatformDelegateNativeLinux::SetFocus(bool setFocus) { | ||
| if (!setFocus) { | ||
| #if BUILDFLAG(SUPPORTS_OZONE_X11) |
There was a problem hiding this comment.
The return on the next context line is now inside this #if block. On non-X11 builds, SetFocus(false) falls through to the focus-setting code — breaking the original behavior. Move return after #endif.
| } | ||
|
|
||
| #if BUILDFLAG(SUPPORTS_OZONE_X11) | ||
| // does this help wayland? I don't know, I'm just targeting X11. If anyone |
There was a problem hiding this comment.
Comments like "does this help wayland? I don't know" and "should(should we?) further investigate" read as dev notes. Rewrite as concise technical comments or remove — these belong in the PR description, not shipped code.
| // one exception you think inappropriate | ||
| wc->Focus(); | ||
| } | ||
| if (client().get()) { |
There was a problem hiding this comment.
Use the CEF idiomatic pattern: if (auto c = client()) { if (auto handler = c->GetFocusHandler()) { ... } } instead of .get() null checks.
| void WebContentsDestroyed() override; | ||
|
|
||
| #if BUILDFLAG(SUPPORTS_OZONE_X11) | ||
| void DidGetUserInteraction(const blink::WebInputEvent& event) override; |
There was a problem hiding this comment.
The #if guard makes the class signature vary by build config. Consider always declaring the override with a no-op body on non-X11 to keep the interface stable.
| #if BUILDFLAG(SUPPORTS_OZONE_X11) | ||
| raw_ptr<CefWindowX11> window_x11_ = nullptr; | ||
| // for chrome_runtime only | ||
| void chromeRuntimeBrowserFocus(); |
There was a problem hiding this comment.
Method names should use PascalCase per Chromium/CEF convention: ChromeRuntimeBrowserFocus, ChromeRuntimeBrowserUnfocus, EnableKeyboardEventsForWindow.
| void chromeRuntimeBrowserUnfocus(); | ||
| void enableKeyboardEventsForWindow(x11::Window target_win, bool enable) const; | ||
| raw_ptr<x11::Connection> connection_ = nullptr; | ||
| x11::Window previously_focused_ = x11::Window::None; |
There was a problem hiding this comment.
previously_focused_ is set but never cleared. If the X11 window is destroyed, the stale ID could be reused by X for a different window, causing chromeRuntimeBrowserUnfocus() to restore focus to the wrong target.
We noticed the style changes too, but we've also inherited a number of the other things you would like altered. If I find some time I'll try provide some updates to this if @JCYang doesn't update. Currently using LeeGDavis@819559b#diff-941690a3e08dd6925162a020800696183a259ad20a450a077ea7f91c704948c2 |