pub struct AgentMuxHandler {
browser_list: Vec<Browser>,
is_closing: bool,
state: Arc<AppState>,
ipc_port: u16,
is_browser_pane: bool,
}Expand description
Core handler state shared across all CEF callback interfaces.
Fields§
§browser_list: Vec<Browser>§is_closing: bool§state: Arc<AppState>§ipc_port: u16§is_browser_pane: boolImplementations§
Source§impl AgentMuxHandler
impl AgentMuxHandler
pub fn new(state: Arc<AppState>, ipc_port: u16) -> Arc<Mutex<Self>>
pub fn new_with_browser_pane( state: Arc<AppState>, ipc_port: u16, is_browser_pane: bool, ) -> Arc<Mutex<Self>>
fn on_title_change( &mut self, browser: Option<&mut Browser>, title: Option<&CefString>, )
fn on_favicon_urlchange( &mut self, browser: Option<&mut Browser>, icon_urls: Option<&mut CefStringList>, )
fn on_after_created(&mut self, browser: Option<&mut Browser>)
fn do_close(&mut self, _browser: Option<&mut Browser>) -> bool
Sourcefn on_before_popup(
&mut self,
browser: Option<&mut Browser>,
_frame: Option<&mut Frame>,
target_url: Option<&CefString>,
_target_disposition: WindowOpenDisposition,
) -> bool
fn on_before_popup( &mut self, browser: Option<&mut Browser>, _frame: Option<&mut Frame>, target_url: Option<&CefString>, _target_disposition: WindowOpenDisposition, ) -> bool
Intercept target="_blank" / window.open() from embedded pages so
they don’t spawn rogue top-level CEF windows. Instead navigate the
current frame to the target URL — matches the UX expectation
that AgentMux owns window management, not the page.
Returning non-zero cancels popup creation. Applies to both main
and pane clients: main’s frontend never relies on window.open
(link clicks go through openExternal IPC), and panes explicitly
don’t want popups. See
specs/SPEC_BROWSER_PANE_DEFAULT_URL_AND_POPUP_2026_04_21.md.
The load_url call is deferred via post_task, not run inline.
Inline load_url caused a UI-thread deadlock on link click:
on_before_popup runs while AgentMuxLifeSpanHandler holds
self.inner.lock() (via the wrap macro). Inline load_url starts
a new navigation on the same UI thread, which triggers
on_loading_state_change on AgentMuxLoadHandler, which also
tries to take self.inner.lock() → deadlock. The host hung with
backend heartbeats still running but the whole UI frozen. Posting
the load_url as a separate UI task lets the popup handler
return, release the lock, then pick up the load on the next loop
iteration.
fn on_before_close(&mut self, browser: Option<&mut Browser>)
Sourcefn on_loading_state_change(
&mut self,
browser: Option<&mut Browser>,
_is_loading: i32,
can_go_back: i32,
can_go_forward: i32,
)
fn on_loading_state_change( &mut self, browser: Option<&mut Browser>, _is_loading: i32, can_go_back: i32, can_go_forward: i32, )
CEF fires this whenever the browser’s loading/history state changes
(navigation started, navigation committed, back/forward enabled).
can_go_back / can_go_forward come directly from the navigation
controller — no need to query browser.can_go_back() (which races
with history commit when called from on_load_end).
For panes: emit browser-pane-nav-state so the frontend address
bar + back/forward buttons reflect CEF’s real history state.
fn on_load_end( &mut self, browser: Option<&mut Browser>, frame: Option<&mut Frame>, _http_status_code: i32, )
fn on_load_error( &mut self, _browser: Option<&mut Browser>, frame: Option<&mut Frame>, error_code: Errorcode, error_text: Option<&CefString>, failed_url: Option<&CefString>, )
Sourcefn on_render_process_terminated(
&mut self,
browser: Option<&mut Browser>,
status: TerminationStatus,
error_code: i32,
error_string: Option<&CefString>,
)
fn on_render_process_terminated( &mut self, browser: Option<&mut Browser>, status: TerminationStatus, error_code: i32, error_string: Option<&CefString>, )
Render-process terminated — typically OOM, a renderer-side panic, or some native bug inside CEF/Chromium. Without this hook the window just turns white. We log the cause and replace the white page with a recovery HTML page that offers Reload / Quit buttons.
See specs/SPEC_GRACEFUL_CRASH_HANDLING_2026_04_13.md (PR 1).
Sourcefn on_auth_credentials(
&mut self,
browser: Option<&mut Browser>,
origin_url: Option<&CefString>,
is_proxy: c_int,
host: Option<&CefString>,
port: c_int,
realm: Option<&CefString>,
_scheme: Option<&CefString>,
callback: Option<&mut AuthCallback>,
) -> c_int
fn on_auth_credentials( &mut self, browser: Option<&mut Browser>, origin_url: Option<&CefString>, is_proxy: c_int, host: Option<&CefString>, port: c_int, realm: Option<&CefString>, _scheme: Option<&CefString>, callback: Option<&mut AuthCallback>, ) -> c_int
CEF asks the embedder for HTTP Basic / Digest credentials on a
401/407. Browser-pane requests get surfaced to the renderer via
browser-pane-auth-required so the user can type credentials;
non-browser-pane requests (the main host window’s frontend
load) are declined — those shouldn’t hit auth-challenged
resources, and silently failing matches the prior behavior.
Returns 1 (async — we’ll resolve the callback via
browser_pane_auth_submit / browser_pane_auth_cancel) or 0
(sync no — CEF aborts the request).
Phase α of SPEC_BROWSER_PANE_HTTP_BASIC_AUTH_2026_05_18.md.
Auto Trait Implementations§
impl Freeze for AgentMuxHandler
impl !RefUnwindSafe for AgentMuxHandler
impl Send for AgentMuxHandler
impl Sync for AgentMuxHandler
impl Unpin for AgentMuxHandler
impl !UnwindSafe for AgentMuxHandler
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, U> ConvertReturnValue<U> for Twhere
T: Into<U>,
impl<T, U> ConvertReturnValue<U> for Twhere
T: Into<U>,
fn wrap_result(self) -> U
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.