Skip to content

Commit 94e5c8f

Browse files
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
1 parent bb4516e commit 94e5c8f

File tree

10 files changed

+106
-42
lines changed

10 files changed

+106
-42
lines changed

desktop/src/cef/internal.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
mod browser_process_app;
22
mod browser_process_client;
33
mod browser_process_handler;
4-
mod browser_process_life_span_handler;
5-
mod browser_process_load_handler;
64

75
mod render_process_app;
86
mod render_process_handler;
97
mod render_process_v8_handler;
108

9+
mod context_menu_handler;
10+
mod display_handler;
11+
mod life_span_handler;
12+
mod load_handler;
1113
mod resource_handler;
1214
mod scheme_handler_factory;
1315

14-
mod display_handler;
15-
1616
pub(super) mod render_handler;
1717

1818
#[cfg(not(target_os = "macos"))]

desktop/src/cef/internal/browser_process_client.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use cef::rc::{Rc, RcImpl};
22
use cef::sys::{_cef_client_t, cef_base_ref_counted_t};
3-
use cef::{DisplayHandler, ImplClient, LifeSpanHandler, LoadHandler, RenderHandler, WrapClient};
3+
use cef::{ContextMenuHandler, DisplayHandler, ImplClient, LifeSpanHandler, LoadHandler, RenderHandler, WrapClient};
44

55
use crate::cef::CefEventHandler;
66
use crate::cef::ipc::{MessageType, UnpackMessage, UnpackedMessage};
77

8-
use super::browser_process_life_span_handler::BrowserProcessLifeSpanHandlerImpl;
9-
use super::browser_process_load_handler::LoadHandlerImpl;
8+
use super::context_menu_handler::ContextMenuHandlerImpl;
109
use super::display_handler::DisplayHandlerImpl;
10+
use super::life_span_handler::LifeSpanHandlerImpl;
11+
use super::load_handler::LoadHandlerImpl;
1112
use super::render_handler::RenderHandlerImpl;
1213

1314
pub(crate) struct BrowserProcessClientImpl<H: CefEventHandler> {
@@ -36,7 +37,7 @@ impl<H: CefEventHandler> ImplClient for BrowserProcessClientImpl<H> {
3637
_frame: Option<&mut cef::Frame>,
3738
_source_process: cef::ProcessId,
3839
message: Option<&mut cef::ProcessMessage>,
39-
) -> ::std::os::raw::c_int {
40+
) -> std::ffi::c_int {
4041
let unpacked_message = unsafe { message.and_then(|m| m.unpack()) };
4142
match unpacked_message {
4243
Some(UnpackedMessage {
@@ -65,13 +66,17 @@ impl<H: CefEventHandler> ImplClient for BrowserProcessClientImpl<H> {
6566
}
6667

6768
fn life_span_handler(&self) -> Option<cef::LifeSpanHandler> {
68-
Some(LifeSpanHandler::new(BrowserProcessLifeSpanHandlerImpl::new()))
69+
Some(LifeSpanHandler::new(LifeSpanHandlerImpl::new()))
6970
}
7071

7172
fn display_handler(&self) -> Option<cef::DisplayHandler> {
7273
Some(self.display_handler.clone())
7374
}
7475

76+
fn context_menu_handler(&self) -> Option<cef::ContextMenuHandler> {
77+
Some(ContextMenuHandler::new(ContextMenuHandlerImpl::new()))
78+
}
79+
7580
fn get_raw(&self) -> *mut _cef_client_t {
7681
self.object.cast()
7782
}

desktop/src/cef/internal/browser_process_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl<H: CefEventHandler> ImplBrowserProcessHandler for BrowserProcessHandlerImpl
2424
self.event_handler.schedule_cef_message_loop_work(Instant::now() + Duration::from_millis(delay_ms as u64));
2525
}
2626

27-
fn on_already_running_app_relaunch(&self, _command_line: Option<&mut cef::CommandLine>, _current_directory: Option<&CefString>) -> ::std::os::raw::c_int {
27+
fn on_already_running_app_relaunch(&self, _command_line: Option<&mut cef::CommandLine>, _current_directory: Option<&CefString>) -> std::ffi::c_int {
2828
1 // Return 1 to prevent default behavior of opening a empty browser window
2929
}
3030

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use cef::rc::{Rc, RcImpl};
2+
use cef::sys::{_cef_context_menu_handler_t, cef_base_ref_counted_t};
3+
use cef::{ImplContextMenuHandler, WrapContextMenuHandler};
4+
5+
pub(crate) struct ContextMenuHandlerImpl {
6+
object: *mut RcImpl<_cef_context_menu_handler_t, Self>,
7+
}
8+
impl ContextMenuHandlerImpl {
9+
pub(crate) fn new() -> Self {
10+
Self { object: std::ptr::null_mut() }
11+
}
12+
}
13+
14+
impl ImplContextMenuHandler for ContextMenuHandlerImpl {
15+
fn run_context_menu(
16+
&self,
17+
_browser: Option<&mut cef::Browser>,
18+
_frame: Option<&mut cef::Frame>,
19+
_params: Option<&mut cef::ContextMenuParams>,
20+
_model: Option<&mut cef::MenuModel>,
21+
_callback: Option<&mut cef::RunContextMenuCallback>,
22+
) -> std::ffi::c_int {
23+
// Prevent context menu
24+
1
25+
}
26+
27+
fn run_quick_menu(
28+
&self,
29+
_browser: Option<&mut cef::Browser>,
30+
_frame: Option<&mut cef::Frame>,
31+
_location: Option<&cef::Point>,
32+
_size: Option<&cef::Size>,
33+
_edit_state_flags: cef::QuickMenuEditStateFlags,
34+
_callback: Option<&mut cef::RunQuickMenuCallback>,
35+
) -> std::ffi::c_int {
36+
// Prevent quick menu
37+
1
38+
}
39+
40+
fn get_raw(&self) -> *mut _cef_context_menu_handler_t {
41+
self.object.cast()
42+
}
43+
}
44+
45+
impl Clone for ContextMenuHandlerImpl {
46+
fn clone(&self) -> Self {
47+
unsafe {
48+
let rc_impl = &mut *self.object;
49+
rc_impl.interface.add_ref();
50+
}
51+
Self { object: self.object }
52+
}
53+
}
54+
impl Rc for ContextMenuHandlerImpl {
55+
fn as_base(&self) -> &cef_base_ref_counted_t {
56+
unsafe {
57+
let base = &*self.object;
58+
std::mem::transmute(&base.cef_object)
59+
}
60+
}
61+
}
62+
impl WrapContextMenuHandler for ContextMenuHandlerImpl {
63+
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_context_menu_handler_t, Self>) {
64+
self.object = object;
65+
}
66+
}

desktop/src/cef/internal/display_handler.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type CefCursorHandle = cef::CursorHandle;
2525
type CefCursorHandle = *mut u8;
2626

2727
impl<H: CefEventHandler> ImplDisplayHandler for DisplayHandlerImpl<H> {
28-
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 {
28+
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 {
2929
let cursor = match cursor_type.into() {
3030
CT_POINTER => CursorIcon::Default,
3131
CT_CROSS => CursorIcon::Crosshair,
@@ -86,14 +86,7 @@ impl<H: CefEventHandler> ImplDisplayHandler for DisplayHandlerImpl<H> {
8686
1 // We handled the cursor change.
8787
}
8888

89-
fn on_console_message(
90-
&self,
91-
_browser: Option<&mut cef::Browser>,
92-
level: cef::LogSeverity,
93-
message: Option<&CefString>,
94-
source: Option<&CefString>,
95-
line: ::std::os::raw::c_int,
96-
) -> ::std::os::raw::c_int {
89+
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 {
9790
let message = message.map(|m| m.to_string()).unwrap_or_default();
9891
let source = source.map(|s| s.to_string()).unwrap_or_default();
9992
let line = line as i64;

desktop/src/cef/internal/browser_process_life_span_handler.rs renamed to desktop/src/cef/internal/life_span_handler.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,32 @@ use cef::rc::{Rc, RcImpl};
22
use cef::sys::{_cef_life_span_handler_t, cef_base_ref_counted_t};
33
use cef::{ImplLifeSpanHandler, WrapLifeSpanHandler};
44

5-
pub(crate) struct BrowserProcessLifeSpanHandlerImpl {
5+
pub(crate) struct LifeSpanHandlerImpl {
66
object: *mut RcImpl<_cef_life_span_handler_t, Self>,
77
}
8-
impl BrowserProcessLifeSpanHandlerImpl {
8+
impl LifeSpanHandlerImpl {
99
pub(crate) fn new() -> Self {
1010
Self { object: std::ptr::null_mut() }
1111
}
1212
}
1313

14-
impl ImplLifeSpanHandler for BrowserProcessLifeSpanHandlerImpl {
14+
impl ImplLifeSpanHandler for LifeSpanHandlerImpl {
1515
fn on_before_popup(
1616
&self,
1717
_browser: Option<&mut cef::Browser>,
1818
_frame: Option<&mut cef::Frame>,
19-
_popup_id: ::std::os::raw::c_int,
19+
_popup_id: std::ffi::c_int,
2020
target_url: Option<&cef::CefString>,
2121
_target_frame_name: Option<&cef::CefString>,
2222
_target_disposition: cef::WindowOpenDisposition,
23-
_user_gesture: ::std::os::raw::c_int,
23+
_user_gesture: std::ffi::c_int,
2424
_popup_features: Option<&cef::PopupFeatures>,
2525
_window_info: Option<&mut cef::WindowInfo>,
2626
_client: Option<&mut Option<cef::Client>>,
2727
_settings: Option<&mut cef::BrowserSettings>,
2828
_extra_info: Option<&mut Option<cef::DictionaryValue>>,
29-
_no_javascript_access: Option<&mut ::std::os::raw::c_int>,
30-
) -> ::std::os::raw::c_int {
29+
_no_javascript_access: Option<&mut std::ffi::c_int>,
30+
) -> std::ffi::c_int {
3131
let target = target_url.map(|url| url.to_string()).unwrap_or("unknown".to_string());
3232
tracing::error!("Browser tried to open a popup at URL: {}", target);
3333

@@ -40,7 +40,7 @@ impl ImplLifeSpanHandler for BrowserProcessLifeSpanHandlerImpl {
4040
}
4141
}
4242

43-
impl Clone for BrowserProcessLifeSpanHandlerImpl {
43+
impl Clone for LifeSpanHandlerImpl {
4444
fn clone(&self) -> Self {
4545
unsafe {
4646
let rc_impl = &mut *self.object;
@@ -49,15 +49,15 @@ impl Clone for BrowserProcessLifeSpanHandlerImpl {
4949
Self { object: self.object }
5050
}
5151
}
52-
impl Rc for BrowserProcessLifeSpanHandlerImpl {
52+
impl Rc for LifeSpanHandlerImpl {
5353
fn as_base(&self) -> &cef_base_ref_counted_t {
5454
unsafe {
5555
let base = &*self.object;
5656
std::mem::transmute(&base.cef_object)
5757
}
5858
}
5959
}
60-
impl WrapLifeSpanHandler for BrowserProcessLifeSpanHandlerImpl {
60+
impl WrapLifeSpanHandler for LifeSpanHandlerImpl {
6161
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_life_span_handler_t, Self>) {
6262
self.object = object;
6363
}

desktop/src/cef/internal/browser_process_load_handler.rs renamed to desktop/src/cef/internal/load_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl<H: CefEventHandler> LoadHandlerImpl<H> {
1818
}
1919

2020
impl<H: CefEventHandler> ImplLoadHandler for LoadHandlerImpl<H> {
21-
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) {
21+
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) {
2222
let view_info = self.event_handler.view_info();
2323

2424
if let Some(browser) = browser

desktop/src/cef/internal/render_handler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ impl<H: CefEventHandler> ImplRenderHandler for RenderHandlerImpl<H> {
3838
_dirty_rect_count: usize,
3939
_dirty_rects: Option<&Rect>,
4040
buffer: *const u8,
41-
width: ::std::os::raw::c_int,
42-
height: ::std::os::raw::c_int,
41+
width: std::ffi::c_int,
42+
height: std::ffi::c_int,
4343
) {
4444
let buffer_size = (width * height * 4) as usize;
4545
let buffer_slice = unsafe { std::slice::from_raw_parts(buffer, buffer_size) };

desktop/src/cef/internal/render_process_handler.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use cef::{CefString, ImplFrame, ImplRenderProcessHandler, ImplV8Context, ImplV8V
44

55
use crate::cef::ipc::{MessageType, UnpackMessage, UnpackedMessage};
66

7-
use super::render_process_v8_handler::BrowserProcessV8HandlerImpl;
7+
use super::render_process_v8_handler::RenderProcessV8HandlerImpl;
88

99
pub(crate) struct RenderProcessHandlerImpl {
1010
object: *mut RcImpl<cef_render_process_handler_t, Self>,
@@ -22,7 +22,7 @@ impl ImplRenderProcessHandler for RenderProcessHandlerImpl {
2222
frame: Option<&mut cef::Frame>,
2323
_source_process: cef::ProcessId,
2424
message: Option<&mut cef::ProcessMessage>,
25-
) -> ::std::os::raw::c_int {
25+
) -> std::ffi::c_int {
2626
let unpacked_message = unsafe { message.and_then(|m| m.unpack()) };
2727
match unpacked_message {
2828
Some(UnpackedMessage {
@@ -77,7 +77,7 @@ impl ImplRenderProcessHandler for RenderProcessHandlerImpl {
7777

7878
fn on_context_created(&self, _browser: Option<&mut cef::Browser>, _frame: Option<&mut cef::Frame>, context: Option<&mut cef::V8Context>) {
7979
let register_js_function = |context: &mut cef::V8Context, name: &'static str| {
80-
let mut v8_handler = V8Handler::new(BrowserProcessV8HandlerImpl::new());
80+
let mut v8_handler = V8Handler::new(RenderProcessV8HandlerImpl::new());
8181
let Some(mut function) = v8_value_create_function(Some(&CefString::from(name)), Some(&mut v8_handler)) else {
8282
tracing::error!("Failed to create V8 function {name}");
8383
return;

desktop/src/cef/internal/render_process_v8_handler.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@ use cef::{ImplV8Handler, ImplV8Value, V8Value, WrapV8Handler, rc::Rc, v8_context
22

33
use crate::cef::ipc::{MessageType, SendMessage};
44

5-
pub struct BrowserProcessV8HandlerImpl {
5+
pub struct RenderProcessV8HandlerImpl {
66
object: *mut cef::rc::RcImpl<cef::sys::_cef_v8_handler_t, Self>,
77
}
8-
impl BrowserProcessV8HandlerImpl {
8+
impl RenderProcessV8HandlerImpl {
99
pub(crate) fn new() -> Self {
1010
Self { object: std::ptr::null_mut() }
1111
}
1212
}
1313

14-
impl ImplV8Handler for BrowserProcessV8HandlerImpl {
14+
impl ImplV8Handler for RenderProcessV8HandlerImpl {
1515
fn execute(
1616
&self,
1717
name: Option<&cef::CefString>,
1818
_object: Option<&mut V8Value>,
1919
arguments: Option<&[Option<V8Value>]>,
2020
_retval: Option<&mut Option<V8Value>>,
2121
_exception: Option<&mut cef::CefString>,
22-
) -> ::std::os::raw::c_int {
22+
) -> std::ffi::c_int {
2323
match name.map(|s| s.to_string()).unwrap_or_default().as_str() {
2424
"initializeNativeCommunication" => {
2525
v8_context_get_current_context().send_message(MessageType::Initialized, vec![0u8].as_slice());
@@ -62,7 +62,7 @@ impl ImplV8Handler for BrowserProcessV8HandlerImpl {
6262
}
6363
}
6464

65-
impl Clone for BrowserProcessV8HandlerImpl {
65+
impl Clone for RenderProcessV8HandlerImpl {
6666
fn clone(&self) -> Self {
6767
unsafe {
6868
let rc_impl = &mut *self.object;
@@ -71,15 +71,15 @@ impl Clone for BrowserProcessV8HandlerImpl {
7171
Self { object: self.object }
7272
}
7373
}
74-
impl Rc for BrowserProcessV8HandlerImpl {
74+
impl Rc for RenderProcessV8HandlerImpl {
7575
fn as_base(&self) -> &cef::sys::cef_base_ref_counted_t {
7676
unsafe {
7777
let base = &*self.object;
7878
std::mem::transmute(&base.cef_object)
7979
}
8080
}
8181
}
82-
impl WrapV8Handler for BrowserProcessV8HandlerImpl {
82+
impl WrapV8Handler for RenderProcessV8HandlerImpl {
8383
fn wrap_rc(&mut self, object: *mut cef::rc::RcImpl<cef::sys::_cef_v8_handler_t, Self>) {
8484
self.object = object;
8585
}

0 commit comments

Comments
 (0)