mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 14:51:30 +11:00
Do not call nextEventMatchingMask twice
wait_event used to call nextEventMatchingMask twice. Once with untilDate:distantFuture, and dequeue:NO to wait until the next event but witout consuming it, and again with untilDate:distantPast and dequeue:YES to retrieve the event (via poll_events). For some reason, with osx 10.11, calling nextEventMatchingMask with dequeue:NO never returns if the user scrolls, freezing the app. So we now call nextEventMatchingMask only once, with dequeue:YES.
This commit is contained in:
parent
a982c599d0
commit
cb78383da0
|
@ -197,101 +197,16 @@ impl<'a> Iterator for PollEventsIterator<'a> {
|
||||||
return Some(ev);
|
return Some(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let event: Option<Event>;
|
||||||
unsafe {
|
unsafe {
|
||||||
let event = NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_(
|
let nsevent = NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_(
|
||||||
NSAnyEventMask.bits(),
|
NSAnyEventMask.bits(),
|
||||||
NSDate::distantPast(nil),
|
NSDate::distantPast(nil),
|
||||||
NSDefaultRunLoopMode,
|
NSDefaultRunLoopMode,
|
||||||
YES);
|
YES);
|
||||||
if event == nil { return None; }
|
event = NSEventToEvent(self.window, nsevent);
|
||||||
|
|
||||||
let event_type = msg_send![event, type];
|
|
||||||
NSApp().sendEvent_(if let NSKeyDown = event_type { nil } else { event });
|
|
||||||
|
|
||||||
let event = match event_type {
|
|
||||||
NSLeftMouseDown => { Some(MouseInput(Pressed, MouseButton::Left)) },
|
|
||||||
NSLeftMouseUp => { Some(MouseInput(Released, MouseButton::Left)) },
|
|
||||||
NSRightMouseDown => { Some(MouseInput(Pressed, MouseButton::Right)) },
|
|
||||||
NSRightMouseUp => { Some(MouseInput(Released, MouseButton::Right)) },
|
|
||||||
NSMouseMoved |
|
|
||||||
NSLeftMouseDragged |
|
|
||||||
NSOtherMouseDragged |
|
|
||||||
NSRightMouseDragged => {
|
|
||||||
let window_point = event.locationInWindow();
|
|
||||||
let window: id = msg_send![event, window];
|
|
||||||
let view_point = if window == nil {
|
|
||||||
let window_rect = self.window.window.convertRectFromScreen_(NSRect::new(window_point, NSSize::new(0.0, 0.0)));
|
|
||||||
self.window.view.convertPoint_fromView_(window_rect.origin, nil)
|
|
||||||
} else {
|
|
||||||
self.window.view.convertPoint_fromView_(window_point, nil)
|
|
||||||
};
|
|
||||||
let view_rect = NSView::frame(*self.window.view);
|
|
||||||
let scale_factor = self.window.hidpi_factor();
|
|
||||||
|
|
||||||
Some(MouseMoved(((scale_factor * view_point.x as f32) as i32,
|
|
||||||
(scale_factor * (view_rect.size.height - view_point.y) as f32) as i32)))
|
|
||||||
},
|
|
||||||
NSKeyDown => {
|
|
||||||
let mut events = VecDeque::new();
|
|
||||||
let received_c_str = event.characters().UTF8String();
|
|
||||||
let received_str = CStr::from_ptr(received_c_str);
|
|
||||||
for received_char in from_utf8(received_str.to_bytes()).unwrap().chars() {
|
|
||||||
if received_char.is_ascii() {
|
|
||||||
events.push_back(ReceivedCharacter(received_char));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let vkey = event::vkeycode_to_element(NSEvent::keyCode(event));
|
|
||||||
events.push_back(KeyboardInput(Pressed, NSEvent::keyCode(event) as u8, vkey));
|
|
||||||
let event = events.pop_front();
|
|
||||||
self.window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter());
|
|
||||||
event
|
|
||||||
},
|
|
||||||
NSKeyUp => {
|
|
||||||
let vkey = event::vkeycode_to_element(NSEvent::keyCode(event));
|
|
||||||
|
|
||||||
Some(KeyboardInput(Released, NSEvent::keyCode(event) as u8, vkey))
|
|
||||||
},
|
|
||||||
NSFlagsChanged => {
|
|
||||||
let mut events = VecDeque::new();
|
|
||||||
let shift_modifier = Window::modifier_event(event, appkit::NSShiftKeyMask, events::VirtualKeyCode::LShift, shift_pressed);
|
|
||||||
if shift_modifier.is_some() {
|
|
||||||
shift_pressed = !shift_pressed;
|
|
||||||
events.push_back(shift_modifier.unwrap());
|
|
||||||
}
|
|
||||||
let ctrl_modifier = Window::modifier_event(event, appkit::NSControlKeyMask, events::VirtualKeyCode::LControl, ctrl_pressed);
|
|
||||||
if ctrl_modifier.is_some() {
|
|
||||||
ctrl_pressed = !ctrl_pressed;
|
|
||||||
events.push_back(ctrl_modifier.unwrap());
|
|
||||||
}
|
|
||||||
let win_modifier = Window::modifier_event(event, appkit::NSCommandKeyMask, events::VirtualKeyCode::LWin, win_pressed);
|
|
||||||
if win_modifier.is_some() {
|
|
||||||
win_pressed = !win_pressed;
|
|
||||||
events.push_back(win_modifier.unwrap());
|
|
||||||
}
|
|
||||||
let alt_modifier = Window::modifier_event(event, appkit::NSAlternateKeyMask, events::VirtualKeyCode::LAlt, alt_pressed);
|
|
||||||
if alt_modifier.is_some() {
|
|
||||||
alt_pressed = !alt_pressed;
|
|
||||||
events.push_back(alt_modifier.unwrap());
|
|
||||||
}
|
|
||||||
let event = events.pop_front();
|
|
||||||
self.window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter());
|
|
||||||
event
|
|
||||||
},
|
|
||||||
NSScrollWheel => {
|
|
||||||
use events::MouseScrollDelta::{LineDelta, PixelDelta};
|
|
||||||
let delta = if event.hasPreciseScrollingDeltas() == YES {
|
|
||||||
PixelDelta(event.scrollingDeltaX() as f32, event.scrollingDeltaY() as f32)
|
|
||||||
} else {
|
|
||||||
LineDelta(event.scrollingDeltaX() as f32, event.scrollingDeltaY() as f32)
|
|
||||||
};
|
|
||||||
Some(MouseWheel(delta))
|
|
||||||
},
|
|
||||||
_ => { None },
|
|
||||||
};
|
|
||||||
|
|
||||||
event
|
|
||||||
}
|
}
|
||||||
|
event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,25 +218,24 @@ impl<'a> Iterator for WaitEventsIterator<'a> {
|
||||||
type Item = Event;
|
type Item = Event;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Event> {
|
fn next(&mut self) -> Option<Event> {
|
||||||
loop {
|
if let Some(ev) = self.window.delegate.state.pending_events.lock().unwrap().pop_front() {
|
||||||
if let Some(ev) = self.window.delegate.state.pending_events.lock().unwrap().pop_front() {
|
return Some(ev);
|
||||||
return Some(ev);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
let event: Option<Event>;
|
||||||
let event = NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_(
|
unsafe {
|
||||||
NSAnyEventMask.bits(),
|
let nsevent = NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_(
|
||||||
NSDate::distantFuture(nil),
|
NSAnyEventMask.bits(),
|
||||||
NSDefaultRunLoopMode,
|
NSDate::distantFuture(nil),
|
||||||
NO);
|
NSDefaultRunLoopMode,
|
||||||
}
|
YES);
|
||||||
|
event = NSEventToEvent(self.window, nsevent);
|
||||||
|
}
|
||||||
|
|
||||||
// calling poll_events()
|
if event.is_none() {
|
||||||
if let Some(ev) = self.window.poll_events().next() {
|
return Some(Awakened);
|
||||||
return Some(ev);
|
} else {
|
||||||
} else {
|
return event;
|
||||||
return Some(Awakened);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -877,3 +791,91 @@ impl Clone for IdRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option<Event> {
|
||||||
|
if nsevent == nil { return None; }
|
||||||
|
|
||||||
|
let event_type = msg_send![nsevent, type];
|
||||||
|
NSApp().sendEvent_(if let NSKeyDown = event_type { nil } else { nsevent });
|
||||||
|
|
||||||
|
match event_type {
|
||||||
|
NSLeftMouseDown => { Some(MouseInput(Pressed, MouseButton::Left)) },
|
||||||
|
NSLeftMouseUp => { Some(MouseInput(Released, MouseButton::Left)) },
|
||||||
|
NSRightMouseDown => { Some(MouseInput(Pressed, MouseButton::Right)) },
|
||||||
|
NSRightMouseUp => { Some(MouseInput(Released, MouseButton::Right)) },
|
||||||
|
NSMouseMoved |
|
||||||
|
NSLeftMouseDragged |
|
||||||
|
NSOtherMouseDragged |
|
||||||
|
NSRightMouseDragged => {
|
||||||
|
let window_point = nsevent.locationInWindow();
|
||||||
|
let cWindow: id = msg_send![nsevent, window];
|
||||||
|
let view_point = if cWindow == nil {
|
||||||
|
let window_rect = window.window.convertRectFromScreen_(NSRect::new(window_point, NSSize::new(0.0, 0.0)));
|
||||||
|
window.view.convertPoint_fromView_(window_rect.origin, nil)
|
||||||
|
} else {
|
||||||
|
window.view.convertPoint_fromView_(window_point, nil)
|
||||||
|
};
|
||||||
|
let view_rect = NSView::frame(*window.view);
|
||||||
|
let scale_factor = window.hidpi_factor();
|
||||||
|
|
||||||
|
Some(MouseMoved(((scale_factor * view_point.x as f32) as i32,
|
||||||
|
(scale_factor * (view_rect.size.height - view_point.y) as f32) as i32)))
|
||||||
|
},
|
||||||
|
NSKeyDown => {
|
||||||
|
let mut events = VecDeque::new();
|
||||||
|
let received_c_str = nsevent.characters().UTF8String();
|
||||||
|
let received_str = CStr::from_ptr(received_c_str);
|
||||||
|
for received_char in from_utf8(received_str.to_bytes()).unwrap().chars() {
|
||||||
|
if received_char.is_ascii() {
|
||||||
|
events.push_back(ReceivedCharacter(received_char));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let vkey = event::vkeycode_to_element(NSEvent::keyCode(nsevent));
|
||||||
|
events.push_back(KeyboardInput(Pressed, NSEvent::keyCode(nsevent) as u8, vkey));
|
||||||
|
let event = events.pop_front();
|
||||||
|
window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter());
|
||||||
|
event
|
||||||
|
},
|
||||||
|
NSKeyUp => {
|
||||||
|
let vkey = event::vkeycode_to_element(NSEvent::keyCode(nsevent));
|
||||||
|
|
||||||
|
Some(KeyboardInput(Released, NSEvent::keyCode(nsevent) as u8, vkey))
|
||||||
|
},
|
||||||
|
NSFlagsChanged => {
|
||||||
|
let mut events = VecDeque::new();
|
||||||
|
let shift_modifier = Window::modifier_event(nsevent, appkit::NSShiftKeyMask, events::VirtualKeyCode::LShift, shift_pressed);
|
||||||
|
if shift_modifier.is_some() {
|
||||||
|
shift_pressed = !shift_pressed;
|
||||||
|
events.push_back(shift_modifier.unwrap());
|
||||||
|
}
|
||||||
|
let ctrl_modifier = Window::modifier_event(nsevent, appkit::NSControlKeyMask, events::VirtualKeyCode::LControl, ctrl_pressed);
|
||||||
|
if ctrl_modifier.is_some() {
|
||||||
|
ctrl_pressed = !ctrl_pressed;
|
||||||
|
events.push_back(ctrl_modifier.unwrap());
|
||||||
|
}
|
||||||
|
let win_modifier = Window::modifier_event(nsevent, appkit::NSCommandKeyMask, events::VirtualKeyCode::LWin, win_pressed);
|
||||||
|
if win_modifier.is_some() {
|
||||||
|
win_pressed = !win_pressed;
|
||||||
|
events.push_back(win_modifier.unwrap());
|
||||||
|
}
|
||||||
|
let alt_modifier = Window::modifier_event(nsevent, appkit::NSAlternateKeyMask, events::VirtualKeyCode::LAlt, alt_pressed);
|
||||||
|
if alt_modifier.is_some() {
|
||||||
|
alt_pressed = !alt_pressed;
|
||||||
|
events.push_back(alt_modifier.unwrap());
|
||||||
|
}
|
||||||
|
let event = events.pop_front();
|
||||||
|
window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter());
|
||||||
|
event
|
||||||
|
},
|
||||||
|
NSScrollWheel => {
|
||||||
|
use events::MouseScrollDelta::{LineDelta, PixelDelta};
|
||||||
|
let delta = if nsevent.hasPreciseScrollingDeltas() == YES {
|
||||||
|
PixelDelta(nsevent.scrollingDeltaX() as f32, nsevent.scrollingDeltaY() as f32)
|
||||||
|
} else {
|
||||||
|
LineDelta(nsevent.scrollingDeltaX() as f32, nsevent.scrollingDeltaY() as f32)
|
||||||
|
};
|
||||||
|
Some(MouseWheel(delta))
|
||||||
|
},
|
||||||
|
_ => { None },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue