This commit is contained in:
2026-08-21 23:52:13 -05:00
parent f2a1898039
commit d6cd7ec94e
10 changed files with 2265 additions and 155 deletions
+5
View File
@@ -0,0 +1,5 @@
# CEF symbols are resolved at runtime from the dlopen'd framework
# (see cef_host::load_framework_if_bundled), so the linker must tolerate
# undefined cef_* symbols.
[target.'cfg(target_os = "macos")']
rustflags = ["-C", "link-arg=-Wl,-undefined,dynamic_lookup"]
Generated
+298 -6
View File
@@ -347,7 +347,7 @@ version = "0.38.0+1.3.281"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f"
dependencies = [ dependencies = [
"libloading", "libloading 0.8.9",
] ]
[[package]] [[package]]
@@ -668,6 +668,7 @@ dependencies = [
name = "browser" name = "browser"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"cef",
"egui", "egui",
"egui-wgpu", "egui-wgpu",
"egui-winit", "egui-winit",
@@ -680,6 +681,8 @@ dependencies = [
"objc2-quartz-core 0.3.2", "objc2-quartz-core 0.3.2",
"pollster", "pollster",
"rustls", "rustls",
"serde",
"serde_json",
"servo", "servo",
"url", "url",
"wgpu", "wgpu",
@@ -759,6 +762,15 @@ version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
[[package]]
name = "bzip2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c"
dependencies = [
"libbz2-rs-sys",
]
[[package]] [[package]]
name = "calendrical_calculations" name = "calendrical_calculations"
version = "0.1.3" version = "0.1.3"
@@ -820,6 +832,39 @@ dependencies = [
"wayland-client", "wayland-client",
] ]
[[package]]
name = "camino"
version = "1.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb1307f12aa967b5a58416e87b3653360e0fd614a016b6e970db08fecbb1b80d"
dependencies = [
"serde_core",
]
[[package]]
name = "cargo-platform"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0061da739915fae12ea00e16397555ed4371a6bb285431aab930f61b0aa4ba"
dependencies = [
"serde",
"serde_core",
]
[[package]]
name = "cargo_metadata"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9"
dependencies = [
"camino",
"cargo-platform",
"semver",
"serde",
"serde_json",
"thiserror 2.0.20",
]
[[package]] [[package]]
name = "cbc" name = "cbc"
version = "0.2.1" version = "0.2.1"
@@ -841,6 +886,38 @@ dependencies = [
"shlex 2.0.1", "shlex 2.0.1",
] ]
[[package]]
name = "cef"
version = "151.7.0+151.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c96acc058418aaf5dbcb95420677eb053032acc9b8af224079fb091a3043d899"
dependencies = [
"anyhow",
"cargo_metadata",
"cef-dll-sys",
"clap",
"libloading 0.9.0",
"objc2 0.6.4",
"plist",
"semver",
"serde",
"serde_json",
"thiserror 2.0.20",
"windows-sys 0.61.2",
]
[[package]]
name = "cef-dll-sys"
version = "151.7.0+151.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "043cf920289eeaa8e6b4d7f1701ef28e07e0cdaa7c8acf54e6008e9b61435a4c"
dependencies = [
"anyhow",
"cmake",
"download-cef",
"serde_json",
]
[[package]] [[package]]
name = "cexpr" name = "cexpr"
version = "0.6.0" version = "0.6.0"
@@ -942,9 +1019,49 @@ checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a"
dependencies = [ dependencies = [
"glob", "glob",
"libc", "libc",
"libloading", "libloading 0.8.9",
] ]
[[package]]
name = "clap"
version = "4.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 3.0.3",
]
[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]] [[package]]
name = "clipboard-win" name = "clipboard-win"
version = "5.4.1" version = "5.4.1"
@@ -1049,6 +1166,18 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "console"
version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c"
dependencies = [
"encode_unicode",
"libc",
"unicode-width",
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "const-oid" name = "const-oid"
version = "0.10.2" version = "0.10.2"
@@ -1087,10 +1216,29 @@ version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87" checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87"
dependencies = [ dependencies = [
"percent-encoding",
"time", "time",
"version_check", "version_check",
] ]
[[package]]
name = "cookie_store"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206"
dependencies = [
"cookie 0.18.2",
"document-features",
"idna",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"time",
"url",
]
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.4" version = "0.9.4"
@@ -1586,7 +1734,7 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a"
dependencies = [ dependencies = [
"libloading", "libloading 0.8.9",
] ]
[[package]] [[package]]
@@ -1604,6 +1752,26 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]]
name = "download-cef"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c169adf067a787e1f1c58ed62906a557de85388bee4b54fb878b722ff606b113"
dependencies = [
"bzip2",
"clap",
"fs-err",
"indicatif",
"regex",
"semver",
"serde",
"serde_json",
"sha1_smol",
"tar",
"thiserror 2.0.20",
"ureq",
]
[[package]] [[package]]
name = "dpi" name = "dpi"
version = "0.1.2" version = "0.1.2"
@@ -1830,6 +1998,12 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]] [[package]]
name = "encoding_c" name = "encoding_c"
version = "0.9.8" version = "0.9.8"
@@ -2235,6 +2409,15 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "fs-err"
version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "fs_extra" name = "fs_extra"
version = "1.3.0" version = "1.3.0"
@@ -3487,6 +3670,19 @@ dependencies = [
"hashbrown 0.17.1", "hashbrown 0.17.1",
] ]
[[package]]
name = "indicatif"
version = "0.18.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c"
dependencies = [
"console",
"portable-atomic",
"unicode-width",
"unit-prefix",
"web-time",
]
[[package]] [[package]]
name = "inout" name = "inout"
version = "0.2.2" version = "0.2.2"
@@ -3746,7 +3942,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76"
dependencies = [ dependencies = [
"libc", "libc",
"libloading", "libloading 0.8.9",
"pkg-config", "pkg-config",
] ]
@@ -3781,6 +3977,12 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8"
[[package]]
name = "libbz2-rs-sys"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.189" version = "0.2.189"
@@ -3807,6 +4009,16 @@ dependencies = [
"windows-link 0.2.1", "windows-link 0.2.1",
] ]
[[package]]
name = "libloading"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60"
dependencies = [
"cfg-if",
"windows-link 0.2.1",
]
[[package]] [[package]]
name = "libm" name = "libm"
version = "0.2.16" version = "0.2.16"
@@ -5107,6 +5319,19 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "plist"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da1d65da6dd5d1e44199ac0f58712d241c0f439f80adea8924d832384087f85"
dependencies = [
"base64 0.22.1",
"indexmap",
"quick-xml",
"serde",
"time",
]
[[package]] [[package]]
name = "png" name = "png"
version = "0.18.1" version = "0.18.1"
@@ -5827,6 +6052,7 @@ dependencies = [
"aws-lc-rs", "aws-lc-rs",
"log", "log",
"once_cell", "once_cell",
"ring",
"rustls-pki-types", "rustls-pki-types",
"rustls-webpki", "rustls-webpki",
"subtle", "subtle",
@@ -6044,6 +6270,10 @@ name = "semver"
version = "1.0.28" version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
dependencies = [
"serde",
"serde_core",
]
[[package]] [[package]]
name = "seq-macro" name = "seq-macro"
@@ -7867,6 +8097,17 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "socks"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b"
dependencies = [
"byteorder",
"libc",
"winapi",
]
[[package]] [[package]]
name = "speexdsp-resampler" name = "speexdsp-resampler"
version = "0.1.0" version = "0.1.0"
@@ -7972,6 +8213,12 @@ dependencies = [
"quote", "quote",
] ]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "strum" name = "strum"
version = "0.28.0" version = "0.28.0"
@@ -8870,6 +9117,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "unit-prefix"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3"
[[package]] [[package]]
name = "universal-hash" name = "universal-hash"
version = "0.6.1" version = "0.6.1"
@@ -8886,6 +9139,39 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "ureq"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "972d7902c8735f2695410b8aed7df6ed12a47394aa1c8d7af49f0497b731a94d"
dependencies = [
"base64 0.23.1",
"cookie_store",
"flate2",
"log",
"percent-encoding",
"rustls",
"rustls-pki-types",
"serde",
"serde_json",
"socks",
"ureq-proto",
"utf8-zero",
"webpki-roots",
]
[[package]]
name = "ureq-proto"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da5f78b09e6941e1a0f2e30e695e4b120377b54d5e0aec11b594bb57b3971613"
dependencies = [
"base64 0.23.1",
"http 1.5.0",
"httparse",
"log",
]
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.8" version = "2.5.8"
@@ -8945,6 +9231,12 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
[[package]]
name = "utf8-zero"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e"
[[package]] [[package]]
name = "utf8_iter" name = "utf8_iter"
version = "1.0.4" version = "1.0.4"
@@ -9566,7 +9858,7 @@ dependencies = [
"js-sys", "js-sys",
"khronos-egl", "khronos-egl",
"libc", "libc",
"libloading", "libloading 0.8.9",
"log", "log",
"naga", "naga",
"naga-types", "naga-types",
@@ -10204,7 +10496,7 @@ dependencies = [
"as-raw-xcb-connection", "as-raw-xcb-connection",
"gethostname", "gethostname",
"libc", "libc",
"libloading", "libloading 0.8.9",
"once_cell", "once_cell",
"rustix 1.1.4", "rustix 1.1.4",
"x11rb-protocol", "x11rb-protocol",
+3
View File
@@ -4,6 +4,9 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
cef = "151"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
egui = "0.36.1" egui = "0.36.1"
egui-wgpu = "0.36.1" egui-wgpu = "0.36.1"
egui-winit = "0.36.1" egui-winit = "0.36.1"
+95
View File
@@ -0,0 +1,95 @@
#!/bin/sh
# Build Fox and assemble Fox.app with the CEF framework + helper bundles.
#
# scripts/bundle.sh [debug|release]
#
# The CEF distribution must be exported first:
# cargo install export-cef-dir --version 151.7.0+151.3.23 && export-cef-dir
set -e
PROFILE="${1:-debug}"
cd "$(dirname "$0")/.."
export CEF_PATH="${CEF_PATH:-$HOME/.local/share/cef}"
DIST="$CEF_PATH"
FRAMEWORK="Chromium Embedded Framework.framework"
if [ "$PROFILE" = "release" ]; then
cargo build --release
BIN="target/release/browser"
else
cargo build
BIN="target/debug/browser"
fi
APP="target/bundle/Fox.app"
CONTENTS="$APP/Contents"
rm -rf "$APP"
mkdir -p "$CONTENTS/MacOS" "$CONTENTS/Frameworks"
cp "$BIN" "$CONTENTS/MacOS/browser"
ditto "$DIST/$FRAMEWORK" "$CONTENTS/Frameworks/$FRAMEWORK"
cat > "$CONTENTS/Info.plist" <<'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key><string>en</string>
<key>CFBundleExecutable</key><string>browser</string>
<key>CFBundleIconFile</key><string></string>
<key>CFBundleIdentifier</key><string>dev.fox.browser</string>
<key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
<key>CFBundleName</key><string>Fox</string>
<key>CFBundleDisplayName</key><string>Fox</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleShortVersionString</key><string>0.2.0</string>
<key>CFBundleVersion</key><string>0.2.0</string>
<key>LSMinimumSystemVersion</key><string>11.0</string>
<key>NSHighResolutionCapable</key><true/>
<key>NSPrincipalClass</key><string>NSApplication</string>
</dict>
</plist>
PLIST
# Chromium on macOS launches child processes (GPU/renderer/network/utility)
# from dedicated .app bundles. We reuse the Fox binary itself as the helper
# executable — CEF child processes are dispatched via --type= arguments, which
# our bootstrap() already understands.
make_helper () {
HELPER_NAME="$1"
HELPER_ID="$2"
HELPER_DIR="$CONTENTS/Frameworks/$HELPER_NAME.app"
mkdir -p "$HELPER_DIR/Contents/MacOS"
cp "$BIN" "$HELPER_DIR/Contents/MacOS/$HELPER_NAME"
cat > "$HELPER_DIR/Contents/Info.plist" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key><string>en</string>
<key>CFBundleExecutable</key><string>$HELPER_NAME</string>
<key>CFBundleIdentifier</key><string>$HELPER_ID</string>
<key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
<key>CFBundleName</key><string>$HELPER_NAME</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleShortVersionString</key><string>0.2.0</string>
<key>CFBundleVersion</key><string>0.2.0</string>
<key>LSMinimumSystemVersion</key><string>11.0</string>
<key>NSSupportsAutomaticGraphicsSwitching</key><true/>
</dict>
</plist>
PLIST
}
make_helper "Fox Helper" "dev.fox.browser.helper"
make_helper "Fox Helper (Renderer)" "dev.fox.browser.helper.renderer"
make_helper "Fox Helper (GPU)" "dev.fox.browser.helper.gpu"
make_helper "Fox Helper (Plugin)" "dev.fox.browser.helper.plugin"
make_helper "Fox Helper (Alerts)" "dev.fox.browser.helper.alerts"
codesign --force --deep --sign - "$APP"
echo "Built $APP"
+21
View File
@@ -0,0 +1,21 @@
#!/bin/sh
# Build and run Fox in dev mode.
#
# scripts/run-dev.sh [extra cargo args...]
#
# On macOS the app must run from a .app bundle (CEF needs its framework
# resources, so a bare target/debug binary cannot start). This script
# therefore bundles first, then launches Fox.app with console output visible.
#
# The CEF distribution must be exported once:
# cargo install export-cef-dir --version 151.7.0+151.3.23
# export-cef-dir # installs to ~/.local/share/cef
set -e
cd "$(dirname "$0")/.."
export CEF_PATH="${CEF_PATH:-$HOME/.local/share/cef}"
scripts/bundle.sh "${FOX_PROFILE:-debug}"
exec ./target/bundle/Fox.app/Contents/MacOS/browser "$@"
+654 -117
View File
File diff suppressed because it is too large Load Diff
+1107
View File
File diff suppressed because it is too large Load Diff
+22 -3
View File
@@ -1,16 +1,21 @@
mod app; mod app;
mod cef_host;
mod servo_host; mod servo_host;
mod settings;
use std::error::Error; use std::error::Error;
use std::process::ExitCode;
use app::BrowserApp; use app::BrowserApp;
#[derive(Debug)] #[derive(Debug)]
pub enum UserEvent { pub enum UserEvent {
RepaintAfter(std::time::Duration), RepaintAfter(std::time::Duration),
/// CEF asked for a message-loop pass after this delay.
PumpCef(std::time::Duration),
} }
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<ExitCode, Box<dyn Error>> {
// Note: logging is initialized by `Servo::setup_logging()` — do not install // Note: logging is initialized by `Servo::setup_logging()` — do not install
// another logger here or it will panic with `SetLoggerError`. // another logger here or it will panic with `SetLoggerError`.
@@ -18,13 +23,27 @@ fn main() -> Result<(), Box<dyn Error>> {
.install_default() .install_default()
.expect("Failed to install crypto provider"); .expect("Failed to install crypto provider");
// The CEF handshake must happen before winit creates an NSApplication:
// when this binary is re-executed as a CEF helper process, bootstrap()
// runs the child-process loop to completion and returns false.
if !cef_host::bootstrap() {
return Ok(ExitCode::SUCCESS);
}
if cef_host::run_probe() {
return Ok(ExitCode::SUCCESS);
}
let event_loop = winit::event_loop::EventLoop::<UserEvent>::with_user_event() let event_loop = winit::event_loop::EventLoop::<UserEvent>::with_user_event()
.build() .build()
.expect("Failed to create event loop"); .expect("Failed to create event loop");
let proxy = event_loop.create_proxy(); let proxy = event_loop.create_proxy();
let mut app = BrowserApp::new(proxy); cef_host::set_pump_proxy(proxy.clone());
let settings = settings::Settings::load();
let mut app = BrowserApp::new(proxy, settings);
event_loop.run_app(&mut app)?; event_loop.run_app(&mut app)?;
Ok(()) Ok(ExitCode::SUCCESS)
} }
+10 -29
View File
@@ -1,7 +1,6 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use egui::TextureHandle;
use keyboard_types::{Code, Key, KeyState, Location, Modifiers, NamedKey}; use keyboard_types::{Code, Key, KeyState, Location, Modifiers, NamedKey};
use servo::{ use servo::{
DevicePoint, EventLoopWaker, InputEvent, KeyboardEvent as ServoKeyboardEvent, LoadStatus, DevicePoint, EventLoopWaker, InputEvent, KeyboardEvent as ServoKeyboardEvent, LoadStatus,
@@ -124,7 +123,7 @@ impl Engine {
self.servo.spin_event_loop(); self.servo.spin_event_loop();
} }
pub fn create_tab(&self, url: Url, hidpi_scale: f32) -> Tab { pub fn create_tab(&self, url: Url, hidpi_scale: f32) -> ServoPage {
let size = self.window_context.size(); let size = self.window_context.size();
let offscreen: Rc<OffscreenRenderingContext> = let offscreen: Rc<OffscreenRenderingContext> =
Rc::new(self.window_context.offscreen_context(size)); Rc::new(self.window_context.offscreen_context(size));
@@ -137,45 +136,27 @@ impl Engine {
.delegate(delegate) .delegate(delegate)
.build(); .build();
webview.notify_theme_change(Theme::Light); webview.notify_theme_change(Theme::Light);
Tab::new(webview) ServoPage::new(webview)
} }
} }
pub struct Tab { /// Engine-side handle for one Servo tab. UI state (title, texture, …) lives in
/// `app::Tab`; this only carries what Servo needs.
pub struct ServoPage {
pub webview: WebView, pub webview: WebView,
pub id: WebViewId, pub id: WebViewId,
pub title: String,
pub url_string: String,
pub status_text: Option<String>,
pub loading: bool,
pub animating: bool,
pub dirty: bool,
pub texture: Option<TextureHandle>,
/// Hash of the last uploaded frame — skips redundant GPU texture uploads.
pub last_frame_hash: u64,
/// Time of the last GPU->CPU readback — throttles readback frequency.
pub last_paint: std::time::Instant,
} }
impl Tab { impl ServoPage {
fn new(webview: WebView) -> Tab { fn new(webview: WebView) -> ServoPage {
Tab { ServoPage {
id: webview.id(), id: webview.id(),
webview, webview,
title: String::from("New Tab"),
url_string: String::new(),
status_text: None,
loading: true,
animating: false,
dirty: true,
texture: None,
last_frame_hash: 0,
last_paint: std::time::Instant::now() - std::time::Duration::from_secs(1),
} }
} }
pub fn adopt(webview: WebView) -> Tab { pub fn adopt(webview: WebView) -> ServoPage {
Tab::new(webview) Self::new(webview)
} }
} }
+50
View File
@@ -0,0 +1,50 @@
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
/// Which browser engine renders a tab.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum EngineKind {
#[default]
Chromium,
Servo,
}
impl EngineKind {
pub fn label(self) -> &'static str {
match self {
EngineKind::Chromium => "Chromium",
EngineKind::Servo => "Servo",
}
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Settings {
pub default_engine: EngineKind,
}
impl Settings {
pub fn load() -> Settings {
let Some(text) = std::fs::read_to_string(Self::path()).ok() else {
return Settings::default();
};
serde_json::from_str(&text).unwrap_or_default()
}
pub fn save(&self) {
let path = Self::path();
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
if let Ok(json) = serde_json::to_string_pretty(self) {
let _ = std::fs::write(path, json);
}
}
fn path() -> PathBuf {
let home = std::env::var("HOME").unwrap_or_else(|_| ".".to_owned());
PathBuf::from(home)
.join("Library/Application Support/Fox/settings.json")
}
}