diff --git a/examples/cursor.rs b/examples/cursor.rs index 596b2736..937bda1f 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -1,6 +1,6 @@ extern crate winit; -use winit::{Event, ElementState, MouseCursor}; +use winit::{WindowEvent as Event, ElementState, MouseCursor}; fn main() { let window = winit::WindowBuilder::new().build().unwrap(); diff --git a/examples/grabbing.rs b/examples/grabbing.rs index f2d1a800..45500777 100644 --- a/examples/grabbing.rs +++ b/examples/grabbing.rs @@ -1,6 +1,6 @@ extern crate winit; -use winit::{Event, ElementState}; +use winit::{WindowEvent as Event, ElementState}; fn main() { let window = winit::WindowBuilder::new().build().unwrap(); diff --git a/src/api/ios/delegate.rs b/src/api/ios/delegate.rs index 62cd89d1..71eb2e72 100644 --- a/src/api/ios/delegate.rs +++ b/src/api/ios/delegate.rs @@ -1,7 +1,7 @@ use libc; use std::mem; use super::DelegateState; -use Event; +use WindowEvent as Event; use events::{ Touch, TouchPhase }; use objc::runtime::{ Class, Object, Sel, BOOL, YES }; diff --git a/src/api/wayland/context.rs b/src/api/wayland/context.rs index b3bd437a..debd5e6b 100644 --- a/src/api/wayland/context.rs +++ b/src/api/wayland/context.rs @@ -1,4 +1,4 @@ -use {Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase}; +use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase}; use std::collections::VecDeque; use std::sync::{Arc, Mutex}; diff --git a/src/api/wayland/window.rs b/src/api/wayland/window.rs index 30b7365a..f4977451 100644 --- a/src/api/wayland/window.rs +++ b/src/api/wayland/window.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Mutex}; use wayland_client::{EventQueue, EventQueueHandle, Init}; use wayland_client::protocol::{wl_display,wl_surface,wl_shell_surface}; -use {CreationError, MouseCursor, CursorState, Event, WindowAttributes}; +use {CreationError, MouseCursor, CursorState, WindowEvent as Event, WindowAttributes}; use platform::MonitorId as PlatformMonitorId; use super::WaylandContext; diff --git a/src/api/x11/input.rs b/src/api/x11/input.rs index 86ce8577..7185a449 100644 --- a/src/api/x11/input.rs +++ b/src/api/x11/input.rs @@ -7,7 +7,7 @@ use std::slice::from_raw_parts; use WindowAttributes; -use events::Event; +use events::WindowEvent as Event; use super::{events, ffi}; use super::XConnection; @@ -123,7 +123,7 @@ impl XInputEventHandler { } pub fn translate_key_event(&self, event: &mut ffi::XKeyEvent) -> Vec { - use events::Event::{KeyboardInput, ReceivedCharacter}; + use events::WindowEvent::{KeyboardInput, ReceivedCharacter}; use events::ElementState::{Pressed, Released}; let mut translated_events = Vec::new(); @@ -170,7 +170,7 @@ impl XInputEventHandler { } pub fn translate_event(&mut self, cookie: &ffi::XGenericEventCookie) -> Option { - use events::Event::{Focused, MouseEntered, MouseInput, MouseLeft, MouseMoved, MouseWheel}; + use events::WindowEvent::{Focused, MouseEntered, MouseInput, MouseLeft, MouseMoved, MouseWheel}; use events::ElementState::{Pressed, Released}; use events::MouseButton::{Left, Right, Middle}; use events::MouseScrollDelta::LineDelta; diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index d4ea33d2..f3640183 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -1,4 +1,4 @@ -use {Event, MouseCursor}; +use {WindowEvent as Event, MouseCursor}; use CreationError; use CreationError::OsError; use libc; @@ -178,7 +178,7 @@ impl<'a> Iterator for PollEventsIterator<'a> { }, ffi::ClientMessage => { - use events::Event::{Closed, Awakened}; + use events::WindowEvent::{Closed, Awakened}; use std::sync::atomic::Ordering::Relaxed; let client_msg: &ffi::XClientMessageEvent = unsafe { mem::transmute(&xev) }; @@ -192,7 +192,7 @@ impl<'a> Iterator for PollEventsIterator<'a> { }, ffi::ConfigureNotify => { - use events::Event::Resized; + use events::WindowEvent::Resized; let cfg_event: &ffi::XConfigureEvent = unsafe { mem::transmute(&xev) }; let (current_width, current_height) = self.window.current_size.get(); if current_width != cfg_event.width || current_height != cfg_event.height { @@ -202,7 +202,7 @@ impl<'a> Iterator for PollEventsIterator<'a> { }, ffi::Expose => { - use events::Event::Refresh; + use events::WindowEvent::Refresh; return Some(Refresh); }, diff --git a/src/api_transition.rs b/src/api_transition.rs new file mode 100644 index 00000000..231ee64a --- /dev/null +++ b/src/api_transition.rs @@ -0,0 +1,64 @@ + +//! This temporary module generates types that wrap around the old API (winit v5 and below) and +//! expose the new API (winit v6 and above). +//! +//! This is temporary so that existing backends can smoothly transition. After all implementations +//! have finished transitionning, this module should disappear. + +macro_rules! gen_api_transition { + () => { + pub struct EventsLoop { + windows: ::std::sync::Mutex>>, + } + + impl EventsLoop { + pub fn new() -> EventsLoop { + EventsLoop { + windows: ::std::sync::Mutex::new(vec![]), + } + } + + pub fn poll_events(&self, mut callback: F) + where F: FnMut(::Event) + { + unimplemented!() + } + + pub fn run_forever(&self, mut callback: F) + where F: FnMut(::Event) + { + unimplemented!() + } + } + + pub struct Window2 { + window: ::std::sync::Arc, + } + + impl ::std::ops::Deref for Window2 { + type Target = Window; + #[inline] + fn deref(&self) -> &Window { + &*self.window + } + } + + impl Window2 { + pub fn new(events_loop: ::std::sync::Arc, window: &::WindowAttributes, + pl_attribs: &PlatformSpecificWindowBuilderAttributes) + -> Result + { + let win = ::std::sync::Arc::new(try!(Window::new(window, pl_attribs))); + events_loop.windows.lock().unwrap().push(win.clone()); + Ok(Window2 { + window: win, + }) + } + + #[inline] + pub fn id(&self) -> usize { + &*self.window as *const Window as usize + } + } + }; +} diff --git a/src/events.rs b/src/events.rs index b6fd7732..520a6c8a 100644 --- a/src/events.rs +++ b/src/events.rs @@ -2,6 +2,17 @@ use std::path::PathBuf; #[derive(Clone, Debug)] pub enum Event { + WindowEvent { + // window_id: , + event: WindowEvent, + } +} + +#[derive(Clone, Debug)] +pub enum WindowEvent { + // TODO: remove ; can break the lib internally so be careful + Awakened, + /// The size of the window has changed. Resized(u32, u32), @@ -49,9 +60,6 @@ pub enum Event { /// is being pressed) and stage (integer representing the click level). TouchpadPressure(f32, i64), - /// The event loop was woken up by another thread. - Awakened, - /// The window needs to be redrawn. Refresh, @@ -60,7 +68,6 @@ pub enum Event { /// The parameter is true if app was suspended, and false if it has been resumed. Suspended(bool), - /// Touch event has been received Touch(Touch) } diff --git a/src/lib.rs b/src/lib.rs index d4d28fe3..b28ea0e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,11 +64,16 @@ extern crate x11_dl; #[macro_use(wayland_env,declare_handler)] extern crate wayland_client; +use std::sync::Arc; + pub use events::*; pub use window::{WindowProxy, PollEventsIterator, WaitEventsIterator}; pub use window::{AvailableMonitorsIter, MonitorId, get_available_monitors, get_primary_monitor}; pub use native_monitor::NativeMonitorId; +#[macro_use] +mod api_transition; + mod api; mod platform; mod events; @@ -94,7 +99,34 @@ pub mod os; /// } /// ``` pub struct Window { - window: platform::Window, + window: platform::Window2, +} + +pub struct EventsLoop { + events_loop: Arc, +} + +impl EventsLoop { + /// Builds a new events loop. + pub fn new() -> EventsLoop { + EventsLoop { + events_loop: Arc::new(platform::EventsLoop::new()), + } + } + + #[inline] + pub fn poll_events(&self, callback: F) + where F: FnMut(Event) + { + self.events_loop.poll_events(callback) + } + + #[inline] + pub fn run_forever(&self, callback: F) + where F: FnMut(Event) + { + self.events_loop.run_forever(callback) + } } /// Object that allows you to build windows. diff --git a/src/platform/android/mod.rs b/src/platform/android/mod.rs index d3973481..aa324d2b 100644 --- a/src/platform/android/mod.rs +++ b/src/platform/android/mod.rs @@ -6,7 +6,7 @@ use libc; use std::ffi::{CString}; use std::sync::mpsc::{Receiver, channel}; use std::os::raw::c_void; -use {CreationError, Event, MouseCursor}; +use {CreationError, WindowEvent as Event, MouseCursor}; use CreationError::OsError; use events::ElementState::{Pressed, Released}; use events::{Touch, TouchPhase}; @@ -17,6 +17,8 @@ use CursorState; use WindowAttributes; use native_monitor::NativeMonitorId; +gen_api_transition!(); + pub struct Window { native_window: *const c_void, event_rx: Receiver, diff --git a/src/platform/ios/mod.rs b/src/platform/ios/mod.rs index 0b1a5509..fcfe51f9 100644 --- a/src/platform/ios/mod.rs +++ b/src/platform/ios/mod.rs @@ -8,6 +8,8 @@ use ContextError; pub use api::ios::*; +gen_api_transition!(); + #[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 5001787c..029ba7d7 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use CreationError; use CursorState; -use Event; +use WindowEvent as Event; use MouseCursor; use WindowAttributes; use libc; @@ -17,6 +17,8 @@ use api::x11::XError; use api::x11::XNotSupported; use api::x11::ffi::XVisualInfo; +gen_api_transition!(); + #[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes { pub visual_infos: Option, diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 3aadfe76..49bcca4c 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -1,6 +1,6 @@ #![cfg(target_os = "macos")] -use {CreationError, Event, MouseCursor, CursorState}; +use {CreationError, WindowEvent as Event, MouseCursor, CursorState}; use CreationError::OsError; use libc; @@ -29,6 +29,8 @@ use os::macos::WindowExt; use events::ElementState; use events::{self, MouseButton, TouchPhase}; +gen_api_transition!(); + pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor}; mod monitor; diff --git a/src/platform/windows/callback.rs b/src/platform/windows/callback.rs index 00296a6a..de611640 100644 --- a/src/platform/windows/callback.rs +++ b/src/platform/windows/callback.rs @@ -7,7 +7,7 @@ use std::ffi::OsString; use std::os::windows::ffi::OsStringExt; use CursorState; -use Event; +use WindowEvent as Event; use super::event; use super::WindowState; @@ -68,7 +68,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, { match msg { winapi::WM_DESTROY => { - use events::Event::Closed; + use events::WindowEvent::Closed; CONTEXT_STASH.with(|context_stash| { let context_stash = context_stash.borrow(); @@ -93,7 +93,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_SIZE => { - use events::Event::Resized; + use events::WindowEvent::Resized; let w = winapi::LOWORD(lparam as winapi::DWORD) as u32; let h = winapi::HIWORD(lparam as winapi::DWORD) as u32; send_event(window, Resized(w, h)); @@ -101,7 +101,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_MOVE => { - use events::Event::Moved; + use events::WindowEvent::Moved; let x = winapi::LOWORD(lparam as winapi::DWORD) as i32; let y = winapi::HIWORD(lparam as winapi::DWORD) as i32; send_event(window, Moved(x, y)); @@ -110,7 +110,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, winapi::WM_CHAR => { use std::mem; - use events::Event::ReceivedCharacter; + use events::WindowEvent::ReceivedCharacter; let chr: char = mem::transmute(wparam as u32); send_event(window, ReceivedCharacter(chr)); 0 @@ -125,7 +125,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, } winapi::WM_MOUSEMOVE => { - use events::Event::{MouseEntered, MouseMoved}; + use events::WindowEvent::{MouseEntered, MouseMoved}; let mouse_outside_window = CONTEXT_STASH.with(|context_stash| { let mut context_stash = context_stash.borrow_mut(); if let Some(context_stash) = context_stash.as_mut() { @@ -159,7 +159,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_MOUSELEAVE => { - use events::Event::MouseLeft; + use events::WindowEvent::MouseLeft; let mouse_in_window = CONTEXT_STASH.with(|context_stash| { let mut context_stash = context_stash.borrow_mut(); if let Some(context_stash) = context_stash.as_mut() { @@ -180,7 +180,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_MOUSEWHEEL => { - use events::Event::MouseWheel; + use events::WindowEvent::MouseWheel; use events::MouseScrollDelta::LineDelta; use events::TouchPhase; @@ -194,7 +194,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_KEYDOWN | winapi::WM_SYSKEYDOWN => { - use events::Event::KeyboardInput; + use events::WindowEvent::KeyboardInput; use events::ElementState::Pressed; if msg == winapi::WM_SYSKEYDOWN && wparam as i32 == winapi::VK_F4 { user32::DefWindowProcW(window, msg, wparam, lparam) @@ -206,7 +206,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_KEYUP | winapi::WM_SYSKEYUP => { - use events::Event::KeyboardInput; + use events::WindowEvent::KeyboardInput; use events::ElementState::Released; let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam); send_event(window, KeyboardInput(Released, scancode, vkey)); @@ -214,7 +214,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_LBUTTONDOWN => { - use events::Event::MouseInput; + use events::WindowEvent::MouseInput; use events::MouseButton::Left; use events::ElementState::Pressed; send_event(window, MouseInput(Pressed, Left)); @@ -222,7 +222,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_LBUTTONUP => { - use events::Event::MouseInput; + use events::WindowEvent::MouseInput; use events::MouseButton::Left; use events::ElementState::Released; send_event(window, MouseInput(Released, Left)); @@ -230,7 +230,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_RBUTTONDOWN => { - use events::Event::MouseInput; + use events::WindowEvent::MouseInput; use events::MouseButton::Right; use events::ElementState::Pressed; send_event(window, MouseInput(Pressed, Right)); @@ -238,7 +238,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_RBUTTONUP => { - use events::Event::MouseInput; + use events::WindowEvent::MouseInput; use events::MouseButton::Right; use events::ElementState::Released; send_event(window, MouseInput(Released, Right)); @@ -246,7 +246,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_MBUTTONDOWN => { - use events::Event::MouseInput; + use events::WindowEvent::MouseInput; use events::MouseButton::Middle; use events::ElementState::Pressed; send_event(window, MouseInput(Pressed, Middle)); @@ -254,7 +254,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_MBUTTONUP => { - use events::Event::MouseInput; + use events::WindowEvent::MouseInput; use events::MouseButton::Middle; use events::ElementState::Released; send_event(window, MouseInput(Released, Middle)); @@ -262,7 +262,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_XBUTTONDOWN => { - use events::Event::MouseInput; + use events::WindowEvent::MouseInput; use events::MouseButton::Other; use events::ElementState::Pressed; let xbutton = winapi::HIWORD(wparam as winapi::DWORD) as winapi::c_int; // waiting on PR for winapi to add GET_XBUTTON_WPARAM @@ -271,7 +271,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_XBUTTONUP => { - use events::Event::MouseInput; + use events::WindowEvent::MouseInput; use events::MouseButton::Other; use events::ElementState::Released; let xbutton = winapi::HIWORD(wparam as winapi::DWORD) as winapi::c_int; @@ -300,13 +300,13 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_SETFOCUS => { - use events::Event::Focused; + use events::WindowEvent::Focused; send_event(window, Focused(true)); 0 }, winapi::WM_KILLFOCUS => { - use events::Event::Focused; + use events::WindowEvent::Focused; send_event(window, Focused(false)); 0 }, @@ -345,7 +345,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_DROPFILES => { - use events::Event::DroppedFile; + use events::WindowEvent::DroppedFile; let hdrop = wparam as winapi::HDROP; let mut pathbuf: [u16; winapi::MAX_PATH] = mem::uninitialized(); @@ -394,7 +394,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, x if x == *super::WAKEUP_MSG_ID => { - use events::Event::Awakened; + use events::WindowEvent::Awakened; send_event(window, Awakened); 0 }, diff --git a/src/platform/windows/mod.rs b/src/platform/windows/mod.rs index ded27376..fe6ac385 100644 --- a/src/platform/windows/mod.rs +++ b/src/platform/windows/mod.rs @@ -10,11 +10,13 @@ use std::sync::{ Mutex }; use std::sync::mpsc::Receiver; -use {CreationError, Event, MouseCursor}; +use {CreationError, WindowEvent as Event, MouseCursor}; use CursorState; use WindowAttributes; +gen_api_transition!(); + #[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes { pub parent: Option, diff --git a/src/window.rs b/src/window.rs index a04575d7..96a5cd80 100644 --- a/src/window.rs +++ b/src/window.rs @@ -2,7 +2,8 @@ use std::collections::vec_deque::IntoIter as VecDequeIter; use CreationError; use CursorState; -use Event; +use WindowEvent as Event; +use EventsLoop; use MouseCursor; use Window; use WindowBuilder; @@ -93,20 +94,11 @@ impl WindowBuilder { self } - /// Provides a resize callback that is called by Mac (and potentially other - /// operating systems) during resize operations. This can be used to repaint - /// during window resizing. - #[inline] - pub fn with_window_resize_callback(mut self, cb: fn(u32, u32)) -> WindowBuilder { - self.window.resize_callback = Some(cb); - self - } - /// Builds the window. /// /// Error should be very rare and only occur in case of permission denied, incompatible system, /// out of memory, etc. - pub fn build(mut self) -> Result { + pub fn build(mut self, events_loop: &EventsLoop) -> Result { // resizing the window to the dimensions of the monitor when fullscreen if self.window.dimensions.is_none() && self.window.monitor.is_some() { self.window.dimensions = Some(self.window.monitor.as_ref().unwrap().get_dimensions()) @@ -118,32 +110,10 @@ impl WindowBuilder { } // building - let mut w = try!(platform::Window::new(&self.window, &self.platform_specific)); - - // a window resize callback was given - if let Some(callback) = self.window.resize_callback { - w.set_window_resize_callback(Some(callback)); - } + let w = try!(platform::Window2::new(events_loop.events_loop.clone(), &self.window, &self.platform_specific)); Ok(Window { window: w }) } - - /// Builds the window. - /// - /// The context is build in a *strict* way. That means that if the backend couldn't give - /// you what you requested, an `Err` will be returned. - #[inline] - pub fn build_strict(self) -> Result { - self.build() - } -} - - -impl Default for Window { - #[inline] - fn default() -> Window { - Window::new().unwrap() - } } impl Window { @@ -154,9 +124,9 @@ 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() -> Result { + pub fn new(events_loop: &EventsLoop) -> Result { let builder = WindowBuilder::new(); - builder.build() + builder.build(events_loop) } /// Modifies the title of the window. @@ -321,14 +291,6 @@ impl Window { } } - /// Sets a resize callback that is called by Mac (and potentially other - /// operating systems) during resize operations. This can be used to repaint - /// during window resizing. - #[inline] - pub fn set_window_resize_callback(&mut self, callback: Option) { - self.window.set_window_resize_callback(callback); - } - /// Modifies the mouse cursor of the window. /// Has no effect on Android. pub fn set_cursor(&self, cursor: MouseCursor) {