Skip to content

Commit 0a08742

Browse files
micahrjdathinaios
authored andcommitted
Merge branch into master
2 parents 960b48a + 3e12973 commit 0a08742

File tree

6 files changed

+56
-8
lines changed

6 files changed

+56
-8
lines changed

.github/workflows/rust.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,5 @@ jobs:
3131
run: cargo test --workspace --all-targets --all-features --verbose
3232
- name: Check docs
3333
run: cargo doc --examples --all-features --no-deps
34-
- name: Clippy
35-
run: cargo clippy --workspace --all-targets --all-features -- -D warnings
3634
- name: Check Formatting (rustfmt)
3735
run: cargo fmt --all -- --check

src/gl/macos.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// This is required because the objc crate is causing a lot of warnings: https://github.com/SSheldon/rust-objc/issues/125
2+
// Eventually we should migrate to the objc2 crate and remove this.
3+
#![allow(unexpected_cfgs)]
4+
15
use std::ffi::c_void;
26
use std::str::FromStr;
37

src/gl/win.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ impl GlContext {
192192
};
193193

194194
wglMakeCurrent(hdc_tmp, std::ptr::null_mut());
195+
wglDeleteContext(hglrc_tmp);
195196
ReleaseDC(hwnd_tmp, hdc_tmp);
196197
UnregisterClassW(class as *const WCHAR, hinstance);
197198
DestroyWindow(hwnd_tmp);

src/macos/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// This is required because the objc crate is causing a lot of warnings: https://github.com/SSheldon/rust-objc/issues/125
2+
// Eventually we should migrate to the objc2 crate and remove this.
3+
#![allow(unexpected_cfgs)]
4+
15
mod keyboard;
26
mod view;
37
mod window;

src/macos/view.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,18 +245,22 @@ extern "C" fn become_first_responder(this: &Object, _sel: Sel) -> BOOL {
245245
let state = unsafe { WindowState::from_view(this) };
246246
let is_key_window = unsafe {
247247
let window: id = msg_send![this, window];
248-
let is_key_window: BOOL = msg_send![window, isKeyWindow];
249-
is_key_window == YES
248+
if window != nil {
249+
let is_key_window: BOOL = msg_send![window, isKeyWindow];
250+
is_key_window == YES
251+
} else {
252+
false
253+
}
250254
};
251255
if is_key_window {
252-
state.trigger_event(Event::Window(WindowEvent::Focused));
256+
state.trigger_deferrable_event(Event::Window(WindowEvent::Focused));
253257
}
254258
YES
255259
}
256260

257261
extern "C" fn resign_first_responder(this: &Object, _sel: Sel) -> BOOL {
258262
let state = unsafe { WindowState::from_view(this) };
259-
state.trigger_event(Event::Window(WindowEvent::Unfocused));
263+
state.trigger_deferrable_event(Event::Window(WindowEvent::Unfocused));
260264
YES
261265
}
262266

src/macos/window.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::cell::{Cell, RefCell};
2+
use std::collections::VecDeque;
23
use std::ffi::c_void;
34
use std::ptr;
45
use std::rc::Rc;
@@ -266,6 +267,7 @@ impl<'a> Window<'a> {
266267
keyboard_state: KeyboardState::new(),
267268
frame_timer: Cell::new(None),
268269
window_info: Cell::new(window_info),
270+
deferred_events: RefCell::default(),
269271
});
270272

271273
let window_state_ptr = Rc::into_raw(Rc::clone(&window_state));
@@ -359,6 +361,9 @@ pub(super) struct WindowState {
359361
frame_timer: Cell<Option<CFRunLoopTimer>>,
360362
/// The last known window info for this window.
361363
pub window_info: Cell<WindowInfo>,
364+
365+
/// Events that will be triggered at the end of `window_handler`'s borrow.
366+
deferred_events: RefCell<VecDeque<Event>>,
362367
}
363368

364369
impl WindowState {
@@ -377,14 +382,34 @@ impl WindowState {
377382
state
378383
}
379384

385+
/// Trigger the event immediately and return the event status.
386+
/// Will panic if `window_handler` is already borrowed (see `trigger_deferrable_event`).
380387
pub(super) fn trigger_event(&self, event: Event) -> EventStatus {
381388
let mut window = crate::Window::new(Window { inner: &self.window_inner });
382-
self.window_handler.borrow_mut().on_event(&mut window, event)
389+
let mut window_handler = self.window_handler.borrow_mut();
390+
let status = window_handler.on_event(&mut window, event);
391+
self.send_deferred_events(window_handler.as_mut());
392+
status
393+
}
394+
395+
/// Trigger the event immediately if `window_handler` can be borrowed mutably,
396+
/// otherwise add the event to a queue that will be cleared once `window_handler`'s mutable borrow ends.
397+
/// As this method might result in the event triggering asynchronously, it can't reliably return the event status.
398+
pub(super) fn trigger_deferrable_event(&self, event: Event) {
399+
if let Ok(mut window_handler) = self.window_handler.try_borrow_mut() {
400+
let mut window = crate::Window::new(Window { inner: &self.window_inner });
401+
window_handler.on_event(&mut window, event);
402+
self.send_deferred_events(window_handler.as_mut());
403+
} else {
404+
self.deferred_events.borrow_mut().push_back(event);
405+
}
383406
}
384407

385408
pub(super) fn trigger_frame(&self) {
386409
let mut window = crate::Window::new(Window { inner: &self.window_inner });
387-
self.window_handler.borrow_mut().on_frame(&mut window);
410+
let mut window_handler = self.window_handler.borrow_mut();
411+
window_handler.on_frame(&mut window);
412+
self.send_deferred_events(window_handler.as_mut());
388413
}
389414

390415
pub(super) fn keyboard_state(&self) -> &KeyboardState {
@@ -418,6 +443,18 @@ impl WindowState {
418443

419444
(*window_state_ptr).frame_timer.set(Some(timer));
420445
}
446+
447+
fn send_deferred_events(&self, window_handler: &mut dyn WindowHandler) {
448+
let mut window = crate::Window::new(Window { inner: &self.window_inner });
449+
loop {
450+
let next_event = self.deferred_events.borrow_mut().pop_front();
451+
if let Some(event) = next_event {
452+
window_handler.on_event(&mut window, event);
453+
} else {
454+
break;
455+
}
456+
}
457+
}
421458
}
422459

423460
unsafe impl<'a> HasRawWindowHandle for Window<'a> {

0 commit comments

Comments
 (0)