Desktop: Buffer web messages until connection is initialized (#3082)

Buffer web messages until connection is initialized
This commit is contained in:
Timon
2025-08-22 15:15:17 +00:00
committed by GitHub
parent a4ec50d8ba
commit c6ec3a27ca
9 changed files with 74 additions and 14 deletions
@@ -32,6 +32,10 @@ impl<H: CefEventHandler> ImplClient for BrowserProcessClientImpl<H> {
) -> ::std::os::raw::c_int {
let unpacked_message = unsafe { message.and_then(|m| m.unpack()) };
match unpacked_message {
Some(UnpackedMessage {
message_type: MessageType::Initialized,
data: _,
}) => self.event_handler.initialized_web_communication(),
Some(UnpackedMessage {
message_type: MessageType::SendToNative,
data,
@@ -76,24 +76,30 @@ impl ImplRenderProcessHandler for RenderProcessHandlerImpl {
}
fn on_context_created(&self, _browser: Option<&mut cef::Browser>, _frame: Option<&mut cef::Frame>, context: Option<&mut cef::V8Context>) {
let function_name = "sendNativeMessage";
let register_js_function = |context: &mut cef::V8Context, name: &'static str| {
let mut v8_handler = V8Handler::new(BrowserProcessV8HandlerImpl::new());
let Some(mut function) = v8_value_create_function(Some(&CefString::from(name)), Some(&mut v8_handler)) else {
tracing::error!("Failed to create V8 function {name}");
return;
};
let Some(global) = context.global() else {
tracing::error!("Global object is not available in V8 context");
return;
};
global.set_value_bykey(Some(&CefString::from(name)), Some(&mut function), V8Propertyattribute::default());
};
let Some(context) = context else {
tracing::error!("V8 context is not available");
return;
};
let mut v8_handler = V8Handler::new(BrowserProcessV8HandlerImpl::new());
let Some(mut function) = v8_value_create_function(Some(&CefString::from(function_name)), Some(&mut v8_handler)) else {
tracing::error!("Failed to create V8 function {function_name}");
return;
};
let initialized_function_name = "initializeNativeCommunication";
let send_function_name = "sendNativeMessage";
let Some(global) = context.global() else {
tracing::error!("Global object is not available in V8 context");
return;
};
global.set_value_bykey(Some(&CefString::from(function_name)), Some(&mut function), V8Propertyattribute::default());
register_js_function(context, initialized_function_name);
register_js_function(context, send_function_name);
}
fn get_raw(&self) -> *mut _cef_render_process_handler_t {
@@ -21,8 +21,11 @@ impl ImplV8Handler for BrowserProcessV8HandlerImpl {
_retval: Option<&mut Option<V8Value>>,
_exception: Option<&mut cef::CefString>,
) -> ::std::os::raw::c_int {
if let Some(name) = name {
if name.to_string() == "sendNativeMessage" {
match name.map(|s| s.to_string()).unwrap_or_default().as_str() {
"initializeNativeCommunication" => {
v8_context_get_current_context().send_message(MessageType::Initialized, vec![0u8].as_slice());
}
"sendNativeMessage" => {
let Some(args) = arguments else {
tracing::error!("No arguments provided to sendNativeMessage");
return 0;
@@ -48,6 +51,9 @@ impl ImplV8Handler for BrowserProcessV8HandlerImpl {
return 1;
}
name => {
tracing::error!("Unknown V8 function called: {}", name);
}
}
1
}