mod context;
mod cursor;
mod error;
mod keyboard;
mod view;
mod window;
use crate::platform::macos::view::BaseviewView;
use crate::wrappers::appkit::{extract_raw_window_handle, ParentWindowHandleError, View};
pub use context::WindowContext;
use dispatch2::MainThreadBound;
pub use error::Error;
use objc2::__framework_prelude::Retained;
use objc2::rc::Weak;
use objc2::{MainThreadMarker, MainThreadOnly};
use objc2_app_kit::NSView;
use raw_window_handle::{DisplayHandle, HasWindowHandle};
use std::fmt;
use std::fmt::Formatter;
pub use window::*;
pub(crate) type Result<T> = std::result::Result<T, Error>;
#[cfg(feature = "opengl")]
pub mod gl;
pub struct PlatformHandle {
inner: MainThreadBound<Weak<View<BaseviewView>>>,
}
impl PlatformHandle {
pub fn window_handle(&self) -> Option<raw_window_handle::WindowHandle<'_>> {
let mtm = MainThreadMarker::new()?;
let view = self.inner.get(mtm);
View::window_handle_from_weak(view)
}
pub fn display_handle(&self) -> DisplayHandle<'_> {
DisplayHandle::appkit()
}
}
impl Clone for PlatformHandle {
fn clone(&self) -> Self {
let mtm = unsafe { MainThreadMarker::new_unchecked() };
let view = self.inner.get(mtm);
Self { inner: MainThreadBound::new(view.clone(), mtm) }
}
}
impl fmt::Debug for PlatformHandle {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
struct PtrFmt<'a>(&'a PlatformHandle);
impl fmt::Debug for PtrFmt<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let mtm = unsafe { MainThreadMarker::new_unchecked() };
match self.0.inner.get(mtm).load() {
Some(retained) => fmt::Pointer::fmt(&retained, f),
_ => f.write_str("(gone)"),
}
}
}
f.debug_struct("PlatformHandle (AppKit)").field("ns_view", &PtrFmt(self)).finish()
}
}
#[derive(Debug)]
pub struct ParentWindowHandle {
view: MainThreadBound<Retained<NSView>>,
}
impl ParentWindowHandle {
pub fn extract(
window: &impl HasWindowHandle,
) -> core::result::Result<Self, ParentWindowHandleError> {
let view = extract_raw_window_handle(window.window_handle()?)?;
let mtm = view.mtm();
Ok(Self { view: MainThreadBound::new(view, mtm) })
}
}
impl Clone for ParentWindowHandle {
fn clone(&self) -> Self {
let mtm = unsafe { MainThreadMarker::new_unchecked() };
let view = self.view.get(mtm);
Self { view: MainThreadBound::new(view.clone(), mtm) }
}
}
impl PartialEq for ParentWindowHandle {
fn eq(&self, other: &Self) -> bool {
let mtm = unsafe { MainThreadMarker::new_unchecked() };
Retained::eq(self.view.get(mtm), other.view.get(mtm))
}
}
impl Eq for ParentWindowHandle {}