Module hwnd

Module hwnd 

Source
Expand description

Win32 HWND-level helpers for browser panes: the WM_SETFOCUS redirect subclass and the focus-bypass flag.

Moved out of client.rs during Phase 2 of the pane modularization split (see docs/specs/SPEC_BROWSER_PANE_MODULARIZATION.md §6). client.rs still uses ALLOW_BROWSER_PANE_FOCUS_ONCE at a distance (nothing there imports the function directly), but install_browser_pane_focus_redirect is the home for pane-focused Win32 subclass logic and future phases can wire it up to pane on_after_created / on_load_end without touching client.rs.

Everything in this file is Windows-only by gating.

Structs§

BrowserPaneContext 🔒
Per-pane context, keyed by the pane’s outer HWND. Populated by install_browser_pane_focus_redirect. The WndProc hook uses it to emit the browser-pane-clicked event on WM_LBUTTONDOWN without needing to round-trip through CEF callbacks — only the outer HWND is keyed here; descendants walk up via GetParent to find their context.

Statics§

ALLOW_BROWSER_PANE_FOCUS_ONCE
When true, the next WM_SETFOCUS delivered to a subclassed pane HWND is allowed through instead of being redirected back to the parent.
BROWSER_PANE_HWND_CONTEXT 🔒
BROWSER_PANE_REDIRECT_LAST_AT 🔒
Last-redirect timestamp per root HWND, used by should_redirect_pane_focus_to_root to rate-limit programmatic focus storms (setInterval-driven window.focus(), OAuth redirector pages, DOM mutation observers re-focusing on every change). Keyed by the root HWND cast to usize. Entries are overwritten on each pass and never explicitly removed — the map is bounded by the count of distinct top-level AgentMux windows seen in a session, which is small.
BROWSER_PANE_WNDPROCS 🔒
Map of pane HWND -> original WndProc, so the subclass hook can delegate to the real handler after running its interception logic. The mutex is held only while mutating the map — hooks that read on the UI thread copy out the pointer quickly.
LAST_FOCUSED_BY_ROOT
Per-top-level-window record of the last child HWND to receive intentional keyboard focus — written by the pane subclass when an allowed-through WM_SETFOCUS lands and by MainFocusReclaimTask after its SetFocus on the main render widget. Programmatic pane focus that the redirect intercepts is NOT recorded — only paths the user actually intends.

Functions§

install_browser_pane_focus_redirect
Subclass a browser pane’s outer HWND (and every descendant HWND Chromium has already created) so WM_SETFOCUS is redirected back to the parent top-level window unless the focus change is user-initiated (see ALLOW_BROWSER_PANE_FOCUS_ONCE).
record_intentional_focus
Single write helper called from both intentional-focus sites (the pane subclass in this module and MainFocusReclaimTask in ui_tasks.rs). Resolves child’s top-level ancestor via GetAncestor(GA_ROOT) and stores the pair into LAST_FOCUSED_BY_ROOT.
remove_contexts_for_block
Remove every BROWSER_PANE_HWND_CONTEXT entry whose context refers to the given block_id. Called from on_before_close_browser_pane so the map doesn’t grow unbounded as panes are opened and closed over the session. Keyed by block_id (not HWND) because the close path has the label/block_id immediately but not the HWND — by the time CEF fires on_before_close, the browser’s HWND may already be invalid.
should_redirect_pane_focus_to_root 🔒
Returns true iff the pane WM_SETFOCUS subclass should redirect to root via SetFocus(root). Two guards, both motivated by the 2026-05-02 multi-window freeze investigation (docs/specs/SPEC_WINDOW_FLEET_REDUCER_2026-05-02.md):