From 01d600f97ee060405f75a495f61fee98b2fc6ffd Mon Sep 17 00:00:00 2001 From: zhom <2717306+zhom@users.noreply.github.com> Date: Mon, 2 Mar 2026 12:36:11 +0400 Subject: [PATCH] feat: set default search engine on camoufox --- src-tauri/Cargo.lock | 16 +++++ src-tauri/Cargo.toml | 1 + src-tauri/src/browser_runner.rs | 8 --- src-tauri/src/camoufox_manager.rs | 107 ++++++++++++++++++++---------- 4 files changed, 90 insertions(+), 42 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c6fc884..3dc9e4a 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1616,6 +1616,7 @@ dependencies = [ "lazy_static", "libc", "log", + "lz4_flex", "lzma-rs", "maxminddb", "mime_guess", @@ -3452,6 +3453,15 @@ dependencies = [ "imgref", ] +[[package]] +name = "lz4_flex" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a" +dependencies = [ + "twox-hash", +] + [[package]] name = "lzma-rs" version = "0.3.0" @@ -7160,6 +7170,12 @@ dependencies = [ "utf-8", ] +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + [[package]] name = "typed-path" version = "0.12.3" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5498324..95cb264 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -100,6 +100,7 @@ maxminddb = "0.27" quick-xml = { version = "0.39", features = ["serialize"] } # VPN support +lz4_flex = "0.11" boringtun = "0.7" smoltcp = { version = "0.11", default-features = false, features = ["std", "medium-ip", "proto-ipv4", "proto-ipv6", "socket-tcp", "socket-udp"] } diff --git a/src-tauri/src/browser_runner.rs b/src-tauri/src/browser_runner.rs index 835d8be..17c2017 100644 --- a/src-tauri/src/browser_runner.rs +++ b/src-tauri/src/browser_runner.rs @@ -223,14 +223,6 @@ impl BrowserRunner { ); } - // Ensure DuckDuckGo is set as default search engine for Camoufox - let mut browser_dir = self.get_binaries_dir(); - browser_dir.push(&profile.browser); - browser_dir.push(&profile.version); - if let Err(e) = crate::downloader::configure_camoufox_search_engine(&browser_dir) { - log::warn!("Failed to configure Camoufox search engine: {e}"); - } - // Create ephemeral dir for ephemeral profiles let override_profile_path = if profile.ephemeral { let dir = crate::ephemeral_dirs::create_ephemeral_dir(&profile.id.to_string()) diff --git a/src-tauri/src/camoufox_manager.rs b/src-tauri/src/camoufox_manager.rs index d48603a..335c8f2 100644 --- a/src-tauri/src/camoufox_manager.rs +++ b/src-tauri/src/camoufox_manager.rs @@ -628,40 +628,8 @@ impl CamoufoxManager { } } - // Write DuckDuckGo search engine prefs to user.js for all profiles - { - let user_js_path = profile_path.join("user.js"); - let ddg_prefs = concat!( - "user_pref(\"browser.search.defaultenginename\", \"DuckDuckGo\");\n", - "user_pref(\"browser.search.order.1\", \"DuckDuckGo\");\n", - "user_pref(\"browser.urlbar.placeholderName\", \"DuckDuckGo\");\n", - "user_pref(\"browser.urlbar.placeholderName.private\", \"DuckDuckGo\");\n", - ); - - let needs_write = if user_js_path.exists() { - std::fs::read_to_string(&user_js_path) - .map(|existing| !existing.contains("browser.search.defaultenginename")) - .unwrap_or(false) - } else { - true - }; - - if needs_write { - use std::fs::OpenOptions; - match OpenOptions::new() - .create(true) - .append(true) - .open(&user_js_path) - { - Ok(mut f) => { - if let Err(e) = std::io::Write::write_all(&mut f, ddg_prefs.as_bytes()) { - log::warn!("Failed to write DuckDuckGo prefs to user.js: {e}"); - } - } - Err(e) => log::warn!("Failed to open user.js for DuckDuckGo prefs: {e}"), - } - } - } + // Write search.json.mozlz4 with default search engines (DuckDuckGo + Google) + write_default_search_config(&profile_path); self .launch_camoufox( @@ -676,6 +644,77 @@ impl CamoufoxManager { } } +fn write_default_search_config(profile_path: &std::path::Path) { + let search_file = profile_path.join("search.json.mozlz4"); + if search_file.exists() { + return; + } + + let json = serde_json::json!({ + "version": 6, + "engines": [ + { + "_name": "DuckDuckGo", + "_isAppProvided": false, + "_metaData": { "order": 1 }, + "_urls": [ + { + "template": "https://duckduckgo.com/?q={searchTerms}", + "type": "text/html", + "params": [] + }, + { + "template": "https://duckduckgo.com/ac/?q={searchTerms}&type=list", + "type": "application/x-suggestions+json", + "params": [] + } + ], + "_iconURL": "https://duckduckgo.com/favicon.ico" + }, + { + "_name": "Google", + "_isAppProvided": false, + "_metaData": { "order": 2 }, + "_urls": [ + { + "template": "https://www.google.com/search?q={searchTerms}", + "type": "text/html", + "params": [] + }, + { + "template": "https://www.google.com/complete/search?client=firefox&q={searchTerms}", + "type": "application/x-suggestions+json", + "params": [] + } + ], + "_iconURL": "https://www.google.com/favicon.ico" + } + ], + "metaData": { + "useSavedOrder": false, + "defaultEngineId": "DuckDuckGo" + } + }); + + let json_bytes = match serde_json::to_vec(&json) { + Ok(bytes) => bytes, + Err(e) => { + log::warn!("Failed to serialize search config: {e}"); + return; + } + }; + + let magic = b"mozLz40\0"; + let compressed = lz4_flex::block::compress_prepend_size(&json_bytes); + let mut output = Vec::with_capacity(magic.len() + compressed.len()); + output.extend_from_slice(magic); + output.extend_from_slice(&compressed); + + if let Err(e) = std::fs::write(&search_file, &output) { + log::warn!("Failed to write search.json.mozlz4: {e}"); + } +} + #[cfg(test)] mod tests { use super::*;