From b4be616de083cc427b1e0466fe54f8a239ef374a Mon Sep 17 00:00:00 2001 From: Timon Date: Thu, 25 Sep 2025 10:42:07 +0000 Subject: [PATCH] Desktop: Browser console message forwarding (#3193) * browser console message forwarding * replace target to make it easy to identify browser console messages * use warn as per review comment --- desktop/src/cef/internal.rs | 2 + .../cef/internal/browser_process_client.rs | 10 ++- desktop/src/cef/internal/display_handler.rs | 65 +++++++++++++++++++ desktop/src/main.rs | 2 +- 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 desktop/src/cef/internal/display_handler.rs diff --git a/desktop/src/cef/internal.rs b/desktop/src/cef/internal.rs index 47f0ff202..4a2559ac1 100644 --- a/desktop/src/cef/internal.rs +++ b/desktop/src/cef/internal.rs @@ -10,6 +10,8 @@ mod render_process_v8_handler; mod resource_handler; mod scheme_handler_factory; +mod display_handler; + pub(super) mod render_handler; pub(super) mod task; diff --git a/desktop/src/cef/internal/browser_process_client.rs b/desktop/src/cef/internal/browser_process_client.rs index 1ed5eeb12..f98ff0103 100644 --- a/desktop/src/cef/internal/browser_process_client.rs +++ b/desktop/src/cef/internal/browser_process_client.rs @@ -1,16 +1,18 @@ use cef::rc::{Rc, RcImpl}; use cef::sys::{_cef_client_t, cef_base_ref_counted_t}; -use cef::{ImplClient, LifeSpanHandler, RenderHandler, WrapClient}; +use cef::{DisplayHandler, ImplClient, LifeSpanHandler, RenderHandler, WrapClient}; use crate::cef::CefEventHandler; use crate::cef::ipc::{MessageType, UnpackMessage, UnpackedMessage}; use super::browser_process_life_span_handler::BrowserProcessLifeSpanHandlerImpl; +use super::display_handler::DisplayHandlerImpl; pub(crate) struct BrowserProcessClientImpl { object: *mut RcImpl<_cef_client_t, Self>, render_handler: RenderHandler, event_handler: H, + display_handler: DisplayHandler, } impl BrowserProcessClientImpl { pub(crate) fn new(render_handler: RenderHandler, event_handler: H) -> Self { @@ -18,6 +20,7 @@ impl BrowserProcessClientImpl { object: std::ptr::null_mut(), render_handler, event_handler, + display_handler: DisplayHandler::new(DisplayHandlerImpl::new()), } } } @@ -57,6 +60,10 @@ impl ImplClient for BrowserProcessClientImpl { Some(LifeSpanHandler::new(BrowserProcessLifeSpanHandlerImpl::new())) } + fn display_handler(&self) -> Option { + Some(self.display_handler.clone()) + } + fn get_raw(&self) -> *mut _cef_client_t { self.object.cast() } @@ -72,6 +79,7 @@ impl Clone for BrowserProcessClientImpl { object: self.object, render_handler: self.render_handler.clone(), event_handler: self.event_handler.clone(), + display_handler: self.display_handler.clone(), } } } diff --git a/desktop/src/cef/internal/display_handler.rs b/desktop/src/cef/internal/display_handler.rs new file mode 100644 index 000000000..5ca8d5d53 --- /dev/null +++ b/desktop/src/cef/internal/display_handler.rs @@ -0,0 +1,65 @@ +use cef::rc::{Rc, RcImpl}; +use cef::sys::{_cef_display_handler_t, cef_base_ref_counted_t, cef_log_severity_t::*}; +use cef::{CefString, ImplDisplayHandler, WrapDisplayHandler}; + +pub(crate) struct DisplayHandlerImpl { + object: *mut RcImpl<_cef_display_handler_t, Self>, +} + +impl DisplayHandlerImpl { + pub fn new() -> Self { + Self { object: std::ptr::null_mut() } + } +} + +impl ImplDisplayHandler for DisplayHandlerImpl { + fn on_console_message( + &self, + _browser: Option<&mut cef::Browser>, + level: cef::LogSeverity, + message: Option<&CefString>, + source: Option<&CefString>, + line: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int { + let message = message.map(|m| m.to_string()).unwrap_or_default(); + let source = source.map(|s| s.to_string()).unwrap_or_default(); + let line = line as i64; + let browser_source = format!("{source}:{line}"); + static BROWSER: &str = "browser"; + match level.as_ref() { + LOGSEVERITY_FATAL | LOGSEVERITY_ERROR => tracing::error!(target: BROWSER, "{browser_source} {message}"), + LOGSEVERITY_WARNING => tracing::warn!(target: BROWSER, "{browser_source} {message}"), + LOGSEVERITY_INFO => tracing::info!(target: BROWSER, "{browser_source} {message}"), + LOGSEVERITY_DEFAULT | LOGSEVERITY_VERBOSE => tracing::debug!(target: BROWSER, "{browser_source} {message}"), + _ => tracing::trace!(target: BROWSER, "{browser_source} {message}"), + } + 0 + } + + fn get_raw(&self) -> *mut _cef_display_handler_t { + self.object.cast() + } +} + +impl Clone for DisplayHandlerImpl { + fn clone(&self) -> Self { + unsafe { + let rc_impl = &mut *self.object; + rc_impl.interface.add_ref(); + } + Self { object: self.object } + } +} +impl Rc for DisplayHandlerImpl { + fn as_base(&self) -> &cef_base_ref_counted_t { + unsafe { + let base = &*self.object; + std::mem::transmute(&base.cef_object) + } + } +} +impl WrapDisplayHandler for DisplayHandlerImpl { + fn wrap_rc(&mut self, object: *mut RcImpl<_cef_display_handler_t, Self>) { + self.object = object; + } +} diff --git a/desktop/src/main.rs b/desktop/src/main.rs index 16190d0f7..fbe8c362b 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -27,7 +27,7 @@ fn main() { // We are in a CEF subprocess // This will block until the CEF subprocess quits let error = cef_context_builder.execute_sub_process(); - tracing::error!("Cef subprocess failed with error: {error}"); + tracing::warn!("Cef subprocess failed with error: {error}"); return; }