2022-12-22 21:35:33 +02:00
|
|
|
#![allow(clippy::unnecessary_cast)]
|
|
|
|
|
|
2023-07-29 00:33:03 +02:00
|
|
|
use objc2::rc::{autoreleasepool, Id};
|
2024-01-14 05:19:23 +01:00
|
|
|
use objc2::{declare_class, mutability, ClassType, DeclaredClass};
|
2024-04-18 17:34:19 +02:00
|
|
|
use objc2_app_kit::{NSResponder, NSWindow};
|
|
|
|
|
use objc2_foundation::{MainThreadBound, MainThreadMarker, NSObject};
|
2022-09-02 18:46:18 +02:00
|
|
|
|
2024-01-31 17:29:59 +04:00
|
|
|
use super::event_loop::ActiveEventLoop;
|
2024-01-14 05:19:23 +01:00
|
|
|
use super::window_delegate::WindowDelegate;
|
|
|
|
|
use crate::error::OsError as RootOsError;
|
|
|
|
|
use crate::window::WindowAttributes;
|
2017-02-03 23:05:57 +11:00
|
|
|
|
2023-08-14 21:19:57 +02:00
|
|
|
pub(crate) struct Window {
|
|
|
|
|
window: MainThreadBound<Id<WinitWindow>>,
|
2024-01-14 05:19:23 +01:00
|
|
|
/// The window only keeps a weak reference to this, so we must keep it around here.
|
|
|
|
|
delegate: MainThreadBound<Id<WindowDelegate>>,
|
2023-08-14 21:19:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for Window {
|
|
|
|
|
fn drop(&mut self) {
|
2023-12-23 18:04:24 +01:00
|
|
|
self.window.get_on_main(|window| autoreleasepool(|_| window.close()))
|
2023-08-14 21:19:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Window {
|
2024-01-13 21:36:53 +01:00
|
|
|
pub(crate) fn new(
|
2024-01-31 17:29:59 +04:00
|
|
|
window_target: &ActiveEventLoop,
|
2023-08-14 21:19:57 +02:00
|
|
|
attributes: WindowAttributes,
|
|
|
|
|
) -> Result<Self, RootOsError> {
|
2024-01-14 05:19:23 +01:00
|
|
|
let mtm = window_target.mtm;
|
2024-01-17 23:37:28 +01:00
|
|
|
let delegate = autoreleasepool(|_| WindowDelegate::new(attributes, mtm))?;
|
2023-08-14 21:19:57 +02:00
|
|
|
Ok(Window {
|
2024-01-14 05:19:23 +01:00
|
|
|
window: MainThreadBound::new(delegate.window().retain(), mtm),
|
|
|
|
|
delegate: MainThreadBound::new(delegate, mtm),
|
2023-08-14 21:19:57 +02:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-14 05:19:23 +01:00
|
|
|
pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&WindowDelegate) + Send + 'static) {
|
2023-08-14 21:19:57 +02:00
|
|
|
// For now, don't actually do queuing, since it may be less predictable
|
|
|
|
|
self.maybe_wait_on_main(f)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) fn maybe_wait_on_main<R: Send>(
|
|
|
|
|
&self,
|
2024-01-14 05:19:23 +01:00
|
|
|
f: impl FnOnce(&WindowDelegate) -> R + Send,
|
2023-08-14 21:19:57 +02:00
|
|
|
) -> R {
|
2024-01-14 05:19:23 +01:00
|
|
|
self.delegate.get_on_main(|delegate| f(delegate))
|
2023-08-14 21:19:57 +02:00
|
|
|
}
|
2023-12-22 22:33:50 +01:00
|
|
|
|
|
|
|
|
#[cfg(feature = "rwh_06")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub(crate) fn raw_window_handle_rwh_06(
|
|
|
|
|
&self,
|
|
|
|
|
) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
2023-12-22 23:18:35 +01:00
|
|
|
if let Some(mtm) = MainThreadMarker::new() {
|
2024-01-14 05:19:23 +01:00
|
|
|
Ok(self.delegate.get(mtm).raw_window_handle_rwh_06())
|
2023-12-22 23:18:35 +01:00
|
|
|
} else {
|
|
|
|
|
Err(rwh_06::HandleError::Unavailable)
|
|
|
|
|
}
|
2023-12-22 22:33:50 +01:00
|
|
|
}
|
2023-12-26 20:13:02 +01:00
|
|
|
|
|
|
|
|
#[cfg(feature = "rwh_06")]
|
|
|
|
|
#[inline]
|
|
|
|
|
pub(crate) fn raw_display_handle_rwh_06(
|
|
|
|
|
&self,
|
|
|
|
|
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
|
|
|
|
Ok(rwh_06::RawDisplayHandle::AppKit(rwh_06::AppKitDisplayHandle::new()))
|
|
|
|
|
}
|
2023-08-14 21:19:57 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-03 23:05:57 +11:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
2022-03-18 14:09:39 +01:00
|
|
|
pub struct WindowId(pub usize);
|
2017-02-03 23:05:57 +11:00
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
impl WindowId {
|
2021-08-30 19:40:02 +02:00
|
|
|
pub const unsafe fn dummy() -> Self {
|
2022-03-18 14:09:39 +01:00
|
|
|
Self(0)
|
2018-12-21 09:51:48 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 14:27:19 +03:00
|
|
|
impl From<WindowId> for u64 {
|
|
|
|
|
fn from(window_id: WindowId) -> Self {
|
|
|
|
|
window_id.0 as u64
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<u64> for WindowId {
|
|
|
|
|
fn from(raw_id: u64) -> Self {
|
|
|
|
|
Self(raw_id as usize)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-02 18:46:18 +02:00
|
|
|
declare_class!(
|
2022-09-08 16:45:29 +02:00
|
|
|
#[derive(Debug)]
|
2023-12-23 18:04:24 +01:00
|
|
|
pub struct WinitWindow;
|
2023-07-29 00:33:03 +02:00
|
|
|
|
2022-09-02 18:46:18 +02:00
|
|
|
unsafe impl ClassType for WinitWindow {
|
|
|
|
|
#[inherits(NSResponder, NSObject)]
|
2022-09-08 16:45:29 +02:00
|
|
|
type Super = NSWindow;
|
2023-12-23 20:58:38 +01:00
|
|
|
type Mutability = mutability::MainThreadOnly;
|
2023-07-29 00:33:03 +02:00
|
|
|
const NAME: &'static str = "WinitWindow";
|
2022-06-08 11:50:26 -07:00
|
|
|
}
|
2022-01-23 21:35:26 +01:00
|
|
|
|
2024-01-14 05:19:23 +01:00
|
|
|
impl DeclaredClass for WinitWindow {}
|
2023-07-08 22:36:42 +03:00
|
|
|
|
2022-09-02 18:46:18 +02:00
|
|
|
unsafe impl WinitWindow {
|
2023-07-29 00:33:03 +02:00
|
|
|
#[method(canBecomeMainWindow)]
|
2022-09-02 18:46:18 +02:00
|
|
|
fn can_become_main_window(&self) -> bool {
|
|
|
|
|
trace_scope!("canBecomeMainWindow");
|
|
|
|
|
true
|
|
|
|
|
}
|
2022-01-23 21:35:26 +01:00
|
|
|
|
2023-07-29 00:33:03 +02:00
|
|
|
#[method(canBecomeKeyWindow)]
|
2022-09-02 18:46:18 +02:00
|
|
|
fn can_become_key_window(&self) -> bool {
|
|
|
|
|
trace_scope!("canBecomeKeyWindow");
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-04-28 18:10:06 +02:00
|
|
|
|
2023-08-14 21:19:57 +02:00
|
|
|
impl WinitWindow {
|
2024-01-14 05:19:23 +01:00
|
|
|
pub(super) fn id(&self) -> WindowId {
|
2022-09-08 16:45:29 +02:00
|
|
|
WindowId(self as *const Self as usize)
|
2017-02-03 23:05:57 +11:00
|
|
|
}
|
2019-05-01 17:03:30 -06:00
|
|
|
}
|