diff --git a/Cargo.toml b/Cargo.toml index dc9ac5598a..11641f863a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,9 @@ cocoa = "0.18.4" core-foundation = "0.6" core-graphics = "0.17.3" +[target.'cfg(target_os = "windows")'.dependencies.crossbeam-channel] +version = "0.3" + [target.'cfg(target_os = "windows")'.dependencies.winapi] version = "0.3.6" features = [ diff --git a/README.md b/README.md index 5f5771bc27..0fbf3b0017 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,10 @@ another library. extern crate winit; fn main() { - let mut events_loop = winit::EventsLoop::new(); - let window = winit::Window::new(&events_loop).unwrap(); + let mut event_loop = winit::EventLoop::new(); + let window = winit::Window::new(&event_loop).unwrap(); - events_loop.run_forever(|event| { + event_loop.run(|event| { match event { winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, diff --git a/examples/proxy.rs b/examples/proxy.rs index c9f7bf751a..fe648ed66b 100644 --- a/examples/proxy.rs +++ b/examples/proxy.rs @@ -1,9 +1,10 @@ extern crate winit; +use winit::{EventLoop, WindowBuilder}; fn main() { - let events_loop = winit::EventLoop::new(); + let events_loop: EventLoop = EventLoop::new_user_event(); - let _window = winit::WindowBuilder::new() + let _window = WindowBuilder::new() .with_title("A fantastic window!") .build(&events_loop) .unwrap(); @@ -11,10 +12,12 @@ fn main() { let proxy = events_loop.create_proxy(); std::thread::spawn(move || { + let mut counter = 0; // Wake up the `events_loop` once every second. loop { std::thread::sleep(std::time::Duration::from_secs(1)); - proxy.wakeup().unwrap(); + proxy.send_event(counter).unwrap(); + counter += 1; } }); @@ -22,7 +25,7 @@ fn main() { println!("{:?}", event); match event { winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => - *control_flow = winit::ControlFlow::Wait, + *control_flow = winit::ControlFlow::Exit, _ => *control_flow = winit::ControlFlow::Wait, } }); diff --git a/src/events.rs b/src/events.rs index 8951ed6f2d..6726fa3b2f 100644 --- a/src/events.rs +++ b/src/events.rs @@ -5,7 +5,7 @@ use {DeviceId, LogicalPosition, LogicalSize, WindowId}; /// Describes a generic event. #[derive(Clone, Debug, PartialEq)] -pub enum Event { +pub enum Event { WindowEvent { window_id: WindowId, event: WindowEvent, @@ -14,7 +14,7 @@ pub enum Event { device_id: DeviceId, event: DeviceEvent, }, - Awakened, + UserEvent(T), /// Emitted when new events arrive from the OS to be processed. NewEvents(StartCause), /// Emitted when all of the event loop's events have been processed and control flow is about @@ -31,6 +31,21 @@ pub enum Event { Suspended(bool), } +impl Event { + pub fn map_nonuser_event(self) -> Result, Event> { + use self::Event::*; + match self { + UserEvent(_) => Err(self), + WindowEvent{window_id, event} => Ok(WindowEvent{window_id, event}), + DeviceEvent{device_id, event} => Ok(DeviceEvent{device_id, event}), + NewEvents(cause) => Ok(NewEvents(cause)), + EventsCleared => Ok(EventsCleared), + LoopDestroyed => Ok(LoopDestroyed), + Suspended(suspended) => Ok(Suspended(suspended)), + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum StartCause { /// Sent if the time specified by `ControlFlow::WaitTimeout` has been elapsed. Contains the diff --git a/src/lib.rs b/src/lib.rs index cce680b140..8c1ec73d20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,6 +72,9 @@ extern crate serde; #[cfg(target_os = "windows")] extern crate winapi; +#[cfg(target_os = "windows")] +#[macro_use] +extern crate crossbeam_channel; #[cfg(any(target_os = "macos", target_os = "ios"))] #[macro_use] extern crate objc; @@ -163,12 +166,12 @@ pub struct DeviceId(platform::DeviceId); /// forbiding it), as such it is neither `Send` nor `Sync`. If you need cross-thread access, the /// `Window` created from this `EventLoop` _can_ be sent to an other thread, and the /// `EventLoopProxy` allows you to wakeup an `EventLoop` from an other thread. -pub struct EventLoop { - events_loop: platform::EventLoop, +pub struct EventLoop { + events_loop: platform::EventLoop, _marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync } -impl std::fmt::Debug for EventLoop { +impl std::fmt::Debug for EventLoop { fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result { fmtr.pad("EventLoop { .. }") } @@ -199,14 +202,20 @@ impl Default for ControlFlow { } } -impl EventLoop { +impl EventLoop<()> { + pub fn new() -> EventLoop<()> { + EventLoop::<()>::new_user_event() + } +} + +impl EventLoop { /// Builds a new events loop. /// /// Usage will result in display backend initialisation, this can be controlled on linux /// using an environment variable `WINIT_UNIX_BACKEND`. Legal values are `x11` and `wayland`. /// If it is not set, winit will try to connect to a wayland connection, and if it fails will /// fallback on x11. If this variable is set with any other value, winit will panic. - pub fn new() -> EventLoop { + pub fn new_user_event() -> EventLoop { EventLoop { events_loop: platform::EventLoop::new(), _marker: ::std::marker::PhantomData, @@ -234,14 +243,14 @@ impl EventLoop { /// Any values not passed to this function will *not* be dropped. #[inline] pub fn run(self, event_handler: F) -> ! - where F: 'static + FnMut(Event, &EventLoop, &mut ControlFlow) + where F: 'static + FnMut(Event, &EventLoop, &mut ControlFlow) { self.events_loop.run(event_handler) } /// Creates an `EventLoopProxy` that can be used to wake up the `EventLoop` from another /// thread. - pub fn create_proxy(&self) -> EventLoopProxy { + pub fn create_proxy(&self) -> EventLoopProxy { EventLoopProxy { events_loop_proxy: self.events_loop.create_proxy(), } @@ -250,24 +259,24 @@ impl EventLoop { /// Used to wake up the `EventLoop` from another thread. #[derive(Clone)] -pub struct EventLoopProxy { - events_loop_proxy: platform::EventLoopProxy, +pub struct EventLoopProxy { + events_loop_proxy: platform::EventLoopProxy, } -impl std::fmt::Debug for EventLoopProxy { +impl std::fmt::Debug for EventLoopProxy { fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result { fmtr.pad("EventLoopProxy { .. }") } } -impl EventLoopProxy { - /// Wake up the `EventLoop` from which this proxy was created. - /// - /// This causes the `EventLoop` to emit an `Awakened` event. +impl EventLoopProxy { + /// Send an event to the `EventLoop` from which this proxy was created. This emits a + /// `UserEvent(event)` event in the event loop, where `event` is the value passed to this + /// function. /// /// Returns an `Err` if the associated `EventLoop` no longer exists. - pub fn wakeup(&self) -> Result<(), EventLoopClosed> { - self.events_loop_proxy.wakeup() + pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> { + self.events_loop_proxy.send_event(event) } } diff --git a/src/os/windows.rs b/src/os/windows.rs index 41e3ac1c4c..6a5b67df1f 100644 --- a/src/os/windows.rs +++ b/src/os/windows.rs @@ -15,7 +15,7 @@ pub trait EventLoopExt { fn new_dpi_unaware() -> Self where Self: Sized; } -impl EventLoopExt for EventLoop { +impl EventLoopExt for EventLoop { #[inline] fn new_dpi_unaware() -> Self { EventLoop { diff --git a/src/platform/windows/drop_handler.rs b/src/platform/windows/drop_handler.rs index b4357e1a8f..99a1920a70 100644 --- a/src/platform/windows/drop_handler.rs +++ b/src/platform/windows/drop_handler.rs @@ -3,9 +3,7 @@ use std::os::windows::ffi::OsStringExt; use std::path::PathBuf; use std::sync::atomic::{AtomicUsize, Ordering}; use std::{mem, ptr}; -use std::rc::Rc; -use std::cell::RefCell; -use std::collections::VecDeque; +use crossbeam_channel::Sender; use winapi::ctypes::c_void; use winapi::shared::guiddef::REFIID; @@ -26,7 +24,7 @@ pub struct FileDropHandlerData { pub interface: IDropTarget, refcount: AtomicUsize, window: HWND, - event_queue: Rc>>, + event_sender: Sender> } pub struct FileDropHandler { @@ -35,14 +33,14 @@ pub struct FileDropHandler { #[allow(non_snake_case)] impl FileDropHandler { - pub fn new(window: HWND, event_queue: Rc>>) -> FileDropHandler { + pub fn new(window: HWND, event_sender: Sender>) -> FileDropHandler { let data = Box::new(FileDropHandlerData { interface: IDropTarget { lpVtbl: &DROP_TARGET_VTBL as *const IDropTargetVtbl, }, refcount: AtomicUsize::new(1), window, - event_queue, + event_sender, }); FileDropHandler { data: Box::into_raw(data), @@ -187,8 +185,8 @@ impl FileDropHandler { } impl FileDropHandlerData { - fn send_event(&self, event: Event) { - self.event_queue.borrow_mut().push_back(event); + fn send_event(&self, event: Event<()>) { + self.event_sender.send(event).ok(); } } diff --git a/src/platform/windows/events_loop.rs b/src/platform/windows/events_loop.rs index fbaa0d0080..a808b78190 100644 --- a/src/platform/windows/events_loop.rs +++ b/src/platform/windows/events_loop.rs @@ -14,13 +14,11 @@ use winapi::shared::basetsd::DWORD_PTR; use winapi::shared::basetsd::UINT_PTR; -use std::rc::Rc; use std::{mem, ptr}; -use std::cell::RefCell; use std::sync::Arc; -use std::collections::VecDeque; use std::time::{Duration, Instant}; use parking_lot::Mutex; +use crossbeam_channel::{self, Sender, Receiver}; use winapi::ctypes::c_int; use winapi::shared::minwindef::{ @@ -107,18 +105,6 @@ pub struct WindowState { pub mouse_buttons_down: u32 } -pub(crate) struct SubclassInput { - pub window_state: Arc>, - pub event_queue: Rc>>, - pub file_drop_handler: FileDropHandler -} - -impl SubclassInput { - fn send_event(&self, event: Event) { - self.event_queue.borrow_mut().push_back(event); - } -} - impl WindowState { pub fn update_min_max(&mut self, old_dpi_factor: f64, new_dpi_factor: f64) { let scale_factor = new_dpi_factor / old_dpi_factor; @@ -132,30 +118,55 @@ impl WindowState { } } -pub struct EventLoop { +pub(crate) struct SubclassInput { + pub window_state: Arc>, + pub event_send: Sender>, + pub file_drop_handler: FileDropHandler +} + +impl SubclassInput { + fn send_event(&self, event: Event<()>) { + self.event_send.send(event).ok(); + } +} + +pub struct EventLoop { // Id of the background thread from the Win32 API. thread_id: DWORD, - pub(crate) event_queue: Rc>> + + pub(crate) event_send: Sender>, + pub(crate) user_event_send: Sender, + + event_recv: Receiver>, + user_event_recv: Receiver } -impl EventLoop { - pub fn new() -> EventLoop { +impl EventLoop { + pub fn new() -> EventLoop { Self::with_dpi_awareness(true) } - pub fn with_dpi_awareness(dpi_aware: bool) -> EventLoop { + pub fn with_dpi_awareness(dpi_aware: bool) -> EventLoop { become_dpi_aware(dpi_aware); let thread_id = unsafe { processthreadsapi::GetCurrentThreadId() }; + let (event_send, event_recv) = crossbeam_channel::unbounded(); + let (user_event_send, user_event_recv) = crossbeam_channel::unbounded(); + EventLoop { thread_id, - event_queue: Rc::new(RefCell::new(VecDeque::new())) + + event_send, + event_recv, + + user_event_send, + user_event_recv, } } pub fn run(self, mut event_handler: F) -> ! - where F: 'static + FnMut(Event, &::EventLoop, &mut ControlFlow) + where F: 'static + FnMut(Event, &::EventLoop, &mut ControlFlow) { let event_loop = ::EventLoop { events_loop: self, @@ -239,9 +250,8 @@ impl EventLoop { while has_message { match msg.message { - x if x == *WAKEUP_MSG_ID => { - call_event_handler!(Event::Awakened); - }, + // Handler is called in loop below. + x if x == *WAKEUP_MSG_ID => (), x if x == *EXEC_MSG_ID => { let mut function: Box> = Box::from_raw(msg.wParam as usize as *mut _); function() @@ -254,14 +264,16 @@ impl EventLoop { } loop { - // For whatever reason doing this in a `whlie let` loop doesn't drop the `RefMut`, - // so we have to do it like this. - let event = match event_loop.events_loop.event_queue.borrow_mut().pop_front() { - Some(event) => event, - None => break + let full_event: Option> = select! { + recv(event_loop.events_loop.event_recv) -> event => + event.ok().map(|e| e.map_nonuser_event().expect("User event sent through nonuser channel")), + recv(event_loop.events_loop.user_event_recv) -> user_event => + user_event.ok().map(|e| Event::UserEvent(e)), + default => break }; - - call_event_handler!(event); + if let Some(full_event) = full_event { + call_event_handler!(full_event); + } } if 0 == winuser::PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, 1) { @@ -281,9 +293,17 @@ impl EventLoop { ::std::process::exit(0); } - pub fn create_proxy(&self) -> EventLoopProxy { + pub fn create_proxy(&self) -> EventLoopProxy { EventLoopProxy { thread_id: self.thread_id, + event_send: self.user_event_send.clone() + } + } + + #[inline(always)] + pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor { + EventLoopThreadExecutor { + thread_id: self.thread_id } } } @@ -310,7 +330,7 @@ pub fn dur2timeout(dur: Duration) -> DWORD { }).unwrap_or(winbase::INFINITE) } -impl Drop for EventLoop { +impl Drop for EventLoop { fn drop(&mut self) { unsafe { // Posting `WM_QUIT` will cause `GetMessage` to stop. @@ -319,29 +339,11 @@ impl Drop for EventLoop { } } -#[derive(Clone)] -pub struct EventLoopProxy { - thread_id: DWORD, +pub(crate) struct EventLoopThreadExecutor { + thread_id: DWORD } -impl EventLoopProxy { - pub fn wakeup(&self) -> Result<(), EventLoopClosed> { - unsafe { - if winuser::PostThreadMessageA(self.thread_id, *WAKEUP_MSG_ID, 0, 0) != 0 { - Ok(()) - } else { - // https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms644946(v=vs.85).aspx - // > If the function fails, the return value is zero. To get extended error - // > information, call GetLastError. GetLastError returns ERROR_INVALID_THREAD_ID - // > if idThread is not a valid thread identifier, or if the thread specified by - // > idThread does not have a message queue. GetLastError returns - // > ERROR_NOT_ENOUGH_QUOTA when the message limit is hit. - // TODO: handle ERROR_NOT_ENOUGH_QUOTA - Err(EventLoopClosed) - } - } - } - +impl EventLoopThreadExecutor { /// Check to see if we're in the parent event loop's thread. pub(super) fn in_event_loop_thread(&self) -> bool { let cur_thread_id = unsafe { processthreadsapi::GetCurrentThreadId() }; @@ -384,6 +386,32 @@ impl EventLoopProxy { } } +#[derive(Clone)] +pub struct EventLoopProxy { + thread_id: DWORD, + event_send: Sender +} + +impl EventLoopProxy { + pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> { + unsafe { + if winuser::PostThreadMessageA(self.thread_id, *WAKEUP_MSG_ID, 0, 0) != 0 { + self.event_send.send(event).ok(); + Ok(()) + } else { + // https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms644946(v=vs.85).aspx + // > If the function fails, the return value is zero. To get extended error + // > information, call GetLastError. GetLastError returns ERROR_INVALID_THREAD_ID + // > if idThread is not a valid thread identifier, or if the thread specified by + // > idThread does not have a message queue. GetLastError returns + // > ERROR_NOT_ENOUGH_QUOTA when the message limit is hit. + // TODO: handle ERROR_NOT_ENOUGH_QUOTA + Err(EventLoopClosed) + } + } + } +} + lazy_static! { // Message sent by the `EventLoopProxy` when we want to wake up the thread. // WPARAM and LPARAM are unused. diff --git a/src/platform/windows/monitor.rs b/src/platform/windows/monitor.rs index 760d392456..b8a562ac2a 100644 --- a/src/platform/windows/monitor.rs +++ b/src/platform/windows/monitor.rs @@ -71,19 +71,19 @@ pub fn get_primary_monitor() -> MonitorId { MonitorId::from_hmonitor(hmonitor) } -impl EventLoop { +pub fn get_current_monitor(hwnd: HWND) -> MonitorId { + let hmonitor = unsafe { + winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST) + }; + MonitorId::from_hmonitor(hmonitor) +} + +impl EventLoop { // TODO: Investigate opportunities for caching pub fn get_available_monitors(&self) -> VecDeque { get_available_monitors() } - pub fn get_current_monitor(hwnd: HWND) -> MonitorId { - let hmonitor = unsafe { - winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST) - }; - MonitorId::from_hmonitor(hmonitor) - } - pub fn get_primary_monitor(&self) -> MonitorId { get_primary_monitor() } diff --git a/src/platform/windows/window.rs b/src/platform/windows/window.rs index 49d9d15e3a..547e4371a1 100644 --- a/src/platform/windows/window.rs +++ b/src/platform/windows/window.rs @@ -32,7 +32,7 @@ use platform::platform::{Cursor, PlatformSpecificWindowBuilderAttributes, Window use platform::platform::dpi::{dpi_to_scale_factor, get_hwnd_dpi}; use platform::platform::events_loop::{self, DESTROY_MSG_ID, EventLoop, INITIAL_DPI_MSG_ID, WindowState}; use platform::platform::icon::{self, IconType, WinIcon}; -use platform::platform::monitor::get_available_monitors; +use platform::platform::monitor; use platform::platform::raw_input::register_all_mice_and_keyboards_for_raw_input; use platform::platform::drop_handler::FileDropHandler; use platform::platform::util; @@ -48,7 +48,7 @@ pub struct Window { window_state: Arc>, // The events loop proxy. - events_loop_proxy: events_loop::EventLoopProxy, + thread_executor: events_loop::EventLoopThreadExecutor, } // https://blogs.msdn.microsoft.com/oldnewthing/20131017-00/?p=2903 @@ -74,8 +74,8 @@ unsafe fn unjust_window_rect(prc: &mut RECT, style: DWORD, ex_style: DWORD) -> B } impl Window { - pub fn new( - events_loop: &EventLoop, + pub fn new( + events_loop: &EventLoop, w_attr: WindowAttributes, pl_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { @@ -322,7 +322,7 @@ impl Window { _ => winuser::IDC_ARROW, // use arrow for the missing cases. }); self.window_state.lock().cursor = cursor_id; - self.events_loop_proxy.execute_in_thread(move || unsafe { + self.thread_executor.execute_in_thread(move || unsafe { let cursor = winuser::LoadCursorW( ptr::null_mut(), cursor_id.0, @@ -384,7 +384,7 @@ impl Window { let window = self.window.clone(); let window_state = Arc::clone(&self.window_state); let (tx, rx) = channel(); - self.events_loop_proxy.execute_in_thread(move || { + self.thread_executor.execute_in_thread(move || { let result = unsafe { Self::grab_cursor_inner(&window, grab) }; if result.is_ok() { window_state.lock().cursor_grabbed = grab; @@ -410,7 +410,7 @@ impl Window { if hide == window_state_lock.cursor_hidden { return; } let (tx, rx) = channel(); let window_state = Arc::clone(&self.window_state); - self.events_loop_proxy.execute_in_thread(move || { + self.thread_executor.execute_in_thread(move || { unsafe { Self::hide_cursor_inner(hide) }; window_state.lock().cursor_hidden = hide; let _ = tx.send(()); @@ -458,7 +458,7 @@ impl Window { let window = self.window.clone(); unsafe { // `ShowWindow` resizes the window, so it must be called from the main thread. - self.events_loop_proxy.execute_in_thread(move || { + self.thread_executor.execute_in_thread(move || { winuser::ShowWindow( window.0, if maximized { @@ -524,7 +524,7 @@ impl Window { drop(window_state_lock); // We're restoring the window to its size and position from before being fullscreened. // `ShowWindow` resizes the window, so it must be called from the main thread. - self.events_loop_proxy.execute_in_thread(move || { + self.thread_executor.execute_in_thread(move || { let _ = Self::grab_cursor_inner(&window, false); if resizable { @@ -585,7 +585,7 @@ impl Window { window_state_lock.fullscreen = monitor; drop(window_state_lock); - self.events_loop_proxy.execute_in_thread(move || { + self.thread_executor.execute_in_thread(move || { let _ = Self::grab_cursor_inner(&window, false); winuser::SetWindowLongW( @@ -681,7 +681,7 @@ impl Window { let window = self.window.clone(); - self.events_loop_proxy.execute_in_thread(move || { + self.thread_executor.execute_in_thread(move || { winuser::SetWindowLongW(window.0, winuser::GWL_STYLE, style); winuser::SetWindowLongW(window.0, winuser::GWL_EXSTYLE, ex_style); winuser::AdjustWindowRectEx(&mut rect, style as _, 0, ex_style as _); @@ -709,7 +709,7 @@ impl Window { let mut window_state = self.window_state.lock(); if mem::replace(&mut window_state.always_on_top, always_on_top) != always_on_top { let window = self.window.clone(); - self.events_loop_proxy.execute_in_thread(move || { + self.thread_executor.execute_in_thread(move || { let insert_after = if always_on_top { winuser::HWND_TOPMOST } else { @@ -734,7 +734,7 @@ impl Window { #[inline] pub fn get_current_monitor(&self) -> RootMonitorId { RootMonitorId { - inner: EventLoop::get_current_monitor(self.window.0), + inner: monitor::get_current_monitor(self.window.0), } } @@ -809,10 +809,10 @@ pub unsafe fn adjust_size( (rect.right - rect.left, rect.bottom - rect.top) } -unsafe fn init( +unsafe fn init( mut attributes: WindowAttributes, mut pl_attribs: PlatformSpecificWindowBuilderAttributes, - event_loop: &events_loop::EventLoop, + event_loop: &events_loop::EventLoop, ) -> Result { let title = OsStr::new(&attributes.title) .encode_wide() @@ -848,7 +848,7 @@ unsafe fn init( let class_name = register_window_class(&window_icon, &taskbar_icon); let guessed_dpi_factor = { - let monitors = get_available_monitors(); + let monitors = monitor::get_available_monitors(); let dpi_factor = if !monitors.is_empty() { let mut dpi_factor = Some(monitors[0].get_hidpi_factor()); for monitor in &monitors { @@ -1055,7 +1055,7 @@ unsafe fn init( let win = Window { window: real_window, window_state, - events_loop_proxy: event_loop.create_proxy(), + thread_executor: event_loop.create_thread_executor(), }; win.set_maximized(attributes.maximized); @@ -1076,7 +1076,7 @@ unsafe fn init( panic!("OleInitialize failed! Result was: `RPC_E_CHANGED_MODE`"); } - let file_drop_handler = FileDropHandler::new(win.window.0, event_loop.event_queue.clone()); + let file_drop_handler = FileDropHandler::new(win.window.0, event_loop.event_send.clone()); let handler_interface_ptr = &mut (*file_drop_handler.data).interface as LPDROPTARGET; assert_eq!(ole2::RegisterDragDrop(win.window.0, handler_interface_ptr), S_OK); @@ -1085,8 +1085,8 @@ unsafe fn init( let subclass_input = events_loop::SubclassInput { window_state: win.window_state.clone(), - event_queue: event_loop.event_queue.clone(), - file_drop_handler + event_send: event_loop.event_send.clone(), + file_drop_handler, }; events_loop::subclass_window(win.window.0, subclass_input); diff --git a/src/window.rs b/src/window.rs index 604fc9fe60..6468099fd3 100644 --- a/src/window.rs +++ b/src/window.rs @@ -142,7 +142,7 @@ impl WindowBuilder { /// Error should be very rare and only occur in case of permission denied, incompatible system, /// out of memory, etc. #[inline] - pub fn build(mut self, events_loop: &EventLoop) -> Result { + pub fn build(mut self, events_loop: &EventLoop) -> Result { self.window.dimensions = Some(self.window.dimensions.unwrap_or_else(|| { if let Some(ref monitor) = self.window.fullscreen { // resizing the window to the dimensions of the monitor when fullscreen @@ -170,7 +170,7 @@ impl Window { /// Error should be very rare and only occur in case of permission denied, incompatible system, /// out of memory, etc. #[inline] - pub fn new(events_loop: &EventLoop) -> Result { + pub fn new(events_loop: &EventLoop) -> Result { let builder = WindowBuilder::new(); builder.build(events_loop) } diff --git a/tests/send_objects.rs b/tests/send_objects.rs index d0a34fd024..6cb0fe43c9 100644 --- a/tests/send_objects.rs +++ b/tests/send_objects.rs @@ -5,7 +5,7 @@ fn needs_send() {} #[test] fn events_loop_proxy_send() { // ensures that `winit::EventLoopProxy` implements `Send` - needs_send::(); + needs_send::>(); } #[test]