mod capture;
mod delegate;
pub use capture::*;
use std::{
fmt,
sync::atomic::{AtomicU64, Ordering},
};
use dispatch2::DispatchQueue;
use objc2::{MainThreadMarker, rc::Retained};
use objc2_app_kit::NSView;
#[derive(Default)]
pub(crate) struct AtomicSize(AtomicU64);
impl AtomicSize {
pub(crate) fn store(&self, width: u32, height: u32) {
self.0
.store((width as u64) << 32 | height as u64, Ordering::Relaxed);
}
pub(crate) fn load(&self) -> (u32, u32) {
let packed = self.0.load(Ordering::Relaxed);
((packed >> 32) as u32, packed as u32)
}
}
impl fmt::Debug for AtomicSize {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.load().fmt(f)
}
}
pub unsafe fn window_id_from_ns_view(ns_view: isize) -> Option<u32> {
let read = move || {
let view = unsafe { Retained::retain(ns_view as *mut NSView) }?;
u32::try_from(view.window()?.windowNumber()).ok()
};
match MainThreadMarker::new() {
Some(_) => read(),
None => {
let mut id = None;
DispatchQueue::main().exec_sync(|| id = read());
id
}
}
}