macOS: Remove unnecessary Mutex in window state (#3390)

This commit is contained in:
Mads Marquart 2024-01-14 04:44:10 +01:00 committed by GitHub
parent 40b61d2d92
commit c86b0daf7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 130 additions and 232 deletions

View file

@ -1,9 +1,8 @@
#![allow(clippy::unnecessary_cast)]
use std::cell::{Cell, RefCell};
use std::collections::VecDeque;
use std::f64;
use std::ops;
use std::sync::{Mutex, MutexGuard};
use core_graphics::display::{CGDisplay, CGPoint};
use icrate::AppKit::{
@ -23,7 +22,6 @@ use icrate::Foundation::{
CGFloat, MainThreadBound, MainThreadMarker, NSArray, NSCopying, NSObject, NSPoint, NSRect,
NSSize, NSString,
};
use log::trace;
use objc2::rc::{autoreleasepool, Id};
use objc2::{declare_class, msg_send, msg_send_id, mutability, sel, ClassType, DeclaredClass};
@ -185,7 +183,7 @@ declare_class!(
}
impl DeclaredClass for WinitWindow {
type Ivars = Mutex<SharedState>;
type Ivars = State;
}
unsafe impl WinitWindow {
@ -204,81 +202,36 @@ declare_class!(
);
#[derive(Debug, Default)]
pub struct SharedState {
pub resizable: bool,
pub struct State {
resizable: Cell<bool>,
/// This field tracks the current fullscreen state of the window
/// (as seen by `WindowDelegate`).
pub(crate) fullscreen: Option<Fullscreen>,
pub(super) fullscreen: RefCell<Option<Fullscreen>>,
// This is true between windowWillEnterFullScreen and windowDidEnterFullScreen
// or windowWillExitFullScreen and windowDidExitFullScreen.
// We must not toggle fullscreen when this is true.
pub in_fullscreen_transition: bool,
pub(super) in_fullscreen_transition: Cell<bool>,
// If it is attempted to toggle fullscreen when in_fullscreen_transition is true,
// Set target_fullscreen and do after fullscreen transition is end.
pub(crate) target_fullscreen: Option<Option<Fullscreen>>,
pub maximized: bool,
pub standard_frame: Option<NSRect>,
pub(crate) is_simple_fullscreen: bool,
pub saved_style: Option<NSWindowStyleMask>,
pub(crate) target_fullscreen: RefCell<Option<Option<Fullscreen>>>,
pub(super) maximized: Cell<bool>,
standard_frame: Cell<Option<NSRect>>,
pub(crate) is_simple_fullscreen: Cell<bool>,
pub(super) saved_style: Cell<Option<NSWindowStyleMask>>,
/// Presentation options saved before entering `set_simple_fullscreen`, and
/// restored upon exiting it. Also used when transitioning from Borderless to
/// Exclusive fullscreen in `set_fullscreen` because we need to disable the menu
/// bar in exclusive fullscreen but want to restore the original options when
/// transitioning back to borderless fullscreen.
save_presentation_opts: Option<NSApplicationPresentationOptions>,
pub current_theme: Option<Theme>,
save_presentation_opts: Cell<Option<NSApplicationPresentationOptions>>,
pub(super) current_theme: Cell<Option<Theme>>,
/// The current resize incerments for the window content.
pub(crate) resize_increments: NSSize,
/// The current resize increments for the window content.
pub(crate) resize_increments: Cell<NSSize>,
/// The state of the `Option` as `Alt`.
pub(crate) option_as_alt: OptionAsAlt,
decorations: bool,
}
impl SharedState {
pub fn saved_standard_frame(&self) -> NSRect {
self.standard_frame
.unwrap_or_else(|| NSRect::new(NSPoint::new(50.0, 50.0), NSSize::new(800.0, 600.0)))
}
}
pub(crate) struct SharedStateMutexGuard<'a> {
guard: MutexGuard<'a, SharedState>,
called_from_fn: &'static str,
}
impl<'a> SharedStateMutexGuard<'a> {
#[inline]
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);
}
option_as_alt: Cell<OptionAsAlt>,
/// Whether the window is showing decorations.
decorations: Cell<bool>,
}
impl WinitWindow {
@ -360,14 +313,12 @@ impl WinitWindow {
masks |= NSWindowStyleMaskFullSizeContentView;
}
let state = SharedState {
resizable: attrs.resizable,
maximized: attrs.maximized,
decorations: attrs.decorations,
let this = mtm.alloc().set_ivars(State {
resizable: Cell::new(attrs.resizable),
maximized: Cell::new(attrs.maximized),
decorations: Cell::new(attrs.decorations),
..Default::default()
};
let this = mtm.alloc().set_ivars(Mutex::new(state));
});
let this: Option<Id<Self>> = unsafe {
msg_send_id![
super(this),
@ -394,7 +345,7 @@ impl WinitWindow {
_ => NSSize::new(1., 1.),
};
this.lock_shared_state("init").resize_increments = resize_increments;
this.ivars().resize_increments.set(resize_increments);
this.setTitle(&NSString::from_str(&attrs.title));
this.setAcceptsMouseMovedEvents(true);
@ -517,13 +468,10 @@ impl WinitWindow {
match attrs.preferred_theme {
Some(theme) => {
set_ns_theme(Some(theme), mtm);
let mut state = this.lock_shared_state("WinitWindow::new");
state.current_theme = Some(theme);
this.ivars().current_theme.set(Some(theme));
}
None => {
let mut state = this.lock_shared_state("WinitWindow::new");
state.current_theme = Some(get_ns_theme(mtm));
this.ivars().current_theme.set(Some(get_ns_theme(mtm)));
}
}
@ -563,14 +511,6 @@ impl WinitWindow {
unsafe { Id::cast(self.contentView().unwrap()) }
}
#[track_caller]
pub(crate) fn lock_shared_state(
&self,
called_from_fn: &'static str,
) -> SharedStateMutexGuard<'_> {
SharedStateMutexGuard::new(self.ivars().lock().unwrap(), called_from_fn)
}
fn set_style_mask(&self, mask: NSWindowStyleMask) {
self.setStyleMask(mask);
// If we don't do this, key handling will break
@ -708,9 +648,7 @@ impl WinitWindow {
}
pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
let increments = self
.lock_shared_state("set_resize_increments")
.resize_increments;
let increments = self.ivars().resize_increments.get();
let (w, h) = (increments.width, increments.height);
if w > 1.0 || h > 1.0 {
Some(LogicalSize::new(w, h).to_physical(self.scale_factor()))
@ -721,13 +659,14 @@ impl WinitWindow {
pub fn set_resize_increments(&self, increments: Option<Size>) {
// XXX the resize increments are only used during live resizes.
let mut shared_state_lock = self.lock_shared_state("set_resize_increments");
shared_state_lock.resize_increments = increments
.map(|increments| {
let logical = increments.to_logical::<f64>(self.scale_factor());
NSSize::new(logical.width.max(1.0), logical.height.max(1.0))
})
.unwrap_or_else(|| NSSize::new(1.0, 1.0));
self.ivars().resize_increments.set(
increments
.map(|increments| {
let logical = increments.to_logical::<f64>(self.scale_factor());
NSSize::new(logical.width.max(1.0), logical.height.max(1.0))
})
.unwrap_or_else(|| NSSize::new(1.0, 1.0)),
);
}
pub(crate) fn set_resize_increments_inner(&self, size: NSSize) {
@ -740,11 +679,8 @@ impl WinitWindow {
#[inline]
pub fn set_resizable(&self, resizable: bool) {
let fullscreen = {
let mut shared_state_lock = self.lock_shared_state("set_resizable");
shared_state_lock.resizable = resizable;
shared_state_lock.fullscreen.is_some()
};
self.ivars().resizable.set(resizable);
let fullscreen = self.ivars().fullscreen.borrow().is_some();
if !fullscreen {
let mut mask = self.styleMask();
if resizable {
@ -917,12 +853,13 @@ impl WinitWindow {
is_zoomed
}
fn saved_style(&self, shared_state: &mut SharedState) -> NSWindowStyleMask {
let base_mask = shared_state
fn saved_style(&self) -> NSWindowStyleMask {
let base_mask = self
.ivars()
.saved_style
.take()
.unwrap_or_else(|| self.styleMask());
if shared_state.resizable {
if self.ivars().resizable.get() {
base_mask | NSWindowStyleMaskResizable
} else {
base_mask & !NSWindowStyleMaskResizable
@ -933,14 +870,10 @@ impl WinitWindow {
/// user clicking on the green fullscreen button or programmatically by
/// `toggleFullScreen:`
pub(crate) fn restore_state_from_fullscreen(&self) {
let mut shared_state_lock = self.lock_shared_state("restore_state_from_fullscreen");
self.ivars().fullscreen.replace(None);
shared_state_lock.fullscreen = None;
let maximized = shared_state_lock.maximized;
let mask = self.saved_style(&mut shared_state_lock);
drop(shared_state_lock);
let maximized = self.ivars().maximized.get();
let mask = self.saved_style();
self.set_style_mask(mask);
self.set_maximized(maximized);
@ -973,21 +906,19 @@ impl WinitWindow {
return;
};
let mut shared_state = self.lock_shared_state("set_maximized");
// Save the standard frame sized if it is not zoomed
if !is_zoomed {
shared_state.standard_frame = Some(self.frame());
self.ivars().standard_frame.set(Some(self.frame()));
}
shared_state.maximized = maximized;
self.ivars().maximized.set(maximized);
if shared_state.fullscreen.is_some() {
if self.ivars().fullscreen.borrow().is_some() {
// Handle it in window_did_exit_fullscreen
return;
}
if mask_contains(self.styleMask(), NSWindowStyleMaskResizable) {
drop(shared_state);
// Just use the native zoom if resizable
self.zoom(None);
} else {
@ -996,17 +927,18 @@ impl WinitWindow {
let screen = NSScreen::mainScreen(mtm).expect("no screen found");
screen.visibleFrame()
} else {
shared_state.saved_standard_frame()
self.ivars()
.standard_frame
.get()
.unwrap_or(DEFAULT_STANDARD_FRAME)
};
drop(shared_state);
self.setFrame_display(new_rect, false);
}
}
#[inline]
pub(crate) fn fullscreen(&self) -> Option<Fullscreen> {
let shared_state_lock = self.lock_shared_state("fullscreen");
shared_state_lock.fullscreen.clone()
self.ivars().fullscreen.borrow().clone()
}
#[inline]
@ -1019,21 +951,19 @@ impl WinitWindow {
let mtm = MainThreadMarker::from(self);
let app = NSApplication::sharedApplication(mtm);
let mut shared_state_lock = self.lock_shared_state("set_fullscreen");
if shared_state_lock.is_simple_fullscreen {
if self.ivars().is_simple_fullscreen.get() {
return;
}
if shared_state_lock.in_fullscreen_transition {
if self.ivars().in_fullscreen_transition.get() {
// We can't set fullscreen here.
// Set fullscreen after transition.
shared_state_lock.target_fullscreen = Some(fullscreen);
self.ivars().target_fullscreen.replace(Some(fullscreen));
return;
}
let old_fullscreen = shared_state_lock.fullscreen.clone();
let old_fullscreen = self.ivars().fullscreen.borrow().clone();
if fullscreen == old_fullscreen {
return;
}
drop(shared_state_lock);
// If the fullscreen is on a different monitor, we must move the window
// to that monitor before we toggle fullscreen (as `toggleFullScreen`
@ -1077,8 +1007,9 @@ impl WinitWindow {
let mut fade_token = ffi::kCGDisplayFadeReservationInvalidToken;
if matches!(old_fullscreen, Some(Fullscreen::Borderless(_))) {
let mut shared_state_lock = self.lock_shared_state("set_fullscreen");
shared_state_lock.save_presentation_opts = Some(app.presentationOptions());
self.ivars()
.save_presentation_opts
.replace(Some(app.presentationOptions()));
}
unsafe {
@ -1128,7 +1059,7 @@ impl WinitWindow {
}
}
self.lock_shared_state("set_fullscreen").fullscreen = fullscreen.clone();
self.ivars().fullscreen.replace(fullscreen.clone());
fn toggle_fullscreen(window: &WinitWindow) {
// Window level must be restored from `CGShieldingWindowLevel()
@ -1147,7 +1078,7 @@ impl WinitWindow {
let required = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable;
if !mask_contains(curr_mask, required) {
self.set_style_mask(required);
self.lock_shared_state("set_fullscreen").saved_style = Some(curr_mask);
self.ivars().saved_style.set(Some(curr_mask));
}
toggle_fullscreen(self);
}
@ -1174,8 +1105,9 @@ impl WinitWindow {
// of the menu bar, and this looks broken, so we must make sure
// that the menu bar is disabled. This is done in the window
// delegate in `window:willUseFullScreenPresentationOptions:`.
self.lock_shared_state("set_fullscreen")
.save_presentation_opts = Some(app.presentationOptions());
self.ivars()
.save_presentation_opts
.set(Some(app.presentationOptions()));
let presentation_options = NSApplicationPresentationFullScreen
| NSApplicationPresentationHideDock
@ -1186,14 +1118,11 @@ impl WinitWindow {
self.setLevel(window_level);
}
(Some(Fullscreen::Exclusive(ref video_mode)), Some(Fullscreen::Borderless(_))) => {
let presentation_options = self
.lock_shared_state("set_fullscreen")
.save_presentation_opts
.unwrap_or(
NSApplicationPresentationFullScreen
| NSApplicationPresentationAutoHideDock
| NSApplicationPresentationAutoHideMenuBar,
);
let presentation_options = self.ivars().save_presentation_opts.get().unwrap_or(
NSApplicationPresentationFullScreen
| NSApplicationPresentationAutoHideDock
| NSApplicationPresentationAutoHideMenuBar,
);
app.setPresentationOptions(presentation_options);
unsafe {
@ -1214,17 +1143,14 @@ impl WinitWindow {
#[inline]
pub fn set_decorations(&self, decorations: bool) {
let mut shared_state_lock = self.lock_shared_state("set_decorations");
if decorations == shared_state_lock.decorations {
if decorations == self.ivars().decorations.get() {
return;
}
shared_state_lock.decorations = decorations;
self.ivars().decorations.set(decorations);
let fullscreen = shared_state_lock.fullscreen.is_some();
let resizable = shared_state_lock.resizable;
drop(shared_state_lock);
let fullscreen = self.ivars().fullscreen.borrow().is_some();
let resizable = self.ivars().resizable.get();
// If we're in fullscreen mode, we wait to apply decoration changes
// until we're in `window_did_exit_fullscreen`.
@ -1251,7 +1177,7 @@ impl WinitWindow {
#[inline]
pub fn is_decorated(&self) -> bool {
self.lock_shared_state("is_decorated").decorations
self.ivars().decorations.get()
}
#[inline]
@ -1389,7 +1315,7 @@ impl WinitWindow {
#[inline]
pub fn theme(&self) -> Option<Theme> {
self.lock_shared_state("theme").current_theme
self.ivars().current_theme.get()
}
#[inline]
@ -1400,8 +1326,9 @@ impl WinitWindow {
pub fn set_theme(&self, theme: Option<Theme>) {
let mtm = MainThreadMarker::from(self);
set_ns_theme(theme, mtm);
self.lock_shared_state("set_theme").current_theme =
theme.or_else(|| Some(get_ns_theme(mtm)));
self.ivars()
.current_theme
.set(theme.or_else(|| Some(get_ns_theme(mtm))));
}
#[inline]
@ -1426,18 +1353,16 @@ impl WinitWindow {
impl WindowExtMacOS for WinitWindow {
#[inline]
fn simple_fullscreen(&self) -> bool {
self.lock_shared_state("simple_fullscreen")
.is_simple_fullscreen
self.ivars().is_simple_fullscreen.get()
}
#[inline]
fn set_simple_fullscreen(&self, fullscreen: bool) -> bool {
let mtm = MainThreadMarker::from(self);
let mut shared_state_lock = self.lock_shared_state("set_simple_fullscreen");
let app = NSApplication::sharedApplication(mtm);
let is_native_fullscreen = shared_state_lock.fullscreen.is_some();
let is_simple_fullscreen = shared_state_lock.is_simple_fullscreen;
let is_native_fullscreen = self.ivars().fullscreen.borrow().is_some();
let is_simple_fullscreen = self.ivars().is_simple_fullscreen.get();
// Do nothing if native fullscreen is active.
if is_native_fullscreen
@ -1450,16 +1375,16 @@ impl WindowExtMacOS for WinitWindow {
if fullscreen {
// Remember the original window's settings
// Exclude title bar
shared_state_lock.standard_frame = Some(self.contentRectForFrameRect(self.frame()));
shared_state_lock.saved_style = Some(self.styleMask());
shared_state_lock.save_presentation_opts = Some(app.presentationOptions());
self.ivars()
.standard_frame
.set(Some(self.contentRectForFrameRect(self.frame())));
self.ivars().saved_style.set(Some(self.styleMask()));
self.ivars()
.save_presentation_opts
.set(Some(app.presentationOptions()));
// Tell our window's state that we're in fullscreen
shared_state_lock.is_simple_fullscreen = true;
// Drop shared state lock before calling app.setPresentationOptions, because
// it will call our windowDidChangeScreen listener which reacquires the lock
drop(shared_state_lock);
self.ivars().is_simple_fullscreen.set(true);
// Simulate pre-Lion fullscreen by hiding the dock and menu bar
let presentation_options =
@ -1480,16 +1405,16 @@ impl WindowExtMacOS for WinitWindow {
true
} else {
let new_mask = self.saved_style(&mut shared_state_lock);
let new_mask = self.saved_style();
self.set_style_mask(new_mask);
shared_state_lock.is_simple_fullscreen = false;
self.ivars().is_simple_fullscreen.set(false);
let save_presentation_opts = shared_state_lock.save_presentation_opts;
let frame = shared_state_lock.saved_standard_frame();
// Drop shared state lock before calling app.setPresentationOptions, because
// it will call our windowDidChangeScreen listener which reacquires the lock
drop(shared_state_lock);
let save_presentation_opts = self.ivars().save_presentation_opts.get();
let frame = self
.ivars()
.standard_frame
.get()
.unwrap_or(DEFAULT_STANDARD_FRAME);
if let Some(presentation_opts) = save_presentation_opts {
app.setPresentationOptions(presentation_opts);
@ -1559,13 +1484,11 @@ impl WindowExtMacOS for WinitWindow {
}
fn set_option_as_alt(&self, option_as_alt: OptionAsAlt) {
let mut shared_state_lock = self.lock_shared_state("set_option_as_alt");
shared_state_lock.option_as_alt = option_as_alt;
self.ivars().option_as_alt.set(option_as_alt);
}
fn option_as_alt(&self) -> OptionAsAlt {
let shared_state_lock = self.lock_shared_state("option_as_alt");
shared_state_lock.option_as_alt
self.ivars().option_as_alt.get()
}
}
@ -1606,3 +1529,6 @@ fn set_ns_theme(theme: Option<Theme>, mtm: MainThreadMarker) {
app.setAppearance(appearance.as_ref().map(|a| a.as_ref()));
}
}
const DEFAULT_STANDARD_FRAME: NSRect =
NSRect::new(NSPoint::new(50.0, 50.0), NSSize::new(800.0, 600.0));

View file

@ -90,11 +90,7 @@ declare_class!(
fn window_will_start_live_resize(&self, _: Option<&AnyObject>) {
trace_scope!("windowWillStartLiveResize:");
let increments = self
.ivars()
.window
.lock_shared_state("window_will_enter_fullscreen")
.resize_increments;
let increments = self.ivars().window.ivars().resize_increments.get();
self.ivars().window.set_resize_increments_inner(increments);
}
@ -147,13 +143,10 @@ declare_class!(
fn window_will_enter_fullscreen(&self, _: Option<&AnyObject>) {
trace_scope!("windowWillEnterFullScreen:");
let mut shared_state = self
.ivars()
.window
.lock_shared_state("window_will_enter_fullscreen");
shared_state.maximized = self.ivars().window.is_zoomed();
let fullscreen = shared_state.fullscreen.as_ref();
match fullscreen {
let window_ivars = self.ivars().window.ivars();
window_ivars.maximized.set(self.ivars().window.is_zoomed());
let mut fullscreen = window_ivars.fullscreen.borrow_mut();
match &*fullscreen {
// Exclusive mode sets the state in `set_fullscreen` as the user
// can't enter exclusive mode by other means (like the
// fullscreen button on the window decorations)
@ -166,10 +159,10 @@ declare_class!(
// on the green fullscreen button. Update state!
None => {
let current_monitor = self.ivars().window.current_monitor_inner();
shared_state.fullscreen = Some(Fullscreen::Borderless(current_monitor))
*fullscreen = Some(Fullscreen::Borderless(current_monitor));
}
}
shared_state.in_fullscreen_transition = true;
window_ivars.in_fullscreen_transition.set(true);
}
/// Invoked when before exit fullscreen
@ -177,11 +170,11 @@ declare_class!(
fn window_will_exit_fullscreen(&self, _: Option<&AnyObject>) {
trace_scope!("windowWillExitFullScreen:");
let mut shared_state = self
.ivars()
self.ivars()
.window
.lock_shared_state("window_will_exit_fullscreen");
shared_state.in_fullscreen_transition = true;
.ivars()
.in_fullscreen_transition
.set(true);
}
#[method(window:willUseFullScreenPresentationOptions:)]
@ -200,11 +193,8 @@ declare_class!(
// we don't, for consistency. If we do, it should be documented that the
// user-provided options are ignored in exclusive fullscreen.
let mut options = proposed_options;
let shared_state = self
.ivars()
.window
.lock_shared_state("window_will_use_fullscreen_presentation_options");
if let Some(Fullscreen::Exclusive(_)) = shared_state.fullscreen {
let fullscreen = self.ivars().window.ivars().fullscreen.borrow();
if let Some(Fullscreen::Exclusive(_)) = &*fullscreen {
options = NSApplicationPresentationFullScreen
| NSApplicationPresentationHideDock
| NSApplicationPresentationHideMenuBar;
@ -218,14 +208,9 @@ declare_class!(
fn window_did_enter_fullscreen(&self, _: Option<&AnyObject>) {
trace_scope!("windowDidEnterFullScreen:");
self.ivars().initial_fullscreen.set(false);
let mut shared_state = self
.ivars()
.window
.lock_shared_state("window_did_enter_fullscreen");
shared_state.in_fullscreen_transition = false;
let target_fullscreen = shared_state.target_fullscreen.take();
drop(shared_state);
if let Some(target_fullscreen) = target_fullscreen {
let window_ivars = self.ivars().window.ivars();
window_ivars.in_fullscreen_transition.set(false);
if let Some(target_fullscreen) = window_ivars.target_fullscreen.take() {
self.ivars().window.set_fullscreen(target_fullscreen);
}
}
@ -236,14 +221,9 @@ declare_class!(
trace_scope!("windowDidExitFullScreen:");
self.ivars().window.restore_state_from_fullscreen();
let mut shared_state = self
.ivars()
.window
.lock_shared_state("window_did_exit_fullscreen");
shared_state.in_fullscreen_transition = false;
let target_fullscreen = shared_state.target_fullscreen.take();
drop(shared_state);
if let Some(target_fullscreen) = target_fullscreen {
let window_ivars = self.ivars().window.ivars();
window_ivars.in_fullscreen_transition.set(false);
if let Some(target_fullscreen) = window_ivars.target_fullscreen.take() {
self.ivars().window.set_fullscreen(target_fullscreen);
}
}
@ -267,12 +247,9 @@ declare_class!(
#[method(windowDidFailToEnterFullScreen:)]
fn window_did_fail_to_enter_fullscreen(&self, _: Option<&AnyObject>) {
trace_scope!("windowDidFailToEnterFullScreen:");
let mut shared_state = self
.ivars()
.window
.lock_shared_state("window_did_fail_to_enter_fullscreen");
shared_state.in_fullscreen_transition = false;
shared_state.target_fullscreen = None;
let window_ivars = self.ivars().window.ivars();
window_ivars.in_fullscreen_transition.set(false);
window_ivars.target_fullscreen.replace(None);
if self.ivars().initial_fullscreen.get() {
#[allow(clippy::let_unit_value)]
unsafe {
@ -300,11 +277,7 @@ declare_class!(
#[method(windowDidChangeScreen:)]
fn window_did_change_screen(&self, _: Option<&AnyObject>) {
trace_scope!("windowDidChangeScreen:");
let is_simple_fullscreen = self
.ivars()
.window
.lock_shared_state("window_did_change_screen")
.is_simple_fullscreen;
let is_simple_fullscreen = self.ivars().window.ivars().is_simple_fullscreen.get();
if is_simple_fullscreen {
if let Some(screen) = self.ivars().window.screen() {
self.ivars().window.setFrame_display(screen.frame(), true);
@ -396,14 +369,13 @@ declare_class!(
fn effective_appearance_did_changed_on_main_thread(&self, _: Option<&AnyObject>) {
let mtm = MainThreadMarker::from(self);
let theme = get_ns_theme(mtm);
let mut shared_state = self
let old_theme = self
.ivars()
.window
.lock_shared_state("effective_appearance_did_change");
let current_theme = shared_state.current_theme;
shared_state.current_theme = Some(theme);
drop(shared_state);
if current_theme != Some(theme) {
.ivars()
.current_theme
.replace(Some(theme));
if old_theme != Some(theme) {
self.queue_event(WindowEvent::ThemeChanged(theme));
}
}