feat: Add configurable CEF command line flags (#16)
## Summary
- Add CommandLineConfig struct for CEF command line switches
- Use direct struct initialization with optional helper methods
- Change default to secure: only use-mock-keychain enabled on macOS debug builds
- Add comprehensive documentation with usage examples
## Usage
```rust
use bevy_cef::prelude::*;
// Default (secure, includes use-mock-keychain on macOS debug)
app.add_plugins((DefaultPlugins, CefPlugin::default()));
// Add switches while preserving defaults (recommended)
app.add_plugins((
DefaultPlugins,
CefPlugin {
command_line_config: CommandLineConfig::default()
.with_switch("disable-gpu")
.with_switch_value("remote-debugging-port", "9222"),
},
));
// Full customization with direct initialization
app.add_plugins((
DefaultPlugins,
CefPlugin {
command_line_config: CommandLineConfig {
switches: vec!["disable-gpu"],
switch_values: vec![("remote-debugging-port", "9222")],
},
},
));
```
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,3 +2,5 @@ target/
|
||||
.idea/
|
||||
book/
|
||||
.DS_Store**/.DS_Store
|
||||
.claude/memo.md
|
||||
docs/plans/
|
||||
@@ -2,6 +2,7 @@ mod app;
|
||||
mod browser_process_handler;
|
||||
mod browsers;
|
||||
mod client_handler;
|
||||
mod command_line_config;
|
||||
mod context_menu_handler;
|
||||
mod display_handler;
|
||||
mod localhost;
|
||||
@@ -13,6 +14,7 @@ pub use app::*;
|
||||
pub use browser_process_handler::*;
|
||||
pub use browsers::*;
|
||||
pub use client_handler::*;
|
||||
pub use command_line_config::*;
|
||||
pub use context_menu_handler::*;
|
||||
pub use localhost::*;
|
||||
pub use message_pump::*;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::browser_process::CommandLineConfig;
|
||||
use crate::browser_process::MessageLoopTimer;
|
||||
use crate::browser_process::browser_process_handler::BrowserProcessHandlerBuilder;
|
||||
use crate::util::{SCHEME_CEF, cef_scheme_flags};
|
||||
@@ -15,13 +16,18 @@ use std::sync::mpsc::Sender;
|
||||
pub struct BrowserProcessAppBuilder {
|
||||
object: *mut RcImpl<_cef_app_t, Self>,
|
||||
message_loop_working_requester: Sender<MessageLoopTimer>,
|
||||
config: CommandLineConfig,
|
||||
}
|
||||
|
||||
impl BrowserProcessAppBuilder {
|
||||
pub fn build(message_loop_working_requester: Sender<MessageLoopTimer>) -> cef::App {
|
||||
pub fn build(
|
||||
message_loop_working_requester: Sender<MessageLoopTimer>,
|
||||
config: CommandLineConfig,
|
||||
) -> cef::App {
|
||||
cef::App::new(Self {
|
||||
object: core::ptr::null_mut(),
|
||||
message_loop_working_requester,
|
||||
config,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -36,6 +42,7 @@ impl Clone for BrowserProcessAppBuilder {
|
||||
Self {
|
||||
object,
|
||||
message_loop_working_requester: self.message_loop_working_requester.clone(),
|
||||
config: self.config.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,10 +65,14 @@ impl ImplApp for BrowserProcessAppBuilder {
|
||||
let Some(command_line) = command_line else {
|
||||
return;
|
||||
};
|
||||
command_line.append_switch(Some(&"use-mock-keychain".into()));
|
||||
// command_line.append_switch(Some(&"disable-gpu".into()));
|
||||
// command_line.append_switch(Some(&"disable-gpu-compositing".into()));
|
||||
// command_line.append_switch(Some(&" disable-gpu-shader-disk-cache".into()));
|
||||
|
||||
for switch in &self.config.switches {
|
||||
command_line.append_switch(Some(&(*switch).into()));
|
||||
}
|
||||
|
||||
for (name, value) in &self.config.switch_values {
|
||||
command_line.append_switch_with_value(Some(&(*name).into()), Some(&(*value).into()));
|
||||
}
|
||||
}
|
||||
|
||||
fn on_register_custom_schemes(&self, registrar: Option<&mut SchemeRegistrar>) {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/// Configuration for CEF command line switches.
|
||||
///
|
||||
/// Used to customize CEF behavior at startup.
|
||||
///
|
||||
/// # Default Switches
|
||||
///
|
||||
/// On macOS debug builds, the following switches are enabled by default:
|
||||
/// - `use-mock-keychain`: Uses a mock keychain for testing
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// use bevy_cef::prelude::*;
|
||||
///
|
||||
/// // Add switches while preserving defaults (recommended)
|
||||
/// let config = CommandLineConfig::default()
|
||||
/// .with_switch("disable-gpu")
|
||||
/// .with_switch_value("remote-debugging-port", "9222");
|
||||
///
|
||||
/// // Or use direct initialization (replaces defaults)
|
||||
/// let config = CommandLineConfig {
|
||||
/// switches: vec!["disable-gpu"],
|
||||
/// switch_values: vec![("remote-debugging-port", "9222")],
|
||||
/// };
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CommandLineConfig {
|
||||
pub switches: Vec<&'static str>,
|
||||
pub switch_values: Vec<(&'static str, &'static str)>,
|
||||
}
|
||||
|
||||
impl Default for CommandLineConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
switches: vec![
|
||||
#[cfg(all(target_os = "macos", debug_assertions))]
|
||||
"use-mock-keychain",
|
||||
],
|
||||
switch_values: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandLineConfig {
|
||||
/// Add a command line switch (e.g., "disable-gpu", "disable-web-security").
|
||||
pub fn with_switch(mut self, name: &'static str) -> Self {
|
||||
self.switches.push(name);
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a command line switch with a value (e.g., "remote-debugging-port", "9222").
|
||||
pub fn with_switch_value(mut self, name: &'static str, value: &'static str) -> Self {
|
||||
self.switch_values.push((name, value));
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ fn main() {
|
||||
.add_plugins((
|
||||
DefaultPlugins,
|
||||
RemotePlugin::default().with_method("greet", greet),
|
||||
CefPlugin,
|
||||
CefPlugin::default(),
|
||||
))
|
||||
.add_systems(
|
||||
Startup,
|
||||
|
||||
@@ -12,7 +12,7 @@ fn main() {
|
||||
App::new()
|
||||
.add_plugins((
|
||||
DefaultPlugins,
|
||||
CefPlugin,
|
||||
CefPlugin::default(),
|
||||
WebviewExtendMaterialPlugin::<CustomExtension>::default(),
|
||||
))
|
||||
.add_systems(Startup, (spawn_camera, spawn_webview))
|
||||
|
||||
@@ -10,7 +10,7 @@ use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_plugins((DefaultPlugins, CefPlugin::default()))
|
||||
.add_systems(
|
||||
Startup,
|
||||
(spawn_camera, spawn_directional_light, spawn_webview),
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_plugins((DefaultPlugins, CefPlugin::default()))
|
||||
.add_systems(
|
||||
Startup,
|
||||
(spawn_camera, spawn_directional_light, spawn_webview),
|
||||
|
||||
@@ -8,7 +8,7 @@ fn main() {
|
||||
App::new()
|
||||
.add_plugins((
|
||||
DefaultPlugins,
|
||||
CefPlugin,
|
||||
CefPlugin::default(),
|
||||
JsEmitEventPlugin::<Message>::default(),
|
||||
))
|
||||
.add_systems(
|
||||
|
||||
@@ -11,7 +11,7 @@ use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_plugins((DefaultPlugins, CefPlugin::default()))
|
||||
.add_systems(
|
||||
Startup,
|
||||
(spawn_camera, spawn_directional_light, spawn_webview),
|
||||
|
||||
@@ -7,7 +7,7 @@ use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_plugins((DefaultPlugins, CefPlugin::default()))
|
||||
.add_systems(
|
||||
Startup,
|
||||
(spawn_camera, spawn_directional_light, spawn_webview),
|
||||
|
||||
@@ -5,7 +5,7 @@ use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_plugins((DefaultPlugins, CefPlugin::default()))
|
||||
.add_systems(
|
||||
Startup,
|
||||
(spawn_camera, spawn_directional_light, spawn_webview),
|
||||
|
||||
@@ -5,7 +5,7 @@ use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_plugins((DefaultPlugins, CefPlugin::default()))
|
||||
.add_systems(Startup, (spawn_camera_2d, spawn_sprite_webview))
|
||||
.run();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use bevy_cef::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, CefPlugin))
|
||||
.add_plugins((DefaultPlugins, CefPlugin::default()))
|
||||
.add_systems(
|
||||
Startup,
|
||||
(spawn_camera, spawn_directional_light, spawn_webview),
|
||||
|
||||
@@ -8,7 +8,9 @@ use cef::{Settings, api_hash, execute_process, initialize, shutdown, sys};
|
||||
///
|
||||
/// - Windows and Linux: Support [`multi_threaded_message_loop`](https://cef-builds.spotifycdn.com/docs/106.1/structcef__settings__t.html#a518ac90db93ca5133a888faa876c08e0), so it is used.
|
||||
/// - macOS: Calls [`CefDoMessageLoopWork`](https://cef-builds.spotifycdn.com/docs/106.1/cef__app_8h.html#a830ae43dcdffcf4e719540204cefdb61) every frame.
|
||||
pub struct MessageLoopPlugin;
|
||||
pub struct MessageLoopPlugin {
|
||||
pub config: CommandLineConfig,
|
||||
}
|
||||
|
||||
impl Plugin for MessageLoopPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
@@ -19,7 +21,7 @@ impl Plugin for MessageLoopPlugin {
|
||||
let args = Args::new();
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
|
||||
let mut cef_app = BrowserProcessAppBuilder::build(tx);
|
||||
let mut cef_app = BrowserProcessAppBuilder::build(tx, self.config.clone());
|
||||
let ret = execute_process(
|
||||
Some(args.as_main_args()),
|
||||
Some(&mut cef_app),
|
||||
|
||||
11
src/lib.rs
11
src/lib.rs
@@ -16,21 +16,28 @@ use crate::mute::AudioMutePlugin;
|
||||
use crate::prelude::{IpcPlugin, NavigationPlugin, WebviewPlugin};
|
||||
use crate::zoom::ZoomPlugin;
|
||||
use bevy::prelude::*;
|
||||
use bevy_cef_core::prelude::CommandLineConfig;
|
||||
use bevy_remote::RemotePlugin;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::{CefPlugin, RunOnMainThread, common::*, navigation::*, webview::prelude::*};
|
||||
pub use bevy_cef_core::prelude::CommandLineConfig;
|
||||
}
|
||||
|
||||
pub struct RunOnMainThread;
|
||||
|
||||
pub struct CefPlugin;
|
||||
#[derive(Debug, Default)]
|
||||
pub struct CefPlugin {
|
||||
pub command_line_config: CommandLineConfig,
|
||||
}
|
||||
|
||||
impl Plugin for CefPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((
|
||||
LocalHostPlugin,
|
||||
MessageLoopPlugin,
|
||||
MessageLoopPlugin {
|
||||
config: self.command_line_config.clone(),
|
||||
},
|
||||
WebviewCoreComponentsPlugin,
|
||||
WebviewPlugin,
|
||||
IpcPlugin,
|
||||
|
||||
Reference in New Issue
Block a user