pub mod app;
pub mod audio;
pub mod backend;
pub(crate) mod convert;
pub mod handlers;
pub mod host;
pub mod new_tab;
pub mod osr;
pub mod permissions;
pub mod view_source_scheme;
pub use app::{
BuffrApp, device_scale_factor, force_renderer_accessibility_enabled, profile_paths,
set_device_scale_factor, set_force_renderer_accessibility,
take_scheduled_message_pump_delay_ms,
};
pub use audio::{
AudioEvent, AudioEventQueue, AudioState, AudioStateSink, any_audio_active, drain_audio_events,
new_audio_event_queue, new_audio_state_sink,
};
pub use backend::{CefBackend, CefEngineSinks};
pub use host::{BrowserHost, ClipboardReader, Tab, TabSession};
pub use buffr_engine::HintStatus;
pub use buffr_engine::ProfilePaths;
pub use buffr_engine::{BrowserEngine, TabId, TabSummary};
pub use new_tab::{
NEW_TAB_HTML_TEMPLATE, NEW_TAB_KEYBINDS_MARKER, NEW_TAB_SPLASH_ART_MARKER, NEW_TAB_URL,
NewTabHtmlProvider, SETTINGS_URL, SettingsHtmlProvider, register_buffr_handler_factory,
register_buffr_handler_factory_static, register_buffr_handler_factory_with_settings,
register_buffr_scheme, settings_html,
};
pub use osr::{OsrFrame, OsrViewState, PopupFrameMap, SharedOsrFrame, SharedOsrViewState};
pub use buffr_engine::{
PendingPopupAlloc, PopupCloseSink, PopupCreateSink, PopupCreated, PopupQueue,
drain_popup_closes, drain_popup_creates, drain_popup_urls, new_pending_popup_alloc,
new_popup_close_sink, new_popup_create_sink, new_popup_queue,
};
pub use permissions::{
CefCallbackRegistry, PendingPermission, PermissionsQueue, PromptOutcome,
capabilities_for_media_mask, capabilities_for_request_mask,
drain_registry_with_defer as drain_permissions_registry_with_defer,
drain_with_defer as drain_permissions_with_defer, enqueue_to_both,
new_queue as new_permissions_queue, next_resolve_id, peek_front as peek_permission_front,
pop_front as pop_permission_front, precheck as precheck_permission,
queue_len as permissions_queue_len,
};
pub use view_source_scheme::{register_buffr_src_handler_factory, register_buffr_src_scheme};
pub fn init_cef_api() {
let _ = cef::api_hash(cef::sys::CEF_API_VERSION_LAST, 0);
}
pub fn execute_subprocess() -> i32 {
init_cef_api();
let args = cef::args::Args::new();
let mut app = BuffrApp::new();
cef::execute_process(
Some(args.as_main_args()),
Some(&mut app),
std::ptr::null_mut(),
)
}
pub fn cef_initialize(cache_path: &str, app: &mut cef::App) -> Result<(), String> {
let args = cef::args::Args::new();
#[allow(unused_mut)]
let mut settings = cef::Settings {
no_sandbox: 1,
multi_threaded_message_loop: 0,
root_cache_path: cef::CefString::from(cache_path),
windowless_rendering_enabled: 1,
..Default::default()
};
#[cfg(target_os = "macos")]
{
settings.external_message_pump = 1;
if let Ok(exe) = std::env::current_exe() {
if !exe.components().any(|c| c.as_os_str() == "Contents") {
if let Some(exe_dir) = exe.parent() {
let fw = exe_dir.join("../Frameworks/Chromium Embedded Framework.framework");
if let Ok(fw) = fw.canonicalize() {
let res = fw.join("Resources");
settings.browser_subprocess_path =
cef::CefString::from(exe.to_string_lossy().as_ref());
settings.framework_dir_path =
cef::CefString::from(fw.to_string_lossy().as_ref());
settings.resources_dir_path =
cef::CefString::from(res.to_string_lossy().as_ref());
}
}
}
}
}
let ok = cef::initialize(
Some(args.as_main_args()),
Some(&settings),
Some(app),
std::ptr::null_mut(),
);
if ok != 1 {
return Err(format!("cef::initialize returned {ok} (expected 1)"));
}
Ok(())
}
pub fn cef_shutdown() {
cef::shutdown();
}
pub fn do_message_loop_work() {
cef::do_message_loop_work();
}
pub fn delete_all_cookies() {
let Some(manager) = cef::cookie_manager_get_global_manager(None) else {
tracing::warn!("delete_all_cookies: cookie_manager_get_global_manager returned None");
return;
};
use cef::ImplCookieManager;
let submitted = manager.delete_cookies(None, None, None);
if submitted == 0 {
tracing::warn!("delete_all_cookies: delete_cookies returned 0 (synchronous failure)");
} else {
tracing::info!("delete_all_cookies: delete dispatched");
}
let _ = manager.flush_store(None);
}
pub fn execute_process_for_subprocess() -> i32 {
init_cef_api();
let args = cef::args::Args::new();
let mut app = BuffrApp::new();
cef::execute_process(
Some(args.as_main_args()),
Some(&mut app),
std::ptr::null_mut(),
)
}
pub fn load_cef_library(exe: &std::path::Path, is_helper: bool) -> Result<(), String> {
#[cfg(target_os = "macos")]
{
let loader = cef::library_loader::LibraryLoader::new(exe, is_helper);
if !loader.load() {
return Err(format!(
"CEF LibraryLoader failed (exe={}, is_helper={is_helper})",
exe.display()
));
}
std::mem::forget(loader);
}
#[cfg(not(target_os = "macos"))]
{
let _ = (exe, is_helper); }
Ok(())
}