Remove CefHandler

This commit is contained in:
Adam 2025-07-23 19:55:59 -07:00
parent 22391cae13
commit 368fa51260
6 changed files with 60 additions and 99 deletions

View file

@ -7,11 +7,6 @@ use std::sync::{Arc, Mutex, MutexGuard, PoisonError};
pub(crate) use context::{Context, InitError, Initialized, Setup, SetupError};
pub(crate) trait CefEventHandler: Clone {
fn window_size(&self) -> WindowSize;
fn on_paint(&self, buffer: *const u8, width: u32, height: u32);
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct WindowSize {
pub(crate) width: u32,

View file

@ -3,10 +3,14 @@ use cef::{App, BrowserSettings, Client, DictionaryValue, ImplBrowser, ImplBrowse
use cef::{Browser, CefString, Settings, api_hash, args::Args, execute_process};
use thiserror::Error;
use winit::event::WindowEvent;
use winit::event_loop::EventLoopProxy;
use crate::WinitEvent;
use crate::cef::WindowSizeHandle;
use super::input;
use super::input::InputState;
use super::scheme_handler::{FRONTEND_DOMAIN, GRAPHITE_SCHEME};
use super::{CefEventHandler, input};
use super::internal::{AppImpl, ClientImpl, NonBrowserAppImpl, RenderHandlerImpl};
@ -57,7 +61,7 @@ impl Context<Setup> {
})
}
pub(crate) fn init(self, event_handler: impl CefEventHandler) -> Result<Context<Initialized>, InitError> {
pub(crate) fn init(self, event_loop_proxy: EventLoopProxy<WinitEvent>, shared_window_size: WindowSizeHandle) -> Result<Context<Initialized>, InitError> {
let settings = Settings {
windowless_rendering_enabled: 1,
multi_threaded_message_loop: 0,
@ -66,14 +70,14 @@ impl Context<Setup> {
};
// Attention! Wrapping this in an extra App is necessary, otherwise the program still compiles but segfaults
let mut cef_app = App::new(AppImpl::new(event_handler.clone()));
let mut cef_app = App::new(AppImpl::new());
let result = initialize(Some(self.args.as_main_args()), Some(&settings), Some(&mut cef_app), std::ptr::null_mut());
if result != 1 {
return Err(InitError::InitializationFailed);
}
let render_handler = RenderHandlerImpl::new(event_handler.clone());
let render_handler = RenderHandlerImpl::new(event_loop_proxy, shared_window_size);
let mut client = Client::new(ClientImpl::new(RenderHandler::new(render_handler)));
let url = CefString::from(format!("{GRAPHITE_SCHEME}://{FRONTEND_DOMAIN}/").as_str());

View file

@ -2,27 +2,22 @@ use cef::rc::{Rc, RcImpl};
use cef::sys::{_cef_app_t, cef_base_ref_counted_t};
use cef::{BrowserProcessHandler, ImplApp, SchemeRegistrar, WrapApp};
use crate::cef::CefEventHandler;
use crate::cef::scheme_handler::GraphiteSchemeHandlerFactory;
use super::browser_process_handler::BrowserProcessHandlerImpl;
pub(crate) struct AppImpl<H: CefEventHandler> {
pub(crate) struct AppImpl {
object: *mut RcImpl<_cef_app_t, Self>,
event_handler: H,
}
impl<H: CefEventHandler> AppImpl<H> {
pub(crate) fn new(event_handler: H) -> Self {
Self {
object: std::ptr::null_mut(),
event_handler,
}
impl AppImpl {
pub(crate) fn new() -> Self {
Self { object: std::ptr::null_mut() }
}
}
impl<H: CefEventHandler> ImplApp for AppImpl<H> {
impl ImplApp for AppImpl {
fn browser_process_handler(&self) -> Option<BrowserProcessHandler> {
Some(BrowserProcessHandler::new(BrowserProcessHandlerImpl::new(self.event_handler.clone())))
Some(BrowserProcessHandler::new(BrowserProcessHandlerImpl::new()))
}
fn on_register_custom_schemes(&self, registrar: Option<&mut SchemeRegistrar>) {
@ -34,19 +29,16 @@ impl<H: CefEventHandler> ImplApp for AppImpl<H> {
}
}
impl<H: CefEventHandler> Clone for AppImpl<H> {
impl Clone for AppImpl {
fn clone(&self) -> Self {
unsafe {
let rc_impl = &mut *self.object;
rc_impl.interface.add_ref();
}
Self {
object: self.object,
event_handler: self.event_handler.clone(),
}
Self { object: self.object }
}
}
impl<H: CefEventHandler> Rc for AppImpl<H> {
impl Rc for AppImpl {
fn as_base(&self) -> &cef_base_ref_counted_t {
unsafe {
let base = &*self.object;
@ -54,7 +46,7 @@ impl<H: CefEventHandler> Rc for AppImpl<H> {
}
}
}
impl<H: CefEventHandler> WrapApp for AppImpl<H> {
impl WrapApp for AppImpl {
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_app_t, Self>) {
self.object = object;
}

View file

@ -2,23 +2,18 @@ use cef::rc::{Rc, RcImpl};
use cef::sys::{_cef_browser_process_handler_t, cef_base_ref_counted_t, cef_browser_process_handler_t};
use cef::{CefString, ImplBrowserProcessHandler, SchemeHandlerFactory, WrapBrowserProcessHandler};
use crate::cef::CefEventHandler;
use crate::cef::scheme_handler::{GRAPHITE_SCHEME, GraphiteSchemeHandlerFactory};
pub(crate) struct BrowserProcessHandlerImpl<H: CefEventHandler> {
pub(crate) struct BrowserProcessHandlerImpl {
object: *mut RcImpl<cef_browser_process_handler_t, Self>,
event_handler: H,
}
impl<H: CefEventHandler> BrowserProcessHandlerImpl<H> {
pub(crate) fn new(event_handler: H) -> Self {
Self {
object: std::ptr::null_mut(),
event_handler,
}
impl BrowserProcessHandlerImpl {
pub(crate) fn new() -> Self {
Self { object: std::ptr::null_mut() }
}
}
impl<H: CefEventHandler> ImplBrowserProcessHandler for BrowserProcessHandlerImpl<H> {
impl ImplBrowserProcessHandler for BrowserProcessHandlerImpl {
fn on_context_initialized(&self) {
cef::register_scheme_handler_factory(Some(&CefString::from(GRAPHITE_SCHEME)), None, Some(&mut SchemeHandlerFactory::new(GraphiteSchemeHandlerFactory::new())));
}
@ -28,19 +23,16 @@ impl<H: CefEventHandler> ImplBrowserProcessHandler for BrowserProcessHandlerImpl
}
}
impl<H: CefEventHandler> Clone for BrowserProcessHandlerImpl<H> {
impl Clone for BrowserProcessHandlerImpl {
fn clone(&self) -> Self {
unsafe {
let rc_impl = &mut *self.object;
rc_impl.interface.add_ref();
}
Self {
object: self.object,
event_handler: self.event_handler.clone(),
}
Self { object: self.object }
}
}
impl<H: CefEventHandler> Rc for BrowserProcessHandlerImpl<H> {
impl Rc for BrowserProcessHandlerImpl {
fn as_base(&self) -> &cef_base_ref_counted_t {
unsafe {
let base = &*self.object;
@ -48,7 +40,7 @@ impl<H: CefEventHandler> Rc for BrowserProcessHandlerImpl<H> {
}
}
}
impl<H: CefEventHandler> WrapBrowserProcessHandler for BrowserProcessHandlerImpl<H> {
impl WrapBrowserProcessHandler for BrowserProcessHandlerImpl {
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_browser_process_handler_t, Self>) {
self.object = object;
}

View file

@ -1,31 +1,38 @@
use cef::rc::{Rc, RcImpl};
use cef::sys::{_cef_render_handler_t, cef_base_ref_counted_t};
use cef::{Browser, ImplRenderHandler, PaintElementType, Rect, WrapRenderHandler};
use winit::event_loop::EventLoopProxy;
use crate::cef::CefEventHandler;
use crate::WinitEvent;
use crate::cef::WindowSizeHandle;
use crate::render::FrameBuffer;
pub(crate) struct RenderHandlerImpl<H: CefEventHandler> {
pub(crate) struct RenderHandlerImpl {
object: *mut RcImpl<_cef_render_handler_t, Self>,
event_handler: H,
event_loop_proxy: EventLoopProxy<WinitEvent>,
window_size: WindowSizeHandle,
}
impl<H: CefEventHandler> RenderHandlerImpl<H> {
pub(crate) fn new(event_handler: H) -> Self {
impl RenderHandlerImpl {
pub(crate) fn new(event_loop_proxy: EventLoopProxy<WinitEvent>, window_size: WindowSizeHandle) -> Self {
Self {
object: std::ptr::null_mut(),
event_handler,
event_loop_proxy,
window_size,
}
}
}
impl<H: CefEventHandler> ImplRenderHandler for RenderHandlerImpl<H> {
impl ImplRenderHandler for RenderHandlerImpl {
fn view_rect(&self, _browser: Option<&mut Browser>, rect: Option<&mut Rect>) {
if let Some(rect) = rect {
let view = self.event_handler.window_size();
*rect = Rect {
x: 0,
y: 0,
width: view.width as i32,
height: view.height as i32,
};
let _ = self.window_size.with(|window_size| {
*rect = Rect {
x: 0,
y: 0,
width: window_size.as_ref().map(|w| w.width).unwrap_or(1) as i32,
height: window_size.as_ref().map(|w| w.height).unwrap_or(1) as i32,
};
});
}
}
@ -39,7 +46,11 @@ impl<H: CefEventHandler> ImplRenderHandler for RenderHandlerImpl<H> {
width: ::std::os::raw::c_int,
height: ::std::os::raw::c_int,
) {
self.event_handler.on_paint(buffer, width as u32, height as u32);
let buffer_size = (width * height * 4) as usize;
let buffer_slice = unsafe { std::slice::from_raw_parts(buffer, buffer_size) };
let frame_buffer = FrameBuffer::new(buffer_slice.to_vec(), width as u32, height as u32).expect("Failed to create frame buffer");
let _ = self.event_loop_proxy.send_event(WinitEvent::UIUpdate { frame_buffer });
}
fn get_raw(&self) -> *mut _cef_render_handler_t {
@ -47,7 +58,7 @@ impl<H: CefEventHandler> ImplRenderHandler for RenderHandlerImpl<H> {
}
}
impl<H: CefEventHandler> Clone for RenderHandlerImpl<H> {
impl Clone for RenderHandlerImpl {
fn clone(&self) -> Self {
unsafe {
let rc_impl = &mut *self.object;
@ -55,11 +66,12 @@ impl<H: CefEventHandler> Clone for RenderHandlerImpl<H> {
}
Self {
object: self.object,
event_handler: self.event_handler.clone(),
event_loop_proxy: self.event_loop_proxy.clone(),
window_size: self.window_size.clone(),
}
}
}
impl<H: CefEventHandler> Rc for RenderHandlerImpl<H> {
impl Rc for RenderHandlerImpl {
fn as_base(&self) -> &cef_base_ref_counted_t {
unsafe {
let base = &*self.object;
@ -67,7 +79,7 @@ impl<H: CefEventHandler> Rc for RenderHandlerImpl<H> {
}
}
}
impl<H: CefEventHandler> WrapRenderHandler for RenderHandlerImpl<H> {
impl WrapRenderHandler for RenderHandlerImpl {
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_render_handler_t, Self>) {
self.object = object;
}

View file

@ -2,7 +2,7 @@ use std::fmt::Debug;
use std::process::exit;
use tracing_subscriber::EnvFilter;
use winit::event_loop::{EventLoop, EventLoopProxy};
use winit::event_loop::EventLoop;
mod cef;
use cef::Setup;
@ -28,40 +28,6 @@ pub(crate) enum WinitEvent {
// ViewportUpdate { texture: wgpu::TextureView },
}
#[derive(Clone)]
struct CefHandler {
event_loop_proxy: EventLoopProxy<WinitEvent>,
window_state: WindowSizeHandle,
}
impl CefHandler {
fn new(event_loop_proxy: EventLoopProxy<WinitEvent>, window_state: WindowSizeHandle) -> Self {
Self { event_loop_proxy, window_state }
}
}
impl cef::CefEventHandler for CefHandler {
fn window_size(&self) -> cef::WindowSize {
let mut window_size = cef::WindowSize::new(1, 1);
self.window_state
.with(|s| {
if let Some(s) = s {
window_size = cef::WindowSize::new(s.width as u32, s.height as u32);
}
})
.unwrap();
window_size
}
fn on_paint(&self, buffer: *const u8, width: u32, height: u32) {
let buffer_size = (width * height * 4) as usize;
let buffer_slice = unsafe { std::slice::from_raw_parts(buffer, buffer_size) };
let frame_buffer = FrameBuffer::new(buffer_slice.to_vec(), width, height).expect("Failed to create frame buffer");
let _ = self.event_loop_proxy.send_event(WinitEvent::UIUpdate { frame_buffer });
}
}
fn main() {
tracing_subscriber::fmt().with_env_filter(EnvFilter::from_default_env()).init();
@ -78,7 +44,7 @@ fn main() {
let event_loop = EventLoop::<WinitEvent>::with_user_event().build().unwrap();
let cef_context = match cef_context.init(CefHandler::new(event_loop.create_proxy(), shared_window_data.clone())) {
let cef_context = match cef_context.init(event_loop.create_proxy(), shared_window_data.clone()) {
Ok(c) => c,
Err(cef::InitError::InitializationFailed) => {
tracing::error!("Cef initialization failed");