mirror of
https://github.com/rust-windowing/winit.git
synced 2026-08-31 22:00:04 -04:00
Re-organize into module structure
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
use winit::{Event, EventLoop, ElementState, MouseCursor, WindowEvent, KeyboardInput, ControlFlow};
|
use winit::window::{WindowBuilder, MouseCursor};
|
||||||
|
use winit::event::{Event, WindowEvent, ElementState, KeyboardInput};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop = EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new().build(&events_loop).unwrap();
|
let window = WindowBuilder::new().build(&events_loop).unwrap();
|
||||||
window.set_title("A fantastic window!");
|
window.set_title("A fantastic window!");
|
||||||
|
|
||||||
let mut cursor_idx = 0;
|
let mut cursor_idx = 0;
|
||||||
|
|||||||
@@ -1,31 +1,34 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
fn main() {
|
use winit::window::WindowBuilder;
|
||||||
let events_loop = winit::EventLoop::new();
|
use winit::event::{Event, WindowEvent, ElementState, KeyboardInput};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new()
|
fn main() {
|
||||||
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
|
let window = WindowBuilder::new()
|
||||||
.with_title("Super Cursor Grab'n'Hide Simulator 9000")
|
.with_title("Super Cursor Grab'n'Hide Simulator 9000")
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
events_loop.run(move |event, _, control_flow| {
|
events_loop.run(move |event, _, control_flow| {
|
||||||
*control_flow = winit::ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
if let winit::Event::WindowEvent { event, .. } = event {
|
if let Event::WindowEvent { event, .. } = event {
|
||||||
use winit::WindowEvent::*;
|
|
||||||
match event {
|
match event {
|
||||||
CloseRequested => *control_flow = winit::ControlFlow::Exit,
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
input: winit::KeyboardInput {
|
input: KeyboardInput {
|
||||||
state: winit::ElementState::Released,
|
state: ElementState::Released,
|
||||||
virtual_keycode: Some(key),
|
virtual_keycode: Some(key),
|
||||||
modifiers,
|
modifiers,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
use winit::VirtualKeyCode::*;
|
use winit::event::VirtualKeyCode::*;
|
||||||
match key {
|
match key {
|
||||||
Escape => *control_flow = winit::ControlFlow::Exit,
|
Escape => *control_flow = ControlFlow::Exit,
|
||||||
G => window.grab_cursor(!modifiers.shift).unwrap(),
|
G => window.grab_cursor(!modifiers.shift).unwrap(),
|
||||||
H => window.hide_cursor(!modifiers.shift),
|
H => window.hide_cursor(!modifiers.shift),
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use winit::{ControlFlow, Event, WindowEvent};
|
use winit::window::WindowBuilder;
|
||||||
|
use winit::event::{Event, WindowEvent, VirtualKeyCode, ElementState, KeyboardInput};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop = winit::EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
// enumerating monitors
|
// enumerating monitors
|
||||||
let monitor = {
|
let monitor = {
|
||||||
@@ -25,7 +27,7 @@ fn main() {
|
|||||||
monitor
|
monitor
|
||||||
};
|
};
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Hello world!")
|
.with_title("Hello world!")
|
||||||
.with_fullscreen(Some(monitor))
|
.with_fullscreen(Some(monitor))
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
@@ -44,15 +46,15 @@ fn main() {
|
|||||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
WindowEvent::KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
input:
|
input:
|
||||||
winit::KeyboardInput {
|
KeyboardInput {
|
||||||
virtual_keycode: Some(virtual_code),
|
virtual_keycode: Some(virtual_code),
|
||||||
state,
|
state,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
} => match (virtual_code, state) {
|
} => match (virtual_code, state) {
|
||||||
(winit::VirtualKeyCode::Escape, _) => *control_flow = ControlFlow::Exit,
|
(VirtualKeyCode::Escape, _) => *control_flow = ControlFlow::Exit,
|
||||||
(winit::VirtualKeyCode::F, winit::ElementState::Pressed) => {
|
(VirtualKeyCode::F, ElementState::Pressed) => {
|
||||||
is_fullscreen = !is_fullscreen;
|
is_fullscreen = !is_fullscreen;
|
||||||
if !is_fullscreen {
|
if !is_fullscreen {
|
||||||
window.set_fullscreen(None);
|
window.set_fullscreen(None);
|
||||||
@@ -60,11 +62,11 @@ fn main() {
|
|||||||
window.set_fullscreen(Some(window.get_current_monitor()));
|
window.set_fullscreen(Some(window.get_current_monitor()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(winit::VirtualKeyCode::M, winit::ElementState::Pressed) => {
|
(VirtualKeyCode::M, ElementState::Pressed) => {
|
||||||
is_maximized = !is_maximized;
|
is_maximized = !is_maximized;
|
||||||
window.set_maximized(is_maximized);
|
window.set_maximized(is_maximized);
|
||||||
}
|
}
|
||||||
(winit::VirtualKeyCode::D, winit::ElementState::Pressed) => {
|
(VirtualKeyCode::D, ElementState::Pressed) => {
|
||||||
decorations = !decorations;
|
decorations = !decorations;
|
||||||
window.set_decorations(decorations);
|
window.set_decorations(decorations);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
fn main() {
|
use winit::window::WindowBuilder;
|
||||||
let events_loop = winit::EventLoop::new();
|
use winit::event::{Event, WindowEvent, KeyboardInput};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
let _window = winit::WindowBuilder::new()
|
fn main() {
|
||||||
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
|
let _window = WindowBuilder::new()
|
||||||
.with_title("Your faithful window")
|
.with_title("Your faithful window")
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -11,13 +15,12 @@ fn main() {
|
|||||||
let mut close_requested = false;
|
let mut close_requested = false;
|
||||||
|
|
||||||
events_loop.run(move |event, _, control_flow| {
|
events_loop.run(move |event, _, control_flow| {
|
||||||
use winit::WindowEvent::*;
|
use winit::event::ElementState::Released;
|
||||||
use winit::ElementState::Released;
|
use winit::event::VirtualKeyCode::{N, Y};
|
||||||
use winit::VirtualKeyCode::{N, Y};
|
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent { event, .. } => match event {
|
Event::WindowEvent { event, .. } => match event {
|
||||||
CloseRequested => {
|
WindowEvent::CloseRequested => {
|
||||||
// `CloseRequested` is sent when the close button on the window is pressed (or
|
// `CloseRequested` is sent when the close button on the window is pressed (or
|
||||||
// through whatever other mechanisms the window manager provides for closing a
|
// through whatever other mechanisms the window manager provides for closing a
|
||||||
// window). If you don't handle this event, the close button won't actually do
|
// window). If you don't handle this event, the close button won't actually do
|
||||||
@@ -34,9 +37,9 @@ fn main() {
|
|||||||
// closing the window. How to close the window is detailed in the handler for
|
// closing the window. How to close the window is detailed in the handler for
|
||||||
// the Y key.
|
// the Y key.
|
||||||
}
|
}
|
||||||
KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
input:
|
input:
|
||||||
winit::KeyboardInput {
|
KeyboardInput {
|
||||||
virtual_keycode: Some(virtual_code),
|
virtual_keycode: Some(virtual_code),
|
||||||
state: Released,
|
state: Released,
|
||||||
..
|
..
|
||||||
@@ -53,7 +56,7 @@ fn main() {
|
|||||||
// event loop (i.e. if it's a multi-window application), you need to
|
// event loop (i.e. if it's a multi-window application), you need to
|
||||||
// drop the window. That closes it, and results in `Destroyed` being
|
// drop the window. That closes it, and results in `Destroyed` being
|
||||||
// sent.
|
// sent.
|
||||||
*control_flow = winit::ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
N => {
|
N => {
|
||||||
@@ -69,6 +72,6 @@ fn main() {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
*control_flow = winit::ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
use winit::dpi::LogicalSize;
|
use winit::dpi::LogicalSize;
|
||||||
|
use winit::window::WindowBuilder;
|
||||||
|
use winit::event::{Event, WindowEvent};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop = winit::EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -16,9 +19,9 @@ fn main() {
|
|||||||
println!("{:?}", event);
|
println!("{:?}", event);
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } =>
|
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } =>
|
||||||
*control_flow = winit::ControlFlow::Exit,
|
*control_flow = ControlFlow::Exit,
|
||||||
_ => *control_flow = winit::ControlFlow::Wait,
|
_ => *control_flow = ControlFlow::Wait,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
use winit::event_loop::EventLoop;
|
||||||
|
use winit::window::WindowBuilder;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let event_loop = winit::EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = winit::WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
println!("{:#?}\nPrimary: {:#?}", window.get_available_monitors(), window.get_primary_monitor());
|
println!("{:#?}\nPrimary: {:#?}", window.get_available_monitors(), window.get_primary_monitor());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,36 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use winit::window::Window;
|
||||||
|
use winit::event::{Event, WindowEvent, ElementState, KeyboardInput};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop = winit::EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
let mut windows = HashMap::new();
|
let mut windows = HashMap::new();
|
||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
let window = winit::Window::new(&events_loop).unwrap();
|
let window = Window::new(&events_loop).unwrap();
|
||||||
windows.insert(window.id(), window);
|
windows.insert(window.id(), window);
|
||||||
}
|
}
|
||||||
|
|
||||||
events_loop.run(move |event, events_loop, control_flow| {
|
events_loop.run(move |event, events_loop, control_flow| {
|
||||||
*control_flow = winit::ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent { event, window_id } => {
|
Event::WindowEvent { event, window_id } => {
|
||||||
match event {
|
match event {
|
||||||
winit::WindowEvent::CloseRequested => {
|
WindowEvent::CloseRequested => {
|
||||||
println!("Window {:?} has received the signal to close", window_id);
|
println!("Window {:?} has received the signal to close", window_id);
|
||||||
|
|
||||||
// This drops the window, causing it to close.
|
// This drops the window, causing it to close.
|
||||||
windows.remove(&window_id);
|
windows.remove(&window_id);
|
||||||
|
|
||||||
if windows.is_empty() {
|
if windows.is_empty() {
|
||||||
*control_flow = winit::ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
winit::WindowEvent::KeyboardInput{..} => {
|
WindowEvent::KeyboardInput { input: KeyboardInput { state: ElementState::Pressed, .. }, .. } => {
|
||||||
let window = winit::Window::new(&events_loop).unwrap();
|
let window = Window::new(&events_loop).unwrap();
|
||||||
windows.insert(window.id(), window);
|
windows.insert(window.id(), window);
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => ()
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
use winit::{EventLoop, WindowBuilder};
|
use winit::window::WindowBuilder;
|
||||||
|
use winit::event::{Event, WindowEvent};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop: EventLoop<i32> = EventLoop::new_user_event();
|
let events_loop: EventLoop<i32> = EventLoop::new_user_event();
|
||||||
@@ -24,9 +26,9 @@ fn main() {
|
|||||||
events_loop.run(move |event, _, control_flow| {
|
events_loop.run(move |event, _, control_flow| {
|
||||||
println!("{:?}", event);
|
println!("{:?}", event);
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } =>
|
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } =>
|
||||||
*control_flow = winit::ControlFlow::Exit,
|
*control_flow = ControlFlow::Exit,
|
||||||
_ => *control_flow = winit::ControlFlow::Wait,
|
_ => *control_flow = ControlFlow::Wait,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
use winit::{Event, WindowEvent};
|
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
|
|
||||||
fn main() {
|
use winit::window::WindowBuilder;
|
||||||
let events_loop = winit::EventLoop::new();
|
use winit::event::{Event, WindowEvent};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new()
|
fn main() {
|
||||||
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -17,10 +20,10 @@ fn main() {
|
|||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
..
|
..
|
||||||
} => *control_flow = winit::ControlFlow::Exit,
|
} => *control_flow = ControlFlow::Exit,
|
||||||
Event::EventsCleared => {
|
Event::EventsCleared => {
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
*control_flow = winit::ControlFlow::WaitUntil(Instant::now() + Duration::new(1, 0))
|
*control_flow = ControlFlow::WaitUntil(Instant::now() + Duration::new(1, 0))
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
use winit::window::WindowBuilder;
|
||||||
|
use winit::event::{Event, WindowEvent, VirtualKeyCode, ElementState, KeyboardInput};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop = winit::EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
let mut resizable = false;
|
let mut resizable = false;
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Hit space to toggle resizability.")
|
.with_title("Hit space to toggle resizability.")
|
||||||
.with_dimensions((400, 200).into())
|
.with_dimensions((400, 200).into())
|
||||||
.with_resizable(resizable)
|
.with_resizable(resizable)
|
||||||
@@ -13,15 +16,15 @@ fn main() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
events_loop.run(move |event, _, control_flow| {
|
events_loop.run(move |event, _, control_flow| {
|
||||||
*control_flow = winit::ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent { event, .. } => match event {
|
Event::WindowEvent { event, .. } => match event {
|
||||||
winit::WindowEvent::CloseRequested => *control_flow = winit::ControlFlow::Exit,
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
winit::WindowEvent::KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
input:
|
input:
|
||||||
winit::KeyboardInput {
|
KeyboardInput {
|
||||||
virtual_keycode: Some(winit::VirtualKeyCode::Space),
|
virtual_keycode: Some(VirtualKeyCode::Space),
|
||||||
state: winit::ElementState::Released,
|
state: ElementState::Released,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
|
use winit::window::WindowBuilder;
|
||||||
|
use winit::event::{Event, WindowEvent};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
use winit::platform::desktop::EventLoopExtDesktop;
|
use winit::platform::desktop::EventLoopExtDesktop;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut events_loop = winit::EventLoop::new();
|
let mut events_loop = EventLoop::new();
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -12,16 +16,16 @@ fn main() {
|
|||||||
println!("Close the window to continue.");
|
println!("Close the window to continue.");
|
||||||
events_loop.run_return(|event, _, control_flow| {
|
events_loop.run_return(|event, _, control_flow| {
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: winit::WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
..
|
..
|
||||||
} => *control_flow = winit::ControlFlow::Exit,
|
} => *control_flow = ControlFlow::Exit,
|
||||||
_ => *control_flow = winit::ControlFlow::Wait,
|
_ => *control_flow = ControlFlow::Wait,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
drop(window);
|
drop(window);
|
||||||
|
|
||||||
let _window_2 = winit::WindowBuilder::new()
|
let _window_2 = WindowBuilder::new()
|
||||||
.with_title("A second, fantasticer window!")
|
.with_title("A second, fantasticer window!")
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -29,11 +33,11 @@ fn main() {
|
|||||||
println!("Wa ha ha! You thought that closing the window would finish this?!");
|
println!("Wa ha ha! You thought that closing the window would finish this?!");
|
||||||
events_loop.run_return(|event, _, control_flow| {
|
events_loop.run_return(|event, _, control_flow| {
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: winit::WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
..
|
..
|
||||||
} => *control_flow = winit::ControlFlow::Exit,
|
} => *control_flow = ControlFlow::Exit,
|
||||||
_ => *control_flow = winit::ControlFlow::Wait,
|
_ => *control_flow = ControlFlow::Wait,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use winit::{Event, WindowEvent, StartCause, ControlFlow};
|
use winit::window::WindowBuilder;
|
||||||
|
use winit::event::{Event, WindowEvent, StartCause};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop = winit::EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
let _window = winit::WindowBuilder::new()
|
let _window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
use winit::window::WindowBuilder;
|
||||||
|
use winit::event::{Event, WindowEvent};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop = winit::EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new().with_decorations(false)
|
let window = WindowBuilder::new().with_decorations(false)
|
||||||
.with_transparency(true)
|
.with_transparency(true)
|
||||||
.build(&events_loop).unwrap();
|
.build(&events_loop).unwrap();
|
||||||
|
|
||||||
@@ -13,9 +16,9 @@ fn main() {
|
|||||||
println!("{:?}", event);
|
println!("{:?}", event);
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } =>
|
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } =>
|
||||||
*control_flow = winit::ControlFlow::Exit,
|
*control_flow = ControlFlow::Exit,
|
||||||
_ => *control_flow = winit::ControlFlow::Wait,
|
_ => *control_flow = ControlFlow::Wait,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
use winit::window::WindowBuilder;
|
||||||
|
use winit::event::{Event, WindowEvent};
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let events_loop = winit::EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
let _window = winit::WindowBuilder::new()
|
let _window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
.build(&events_loop)
|
.build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -12,11 +15,11 @@ fn main() {
|
|||||||
println!("{:?}", event);
|
println!("{:?}", event);
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: winit::WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
..
|
..
|
||||||
} => *control_flow = winit::ControlFlow::Exit,
|
} => *control_flow = ControlFlow::Exit,
|
||||||
_ => *control_flow = winit::ControlFlow::Wait,
|
_ => *control_flow = ControlFlow::Wait,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,14 @@ extern crate image;
|
|||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
#[cfg(feature = "icon_loading")]
|
||||||
fn main() {
|
fn main() {
|
||||||
|
<<<<<<< HEAD
|
||||||
use winit::Icon;
|
use winit::Icon;
|
||||||
|
=======
|
||||||
|
use winit::window::{WindowBuilder, Icon};
|
||||||
|
use winit::event::Event;
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
|
>>>>>>> Re-organize into module structure
|
||||||
// You'll have to choose an icon size at your own discretion. On X11, the desired size varies
|
// You'll have to choose an icon size at your own discretion. On X11, the desired size varies
|
||||||
// by WM, and on Windows, you still have to account for screen scaling. Here we use 32px,
|
// by WM, and on Windows, you still have to account for screen scaling. Here we use 32px,
|
||||||
// since it seems to work well enough in most cases. Be careful about going too high, or
|
// since it seems to work well enough in most cases. Be careful about going too high, or
|
||||||
@@ -20,9 +27,9 @@ fn main() {
|
|||||||
// feature enabled).
|
// feature enabled).
|
||||||
let icon = Icon::from_path(path).expect("Failed to open icon");
|
let icon = Icon::from_path(path).expect("Failed to open icon");
|
||||||
|
|
||||||
let events_loop = winit::EventLoop::new();
|
let events_loop = EventLoop::new();
|
||||||
|
|
||||||
let window = winit::WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("An iconic window!")
|
.with_title("An iconic window!")
|
||||||
// At present, this only does anything on Windows and X11, so if you want to save load
|
// At present, this only does anything on Windows and X11, so if you want to save load
|
||||||
// time, you can put icon loading behind a function that returns `None` on other platforms.
|
// time, you can put icon loading behind a function that returns `None` on other platforms.
|
||||||
@@ -31,11 +38,11 @@ fn main() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
events_loop.run(move |event, _, control_flow| {
|
events_loop.run(move |event, _, control_flow| {
|
||||||
*control_flow = winit::ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
if let winit::Event::WindowEvent { event, .. } = event {
|
if let Event::WindowEvent { event, .. } = event {
|
||||||
use winit::WindowEvent::*;
|
use winit::event::WindowEvent::*;
|
||||||
match event {
|
match event {
|
||||||
CloseRequested => *control_flow = winit::ControlFlow::Exit,
|
CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
DroppedFile(path) => {
|
DroppedFile(path) => {
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use {DeviceId, LogicalPosition, LogicalSize, WindowId};
|
use dpi::{LogicalPosition, LogicalSize};
|
||||||
|
use window::WindowId;
|
||||||
|
use platform_impl;
|
||||||
|
|
||||||
/// Describes a generic event.
|
/// Describes a generic event.
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
@@ -158,6 +160,14 @@ pub enum WindowEvent {
|
|||||||
HiDpiFactorChanged(f64),
|
HiDpiFactorChanged(f64),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Identifier of an input device.
|
||||||
|
///
|
||||||
|
/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
|
||||||
|
/// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
|
||||||
|
/// physical. Virtual devices typically aggregate inputs from multiple physical devices.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct DeviceId(pub(crate) platform_impl::DeviceId);
|
||||||
|
|
||||||
/// Represents raw hardware events that are not associated with any particular window.
|
/// Represents raw hardware events that are not associated with any particular window.
|
||||||
///
|
///
|
||||||
/// Useful for interactions that diverge significantly from a conventional 2D GUI, such as 3D camera or first-person
|
/// Useful for interactions that diverge significantly from a conventional 2D GUI, such as 3D camera or first-person
|
||||||
151
src/event_loop.rs
Normal file
151
src/event_loop.rs
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
use std::{fmt, error};
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use platform_impl;
|
||||||
|
use event::Event;
|
||||||
|
use monitor::{AvailableMonitorsIter, MonitorId};
|
||||||
|
|
||||||
|
/// Provides a way to retrieve events from the system and from the windows that were registered to
|
||||||
|
/// the events loop.
|
||||||
|
///
|
||||||
|
/// An `EventLoop` can be seen more or less as a "context". Calling `EventLoop::new()`
|
||||||
|
/// initializes everything that will be required to create windows. For example on Linux creating
|
||||||
|
/// an events loop opens a connection to the X or Wayland server.
|
||||||
|
///
|
||||||
|
/// To wake up an `EventLoop` from a another thread, see the `EventLoopProxy` docs.
|
||||||
|
///
|
||||||
|
/// Note that the `EventLoop` cannot be shared accross threads (due to platform-dependant logic
|
||||||
|
/// 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<T> {
|
||||||
|
pub(crate) events_loop: platform_impl::EventLoop<T>,
|
||||||
|
pub(crate) _marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> std::fmt::Debug for EventLoop<T> {
|
||||||
|
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
fmtr.pad("EventLoop { .. }")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returned by the user callback given to the `EventLoop::run_forever` method.
|
||||||
|
///
|
||||||
|
/// Indicates whether the `run_forever` method should continue or complete.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub enum ControlFlow {
|
||||||
|
/// When the current loop iteration finishes, suspend the thread until another event arrives.
|
||||||
|
Wait,
|
||||||
|
/// When the current loop iteration finishes, suspend the thread until either another event
|
||||||
|
/// arrives or the given time is reached.
|
||||||
|
WaitUntil(Instant),
|
||||||
|
/// When the current loop iteration finishes, immediately begin a new iteration regardless of
|
||||||
|
/// whether or not new events are available to process.
|
||||||
|
Poll,
|
||||||
|
/// Send a `LoopDestroyed` event and stop the event loop.
|
||||||
|
Exit
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ControlFlow {
|
||||||
|
#[inline(always)]
|
||||||
|
fn default() -> ControlFlow {
|
||||||
|
ControlFlow::Poll
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventLoop<()> {
|
||||||
|
pub fn new() -> EventLoop<()> {
|
||||||
|
EventLoop::<()>::new_user_event()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> EventLoop<T> {
|
||||||
|
/// 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_user_event() -> EventLoop<T> {
|
||||||
|
EventLoop {
|
||||||
|
events_loop: platform_impl::EventLoop::new(),
|
||||||
|
_marker: ::std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the list of all the monitors available on the system.
|
||||||
|
///
|
||||||
|
// Note: should be replaced with `-> impl Iterator` once stable.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_available_monitors(&self) -> AvailableMonitorsIter {
|
||||||
|
let data = self.events_loop.get_available_monitors();
|
||||||
|
AvailableMonitorsIter{ data: data.into_iter() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the primary monitor of the system.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_primary_monitor(&self) -> MonitorId {
|
||||||
|
MonitorId { inner: self.events_loop.get_primary_monitor() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hijacks the calling thread and initializes the `winit` event loop. Can take a
|
||||||
|
/// `FnMut(Event, &EventLoop) -> ControlFlow` or a custom `EventHandler` type.
|
||||||
|
///
|
||||||
|
/// Any values not passed to this function will *not* be dropped.
|
||||||
|
#[inline]
|
||||||
|
pub fn run<F>(self, event_handler: F) -> !
|
||||||
|
where F: 'static + FnMut(Event<T>, &EventLoop<T>, &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<T> {
|
||||||
|
EventLoopProxy {
|
||||||
|
events_loop_proxy: self.events_loop.create_proxy(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to wake up the `EventLoop` from another thread.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct EventLoopProxy<T> {
|
||||||
|
events_loop_proxy: platform_impl::EventLoopProxy<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> EventLoopProxy<T> {
|
||||||
|
/// 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 send_event(&self, event: T) -> Result<(), EventLoopClosed> {
|
||||||
|
self.events_loop_proxy.send_event(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> std::fmt::Debug for EventLoopProxy<T> {
|
||||||
|
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
fmtr.pad("EventLoopProxy { .. }")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The error that is returned when an `EventLoopProxy` attempts to wake up an `EventLoop` that
|
||||||
|
/// no longer exists.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct EventLoopClosed;
|
||||||
|
|
||||||
|
impl fmt::Display for EventLoopClosed {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", error::Error::description(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for EventLoopClosed {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
"Tried to wake up a closed `EventLoop`"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
412
src/lib.rs
412
src/lib.rs
@@ -6,7 +6,7 @@
|
|||||||
//! `EventLoop::new()` function. Example:
|
//! `EventLoop::new()` function. Example:
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use winit::EventLoop;
|
//! use winit::event_loop::EventLoop;
|
||||||
//! let events_loop = EventLoop::new();
|
//! let events_loop = EventLoop::new();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
@@ -32,8 +32,9 @@
|
|||||||
//! stopped by returning `ControlFlow::Exit`, at which point the entire program will terminate.
|
//! stopped by returning `ControlFlow::Exit`, at which point the entire program will terminate.
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use winit::{ControlFlow, Event, WindowEvent};
|
//! use winit::event_loop::ControlFlow;
|
||||||
//! # use winit::EventLoop;
|
//! use winit::event::{Event, WindowEvent};
|
||||||
|
//! # use winit::event_loop::EventLoop;
|
||||||
//! # let events_loop = EventLoop::new();
|
//! # let events_loop = EventLoop::new();
|
||||||
//!
|
//!
|
||||||
//! events_loop.run(move |event, _, control_flow| {
|
//! events_loop.run(move |event, _, control_flow| {
|
||||||
@@ -54,7 +55,7 @@
|
|||||||
//! # Drawing on the window
|
//! # Drawing on the window
|
||||||
//!
|
//!
|
||||||
//! Winit doesn't provide any function that allows drawing on a window. However it allows you to
|
//! Winit doesn't provide any function that allows drawing on a window. However it allows you to
|
||||||
//! retrieve the raw handle of the window (see the `os` module for that), which in turn allows you
|
//! retrieve the raw handle of the window (see the `platform` module for that), which in turn allows you
|
||||||
//! to create an OpenGL/Vulkan/DirectX/Metal/etc. context that will draw on the window.
|
//! to create an OpenGL/Vulkan/DirectX/Metal/etc. context that will draw on the window.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
@@ -93,407 +94,12 @@ extern crate percent_encoding;
|
|||||||
#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
|
#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
|
||||||
extern crate smithay_client_toolkit as sctk;
|
extern crate smithay_client_toolkit as sctk;
|
||||||
|
|
||||||
use std::time::Instant;
|
|
||||||
pub(crate) use dpi::*; // TODO: Actually change the imports throughout the codebase.
|
|
||||||
pub use events::*;
|
|
||||||
pub use window::{AvailableMonitorsIter, MonitorId};
|
|
||||||
pub use icon::*;
|
|
||||||
|
|
||||||
pub mod dpi;
|
pub mod dpi;
|
||||||
mod events;
|
pub mod event;
|
||||||
|
pub mod event_loop;
|
||||||
mod icon;
|
mod icon;
|
||||||
mod platform_impl;
|
mod platform_impl;
|
||||||
mod window;
|
pub mod window;
|
||||||
|
pub mod monitor;
|
||||||
|
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
|
|
||||||
/// Represents a window.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use winit::{Event, EventLoop, Window, WindowEvent, ControlFlow};
|
|
||||||
///
|
|
||||||
/// let mut events_loop = EventLoop::new();
|
|
||||||
/// let window = Window::new(&events_loop).unwrap();
|
|
||||||
///
|
|
||||||
/// events_loop.run(move |event, _, control_flow| {
|
|
||||||
/// match event {
|
|
||||||
/// Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
|
||||||
/// *control_flow = ControlFlow::Exit
|
|
||||||
/// },
|
|
||||||
/// _ => *control_flow = ControlFlow::Wait,
|
|
||||||
/// }
|
|
||||||
/// });
|
|
||||||
/// ```
|
|
||||||
pub struct Window {
|
|
||||||
window: platform_impl::Window,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Debug for Window {
|
|
||||||
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
fmtr.pad("Window { .. }")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Identifier of a window. Unique for each window.
|
|
||||||
///
|
|
||||||
/// Can be obtained with `window.id()`.
|
|
||||||
///
|
|
||||||
/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you
|
|
||||||
/// can then compare to the ids of your windows.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct WindowId(platform_impl::WindowId);
|
|
||||||
|
|
||||||
/// Identifier of an input device.
|
|
||||||
///
|
|
||||||
/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
|
|
||||||
/// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
|
|
||||||
/// physical. Virtual devices typically aggregate inputs from multiple physical devices.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct DeviceId(platform_impl::DeviceId);
|
|
||||||
|
|
||||||
/// Provides a way to retrieve events from the system and from the windows that were registered to
|
|
||||||
/// the events loop.
|
|
||||||
///
|
|
||||||
/// An `EventLoop` can be seen more or less as a "context". Calling `EventLoop::new()`
|
|
||||||
/// initializes everything that will be required to create windows. For example on Linux creating
|
|
||||||
/// an events loop opens a connection to the X or Wayland server.
|
|
||||||
///
|
|
||||||
/// To wake up an `EventLoop` from a another thread, see the `EventLoopProxy` docs.
|
|
||||||
///
|
|
||||||
/// Note that the `EventLoop` cannot be shared accross threads (due to platform-dependant logic
|
|
||||||
/// 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<T> {
|
|
||||||
events_loop: platform_impl::EventLoop<T>,
|
|
||||||
_marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> std::fmt::Debug for EventLoop<T> {
|
|
||||||
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
fmtr.pad("EventLoop { .. }")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returned by the user callback given to the `EventLoop::run_forever` method.
|
|
||||||
///
|
|
||||||
/// Indicates whether the `run_forever` method should continue or complete.
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
||||||
pub enum ControlFlow {
|
|
||||||
/// When the current loop iteration finishes, suspend the thread until another event arrives.
|
|
||||||
Wait,
|
|
||||||
/// When the current loop iteration finishes, suspend the thread until either another event
|
|
||||||
/// arrives or the given time is reached.
|
|
||||||
WaitUntil(Instant),
|
|
||||||
/// When the current loop iteration finishes, immediately begin a new iteration regardless of
|
|
||||||
/// whether or not new events are available to process.
|
|
||||||
Poll,
|
|
||||||
/// Send a `LoopDestroyed` event and stop the event loop.
|
|
||||||
Exit
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ControlFlow {
|
|
||||||
#[inline(always)]
|
|
||||||
fn default() -> ControlFlow {
|
|
||||||
ControlFlow::Poll
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventLoop<()> {
|
|
||||||
pub fn new() -> EventLoop<()> {
|
|
||||||
EventLoop::<()>::new_user_event()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> EventLoop<T> {
|
|
||||||
/// 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_user_event() -> EventLoop<T> {
|
|
||||||
EventLoop {
|
|
||||||
events_loop: platform_impl::EventLoop::new(),
|
|
||||||
_marker: ::std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the list of all the monitors available on the system.
|
|
||||||
///
|
|
||||||
// Note: should be replaced with `-> impl Iterator` once stable.
|
|
||||||
#[inline]
|
|
||||||
pub fn get_available_monitors(&self) -> AvailableMonitorsIter {
|
|
||||||
let data = self.events_loop.get_available_monitors();
|
|
||||||
AvailableMonitorsIter{ data: data.into_iter() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the primary monitor of the system.
|
|
||||||
#[inline]
|
|
||||||
pub fn get_primary_monitor(&self) -> MonitorId {
|
|
||||||
MonitorId { inner: self.events_loop.get_primary_monitor() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hijacks the calling thread and initializes the `winit` event loop. Can take a
|
|
||||||
/// `FnMut(Event, &EventLoop) -> ControlFlow` or a custom `EventHandler` type.
|
|
||||||
///
|
|
||||||
/// Any values not passed to this function will *not* be dropped.
|
|
||||||
#[inline]
|
|
||||||
pub fn run<F>(self, event_handler: F) -> !
|
|
||||||
where F: 'static + FnMut(Event<T>, &EventLoop<T>, &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<T> {
|
|
||||||
EventLoopProxy {
|
|
||||||
events_loop_proxy: self.events_loop.create_proxy(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Used to wake up the `EventLoop` from another thread.
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct EventLoopProxy<T> {
|
|
||||||
events_loop_proxy: platform_impl::EventLoopProxy<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> std::fmt::Debug for EventLoopProxy<T> {
|
|
||||||
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
fmtr.pad("EventLoopProxy { .. }")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> EventLoopProxy<T> {
|
|
||||||
/// 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 send_event(&self, event: T) -> Result<(), EventLoopClosed> {
|
|
||||||
self.events_loop_proxy.send_event(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The error that is returned when an `EventLoopProxy` attempts to wake up an `EventLoop` that
|
|
||||||
/// no longer exists.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct EventLoopClosed;
|
|
||||||
|
|
||||||
impl std::fmt::Display for EventLoopClosed {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
write!(f, "{}", std::error::Error::description(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::error::Error for EventLoopClosed {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
"Tried to wake up a closed `EventLoop`"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Object that allows you to build windows.
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct WindowBuilder {
|
|
||||||
/// The attributes to use to create the window.
|
|
||||||
pub window: WindowAttributes,
|
|
||||||
|
|
||||||
// Platform-specific configuration. Private.
|
|
||||||
platform_specific: platform_impl::PlatformSpecificWindowBuilderAttributes,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Debug for WindowBuilder {
|
|
||||||
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
fmtr.debug_struct("WindowBuilder")
|
|
||||||
.field("window", &self.window)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error that can happen while creating a window or a headless renderer.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum CreationError {
|
|
||||||
OsError(String),
|
|
||||||
/// TODO: remove this error
|
|
||||||
NotSupported,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreationError {
|
|
||||||
fn to_string(&self) -> &str {
|
|
||||||
match *self {
|
|
||||||
CreationError::OsError(ref text) => &text,
|
|
||||||
CreationError::NotSupported => "Some of the requested attributes are not supported",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for CreationError {
|
|
||||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
|
||||||
formatter.write_str(self.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::error::Error for CreationError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
self.to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Describes the appearance of the mouse cursor.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
||||||
pub enum MouseCursor {
|
|
||||||
/// The platform-dependent default cursor.
|
|
||||||
Default,
|
|
||||||
/// A simple crosshair.
|
|
||||||
Crosshair,
|
|
||||||
/// A hand (often used to indicate links in web browsers).
|
|
||||||
Hand,
|
|
||||||
/// Self explanatory.
|
|
||||||
Arrow,
|
|
||||||
/// Indicates something is to be moved.
|
|
||||||
Move,
|
|
||||||
/// Indicates text that may be selected or edited.
|
|
||||||
Text,
|
|
||||||
/// Program busy indicator.
|
|
||||||
Wait,
|
|
||||||
/// Help indicator (often rendered as a "?")
|
|
||||||
Help,
|
|
||||||
/// Progress indicator. Shows that processing is being done. But in contrast
|
|
||||||
/// with "Wait" the user may still interact with the program. Often rendered
|
|
||||||
/// as a spinning beach ball, or an arrow with a watch or hourglass.
|
|
||||||
Progress,
|
|
||||||
|
|
||||||
/// Cursor showing that something cannot be done.
|
|
||||||
NotAllowed,
|
|
||||||
ContextMenu,
|
|
||||||
Cell,
|
|
||||||
VerticalText,
|
|
||||||
Alias,
|
|
||||||
Copy,
|
|
||||||
NoDrop,
|
|
||||||
Grab,
|
|
||||||
Grabbing,
|
|
||||||
AllScroll,
|
|
||||||
ZoomIn,
|
|
||||||
ZoomOut,
|
|
||||||
|
|
||||||
/// Indicate that some edge is to be moved. For example, the 'SeResize' cursor
|
|
||||||
/// is used when the movement starts from the south-east corner of the box.
|
|
||||||
EResize,
|
|
||||||
NResize,
|
|
||||||
NeResize,
|
|
||||||
NwResize,
|
|
||||||
SResize,
|
|
||||||
SeResize,
|
|
||||||
SwResize,
|
|
||||||
WResize,
|
|
||||||
EwResize,
|
|
||||||
NsResize,
|
|
||||||
NeswResize,
|
|
||||||
NwseResize,
|
|
||||||
ColResize,
|
|
||||||
RowResize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for MouseCursor {
|
|
||||||
fn default() -> Self {
|
|
||||||
MouseCursor::Default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attributes to use when creating a window.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct WindowAttributes {
|
|
||||||
/// The dimensions of the window. If this is `None`, some platform-specific dimensions will be
|
|
||||||
/// used.
|
|
||||||
///
|
|
||||||
/// The default is `None`.
|
|
||||||
pub dimensions: Option<LogicalSize>,
|
|
||||||
|
|
||||||
/// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved).
|
|
||||||
///
|
|
||||||
/// The default is `None`.
|
|
||||||
pub min_dimensions: Option<LogicalSize>,
|
|
||||||
|
|
||||||
/// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
|
|
||||||
///
|
|
||||||
/// The default is `None`.
|
|
||||||
pub max_dimensions: Option<LogicalSize>,
|
|
||||||
|
|
||||||
/// Whether the window is resizable or not.
|
|
||||||
///
|
|
||||||
/// The default is `true`.
|
|
||||||
pub resizable: bool,
|
|
||||||
|
|
||||||
/// Whether the window should be set as fullscreen upon creation.
|
|
||||||
///
|
|
||||||
/// The default is `None`.
|
|
||||||
pub fullscreen: Option<MonitorId>,
|
|
||||||
|
|
||||||
/// The title of the window in the title bar.
|
|
||||||
///
|
|
||||||
/// The default is `"winit window"`.
|
|
||||||
pub title: String,
|
|
||||||
|
|
||||||
/// Whether the window should be maximized upon creation.
|
|
||||||
///
|
|
||||||
/// The default is `false`.
|
|
||||||
pub maximized: bool,
|
|
||||||
|
|
||||||
/// Whether the window should be immediately visible upon creation.
|
|
||||||
///
|
|
||||||
/// The default is `true`.
|
|
||||||
pub visible: bool,
|
|
||||||
|
|
||||||
/// Whether the the window should be transparent. If this is true, writing colors
|
|
||||||
/// with alpha values different than `1.0` will produce a transparent window.
|
|
||||||
///
|
|
||||||
/// The default is `false`.
|
|
||||||
pub transparent: bool,
|
|
||||||
|
|
||||||
/// Whether the window should have borders and bars.
|
|
||||||
///
|
|
||||||
/// The default is `true`.
|
|
||||||
pub decorations: bool,
|
|
||||||
|
|
||||||
/// Whether the window should always be on top of other windows.
|
|
||||||
///
|
|
||||||
/// The default is `false`.
|
|
||||||
pub always_on_top: bool,
|
|
||||||
|
|
||||||
/// The window icon.
|
|
||||||
///
|
|
||||||
/// The default is `None`.
|
|
||||||
pub window_icon: Option<Icon>,
|
|
||||||
|
|
||||||
/// [iOS only] Enable multitouch,
|
|
||||||
/// see [multipleTouchEnabled](https://developer.apple.com/documentation/uikit/uiview/1622519-multipletouchenabled)
|
|
||||||
pub multitouch: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for WindowAttributes {
|
|
||||||
#[inline]
|
|
||||||
fn default() -> WindowAttributes {
|
|
||||||
WindowAttributes {
|
|
||||||
dimensions: None,
|
|
||||||
min_dimensions: None,
|
|
||||||
max_dimensions: None,
|
|
||||||
resizable: true,
|
|
||||||
title: "winit window".to_owned(),
|
|
||||||
maximized: false,
|
|
||||||
fullscreen: None,
|
|
||||||
visible: true,
|
|
||||||
transparent: false,
|
|
||||||
decorations: true,
|
|
||||||
always_on_top: false,
|
|
||||||
window_icon: None,
|
|
||||||
multitouch: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
68
src/monitor.rs
Normal file
68
src/monitor.rs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
use std::collections::vec_deque::IntoIter as VecDequeIter;
|
||||||
|
|
||||||
|
use platform_impl;
|
||||||
|
use dpi::{PhysicalPosition, PhysicalSize};
|
||||||
|
|
||||||
|
/// An iterator for the list of available monitors.
|
||||||
|
// Implementation note: we retrieve the list once, then serve each element by one by one.
|
||||||
|
// This may change in the future.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AvailableMonitorsIter {
|
||||||
|
pub(crate) data: VecDequeIter<platform_impl::MonitorId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for AvailableMonitorsIter {
|
||||||
|
type Item = MonitorId;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<MonitorId> {
|
||||||
|
self.data.next().map(|id| MonitorId { inner: id })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.data.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Identifier for a monitor.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct MonitorId {
|
||||||
|
pub(crate) inner: platform_impl::MonitorId
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MonitorId {
|
||||||
|
/// Returns a human-readable name of the monitor.
|
||||||
|
///
|
||||||
|
/// Returns `None` if the monitor doesn't exist anymore.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_name(&self) -> Option<String> {
|
||||||
|
self.inner.get_name()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the monitor's resolution.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||||
|
self.inner.get_dimensions()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the top-left corner position of the monitor relative to the larger full
|
||||||
|
/// screen area.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_position(&self) -> PhysicalPosition {
|
||||||
|
self.inner.get_position()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa.
|
||||||
|
///
|
||||||
|
/// See the [`dpi`](dpi/index.html) module for more information.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
|
||||||
|
/// - **Android:** Always returns 1.0.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_hidpi_factor(&self) -> f64 {
|
||||||
|
self.inner.get_hidpi_factor()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"
|
target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"
|
||||||
))]
|
))]
|
||||||
|
|
||||||
use {EventLoop, Event, ControlFlow};
|
use event::Event;
|
||||||
|
use event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
/// Additional methods on `EventLoop` that are specific to desktop platforms.
|
/// Additional methods on `EventLoop` that are specific to desktop platforms.
|
||||||
pub trait EventLoopExtDesktop {
|
pub trait EventLoopExtDesktop {
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ use std::os::raw::c_void;
|
|||||||
use libc;
|
use libc;
|
||||||
use winapi::shared::windef::HWND;
|
use winapi::shared::windef::HWND;
|
||||||
|
|
||||||
use {DeviceId, EventLoop, Icon, MonitorId, Window, WindowBuilder};
|
use event::DeviceId;
|
||||||
|
use monitor::MonitorId;
|
||||||
|
use event_loop::EventLoop;
|
||||||
|
use window::{Icon, Window, WindowBuilder};
|
||||||
use platform_impl::EventLoop as WindowsEventLoop;
|
use platform_impl::EventLoop as WindowsEventLoop;
|
||||||
|
|
||||||
/// Additional methods on `EventLoop` that are specific to Windows.
|
/// Additional methods on `EventLoop` that are specific to Windows.
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ use winapi::um::{shellapi, unknwnbase};
|
|||||||
|
|
||||||
use platform_impl::platform::WindowId;
|
use platform_impl::platform::WindowId;
|
||||||
|
|
||||||
use {Event, WindowId as SuperWindowId};
|
use event::Event;
|
||||||
|
use window::WindowId as SuperWindowId;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct FileDropHandlerData {
|
pub struct FileDropHandlerData {
|
||||||
@@ -81,7 +82,7 @@ impl FileDropHandler {
|
|||||||
_pt: *const POINTL,
|
_pt: *const POINTL,
|
||||||
_pdwEffect: *mut DWORD,
|
_pdwEffect: *mut DWORD,
|
||||||
) -> HRESULT {
|
) -> HRESULT {
|
||||||
use events::WindowEvent::HoveredFile;
|
use event::WindowEvent::HoveredFile;
|
||||||
let drop_handler = Self::from_interface(this);
|
let drop_handler = Self::from_interface(this);
|
||||||
Self::iterate_filenames(pDataObj, |filename| {
|
Self::iterate_filenames(pDataObj, |filename| {
|
||||||
drop_handler.send_event(Event::WindowEvent {
|
drop_handler.send_event(Event::WindowEvent {
|
||||||
@@ -103,7 +104,7 @@ impl FileDropHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe extern "system" fn DragLeave(this: *mut IDropTarget) -> HRESULT {
|
pub unsafe extern "system" fn DragLeave(this: *mut IDropTarget) -> HRESULT {
|
||||||
use events::WindowEvent::HoveredFileCancelled;
|
use event::WindowEvent::HoveredFileCancelled;
|
||||||
let drop_handler = Self::from_interface(this);
|
let drop_handler = Self::from_interface(this);
|
||||||
drop_handler.send_event(Event::WindowEvent {
|
drop_handler.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(drop_handler.window)),
|
window_id: SuperWindowId(WindowId(drop_handler.window)),
|
||||||
@@ -120,7 +121,7 @@ impl FileDropHandler {
|
|||||||
_pt: *const POINTL,
|
_pt: *const POINTL,
|
||||||
_pdwEffect: *mut DWORD,
|
_pdwEffect: *mut DWORD,
|
||||||
) -> HRESULT {
|
) -> HRESULT {
|
||||||
use events::WindowEvent::DroppedFile;
|
use event::WindowEvent::DroppedFile;
|
||||||
let drop_handler = Self::from_interface(this);
|
let drop_handler = Self::from_interface(this);
|
||||||
let hdrop = Self::iterate_filenames(pDataObj, |filename| {
|
let hdrop = Self::iterate_filenames(pDataObj, |filename| {
|
||||||
drop_handler.send_event(Event::WindowEvent {
|
drop_handler.send_event(Event::WindowEvent {
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
use std::char;
|
use std::char;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
use events::VirtualKeyCode;
|
use event::{ScanCode, ModifiersState, VirtualKeyCode};
|
||||||
use events::ModifiersState;
|
|
||||||
|
|
||||||
use winapi::shared::minwindef::{WPARAM, LPARAM, UINT};
|
use winapi::shared::minwindef::{WPARAM, LPARAM, UINT};
|
||||||
use winapi::um::winuser;
|
use winapi::um::winuser;
|
||||||
|
|
||||||
use ScanCode;
|
|
||||||
|
|
||||||
pub fn get_key_mods() -> ModifiersState {
|
pub fn get_key_mods() -> ModifiersState {
|
||||||
let mut mods = ModifiersState::default();
|
let mut mods = ModifiersState::default();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|||||||
@@ -40,18 +40,11 @@ use winapi::shared::windowsx;
|
|||||||
use winapi::um::{winuser, winbase, ole2, processthreadsapi, commctrl, libloaderapi};
|
use winapi::um::{winuser, winbase, ole2, processthreadsapi, commctrl, libloaderapi};
|
||||||
use winapi::um::winnt::{LONG, LPCSTR, SHORT};
|
use winapi::um::winnt::{LONG, LPCSTR, SHORT};
|
||||||
|
|
||||||
use {
|
use window::WindowId as RootWindowId;
|
||||||
ControlFlow,
|
use monitor::MonitorId;
|
||||||
Event,
|
use event_loop::{ControlFlow, EventLoop as RootEventLoop, EventLoopClosed};
|
||||||
EventLoopClosed,
|
use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||||
KeyboardInput,
|
use event::{DeviceEvent, Touch, TouchPhase, StartCause, KeyboardInput, Event, WindowEvent};
|
||||||
LogicalPosition,
|
|
||||||
LogicalSize,
|
|
||||||
PhysicalSize,
|
|
||||||
WindowEvent,
|
|
||||||
WindowId as SuperWindowId,
|
|
||||||
};
|
|
||||||
use events::{DeviceEvent, Touch, TouchPhase, StartCause};
|
|
||||||
use platform_impl::platform::{event, Cursor, WindowId, DEVICE_ID, wrap_device_id, util};
|
use platform_impl::platform::{event, Cursor, WindowId, DEVICE_ID, wrap_device_id, util};
|
||||||
use platform_impl::platform::dpi::{
|
use platform_impl::platform::dpi::{
|
||||||
become_dpi_aware,
|
become_dpi_aware,
|
||||||
@@ -98,7 +91,7 @@ pub struct WindowState {
|
|||||||
// This is different from the value in `SavedWindowInfo`! That one represents the DPI saved upon entering
|
// This is different from the value in `SavedWindowInfo`! That one represents the DPI saved upon entering
|
||||||
// fullscreen. This will always be the most recent DPI for the window.
|
// fullscreen. This will always be the most recent DPI for the window.
|
||||||
pub dpi_factor: f64,
|
pub dpi_factor: f64,
|
||||||
pub fullscreen: Option<::MonitorId>,
|
pub fullscreen: Option<MonitorId>,
|
||||||
pub window_icon: Option<WinIcon>,
|
pub window_icon: Option<WinIcon>,
|
||||||
pub taskbar_icon: Option<WinIcon>,
|
pub taskbar_icon: Option<WinIcon>,
|
||||||
pub decorations: bool,
|
pub decorations: bool,
|
||||||
@@ -183,14 +176,14 @@ impl<T> EventLoop<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F>(mut self, event_handler: F) -> !
|
pub fn run<F>(mut self, event_handler: F) -> !
|
||||||
where F: 'static + FnMut(Event<T>, &::EventLoop<T>, &mut ControlFlow)
|
where F: 'static + FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
|
||||||
{
|
{
|
||||||
self.run_return(event_handler);
|
self.run_return(event_handler);
|
||||||
::std::process::exit(0);
|
::std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_return<F>(&mut self, mut event_handler: F)
|
pub fn run_return<F>(&mut self, mut event_handler: F)
|
||||||
where F: FnMut(Event<T>, &::EventLoop<T>, &mut ControlFlow)
|
where F: FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
|
||||||
{
|
{
|
||||||
unsafe{ winuser::IsGUIThread(1); }
|
unsafe{ winuser::IsGUIThread(1); }
|
||||||
let mut runner = EventLoopRunner {
|
let mut runner = EventLoopRunner {
|
||||||
@@ -201,8 +194,8 @@ impl<T> EventLoop<T> {
|
|||||||
event_handler: unsafe {
|
event_handler: unsafe {
|
||||||
// Transmute used to erase lifetimes.
|
// Transmute used to erase lifetimes.
|
||||||
mem::transmute::<
|
mem::transmute::<
|
||||||
&mut FnMut(Event<T>, &::EventLoop<T>, &mut ControlFlow),
|
&mut FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow),
|
||||||
*mut FnMut(Event<T>, &::EventLoop<T>, &mut ControlFlow)
|
*mut FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
|
||||||
>(&mut event_handler)
|
>(&mut event_handler)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -294,7 +287,7 @@ pub(crate) struct EventLoopRunner<T> {
|
|||||||
control_flow: ControlFlow,
|
control_flow: ControlFlow,
|
||||||
runner_state: RunnerState,
|
runner_state: RunnerState,
|
||||||
modal_loop_data: Option<ModalLoopData>,
|
modal_loop_data: Option<ModalLoopData>,
|
||||||
event_handler: *mut FnMut(Event<T>, &::EventLoop<T>, &mut ControlFlow)
|
event_handler: *mut FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ModalLoopData {
|
struct ModalLoopData {
|
||||||
@@ -468,8 +461,8 @@ impl<T> EventLoopRunner<T> {
|
|||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(mem::size_of::<::EventLoop<T>>(), mem::size_of::<EventLoop<T>>());
|
assert_eq!(mem::size_of::<RootEventLoop<T>>(), mem::size_of::<EventLoop<T>>());
|
||||||
let event_loop_ref = &*(self.event_loop as *const ::EventLoop<T>);
|
let event_loop_ref = &*(self.event_loop as *const RootEventLoop<T>);
|
||||||
|
|
||||||
if self.control_flow != ControlFlow::Exit {
|
if self.control_flow != ControlFlow::Exit {
|
||||||
(*self.event_handler)(event, event_loop_ref, &mut self.control_flow);
|
(*self.event_handler)(event, event_loop_ref, &mut self.control_flow);
|
||||||
@@ -800,16 +793,16 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_CLOSE => {
|
winuser::WM_CLOSE => {
|
||||||
use events::WindowEvent::CloseRequested;
|
use event::WindowEvent::CloseRequested;
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: CloseRequested
|
event: CloseRequested
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_DESTROY => {
|
winuser::WM_DESTROY => {
|
||||||
use events::WindowEvent::Destroyed;
|
use event::WindowEvent::Destroyed;
|
||||||
ole2::RevokeDragDrop(window);
|
ole2::RevokeDragDrop(window);
|
||||||
{
|
{
|
||||||
let window_state = subclass_input.window_state.lock();
|
let window_state = subclass_input.window_state.lock();
|
||||||
@@ -818,7 +811,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: Destroyed
|
event: Destroyed
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -828,14 +821,14 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
_ if msg == *REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID => {
|
_ if msg == *REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID => {
|
||||||
use events::WindowEvent::RedrawRequested;
|
use event::WindowEvent::RedrawRequested;
|
||||||
let runner = subclass_input.event_loop_runner.borrow_mut();
|
let runner = subclass_input.event_loop_runner.borrow_mut();
|
||||||
if let ELRSharedOption::Runner(runner) = *runner {
|
if let ELRSharedOption::Runner(runner) = *runner {
|
||||||
let runner = &mut *runner;
|
let runner = &mut *runner;
|
||||||
match runner.runner_state {
|
match runner.runner_state {
|
||||||
RunnerState::Idle(..) |
|
RunnerState::Idle(..) |
|
||||||
RunnerState::DeferredNewEvents(..) => runner.call_event_handler(Event::WindowEvent {
|
RunnerState::DeferredNewEvents(..) => runner.call_event_handler(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: RedrawRequested,
|
event: RedrawRequested,
|
||||||
}),
|
}),
|
||||||
_ => ()
|
_ => ()
|
||||||
@@ -844,9 +837,9 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
0
|
0
|
||||||
},
|
},
|
||||||
winuser::WM_PAINT => {
|
winuser::WM_PAINT => {
|
||||||
use events::WindowEvent::RedrawRequested;
|
use event::WindowEvent::RedrawRequested;
|
||||||
let event = || Event::WindowEvent {
|
let event = || Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: RedrawRequested,
|
event: RedrawRequested,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -870,7 +863,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
|
|
||||||
// WM_MOVE supplies client area positions, so we send Moved here instead.
|
// WM_MOVE supplies client area positions, so we send Moved here instead.
|
||||||
winuser::WM_WINDOWPOSCHANGED => {
|
winuser::WM_WINDOWPOSCHANGED => {
|
||||||
use events::WindowEvent::Moved;
|
use event::WindowEvent::Moved;
|
||||||
|
|
||||||
let windowpos = lparam as *const winuser::WINDOWPOS;
|
let windowpos = lparam as *const winuser::WINDOWPOS;
|
||||||
if (*windowpos).flags & winuser::SWP_NOMOVE != winuser::SWP_NOMOVE {
|
if (*windowpos).flags & winuser::SWP_NOMOVE != winuser::SWP_NOMOVE {
|
||||||
@@ -880,7 +873,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
dpi_factor,
|
dpi_factor,
|
||||||
);
|
);
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: Moved(logical_position),
|
event: Moved(logical_position),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -890,14 +883,14 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_SIZE => {
|
winuser::WM_SIZE => {
|
||||||
use events::WindowEvent::Resized;
|
use event::WindowEvent::Resized;
|
||||||
let w = LOWORD(lparam as DWORD) as u32;
|
let w = LOWORD(lparam as DWORD) as u32;
|
||||||
let h = HIWORD(lparam as DWORD) as u32;
|
let h = HIWORD(lparam as DWORD) as u32;
|
||||||
|
|
||||||
let dpi_factor = get_hwnd_scale_factor(window);
|
let dpi_factor = get_hwnd_scale_factor(window);
|
||||||
let logical_size = LogicalSize::from_physical((w, h), dpi_factor);
|
let logical_size = LogicalSize::from_physical((w, h), dpi_factor);
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: Resized(logical_size),
|
event: Resized(logical_size),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -907,10 +900,10 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
|
|
||||||
winuser::WM_CHAR => {
|
winuser::WM_CHAR => {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use events::WindowEvent::ReceivedCharacter;
|
use event::WindowEvent::ReceivedCharacter;
|
||||||
let chr: char = mem::transmute(wparam as u32);
|
let chr: char = mem::transmute(wparam as u32);
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: ReceivedCharacter(chr),
|
event: ReceivedCharacter(chr),
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
@@ -925,7 +918,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
winuser::WM_MOUSEMOVE => {
|
winuser::WM_MOUSEMOVE => {
|
||||||
use events::WindowEvent::{CursorEntered, CursorMoved};
|
use event::WindowEvent::{CursorEntered, CursorMoved};
|
||||||
let mouse_outside_window = {
|
let mouse_outside_window = {
|
||||||
let mut window = subclass_input.window_state.lock();
|
let mut window = subclass_input.window_state.lock();
|
||||||
if !window.mouse_in_window {
|
if !window.mouse_in_window {
|
||||||
@@ -938,7 +931,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
|
|
||||||
if mouse_outside_window {
|
if mouse_outside_window {
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: CursorEntered { device_id: DEVICE_ID },
|
event: CursorEntered { device_id: DEVICE_ID },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -957,7 +950,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
let position = LogicalPosition::from_physical((x, y), dpi_factor);
|
let position = LogicalPosition::from_physical((x, y), dpi_factor);
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: CursorMoved { device_id: DEVICE_ID, position, modifiers: event::get_key_mods() },
|
event: CursorMoved { device_id: DEVICE_ID, position, modifiers: event::get_key_mods() },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -965,7 +958,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_MOUSELEAVE => {
|
winuser::WM_MOUSELEAVE => {
|
||||||
use events::WindowEvent::CursorLeft;
|
use event::WindowEvent::CursorLeft;
|
||||||
let mouse_in_window = {
|
let mouse_in_window = {
|
||||||
let mut window = subclass_input.window_state.lock();
|
let mut window = subclass_input.window_state.lock();
|
||||||
if window.mouse_in_window {
|
if window.mouse_in_window {
|
||||||
@@ -978,7 +971,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
|
|
||||||
if mouse_in_window {
|
if mouse_in_window {
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: CursorLeft { device_id: DEVICE_ID }
|
event: CursorLeft { device_id: DEVICE_ID }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -987,15 +980,15 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_MOUSEWHEEL => {
|
winuser::WM_MOUSEWHEEL => {
|
||||||
use events::MouseScrollDelta::LineDelta;
|
use event::MouseScrollDelta::LineDelta;
|
||||||
use events::TouchPhase;
|
use event::TouchPhase;
|
||||||
|
|
||||||
let value = (wparam >> 16) as i16;
|
let value = (wparam >> 16) as i16;
|
||||||
let value = value as i32;
|
let value = value as i32;
|
||||||
let value = value as f32 / winuser::WHEEL_DELTA as f32;
|
let value = value as f32 / winuser::WHEEL_DELTA as f32;
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: WindowEvent::MouseWheel { device_id: DEVICE_ID, delta: LineDelta(0.0, value), phase: TouchPhase::Moved, modifiers: event::get_key_mods() },
|
event: WindowEvent::MouseWheel { device_id: DEVICE_ID, delta: LineDelta(0.0, value), phase: TouchPhase::Moved, modifiers: event::get_key_mods() },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1003,14 +996,14 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_KEYDOWN | winuser::WM_SYSKEYDOWN => {
|
winuser::WM_KEYDOWN | winuser::WM_SYSKEYDOWN => {
|
||||||
use events::ElementState::Pressed;
|
use event::ElementState::Pressed;
|
||||||
use events::VirtualKeyCode;
|
use event::VirtualKeyCode;
|
||||||
if msg == winuser::WM_SYSKEYDOWN && wparam as i32 == winuser::VK_F4 {
|
if msg == winuser::WM_SYSKEYDOWN && wparam as i32 == winuser::VK_F4 {
|
||||||
commctrl::DefSubclassProc(window, msg, wparam, lparam)
|
commctrl::DefSubclassProc(window, msg, wparam, lparam)
|
||||||
} else {
|
} else {
|
||||||
if let Some((scancode, vkey)) = process_key_params(wparam, lparam) {
|
if let Some((scancode, vkey)) = process_key_params(wparam, lparam) {
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: WindowEvent::KeyboardInput {
|
event: WindowEvent::KeyboardInput {
|
||||||
device_id: DEVICE_ID,
|
device_id: DEVICE_ID,
|
||||||
input: KeyboardInput {
|
input: KeyboardInput {
|
||||||
@@ -1025,7 +1018,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
// consistent with the other platforms we'll emit a delete character here.
|
// consistent with the other platforms we'll emit a delete character here.
|
||||||
if vkey == Some(VirtualKeyCode::Delete) {
|
if vkey == Some(VirtualKeyCode::Delete) {
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: WindowEvent::ReceivedCharacter('\u{7F}'),
|
event: WindowEvent::ReceivedCharacter('\u{7F}'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1035,10 +1028,10 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_KEYUP | winuser::WM_SYSKEYUP => {
|
winuser::WM_KEYUP | winuser::WM_SYSKEYUP => {
|
||||||
use events::ElementState::Released;
|
use event::ElementState::Released;
|
||||||
if let Some((scancode, vkey)) = process_key_params(wparam, lparam) {
|
if let Some((scancode, vkey)) = process_key_params(wparam, lparam) {
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: WindowEvent::KeyboardInput {
|
event: WindowEvent::KeyboardInput {
|
||||||
device_id: DEVICE_ID,
|
device_id: DEVICE_ID,
|
||||||
input: KeyboardInput {
|
input: KeyboardInput {
|
||||||
@@ -1054,114 +1047,114 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_LBUTTONDOWN => {
|
winuser::WM_LBUTTONDOWN => {
|
||||||
use events::WindowEvent::MouseInput;
|
use event::WindowEvent::MouseInput;
|
||||||
use events::MouseButton::Left;
|
use event::MouseButton::Left;
|
||||||
use events::ElementState::Pressed;
|
use event::ElementState::Pressed;
|
||||||
|
|
||||||
capture_mouse(window, &mut *subclass_input.window_state.lock());
|
capture_mouse(window, &mut *subclass_input.window_state.lock());
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Left, modifiers: event::get_key_mods() }
|
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Left, modifiers: event::get_key_mods() }
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_LBUTTONUP => {
|
winuser::WM_LBUTTONUP => {
|
||||||
use events::WindowEvent::MouseInput;
|
use event::WindowEvent::MouseInput;
|
||||||
use events::MouseButton::Left;
|
use event::MouseButton::Left;
|
||||||
use events::ElementState::Released;
|
use event::ElementState::Released;
|
||||||
|
|
||||||
release_mouse(&mut *subclass_input.window_state.lock());
|
release_mouse(&mut *subclass_input.window_state.lock());
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Left, modifiers: event::get_key_mods() }
|
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Left, modifiers: event::get_key_mods() }
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_RBUTTONDOWN => {
|
winuser::WM_RBUTTONDOWN => {
|
||||||
use events::WindowEvent::MouseInput;
|
use event::WindowEvent::MouseInput;
|
||||||
use events::MouseButton::Right;
|
use event::MouseButton::Right;
|
||||||
use events::ElementState::Pressed;
|
use event::ElementState::Pressed;
|
||||||
|
|
||||||
capture_mouse(window, &mut *subclass_input.window_state.lock());
|
capture_mouse(window, &mut *subclass_input.window_state.lock());
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Right, modifiers: event::get_key_mods() }
|
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Right, modifiers: event::get_key_mods() }
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_RBUTTONUP => {
|
winuser::WM_RBUTTONUP => {
|
||||||
use events::WindowEvent::MouseInput;
|
use event::WindowEvent::MouseInput;
|
||||||
use events::MouseButton::Right;
|
use event::MouseButton::Right;
|
||||||
use events::ElementState::Released;
|
use event::ElementState::Released;
|
||||||
|
|
||||||
release_mouse(&mut *subclass_input.window_state.lock());
|
release_mouse(&mut *subclass_input.window_state.lock());
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Right, modifiers: event::get_key_mods() }
|
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Right, modifiers: event::get_key_mods() }
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_MBUTTONDOWN => {
|
winuser::WM_MBUTTONDOWN => {
|
||||||
use events::WindowEvent::MouseInput;
|
use event::WindowEvent::MouseInput;
|
||||||
use events::MouseButton::Middle;
|
use event::MouseButton::Middle;
|
||||||
use events::ElementState::Pressed;
|
use event::ElementState::Pressed;
|
||||||
|
|
||||||
capture_mouse(window, &mut *subclass_input.window_state.lock());
|
capture_mouse(window, &mut *subclass_input.window_state.lock());
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Middle, modifiers: event::get_key_mods() }
|
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Middle, modifiers: event::get_key_mods() }
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_MBUTTONUP => {
|
winuser::WM_MBUTTONUP => {
|
||||||
use events::WindowEvent::MouseInput;
|
use event::WindowEvent::MouseInput;
|
||||||
use events::MouseButton::Middle;
|
use event::MouseButton::Middle;
|
||||||
use events::ElementState::Released;
|
use event::ElementState::Released;
|
||||||
|
|
||||||
release_mouse(&mut *subclass_input.window_state.lock());
|
release_mouse(&mut *subclass_input.window_state.lock());
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Middle, modifiers: event::get_key_mods() }
|
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Middle, modifiers: event::get_key_mods() }
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_XBUTTONDOWN => {
|
winuser::WM_XBUTTONDOWN => {
|
||||||
use events::WindowEvent::MouseInput;
|
use event::WindowEvent::MouseInput;
|
||||||
use events::MouseButton::Other;
|
use event::MouseButton::Other;
|
||||||
use events::ElementState::Pressed;
|
use event::ElementState::Pressed;
|
||||||
let xbutton = winuser::GET_XBUTTON_WPARAM(wparam);
|
let xbutton = winuser::GET_XBUTTON_WPARAM(wparam);
|
||||||
|
|
||||||
capture_mouse(window, &mut *subclass_input.window_state.lock());
|
capture_mouse(window, &mut *subclass_input.window_state.lock());
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Other(xbutton as u8), modifiers: event::get_key_mods() }
|
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Other(xbutton as u8), modifiers: event::get_key_mods() }
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_XBUTTONUP => {
|
winuser::WM_XBUTTONUP => {
|
||||||
use events::WindowEvent::MouseInput;
|
use event::WindowEvent::MouseInput;
|
||||||
use events::MouseButton::Other;
|
use event::MouseButton::Other;
|
||||||
use events::ElementState::Released;
|
use event::ElementState::Released;
|
||||||
let xbutton = winuser::GET_XBUTTON_WPARAM(wparam);
|
let xbutton = winuser::GET_XBUTTON_WPARAM(wparam);
|
||||||
|
|
||||||
release_mouse(&mut *subclass_input.window_state.lock());
|
release_mouse(&mut *subclass_input.window_state.lock());
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Other(xbutton as u8), modifiers: event::get_key_mods() }
|
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Other(xbutton as u8), modifiers: event::get_key_mods() }
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
@@ -1183,9 +1176,9 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_INPUT => {
|
winuser::WM_INPUT => {
|
||||||
use events::DeviceEvent::{Motion, MouseMotion, MouseWheel, Button, Key};
|
use event::DeviceEvent::{Motion, MouseMotion, MouseWheel, Button, Key};
|
||||||
use events::MouseScrollDelta::LineDelta;
|
use event::MouseScrollDelta::LineDelta;
|
||||||
use events::ElementState::{Pressed, Released};
|
use event::ElementState::{Pressed, Released};
|
||||||
|
|
||||||
if let Some(data) = get_raw_input_data(lparam as _) {
|
if let Some(data) = get_raw_input_data(lparam as _) {
|
||||||
let device_id = wrap_device_id(data.header.hDevice as _);
|
let device_id = wrap_device_id(data.header.hDevice as _);
|
||||||
@@ -1303,7 +1296,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
let y = (input.y as f64) / 100f64;
|
let y = (input.y as f64) / 100f64;
|
||||||
let location = LogicalPosition::from_physical((x, y), dpi_factor);
|
let location = LogicalPosition::from_physical((x, y), dpi_factor);
|
||||||
subclass_input.send_event( Event::WindowEvent {
|
subclass_input.send_event( Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: WindowEvent::Touch(Touch {
|
event: WindowEvent::Touch(Touch {
|
||||||
phase:
|
phase:
|
||||||
if input.dwFlags & winuser::TOUCHEVENTF_DOWN != 0 {
|
if input.dwFlags & winuser::TOUCHEVENTF_DOWN != 0 {
|
||||||
@@ -1327,9 +1320,9 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
winuser::WM_SETFOCUS => {
|
winuser::WM_SETFOCUS => {
|
||||||
use events::WindowEvent::{Focused, CursorMoved};
|
use event::WindowEvent::{Focused, CursorMoved};
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: Focused(true)
|
event: Focused(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1339,7 +1332,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
let position = LogicalPosition::from_physical((x, y), dpi_factor);
|
let position = LogicalPosition::from_physical((x, y), dpi_factor);
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: CursorMoved { device_id: DEVICE_ID, position, modifiers: event::get_key_mods() },
|
event: CursorMoved { device_id: DEVICE_ID, position, modifiers: event::get_key_mods() },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1347,9 +1340,9 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
winuser::WM_KILLFOCUS => {
|
winuser::WM_KILLFOCUS => {
|
||||||
use events::WindowEvent::Focused;
|
use event::WindowEvent::Focused;
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: Focused(false)
|
event: Focused(false)
|
||||||
});
|
});
|
||||||
0
|
0
|
||||||
@@ -1406,7 +1399,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
// Only sent on Windows 8.1 or newer. On Windows 7 and older user has to log out to change
|
// Only sent on Windows 8.1 or newer. On Windows 7 and older user has to log out to change
|
||||||
// DPI, therefore all applications are closed while DPI is changing.
|
// DPI, therefore all applications are closed while DPI is changing.
|
||||||
winuser::WM_DPICHANGED => {
|
winuser::WM_DPICHANGED => {
|
||||||
use events::WindowEvent::HiDpiFactorChanged;
|
use event::WindowEvent::HiDpiFactorChanged;
|
||||||
|
|
||||||
// This message actually provides two DPI values - x and y. However MSDN says that
|
// This message actually provides two DPI values - x and y. However MSDN says that
|
||||||
// "you only need to use either the X-axis or the Y-axis value when scaling your
|
// "you only need to use either the X-axis or the Y-axis value when scaling your
|
||||||
@@ -1454,7 +1447,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: HiDpiFactorChanged(new_dpi_factor),
|
event: HiDpiFactorChanged(new_dpi_factor),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1466,10 +1459,10 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
winuser::DestroyWindow(window);
|
winuser::DestroyWindow(window);
|
||||||
0
|
0
|
||||||
} else if msg == *INITIAL_DPI_MSG_ID {
|
} else if msg == *INITIAL_DPI_MSG_ID {
|
||||||
use events::WindowEvent::HiDpiFactorChanged;
|
use event::WindowEvent::HiDpiFactorChanged;
|
||||||
let scale_factor = dpi_to_scale_factor(wparam as u32);
|
let scale_factor = dpi_to_scale_factor(wparam as u32);
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
window_id: SuperWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: HiDpiFactorChanged(scale_factor),
|
event: HiDpiFactorChanged(scale_factor),
|
||||||
});
|
});
|
||||||
// Automatically resize for actual DPI
|
// Automatically resize for actual DPI
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use winapi::shared::minwindef::{BYTE, LPARAM, WPARAM};
|
|||||||
use winapi::shared::windef::{HICON, HWND};
|
use winapi::shared::windef::{HICON, HWND};
|
||||||
use winapi::um::winuser;
|
use winapi::um::winuser;
|
||||||
|
|
||||||
use {Pixel, PIXEL_SIZE, Icon};
|
use icon::{Pixel, PIXEL_SIZE, Icon};
|
||||||
use platform_impl::platform::util;
|
use platform_impl::platform::util;
|
||||||
|
|
||||||
impl Pixel {
|
impl Pixel {
|
||||||
|
|||||||
@@ -7,10 +7,13 @@ pub use self::events_loop::{EventLoop, EventLoopProxy};
|
|||||||
pub use self::monitor::MonitorId;
|
pub use self::monitor::MonitorId;
|
||||||
pub use self::window::Window;
|
pub use self::window::Window;
|
||||||
|
|
||||||
|
use window::Icon;
|
||||||
|
use event::DeviceId as RootDeviceId;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct PlatformSpecificWindowBuilderAttributes {
|
pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
pub parent: Option<HWND>,
|
pub parent: Option<HWND>,
|
||||||
pub taskbar_icon: Option<::Icon>,
|
pub taskbar_icon: Option<Icon>,
|
||||||
pub no_redirection_bitmap: bool,
|
pub no_redirection_bitmap: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,10 +40,10 @@ impl DeviceId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Constant device ID, to be removed when this backend is updated to report real device IDs.
|
// Constant device ID, to be removed when this backend is updated to report real device IDs.
|
||||||
const DEVICE_ID: ::DeviceId = ::DeviceId(DeviceId(0));
|
const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId(0));
|
||||||
|
|
||||||
fn wrap_device_id(id: u32) -> ::DeviceId {
|
fn wrap_device_id(id: u32) -> RootDeviceId {
|
||||||
::DeviceId(DeviceId(id))
|
RootDeviceId(DeviceId(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ use winapi::um::winuser::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use platform_impl::platform::util;
|
use platform_impl::platform::util;
|
||||||
use events::ElementState;
|
use event::ElementState;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {
|
pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {
|
||||||
|
|||||||
@@ -18,16 +18,9 @@ use winapi::um::wingdi::{CreateRectRgn, DeleteObject};
|
|||||||
use winapi::um::oleidl::LPDROPTARGET;
|
use winapi::um::oleidl::LPDROPTARGET;
|
||||||
use winapi::um::winnt::{LONG, LPCWSTR};
|
use winapi::um::winnt::{LONG, LPCWSTR};
|
||||||
|
|
||||||
use {
|
use window::{CreationError, Icon, WindowAttributes, MouseCursor};
|
||||||
CreationError,
|
use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||||
Icon,
|
use monitor::MonitorId as RootMonitorId;
|
||||||
LogicalPosition,
|
|
||||||
LogicalSize,
|
|
||||||
MonitorId as RootMonitorId,
|
|
||||||
MouseCursor,
|
|
||||||
PhysicalSize,
|
|
||||||
WindowAttributes,
|
|
||||||
};
|
|
||||||
use platform_impl::platform::{Cursor, PlatformSpecificWindowBuilderAttributes, WindowId};
|
use platform_impl::platform::{Cursor, PlatformSpecificWindowBuilderAttributes, WindowId};
|
||||||
use platform_impl::platform::dpi::{dpi_to_scale_factor, get_hwnd_dpi};
|
use platform_impl::platform::dpi::{dpi_to_scale_factor, get_hwnd_dpi};
|
||||||
use platform_impl::platform::events_loop::{self, EventLoop, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID};
|
use platform_impl::platform::events_loop::{self, EventLoop, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID};
|
||||||
|
|||||||
314
src/window.rs
314
src/window.rs
@@ -1,20 +1,160 @@
|
|||||||
use std::collections::vec_deque::IntoIter as VecDequeIter;
|
use std::{fmt, error};
|
||||||
|
|
||||||
use {
|
use platform_impl;
|
||||||
CreationError,
|
use event_loop::EventLoop;
|
||||||
EventLoop,
|
use monitor::{AvailableMonitorsIter, MonitorId};
|
||||||
Icon,
|
use dpi::{LogicalPosition, LogicalSize};
|
||||||
LogicalPosition,
|
|
||||||
LogicalSize,
|
|
||||||
MouseCursor,
|
|
||||||
PhysicalPosition,
|
|
||||||
PhysicalSize,
|
|
||||||
platform_impl,
|
|
||||||
Window,
|
|
||||||
WindowBuilder,
|
|
||||||
WindowId,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
pub use icon::*;
|
||||||
|
|
||||||
|
/// Represents a window.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use winit::window::Window;
|
||||||
|
/// use winit::event::{Event, WindowEvent};
|
||||||
|
/// use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
///
|
||||||
|
/// let mut events_loop = EventLoop::new();
|
||||||
|
/// let window = Window::new(&events_loop).unwrap();
|
||||||
|
///
|
||||||
|
/// events_loop.run(move |event, _, control_flow| {
|
||||||
|
/// match event {
|
||||||
|
/// Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
||||||
|
/// *control_flow = ControlFlow::Exit
|
||||||
|
/// },
|
||||||
|
/// _ => *control_flow = ControlFlow::Wait,
|
||||||
|
/// }
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
|
pub struct Window {
|
||||||
|
pub(crate) window: platform_impl::Window,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Window {
|
||||||
|
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
fmtr.pad("Window { .. }")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Identifier of a window. Unique for each window.
|
||||||
|
///
|
||||||
|
/// Can be obtained with `window.id()`.
|
||||||
|
///
|
||||||
|
/// Whenever you receive an event specific to a window, this event contains a `WindowId` which you
|
||||||
|
/// can then compare to the ids of your windows.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct WindowId(pub(crate) platform_impl::WindowId);
|
||||||
|
|
||||||
|
/// Object that allows you to build windows.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct WindowBuilder {
|
||||||
|
/// The attributes to use to create the window.
|
||||||
|
pub window: WindowAttributes,
|
||||||
|
|
||||||
|
// Platform-specific configuration. Private.
|
||||||
|
pub(crate) platform_specific: platform_impl::PlatformSpecificWindowBuilderAttributes,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for WindowBuilder {
|
||||||
|
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
fmtr.debug_struct("WindowBuilder")
|
||||||
|
.field("window", &self.window)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attributes to use when creating a window.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct WindowAttributes {
|
||||||
|
/// The dimensions of the window. If this is `None`, some platform-specific dimensions will be
|
||||||
|
/// used.
|
||||||
|
///
|
||||||
|
/// The default is `None`.
|
||||||
|
pub dimensions: Option<LogicalSize>,
|
||||||
|
|
||||||
|
/// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved).
|
||||||
|
///
|
||||||
|
/// The default is `None`.
|
||||||
|
pub min_dimensions: Option<LogicalSize>,
|
||||||
|
|
||||||
|
/// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
|
||||||
|
///
|
||||||
|
/// The default is `None`.
|
||||||
|
pub max_dimensions: Option<LogicalSize>,
|
||||||
|
|
||||||
|
/// Whether the window is resizable or not.
|
||||||
|
///
|
||||||
|
/// The default is `true`.
|
||||||
|
pub resizable: bool,
|
||||||
|
|
||||||
|
/// Whether the window should be set as fullscreen upon creation.
|
||||||
|
///
|
||||||
|
/// The default is `None`.
|
||||||
|
pub fullscreen: Option<MonitorId>,
|
||||||
|
|
||||||
|
/// The title of the window in the title bar.
|
||||||
|
///
|
||||||
|
/// The default is `"winit window"`.
|
||||||
|
pub title: String,
|
||||||
|
|
||||||
|
/// Whether the window should be maximized upon creation.
|
||||||
|
///
|
||||||
|
/// The default is `false`.
|
||||||
|
pub maximized: bool,
|
||||||
|
|
||||||
|
/// Whether the window should be immediately visible upon creation.
|
||||||
|
///
|
||||||
|
/// The default is `true`.
|
||||||
|
pub visible: bool,
|
||||||
|
|
||||||
|
/// Whether the the window should be transparent. If this is true, writing colors
|
||||||
|
/// with alpha values different than `1.0` will produce a transparent window.
|
||||||
|
///
|
||||||
|
/// The default is `false`.
|
||||||
|
pub transparent: bool,
|
||||||
|
|
||||||
|
/// Whether the window should have borders and bars.
|
||||||
|
///
|
||||||
|
/// The default is `true`.
|
||||||
|
pub decorations: bool,
|
||||||
|
|
||||||
|
/// Whether the window should always be on top of other windows.
|
||||||
|
///
|
||||||
|
/// The default is `false`.
|
||||||
|
pub always_on_top: bool,
|
||||||
|
|
||||||
|
/// The window icon.
|
||||||
|
///
|
||||||
|
/// The default is `None`.
|
||||||
|
pub window_icon: Option<Icon>,
|
||||||
|
|
||||||
|
/// [iOS only] Enable multitouch,
|
||||||
|
/// see [multipleTouchEnabled](https://developer.apple.com/documentation/uikit/uiview/1622519-multipletouchenabled)
|
||||||
|
pub multitouch: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WindowAttributes {
|
||||||
|
#[inline]
|
||||||
|
fn default() -> WindowAttributes {
|
||||||
|
WindowAttributes {
|
||||||
|
dimensions: None,
|
||||||
|
min_dimensions: None,
|
||||||
|
max_dimensions: None,
|
||||||
|
resizable: true,
|
||||||
|
title: "winit window".to_owned(),
|
||||||
|
maximized: false,
|
||||||
|
fullscreen: None,
|
||||||
|
visible: true,
|
||||||
|
transparent: false,
|
||||||
|
decorations: true,
|
||||||
|
always_on_top: false,
|
||||||
|
window_icon: None,
|
||||||
|
multitouch: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl WindowBuilder {
|
impl WindowBuilder {
|
||||||
/// Initializes a new `WindowBuilder` with default values.
|
/// Initializes a new `WindowBuilder` with default values.
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -444,66 +584,94 @@ impl Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator for the list of available monitors.
|
/// Error that can happen while creating a window or a headless renderer.
|
||||||
// Implementation note: we retrieve the list once, then serve each element by one by one.
|
|
||||||
// This may change in the future.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct AvailableMonitorsIter {
|
|
||||||
pub(crate) data: VecDequeIter<platform_impl::MonitorId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for AvailableMonitorsIter {
|
|
||||||
type Item = MonitorId;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<MonitorId> {
|
|
||||||
self.data.next().map(|id| MonitorId { inner: id })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
self.data.size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Identifier for a monitor.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MonitorId {
|
pub enum CreationError {
|
||||||
pub(crate) inner: platform_impl::MonitorId
|
OsError(String),
|
||||||
|
/// TODO: remove this error
|
||||||
|
NotSupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitorId {
|
impl CreationError {
|
||||||
/// Returns a human-readable name of the monitor.
|
fn to_string(&self) -> &str {
|
||||||
///
|
match *self {
|
||||||
/// Returns `None` if the monitor doesn't exist anymore.
|
CreationError::OsError(ref text) => &text,
|
||||||
#[inline]
|
CreationError::NotSupported => "Some of the requested attributes are not supported",
|
||||||
pub fn get_name(&self) -> Option<String> {
|
}
|
||||||
self.inner.get_name()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the monitor's resolution.
|
impl fmt::Display for CreationError {
|
||||||
#[inline]
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
formatter.write_str(self.to_string())
|
||||||
self.inner.get_dimensions()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the top-left corner position of the monitor relative to the larger full
|
impl error::Error for CreationError {
|
||||||
/// screen area.
|
fn description(&self) -> &str {
|
||||||
#[inline]
|
self.to_string()
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
}
|
||||||
self.inner.get_position()
|
}
|
||||||
}
|
|
||||||
|
/// Describes the appearance of the mouse cursor.
|
||||||
/// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa.
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
///
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
/// See the [`dpi`](dpi/index.html) module for more information.
|
pub enum MouseCursor {
|
||||||
///
|
/// The platform-dependent default cursor.
|
||||||
/// ## Platform-specific
|
Default,
|
||||||
///
|
/// A simple crosshair.
|
||||||
/// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
|
Crosshair,
|
||||||
/// - **Android:** Always returns 1.0.
|
/// A hand (often used to indicate links in web browsers).
|
||||||
#[inline]
|
Hand,
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
/// Self explanatory.
|
||||||
self.inner.get_hidpi_factor()
|
Arrow,
|
||||||
|
/// Indicates something is to be moved.
|
||||||
|
Move,
|
||||||
|
/// Indicates text that may be selected or edited.
|
||||||
|
Text,
|
||||||
|
/// Program busy indicator.
|
||||||
|
Wait,
|
||||||
|
/// Help indicator (often rendered as a "?")
|
||||||
|
Help,
|
||||||
|
/// Progress indicator. Shows that processing is being done. But in contrast
|
||||||
|
/// with "Wait" the user may still interact with the program. Often rendered
|
||||||
|
/// as a spinning beach ball, or an arrow with a watch or hourglass.
|
||||||
|
Progress,
|
||||||
|
|
||||||
|
/// Cursor showing that something cannot be done.
|
||||||
|
NotAllowed,
|
||||||
|
ContextMenu,
|
||||||
|
Cell,
|
||||||
|
VerticalText,
|
||||||
|
Alias,
|
||||||
|
Copy,
|
||||||
|
NoDrop,
|
||||||
|
Grab,
|
||||||
|
Grabbing,
|
||||||
|
AllScroll,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
|
|
||||||
|
/// Indicate that some edge is to be moved. For example, the 'SeResize' cursor
|
||||||
|
/// is used when the movement starts from the south-east corner of the box.
|
||||||
|
EResize,
|
||||||
|
NResize,
|
||||||
|
NeResize,
|
||||||
|
NwResize,
|
||||||
|
SResize,
|
||||||
|
SeResize,
|
||||||
|
SwResize,
|
||||||
|
WResize,
|
||||||
|
EwResize,
|
||||||
|
NsResize,
|
||||||
|
NeswResize,
|
||||||
|
NwseResize,
|
||||||
|
ColResize,
|
||||||
|
RowResize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MouseCursor {
|
||||||
|
fn default() -> Self {
|
||||||
|
MouseCursor::Default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ fn needs_send<T:Send>() {}
|
|||||||
#[test]
|
#[test]
|
||||||
fn events_loop_proxy_send() {
|
fn events_loop_proxy_send() {
|
||||||
// ensures that `winit::EventLoopProxy` implements `Send`
|
// ensures that `winit::EventLoopProxy` implements `Send`
|
||||||
needs_send::<winit::EventLoopProxy<()>>();
|
needs_send::<winit::event_loop::EventLoopProxy<()>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn window_send() {
|
fn window_send() {
|
||||||
// ensures that `winit::Window` implements `Send`
|
// ensures that `winit::Window` implements `Send`
|
||||||
needs_send::<winit::Window>();
|
needs_send::<winit::window::Window>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ids_send() {
|
fn ids_send() {
|
||||||
// ensures that the various `..Id` types implement `Send`
|
// ensures that the various `..Id` types implement `Send`
|
||||||
needs_send::<winit::WindowId>();
|
needs_send::<winit::window::WindowId>();
|
||||||
needs_send::<winit::DeviceId>();
|
needs_send::<winit::event::DeviceId>();
|
||||||
needs_send::<winit::MonitorId>();
|
needs_send::<winit::monitor::MonitorId>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ fn needs_sync<T:Sync>() {}
|
|||||||
#[test]
|
#[test]
|
||||||
fn window_sync() {
|
fn window_sync() {
|
||||||
// ensures that `winit::Window` implements `Sync`
|
// ensures that `winit::Window` implements `Sync`
|
||||||
needs_sync::<winit::Window>();
|
needs_sync::<winit::window::Window>();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user