mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 23:01:30 +11:00
Update macos backend to addition of ControlFlow (untested)
This commit is contained in:
parent
db9e80bdb6
commit
c5b9bd3612
|
@ -1,4 +1,4 @@
|
||||||
use EventsLoopClosed;
|
use {ControlFlow, EventsLoopClosed};
|
||||||
use cocoa::{self, appkit, foundation};
|
use cocoa::{self, appkit, foundation};
|
||||||
use cocoa::appkit::{NSApplication, NSEvent, NSView, NSWindow};
|
use cocoa::appkit::{NSApplication, NSEvent, NSView, NSWindow};
|
||||||
use events::{self, ElementState, Event, MouseButton, TouchPhase, WindowEvent, ModifiersState, KeyboardInput};
|
use events::{self, ElementState, Event, MouseButton, TouchPhase, WindowEvent, ModifiersState, KeyboardInput};
|
||||||
|
@ -11,7 +11,6 @@ pub struct EventsLoop {
|
||||||
pub windows: std::sync::Mutex<Vec<std::sync::Weak<Window>>>,
|
pub windows: std::sync::Mutex<Vec<std::sync::Weak<Window>>>,
|
||||||
pub pending_events: std::sync::Mutex<std::collections::VecDeque<Event>>,
|
pub pending_events: std::sync::Mutex<std::collections::VecDeque<Event>>,
|
||||||
modifiers: std::sync::Mutex<Modifiers>,
|
modifiers: std::sync::Mutex<Modifiers>,
|
||||||
interrupted: std::sync::atomic::AtomicBool,
|
|
||||||
|
|
||||||
// The user event callback given via either of the `poll_events` or `run_forever` methods.
|
// The user event callback given via either of the `poll_events` or `run_forever` methods.
|
||||||
//
|
//
|
||||||
|
@ -102,12 +101,11 @@ impl EventsLoop {
|
||||||
windows: std::sync::Mutex::new(Vec::new()),
|
windows: std::sync::Mutex::new(Vec::new()),
|
||||||
pending_events: std::sync::Mutex::new(std::collections::VecDeque::new()),
|
pending_events: std::sync::Mutex::new(std::collections::VecDeque::new()),
|
||||||
modifiers: std::sync::Mutex::new(modifiers),
|
modifiers: std::sync::Mutex::new(modifiers),
|
||||||
interrupted: std::sync::atomic::AtomicBool::new(false),
|
|
||||||
user_callback: UserCallback { mutex: std::sync::Mutex::new(None) },
|
user_callback: UserCallback { mutex: std::sync::Mutex::new(None) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events<F>(&self, mut callback: F)
|
pub fn poll_events<F>(&mut self, mut callback: F)
|
||||||
where F: FnMut(Event),
|
where F: FnMut(Event),
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -148,23 +146,33 @@ impl EventsLoop {
|
||||||
self.user_callback.drop();
|
self.user_callback.drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_forever<F>(&self, mut callback: F)
|
pub fn run_forever<F>(&mut self, mut callback: F)
|
||||||
where F: FnMut(Event)
|
where F: FnMut(Event) -> ControlFlow
|
||||||
{
|
{
|
||||||
self.interrupted.store(false, std::sync::atomic::Ordering::Relaxed);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if !msg_send![cocoa::base::class("NSThread"), isMainThread] {
|
if !msg_send![cocoa::base::class("NSThread"), isMainThread] {
|
||||||
panic!("Events can only be polled from the main thread on macOS");
|
panic!("Events can only be polled from the main thread on macOS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track whether or not control flow has changed.
|
||||||
|
let mut control_flow = std::cell::Cell::new(ControlFlow::Continue);
|
||||||
|
|
||||||
|
let mut callback = |event| {
|
||||||
|
if let ControlFlow::Complete = callback(event) {
|
||||||
|
control_flow.set(ControlFlow::Complete);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
self.user_callback.store(&mut callback);
|
self.user_callback.store(&mut callback);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
unsafe {
|
unsafe {
|
||||||
// First, yield all pending events.
|
// First, yield all pending events.
|
||||||
self.call_user_callback_with_pending_events();
|
self.call_user_callback_with_pending_events();
|
||||||
|
if let ControlFlow::Complete = control_flow.get() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
let pool = foundation::NSAutoreleasePool::new(cocoa::base::nil);
|
let pool = foundation::NSAutoreleasePool::new(cocoa::base::nil);
|
||||||
|
|
||||||
|
@ -183,22 +191,16 @@ impl EventsLoop {
|
||||||
|
|
||||||
if let Some(event) = maybe_event {
|
if let Some(event) = maybe_event {
|
||||||
self.user_callback.call_with_event(event);
|
self.user_callback.call_with_event(event);
|
||||||
}
|
if let ControlFlow::Complete = control_flow.get() {
|
||||||
}
|
|
||||||
|
|
||||||
if self.interrupted.load(std::sync::atomic::Ordering::Relaxed) {
|
|
||||||
self.interrupted.store(false, std::sync::atomic::Ordering::Relaxed);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.user_callback.drop();
|
self.user_callback.drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interrupt(&self) {
|
|
||||||
self.interrupted.store(true, std::sync::atomic::Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes the window with the given `Id` from the `windows` list.
|
// Removes the window with the given `Id` from the `windows` list.
|
||||||
//
|
//
|
||||||
// This is called when a window is either `Closed` or `Drop`ped.
|
// This is called when a window is either `Closed` or `Drop`ped.
|
||||||
|
|
Loading…
Reference in a new issue