mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 07:18:04 +08:00
* Extract CEF rendered UI into a separate process and crate * Review * Review * Review * Review * Remove necessary workarounds * Block on frame copy ack * Crop and resample frames correctly * Skip blank frames * Fix deps * Fix fmt * Fix clippy warning * Review * Fix todo
64 lines
2.1 KiB
Rust
64 lines
2.1 KiB
Rust
use objc2::rc::Retained;
|
|
use objc2::runtime::Bool;
|
|
use objc2::{ClassType, define_class, msg_send};
|
|
use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSEvent, NSResponder};
|
|
use objc2_foundation::NSObject;
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
use std::time::Duration;
|
|
|
|
use cef::application_mac::{CefAppProtocol, CrAppControlProtocol, CrAppProtocol};
|
|
|
|
static HANDLING_SEND_EVENT: AtomicBool = AtomicBool::new(false);
|
|
|
|
define_class!(
|
|
#[unsafe(super(NSApplication, NSResponder, NSObject))]
|
|
#[name = "GraphiteCefHostApplication"]
|
|
struct CefHostApplication;
|
|
|
|
unsafe impl CrAppProtocol for CefHostApplication {
|
|
#[unsafe(method(isHandlingSendEvent))]
|
|
fn is_handling_send_event(&self) -> Bool {
|
|
Bool::new(HANDLING_SEND_EVENT.load(Ordering::Relaxed))
|
|
}
|
|
}
|
|
|
|
unsafe impl CrAppControlProtocol for CefHostApplication {
|
|
#[unsafe(method(setHandlingSendEvent:))]
|
|
fn set_handling_send_event(&self, handling: Bool) {
|
|
HANDLING_SEND_EVENT.store(handling.as_bool(), Ordering::Relaxed);
|
|
}
|
|
}
|
|
|
|
unsafe impl CefAppProtocol for CefHostApplication {}
|
|
|
|
impl CefHostApplication {
|
|
#[unsafe(method(sendEvent:))]
|
|
fn send_event(&self, event: &NSEvent) {
|
|
let was_handling = HANDLING_SEND_EVENT.swap(true, Ordering::Relaxed);
|
|
let _: () = unsafe { msg_send![super(self), sendEvent: event] };
|
|
HANDLING_SEND_EVENT.store(was_handling, Ordering::Relaxed);
|
|
}
|
|
}
|
|
);
|
|
|
|
pub(crate) fn install_application() {
|
|
let app: Retained<NSApplication> = unsafe { msg_send![CefHostApplication::class(), sharedApplication] };
|
|
app.setActivationPolicy(NSApplicationActivationPolicy::Prohibited);
|
|
}
|
|
|
|
pub(crate) fn spawn_parent_watchdog(main_pid: u32) {
|
|
let result = std::thread::Builder::new().name("parent-watchdog".to_string()).spawn(move || {
|
|
loop {
|
|
// SAFETY: getppid is always safe to call.
|
|
if unsafe { libc::getppid() } as u32 != main_pid {
|
|
tracing::warn!("Parent process is gone, exiting...");
|
|
std::process::exit(0);
|
|
}
|
|
std::thread::sleep(Duration::from_millis(500));
|
|
}
|
|
});
|
|
if let Err(e) = result {
|
|
tracing::error!("Failed to spawn parent watchdog: {e}");
|
|
}
|
|
}
|