mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
Macos fullscreen & dialog support with run_return
(#1581)
* Fix for fullscreen with run_return on mac * Cleanup * Removed a comment * fmt * This doesn't break exiting run_return anymore * Now you can also transition from code * Fmt & cleanup * Now using a atomic instead of a static bool * reinserted a line * Fmt * Added support for dialogs and child windows * Cargo fmt * Dialogs are now being shutdown properly * Cargo fmt * Update CHANGELOG.md
This commit is contained in:
parent
a4121a2c2e
commit
5a6cfc314e
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
- On Wayland, fix deadlock when calling to `set_inner_size` from a callback.
|
- On Wayland, fix deadlock when calling to `set_inner_size` from a callback.
|
||||||
- On macOS, add `hide__other_applications` to `EventLoopWindowTarget` via existing `EventLoopWindowTargetExtMacOS` trait. `hide_other_applications` will hide other applications by calling `-[NSApplication hideOtherApplications: nil]`.
|
- On macOS, add `hide__other_applications` to `EventLoopWindowTarget` via existing `EventLoopWindowTargetExtMacOS` trait. `hide_other_applications` will hide other applications by calling `-[NSApplication hideOtherApplications: nil]`.
|
||||||
|
- On MacOS, Fixed fullscreen and dialog support for `run_return`.
|
||||||
|
|
||||||
# 0.22.2 (2020-05-16)
|
# 0.22.2 (2020-05-16)
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ impl<T> EventHandler for EventLoopHandler<T> {
|
||||||
struct Handler {
|
struct Handler {
|
||||||
ready: AtomicBool,
|
ready: AtomicBool,
|
||||||
in_callback: AtomicBool,
|
in_callback: AtomicBool,
|
||||||
|
dialog_is_closing: AtomicBool,
|
||||||
control_flow: Mutex<ControlFlow>,
|
control_flow: Mutex<ControlFlow>,
|
||||||
control_flow_prev: Mutex<ControlFlow>,
|
control_flow_prev: Mutex<ControlFlow>,
|
||||||
start_time: Mutex<Option<Instant>>,
|
start_time: Mutex<Option<Instant>>,
|
||||||
|
@ -223,6 +224,8 @@ impl Handler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub static INTERRUPT_EVENT_LOOP_EXIT: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
pub enum AppState {}
|
pub enum AppState {}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
|
@ -336,14 +339,28 @@ impl AppState {
|
||||||
}
|
}
|
||||||
if HANDLER.should_exit() {
|
if HANDLER.should_exit() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _: () = msg_send![NSApp(), stop: nil];
|
let app: id = NSApp();
|
||||||
|
let windows: id = msg_send![app, windows];
|
||||||
let pool = NSAutoreleasePool::new(nil);
|
|
||||||
|
|
||||||
let windows: id = msg_send![NSApp(), windows];
|
|
||||||
let window: id = msg_send![windows, objectAtIndex:0];
|
let window: id = msg_send![windows, objectAtIndex:0];
|
||||||
|
let window_count: usize = msg_send![windows, count];
|
||||||
assert_ne!(window, nil);
|
assert_ne!(window, nil);
|
||||||
|
|
||||||
|
let dialog_open = if window_count > 1 {
|
||||||
|
let dialog: id = msg_send![windows, lastObject];
|
||||||
|
let is_main_window: bool = msg_send![dialog, isMainWindow];
|
||||||
|
msg_send![dialog, isVisible] && !is_main_window
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
let dialog_is_closing = HANDLER.dialog_is_closing.load(Ordering::SeqCst);
|
||||||
|
let pool = NSAutoreleasePool::new(nil);
|
||||||
|
if !INTERRUPT_EVENT_LOOP_EXIT.load(Ordering::SeqCst)
|
||||||
|
&& !dialog_open
|
||||||
|
&& !dialog_is_closing
|
||||||
|
{
|
||||||
|
let _: () = msg_send![app, stop: nil];
|
||||||
|
|
||||||
let dummy_event: id = msg_send![class!(NSEvent),
|
let dummy_event: id = msg_send![class!(NSEvent),
|
||||||
otherEventWithType: NSApplicationDefined
|
otherEventWithType: NSApplicationDefined
|
||||||
location: NSPoint::new(0.0, 0.0)
|
location: NSPoint::new(0.0, 0.0)
|
||||||
|
@ -357,8 +374,16 @@ impl AppState {
|
||||||
];
|
];
|
||||||
// To stop event loop immediately, we need to post some event here.
|
// To stop event loop immediately, we need to post some event here.
|
||||||
let _: () = msg_send![window, postEvent: dummy_event atStart: YES];
|
let _: () = msg_send![window, postEvent: dummy_event atStart: YES];
|
||||||
|
}
|
||||||
pool.drain();
|
pool.drain();
|
||||||
|
|
||||||
|
let window_has_focus = msg_send![window, isKeyWindow];
|
||||||
|
if !dialog_open && window_has_focus && dialog_is_closing {
|
||||||
|
HANDLER.dialog_is_closing.store(false, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
if dialog_open {
|
||||||
|
HANDLER.dialog_is_closing.store(true, Ordering::SeqCst);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
HANDLER.update_start_time();
|
HANDLER.update_start_time();
|
||||||
|
|
|
@ -19,6 +19,7 @@ use crate::{
|
||||||
platform::macos::{ActivationPolicy, RequestUserAttentionType, WindowExtMacOS},
|
platform::macos::{ActivationPolicy, RequestUserAttentionType, WindowExtMacOS},
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
app_state::AppState,
|
app_state::AppState,
|
||||||
|
app_state::INTERRUPT_EVENT_LOOP_EXIT,
|
||||||
ffi,
|
ffi,
|
||||||
monitor::{self, MonitorHandle, VideoMode},
|
monitor::{self, MonitorHandle, VideoMode},
|
||||||
util::{self, IdRef},
|
util::{self, IdRef},
|
||||||
|
@ -820,6 +821,8 @@ impl UnownedWindow {
|
||||||
shared_state_lock.fullscreen = fullscreen.clone();
|
shared_state_lock.fullscreen = fullscreen.clone();
|
||||||
trace!("Unlocked shared state in `set_fullscreen`");
|
trace!("Unlocked shared state in `set_fullscreen`");
|
||||||
|
|
||||||
|
INTERRUPT_EVENT_LOOP_EXIT.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
match (&old_fullscreen, &fullscreen) {
|
match (&old_fullscreen, &fullscreen) {
|
||||||
(&None, &Some(_)) => unsafe {
|
(&None, &Some(_)) => unsafe {
|
||||||
util::toggle_full_screen_async(
|
util::toggle_full_screen_async(
|
||||||
|
@ -865,7 +868,7 @@ impl UnownedWindow {
|
||||||
) => unsafe {
|
) => unsafe {
|
||||||
util::restore_display_mode_async(video_mode.monitor().inner.native_identifier());
|
util::restore_display_mode_async(video_mode.monitor().inner.native_identifier());
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => INTERRUPT_EVENT_LOOP_EXIT.store(false, Ordering::SeqCst),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
f64,
|
f64,
|
||||||
os::raw::c_void,
|
os::raw::c_void,
|
||||||
sync::{Arc, Weak},
|
sync::{atomic::Ordering, Arc, Weak},
|
||||||
};
|
};
|
||||||
|
|
||||||
use cocoa::{
|
use cocoa::{
|
||||||
|
@ -19,6 +19,7 @@ use crate::{
|
||||||
event::{Event, ModifiersState, WindowEvent},
|
event::{Event, ModifiersState, WindowEvent},
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
app_state::AppState,
|
app_state::AppState,
|
||||||
|
app_state::INTERRUPT_EVENT_LOOP_EXIT,
|
||||||
event::{EventProxy, EventWrapper},
|
event::{EventProxy, EventWrapper},
|
||||||
util::{self, IdRef},
|
util::{self, IdRef},
|
||||||
view::ViewState,
|
view::ViewState,
|
||||||
|
@ -429,6 +430,9 @@ extern "C" fn dragging_exited(this: &Object, _: Sel, _: id) {
|
||||||
/// Invoked when before enter fullscreen
|
/// Invoked when before enter fullscreen
|
||||||
extern "C" fn window_will_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
extern "C" fn window_will_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
trace!("Triggered `windowWillEnterFullscreen:`");
|
trace!("Triggered `windowWillEnterFullscreen:`");
|
||||||
|
|
||||||
|
INTERRUPT_EVENT_LOOP_EXIT.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
with_state(this, |state| {
|
with_state(this, |state| {
|
||||||
state.with_window(|window| {
|
state.with_window(|window| {
|
||||||
trace!("Locked shared state in `window_will_enter_fullscreen`");
|
trace!("Locked shared state in `window_will_enter_fullscreen`");
|
||||||
|
@ -459,6 +463,9 @@ extern "C" fn window_will_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
/// Invoked when before exit fullscreen
|
/// Invoked when before exit fullscreen
|
||||||
extern "C" fn window_will_exit_fullscreen(this: &Object, _: Sel, _: id) {
|
extern "C" fn window_will_exit_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
trace!("Triggered `windowWillExitFullScreen:`");
|
trace!("Triggered `windowWillExitFullScreen:`");
|
||||||
|
|
||||||
|
INTERRUPT_EVENT_LOOP_EXIT.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
with_state(this, |state| {
|
with_state(this, |state| {
|
||||||
state.with_window(|window| {
|
state.with_window(|window| {
|
||||||
trace!("Locked shared state in `window_will_exit_fullscreen`");
|
trace!("Locked shared state in `window_will_exit_fullscreen`");
|
||||||
|
@ -492,6 +499,8 @@ extern "C" fn window_will_use_fullscreen_presentation_options(
|
||||||
|
|
||||||
/// Invoked when entered fullscreen
|
/// Invoked when entered fullscreen
|
||||||
extern "C" fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
extern "C" fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
|
INTERRUPT_EVENT_LOOP_EXIT.store(false, Ordering::SeqCst);
|
||||||
|
|
||||||
trace!("Triggered `windowDidEnterFullscreen:`");
|
trace!("Triggered `windowDidEnterFullscreen:`");
|
||||||
with_state(this, |state| {
|
with_state(this, |state| {
|
||||||
state.initial_fullscreen = false;
|
state.initial_fullscreen = false;
|
||||||
|
@ -512,6 +521,8 @@ extern "C" fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
|
|
||||||
/// Invoked when exited fullscreen
|
/// Invoked when exited fullscreen
|
||||||
extern "C" fn window_did_exit_fullscreen(this: &Object, _: Sel, _: id) {
|
extern "C" fn window_did_exit_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
|
INTERRUPT_EVENT_LOOP_EXIT.store(false, Ordering::SeqCst);
|
||||||
|
|
||||||
trace!("Triggered `windowDidExitFullscreen:`");
|
trace!("Triggered `windowDidExitFullscreen:`");
|
||||||
with_state(this, |state| {
|
with_state(this, |state| {
|
||||||
state.with_window(|window| {
|
state.with_window(|window| {
|
||||||
|
|
Loading…
Reference in a new issue