diff --git a/Cargo.lock b/Cargo.lock index 8d138bb49..e9ee02ce7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4723,6 +4723,7 @@ dependencies = [ name = "oak-app" version = "0.5.0" dependencies = [ + "embed-resource", "gpui", "gpui_elements", "gpui_platform", diff --git a/assets/appicon/icon.ico b/assets/appicon/icon.ico new file mode 100644 index 000000000..95beabd21 Binary files /dev/null and b/assets/appicon/icon.ico differ diff --git a/assets/appicon/icon.png b/assets/appicon/icon.png new file mode 100644 index 000000000..c603c1042 Binary files /dev/null and b/assets/appicon/icon.png differ diff --git a/crates/oak-app/Cargo.toml b/crates/oak-app/Cargo.toml index b3388c418..27f66722c 100644 --- a/crates/oak-app/Cargo.toml +++ b/crates/oak-app/Cargo.toml @@ -92,6 +92,14 @@ default = [] # is given at runtime (or this feature is enabled at build time). mock-engine = [] +# The Windows window/taskbar icon: embeds resources/windows/oak.rc (icon +# resource ID 1, read by gpui_windows' `load_icon`) into oak-editor.exe. +# Same crate gpui uses for its Windows manifest (see gpui's build.rs). +# Unconditional (not target-gated): the build script references it behind +# a runtime `CARGO_CFG_TARGET_OS` check, so it must resolve on every host. +[build-dependencies] +embed-resource = "3.0" + [dev-dependencies] # `#[gpui::test]` harness for engine-seam smoke tests (test-support feature). gpui = { path = "../../gpui/crates/gpui", features = ["test-support"] } diff --git a/crates/oak-app/build.rs b/crates/oak-app/build.rs index 336c9a620..5e5e6fba1 100644 --- a/crates/oak-app/build.rs +++ b/crates/oak-app/build.rs @@ -37,6 +37,16 @@ fn main() { // at the real system library. println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/lib"); } + if os == "windows" { + // The window/taskbar icon on Windows comes from the exe's icon + // resource (ID 1 — gpui_windows' `load_icon`); compile it in. The + // same resource is the exe's Explorer icon. + println!("cargo:rerun-if-changed=resources/windows/oak.rc"); + println!("cargo:rerun-if-changed=../../assets/appicon/icon.ico"); + embed_resource::compile("resources/windows/oak.rc", embed_resource::NONE) + .manifest_optional() + .unwrap(); + } // --- OFX interact end-to-end test plugin --------------------------------- // The app-side interact tests (src/oakui/ofx.rs) drive the *real* // minimal test plugin (../../crates/oak-plugin/cbits/oak_test_plugin.c) through diff --git a/crates/oak-app/resources/windows/oak.rc b/crates/oak-app/resources/windows/oak.rc new file mode 100644 index 000000000..27c99f4ca --- /dev/null +++ b/crates/oak-app/resources/windows/oak.rc @@ -0,0 +1,4 @@ +// Icon resource ID 1 is what gpui_windows' `load_icon` reads for the +// window/taskbar icon; it is also the exe's Explorer icon. The path is +// resolved from the crate root (the build script's working directory). +1 ICON "../../assets/appicon/icon.ico" diff --git a/crates/oak-app/src/app.rs b/crates/oak-app/src/app.rs index 78d846831..dd5092189 100644 --- a/crates/oak-app/src/app.rs +++ b/crates/oak-app/src/app.rs @@ -3817,11 +3817,20 @@ fn run_with(args: AppArgs) { let bounds = Bounds::centered(None, size(px(1600.0), px(900.0)), cx); let initial = initial.clone(); let show_manager = initial.is_none(); + // The window/taskbar icon, per platform: X11 takes the pixels up + // front (_NET_WM_ICON, decoded here from the embedded PNG); + // Wayland resolves the icon from oak.desktop via the app id; + // Windows reads it from the exe's icon resource (see build.rs). + let icon = image::load_from_memory(include_bytes!("../../../assets/appicon/icon.png")) + .expect("the embedded app icon must decode") + .into_rgba8(); let mut root_slot = None; let window = cx .open_window( WindowOptions { window_bounds: Some(WindowBounds::Windowed(bounds)), + app_id: Some("oak".into()), + icon: Some(Arc::new(icon)), ..Default::default() }, |window, cx| { diff --git a/tooling/package/PKGBUILD b/tooling/package/PKGBUILD index 46e15f76d..919f73376 100644 --- a/tooling/package/PKGBUILD +++ b/tooling/package/PKGBUILD @@ -36,6 +36,7 @@ package() { install -Dm755 "$OAK_BIN/oak-worker" "$pkgdir/usr/bin/oak-worker" install -Dm644 "$OAK_ROOT/packaging/oak.desktop" "$pkgdir/usr/share/applications/oak.desktop" install -Dm644 "$OAK_ROOT/icons/icon.png" "$pkgdir/usr/share/icons/hicolor/512x512/apps/oak.png" + install -Dm644 "$OAK_ROOT/Oak_Icon.svg" "$pkgdir/usr/share/icons/hicolor/scalable/apps/oak.svg" for f in "$OAK_ROOT"/assets/i18n/*.yaml; do install -Dm644 "$f" "$pkgdir/usr/share/oak/i18n/$(basename "$f")" done diff --git a/tooling/package/build-deb.sh b/tooling/package/build-deb.sh index dd4f8b9f8..eaf75c4dd 100755 --- a/tooling/package/build-deb.sh +++ b/tooling/package/build-deb.sh @@ -26,12 +26,13 @@ STAGING=target/pkg/deb rm -rf "$STAGING" mkdir -p "$STAGING/usr/bin" "$STAGING/usr/share/applications" \ "$STAGING/usr/share/icons/hicolor/512x512/apps" "$STAGING/usr/share/oak/i18n" \ - "$STAGING/DEBIAN" + "$STAGING/usr/share/icons/hicolor/scalable/apps" "$STAGING/DEBIAN" install -m755 target/release/oak-editor target/release/oak-cli target/release/oak-worker \ "$STAGING/usr/bin/" install -m644 packaging/oak.desktop "$STAGING/usr/share/applications/oak.desktop" install -m644 icons/icon.png "$STAGING/usr/share/icons/hicolor/512x512/apps/oak.png" +install -m644 Oak_Icon.svg "$STAGING/usr/share/icons/hicolor/scalable/apps/oak.svg" install -m644 assets/i18n/*.yaml "$STAGING/usr/share/oak/i18n/" # The full shlib dependency set (FFmpeg/OCIO are statically linked, so diff --git a/tooling/package/build-rpm.sh b/tooling/package/build-rpm.sh index 217d007ab..c3ba423bc 100755 --- a/tooling/package/build-rpm.sh +++ b/tooling/package/build-rpm.sh @@ -28,11 +28,13 @@ mkdir -p "$TOP"/{BUILD,RPMS,SOURCES,SPECS,BUILDROOT} ROOT="$TOP/BUILDROOT/oak-editor-$VERSION-1.x86_64" mkdir -p "$ROOT/usr/bin" "$ROOT/usr/share/applications" \ - "$ROOT/usr/share/icons/hicolor/512x512/apps" "$ROOT/usr/share/oak/i18n" + "$ROOT/usr/share/icons/hicolor/512x512/apps" "$ROOT/usr/share/oak/i18n" \ + "$ROOT/usr/share/icons/hicolor/scalable/apps" install -m755 target/release/oak-editor target/release/oak-cli target/release/oak-worker \ "$ROOT/usr/bin/" install -m644 packaging/oak.desktop "$ROOT/usr/share/applications/oak.desktop" install -m644 icons/icon.png "$ROOT/usr/share/icons/hicolor/512x512/apps/oak.png" +install -m644 Oak_Icon.svg "$ROOT/usr/share/icons/hicolor/scalable/apps/oak.svg" install -m644 assets/i18n/*.yaml "$ROOT/usr/share/oak/i18n/" rpmbuild -bb \ diff --git a/tooling/package/oak.spec b/tooling/package/oak.spec index 379332bf2..165a5b766 100644 --- a/tooling/package/oak.spec +++ b/tooling/package/oak.spec @@ -39,6 +39,7 @@ true /usr/bin/oak-worker /usr/share/applications/oak.desktop /usr/share/icons/hicolor/512x512/apps/oak.png +/usr/share/icons/hicolor/scalable/apps/oak.svg /usr/share/oak/i18n/ %changelog