Simplify event queuing on macOS (#2642)

This commit is contained in:
Mads Marquart 2023-01-22 23:29:38 +01:00 committed by GitHub
parent 7341ee80ea
commit 0f2fbe373b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 143 additions and 270 deletions

View file

@ -1,7 +1,5 @@
#![allow(clippy::unnecessary_cast)] #![allow(clippy::unnecessary_cast)]
use std::collections::VecDeque;
use objc2::foundation::NSObject; use objc2::foundation::NSObject;
use objc2::{declare_class, msg_send, ClassType}; use objc2::{declare_class, msg_send, ClassType};
@ -50,70 +48,51 @@ fn maybe_dispatch_device_event(event: &NSEvent) {
| NSEventType::NSLeftMouseDragged | NSEventType::NSLeftMouseDragged
| NSEventType::NSOtherMouseDragged | NSEventType::NSOtherMouseDragged
| NSEventType::NSRightMouseDragged => { | NSEventType::NSRightMouseDragged => {
let mut events = VecDeque::with_capacity(3);
let delta_x = event.deltaX() as f64; let delta_x = event.deltaX() as f64;
let delta_y = event.deltaY() as f64; let delta_y = event.deltaY() as f64;
if delta_x != 0.0 { if delta_x != 0.0 {
events.push_back(EventWrapper::StaticEvent(Event::DeviceEvent { queue_device_event(DeviceEvent::Motion {
device_id: DEVICE_ID, axis: 0,
event: DeviceEvent::Motion { value: delta_x,
axis: 0, });
value: delta_x,
},
}));
} }
if delta_y != 0.0 { if delta_y != 0.0 {
events.push_back(EventWrapper::StaticEvent(Event::DeviceEvent { queue_device_event(DeviceEvent::Motion {
device_id: DEVICE_ID, axis: 1,
event: DeviceEvent::Motion { value: delta_y,
axis: 1, })
value: delta_y,
},
}));
} }
if delta_x != 0.0 || delta_y != 0.0 { if delta_x != 0.0 || delta_y != 0.0 {
events.push_back(EventWrapper::StaticEvent(Event::DeviceEvent { queue_device_event(DeviceEvent::MouseMotion {
device_id: DEVICE_ID, delta: (delta_x, delta_y),
event: DeviceEvent::MouseMotion { });
delta: (delta_x, delta_y),
},
}));
} }
AppState::queue_events(events);
} }
NSEventType::NSLeftMouseDown NSEventType::NSLeftMouseDown
| NSEventType::NSRightMouseDown | NSEventType::NSRightMouseDown
| NSEventType::NSOtherMouseDown => { | NSEventType::NSOtherMouseDown => {
let mut events = VecDeque::with_capacity(1); queue_device_event(DeviceEvent::Button {
button: event.buttonNumber() as u32,
events.push_back(EventWrapper::StaticEvent(Event::DeviceEvent { state: ElementState::Pressed,
device_id: DEVICE_ID, });
event: DeviceEvent::Button {
button: event.buttonNumber() as u32,
state: ElementState::Pressed,
},
}));
AppState::queue_events(events);
} }
NSEventType::NSLeftMouseUp | NSEventType::NSRightMouseUp | NSEventType::NSOtherMouseUp => { NSEventType::NSLeftMouseUp | NSEventType::NSRightMouseUp | NSEventType::NSOtherMouseUp => {
let mut events = VecDeque::with_capacity(1); queue_device_event(DeviceEvent::Button {
button: event.buttonNumber() as u32,
events.push_back(EventWrapper::StaticEvent(Event::DeviceEvent { state: ElementState::Released,
device_id: DEVICE_ID, });
event: DeviceEvent::Button {
button: event.buttonNumber() as u32,
state: ElementState::Released,
},
}));
AppState::queue_events(events);
} }
_ => (), _ => (),
} }
} }
fn queue_device_event(event: DeviceEvent) {
let event = Event::DeviceEvent {
device_id: DEVICE_ID,
event,
};
AppState::queue_event(EventWrapper::StaticEvent(event));
}

View file

@ -368,13 +368,6 @@ impl AppState {
HANDLER.events().push_back(wrapper); HANDLER.events().push_back(wrapper);
} }
pub fn queue_events(mut wrappers: VecDeque<EventWrapper>) {
if !is_main_thread() {
panic!("Events queued from different thread: {:#?}", wrappers);
}
HANDLER.events().append(&mut wrappers);
}
pub fn cleared(panic_info: Weak<PanicInfo>) { pub fn cleared(panic_info: Weak<PanicInfo>) {
let panic_info = panic_info let panic_info = panic_info
.upgrade() .upgrade()

View file

@ -1,6 +1,6 @@
#![allow(clippy::unnecessary_cast)] #![allow(clippy::unnecessary_cast)]
use std::{boxed::Box, collections::VecDeque, os::raw::*, ptr, str, sync::Mutex}; use std::{boxed::Box, os::raw::*, ptr, str, sync::Mutex};
use objc2::declare::{Ivar, IvarDrop}; use objc2::declare::{Ivar, IvarDrop};
use objc2::foundation::{ use objc2::foundation::{
@ -224,10 +224,7 @@ declare_class!(
// 2. Even when a window resize does occur on a new tabbed window, it contains the wrong size (includes tab height). // 2. Even when a window resize does occur on a new tabbed window, it contains the wrong size (includes tab height).
let logical_size = LogicalSize::new(rect.size.width as f64, rect.size.height as f64); let logical_size = LogicalSize::new(rect.size.width as f64, rect.size.height as f64);
let size = logical_size.to_physical::<u32>(self.scale_factor()); let size = logical_size.to_physical::<u32>(self.scale_factor());
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::Resized(size));
window_id: self.window_id(),
event: WindowEvent::Resized(size),
}));
} }
#[sel(drawRect:)] #[sel(drawRect:)]
@ -329,10 +326,7 @@ declare_class!(
// Notify IME is active if application still doesn't know it. // Notify IME is active if application still doesn't know it.
if self.state.ime_state == ImeState::Disabled { if self.state.ime_state == ImeState::Disabled {
self.state.input_source = self.current_input_source(); self.state.input_source = self.current_input_source();
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::Ime(Ime::Enabled));
window_id: self.window_id(),
event: WindowEvent::Ime(Ime::Enabled),
}));
} }
// Don't update self.state to preedit when we've just commited a string, since the following // Don't update self.state to preedit when we've just commited a string, since the following
@ -350,10 +344,7 @@ declare_class!(
}; };
// Send WindowEvent for updating marked text // Send WindowEvent for updating marked text
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::Ime(Ime::Preedit(preedit_string, cursor_range)));
window_id: self.window_id(),
event: WindowEvent::Ime(Ime::Preedit(preedit_string, cursor_range)),
}));
} }
#[sel(unmarkText)] #[sel(unmarkText)]
@ -364,10 +355,7 @@ declare_class!(
let input_context = self.inputContext().expect("input context"); let input_context = self.inputContext().expect("input context");
input_context.discardMarkedText(); input_context.discardMarkedText();
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::Ime(Ime::Preedit(String::new(), None)));
window_id: self.window_id(),
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
}));
if self.is_ime_enabled() { if self.is_ime_enabled() {
// Leave the Preedit self.state // Leave the Preedit self.state
self.state.ime_state = ImeState::Enabled; self.state.ime_state = ImeState::Enabled;
@ -436,14 +424,8 @@ declare_class!(
let is_control = string.chars().next().map_or(false, |c| c.is_control()); let is_control = string.chars().next().map_or(false, |c| c.is_control());
if self.is_ime_enabled() && !is_control { if self.is_ime_enabled() && !is_control {
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::Ime(Ime::Preedit(String::new(), None)));
window_id: self.window_id(), self.queue_event(WindowEvent::Ime(Ime::Commit(string)));
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
}));
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent {
window_id: self.window_id(),
event: WindowEvent::Ime(Ime::Commit(string)),
}));
self.state.ime_state = ImeState::Commited; self.state.ime_state = ImeState::Commited;
} }
} }
@ -473,16 +455,11 @@ declare_class!(
#[sel(keyDown:)] #[sel(keyDown:)]
fn key_down(&mut self, event: &NSEvent) { fn key_down(&mut self, event: &NSEvent) {
trace_scope!("keyDown:"); trace_scope!("keyDown:");
let window_id = self.window_id();
let input_source = self.current_input_source(); let input_source = self.current_input_source();
if self.state.input_source != input_source && self.is_ime_enabled() { if self.state.input_source != input_source && self.is_ime_enabled() {
self.state.ime_state = ImeState::Disabled; self.state.ime_state = ImeState::Disabled;
self.state.input_source = input_source; self.state.input_source = input_source;
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::Ime(Ime::Disabled));
window_id,
event: WindowEvent::Ime(Ime::Disabled),
}));
} }
let was_in_preedit = self.state.ime_state == ImeState::Preedit; let was_in_preedit = self.state.ime_state == ImeState::Preedit;
@ -518,27 +495,19 @@ declare_class!(
if !ime_related || self.state.forward_key_to_app || !self.state.ime_allowed { if !ime_related || self.state.forward_key_to_app || !self.state.ime_allowed {
#[allow(deprecated)] #[allow(deprecated)]
let window_event = Event::WindowEvent { self.queue_event(WindowEvent::KeyboardInput {
window_id, device_id: DEVICE_ID,
event: WindowEvent::KeyboardInput { input: KeyboardInput {
device_id: DEVICE_ID, state: ElementState::Pressed,
input: KeyboardInput { scancode,
state: ElementState::Pressed, virtual_keycode,
scancode, modifiers: event_mods(event),
virtual_keycode,
modifiers: event_mods(event),
},
is_synthetic: false,
}, },
}; is_synthetic: false,
});
AppState::queue_event(EventWrapper::StaticEvent(window_event));
for character in characters.chars().filter(|c| !is_corporate_character(*c)) { for character in characters.chars().filter(|c| !is_corporate_character(*c)) {
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::ReceivedCharacter(character));
window_id,
event: WindowEvent::ReceivedCharacter(character),
}));
} }
} }
} }
@ -554,21 +523,16 @@ declare_class!(
// We want to send keyboard input when we are not currently in preedit // We want to send keyboard input when we are not currently in preedit
if self.state.ime_state != ImeState::Preedit { if self.state.ime_state != ImeState::Preedit {
#[allow(deprecated)] #[allow(deprecated)]
let window_event = Event::WindowEvent { self.queue_event(WindowEvent::KeyboardInput {
window_id: self.window_id(), device_id: DEVICE_ID,
event: WindowEvent::KeyboardInput { input: KeyboardInput {
device_id: DEVICE_ID, state: ElementState::Released,
input: KeyboardInput { scancode,
state: ElementState::Released, virtual_keycode,
scancode, modifiers: event_mods(event),
virtual_keycode,
modifiers: event_mods(event),
},
is_synthetic: false,
}, },
}; is_synthetic: false,
});
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
} }
@ -576,15 +540,13 @@ declare_class!(
fn flags_changed(&mut self, event: &NSEvent) { fn flags_changed(&mut self, event: &NSEvent) {
trace_scope!("flagsChanged:"); trace_scope!("flagsChanged:");
let mut events = VecDeque::with_capacity(4);
if let Some(window_event) = modifier_event( if let Some(window_event) = modifier_event(
event, event,
NSEventModifierFlags::NSShiftKeyMask, NSEventModifierFlags::NSShiftKeyMask,
self.state.modifiers.shift(), self.state.modifiers.shift(),
) { ) {
self.state.modifiers.toggle(ModifiersState::SHIFT); self.state.modifiers.toggle(ModifiersState::SHIFT);
events.push_back(window_event); self.queue_event(window_event);
} }
if let Some(window_event) = modifier_event( if let Some(window_event) = modifier_event(
@ -593,7 +555,7 @@ declare_class!(
self.state.modifiers.ctrl(), self.state.modifiers.ctrl(),
) { ) {
self.state.modifiers.toggle(ModifiersState::CTRL); self.state.modifiers.toggle(ModifiersState::CTRL);
events.push_back(window_event); self.queue_event(window_event);
} }
if let Some(window_event) = modifier_event( if let Some(window_event) = modifier_event(
@ -602,7 +564,7 @@ declare_class!(
self.state.modifiers.logo(), self.state.modifiers.logo(),
) { ) {
self.state.modifiers.toggle(ModifiersState::LOGO); self.state.modifiers.toggle(ModifiersState::LOGO);
events.push_back(window_event); self.queue_event(window_event);
} }
if let Some(window_event) = modifier_event( if let Some(window_event) = modifier_event(
@ -611,22 +573,10 @@ declare_class!(
self.state.modifiers.alt(), self.state.modifiers.alt(),
) { ) {
self.state.modifiers.toggle(ModifiersState::ALT); self.state.modifiers.toggle(ModifiersState::ALT);
events.push_back(window_event); self.queue_event(window_event);
} }
let window_id = self.window_id(); self.queue_event(WindowEvent::ModifiersChanged(self.state.modifiers));
for event in events {
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent {
window_id,
event,
}));
}
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent {
window_id,
event: WindowEvent::ModifiersChanged(self.state.modifiers),
}));
} }
#[sel(insertTab:)] #[sel(insertTab:)]
@ -667,21 +617,16 @@ declare_class!(
self.update_potentially_stale_modifiers(&event); self.update_potentially_stale_modifiers(&event);
#[allow(deprecated)] #[allow(deprecated)]
let window_event = Event::WindowEvent { self.queue_event(WindowEvent::KeyboardInput {
window_id: self.window_id(), device_id: DEVICE_ID,
event: WindowEvent::KeyboardInput { input: KeyboardInput {
device_id: DEVICE_ID, state: ElementState::Pressed,
input: KeyboardInput { scancode: scancode as _,
state: ElementState::Pressed, virtual_keycode,
scancode: scancode as _, modifiers: event_mods(&event),
virtual_keycode,
modifiers: event_mods(&event),
},
is_synthetic: false,
}, },
}; is_synthetic: false,
});
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
#[sel(mouseDown:)] #[sel(mouseDown:)]
@ -751,27 +696,18 @@ declare_class!(
#[sel(mouseEntered:)] #[sel(mouseEntered:)]
fn mouse_entered(&self, _event: &NSEvent) { fn mouse_entered(&self, _event: &NSEvent) {
trace_scope!("mouseEntered:"); trace_scope!("mouseEntered:");
let enter_event = Event::WindowEvent { self.queue_event(WindowEvent::CursorEntered {
window_id: self.window_id(), device_id: DEVICE_ID,
event: WindowEvent::CursorEntered { });
device_id: DEVICE_ID,
},
};
AppState::queue_event(EventWrapper::StaticEvent(enter_event));
} }
#[sel(mouseExited:)] #[sel(mouseExited:)]
fn mouse_exited(&self, _event: &NSEvent) { fn mouse_exited(&self, _event: &NSEvent) {
trace_scope!("mouseExited:"); trace_scope!("mouseExited:");
let window_event = Event::WindowEvent {
window_id: self.window_id(),
event: WindowEvent::CursorLeft {
device_id: DEVICE_ID,
},
};
AppState::queue_event(EventWrapper::StaticEvent(window_event)); self.queue_event(WindowEvent::CursorLeft {
device_id: DEVICE_ID,
});
} }
#[sel(scrollWheel:)] #[sel(scrollWheel:)]
@ -812,32 +748,21 @@ declare_class!(
}, },
}; };
let device_event = Event::DeviceEvent {
device_id: DEVICE_ID,
event: DeviceEvent::MouseWheel { delta },
};
self.update_potentially_stale_modifiers(event); self.update_potentially_stale_modifiers(event);
let window_event = Event::WindowEvent { self.queue_device_event(DeviceEvent::MouseWheel { delta });
window_id: self.window_id(), self.queue_event(WindowEvent::MouseWheel {
event: WindowEvent::MouseWheel { device_id: DEVICE_ID,
device_id: DEVICE_ID, delta,
delta, phase,
phase, modifiers: event_mods(event),
modifiers: event_mods(event), });
},
};
AppState::queue_event(EventWrapper::StaticEvent(device_event));
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
#[sel(magnifyWithEvent:)] #[sel(magnifyWithEvent:)]
fn magnify_with_event(&self, event: &NSEvent) { fn magnify_with_event(&self, event: &NSEvent) {
trace_scope!("magnifyWithEvent:"); trace_scope!("magnifyWithEvent:");
let delta = event.magnification();
let phase = match event.phase() { let phase = match event.phase() {
NSEventPhase::NSEventPhaseBegan => TouchPhase::Started, NSEventPhase::NSEventPhaseBegan => TouchPhase::Started,
NSEventPhase::NSEventPhaseChanged => TouchPhase::Moved, NSEventPhase::NSEventPhaseChanged => TouchPhase::Moved,
@ -846,37 +771,26 @@ declare_class!(
_ => return, _ => return,
}; };
let window_event = Event::WindowEvent { self.queue_event(WindowEvent::TouchpadMagnify {
window_id: self.window_id(), device_id: DEVICE_ID,
event: WindowEvent::TouchpadMagnify { delta: event.magnification(),
device_id: DEVICE_ID, phase,
delta, });
phase,
},
};
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
#[sel(smartMagnifyWithEvent:)] #[sel(smartMagnifyWithEvent:)]
fn smart_magnify_with_event(&self, _event: &NSEvent) { fn smart_magnify_with_event(&self, _event: &NSEvent) {
trace_scope!("smartMagnifyWithEvent:"); trace_scope!("smartMagnifyWithEvent:");
let window_event = Event::WindowEvent { self.queue_event(WindowEvent::SmartMagnify {
window_id: self.window_id(), device_id: DEVICE_ID,
event: WindowEvent::SmartMagnify { });
device_id: DEVICE_ID,
},
};
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
#[sel(rotateWithEvent:)] #[sel(rotateWithEvent:)]
fn rotate_with_event(&self, event: &NSEvent) { fn rotate_with_event(&self, event: &NSEvent) {
trace_scope!("rotateWithEvent:"); trace_scope!("rotateWithEvent:");
let delta = event.rotation();
let phase = match event.phase() { let phase = match event.phase() {
NSEventPhase::NSEventPhaseBegan => TouchPhase::Started, NSEventPhase::NSEventPhaseBegan => TouchPhase::Started,
NSEventPhase::NSEventPhaseChanged => TouchPhase::Moved, NSEventPhase::NSEventPhaseChanged => TouchPhase::Moved,
@ -885,16 +799,11 @@ declare_class!(
_ => return, _ => return,
}; };
let window_event = Event::WindowEvent { self.queue_event(WindowEvent::TouchpadRotate {
window_id: self.window_id(), device_id: DEVICE_ID,
event: WindowEvent::TouchpadRotate { delta: event.rotation(),
device_id: DEVICE_ID, phase,
delta, });
phase,
},
};
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
#[sel(pressureChangeWithEvent:)] #[sel(pressureChangeWithEvent:)]
@ -903,19 +812,11 @@ declare_class!(
self.mouse_motion(event); self.mouse_motion(event);
let pressure = event.pressure(); self.queue_event(WindowEvent::TouchpadPressure {
let stage = event.stage(); device_id: DEVICE_ID,
pressure: event.pressure(),
let window_event = Event::WindowEvent { stage: event.stage() as i64,
window_id: self.window_id(), });
event: WindowEvent::TouchpadPressure {
device_id: DEVICE_ID,
pressure,
stage: stage as i64,
},
};
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
// Allows us to receive Ctrl-Tab and Ctrl-Esc. // Allows us to receive Ctrl-Tab and Ctrl-Esc.
@ -959,6 +860,22 @@ impl WinitView {
WindowId(self._ns_window.id()) WindowId(self._ns_window.id())
} }
fn queue_event(&self, event: WindowEvent<'static>) {
let event = Event::WindowEvent {
window_id: self.window_id(),
event,
};
AppState::queue_event(EventWrapper::StaticEvent(event));
}
fn queue_device_event(&self, event: DeviceEvent) {
let event = Event::DeviceEvent {
device_id: DEVICE_ID,
event,
};
AppState::queue_event(EventWrapper::StaticEvent(event));
}
fn scale_factor(&self) -> f64 { fn scale_factor(&self) -> f64 {
self.window().backingScaleFactor() as f64 self.window().backingScaleFactor() as f64
} }
@ -989,10 +906,7 @@ impl WinitView {
if self.state.ime_state != ImeState::Disabled { if self.state.ime_state != ImeState::Disabled {
self.state.ime_state = ImeState::Disabled; self.state.ime_state = ImeState::Disabled;
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::Ime(Ime::Disabled));
window_id: self.window_id(),
event: WindowEvent::Ime(Ime::Disabled),
}));
} }
} }
@ -1008,10 +922,7 @@ impl WinitView {
if self.state.modifiers != event_modifiers { if self.state.modifiers != event_modifiers {
self.state.modifiers = event_modifiers; self.state.modifiers = event_modifiers;
AppState::queue_event(EventWrapper::StaticEvent(Event::WindowEvent { self.queue_event(WindowEvent::ModifiersChanged(self.state.modifiers));
window_id: self.window_id(),
event: WindowEvent::ModifiersChanged(self.state.modifiers),
}));
} }
} }
@ -1020,17 +931,12 @@ impl WinitView {
self.update_potentially_stale_modifiers(event); self.update_potentially_stale_modifiers(event);
let window_event = Event::WindowEvent { self.queue_event(WindowEvent::MouseInput {
window_id: self.window_id(), device_id: DEVICE_ID,
event: WindowEvent::MouseInput { state: button_state,
device_id: DEVICE_ID, button,
state: button_state, modifiers: event_mods(event),
button, });
modifiers: event_mods(event),
},
};
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
fn mouse_motion(&mut self, event: &NSEvent) { fn mouse_motion(&mut self, event: &NSEvent) {
@ -1056,16 +962,11 @@ impl WinitView {
self.update_potentially_stale_modifiers(event); self.update_potentially_stale_modifiers(event);
let window_event = Event::WindowEvent { self.queue_event(WindowEvent::CursorMoved {
window_id: self.window_id(), device_id: DEVICE_ID,
event: WindowEvent::CursorMoved { position: logical_position.to_physical(self.scale_factor()),
device_id: DEVICE_ID, modifiers: event_mods(event),
position: logical_position.to_physical(self.scale_factor()), });
modifiers: event_mods(event),
},
};
AppState::queue_event(EventWrapper::StaticEvent(window_event));
} }
} }

View file

@ -65,7 +65,7 @@ declare_class!(
Ivar::write(&mut this.previous_scale_factor, scale_factor); Ivar::write(&mut this.previous_scale_factor, scale_factor);
if scale_factor != 1.0 { if scale_factor != 1.0 {
this.emit_static_scale_factor_changed_event(); this.queue_static_scale_factor_changed_event();
} }
this.window.setDelegate(Some(this)); this.window.setDelegate(Some(this));
@ -94,7 +94,7 @@ declare_class!(
#[sel(windowShouldClose:)] #[sel(windowShouldClose:)]
fn window_should_close(&self, _: Option<&Object>) -> bool { fn window_should_close(&self, _: Option<&Object>) -> bool {
trace_scope!("windowShouldClose:"); trace_scope!("windowShouldClose:");
self.emit_event(WindowEvent::CloseRequested); self.queue_event(WindowEvent::CloseRequested);
false false
} }
@ -107,7 +107,7 @@ declare_class!(
// be called after the window closes. // be called after the window closes.
self.window.setDelegate(None); self.window.setDelegate(None);
}); });
self.emit_event(WindowEvent::Destroyed); self.queue_event(WindowEvent::Destroyed);
} }
#[sel(windowDidResize:)] #[sel(windowDidResize:)]
@ -127,7 +127,7 @@ declare_class!(
#[sel(windowDidChangeBackingProperties:)] #[sel(windowDidChangeBackingProperties:)]
fn window_did_change_backing_properties(&mut self, _: Option<&Object>) { fn window_did_change_backing_properties(&mut self, _: Option<&Object>) {
trace_scope!("windowDidChangeBackingProperties:"); trace_scope!("windowDidChangeBackingProperties:");
self.emit_static_scale_factor_changed_event(); self.queue_static_scale_factor_changed_event();
} }
#[sel(windowDidBecomeKey:)] #[sel(windowDidBecomeKey:)]
@ -135,7 +135,7 @@ declare_class!(
trace_scope!("windowDidBecomeKey:"); trace_scope!("windowDidBecomeKey:");
// TODO: center the cursor if the window had mouse grab when it // TODO: center the cursor if the window had mouse grab when it
// lost focus // lost focus
self.emit_event(WindowEvent::Focused(true)); self.queue_event(WindowEvent::Focused(true));
} }
#[sel(windowDidResignKey:)] #[sel(windowDidResignKey:)]
@ -155,10 +155,10 @@ declare_class!(
// Both update the state and emit a ModifiersChanged event. // Both update the state and emit a ModifiersChanged event.
if !view.state.modifiers.is_empty() { if !view.state.modifiers.is_empty() {
view.state.modifiers = ModifiersState::empty(); view.state.modifiers = ModifiersState::empty();
self.emit_event(WindowEvent::ModifiersChanged(view.state.modifiers)); self.queue_event(WindowEvent::ModifiersChanged(view.state.modifiers));
} }
self.emit_event(WindowEvent::Focused(false)); self.queue_event(WindowEvent::Focused(false));
} }
/// Invoked when the dragged image enters destination bounds or frame /// Invoked when the dragged image enters destination bounds or frame
@ -174,7 +174,7 @@ declare_class!(
filenames.into_iter().for_each(|file| { filenames.into_iter().for_each(|file| {
let path = PathBuf::from(file.to_string()); let path = PathBuf::from(file.to_string());
self.emit_event(WindowEvent::HoveredFile(path)); self.queue_event(WindowEvent::HoveredFile(path));
}); });
true true
@ -200,7 +200,7 @@ declare_class!(
filenames.into_iter().for_each(|file| { filenames.into_iter().for_each(|file| {
let path = PathBuf::from(file.to_string()); let path = PathBuf::from(file.to_string());
self.emit_event(WindowEvent::DroppedFile(path)); self.queue_event(WindowEvent::DroppedFile(path));
}); });
true true
@ -216,7 +216,7 @@ declare_class!(
#[sel(draggingExited:)] #[sel(draggingExited:)]
fn dragging_exited(&self, _: Option<&Object>) { fn dragging_exited(&self, _: Option<&Object>) {
trace_scope!("draggingExited:"); trace_scope!("draggingExited:");
self.emit_event(WindowEvent::HoveredFileCancelled); self.queue_event(WindowEvent::HoveredFileCancelled);
} }
/// Invoked when before enter fullscreen /// Invoked when before enter fullscreen
@ -357,7 +357,7 @@ declare_class!(
#[sel(windowDidChangeOcclusionState:)] #[sel(windowDidChangeOcclusionState:)]
fn window_did_change_occlusion_state(&self, _: Option<&Object>) { fn window_did_change_occlusion_state(&self, _: Option<&Object>) {
trace_scope!("windowDidChangeOcclusionState:"); trace_scope!("windowDidChangeOcclusionState:");
self.emit_event(WindowEvent::Occluded( self.queue_event(WindowEvent::Occluded(
!self !self
.window .window
.occlusionState() .occlusionState()
@ -389,7 +389,7 @@ declare_class!(
shared_state.current_theme = Some(theme); shared_state.current_theme = Some(theme);
drop(shared_state); drop(shared_state);
if current_theme != Some(theme) { if current_theme != Some(theme) {
self.emit_event(WindowEvent::ThemeChanged(theme)); self.queue_event(WindowEvent::ThemeChanged(theme));
} }
} }
} }
@ -406,7 +406,7 @@ impl WinitWindowDelegate {
} }
} }
fn emit_event(&self, event: WindowEvent<'static>) { fn queue_event(&self, event: WindowEvent<'static>) {
let event = Event::WindowEvent { let event = Event::WindowEvent {
window_id: WindowId(self.window.id()), window_id: WindowId(self.window.id()),
event, event,
@ -414,7 +414,7 @@ impl WinitWindowDelegate {
AppState::queue_event(EventWrapper::StaticEvent(event)); AppState::queue_event(EventWrapper::StaticEvent(event));
} }
fn emit_static_scale_factor_changed_event(&mut self) { fn queue_static_scale_factor_changed_event(&mut self) {
let scale_factor = self.window.scale_factor(); let scale_factor = self.window.scale_factor();
if scale_factor == *self.previous_scale_factor { if scale_factor == *self.previous_scale_factor {
return; return;
@ -437,7 +437,7 @@ impl WinitWindowDelegate {
*self.previous_position = Some(Box::new((x, y))); *self.previous_position = Some(Box::new((x, y)));
let scale_factor = self.window.scale_factor(); let scale_factor = self.window.scale_factor();
let physical_pos = LogicalPosition::<f64>::from((x, y)).to_physical(scale_factor); let physical_pos = LogicalPosition::<f64>::from((x, y)).to_physical(scale_factor);
self.emit_event(WindowEvent::Moved(physical_pos)); self.queue_event(WindowEvent::Moved(physical_pos));
} }
} }