Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ rfd = { workspace = true }
open = { workspace = true }
rand = { workspace = true, features = ["thread_rng"] }
serde = { workspace = true }
clap = { workspace = true, features = ["derive"] }

# Hardware acceleration dependencies
ash = { version = "0.38", optional = true }
Expand Down
43 changes: 33 additions & 10 deletions desktop/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use rfd::AsyncFileDialog;
use std::fs;
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
Expand Down Expand Up @@ -39,6 +41,7 @@ pub(crate) struct App {
web_communication_initialized: bool,
web_communication_startup_buffer: Vec<Vec<u8>>,
persistent_data: PersistentData,
launch_documents: Vec<PathBuf>,
}

impl App {
Expand All @@ -48,6 +51,7 @@ impl App {
wgpu_context: WgpuContext,
app_event_receiver: Receiver<AppEvent>,
app_event_scheduler: AppEventScheduler,
launch_documents: Vec<PathBuf>,
) -> Self {
let rendering_app_event_scheduler = app_event_scheduler.clone();
let (start_render_sender, start_render_receiver) = std::sync::mpsc::sync_channel(1);
Expand Down Expand Up @@ -79,6 +83,7 @@ impl App {
web_communication_startup_buffer: Vec::new(),
persistent_data,
native_window: Default::default(),
launch_documents,
}
}

Expand All @@ -102,7 +107,7 @@ impl App {
let show_dialog = async move { dialog.pick_file().await.map(|f| f.path().to_path_buf()) };

if let Some(path) = futures::executor::block_on(show_dialog)
&& let Ok(content) = std::fs::read(&path)
&& let Ok(content) = fs::read(&path)
{
let message = DesktopWrapperMessage::OpenFileDialogResult { path, content, context };
app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
Expand Down Expand Up @@ -135,7 +140,7 @@ impl App {
});
}
DesktopFrontendMessage::WriteFile { path, content } => {
if let Err(e) = std::fs::write(&path, content) {
if let Err(e) = fs::write(&path, content) {
tracing::error!("Failed to write file {}: {}", path.display(), e);
}
}
Expand Down Expand Up @@ -197,6 +202,14 @@ impl App {
DesktopFrontendMessage::PersistenceUpdateDocumentsList { ids } => {
self.persistent_data.set_document_order(ids);
}
DesktopFrontendMessage::PersistenceWritePreferences { preferences } => {
self.persistent_data.write_preferences(preferences);
}
DesktopFrontendMessage::PersistenceLoadPreferences => {
let preferences = self.persistent_data.load_preferences();
let message = DesktopWrapperMessage::LoadPreferences { preferences };
responses.push(message);
}
DesktopFrontendMessage::PersistenceLoadCurrentDocument => {
if let Some((id, document)) = self.persistent_data.current_document() {
let message = DesktopWrapperMessage::LoadDocument {
Expand Down Expand Up @@ -232,13 +245,23 @@ impl App {
responses.push(message);
}
}
DesktopFrontendMessage::PersistenceWritePreferences { preferences } => {
self.persistent_data.write_preferences(preferences);
}
DesktopFrontendMessage::PersistenceLoadPreferences => {
let preferences = self.persistent_data.load_preferences();
let message = DesktopWrapperMessage::LoadPreferences { preferences };
responses.push(message);
DesktopFrontendMessage::OpenLaunchDocuments => {
if self.launch_documents.is_empty() {
return;
}
let app_event_scheduler = self.app_event_scheduler.clone();
let launch_documents = std::mem::take(&mut self.launch_documents);
let _ = thread::spawn(move || {
for path in launch_documents {
tracing::info!("Opening file from command line: {}", path.display());
if let Ok(content) = fs::read(&path) {
let message = DesktopWrapperMessage::OpenFile { path, content };
app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
} else {
tracing::error!("Failed to read file: {}", path.display());
}
}
});
}
}
}
Expand Down Expand Up @@ -389,7 +412,7 @@ impl ApplicationHandler for App {
}
WindowEvent::DragDropped { paths, .. } => {
for path in paths {
match std::fs::read(&path) {
match fs::read(&path) {
Ok(content) => {
let message = DesktopWrapperMessage::OpenFile { path, content };
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(message));
Expand Down
19 changes: 13 additions & 6 deletions desktop/src/cef/context/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
}

#[cfg(target_os = "macos")]
pub(crate) fn initialize(self, event_handler: H) -> Result<impl CefContext, InitError> {
pub(crate) fn initialize(self, event_handler: H, disable_gpu_acceleration: bool) -> Result<impl CefContext, InitError> {
let instance_dir = create_instance_dir();

let settings = Settings {
Expand All @@ -77,11 +77,11 @@ impl<H: CefEventHandler> CefContextBuilder<H> {

self.initialize_inner(&event_handler, settings)?;

create_browser(event_handler, instance_dir)
create_browser(event_handler, instance_dir, disable_gpu_acceleration)
}

#[cfg(not(target_os = "macos"))]
pub(crate) fn initialize(self, event_handler: H) -> Result<impl CefContext, InitError> {
pub(crate) fn initialize(self, event_handler: H, disable_gpu_acceleration: bool) -> Result<impl CefContext, InitError> {
let instance_dir = create_instance_dir();

let settings = Settings {
Expand All @@ -94,7 +94,7 @@ impl<H: CefEventHandler> CefContextBuilder<H> {

self.initialize_inner(&event_handler, settings)?;

super::multithreaded::run_on_ui_thread(move || match create_browser(event_handler, instance_dir) {
super::multithreaded::run_on_ui_thread(move || match create_browser(event_handler, instance_dir, disable_gpu_acceleration) {
Ok(context) => {
super::multithreaded::CONTEXT.with(|b| {
*b.borrow_mut() = Some(context);
Expand Down Expand Up @@ -125,14 +125,21 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
}
}

fn create_browser<H: CefEventHandler>(event_handler: H, instance_dir: PathBuf) -> Result<SingleThreadedCefContext, InitError> {
fn create_browser<H: CefEventHandler>(event_handler: H, instance_dir: PathBuf, disable_gpu_acceleration: bool) -> Result<SingleThreadedCefContext, InitError> {
let render_handler = RenderHandler::new(RenderHandlerImpl::new(event_handler.clone()));
let mut client = Client::new(BrowserProcessClientImpl::new(render_handler, event_handler.clone()));

#[cfg(feature = "accelerated_paint")]
let use_accelerated_paint = if disable_gpu_acceleration {
false
} else {
crate::cef::platform::should_enable_hardware_acceleration()
};

let window_info = WindowInfo {
windowless_rendering_enabled: 1,
#[cfg(feature = "accelerated_paint")]
shared_texture_enabled: if crate::cef::platform::should_enable_hardware_acceleration() { 1 } else { 0 },
shared_texture_enabled: use_accelerated_paint as i32,
..Default::default()
};

Expand Down
9 changes: 9 additions & 0 deletions desktop/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[derive(clap::Parser)]
#[clap(name = "graphite-editor", version)]
pub struct Cli {
#[arg(help = "Files to open on startup")]
pub files: Vec<std::path::PathBuf>,

#[arg(long, action = clap::ArgAction::SetTrue, help = "Disable hardware accelerated UI rendering")]
pub disable_ui_acceleration: bool,
}
9 changes: 7 additions & 2 deletions desktop/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use clap::Parser;
use std::process::exit;
use tracing_subscriber::EnvFilter;
use winit::event_loop::EventLoop;
Expand All @@ -6,6 +7,7 @@ pub(crate) mod consts;

mod app;
mod cef;
mod cli;
mod dirs;
mod event;
mod native_window;
Expand All @@ -16,6 +18,7 @@ mod gpu_context;

use app::App;
use cef::CefHandler;
use cli::Cli;
use event::CreateAppEventSchedulerEventLoopExt;

fn main() {
Expand All @@ -31,6 +34,8 @@ fn main() {
return;
}

let cli = Cli::parse();

let wgpu_context = futures::executor::block_on(gpu_context::create_wgpu_context());

let event_loop = EventLoop::new().unwrap();
Expand All @@ -40,7 +45,7 @@ fn main() {
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) {
let cef_context = match cef_context_builder.initialize(cef_handler, cli.disable_ui_acceleration) {
Ok(c) => {
tracing::info!("CEF initialized successfully");
c
Expand All @@ -63,7 +68,7 @@ fn main() {
}
};

let mut app = App::new(Box::new(cef_context), window_size_sender, wgpu_context, app_event_receiver, app_event_scheduler);
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();
}
3 changes: 3 additions & 0 deletions desktop/wrapper/src/intercept_frontend_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ pub(super) fn intercept_frontend_message(dispatcher: &mut DesktopWrapperMessageD
FrontendMessage::TriggerLoadRestAutoSaveDocuments => {
dispatcher.respond(DesktopFrontendMessage::PersistenceLoadRemainingDocuments);
}
FrontendMessage::TriggerOpenLaunchDocuments => {
dispatcher.respond(DesktopFrontendMessage::OpenLaunchDocuments);
}
FrontendMessage::TriggerSavePreferences { preferences } => {
dispatcher.respond(DesktopFrontendMessage::PersistenceWritePreferences { preferences });
}
Expand Down
1 change: 1 addition & 0 deletions desktop/wrapper/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub use graphite_editor::messages::prelude::PreferencesMessageHandler as Prefere

pub enum DesktopFrontendMessage {
ToWeb(Vec<FrontendMessage>),
OpenLaunchDocuments,
OpenFileDialog {
title: String,
filters: Vec<FileFilter>,
Expand Down
1 change: 1 addition & 0 deletions editor/src/messages/frontend/frontend_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ pub enum FrontendMessage {
},
TriggerLoadFirstAutoSaveDocument,
TriggerLoadRestAutoSaveDocuments,
TriggerOpenLaunchDocuments,
TriggerLoadPreferences,
TriggerOpenDocument,
TriggerPaste,
Expand Down
2 changes: 2 additions & 0 deletions editor/src/messages/portfolio/portfolio_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio

// Tell frontend to finish loading persistent documents
responses.add(FrontendMessage::TriggerLoadRestAutoSaveDocuments);

responses.add(FrontendMessage::TriggerOpenLaunchDocuments);
}
PortfolioMessage::DocumentPassMessage { document_id, message } => {
if let Some(document) = self.documents.get_mut(&document_id) {
Expand Down
Loading