diff --git a/Cargo.lock b/Cargo.lock index 961ee8dec4..547ff2fcc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -991,6 +991,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1004,7 +1014,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "libc", ] @@ -2253,7 +2263,7 @@ dependencies = [ "cef", "cef-dll-sys", "clap", - "core-foundation", + "core-foundation 0.10.1", "derivative", "dirs", "futures", @@ -2261,8 +2271,8 @@ dependencies = [ "graphite-desktop-embedded-resources", "graphite-desktop-wrapper", "libc", - "objc2-io-surface", - "objc2-metal", + "metal", + "objc", "open", "rand 0.9.2", "rfd", @@ -3720,33 +3730,6 @@ dependencies = [ "objc2-core-foundation", ] -[[package]] -name = "objc2-io-surface" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" -dependencies = [ - "bitflags 2.9.3", - "libc", - "objc2", - "objc2-core-foundation", - "objc2-foundation", -] - -[[package]] -name = "objc2-metal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f246c183239540aab1782457b35ab2040d4259175bd1d0c58e46ada7b47a874" -dependencies = [ - "bitflags 2.9.3", - "block2", - "dispatch2", - "objc2", - "objc2-core-foundation", - "objc2-foundation", -] - [[package]] name = "objc2-ui-kit" version = "0.3.1" @@ -4968,7 +4951,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.9.3", - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "libc", "security-framework-sys", @@ -5532,7 +5515,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.9.3", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] diff --git a/Cargo.toml b/Cargo.toml index c666091b2a..345484ae2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,6 @@ members = [ "proc-macros", ] default-members = [ - "desktop", - "desktop/wrapper", "editor", "frontend/wasm", "libraries/dyn-any", diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index 586e2470b0..a3a0bf13fe 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -18,7 +18,7 @@ gpu = ["graphite-desktop-wrapper/gpu"] accelerated_paint = ["accelerated_paint_dmabuf", "accelerated_paint_d3d11", "accelerated_paint_iosurface"] accelerated_paint_dmabuf = ["libc", "ash"] accelerated_paint_d3d11 = ["windows", "ash"] -accelerated_paint_iosurface = ["objc2-io-surface", "objc2-metal", "core-foundation"] +accelerated_paint_iosurface = ["metal", "objc", "core-foundation"] [dependencies] # Local dependencies @@ -66,9 +66,9 @@ windows = { version = "0.58.0", features = [ # macOS-specific dependencies [target.'cfg(target_os = "macos")'.dependencies] -objc2-io-surface = { version = "0.3", optional = true } -objc2-metal = { version = "0.3", optional = true } -core-foundation = { version = "0.9", optional = true } +metal = { version = "0.31.0", optional = true } +objc = { version = "0.2", optional = true } +core-foundation = { version = "0.10", optional = true } # Linux-specific dependencies [target.'cfg(target_os = "linux")'.dependencies] diff --git a/desktop/src/cef/context.rs b/desktop/src/cef/context.rs index 2880663a10..1f6279c388 100644 --- a/desktop/src/cef/context.rs +++ b/desktop/src/cef/context.rs @@ -1,3 +1,4 @@ +#[cfg(not(target_os = "macos"))] mod multithreaded; mod singlethreaded; diff --git a/desktop/src/cef/context/builder.rs b/desktop/src/cef/context/builder.rs index ba54062f64..cd586089d3 100644 --- a/desktop/src/cef/context/builder.rs +++ b/desktop/src/cef/context/builder.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use cef::args::Args; use cef::sys::{CEF_API_VERSION_LAST, cef_resultcode_t}; @@ -25,12 +25,23 @@ unsafe impl Send for CefContextBuilder {} impl CefContextBuilder { pub(crate) fn new() -> Self { + Self::new_inner(false) + } + + pub(crate) fn new_helper() -> Self { + Self::new_inner(true) + } + + fn new_inner(helper: bool) -> Self { #[cfg(target_os = "macos")] let _loader = { - let loader = library_loader::LibraryLoader::new(&std::env::current_exe().unwrap(), false); + let loader = cef::library_loader::LibraryLoader::new(&std::env::current_exe().unwrap(), helper); assert!(loader.load()); loader }; + #[cfg(not(target_os = "macos"))] + let _ = helper; + let _ = api_hash(CEF_API_VERSION_LAST, 0); let args = Args::new(); @@ -62,17 +73,29 @@ impl CefContextBuilder { } } + fn common_settings(instance_dir: &Path) -> Settings { + Settings { + windowless_rendering_enabled: 1, + root_cache_path: instance_dir.to_str().map(CefString::from).unwrap(), + cache_path: CefString::from(""), + disable_signal_handlers: 1, + ..Default::default() + } + } + #[cfg(target_os = "macos")] pub(crate) fn initialize(self, event_handler: H, disable_gpu_acceleration: bool) -> Result { let instance_dir = create_instance_dir(); + let exe = std::env::current_exe().expect("cannot get current exe path"); + let app_root = exe.parent().and_then(|p| p.parent()).expect("bad path structure").parent().expect("bad path structure"); + let settings = Settings { - windowless_rendering_enabled: 1, + main_bundle_path: CefString::from(app_root.to_str().unwrap()), multi_threaded_message_loop: 0, external_message_pump: 1, - root_cache_path: instance_dir.to_str().map(CefString::from).unwrap(), - cache_path: CefString::from(""), - ..Default::default() + no_sandbox: 1, // GPU helper crashes when running with sandbox + ..Self::common_settings(&instance_dir) }; self.initialize_inner(&event_handler, settings)?; @@ -85,11 +108,8 @@ impl CefContextBuilder { let instance_dir = create_instance_dir(); let settings = Settings { - windowless_rendering_enabled: 1, multi_threaded_message_loop: 1, - root_cache_path: instance_dir.to_str().map(CefString::from).unwrap(), - cache_path: CefString::from(""), - ..Default::default() + ..Self::common_settings(&instance_dir) }; self.initialize_inner(&event_handler, settings)?; diff --git a/desktop/src/cef/internal.rs b/desktop/src/cef/internal.rs index 4a2559ac19..1a9c8645a3 100644 --- a/desktop/src/cef/internal.rs +++ b/desktop/src/cef/internal.rs @@ -13,6 +13,8 @@ mod scheme_handler_factory; mod display_handler; pub(super) mod render_handler; + +#[cfg(not(target_os = "macos"))] pub(super) mod task; pub(super) use browser_process_app::BrowserProcessAppImpl; diff --git a/desktop/src/cef/internal/browser_process_app.rs b/desktop/src/cef/internal/browser_process_app.rs index 7a0ec0feb1..2ecae79100 100644 --- a/desktop/src/cef/internal/browser_process_app.rs +++ b/desktop/src/cef/internal/browser_process_app.rs @@ -66,6 +66,12 @@ impl ImplApp for BrowserProcessAppImpl { cmd.append_switch_with_value(Some(&CefString::from("ozone-platform")), Some(&CefString::from("wayland"))); } } + + #[cfg(target_os = "macos")] + { + // Hide user prompt asking for keychain access + cmd.append_switch(Some(&CefString::from("use-mock-keychain"))); + } } } diff --git a/desktop/src/cef/internal/display_handler.rs b/desktop/src/cef/internal/display_handler.rs index 4e075dc39a..de56609bd2 100644 --- a/desktop/src/cef/internal/display_handler.rs +++ b/desktop/src/cef/internal/display_handler.rs @@ -19,8 +19,13 @@ impl DisplayHandlerImpl { } } +#[cfg(not(target_os = "macos"))] +type CefCursorHandle = cef::CursorHandle; +#[cfg(target_os = "macos")] +type CefCursorHandle = *mut u8; + impl ImplDisplayHandler for DisplayHandlerImpl { - fn on_cursor_change(&self, _browser: Option<&mut cef::Browser>, _cursor: cef::CursorHandle, cursor_type: cef::CursorType, _custom_cursor_info: Option<&cef::CursorInfo>) -> ::std::os::raw::c_int { + fn on_cursor_change(&self, _browser: Option<&mut cef::Browser>, _cursor: CefCursorHandle, cursor_type: cef::CursorType, _custom_cursor_info: Option<&cef::CursorInfo>) -> ::std::os::raw::c_int { let cursor = match cursor_type.into() { CT_POINTER => CursorIcon::Default, CT_CROSS => CursorIcon::Crosshair, diff --git a/desktop/src/cef/texture_import/common.rs b/desktop/src/cef/texture_import/common.rs index ec5951f46d..a9b347373f 100644 --- a/desktop/src/cef/texture_import/common.rs +++ b/desktop/src/cef/texture_import/common.rs @@ -1,7 +1,6 @@ //! Common utilities and traits for texture import across platforms use crate::cef::texture_import::*; -use ash::vk; use cef::sys::cef_color_type_t; use wgpu::Device; @@ -20,10 +19,10 @@ pub mod format { #[cfg(not(target_os = "macos"))] /// Convert CEF color type to Vulkan format - pub fn cef_to_vulkan(format: cef_color_type_t) -> Result { + pub fn cef_to_vulkan(format: cef_color_type_t) -> Result { match format { - cef_color_type_t::CEF_COLOR_TYPE_BGRA_8888 => Ok(vk::Format::B8G8R8A8_UNORM), - cef_color_type_t::CEF_COLOR_TYPE_RGBA_8888 => Ok(vk::Format::R8G8B8A8_UNORM), + cef_color_type_t::CEF_COLOR_TYPE_BGRA_8888 => Ok(ash::vk::Format::B8G8R8A8_UNORM), + cef_color_type_t::CEF_COLOR_TYPE_RGBA_8888 => Ok(ash::vk::Format::R8G8B8A8_UNORM), _ => Err(TextureImportError::UnsupportedFormat { format }), } } @@ -63,8 +62,10 @@ pub mod texture { } /// Common Vulkan utilities +#[cfg(not(target_os = "macos"))] pub mod vulkan { use super::*; + use ash::vk; /// Find a suitable memory type index for Vulkan allocation pub fn find_memory_type_index(type_filter: u32, properties: vk::MemoryPropertyFlags, mem_properties: &vk::PhysicalDeviceMemoryProperties) -> Option { @@ -72,7 +73,6 @@ pub mod vulkan { } /// Check if the wgpu device is using Vulkan backend - #[cfg(not(target_os = "macos"))] pub fn is_vulkan_backend(device: &Device) -> bool { use wgpu::hal::api; let mut is_vulkan = false; diff --git a/desktop/src/cef/texture_import/iosurface.rs b/desktop/src/cef/texture_import/iosurface.rs index 65b4fdcc2a..04f6912460 100644 --- a/desktop/src/cef/texture_import/iosurface.rs +++ b/desktop/src/cef/texture_import/iosurface.rs @@ -3,9 +3,8 @@ use super::common::{format, texture}; use super::{TextureImportError, TextureImportResult, TextureImporter}; use cef::{AcceleratedPaintInfo, sys::cef_color_type_t}; -use core_foundation::base::{CFType, TCFType}; -use objc2_io_surface::{IOSurface, IOSurfaceRef}; -use objc2_metal::{MTLDevice, MTLPixelFormat, MTLTexture, MTLTextureDescriptor, MTLTextureType, MTLTextureUsage}; +use metal::foreign_types::ForeignType; +use metal::{MTLPixelFormat, MTLTextureType, MTLTextureUsage, Texture}; use std::os::raw::c_void; use wgpu::hal::api; @@ -19,7 +18,7 @@ pub struct IOSurfaceImporter { impl TextureImporter for IOSurfaceImporter { fn new(info: &AcceleratedPaintInfo) -> Self { Self { - handle: info.shared_texture_handle, + handle: info.shared_texture_io_surface, format: *info.format.as_ref(), width: info.extra.coded_size.width as u32, height: info.extra.coded_size.height as u32, @@ -58,37 +57,31 @@ impl TextureImporter for IOSurfaceImporter { impl IOSurfaceImporter { fn import_via_metal(&self, device: &wgpu::Device) -> TextureImportResult { // Get wgpu's Metal device - use wgpu::{hal::Api, wgc::api::Metal}; + use wgpu::wgc::api::Metal; let hal_texture = unsafe { - device.as_hal::(|device| { - let Some(device) = device else { + device.as_hal::(|hal_device| { + let Some(hal_device) = hal_device else { return Err(TextureImportError::HardwareUnavailable { reason: "Device is not using Metal backend".to_string(), }); }; // Import IOSurface handle into Metal texture - let metal_texture = self.import_iosurface_to_metal(device)?; + let metal_texture = self.import_iosurface_to_metal_texture(hal_device)?; // Wrap Metal texture in wgpu-hal texture + // texture_from_raw signature: (texture, format, texture_type, mip_levels, sample_count, copy_extent) let hal_texture = ::Device::texture_from_raw( metal_texture, - &wgpu::hal::TextureDescriptor { - label: Some("CEF IOSurface Texture"), - size: wgpu::Extent3d { - width: self.width, - height: self.height, - depth_or_array_layers: 1, - }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: format::cef_to_wgpu(self.format)?, - usage: wgpu::hal::TextureUses::RESOURCE, - memory_flags: wgpu::hal::MemoryFlags::empty(), - view_formats: vec![], + format::cef_to_wgpu(self.format)?, + MTLTextureType::D2, + 1, // mip_level_count + 1, // sample_count + wgpu::hal::CopyExtent { + width: self.width, + height: self.height, + depth: 1, }, - None, // drop_callback ); Ok(hal_texture) @@ -119,46 +112,61 @@ impl IOSurfaceImporter { Ok(texture) } - fn import_iosurface_to_metal(&self, hal_device: &::Device) -> Result<::Texture, TextureImportError> { + fn import_iosurface_to_metal_texture(&self, hal_device: &::Device) -> Result { // Validate dimensions if self.width == 0 || self.height == 0 { return Err(TextureImportError::InvalidHandle("Invalid IOSurface texture dimensions".to_string())); } - // Convert handle to IOSurface - let iosurface = unsafe { - let cf_type = CFType::wrap_under_get_rule(self.handle as IOSurfaceRef); - IOSurface::from(cf_type) - }; - // Get the Metal device from wgpu-hal let metal_device = hal_device.raw_device(); // Convert CEF format to Metal pixel format let metal_format = self.cef_to_metal_format(self.format)?; - // Create Metal texture descriptor - let texture_descriptor = MTLTextureDescriptor::new(); - texture_descriptor.setTextureType(MTLTextureType::Type2D); - texture_descriptor.setPixelFormat(metal_format); - texture_descriptor.setWidth(self.width as usize); - texture_descriptor.setHeight(self.height as usize); - texture_descriptor.setDepth(1); - texture_descriptor.setMipmapLevelCount(1); - texture_descriptor.setSampleCount(1); - texture_descriptor.setUsage(MTLTextureUsage::ShaderRead); - - // Create Metal texture from IOSurface - let metal_texture = unsafe { metal_device.newTextureWithDescriptor_iosurface_plane(&texture_descriptor, &iosurface, 0) }; - - let Some(metal_texture) = metal_texture else { - return Err(TextureImportError::PlatformError { - message: "Failed to create Metal texture from IOSurface".to_string(), - }); - }; + // Create Metal texture from IOSurface using objc runtime + // We need to use raw objc because the metal crate doesn't expose IOSurface creation directly + #[allow(unexpected_cfgs)] // Suppress objc crate internal cfg warnings + unsafe { + use objc::runtime::Object; + use objc::{class, msg_send, sel, sel_impl}; + + let iosurface = self.handle; + + // Create texture descriptor using NSObject/Objective-C + let descriptor_class = class!(MTLTextureDescriptor); + let descriptor: *mut Object = msg_send![descriptor_class, new]; + + // Set descriptor properties + let _: () = msg_send![descriptor, setTextureType: MTLTextureType::D2]; + let _: () = msg_send![descriptor, setPixelFormat: metal_format]; + let _: () = msg_send![descriptor, setWidth: self.width as u64]; + let _: () = msg_send![descriptor, setHeight: self.height as u64]; + let _: () = msg_send![descriptor, setDepth: 1u64]; + let _: () = msg_send![descriptor, setMipmapLevelCount: 1u64]; + let _: () = msg_send![descriptor, setSampleCount: 1u64]; + let _: () = msg_send![descriptor, setArrayLength: 1u64]; + let _: () = msg_send![descriptor, setUsage: MTLTextureUsage::ShaderRead.bits()]; + + // Get device pointer + let device_ptr = metal_device.lock().as_ptr(); + + // Call newTextureWithDescriptor:iosurface:plane: + let metal_texture: *mut Object = msg_send![device_ptr, newTextureWithDescriptor:descriptor iosurface:iosurface plane:0u64]; + + // Release the descriptor + let _: () = msg_send![descriptor, release]; + + if metal_texture.is_null() { + return Err(TextureImportError::PlatformError { + message: "Failed to create Metal texture from IOSurface".to_string(), + }); + } - tracing::trace!("Successfully created Metal texture from IOSurface"); - Ok(metal_texture) + // Cast to correct type and wrap in metal::Texture + let mtl_texture = metal_texture as *mut metal::MTLTexture; + Ok(Texture::from_ptr(mtl_texture)) + } } fn cef_to_metal_format(&self, format: cef_color_type_t) -> Result { diff --git a/desktop/src/cef/texture_import/mod.rs b/desktop/src/cef/texture_import/mod.rs index 485acf4d11..9e2ea0b6c4 100644 --- a/desktop/src/cef/texture_import/mod.rs +++ b/desktop/src/cef/texture_import/mod.rs @@ -10,13 +10,6 @@ //! - **Windows**: D3D11 shared textures via Vulkan interop //! - **macOS**: IOSurface via Metal native API //! -//! # Usage -//! -//! ```no_run -//! // Import texture with automatic platform detection -//! let texture = shared_handle.import_texture(&device)?; -//! ``` -//! //! # Features //! //! - `accelerated_paint` - Base feature for texture import @@ -54,6 +47,7 @@ pub enum TextureImportError { HardwareUnavailable { reason: String }, #[error("Vulkan operation failed: {operation}")] + #[cfg(not(target_os = "macos"))] VulkanError { operation: String }, #[error("Platform-specific error: {message}")] diff --git a/desktop/src/lib.rs b/desktop/src/lib.rs new file mode 100644 index 0000000000..04a99182af --- /dev/null +++ b/desktop/src/lib.rs @@ -0,0 +1,80 @@ +use clap::Parser; +use std::process::exit; +use tracing_subscriber::EnvFilter; +use winit::event_loop::EventLoop; + +pub(crate) mod consts; + +mod app; +mod cef; +mod cli; +mod dirs; +mod event; +mod native_window; +mod persist; +mod render; + +mod gpu_context; + +use app::App; +use cef::CefHandler; +use cli::Cli; +use event::CreateAppEventSchedulerEventLoopExt; + +pub fn start() { + tracing_subscriber::fmt().with_env_filter(EnvFilter::from_default_env()).init(); + + let cef_context_builder = cef::CefContextBuilder::::new(); + + if cef_context_builder.is_sub_process() { + // We are in a CEF subprocess + // This will block until the CEF subprocess quits + let error = cef_context_builder.execute_sub_process(); + tracing::warn!("Cef subprocess failed with error: {error}"); + return; + } + + let cli = Cli::parse(); + + let wgpu_context = futures::executor::block_on(gpu_context::create_wgpu_context()); + + let event_loop = EventLoop::new().unwrap(); + let (app_event_sender, app_event_receiver) = std::sync::mpsc::channel(); + let app_event_scheduler = event_loop.create_app_event_scheduler(app_event_sender); + + let (window_size_sender, window_size_receiver) = std::sync::mpsc::channel(); + + let cef_handler = cef::CefHandler::new(wgpu_context.clone(), app_event_scheduler.clone(), window_size_receiver); + let cef_context = match cef_context_builder.initialize(cef_handler, cli.disable_ui_acceleration) { + Ok(c) => { + tracing::info!("CEF initialized successfully"); + c + } + Err(cef::InitError::AlreadyRunning) => { + tracing::error!("Another instance is already running, Exiting."); + exit(0); + } + Err(cef::InitError::InitializationFailed(code)) => { + tracing::error!("Cef initialization failed with code: {code}"); + exit(1); + } + Err(cef::InitError::BrowserCreationFailed) => { + tracing::error!("Failed to create CEF browser"); + exit(1); + } + Err(cef::InitError::RequestContextCreationFailed) => { + tracing::error!("Failed to create CEF request context"); + exit(1); + } + }; + + let mut app = App::new(Box::new(cef_context), window_size_sender, wgpu_context, app_event_receiver, app_event_scheduler, cli.files); + + event_loop.run_app(&mut app).unwrap(); +} + +pub fn start_helper() { + let cef_context_builder = cef::CefContextBuilder::::new_helper(); + assert!(cef_context_builder.is_sub_process()); + cef_context_builder.execute_sub_process(); +} diff --git a/desktop/src/main.rs b/desktop/src/main.rs index 430db35648..5420d97bbe 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -1,74 +1,3 @@ -use clap::Parser; -use std::process::exit; -use tracing_subscriber::EnvFilter; -use winit::event_loop::EventLoop; - -pub(crate) mod consts; - -mod app; -mod cef; -mod cli; -mod dirs; -mod event; -mod native_window; -mod persist; -mod render; - -mod gpu_context; - -use app::App; -use cef::CefHandler; -use cli::Cli; -use event::CreateAppEventSchedulerEventLoopExt; - fn main() { - tracing_subscriber::fmt().with_env_filter(EnvFilter::from_default_env()).init(); - - let cef_context_builder = cef::CefContextBuilder::::new(); - - if cef_context_builder.is_sub_process() { - // We are in a CEF subprocess - // This will block until the CEF subprocess quits - let error = cef_context_builder.execute_sub_process(); - tracing::warn!("Cef subprocess failed with error: {error}"); - return; - } - - let cli = Cli::parse(); - - let wgpu_context = futures::executor::block_on(gpu_context::create_wgpu_context()); - - let event_loop = EventLoop::new().unwrap(); - let (app_event_sender, app_event_receiver) = std::sync::mpsc::channel(); - let app_event_scheduler = event_loop.create_app_event_scheduler(app_event_sender); - - let (window_size_sender, window_size_receiver) = std::sync::mpsc::channel(); - - let cef_handler = cef::CefHandler::new(wgpu_context.clone(), app_event_scheduler.clone(), window_size_receiver); - let cef_context = match cef_context_builder.initialize(cef_handler, cli.disable_ui_acceleration) { - Ok(c) => { - tracing::info!("CEF initialized successfully"); - c - } - Err(cef::InitError::AlreadyRunning) => { - tracing::error!("Another instance is already running, Exiting."); - exit(0); - } - Err(cef::InitError::InitializationFailed(code)) => { - tracing::error!("Cef initialization failed with code: {code}"); - exit(1); - } - Err(cef::InitError::BrowserCreationFailed) => { - tracing::error!("Failed to create CEF browser"); - exit(1); - } - Err(cef::InitError::RequestContextCreationFailed) => { - tracing::error!("Failed to create CEF request context"); - exit(1); - } - }; - - let mut app = App::new(Box::new(cef_context), window_size_sender, wgpu_context, app_event_receiver, app_event_scheduler, cli.files); - - event_loop.run_app(&mut app).unwrap(); + graphite_desktop::start(); } diff --git a/desktop/src/native_window.rs b/desktop/src/native_window.rs index 80cadf47dc..154ffcb316 100644 --- a/desktop/src/native_window.rs +++ b/desktop/src/native_window.rs @@ -50,6 +50,15 @@ impl NativeWindowHandle { } } + #[cfg(target_os = "macos")] + { + let mac_window = winit::platform::macos::WindowAttributesMacOS::default() + .with_titlebar_transparent(true) + .with_fullsize_content_view(true) + .with_title_hidden(true); + window = window.with_platform_attributes(Box::new(mac_window)); + } + window } #[allow(unused_variables)]