Added app icon
This commit is contained in:
Generated
+3
@@ -2175,6 +2175,9 @@ name = "furumi-platform-desktop"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation 0.10.1",
|
"core-foundation 0.10.1",
|
||||||
|
"objc2 0.6.4",
|
||||||
|
"objc2-app-kit 0.3.2",
|
||||||
|
"objc2-foundation 0.3.2",
|
||||||
"rfd",
|
"rfd",
|
||||||
"souvlaki",
|
"souvlaki",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
|
|||||||
@@ -49,6 +49,13 @@ rodio = { version = "0.22.2", default-features = false, features = [
|
|||||||
] }
|
] }
|
||||||
souvlaki = { version = "0.8.3", default-features = false, features = ["use_zbus"] }
|
souvlaki = { version = "0.8.3", default-features = false, features = ["use_zbus"] }
|
||||||
core-foundation = "0.10.1"
|
core-foundation = "0.10.1"
|
||||||
|
objc2 = "0.6.4"
|
||||||
|
objc2-app-kit = { version = "0.3.2", default-features = false, features = [
|
||||||
|
"NSApplication",
|
||||||
|
"NSImage",
|
||||||
|
"NSResponder",
|
||||||
|
] }
|
||||||
|
objc2-foundation = { version = "0.3.2", default-features = false, features = ["NSData"] }
|
||||||
windows-sys = { version = "0.61.2", features = ["Win32_System_LibraryLoader", "Win32_UI_WindowsAndMessaging"] }
|
windows-sys = { version = "0.61.2", features = ["Win32_System_LibraryLoader", "Win32_UI_WindowsAndMessaging"] }
|
||||||
|
|
||||||
furumi-application = { path = "crates/application" }
|
furumi-application = { path = "crates/application" }
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ souvlaki.workspace = true
|
|||||||
|
|
||||||
[target.'cfg(target_os="macos")'.dependencies]
|
[target.'cfg(target_os="macos")'.dependencies]
|
||||||
core-foundation.workspace = true
|
core-foundation.workspace = true
|
||||||
|
objc2.workspace = true
|
||||||
|
objc2-app-kit.workspace = true
|
||||||
|
objc2-foundation.workspace = true
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
windows-sys.workspace = true
|
windows-sys.workspace = true
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/// Applies the Furumi federation mark as the native application icon.
|
||||||
|
///
|
||||||
|
/// Slint forwards its window icon to Windows and X11. macOS deliberately
|
||||||
|
/// ignores that window-level API, so its Dock icon is installed through
|
||||||
|
/// `AppKit` from the same embedded SVG asset. On macOS this must be called
|
||||||
|
/// from the main event loop after `applicationDidFinishLaunching`.
|
||||||
|
pub fn set_application_icon() {
|
||||||
|
if let Err(error) = set_native_application_icon() {
|
||||||
|
eprintln!("failed to install the Furumi application icon: {error}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn set_native_application_icon() -> Result<(), &'static str> {
|
||||||
|
use std::ffi::c_void;
|
||||||
|
|
||||||
|
use objc2::MainThreadMarker;
|
||||||
|
use objc2_app_kit::{NSApplication, NSImage};
|
||||||
|
use objc2_foundation::NSData;
|
||||||
|
|
||||||
|
let main_thread = MainThreadMarker::new().ok_or("not running on the macOS main thread")?;
|
||||||
|
let svg = include_bytes!("../../ui/assets/federation.svg");
|
||||||
|
// SAFETY: `dataWithBytes_length` copies `svg`; its pointer is valid for
|
||||||
|
// the complete duration of the Objective-C call.
|
||||||
|
let data = unsafe { NSData::dataWithBytes_length(svg.as_ptr().cast::<c_void>(), svg.len()) };
|
||||||
|
let icon = NSImage::initWithData(main_thread.alloc(), &data)
|
||||||
|
.ok_or("AppKit could not decode the embedded federation SVG")?;
|
||||||
|
let application = NSApplication::sharedApplication(main_thread);
|
||||||
|
// SAFETY: AppKit accepts a live NSImage here and retains it as the
|
||||||
|
// application's Dock icon. This function is restricted to the main thread.
|
||||||
|
unsafe { application.setApplicationIconImage(Some(&icon)) };
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
fn set_native_application_icon() -> Result<(), &'static str> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
mod app;
|
||||||
mod media;
|
mod media;
|
||||||
|
pub use app::set_application_icon;
|
||||||
pub use media::{MediaCommand, MediaSession};
|
pub use media::{MediaCommand, MediaSession};
|
||||||
|
|
||||||
/// Opens the platform-native directory picker.
|
/// Opens the platform-native directory picker.
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ pub fn run(backend: &BackendHandle) -> Result<(), slint::PlatformError> {
|
|||||||
let window = AppWindow::new()?;
|
let window = AppWindow::new()?;
|
||||||
let state = Arc::new(Mutex::new(AppState::default()));
|
let state = Arc::new(Mutex::new(AppState::default()));
|
||||||
|
|
||||||
|
// Winit completes NSApplication initialization only after entering the
|
||||||
|
// event loop. AppKit discards a Dock icon assigned before that point.
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
slint::Timer::single_shot(std::time::Duration::ZERO, || {
|
||||||
|
furumi_platform_desktop::set_application_icon();
|
||||||
|
});
|
||||||
|
|
||||||
let media_backend = backend.clone();
|
let media_backend = backend.clone();
|
||||||
MEDIA_SESSION.with_borrow_mut(|session| {
|
MEDIA_SESSION.with_borrow_mut(|session| {
|
||||||
*session = MediaSession::new(move |command| {
|
*session = MediaSession::new(move |command| {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { AlbumGrid, ArtistGrid, ArtistLinksRow, BuildInfoCard, DeviceRow, Federa
|
|||||||
|
|
||||||
export component AppWindow inherits Window {
|
export component AppWindow inherits Window {
|
||||||
title: "Furumi Desktop";
|
title: "Furumi Desktop";
|
||||||
|
icon: @image-url("../assets/federation.svg");
|
||||||
preferred-width: 1180px;
|
preferred-width: 1180px;
|
||||||
preferred-height: 760px;
|
preferred-height: 760px;
|
||||||
min-width: 920px;
|
min-width: 920px;
|
||||||
|
|||||||
Reference in New Issue
Block a user