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
128 changes: 117 additions & 11 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ open = { workspace = true }
rand = { workspace = true, features = ["thread_rng"] }
serde = { workspace = true }
clap = { workspace = true, features = ["derive"] }
pidlock = "0.2.2"
ctrlc = "3.5.1"

# Windows-specific dependencies
[target.'cfg(target_os = "windows")'.dependencies]
Expand Down
2 changes: 1 addition & 1 deletion desktop/bundle/src/mac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn bundle(out_dir: &Path, app_bin: &Path, helper_bin: &Path) -> PathBuf {

create_app(&app_dir, APP_ID, APP_NAME, app_bin, false);

for helper_type in [None, Some("GPU"), Some("Renderer"), Some("Plugin"), Some("Alerts")] {
for helper_type in [None, Some("GPU"), Some("Renderer")] {
let helper_id_suffix = helper_type.map(|t| format!(".{t}")).unwrap_or_default();
let helper_id = format!("{APP_ID}.helper{helper_id_suffix}");
let helper_name_suffix = helper_type.map(|t| format!(" ({t})")).unwrap_or_default();
Expand Down
8 changes: 8 additions & 0 deletions desktop/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ impl App {
app_event_scheduler: AppEventScheduler,
launch_documents: Vec<PathBuf>,
) -> Self {
let ctrlc_app_event_scheduler = app_event_scheduler.clone();
ctrlc::set_handler(move || {
tracing::info!("Termination signal received, exiting...");
ctrlc_app_event_scheduler.schedule(AppEvent::CloseWindow);
})
.expect("Error setting Ctrl-C handler");

let rendering_app_event_scheduler = app_event_scheduler.clone();
let (start_render_sender, start_render_receiver) = std::sync::mpsc::sync_channel(1);
std::thread::spawn(move || {
Expand Down Expand Up @@ -365,6 +372,7 @@ impl App {
tracing::info!("Exiting main event loop");
event_loop.exit();
}
#[cfg(target_os = "macos")]
AppEvent::MenuEvent { id } => {
self.dispatch_desktop_wrapper_message(DesktopWrapperMessage::MenuEvent { id });
}
Expand Down
4 changes: 3 additions & 1 deletion desktop/src/cef/context/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use super::CefContext;
use super::singlethreaded::SingleThreadedCefContext;
use crate::cef::CefEventHandler;
use crate::cef::consts::{RESOURCE_DOMAIN, RESOURCE_SCHEME};
use crate::cef::dirs::create_instance_dir;
use crate::cef::dirs::{create_instance_dir, delete_instance_dirs};
use crate::cef::input::InputState;
use crate::cef::internal::{BrowserProcessAppImpl, BrowserProcessClientImpl, RenderProcessAppImpl, SchemeHandlerFactoryImpl};

Expand Down Expand Up @@ -85,6 +85,7 @@ impl<H: CefEventHandler> CefContextBuilder<H> {

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

let exe = std::env::current_exe().expect("cannot get current exe path");
Expand All @@ -105,6 +106,7 @@ impl<H: CefEventHandler> CefContextBuilder<H> {

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

let settings = Settings {
Expand Down
14 changes: 13 additions & 1 deletion desktop/src/cef/context/singlethreaded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,19 @@ impl CefContext for SingleThreadedCefContext {
impl Drop for SingleThreadedCefContext {
fn drop(&mut self) {
cef::shutdown();
std::fs::remove_dir_all(&self.instance_dir).expect("Failed to remove CEF cache directory");

// Sometimes some CEF processes still linger at this point and hold file handles to the cache directory.
// To mitigate this, we try to remove the directory multiple times with some delay.
// TODO: find a better solution if possible.
for _ in 0..30 {
match std::fs::remove_dir_all(&self.instance_dir) {
Ok(_) => break,
Err(e) => {
tracing::warn!("Failed to remove CEF cache directory, retrying...: {e}");
std::thread::sleep(std::time::Duration::from_millis(100));
}
}
}
}
}

Expand Down
16 changes: 14 additions & 2 deletions desktop/src/cef/dirs.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
use std::path::PathBuf;

use crate::dirs::{ensure_dir_exists, graphite_data_dir};
use crate::dirs::{app_data_dir, ensure_dir_exists};

static CEF_DIR_NAME: &str = "browser";

pub(crate) fn delete_instance_dirs() {
let cef_dir = app_data_dir().join(CEF_DIR_NAME);
if let Ok(entries) = std::fs::read_dir(&cef_dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.is_dir() {
let _ = std::fs::remove_dir_all(&path);
}
}
}
}

pub(crate) fn create_instance_dir() -> PathBuf {
let instance_id: String = (0..32).map(|_| format!("{:x}", rand::random::<u8>() % 16)).collect();
let path = graphite_data_dir().join(CEF_DIR_NAME).join(instance_id);
let path = app_data_dir().join(CEF_DIR_NAME).join(instance_id);
ensure_dir_exists(&path);
path
}
11 changes: 6 additions & 5 deletions desktop/src/cef/input.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use cef::sys::{cef_event_flags_t, cef_key_event_type_t, cef_mouse_button_type_t};
use cef::sys::{cef_key_event_type_t, cef_mouse_button_type_t};
use cef::{Browser, ImplBrowser, ImplBrowserHost, KeyEvent, MouseEvent};
use winit::event::{ButtonSource, ElementState, MouseButton, MouseScrollDelta, WindowEvent};

mod keymap;
use keymap::{ToCharRepresentation, ToNativeKeycode, ToVKBits};

mod state;
pub(crate) use state::InputState;
pub(crate) use state::{CefModifiers, InputState};

use super::consts::{PINCH_ZOOM_SPEED, SCROLL_LINE_HEIGHT, SCROLL_LINE_WIDTH, SCROLL_SPEED_X, SCROLL_SPEED_Y};

Expand Down Expand Up @@ -129,9 +129,10 @@ pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputStat
}
let Some(host) = browser.host() else { return };

let mut mouse_event: MouseEvent = input_state.into();
mouse_event.modifiers |= cef_event_flags_t::EVENTFLAG_CONTROL_DOWN.0 as u32;
mouse_event.modifiers |= cef_event_flags_t::EVENTFLAG_PRECISION_SCROLLING_DELTA.0 as u32;
let mouse_event = MouseEvent {
modifiers: CefModifiers::PINCH_MODIFIERS.into(),
..input_state.into()
};

let delta = (delta * PINCH_ZOOM_SPEED).round() as i32;

Expand Down
Loading