mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-12-23 10:11:54 +00:00
Desktop: Fixup MacOS build (#3295)
desktop mac os fixup Co-authored-by: Dennis Kobert <dennis@kobert.dev>
This commit is contained in:
parent
5acf50c1ef
commit
39f4ccf8e0
14 changed files with 218 additions and 183 deletions
49
Cargo.lock
generated
49
Cargo.lock
generated
|
|
@ -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",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ members = [
|
|||
"proc-macros",
|
||||
]
|
||||
default-members = [
|
||||
"desktop",
|
||||
"desktop/wrapper",
|
||||
"editor",
|
||||
"frontend/wasm",
|
||||
"libraries/dyn-any",
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#[cfg(not(target_os = "macos"))]
|
||||
mod multithreaded;
|
||||
mod singlethreaded;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<H: CefEventHandler> Send for CefContextBuilder<H> {}
|
|||
|
||||
impl<H: CefEventHandler> CefContextBuilder<H> {
|
||||
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<H: CefEventHandler> CefContextBuilder<H> {
|
|||
}
|
||||
}
|
||||
|
||||
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<impl CefContext, InitError> {
|
||||
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<H: CefEventHandler> CefContextBuilder<H> {
|
|||
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)?;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,12 @@ impl<H: CefEventHandler + Clone> ImplApp for BrowserProcessAppImpl<H> {
|
|||
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")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,13 @@ impl<H: CefEventHandler> DisplayHandlerImpl<H> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
type CefCursorHandle = cef::CursorHandle;
|
||||
#[cfg(target_os = "macos")]
|
||||
type CefCursorHandle = *mut u8;
|
||||
|
||||
impl<H: CefEventHandler> ImplDisplayHandler for DisplayHandlerImpl<H> {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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<vk::Format, TextureImportError> {
|
||||
pub fn cef_to_vulkan(format: cef_color_type_t) -> Result<ash::vk::Format, TextureImportError> {
|
||||
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<u32> {
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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::<api::Metal, _, _>(|device| {
|
||||
let Some(device) = device else {
|
||||
device.as_hal::<api::Metal, _, _>(|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 = <api::Metal as wgpu::hal::Api>::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: &<api::Metal as wgpu::hal::Api>::Device) -> Result<<api::Metal as wgpu::hal::Api>::Texture, TextureImportError> {
|
||||
fn import_iosurface_to_metal_texture(&self, hal_device: &<api::Metal as wgpu::hal::Api>::Device) -> Result<Texture, TextureImportError> {
|
||||
// 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 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};
|
||||
|
||||
// Create Metal texture from IOSurface
|
||||
let metal_texture = unsafe { metal_device.newTextureWithDescriptor_iosurface_plane(&texture_descriptor, &iosurface, 0) };
|
||||
let iosurface = self.handle;
|
||||
|
||||
let Some(metal_texture) = metal_texture else {
|
||||
return Err(TextureImportError::PlatformError {
|
||||
message: "Failed to create Metal texture from IOSurface".to_string(),
|
||||
});
|
||||
};
|
||||
// Create texture descriptor using NSObject/Objective-C
|
||||
let descriptor_class = class!(MTLTextureDescriptor);
|
||||
let descriptor: *mut Object = msg_send![descriptor_class, new];
|
||||
|
||||
tracing::trace!("Successfully created Metal texture from IOSurface");
|
||||
Ok(metal_texture)
|
||||
// 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(),
|
||||
});
|
||||
}
|
||||
|
||||
// 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<MTLPixelFormat, TextureImportError> {
|
||||
|
|
|
|||
|
|
@ -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}")]
|
||||
|
|
|
|||
80
desktop/src/lib.rs
Normal file
80
desktop/src/lib.rs
Normal file
|
|
@ -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::<CefHandler>::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::<CefHandler>::new_helper();
|
||||
assert!(cef_context_builder.is_sub_process());
|
||||
cef_context_builder.execute_sub_process();
|
||||
}
|
||||
|
|
@ -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::<CefHandler>::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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue