Desktop: Prevent CEF context menu to fix crashing by right-clicking a text field (#3429)
* add dummy context menu handler to prevent some crashes * some cleanup correcting cef handler impl names using std::ffi::c_int
This commit is contained in:
parent
bb4516e377
commit
94e5c8fc05
|
|
@ -1,18 +1,18 @@
|
|||
mod browser_process_app;
|
||||
mod browser_process_client;
|
||||
mod browser_process_handler;
|
||||
mod browser_process_life_span_handler;
|
||||
mod browser_process_load_handler;
|
||||
|
||||
mod render_process_app;
|
||||
mod render_process_handler;
|
||||
mod render_process_v8_handler;
|
||||
|
||||
mod context_menu_handler;
|
||||
mod display_handler;
|
||||
mod life_span_handler;
|
||||
mod load_handler;
|
||||
mod resource_handler;
|
||||
mod scheme_handler_factory;
|
||||
|
||||
mod display_handler;
|
||||
|
||||
pub(super) mod render_handler;
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
use cef::rc::{Rc, RcImpl};
|
||||
use cef::sys::{_cef_client_t, cef_base_ref_counted_t};
|
||||
use cef::{DisplayHandler, ImplClient, LifeSpanHandler, LoadHandler, RenderHandler, WrapClient};
|
||||
use cef::{ContextMenuHandler, DisplayHandler, ImplClient, LifeSpanHandler, LoadHandler, RenderHandler, WrapClient};
|
||||
|
||||
use crate::cef::CefEventHandler;
|
||||
use crate::cef::ipc::{MessageType, UnpackMessage, UnpackedMessage};
|
||||
|
||||
use super::browser_process_life_span_handler::BrowserProcessLifeSpanHandlerImpl;
|
||||
use super::browser_process_load_handler::LoadHandlerImpl;
|
||||
use super::context_menu_handler::ContextMenuHandlerImpl;
|
||||
use super::display_handler::DisplayHandlerImpl;
|
||||
use super::life_span_handler::LifeSpanHandlerImpl;
|
||||
use super::load_handler::LoadHandlerImpl;
|
||||
use super::render_handler::RenderHandlerImpl;
|
||||
|
||||
pub(crate) struct BrowserProcessClientImpl<H: CefEventHandler> {
|
||||
|
|
@ -36,7 +37,7 @@ impl<H: CefEventHandler> ImplClient for BrowserProcessClientImpl<H> {
|
|||
_frame: Option<&mut cef::Frame>,
|
||||
_source_process: cef::ProcessId,
|
||||
message: Option<&mut cef::ProcessMessage>,
|
||||
) -> ::std::os::raw::c_int {
|
||||
) -> std::ffi::c_int {
|
||||
let unpacked_message = unsafe { message.and_then(|m| m.unpack()) };
|
||||
match unpacked_message {
|
||||
Some(UnpackedMessage {
|
||||
|
|
@ -65,13 +66,17 @@ impl<H: CefEventHandler> ImplClient for BrowserProcessClientImpl<H> {
|
|||
}
|
||||
|
||||
fn life_span_handler(&self) -> Option<cef::LifeSpanHandler> {
|
||||
Some(LifeSpanHandler::new(BrowserProcessLifeSpanHandlerImpl::new()))
|
||||
Some(LifeSpanHandler::new(LifeSpanHandlerImpl::new()))
|
||||
}
|
||||
|
||||
fn display_handler(&self) -> Option<cef::DisplayHandler> {
|
||||
Some(self.display_handler.clone())
|
||||
}
|
||||
|
||||
fn context_menu_handler(&self) -> Option<cef::ContextMenuHandler> {
|
||||
Some(ContextMenuHandler::new(ContextMenuHandlerImpl::new()))
|
||||
}
|
||||
|
||||
fn get_raw(&self) -> *mut _cef_client_t {
|
||||
self.object.cast()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ impl<H: CefEventHandler> ImplBrowserProcessHandler for BrowserProcessHandlerImpl
|
|||
self.event_handler.schedule_cef_message_loop_work(Instant::now() + Duration::from_millis(delay_ms as u64));
|
||||
}
|
||||
|
||||
fn on_already_running_app_relaunch(&self, _command_line: Option<&mut cef::CommandLine>, _current_directory: Option<&CefString>) -> ::std::os::raw::c_int {
|
||||
fn on_already_running_app_relaunch(&self, _command_line: Option<&mut cef::CommandLine>, _current_directory: Option<&CefString>) -> std::ffi::c_int {
|
||||
1 // Return 1 to prevent default behavior of opening a empty browser window
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
use cef::rc::{Rc, RcImpl};
|
||||
use cef::sys::{_cef_context_menu_handler_t, cef_base_ref_counted_t};
|
||||
use cef::{ImplContextMenuHandler, WrapContextMenuHandler};
|
||||
|
||||
pub(crate) struct ContextMenuHandlerImpl {
|
||||
object: *mut RcImpl<_cef_context_menu_handler_t, Self>,
|
||||
}
|
||||
impl ContextMenuHandlerImpl {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { object: std::ptr::null_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl ImplContextMenuHandler for ContextMenuHandlerImpl {
|
||||
fn run_context_menu(
|
||||
&self,
|
||||
_browser: Option<&mut cef::Browser>,
|
||||
_frame: Option<&mut cef::Frame>,
|
||||
_params: Option<&mut cef::ContextMenuParams>,
|
||||
_model: Option<&mut cef::MenuModel>,
|
||||
_callback: Option<&mut cef::RunContextMenuCallback>,
|
||||
) -> std::ffi::c_int {
|
||||
// Prevent context menu
|
||||
1
|
||||
}
|
||||
|
||||
fn run_quick_menu(
|
||||
&self,
|
||||
_browser: Option<&mut cef::Browser>,
|
||||
_frame: Option<&mut cef::Frame>,
|
||||
_location: Option<&cef::Point>,
|
||||
_size: Option<&cef::Size>,
|
||||
_edit_state_flags: cef::QuickMenuEditStateFlags,
|
||||
_callback: Option<&mut cef::RunQuickMenuCallback>,
|
||||
) -> std::ffi::c_int {
|
||||
// Prevent quick menu
|
||||
1
|
||||
}
|
||||
|
||||
fn get_raw(&self) -> *mut _cef_context_menu_handler_t {
|
||||
self.object.cast()
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for ContextMenuHandlerImpl {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
let rc_impl = &mut *self.object;
|
||||
rc_impl.interface.add_ref();
|
||||
}
|
||||
Self { object: self.object }
|
||||
}
|
||||
}
|
||||
impl Rc for ContextMenuHandlerImpl {
|
||||
fn as_base(&self) -> &cef_base_ref_counted_t {
|
||||
unsafe {
|
||||
let base = &*self.object;
|
||||
std::mem::transmute(&base.cef_object)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl WrapContextMenuHandler for ContextMenuHandlerImpl {
|
||||
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_context_menu_handler_t, Self>) {
|
||||
self.object = object;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ type CefCursorHandle = cef::CursorHandle;
|
|||
type CefCursorHandle = *mut u8;
|
||||
|
||||
impl<H: CefEventHandler> ImplDisplayHandler for DisplayHandlerImpl<H> {
|
||||
fn on_cursor_change(&self, _browser: Option<&mut cef::Browser>, _cursor: CefCursorHandle, cursor_type: cef::CursorType, _custom_cursor_info: Option<&cef::CursorInfo>) -> ::std::os::raw::c_int {
|
||||
fn on_cursor_change(&self, _browser: Option<&mut cef::Browser>, _cursor: CefCursorHandle, cursor_type: cef::CursorType, _custom_cursor_info: Option<&cef::CursorInfo>) -> std::ffi::c_int {
|
||||
let cursor = match cursor_type.into() {
|
||||
CT_POINTER => CursorIcon::Default,
|
||||
CT_CROSS => CursorIcon::Crosshair,
|
||||
|
|
@ -86,14 +86,7 @@ impl<H: CefEventHandler> ImplDisplayHandler for DisplayHandlerImpl<H> {
|
|||
1 // We handled the cursor change.
|
||||
}
|
||||
|
||||
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 {
|
||||
fn on_console_message(&self, _browser: Option<&mut cef::Browser>, level: cef::LogSeverity, message: Option<&CefString>, source: Option<&CefString>, line: std::ffi::c_int) -> std::ffi::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;
|
||||
|
|
|
|||
|
|
@ -2,32 +2,32 @@ use cef::rc::{Rc, RcImpl};
|
|||
use cef::sys::{_cef_life_span_handler_t, cef_base_ref_counted_t};
|
||||
use cef::{ImplLifeSpanHandler, WrapLifeSpanHandler};
|
||||
|
||||
pub(crate) struct BrowserProcessLifeSpanHandlerImpl {
|
||||
pub(crate) struct LifeSpanHandlerImpl {
|
||||
object: *mut RcImpl<_cef_life_span_handler_t, Self>,
|
||||
}
|
||||
impl BrowserProcessLifeSpanHandlerImpl {
|
||||
impl LifeSpanHandlerImpl {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { object: std::ptr::null_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl ImplLifeSpanHandler for BrowserProcessLifeSpanHandlerImpl {
|
||||
impl ImplLifeSpanHandler for LifeSpanHandlerImpl {
|
||||
fn on_before_popup(
|
||||
&self,
|
||||
_browser: Option<&mut cef::Browser>,
|
||||
_frame: Option<&mut cef::Frame>,
|
||||
_popup_id: ::std::os::raw::c_int,
|
||||
_popup_id: std::ffi::c_int,
|
||||
target_url: Option<&cef::CefString>,
|
||||
_target_frame_name: Option<&cef::CefString>,
|
||||
_target_disposition: cef::WindowOpenDisposition,
|
||||
_user_gesture: ::std::os::raw::c_int,
|
||||
_user_gesture: std::ffi::c_int,
|
||||
_popup_features: Option<&cef::PopupFeatures>,
|
||||
_window_info: Option<&mut cef::WindowInfo>,
|
||||
_client: Option<&mut Option<cef::Client>>,
|
||||
_settings: Option<&mut cef::BrowserSettings>,
|
||||
_extra_info: Option<&mut Option<cef::DictionaryValue>>,
|
||||
_no_javascript_access: Option<&mut ::std::os::raw::c_int>,
|
||||
) -> ::std::os::raw::c_int {
|
||||
_no_javascript_access: Option<&mut std::ffi::c_int>,
|
||||
) -> std::ffi::c_int {
|
||||
let target = target_url.map(|url| url.to_string()).unwrap_or("unknown".to_string());
|
||||
tracing::error!("Browser tried to open a popup at URL: {}", target);
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ impl ImplLifeSpanHandler for BrowserProcessLifeSpanHandlerImpl {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for BrowserProcessLifeSpanHandlerImpl {
|
||||
impl Clone for LifeSpanHandlerImpl {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
let rc_impl = &mut *self.object;
|
||||
|
|
@ -49,7 +49,7 @@ impl Clone for BrowserProcessLifeSpanHandlerImpl {
|
|||
Self { object: self.object }
|
||||
}
|
||||
}
|
||||
impl Rc for BrowserProcessLifeSpanHandlerImpl {
|
||||
impl Rc for LifeSpanHandlerImpl {
|
||||
fn as_base(&self) -> &cef_base_ref_counted_t {
|
||||
unsafe {
|
||||
let base = &*self.object;
|
||||
|
|
@ -57,7 +57,7 @@ impl Rc for BrowserProcessLifeSpanHandlerImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl WrapLifeSpanHandler for BrowserProcessLifeSpanHandlerImpl {
|
||||
impl WrapLifeSpanHandler for LifeSpanHandlerImpl {
|
||||
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_life_span_handler_t, Self>) {
|
||||
self.object = object;
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ impl<H: CefEventHandler> LoadHandlerImpl<H> {
|
|||
}
|
||||
|
||||
impl<H: CefEventHandler> ImplLoadHandler for LoadHandlerImpl<H> {
|
||||
fn on_loading_state_change(&self, browser: Option<&mut cef::Browser>, is_loading: ::std::os::raw::c_int, _can_go_back: ::std::os::raw::c_int, _can_go_forward: ::std::os::raw::c_int) {
|
||||
fn on_loading_state_change(&self, browser: Option<&mut cef::Browser>, is_loading: std::ffi::c_int, _can_go_back: std::ffi::c_int, _can_go_forward: std::ffi::c_int) {
|
||||
let view_info = self.event_handler.view_info();
|
||||
|
||||
if let Some(browser) = browser
|
||||
|
|
@ -38,8 +38,8 @@ impl<H: CefEventHandler> ImplRenderHandler for RenderHandlerImpl<H> {
|
|||
_dirty_rect_count: usize,
|
||||
_dirty_rects: Option<&Rect>,
|
||||
buffer: *const u8,
|
||||
width: ::std::os::raw::c_int,
|
||||
height: ::std::os::raw::c_int,
|
||||
width: std::ffi::c_int,
|
||||
height: std::ffi::c_int,
|
||||
) {
|
||||
let buffer_size = (width * height * 4) as usize;
|
||||
let buffer_slice = unsafe { std::slice::from_raw_parts(buffer, buffer_size) };
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use cef::{CefString, ImplFrame, ImplRenderProcessHandler, ImplV8Context, ImplV8V
|
|||
|
||||
use crate::cef::ipc::{MessageType, UnpackMessage, UnpackedMessage};
|
||||
|
||||
use super::render_process_v8_handler::BrowserProcessV8HandlerImpl;
|
||||
use super::render_process_v8_handler::RenderProcessV8HandlerImpl;
|
||||
|
||||
pub(crate) struct RenderProcessHandlerImpl {
|
||||
object: *mut RcImpl<cef_render_process_handler_t, Self>,
|
||||
|
|
@ -22,7 +22,7 @@ impl ImplRenderProcessHandler for RenderProcessHandlerImpl {
|
|||
frame: Option<&mut cef::Frame>,
|
||||
_source_process: cef::ProcessId,
|
||||
message: Option<&mut cef::ProcessMessage>,
|
||||
) -> ::std::os::raw::c_int {
|
||||
) -> std::ffi::c_int {
|
||||
let unpacked_message = unsafe { message.and_then(|m| m.unpack()) };
|
||||
match unpacked_message {
|
||||
Some(UnpackedMessage {
|
||||
|
|
@ -77,7 +77,7 @@ 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 register_js_function = |context: &mut cef::V8Context, name: &'static str| {
|
||||
let mut v8_handler = V8Handler::new(BrowserProcessV8HandlerImpl::new());
|
||||
let mut v8_handler = V8Handler::new(RenderProcessV8HandlerImpl::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;
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ use cef::{ImplV8Handler, ImplV8Value, V8Value, WrapV8Handler, rc::Rc, v8_context
|
|||
|
||||
use crate::cef::ipc::{MessageType, SendMessage};
|
||||
|
||||
pub struct BrowserProcessV8HandlerImpl {
|
||||
pub struct RenderProcessV8HandlerImpl {
|
||||
object: *mut cef::rc::RcImpl<cef::sys::_cef_v8_handler_t, Self>,
|
||||
}
|
||||
impl BrowserProcessV8HandlerImpl {
|
||||
impl RenderProcessV8HandlerImpl {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { object: std::ptr::null_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl ImplV8Handler for BrowserProcessV8HandlerImpl {
|
||||
impl ImplV8Handler for RenderProcessV8HandlerImpl {
|
||||
fn execute(
|
||||
&self,
|
||||
name: Option<&cef::CefString>,
|
||||
|
|
@ -19,7 +19,7 @@ impl ImplV8Handler for BrowserProcessV8HandlerImpl {
|
|||
arguments: Option<&[Option<V8Value>]>,
|
||||
_retval: Option<&mut Option<V8Value>>,
|
||||
_exception: Option<&mut cef::CefString>,
|
||||
) -> ::std::os::raw::c_int {
|
||||
) -> std::ffi::c_int {
|
||||
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());
|
||||
|
|
@ -62,7 +62,7 @@ impl ImplV8Handler for BrowserProcessV8HandlerImpl {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for BrowserProcessV8HandlerImpl {
|
||||
impl Clone for RenderProcessV8HandlerImpl {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
let rc_impl = &mut *self.object;
|
||||
|
|
@ -71,7 +71,7 @@ impl Clone for BrowserProcessV8HandlerImpl {
|
|||
Self { object: self.object }
|
||||
}
|
||||
}
|
||||
impl Rc for BrowserProcessV8HandlerImpl {
|
||||
impl Rc for RenderProcessV8HandlerImpl {
|
||||
fn as_base(&self) -> &cef::sys::cef_base_ref_counted_t {
|
||||
unsafe {
|
||||
let base = &*self.object;
|
||||
|
|
@ -79,7 +79,7 @@ impl Rc for BrowserProcessV8HandlerImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl WrapV8Handler for BrowserProcessV8HandlerImpl {
|
||||
impl WrapV8Handler for RenderProcessV8HandlerImpl {
|
||||
fn wrap_rc(&mut self, object: *mut cef::rc::RcImpl<cef::sys::_cef_v8_handler_t, Self>) {
|
||||
self.object = object;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue