macOS RAII trace guards (#2150)
* Add TraceGuard to make tracing simpler * Add SharedStateMutexGuard to make tracing simpler * Add trace_scope macro * Add missing let binding in trace_scope!
This commit is contained in:
parent
51bb6b751e
commit
9229e2d88b
7 changed files with 176 additions and 135 deletions
|
|
@ -2,11 +2,11 @@ use raw_window_handle::{AppKitHandle, RawWindowHandle};
|
|||
use std::{
|
||||
collections::VecDeque,
|
||||
convert::TryInto,
|
||||
f64,
|
||||
f64, ops,
|
||||
os::raw::c_void,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, Mutex, Weak,
|
||||
Arc, Mutex, MutexGuard, Weak,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -251,13 +251,24 @@ lazy_static! {
|
|||
static ref WINDOW_CLASS: WindowClass = unsafe {
|
||||
let window_superclass = class!(NSWindow);
|
||||
let mut decl = ClassDecl::new("WinitWindow", window_superclass).unwrap();
|
||||
|
||||
pub extern "C" fn can_become_main_window(_: &Object, _: Sel) -> BOOL {
|
||||
trace_scope!("canBecomeMainWindow");
|
||||
YES
|
||||
}
|
||||
|
||||
pub extern "C" fn can_become_key_window(_: &Object, _: Sel) -> BOOL {
|
||||
trace_scope!("canBecomeKeyWindow");
|
||||
YES
|
||||
}
|
||||
|
||||
decl.add_method(
|
||||
sel!(canBecomeMainWindow),
|
||||
util::yes as extern "C" fn(&Object, Sel) -> BOOL,
|
||||
can_become_main_window as extern "C" fn(&Object, Sel) -> BOOL,
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(canBecomeKeyWindow),
|
||||
util::yes as extern "C" fn(&Object, Sel) -> BOOL,
|
||||
can_become_key_window as extern "C" fn(&Object, Sel) -> BOOL,
|
||||
);
|
||||
WindowClass(decl.register())
|
||||
};
|
||||
|
|
@ -311,11 +322,49 @@ impl From<WindowAttributes> for SharedState {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SharedStateMutexGuard<'a> {
|
||||
guard: MutexGuard<'a, SharedState>,
|
||||
called_from_fn: &'static str,
|
||||
}
|
||||
|
||||
impl<'a> SharedStateMutexGuard<'a> {
|
||||
#[inline]
|
||||
pub(crate) fn new(guard: MutexGuard<'a, SharedState>, called_from_fn: &'static str) -> Self {
|
||||
trace!("Locked shared state in `{}`", called_from_fn);
|
||||
Self {
|
||||
guard,
|
||||
called_from_fn,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Deref for SharedStateMutexGuard<'_> {
|
||||
type Target = SharedState;
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.guard.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::DerefMut for SharedStateMutexGuard<'_> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.guard.deref_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SharedStateMutexGuard<'_> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
trace!("Unlocked shared state in `{}`", self.called_from_fn);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UnownedWindow {
|
||||
pub ns_window: IdRef, // never changes
|
||||
pub ns_view: IdRef, // never changes
|
||||
input_context: IdRef, // never changes
|
||||
pub shared_state: Arc<Mutex<SharedState>>,
|
||||
shared_state: Arc<Mutex<SharedState>>,
|
||||
decorations: AtomicBool,
|
||||
cursor_state: Weak<Mutex<CursorState>>,
|
||||
pub inner_rect: Option<PhysicalSize<u32>>,
|
||||
|
|
@ -420,6 +469,14 @@ impl UnownedWindow {
|
|||
Ok((window, delegate))
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub(crate) fn lock_shared_state(
|
||||
&self,
|
||||
called_from_fn: &'static str,
|
||||
) -> SharedStateMutexGuard<'_> {
|
||||
SharedStateMutexGuard::new(self.shared_state.lock().unwrap(), called_from_fn)
|
||||
}
|
||||
|
||||
fn set_style_mask_async(&self, mask: NSWindowStyleMask) {
|
||||
unsafe { util::set_style_mask_async(*self.ns_window, *self.ns_view, mask) };
|
||||
}
|
||||
|
|
@ -530,10 +587,8 @@ impl UnownedWindow {
|
|||
#[inline]
|
||||
pub fn set_resizable(&self, resizable: bool) {
|
||||
let fullscreen = {
|
||||
trace!("Locked shared state in `set_resizable`");
|
||||
let mut shared_state_lock = self.shared_state.lock().unwrap();
|
||||
let mut shared_state_lock = self.lock_shared_state("set_resizable");
|
||||
shared_state_lock.resizable = resizable;
|
||||
trace!("Unlocked shared state in `set_resizable`");
|
||||
shared_state_lock.fullscreen.is_some()
|
||||
};
|
||||
if !fullscreen {
|
||||
|
|
@ -653,8 +708,7 @@ impl UnownedWindow {
|
|||
/// user clicking on the green fullscreen button or programmatically by
|
||||
/// `toggleFullScreen:`
|
||||
pub(crate) fn restore_state_from_fullscreen(&self) {
|
||||
trace!("Locked shared state in `restore_state_from_fullscreen`");
|
||||
let mut shared_state_lock = self.shared_state.lock().unwrap();
|
||||
let mut shared_state_lock = self.lock_shared_state("restore_state_from_fullscreen");
|
||||
|
||||
shared_state_lock.fullscreen = None;
|
||||
|
||||
|
|
@ -662,7 +716,6 @@ impl UnownedWindow {
|
|||
let mask = self.saved_style(&mut *shared_state_lock);
|
||||
|
||||
drop(shared_state_lock);
|
||||
trace!("Unocked shared state in `restore_state_from_fullscreen`");
|
||||
|
||||
self.set_style_mask_async(mask);
|
||||
self.set_maximized(maximized);
|
||||
|
|
@ -705,7 +758,7 @@ impl UnownedWindow {
|
|||
|
||||
#[inline]
|
||||
pub fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
let shared_state_lock = self.shared_state.lock().unwrap();
|
||||
let shared_state_lock = self.lock_shared_state("fullscreen");
|
||||
shared_state_lock.fullscreen.clone()
|
||||
}
|
||||
|
||||
|
|
@ -716,25 +769,20 @@ impl UnownedWindow {
|
|||
|
||||
#[inline]
|
||||
pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
|
||||
trace!("Locked shared state in `set_fullscreen`");
|
||||
let mut shared_state_lock = self.shared_state.lock().unwrap();
|
||||
let mut shared_state_lock = self.lock_shared_state("set_fullscreen");
|
||||
if shared_state_lock.is_simple_fullscreen {
|
||||
trace!("Unlocked shared state in `set_fullscreen`");
|
||||
return;
|
||||
}
|
||||
if shared_state_lock.in_fullscreen_transition {
|
||||
// We can't set fullscreen here.
|
||||
// Set fullscreen after transition.
|
||||
shared_state_lock.target_fullscreen = Some(fullscreen);
|
||||
trace!("Unlocked shared state in `set_fullscreen`");
|
||||
return;
|
||||
}
|
||||
let old_fullscreen = shared_state_lock.fullscreen.clone();
|
||||
if fullscreen == old_fullscreen {
|
||||
trace!("Unlocked shared state in `set_fullscreen`");
|
||||
return;
|
||||
}
|
||||
trace!("Unlocked shared state in `set_fullscreen`");
|
||||
drop(shared_state_lock);
|
||||
|
||||
// If the fullscreen is on a different monitor, we must move the window
|
||||
|
|
@ -787,8 +835,7 @@ impl UnownedWindow {
|
|||
if matches!(old_fullscreen, Some(Fullscreen::Borderless(_))) {
|
||||
unsafe {
|
||||
let app = NSApp();
|
||||
trace!("Locked shared state in `set_fullscreen`");
|
||||
let mut shared_state_lock = self.shared_state.lock().unwrap();
|
||||
let mut shared_state_lock = self.lock_shared_state("set_fullscreen");
|
||||
shared_state_lock.save_presentation_opts = Some(app.presentationOptions_());
|
||||
}
|
||||
}
|
||||
|
|
@ -840,8 +887,7 @@ impl UnownedWindow {
|
|||
}
|
||||
}
|
||||
|
||||
trace!("Locked shared state in `set_fullscreen`");
|
||||
let mut shared_state_lock = self.shared_state.lock().unwrap();
|
||||
let mut shared_state_lock = self.lock_shared_state("set_fullscreen");
|
||||
shared_state_lock.fullscreen = fullscreen.clone();
|
||||
|
||||
INTERRUPT_EVENT_LOOP_EXIT.store(true, Ordering::SeqCst);
|
||||
|
|
@ -884,7 +930,6 @@ impl UnownedWindow {
|
|||
// that the menu bar is disabled. This is done in the window
|
||||
// delegate in `window:willUseFullScreenPresentationOptions:`.
|
||||
let app = NSApp();
|
||||
trace!("Locked shared state in `set_fullscreen`");
|
||||
shared_state_lock.save_presentation_opts = Some(app.presentationOptions_());
|
||||
|
||||
let presentation_options =
|
||||
|
|
@ -918,7 +963,6 @@ impl UnownedWindow {
|
|||
},
|
||||
_ => INTERRUPT_EVENT_LOOP_EXIT.store(false, Ordering::SeqCst),
|
||||
};
|
||||
trace!("Unlocked shared state in `set_fullscreen`");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -927,9 +971,7 @@ impl UnownedWindow {
|
|||
self.decorations.store(decorations, Ordering::Release);
|
||||
|
||||
let (fullscreen, resizable) = {
|
||||
trace!("Locked shared state in `set_decorations`");
|
||||
let shared_state_lock = self.shared_state.lock().unwrap();
|
||||
trace!("Unlocked shared state in `set_decorations`");
|
||||
let shared_state_lock = self.lock_shared_state("set_decorations");
|
||||
(
|
||||
shared_state_lock.fullscreen.is_some(),
|
||||
shared_state_lock.resizable,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue