Refine function names and type signatures (#886)

* First name consistency pass. More to come!

* Remove multitouch variable (hopefully this compiles!)

* Remove CreationError::NotSupported

* Add new error handling types

* Remove `get_` prefix from getters.

This is as per the Rust naming conventions recommended in
https://rust-lang-nursery.github.io/api-guidelines/naming.html#getter-names-follow-rust-convention-c-getter

* Make changes to Window position and size function signatures

* Remove CreationError in favor of OsError

* Begin updating iOS backend

* Change MonitorHandle::outer_position to just position

* Fix build on Windows and Linux

* Add Display and Error implementations to Error types

* Attempt to fix iOS build.

I can't actually check that this works since I can't cross-compile to
iOS on a Windows machine (thanks apple :/) but this should be one of
several commits to get it working.

* Attempt to fix iOS errors, and muck up Travis to make debugging easier

* More iOS fixins

* Add Debug and Display impls to OsError

* Fix Display impl

* Fix unused code warnings and travis

* Rename set_ime_spot to set_ime_position

* Add CHANGELOG entry

* Rename set_cursor to set_cursor_icon and MouseCursor to CursorIcon

* Organize Window functions into multiple, categorized impls

* Improve clarity of function ordering and docs in EventLoop
This commit is contained in:
Osspial 2019-05-29 21:29:54 -04:00 committed by GitHub
parent ae63fbdbbb
commit 0df436901a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 1249 additions and 1250 deletions

View file

@ -37,6 +37,8 @@
- `LoopDestroyed` is emitted when the `run` or `run_return` method is about to exit. - `LoopDestroyed` is emitted when the `run` or `run_return` method is about to exit.
- Rename `MonitorId` to `MonitorHandle`. - Rename `MonitorId` to `MonitorHandle`.
- Removed `serde` implementations from `ControlFlow`. - Removed `serde` implementations from `ControlFlow`.
- Rename several functions to improve both internal consistency and compliance with Rust API guidelines.
- Remove `WindowBuilder::multitouch` field, since it was only implemented on a few platforms. Multitouch is always enabled now.
# Version 0.19.1 (2019-04-08) # Version 0.19.1 (2019-04-08)

View file

@ -1,6 +1,6 @@
extern crate winit; extern crate winit;
use winit::window::{WindowBuilder, MouseCursor}; use winit::window::{WindowBuilder, CursorIcon};
use winit::event::{Event, WindowEvent, ElementState, KeyboardInput}; use winit::event::{Event, WindowEvent, ElementState, KeyboardInput};
use winit::event_loop::{EventLoop, ControlFlow}; use winit::event_loop::{EventLoop, ControlFlow};
@ -16,7 +16,7 @@ fn main() {
match event { match event {
Event::WindowEvent { event: WindowEvent::KeyboardInput { input: KeyboardInput { state: ElementState::Pressed, .. }, .. }, .. } => { Event::WindowEvent { event: WindowEvent::KeyboardInput { input: KeyboardInput { state: ElementState::Pressed, .. }, .. }, .. } => {
println!("Setting cursor to \"{:?}\"", CURSORS[cursor_idx]); println!("Setting cursor to \"{:?}\"", CURSORS[cursor_idx]);
window.set_cursor(CURSORS[cursor_idx]); window.set_cursor_icon(CURSORS[cursor_idx]);
if cursor_idx < CURSORS.len() - 1 { if cursor_idx < CURSORS.len() - 1 {
cursor_idx += 1; cursor_idx += 1;
} else { } else {
@ -32,17 +32,17 @@ fn main() {
}); });
} }
const CURSORS: &[MouseCursor] = &[ const CURSORS: &[CursorIcon] = &[
MouseCursor::Default, MouseCursor::Crosshair, MouseCursor::Hand, CursorIcon::Default, CursorIcon::Crosshair, CursorIcon::Hand,
MouseCursor::Arrow, MouseCursor::Move, MouseCursor::Text, CursorIcon::Arrow, CursorIcon::Move, CursorIcon::Text,
MouseCursor::Wait, MouseCursor::Help, MouseCursor::Progress, CursorIcon::Wait, CursorIcon::Help, CursorIcon::Progress,
MouseCursor::NotAllowed, MouseCursor::ContextMenu, MouseCursor::Cell, CursorIcon::NotAllowed, CursorIcon::ContextMenu, CursorIcon::Cell,
MouseCursor::VerticalText, MouseCursor::Alias, MouseCursor::Copy, CursorIcon::VerticalText, CursorIcon::Alias, CursorIcon::Copy,
MouseCursor::NoDrop, MouseCursor::Grab, MouseCursor::Grabbing, CursorIcon::NoDrop, CursorIcon::Grab, CursorIcon::Grabbing,
MouseCursor::AllScroll, MouseCursor::ZoomIn, MouseCursor::ZoomOut, CursorIcon::AllScroll, CursorIcon::ZoomIn, CursorIcon::ZoomOut,
MouseCursor::EResize, MouseCursor::NResize, MouseCursor::NeResize, CursorIcon::EResize, CursorIcon::NResize, CursorIcon::NeResize,
MouseCursor::NwResize, MouseCursor::SResize, MouseCursor::SeResize, CursorIcon::NwResize, CursorIcon::SResize, CursorIcon::SeResize,
MouseCursor::SwResize, MouseCursor::WResize, MouseCursor::EwResize, CursorIcon::SwResize, CursorIcon::WResize, CursorIcon::EwResize,
MouseCursor::NsResize, MouseCursor::NeswResize, MouseCursor::NwseResize, CursorIcon::NsResize, CursorIcon::NeswResize, CursorIcon::NwseResize,
MouseCursor::ColResize, MouseCursor::RowResize CursorIcon::ColResize, CursorIcon::RowResize
]; ];

View file

@ -29,8 +29,8 @@ fn main() {
use winit::event::VirtualKeyCode::*; use winit::event::VirtualKeyCode::*;
match key { match key {
Escape => *control_flow = ControlFlow::Exit, Escape => *control_flow = ControlFlow::Exit,
G => window.grab_cursor(!modifiers.shift).unwrap(), G => window.set_cursor_grab(!modifiers.shift).unwrap(),
H => window.hide_cursor(!modifiers.shift), H => window.set_cursor_visible(modifiers.shift),
_ => (), _ => (),
} }
} }

View file

@ -82,16 +82,16 @@ fn main() {
if !is_fullscreen { if !is_fullscreen {
window.set_fullscreen(None); window.set_fullscreen(None);
} else { } else {
window.set_fullscreen(Some(window.get_current_monitor())); window.set_fullscreen(Some(window.current_monitor()));
} }
} }
(VirtualKeyCode::S, ElementState::Pressed) => { (VirtualKeyCode::S, ElementState::Pressed) => {
println!("window.get_fullscreen {:?}", window.get_fullscreen()); println!("window.fullscreen {:?}", window.fullscreen());
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
use winit::platform::macos::WindowExtMacOS; use winit::platform::macos::WindowExtMacOS;
println!("window.get_simple_fullscreen {:?}", WindowExtMacOS::get_simple_fullscreen(&window)); println!("window.simple_fullscreen {:?}", WindowExtMacOS::simple_fullscreen(&window));
} }
} }
(VirtualKeyCode::M, ElementState::Pressed) => { (VirtualKeyCode::M, ElementState::Pressed) => {
@ -113,8 +113,8 @@ fn main() {
// Enumerate monitors and prompt user to choose one // Enumerate monitors and prompt user to choose one
fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle { fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle {
for (num, monitor) in event_loop.get_available_monitors().enumerate() { for (num, monitor) in event_loop.available_monitors().enumerate() {
println!("Monitor #{}: {:?}", num, monitor.get_name()); println!("Monitor #{}: {:?}", num, monitor.name());
} }
print!("Please write the number of the monitor to use: "); print!("Please write the number of the monitor to use: ");
@ -123,9 +123,9 @@ fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle {
let mut num = String::new(); let mut num = String::new();
io::stdin().read_line(&mut num).unwrap(); io::stdin().read_line(&mut num).unwrap();
let num = num.trim().parse().ok().expect("Please enter a number"); let num = num.trim().parse().ok().expect("Please enter a number");
let monitor = event_loop.get_available_monitors().nth(num).expect("Please enter a valid ID"); let monitor = event_loop.available_monitors().nth(num).expect("Please enter a valid ID");
println!("Using {:?}", monitor.get_name()); println!("Using {:?}", monitor.name());
monitor monitor
} }

View file

@ -12,8 +12,8 @@ fn main() {
.build(&event_loop) .build(&event_loop)
.unwrap(); .unwrap();
window.set_min_dimensions(Some(LogicalSize::new(400.0, 200.0))); window.set_min_inner_size(Some(LogicalSize::new(400.0, 200.0)));
window.set_max_dimensions(Some(LogicalSize::new(800.0, 400.0))); window.set_max_inner_size(Some(LogicalSize::new(800.0, 400.0)));
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
println!("{:?}", event); println!("{:?}", event);

View file

@ -5,5 +5,5 @@ use winit::window::WindowBuilder;
fn main() { fn main() {
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
let window = 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.available_monitors(), window.primary_monitor());
} }

View file

@ -5,7 +5,7 @@ use std::{collections::HashMap, sync::mpsc, thread, time::Duration};
use winit::{ use winit::{
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}, event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
event_loop::{ControlFlow, EventLoop}, window::{MouseCursor, WindowBuilder}, event_loop::{ControlFlow, EventLoop}, window::{CursorIcon, WindowBuilder},
}; };
const WINDOW_COUNT: usize = 3; const WINDOW_COUNT: usize = 3;
@ -17,7 +17,7 @@ fn main() {
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT); let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
for _ in 0..WINDOW_COUNT { for _ in 0..WINDOW_COUNT {
let window = WindowBuilder::new() let window = WindowBuilder::new()
.with_dimensions(WINDOW_SIZE.into()) .with_inner_size(WINDOW_SIZE.into())
.build(&event_loop) .build(&event_loop)
.unwrap(); .unwrap();
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
@ -36,31 +36,31 @@ fn main() {
use self::VirtualKeyCode::*; use self::VirtualKeyCode::*;
match key { match key {
A => window.set_always_on_top(state), A => window.set_always_on_top(state),
C => window.set_cursor(match state { C => window.set_cursor_icon(match state {
true => MouseCursor::Progress, true => CursorIcon::Progress,
false => MouseCursor::Default, false => CursorIcon::Default,
}), }),
D => window.set_decorations(!state), D => window.set_decorations(!state),
F => window.set_fullscreen(match state { F => window.set_fullscreen(match state {
true => Some(window.get_current_monitor()), true => Some(window.current_monitor()),
false => None, false => None,
}), }),
G => window.grab_cursor(state).unwrap(), G => window.set_cursor_grab(state).unwrap(),
H => window.hide_cursor(state), H => window.set_cursor_visible(!state),
I => { I => {
println!("Info:"); println!("Info:");
println!("-> position : {:?}", window.get_position()); println!("-> outer_position : {:?}", window.outer_position());
println!("-> inner_position : {:?}", window.get_inner_position()); println!("-> inner_position : {:?}", window.inner_position());
println!("-> outer_size : {:?}", window.get_outer_size()); println!("-> outer_size : {:?}", window.outer_size());
println!("-> inner_size : {:?}", window.get_inner_size()); println!("-> inner_size : {:?}", window.inner_size());
}, },
L => window.set_min_dimensions(match state { L => window.set_min_inner_size(match state {
true => Some(WINDOW_SIZE.into()), true => Some(WINDOW_SIZE.into()),
false => None, false => None,
}), }),
M => window.set_maximized(state), M => window.set_maximized(state),
P => window.set_position({ P => window.set_outer_position({
let mut position = window.get_position().unwrap(); let mut position = window.outer_position().unwrap();
let sign = if state { 1.0 } else { -1.0 }; let sign = if state { 1.0 } else { -1.0 };
position.x += 10.0 * sign; position.x += 10.0 * sign;
position.y += 10.0 * sign; position.y += 10.0 * sign;
@ -77,9 +77,9 @@ fn main() {
WINDOW_SIZE.1 as i32 / 2, WINDOW_SIZE.1 as i32 / 2,
).into()).unwrap(), ).into()).unwrap(),
Z => { Z => {
window.hide(); window.set_visible(false);
thread::sleep(Duration::from_secs(1)); thread::sleep(Duration::from_secs(1));
window.show(); window.set_visible(true);
}, },
_ => (), _ => (),
} }

View file

@ -10,7 +10,7 @@ fn main() {
let window = 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_inner_size((400, 200).into())
.with_resizable(resizable) .with_resizable(resizable)
.build(&event_loop) .build(&event_loop)
.unwrap(); .unwrap();

View file

@ -33,10 +33,10 @@
//! windows. This event is sent any time the DPI factor changes, either because the window moved to another monitor, //! windows. This event is sent any time the DPI factor changes, either because the window moved to another monitor,
//! or because the user changed the configuration of their screen. //! or because the user changed the configuration of their screen.
//! - You can also retrieve the DPI factor of a monitor by calling //! - You can also retrieve the DPI factor of a monitor by calling
//! [`MonitorHandle::get_hidpi_factor`](../monitor/struct.MonitorHandle.html#method.get_hidpi_factor), or the //! [`MonitorHandle::hidpi_factor`](../monitor/struct.MonitorHandle.html#method.hidpi_factor), or the
//! current DPI factor applied to a window by calling //! current DPI factor applied to a window by calling
//! [`Window::get_hidpi_factor`](../window/struct.Window.html#method.get_hidpi_factor), which is roughly equivalent //! [`Window::hidpi_factor`](../window/struct.Window.html#method.hidpi_factor), which is roughly equivalent
//! to `window.get_current_monitor().get_hidpi_factor()`. //! to `window.current_monitor().hidpi_factor()`.
//! //!
//! Depending on the platform, the window's actual DPI factor may only be known after //! Depending on the platform, the window's actual DPI factor may only be known after
//! the event loop has started and your window has been drawn once. To properly handle these cases, //! the event loop has started and your window has been drawn once. To properly handle these cases,

86
src/error.rs Normal file
View file

@ -0,0 +1,86 @@
use std::fmt;
use std::error;
use platform_impl;
/// An error whose cause it outside Winit's control.
#[derive(Debug)]
pub enum ExternalError {
/// The operation is not supported by the backend.
NotSupported(NotSupportedError),
/// The OS cannot perform the operation.
Os(OsError),
}
/// The error type for when the requested operation is not supported by the backend.
#[derive(Clone)]
pub struct NotSupportedError {
_marker: (),
}
/// The error type for when the OS cannot perform the requested operation.
#[derive(Debug)]
pub struct OsError {
line: u32,
file: &'static str,
error: platform_impl::OsError,
}
impl NotSupportedError {
#[inline]
#[allow(dead_code)]
pub(crate) fn new() -> NotSupportedError {
NotSupportedError {
_marker: ()
}
}
}
impl OsError {
#[allow(dead_code)]
pub(crate) fn new(line: u32, file: &'static str, error: platform_impl::OsError) -> OsError {
OsError {
line,
file,
error,
}
}
}
#[allow(unused_macros)]
macro_rules! os_error {
($error:expr) => {{
crate::error::OsError::new(line!(), file!(), $error)
}}
}
impl fmt::Display for OsError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.pad(&format!("os error at {}:{}: {}", self.file, self.line, self.error))
}
}
impl fmt::Display for ExternalError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
ExternalError::NotSupported(e) => e.fmt(formatter),
ExternalError::Os(e) => e.fmt(formatter),
}
}
}
impl fmt::Debug for NotSupportedError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.debug_struct("NotSupportedError").finish()
}
}
impl fmt::Display for NotSupportedError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.pad("the requested operation is not supported by Winit")
}
}
impl error::Error for OsError {}
impl error::Error for ExternalError {}
impl error::Error for NotSupportedError {}

View file

@ -94,9 +94,9 @@ impl Default for ControlFlow {
impl EventLoop<()> { impl EventLoop<()> {
/// Builds a new event loop with a `()` as the user event type. /// Builds a new event loop with a `()` as the user event type.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Can only be called on the main thread. /// - **iOS:** Can only be called on the main thread.
pub fn new() -> EventLoop<()> { pub fn new() -> EventLoop<()> {
EventLoop::<()>::new_user_event() EventLoop::<()>::new_user_event()
@ -110,9 +110,9 @@ impl<T> EventLoop<T> {
/// using an environment variable `WINIT_UNIX_BACKEND`. Legal values are `x11` and `wayland`. /// 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 /// 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. /// fallback on x11. If this variable is set with any other value, winit will panic.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Can only be called on the main thread. /// - **iOS:** Can only be called on the main thread.
pub fn new_user_event() -> EventLoop<T> { pub fn new_user_event() -> EventLoop<T> {
EventLoop { EventLoop {
@ -121,21 +121,6 @@ impl<T> EventLoop<T> {
} }
} }
/// 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.event_loop.get_available_monitors();
AvailableMonitorsIter{ data: data.into_iter() }
}
/// Returns the primary monitor of the system.
#[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle {
MonitorHandle { inner: self.event_loop.get_primary_monitor() }
}
/// Hijacks the calling thread and initializes the `winit` event loop with the provided /// Hijacks the calling thread and initializes the `winit` event loop with the provided
/// closure. Since the closure is `'static`, it must be a `move` closure if it needs to /// closure. Since the closure is `'static`, it must be a `move` closure if it needs to
/// access any data from the calling context. /// access any data from the calling context.
@ -153,13 +138,27 @@ impl<T> EventLoop<T> {
self.event_loop.run(event_handler) self.event_loop.run(event_handler)
} }
/// Creates an `EventLoopProxy` that can be used to wake up the `EventLoop` from another /// Creates an `EventLoopProxy` that can be used to dispatch user events to the main event loop.
/// thread.
pub fn create_proxy(&self) -> EventLoopProxy<T> { pub fn create_proxy(&self) -> EventLoopProxy<T> {
EventLoopProxy { EventLoopProxy {
event_loop_proxy: self.event_loop.create_proxy(), event_loop_proxy: self.event_loop.create_proxy(),
} }
} }
/// Returns the list of all the monitors available on the system.
///
// Note: should be replaced with `-> impl Iterator` once stable.
#[inline]
pub fn available_monitors(&self) -> AvailableMonitorsIter {
let data = self.event_loop.available_monitors();
AvailableMonitorsIter{ data: data.into_iter() }
}
/// Returns the primary monitor of the system.
#[inline]
pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle { inner: self.event_loop.primary_monitor() }
}
} }
impl<T> Deref for EventLoop<T> { impl<T> Deref for EventLoop<T> {

View file

@ -113,6 +113,8 @@ extern crate smithay_client_toolkit as sctk;
extern crate calloop; extern crate calloop;
pub mod dpi; pub mod dpi;
#[macro_use]
pub mod error;
pub mod event; pub mod event;
pub mod event_loop; pub mod event_loop;
mod icon; mod icon;

View file

@ -3,13 +3,13 @@
//! If you want to get basic information about a monitor, you can use the [`MonitorHandle`][monitor_id] //! If you want to get basic information about a monitor, you can use the [`MonitorHandle`][monitor_id]
//! type. This is retreived from an [`AvailableMonitorsIter`][monitor_iter], which can be acquired //! type. This is retreived from an [`AvailableMonitorsIter`][monitor_iter], which can be acquired
//! with: //! with:
//! - [`EventLoop::get_available_monitors`][loop_get] //! - [`EventLoop::available_monitors`][loop_get]
//! - [`Window::get_available_monitors`][window_get]. //! - [`Window::available_monitors`][window_get].
//! //!
//! [monitor_id]: ./struct.MonitorHandle.html //! [monitor_id]: ./struct.MonitorHandle.html
//! [monitor_iter]: ./struct.AvailableMonitorsIter.html //! [monitor_iter]: ./struct.AvailableMonitorsIter.html
//! [loop_get]: ../event_loop/struct.EventLoop.html#method.get_available_monitors //! [loop_get]: ../event_loop/struct.EventLoop.html#method.available_monitors
//! [window_get]: ../window/struct.Window.html#method.get_available_monitors //! [window_get]: ../window/struct.Window.html#method.available_monitors
use std::collections::vec_deque::IntoIter as VecDequeIter; use std::collections::vec_deque::IntoIter as VecDequeIter;
use platform_impl; use platform_impl;
@ -18,11 +18,11 @@ use dpi::{PhysicalPosition, PhysicalSize};
/// An iterator over all available monitors. /// An iterator over all available monitors.
/// ///
/// Can be acquired with: /// Can be acquired with:
/// - [`EventLoop::get_available_monitors`][loop_get] /// - [`EventLoop::available_monitors`][loop_get]
/// - [`Window::get_available_monitors`][window_get]. /// - [`Window::available_monitors`][window_get].
/// ///
/// [loop_get]: ../event_loop/struct.EventLoop.html#method.get_available_monitors /// [loop_get]: ../event_loop/struct.EventLoop.html#method.available_monitors
/// [window_get]: ../window/struct.Window.html#method.get_available_monitors /// [window_get]: ../window/struct.Window.html#method.available_monitors
// Implementation note: we retrieve the list once, then serve each element by one by one. // Implementation note: we retrieve the list once, then serve each element by one by one.
// This may change in the future. // This may change in the future.
#[derive(Debug)] #[derive(Debug)]
@ -59,21 +59,21 @@ impl MonitorHandle {
/// ///
/// Returns `None` if the monitor doesn't exist anymore. /// Returns `None` if the monitor doesn't exist anymore.
#[inline] #[inline]
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
self.inner.get_name() self.inner.name()
} }
/// Returns the monitor's resolution. /// Returns the monitor's resolution.
#[inline] #[inline]
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
self.inner.get_dimensions() self.inner.dimensions()
} }
/// Returns the top-left corner position of the monitor relative to the larger full /// Returns the top-left corner position of the monitor relative to the larger full
/// screen area. /// screen area.
#[inline] #[inline]
pub fn get_position(&self) -> PhysicalPosition { pub fn position(&self) -> PhysicalPosition {
self.inner.get_position() self.inner.position()
} }
/// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa. /// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa.
@ -85,7 +85,7 @@ impl MonitorHandle {
/// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable. /// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
/// - **Android:** Always returns 1.0. /// - **Android:** Always returns 1.0.
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
self.inner.get_hidpi_factor() self.inner.hidpi_factor()
} }
} }

View file

@ -19,13 +19,13 @@ impl EventLoopExtAndroid for EventLoop {
/// Additional methods on `Window` that are specific to Android. /// Additional methods on `Window` that are specific to Android.
pub trait WindowExtAndroid { pub trait WindowExtAndroid {
fn get_native_window(&self) -> *const c_void; fn native_window(&self) -> *const c_void;
} }
impl WindowExtAndroid for Window { impl WindowExtAndroid for Window {
#[inline] #[inline]
fn get_native_window(&self) -> *const c_void { fn native_window(&self) -> *const c_void {
self.window.get_native_window() self.window.native_window()
} }
} }

View file

@ -9,12 +9,12 @@ use window::{Window, WindowBuilder};
/// Additional methods on `EventLoop` that are specific to iOS. /// Additional methods on `EventLoop` that are specific to iOS.
pub trait EventLoopExtIOS { pub trait EventLoopExtIOS {
/// Returns the idiom (phone/tablet/tv/etc) for the current device. /// Returns the idiom (phone/tablet/tv/etc) for the current device.
fn get_idiom(&self) -> Idiom; fn idiom(&self) -> Idiom;
} }
impl<T: 'static> EventLoopExtIOS for EventLoop<T> { impl<T: 'static> EventLoopExtIOS for EventLoop<T> {
fn get_idiom(&self) -> Idiom { fn idiom(&self) -> Idiom {
self.event_loop.get_idiom() self.event_loop.idiom()
} }
} }
@ -23,43 +23,43 @@ pub trait WindowExtIOS {
/// Returns a pointer to the `UIWindow` that is used by this window. /// Returns a pointer to the `UIWindow` that is used by this window.
/// ///
/// The pointer will become invalid when the `Window` is destroyed. /// The pointer will become invalid when the `Window` is destroyed.
fn get_uiwindow(&self) -> *mut c_void; fn ui_window(&self) -> *mut c_void;
/// Returns a pointer to the `UIViewController` that is used by this window. /// Returns a pointer to the `UIViewController` that is used by this window.
/// ///
/// The pointer will become invalid when the `Window` is destroyed. /// The pointer will become invalid when the `Window` is destroyed.
fn get_uiviewcontroller(&self) -> *mut c_void; fn ui_view_controller(&self) -> *mut c_void;
/// Returns a pointer to the `UIView` that is used by this window. /// Returns a pointer to the `UIView` that is used by this window.
/// ///
/// The pointer will become invalid when the `Window` is destroyed. /// The pointer will become invalid when the `Window` is destroyed.
fn get_uiview(&self) -> *mut c_void; fn ui_view(&self) -> *mut c_void;
/// Sets the HiDpi factor used by this window. /// Sets the HiDpi factor used by this window.
/// ///
/// This translates to `-[UIWindow setContentScaleFactor:hidpi_factor]`. /// This translates to `-[UIWindow setContentScaleFactor:hidpi_factor]`.
fn set_hidpi_factor(&self, hidpi_factor: f64); fn set_hidpi_factor(&self, hidpi_factor: f64);
/// Sets the valid orientations for screens showing this `Window`. /// Sets the valid orientations for screens showing this `Window`.
/// ///
/// On iPhones and iPods upside down portrait is never enabled. /// On iPhones and iPods upside down portrait is never enabled.
fn set_valid_orientations(&self, valid_orientations: ValidOrientations); fn set_valid_orientations(&self, valid_orientations: ValidOrientations);
} }
impl WindowExtIOS for Window { impl WindowExtIOS for Window {
#[inline] #[inline]
fn get_uiwindow(&self) -> *mut c_void { fn ui_window(&self) -> *mut c_void {
self.window.get_uiwindow() as _ self.window.ui_window() as _
} }
#[inline] #[inline]
fn get_uiviewcontroller(&self) -> *mut c_void { fn ui_view_controller(&self) -> *mut c_void {
self.window.get_uiviewcontroller() as _ self.window.ui_view_controller() as _
} }
#[inline] #[inline]
fn get_uiview(&self) -> *mut c_void { fn ui_view(&self) -> *mut c_void {
self.window.get_uiview() as _ self.window.ui_view() as _
} }
#[inline] #[inline]
@ -79,13 +79,13 @@ pub trait WindowBuilderExtIOS {
/// ///
/// The class will be initialized by calling `[root_view initWithFrame:CGRect]` /// The class will be initialized by calling `[root_view initWithFrame:CGRect]`
fn with_root_view_class(self, root_view_class: *const c_void) -> WindowBuilder; fn with_root_view_class(self, root_view_class: *const c_void) -> WindowBuilder;
/// Sets the `contentScaleFactor` of the underlying `UIWindow` to `hidpi_factor`. /// Sets the `contentScaleFactor` of the underlying `UIWindow` to `hidpi_factor`.
/// ///
/// The default value is device dependent, and it's recommended GLES or Metal applications set /// The default value is device dependent, and it's recommended GLES or Metal applications set
/// this to `MonitorHandle::get_hidpi_factor()`. /// this to `MonitorHandle::hidpi_factor()`.
fn with_hidpi_factor(self, hidpi_factor: f64) -> WindowBuilder; fn with_hidpi_factor(self, hidpi_factor: f64) -> WindowBuilder;
/// Sets the valid orientations for the `Window`. /// Sets the valid orientations for the `Window`.
fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> WindowBuilder; fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> WindowBuilder;
} }
@ -113,13 +113,13 @@ impl WindowBuilderExtIOS for WindowBuilder {
/// Additional methods on `MonitorHandle` that are specific to iOS. /// Additional methods on `MonitorHandle` that are specific to iOS.
pub trait MonitorHandleExtIOS { pub trait MonitorHandleExtIOS {
/// Returns a pointer to the `UIScreen` that is used by this monitor. /// Returns a pointer to the `UIScreen` that is used by this monitor.
fn get_uiscreen(&self) -> *mut c_void; fn ui_screen(&self) -> *mut c_void;
} }
impl MonitorHandleExtIOS for MonitorHandle { impl MonitorHandleExtIOS for MonitorHandle {
#[inline] #[inline]
fn get_uiscreen(&self) -> *mut c_void { fn ui_screen(&self) -> *mut c_void {
self.inner.get_uiscreen() as _ self.inner.ui_screen() as _
} }
} }
@ -130,7 +130,7 @@ pub enum ValidOrientations {
LandscapeAndPortrait, LandscapeAndPortrait,
Landscape, Landscape,
/// Excludes `PortraitUpsideDown` on iphone /// Excludes `PortraitUpsideDown` on iphone
Portrait, Portrait,
} }
@ -143,7 +143,7 @@ impl Default for ValidOrientations {
} }
/// The device [idiom]. /// The device [idiom].
/// ///
/// [idiom]: https://developer.apple.com/documentation/uikit/uidevice/1620037-userinterfaceidiom?language=objc /// [idiom]: https://developer.apple.com/documentation/uikit/uidevice/1620037-userinterfaceidiom?language=objc
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Idiom { pub enum Idiom {

View file

@ -11,12 +11,12 @@ pub trait WindowExtMacOS {
/// Returns a pointer to the cocoa `NSWindow` that is used by this window. /// Returns a pointer to the cocoa `NSWindow` that is used by this window.
/// ///
/// The pointer will become invalid when the `Window` is destroyed. /// The pointer will become invalid when the `Window` is destroyed.
fn get_nswindow(&self) -> *mut c_void; fn nswindow(&self) -> *mut c_void;
/// Returns a pointer to the cocoa `NSView` that is used by this window. /// Returns a pointer to the cocoa `NSView` that is used by this window.
/// ///
/// The pointer will become invalid when the `Window` is destroyed. /// The pointer will become invalid when the `Window` is destroyed.
fn get_nsview(&self) -> *mut c_void; fn nsview(&self) -> *mut c_void;
/// Request user attention, causing the application's dock icon to bounce. /// Request user attention, causing the application's dock icon to bounce.
/// Note that this has no effect if the application is already focused. /// Note that this has no effect if the application is already focused.
@ -27,7 +27,7 @@ pub trait WindowExtMacOS {
fn request_user_attention(&self, is_critical: bool); fn request_user_attention(&self, is_critical: bool);
/// Returns whether or not the window is in simple fullscreen mode. /// Returns whether or not the window is in simple fullscreen mode.
fn get_simple_fullscreen(&self) -> bool; fn simple_fullscreen(&self) -> bool;
/// Toggles a fullscreen mode that doesn't require a new macOS space. /// Toggles a fullscreen mode that doesn't require a new macOS space.
/// Returns a boolean indicating whether the transition was successful (this /// Returns a boolean indicating whether the transition was successful (this
@ -41,13 +41,13 @@ pub trait WindowExtMacOS {
impl WindowExtMacOS for Window { impl WindowExtMacOS for Window {
#[inline] #[inline]
fn get_nswindow(&self) -> *mut c_void { fn nswindow(&self) -> *mut c_void {
self.window.get_nswindow() self.window.nswindow()
} }
#[inline] #[inline]
fn get_nsview(&self) -> *mut c_void { fn nsview(&self) -> *mut c_void {
self.window.get_nsview() self.window.nsview()
} }
#[inline] #[inline]
@ -56,8 +56,8 @@ impl WindowExtMacOS for Window {
} }
#[inline] #[inline]
fn get_simple_fullscreen(&self) -> bool { fn simple_fullscreen(&self) -> bool {
self.window.get_simple_fullscreen() self.window.simple_fullscreen()
} }
#[inline] #[inline]
@ -167,16 +167,16 @@ pub trait MonitorHandleExtMacOS {
/// Returns the identifier of the monitor for Cocoa. /// Returns the identifier of the monitor for Cocoa.
fn native_id(&self) -> u32; fn native_id(&self) -> u32;
/// Returns a pointer to the NSScreen representing this monitor. /// Returns a pointer to the NSScreen representing this monitor.
fn get_nsscreen(&self) -> Option<*mut c_void>; fn nsscreen(&self) -> Option<*mut c_void>;
} }
impl MonitorHandleExtMacOS for MonitorHandle { impl MonitorHandleExtMacOS for MonitorHandle {
#[inline] #[inline]
fn native_id(&self) -> u32 { fn native_id(&self) -> u32 {
self.inner.get_native_identifier() self.inner.native_identifier()
} }
fn get_nsscreen(&self) -> Option<*mut c_void> { fn nsscreen(&self) -> Option<*mut c_void> {
self.inner.get_nsscreen().map(|s| s as *mut c_void) self.inner.nsscreen().map(|s| s as *mut c_void)
} }
} }

View file

@ -110,14 +110,14 @@ pub trait EventLoopExtUnix {
fn is_x11(&self) -> bool; fn is_x11(&self) -> bool;
#[doc(hidden)] #[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>; fn xlib_xconnection(&self) -> Option<Arc<XConnection>>;
/// Returns a pointer to the `wl_display` object of wayland that is used by this `EventLoop`. /// Returns a pointer to the `wl_display` object of wayland that is used by this `EventLoop`.
/// ///
/// Returns `None` if the `EventLoop` doesn't use wayland (if it uses xlib for example). /// Returns `None` if the `EventLoop` doesn't use wayland (if it uses xlib for example).
/// ///
/// The pointer will become invalid when the glutin `EventLoop` is destroyed. /// The pointer will become invalid when the glutin `EventLoop` is destroyed.
fn get_wayland_display(&self) -> Option<*mut raw::c_void>; fn wayland_display(&self) -> Option<*mut raw::c_void>;
} }
impl<T> EventLoopExtUnix for EventLoop<T> { impl<T> EventLoopExtUnix for EventLoop<T> {
@ -154,7 +154,7 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
#[inline] #[inline]
#[doc(hidden)] #[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> { fn xlib_xconnection(&self) -> Option<Arc<XConnection>> {
match self.event_loop { match self.event_loop {
LinuxEventLoop::X(ref e) => Some(e.x_connection().clone()), LinuxEventLoop::X(ref e) => Some(e.x_connection().clone()),
_ => None _ => None
@ -162,9 +162,9 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
} }
#[inline] #[inline]
fn get_wayland_display(&self) -> Option<*mut raw::c_void> { fn wayland_display(&self) -> Option<*mut raw::c_void> {
match self.event_loop { match self.event_loop {
LinuxEventLoop::Wayland(ref e) => Some(e.get_display().get_display_ptr() as *mut _), LinuxEventLoop::Wayland(ref e) => Some(e.display().get_display_ptr() as *mut _),
_ => None _ => None
} }
} }
@ -175,19 +175,19 @@ pub trait WindowExtUnix {
/// Returns the ID of the `Window` xlib object that is used by this window. /// Returns the ID of the `Window` xlib object that is used by this window.
/// ///
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example). /// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
fn get_xlib_window(&self) -> Option<raw::c_ulong>; fn xlib_window(&self) -> Option<raw::c_ulong>;
/// Returns a pointer to the `Display` object of xlib that is used by this window. /// Returns a pointer to the `Display` object of xlib that is used by this window.
/// ///
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example). /// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
/// ///
/// The pointer will become invalid when the glutin `Window` is destroyed. /// The pointer will become invalid when the glutin `Window` is destroyed.
fn get_xlib_display(&self) -> Option<*mut raw::c_void>; fn xlib_display(&self) -> Option<*mut raw::c_void>;
fn get_xlib_screen_id(&self) -> Option<raw::c_int>; fn xlib_screen_id(&self) -> Option<raw::c_int>;
#[doc(hidden)] #[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>; fn xlib_xconnection(&self) -> Option<Arc<XConnection>>;
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X. /// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
fn set_urgent(&self, is_urgent: bool); fn set_urgent(&self, is_urgent: bool);
@ -197,21 +197,21 @@ pub trait WindowExtUnix {
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example). /// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
/// ///
/// The pointer will become invalid when the glutin `Window` is destroyed. /// The pointer will become invalid when the glutin `Window` is destroyed.
fn get_xcb_connection(&self) -> Option<*mut raw::c_void>; fn xcb_connection(&self) -> Option<*mut raw::c_void>;
/// Returns a pointer to the `wl_surface` object of wayland that is used by this window. /// Returns a pointer to the `wl_surface` object of wayland that is used by this window.
/// ///
/// Returns `None` if the window doesn't use wayland (if it uses xlib for example). /// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
/// ///
/// The pointer will become invalid when the glutin `Window` is destroyed. /// The pointer will become invalid when the glutin `Window` is destroyed.
fn get_wayland_surface(&self) -> Option<*mut raw::c_void>; fn wayland_surface(&self) -> Option<*mut raw::c_void>;
/// Returns a pointer to the `wl_display` object of wayland that is used by this window. /// Returns a pointer to the `wl_display` object of wayland that is used by this window.
/// ///
/// Returns `None` if the window doesn't use wayland (if it uses xlib for example). /// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
/// ///
/// The pointer will become invalid when the glutin `Window` is destroyed. /// The pointer will become invalid when the glutin `Window` is destroyed.
fn get_wayland_display(&self) -> Option<*mut raw::c_void>; fn wayland_display(&self) -> Option<*mut raw::c_void>;
/// Sets the color theme of the client side window decorations on wayland /// Sets the color theme of the client side window decorations on wayland
fn set_wayland_theme(&self, theme: WaylandTheme); fn set_wayland_theme(&self, theme: WaylandTheme);
@ -228,42 +228,42 @@ pub trait WindowExtUnix {
impl WindowExtUnix for Window { impl WindowExtUnix for Window {
#[inline] #[inline]
fn get_xlib_window(&self) -> Option<raw::c_ulong> { fn xlib_window(&self) -> Option<raw::c_ulong> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_window()), LinuxWindow::X(ref w) => Some(w.xlib_window()),
_ => None _ => None
} }
} }
#[inline] #[inline]
fn get_xlib_display(&self) -> Option<*mut raw::c_void> { fn xlib_display(&self) -> Option<*mut raw::c_void> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_display()), LinuxWindow::X(ref w) => Some(w.xlib_display()),
_ => None _ => None
} }
} }
#[inline] #[inline]
fn get_xlib_screen_id(&self) -> Option<raw::c_int> { fn xlib_screen_id(&self) -> Option<raw::c_int> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()), LinuxWindow::X(ref w) => Some(w.xlib_screen_id()),
_ => None _ => None
} }
} }
#[inline] #[inline]
#[doc(hidden)] #[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> { fn xlib_xconnection(&self) -> Option<Arc<XConnection>> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()), LinuxWindow::X(ref w) => Some(w.xlib_xconnection()),
_ => None _ => None
} }
} }
#[inline] #[inline]
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> { fn xcb_connection(&self) -> Option<*mut raw::c_void> {
match self.window { match self.window {
LinuxWindow::X(ref w) => Some(w.get_xcb_connection()), LinuxWindow::X(ref w) => Some(w.xcb_connection()),
_ => None _ => None
} }
} }
@ -276,17 +276,17 @@ impl WindowExtUnix for Window {
} }
#[inline] #[inline]
fn get_wayland_surface(&self) -> Option<*mut raw::c_void> { fn wayland_surface(&self) -> Option<*mut raw::c_void> {
match self.window { match self.window {
LinuxWindow::Wayland(ref w) => Some(w.get_surface().as_ref().c_ptr() as *mut _), LinuxWindow::Wayland(ref w) => Some(w.surface().as_ref().c_ptr() as *mut _),
_ => None _ => None
} }
} }
#[inline] #[inline]
fn get_wayland_display(&self) -> Option<*mut raw::c_void> { fn wayland_display(&self) -> Option<*mut raw::c_void> {
match self.window { match self.window {
LinuxWindow::Wayland(ref w) => Some(w.get_display().as_ref().c_ptr() as *mut _), LinuxWindow::Wayland(ref w) => Some(w.display().as_ref().c_ptr() as *mut _),
_ => None _ => None
} }
} }
@ -398,6 +398,6 @@ pub trait MonitorHandleExtUnix {
impl MonitorHandleExtUnix for MonitorHandle { impl MonitorHandleExtUnix for MonitorHandle {
#[inline] #[inline]
fn native_id(&self) -> u32 { fn native_id(&self) -> u32 {
self.inner.get_native_identifier() self.inner.native_identifier()
} }
} }

View file

@ -33,7 +33,7 @@ pub trait WindowExtWindows {
/// Returns the native handle that is used by this window. /// Returns the native handle that is used by this window.
/// ///
/// The pointer will become invalid when the native window was destroyed. /// The pointer will become invalid when the native window was destroyed.
fn get_hwnd(&self) -> *mut libc::c_void; fn hwnd(&self) -> *mut libc::c_void;
/// This sets `ICON_BIG`. A good ceiling here is 256x256. /// This sets `ICON_BIG`. A good ceiling here is 256x256.
fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>); fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>);
@ -41,7 +41,7 @@ pub trait WindowExtWindows {
impl WindowExtWindows for Window { impl WindowExtWindows for Window {
#[inline] #[inline]
fn get_hwnd(&self) -> *mut libc::c_void { fn hwnd(&self) -> *mut libc::c_void {
self.window.hwnd() as *mut _ self.window.hwnd() as *mut _
} }
@ -95,12 +95,12 @@ pub trait MonitorHandleExtWindows {
impl MonitorHandleExtWindows for MonitorHandle { impl MonitorHandleExtWindows for MonitorHandle {
#[inline] #[inline]
fn native_id(&self) -> String { fn native_id(&self) -> String {
self.inner.get_native_identifier() self.inner.native_identifier()
} }
#[inline] #[inline]
fn hmonitor(&self) -> *mut c_void { fn hmonitor(&self) -> *mut c_void {
self.inner.get_hmonitor() as *mut _ self.inner.hmonitor() as *mut _
} }
} }
@ -109,12 +109,12 @@ pub trait DeviceIdExtWindows {
/// Returns an identifier that persistently refers to this specific device. /// Returns an identifier that persistently refers to this specific device.
/// ///
/// Will return `None` if the device is no longer available. /// Will return `None` if the device is no longer available.
fn get_persistent_identifier(&self) -> Option<String>; fn persistent_identifier(&self) -> Option<String>;
} }
impl DeviceIdExtWindows for DeviceId { impl DeviceIdExtWindows for DeviceId {
#[inline] #[inline]
fn get_persistent_identifier(&self) -> Option<String> { fn persistent_identifier(&self) -> Option<String> {
self.0.get_persistent_identifier() self.0.persistent_identifier()
} }
} }

View file

@ -15,7 +15,7 @@ use {
Event, Event,
LogicalPosition, LogicalPosition,
LogicalSize, LogicalSize,
MouseCursor, CursorIcon,
PhysicalPosition, PhysicalPosition,
PhysicalSize, PhysicalSize,
WindowAttributes, WindowAttributes,
@ -23,9 +23,12 @@ use {
WindowId as RootWindowId, WindowId as RootWindowId,
}; };
use CreationError::OsError; use CreationError::OsError;
use error::{ExternalError, NotSupportedError};
use events::{Touch, TouchPhase}; use events::{Touch, TouchPhase};
use window::MonitorHandle as RootMonitorHandle; use window::MonitorHandle as RootMonitorHandle;
pub type OsError = std::io::Error;
pub struct EventLoop { pub struct EventLoop {
event_rx: Receiver<android_glue::Event>, event_rx: Receiver<android_glue::Event>,
suspend_callback: RefCell<Option<Box<Fn(bool) -> ()>>>, suspend_callback: RefCell<Option<Box<Fn(bool) -> ()>>>,
@ -45,14 +48,14 @@ impl EventLoop {
} }
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
let mut rb = VecDeque::with_capacity(1); let mut rb = VecDeque::with_capacity(1);
rb.push_back(MonitorHandle); rb.push_back(MonitorHandle);
rb rb
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle MonitorHandle
} }
@ -62,7 +65,7 @@ impl EventLoop {
while let Ok(event) = self.event_rx.try_recv() { while let Ok(event) = self.event_rx.try_recv() {
let e = match event{ let e = match event{
android_glue::Event::EventMotion(motion) => { android_glue::Event::EventMotion(motion) => {
let dpi_factor = MonitorHandle.get_hidpi_factor(); let dpi_factor = MonitorHandle.hidpi_factor();
let location = LogicalPosition::from_physical( let location = LogicalPosition::from_physical(
(motion.x as f64, motion.y as f64), (motion.x as f64, motion.y as f64),
dpi_factor, dpi_factor,
@ -99,12 +102,12 @@ impl EventLoop {
android_glue::Event::WindowResized | android_glue::Event::WindowResized |
android_glue::Event::ConfigChanged => { android_glue::Event::ConfigChanged => {
// Activity Orientation changed or resized. // Activity Orientation changed or resized.
let native_window = unsafe { android_glue::get_native_window() }; let native_window = unsafe { android_glue::native_window() };
if native_window.is_null() { if native_window.is_null() {
None None
} else { } else {
let dpi_factor = MonitorHandle.get_hidpi_factor(); let dpi_factor = MonitorHandle.hidpi_factor();
let physical_size = MonitorHandle.get_dimensions(); let physical_size = MonitorHandle.dimensions();
let size = LogicalSize::from_physical(physical_size, dpi_factor); let size = LogicalSize::from_physical(physical_size, dpi_factor);
Some(Event::WindowEvent { Some(Event::WindowEvent {
window_id: RootWindowId(WindowId), window_id: RootWindowId(WindowId),
@ -203,10 +206,10 @@ impl fmt::Debug for MonitorHandle {
} }
let monitor_id_proxy = MonitorHandle { let monitor_id_proxy = MonitorHandle {
name: self.get_name(), name: self.name(),
dimensions: self.get_dimensions(), dimensions: self.dimensions(),
position: self.get_position(), position: self.outer_position(),
hidpi_factor: self.get_hidpi_factor(), hidpi_factor: self.hidpi_factor(),
}; };
monitor_id_proxy.fmt(f) monitor_id_proxy.fmt(f)
@ -215,14 +218,14 @@ impl fmt::Debug for MonitorHandle {
impl MonitorHandle { impl MonitorHandle {
#[inline] #[inline]
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
Some("Primary".to_string()) Some("Primary".to_string())
} }
#[inline] #[inline]
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
unsafe { unsafe {
let window = android_glue::get_native_window(); let window = android_glue::native_window();
( (
ffi::ANativeWindow_getWidth(window) as f64, ffi::ANativeWindow_getWidth(window) as f64,
ffi::ANativeWindow_getHeight(window) as f64, ffi::ANativeWindow_getHeight(window) as f64,
@ -231,13 +234,13 @@ impl MonitorHandle {
} }
#[inline] #[inline]
pub fn get_position(&self) -> PhysicalPosition { pub fn outer_position(&self) -> PhysicalPosition {
// Android assumes single screen // Android assumes single screen
(0, 0).into() (0, 0).into()
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
1.0 1.0
} }
} }
@ -252,12 +255,12 @@ impl Window {
_: PlatformSpecificWindowBuilderAttributes) _: PlatformSpecificWindowBuilderAttributes)
-> Result<Window, CreationError> -> Result<Window, CreationError>
{ {
let native_window = unsafe { android_glue::get_native_window() }; let native_window = unsafe { android_glue::native_window() };
if native_window.is_null() { if native_window.is_null() {
return Err(OsError(format!("Android's native window is null"))); return Err(OsError(format!("Android's native window is null")));
} }
android_glue::set_multitouch(win_attribs.multitouch); android_glue::set_multitouch(true);
Ok(Window { Ok(Window {
native_window: native_window as *const _, native_window: native_window as *const _,
@ -265,7 +268,7 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_native_window(&self) -> *const c_void { pub fn native_window(&self) -> *const c_void {
self.native_window self.native_window
} }
@ -285,29 +288,29 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn outer_position(&self) -> Option<LogicalPosition> {
// N/A // N/A
None None
} }
#[inline] #[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn inner_position(&self) -> Option<LogicalPosition> {
// N/A // N/A
None None
} }
#[inline] #[inline]
pub fn set_position(&self, _position: LogicalPosition) { pub fn set_outer_position(&self, _position: LogicalPosition) {
// N/A // N/A
} }
#[inline] #[inline]
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) { pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
// N/A // N/A
} }
#[inline] #[inline]
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) { pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
// N/A // N/A
} }
@ -317,19 +320,19 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn inner_size(&self) -> Option<LogicalSize> {
if self.native_window.is_null() { if self.native_window.is_null() {
None None
} else { } else {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
let physical_size = self.get_current_monitor().get_dimensions(); let physical_size = self.current_monitor().dimensions();
Some(LogicalSize::from_physical(physical_size, dpi_factor)) Some(LogicalSize::from_physical(physical_size, dpi_factor))
} }
} }
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn outer_size(&self) -> Option<LogicalSize> {
self.get_inner_size() self.inner_size()
} }
#[inline] #[inline]
@ -338,18 +341,18 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
self.get_current_monitor().get_hidpi_factor() self.current_monitor().hidpi_factor()
} }
#[inline] #[inline]
pub fn set_cursor(&self, _: MouseCursor) { pub fn set_cursor_icon(&self, _: CursorIcon) {
// N/A // N/A
} }
#[inline] #[inline]
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> { pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
Err("Cursor grabbing is not possible on Android.".to_owned()) Err(ExternalError::NotSupported(NotSupportedError::new()))
} }
#[inline] #[inline]
@ -358,8 +361,8 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
Err("Setting cursor position is not possible on Android.".to_owned()) Err(ExternalError::NotSupported(NotSupportedError::new()))
} }
#[inline] #[inline]
@ -369,7 +372,7 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> { pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
// N/A // N/A
// Android has single screen maximized apps so nothing to do // Android has single screen maximized apps so nothing to do
None None
@ -397,24 +400,24 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_ime_spot(&self, _spot: LogicalPosition) { pub fn set_ime_position(&self, _spot: LogicalPosition) {
// N/A // N/A
} }
#[inline] #[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle { pub fn current_monitor(&self) -> RootMonitorHandle {
RootMonitorHandle { inner: MonitorHandle } RootMonitorHandle { inner: MonitorHandle }
} }
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
let mut rb = VecDeque::with_capacity(1); let mut rb = VecDeque::with_capacity(1);
rb.push_back(MonitorHandle); rb.push_back(MonitorHandle);
rb rb
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle MonitorHandle
} }

View file

@ -10,11 +10,12 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Mutex, Arc}; use std::sync::{Mutex, Arc};
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}; use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
use error::{ExternalError, NotSupportedError};
use window::MonitorHandle as RootMonitorHandle; use window::MonitorHandle as RootMonitorHandle;
const DOCUMENT_NAME: &'static str = "#document\0"; const DOCUMENT_NAME: &'static str = "#document\0";
fn get_hidpi_factor() -> f64 { fn hidpi_factor() -> f64 {
unsafe { ffi::emscripten_get_device_pixel_ratio() as f64 } unsafe { ffi::emscripten_get_device_pixel_ratio() as f64 }
} }
@ -24,6 +25,8 @@ pub struct PlatformSpecificWindowBuilderAttributes;
unsafe impl Send for PlatformSpecificWindowBuilderAttributes {} unsafe impl Send for PlatformSpecificWindowBuilderAttributes {}
unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {} unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {}
pub type OsError = std::io::Error;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DeviceId; pub struct DeviceId;
@ -41,23 +44,23 @@ pub struct MonitorHandle;
impl MonitorHandle { impl MonitorHandle {
#[inline] #[inline]
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
Some("Canvas".to_owned()) Some("Canvas".to_owned())
} }
#[inline] #[inline]
pub fn get_position(&self) -> PhysicalPosition { pub fn outer_position(&self) -> PhysicalPosition {
unimplemented!() unimplemented!()
} }
#[inline] #[inline]
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
(0, 0).into() (0, 0).into()
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
get_hidpi_factor() hidpi_factor()
} }
} }
@ -113,14 +116,14 @@ impl EventLoop {
} }
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
let mut list = VecDeque::with_capacity(1); let mut list = VecDeque::with_capacity(1);
list.push_back(MonitorHandle); list.push_back(MonitorHandle);
list list
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle MonitorHandle
} }
@ -163,7 +166,7 @@ impl WindowId {
pub struct Window2 { pub struct Window2 {
cursor_grabbed: Mutex<bool>, cursor_grabbed: Mutex<bool>,
cursor_hidden: Mutex<bool>, cursor_visible: Mutex<bool>,
is_fullscreen: bool, is_fullscreen: bool,
events: Box<Mutex<VecDeque<::Event>>>, events: Box<Mutex<VecDeque<::Event>>>,
} }
@ -208,7 +211,7 @@ extern "C" fn mouse_callback(
match event_type { match event_type {
ffi::EMSCRIPTEN_EVENT_MOUSEMOVE => { ffi::EMSCRIPTEN_EVENT_MOUSEMOVE => {
let dpi_factor = get_hidpi_factor(); let dpi_factor = hidpi_factor();
let position = LogicalPosition::from_physical( let position = LogicalPosition::from_physical(
((*event).canvasX as f64, (*event).canvasY as f64), ((*event).canvasX as f64, (*event).canvasY as f64),
dpi_factor, dpi_factor,
@ -328,7 +331,7 @@ extern fn touch_callback(
for touch in 0..(*event).numTouches as usize { for touch in 0..(*event).numTouches as usize {
let touch = (*event).touches[touch]; let touch = (*event).touches[touch];
if touch.isChanged == ffi::EM_TRUE { if touch.isChanged == ffi::EM_TRUE {
let dpi_factor = get_hidpi_factor(); let dpi_factor = hidpi_factor();
let location = LogicalPosition::from_physical( let location = LogicalPosition::from_physical(
(touch.canvasX as f64, touch.canvasY as f64), (touch.canvasX as f64, touch.canvasY as f64),
dpi_factor, dpi_factor,
@ -387,8 +390,8 @@ impl Window {
} }
let w = Window2 { let w = Window2 {
cursor_grabbed: Default::default(), cursor_grabbed: Mutex::new(false),
cursor_hidden: Default::default(), cursor_visible: Mutex::new(true),
events: Default::default(), events: Default::default(),
is_fullscreen: attribs.fullscreen.is_some(), is_fullscreen: attribs.fullscreen.is_some(),
}; };
@ -427,7 +430,7 @@ impl Window {
em_try(ffi::emscripten_set_fullscreenchange_callback(ptr::null(), 0 as *mut c_void, ffi::EM_FALSE, Some(fullscreen_callback))) em_try(ffi::emscripten_set_fullscreenchange_callback(ptr::null(), 0 as *mut c_void, ffi::EM_FALSE, Some(fullscreen_callback)))
.map_err(|e| ::CreationError::OsError(e))?; .map_err(|e| ::CreationError::OsError(e))?;
} }
} else if let Some(size) = attribs.dimensions { } else if let Some(size) = attribs.inner_size {
window.set_inner_size(size); window.set_inner_size(size);
} }
@ -445,21 +448,21 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn outer_position(&self) -> Option<LogicalPosition> {
Some((0, 0).into()) Some((0, 0).into())
} }
#[inline] #[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn inner_position(&self) -> Option<LogicalPosition> {
Some((0, 0).into()) Some((0, 0).into())
} }
#[inline] #[inline]
pub fn set_position(&self, _: LogicalPosition) { pub fn set_outer_position(&self, _: LogicalPosition) {
} }
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn inner_size(&self) -> Option<LogicalSize> {
unsafe { unsafe {
let mut width = 0; let mut width = 0;
let mut height = 0; let mut height = 0;
@ -470,7 +473,7 @@ impl Window {
{ {
None None
} else { } else {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
let logical = LogicalSize::from_physical((width as u32, height as u32), dpi_factor); let logical = LogicalSize::from_physical((width as u32, height as u32), dpi_factor);
Some(logical) Some(logical)
} }
@ -478,14 +481,14 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn outer_size(&self) -> Option<LogicalSize> {
self.get_inner_size() self.inner_size()
} }
#[inline] #[inline]
pub fn set_inner_size(&self, size: LogicalSize) { pub fn set_inner_size(&self, size: LogicalSize) {
unsafe { unsafe {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
let physical = PhysicalSize::from_logical(size, dpi_factor); let physical = PhysicalSize::from_logical(size, dpi_factor);
let (width, height): (u32, u32) = physical.into(); let (width, height): (u32, u32) = physical.into();
ffi::emscripten_set_element_css_size( ffi::emscripten_set_element_css_size(
@ -497,12 +500,12 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) { pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
// N/A // N/A
} }
#[inline] #[inline]
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) { pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
// N/A // N/A
} }
@ -522,12 +525,12 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_cursor(&self, _cursor: ::MouseCursor) { pub fn set_cursor_icon(&self, _cursor: ::CursorIcon) {
// N/A // N/A
} }
#[inline] #[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
let mut grabbed_lock = self.window.cursor_grabbed.lock().unwrap(); let mut grabbed_lock = self.window.cursor_grabbed.lock().unwrap();
if grab == *grabbed_lock { return Ok(()); } if grab == *grabbed_lock { return Ok(()); }
unsafe { unsafe {
@ -554,24 +557,24 @@ impl Window {
} }
#[inline] #[inline]
pub fn hide_cursor(&self, hide: bool) { pub fn set_cursor_visible(&self, visible: bool) {
let mut hidden_lock = self.window.cursor_hidden.lock().unwrap(); let mut visible_lock = self.window.cursor_visible.lock().unwrap();
if hide == *hidden_lock { return; } if visible == *visible_lock { return; }
if hide { if visible {
unsafe { ffi::emscripten_hide_mouse() };
} else {
show_mouse(); show_mouse();
} else {
unsafe { ffi::emscripten_hide_mouse() };
} }
*hidden_lock = hide; *visible_lock = visible;
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
get_hidpi_factor() hidpi_factor()
} }
#[inline] #[inline]
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
Err("Setting cursor position is not possible on Emscripten.".to_owned()) Err("Setting cursor position is not possible on Emscripten.".to_owned())
} }
@ -581,7 +584,7 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_fullscreen(&self) -> Option<::MonitorHandle> { pub fn fullscreen(&self) -> Option<::MonitorHandle> {
None None
} }
@ -606,24 +609,24 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_ime_spot(&self, _logical_spot: LogicalPosition) { pub fn set_ime_position(&self, _logical_spot: LogicalPosition) {
// N/A // N/A
} }
#[inline] #[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle { pub fn current_monitor(&self) -> RootMonitorHandle {
RootMonitorHandle { inner: MonitorHandle } RootMonitorHandle { inner: MonitorHandle }
} }
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
let mut list = VecDeque::with_capacity(1); let mut list = VecDeque::with_capacity(1);
list.push_back(MonitorHandle); list.push_back(MonitorHandle);
list list
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle MonitorHandle
} }
} }
@ -639,7 +642,7 @@ impl Drop for Window {
unsafe { unsafe {
// Return back to normal cursor state // Return back to normal cursor state
self.hide_cursor(false); self.hide_cursor(false);
self.grab_cursor(false); self.set_cursor_grab(false);
// Exit fullscreen if on // Exit fullscreen if on
if self.window.is_fullscreen { if self.window.is_fullscreen {

View file

@ -119,14 +119,14 @@ impl<T: 'static> EventLoop<T> {
EventLoopProxy::new(self.window_target.p.sender_to_clone.clone()) EventLoopProxy::new(self.window_target.p.sender_to_clone.clone())
} }
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
// guaranteed to be on main thread // guaranteed to be on main thread
unsafe { unsafe {
monitor::uiscreens() monitor::uiscreens()
} }
} }
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
// guaranteed to be on main thread // guaranteed to be on main thread
unsafe { unsafe {
monitor::main_uiscreen() monitor::main_uiscreen()
@ -140,7 +140,7 @@ impl<T: 'static> EventLoop<T> {
// EventLoopExtIOS // EventLoopExtIOS
impl<T: 'static> EventLoop<T> { impl<T: 'static> EventLoop<T> {
pub fn get_idiom(&self) -> Idiom { pub fn idiom(&self) -> Idiom {
// guaranteed to be on main thread // guaranteed to be on main thread
unsafe { unsafe {
self::get_idiom() self::get_idiom()
@ -331,4 +331,4 @@ impl From<NSOperatingSystemVersion> for Capabilities {
Capabilities { supports_safe_area } Capabilities { supports_safe_area }
} }
} }

View file

@ -76,6 +76,8 @@ mod monitor;
mod view; mod view;
mod window; mod window;
use std::fmt;
pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget}; pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
pub use self::monitor::MonitorHandle; pub use self::monitor::MonitorHandle;
pub use self::window::{ pub use self::window::{
@ -99,3 +101,14 @@ impl DeviceId {
unsafe impl Send for DeviceId {} unsafe impl Send for DeviceId {}
unsafe impl Sync for DeviceId {} unsafe impl Sync for DeviceId {}
#[derive(Debug)]
pub enum OsError {}
impl fmt::Display for OsError {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
match self {
_ => unreachable!()
}
}
}

View file

@ -78,10 +78,10 @@ impl fmt::Debug for MonitorHandle {
} }
let monitor_id_proxy = MonitorHandle { let monitor_id_proxy = MonitorHandle {
name: self.get_name(), name: self.name(),
dimensions: self.get_dimensions(), dimensions: self.dimensions(),
position: self.get_position(), position: self.position(),
hidpi_factor: self.get_hidpi_factor(), hidpi_factor: self.hidpi_factor(),
}; };
monitor_id_proxy.fmt(f) monitor_id_proxy.fmt(f)
@ -99,7 +99,7 @@ impl MonitorHandle {
} }
impl Inner { impl Inner {
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
unsafe { unsafe {
if self.uiscreen == main_uiscreen().uiscreen { if self.uiscreen == main_uiscreen().uiscreen {
Some("Primary".to_string()) Some("Primary".to_string())
@ -113,24 +113,24 @@ impl Inner {
} }
} }
} }
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
unsafe { unsafe {
let bounds: CGRect = msg_send![self.get_uiscreen(), nativeBounds]; let bounds: CGRect = msg_send![self.ui_screen(), nativeBounds];
(bounds.size.width as f64, bounds.size.height as f64).into() (bounds.size.width as f64, bounds.size.height as f64).into()
} }
} }
pub fn get_position(&self) -> PhysicalPosition { pub fn position(&self) -> PhysicalPosition {
unsafe { unsafe {
let bounds: CGRect = msg_send![self.get_uiscreen(), nativeBounds]; let bounds: CGRect = msg_send![self.ui_screen(), nativeBounds];
(bounds.origin.x as f64, bounds.origin.y as f64).into() (bounds.origin.x as f64, bounds.origin.y as f64).into()
} }
} }
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
unsafe { unsafe {
let scale: CGFloat = msg_send![self.get_uiscreen(), nativeScale]; let scale: CGFloat = msg_send![self.ui_screen(), nativeScale];
scale as f64 scale as f64
} }
} }
@ -138,7 +138,7 @@ impl Inner {
// MonitorHandleExtIOS // MonitorHandleExtIOS
impl Inner { impl Inner {
pub fn get_uiscreen(&self) -> id { pub fn ui_screen(&self) -> id {
self.uiscreen self.uiscreen
} }
} }

View file

@ -31,7 +31,7 @@ use platform_impl::platform::window::{PlatformSpecificWindowBuilderAttributes};
unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class { unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
static mut CLASSES: Option<HashMap<*const Class, &'static Class>> = None; static mut CLASSES: Option<HashMap<*const Class, &'static Class>> = None;
static mut ID: usize = 0; static mut ID: usize = 0;
if CLASSES.is_none() { if CLASSES.is_none() {
CLASSES = Some(HashMap::default()); CLASSES = Some(HashMap::default());
} }
@ -255,7 +255,7 @@ unsafe fn get_window_class() -> &'static Class {
// requires main thread // requires main thread
pub unsafe fn create_view( pub unsafe fn create_view(
window_attributes: &WindowAttributes, _window_attributes: &WindowAttributes,
platform_attributes: &PlatformSpecificWindowBuilderAttributes, platform_attributes: &PlatformSpecificWindowBuilderAttributes,
frame: CGRect, frame: CGRect,
) -> id { ) -> id {
@ -265,9 +265,7 @@ pub unsafe fn create_view(
assert!(!view.is_null(), "Failed to create `UIView` instance"); assert!(!view.is_null(), "Failed to create `UIView` instance");
let view: id = msg_send![view, initWithFrame:frame]; let view: id = msg_send![view, initWithFrame:frame];
assert!(!view.is_null(), "Failed to initialize `UIView` instance"); assert!(!view.is_null(), "Failed to initialize `UIView` instance");
if window_attributes.multitouch { let () = msg_send![view, setMultipleTouchEnabled:YES];
let () = msg_send![view, setMultipleTouchEnabled:YES];
}
view view
} }
@ -318,7 +316,7 @@ pub unsafe fn create_window(
let () = msg_send![window, setContentScaleFactor:hidpi_factor as CGFloat]; let () = msg_send![window, setContentScaleFactor:hidpi_factor as CGFloat];
} }
if let &Some(ref monitor) = &window_attributes.fullscreen { if let &Some(ref monitor) = &window_attributes.fullscreen {
let () = msg_send![window, setScreen:monitor.get_uiscreen()]; let () = msg_send![window, setScreen:monitor.ui_screen()];
} }
window window

View file

@ -6,12 +6,12 @@ use std::{
use objc::runtime::{Class, NO, Object, YES}; use objc::runtime::{Class, NO, Object, YES};
use dpi::{self, LogicalPosition, LogicalSize}; use dpi::{self, LogicalPosition, LogicalSize};
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
use icon::Icon; use icon::Icon;
use monitor::MonitorHandle as RootMonitorHandle; use monitor::MonitorHandle as RootMonitorHandle;
use platform::ios::{MonitorHandleExtIOS, ValidOrientations}; use platform::ios::{MonitorHandleExtIOS, ValidOrientations};
use window::{ use window::{
CreationError, CursorIcon,
MouseCursor,
WindowAttributes, WindowAttributes,
}; };
use platform_impl::{ use platform_impl::{
@ -56,15 +56,14 @@ impl Inner {
debug!("`Window::set_title` is ignored on iOS") debug!("`Window::set_title` is ignored on iOS")
} }
pub fn show(&self) { pub fn set_visible(&self, visible: bool) {
unsafe { match visible {
let () = msg_send![self.window, setHidden:NO]; true => unsafe {
} let () = msg_send![self.window, setHidden:NO];
} },
false => unsafe {
pub fn hide(&self) { let () = msg_send![self.window, setHidden:YES];
unsafe { },
let () = msg_send![self.window, setHidden:YES];
} }
} }
@ -73,28 +72,28 @@ impl Inner {
let () = msg_send![self.view, setNeedsDisplay]; let () = msg_send![self.view, setNeedsDisplay];
} }
} }
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
unsafe { unsafe {
let safe_area = self.safe_area_screen_space(); let safe_area = self.safe_area_screen_space();
Some(LogicalPosition { Ok(LogicalPosition {
x: safe_area.origin.x, x: safe_area.origin.x,
y: safe_area.origin.y, y: safe_area.origin.y,
}) })
} }
} }
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
unsafe { unsafe {
let screen_frame = self.screen_frame(); let screen_frame = self.screen_frame();
Some(LogicalPosition { Ok(LogicalPosition {
x: screen_frame.origin.x, x: screen_frame.origin.x,
y: screen_frame.origin.y, y: screen_frame.origin.y,
}) })
} }
} }
pub fn set_position(&self, position: LogicalPosition) { pub fn set_outer_position(&self, position: LogicalPosition) {
unsafe { unsafe {
let screen_frame = self.screen_frame(); let screen_frame = self.screen_frame();
let new_screen_frame = CGRect { let new_screen_frame = CGRect {
@ -109,23 +108,23 @@ impl Inner {
} }
} }
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn inner_size(&self) -> LogicalSize {
unsafe { unsafe {
let safe_area = self.safe_area_screen_space(); let safe_area = self.safe_area_screen_space();
Some(LogicalSize { LogicalSize {
width: safe_area.size.width, width: safe_area.size.width,
height: safe_area.size.height, height: safe_area.size.height,
}) }
} }
} }
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn outer_size(&self) -> LogicalSize {
unsafe { unsafe {
let screen_frame = self.screen_frame(); let screen_frame = self.screen_frame();
Some(LogicalSize { LogicalSize {
width: screen_frame.size.width, width: screen_frame.size.width,
height: screen_frame.size.height, height: screen_frame.size.height,
}) }
} }
} }
@ -133,39 +132,39 @@ impl Inner {
unimplemented!("not clear what `Window::set_inner_size` means on iOS"); unimplemented!("not clear what `Window::set_inner_size` means on iOS");
} }
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) { pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
warn!("`Window::set_min_dimensions` is ignored on iOS") warn!("`Window::set_min_inner_size` is ignored on iOS")
} }
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) { pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
warn!("`Window::set_max_dimensions` is ignored on iOS") warn!("`Window::set_max_inner_size` is ignored on iOS")
} }
pub fn set_resizable(&self, _resizable: bool) { pub fn set_resizable(&self, _resizable: bool) {
warn!("`Window::set_resizable` is ignored on iOS") warn!("`Window::set_resizable` is ignored on iOS")
} }
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
unsafe { unsafe {
let hidpi: CGFloat = msg_send![self.view, contentScaleFactor]; let hidpi: CGFloat = msg_send![self.view, contentScaleFactor];
hidpi as _ hidpi as _
} }
} }
pub fn set_cursor(&self, _cursor: MouseCursor) { pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
debug!("`Window::set_cursor` ignored on iOS") debug!("`Window::set_cursor_icon` ignored on iOS")
} }
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
Err("Setting cursor position is not possible on iOS.".to_owned()) Err(ExternalError::NotSupported(NotSupportedError::new()))
} }
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> { pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
Err("Cursor grabbing is not possible on iOS.".to_owned()) Err(ExternalError::NotSupported(NotSupportedError::new()))
} }
pub fn hide_cursor(&self, _hide: bool) { pub fn set_cursor_visible(&self, _visible: bool) {
debug!("`Window::hide_cursor` is ignored on iOS") debug!("`Window::set_cursor_visible` is ignored on iOS")
} }
pub fn set_maximized(&self, _maximized: bool) { pub fn set_maximized(&self, _maximized: bool) {
@ -176,7 +175,7 @@ impl Inner {
unsafe { unsafe {
match monitor { match monitor {
Some(monitor) => { Some(monitor) => {
let uiscreen = monitor.get_uiscreen() as id; let uiscreen = monitor.ui_screen() as id;
let current: id = msg_send![self.window, screen]; let current: id = msg_send![self.window, screen];
let bounds: CGRect = msg_send![uiscreen, bounds]; let bounds: CGRect = msg_send![uiscreen, bounds];
@ -191,10 +190,10 @@ impl Inner {
} }
} }
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> { pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
unsafe { unsafe {
let monitor = self.get_current_monitor(); let monitor = self.current_monitor();
let uiscreen = monitor.inner.get_uiscreen(); let uiscreen = monitor.inner.ui_screen();
let screen_space_bounds = self.screen_frame(); let screen_space_bounds = self.screen_frame();
let screen_bounds: CGRect = msg_send![uiscreen, bounds]; let screen_bounds: CGRect = msg_send![uiscreen, bounds];
@ -226,24 +225,24 @@ impl Inner {
warn!("`Window::set_window_icon` is ignored on iOS") warn!("`Window::set_window_icon` is ignored on iOS")
} }
pub fn set_ime_spot(&self, _position: LogicalPosition) { pub fn set_ime_position(&self, _position: LogicalPosition) {
warn!("`Window::set_ime_spot` is ignored on iOS") warn!("`Window::set_ime_position` is ignored on iOS")
} }
pub fn get_current_monitor(&self) -> RootMonitorHandle { pub fn current_monitor(&self) -> RootMonitorHandle {
unsafe { unsafe {
let uiscreen: id = msg_send![self.window, screen]; let uiscreen: id = msg_send![self.window, screen];
RootMonitorHandle { inner: MonitorHandle::retained_new(uiscreen) } RootMonitorHandle { inner: MonitorHandle::retained_new(uiscreen) }
} }
} }
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
unsafe { unsafe {
monitor::uiscreens() monitor::uiscreens()
} }
} }
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
unsafe { unsafe {
monitor::main_uiscreen() monitor::main_uiscreen()
} }
@ -294,12 +293,12 @@ impl Window {
event_loop: &EventLoopWindowTarget<T>, event_loop: &EventLoopWindowTarget<T>,
window_attributes: WindowAttributes, window_attributes: WindowAttributes,
platform_attributes: PlatformSpecificWindowBuilderAttributes, platform_attributes: PlatformSpecificWindowBuilderAttributes,
) -> Result<Window, CreationError> { ) -> Result<Window, RootOsError> {
if let Some(_) = window_attributes.min_dimensions { if let Some(_) = window_attributes.min_inner_size {
warn!("`WindowAttributes::min_dimensions` is ignored on iOS"); warn!("`WindowAttributes::min_inner_size` is ignored on iOS");
} }
if let Some(_) = window_attributes.max_dimensions { if let Some(_) = window_attributes.max_inner_size {
warn!("`WindowAttributes::max_dimensions` is ignored on iOS"); warn!("`WindowAttributes::max_inner_size` is ignored on iOS");
} }
if window_attributes.always_on_top { if window_attributes.always_on_top {
warn!("`WindowAttributes::always_on_top` is unsupported on iOS"); warn!("`WindowAttributes::always_on_top` is unsupported on iOS");
@ -309,11 +308,11 @@ impl Window {
unsafe { unsafe {
let screen = window_attributes.fullscreen let screen = window_attributes.fullscreen
.as_ref() .as_ref()
.map(|screen| screen.get_uiscreen() as _) .map(|screen| screen.ui_screen() as _)
.unwrap_or_else(|| monitor::main_uiscreen().get_uiscreen()); .unwrap_or_else(|| monitor::main_uiscreen().ui_screen());
let screen_bounds: CGRect = msg_send![screen, bounds]; let screen_bounds: CGRect = msg_send![screen, bounds];
let frame = match window_attributes.dimensions { let frame = match window_attributes.inner_size {
Some(dim) => CGRect { Some(dim) => CGRect {
origin: screen_bounds.origin, origin: screen_bounds.origin,
size: CGSize { width: dim.width, height: dim.height }, size: CGSize { width: dim.width, height: dim.height },
@ -343,9 +342,9 @@ impl Window {
// WindowExtIOS // WindowExtIOS
impl Inner { impl Inner {
pub fn get_uiwindow(&self) -> id { self.window } pub fn ui_window(&self) -> id { self.window }
pub fn get_uiviewcontroller(&self) -> id { self.view_controller } pub fn ui_view_controller(&self) -> id { self.view_controller }
pub fn get_uiview(&self) -> id { self.view } pub fn ui_view(&self) -> id { self.view }
pub fn set_hidpi_factor(&self, hidpi_factor: f64) { pub fn set_hidpi_factor(&self, hidpi_factor: f64) {
unsafe { unsafe {

View file

@ -1,7 +1,7 @@
#![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"))]
use std::collections::VecDeque; use std::collections::VecDeque;
use std::{env, mem}; use std::{env, mem, fmt};
use std::ffi::CStr; use std::ffi::CStr;
use std::os::raw::*; use std::os::raw::*;
use std::sync::Arc; use std::sync::Arc;
@ -11,10 +11,11 @@ use sctk::reexports::client::ConnectError;
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize}; use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
use icon::Icon; use icon::Icon;
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
use event::Event; use event::Event;
use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW}; use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
use monitor::MonitorHandle as RootMonitorHandle; use monitor::MonitorHandle as RootMonitorHandle;
use window::{WindowAttributes, CreationError, MouseCursor}; use window::{WindowAttributes, CursorIcon};
use self::x11::{XConnection, XError}; use self::x11::{XConnection, XError};
use self::x11::ffi::XVisualInfo; use self::x11::ffi::XVisualInfo;
pub use self::x11::XNotSupported; pub use self::x11::XNotSupported;
@ -51,6 +52,21 @@ lazy_static!(
}; };
); );
#[derive(Debug, Clone)]
pub enum OsError {
XError(XError),
XMisc(&'static str),
}
impl fmt::Display for OsError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
OsError::XError(e) => formatter.pad(&e.description),
OsError::XMisc(e) => formatter.pad(e),
}
}
}
pub enum Window { pub enum Window {
X(x11::Window), X(x11::Window),
Wayland(wayland::Window), Wayland(wayland::Window),
@ -88,42 +104,42 @@ pub enum MonitorHandle {
impl MonitorHandle { impl MonitorHandle {
#[inline] #[inline]
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
match self { match self {
&MonitorHandle::X(ref m) => m.get_name(), &MonitorHandle::X(ref m) => m.name(),
&MonitorHandle::Wayland(ref m) => m.get_name(), &MonitorHandle::Wayland(ref m) => m.name(),
} }
} }
#[inline] #[inline]
pub fn get_native_identifier(&self) -> u32 { pub fn native_identifier(&self) -> u32 {
match self { match self {
&MonitorHandle::X(ref m) => m.get_native_identifier(), &MonitorHandle::X(ref m) => m.native_identifier(),
&MonitorHandle::Wayland(ref m) => m.get_native_identifier(), &MonitorHandle::Wayland(ref m) => m.native_identifier(),
} }
} }
#[inline] #[inline]
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
match self { match self {
&MonitorHandle::X(ref m) => m.get_dimensions(), &MonitorHandle::X(ref m) => m.dimensions(),
&MonitorHandle::Wayland(ref m) => m.get_dimensions(), &MonitorHandle::Wayland(ref m) => m.dimensions(),
} }
} }
#[inline] #[inline]
pub fn get_position(&self) -> PhysicalPosition { pub fn position(&self) -> PhysicalPosition {
match self { match self {
&MonitorHandle::X(ref m) => m.get_position(), &MonitorHandle::X(ref m) => m.position(),
&MonitorHandle::Wayland(ref m) => m.get_position(), &MonitorHandle::Wayland(ref m) => m.position(),
} }
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
match self { match self {
&MonitorHandle::X(ref m) => m.get_hidpi_factor(), &MonitorHandle::X(ref m) => m.hidpi_factor(),
&MonitorHandle::Wayland(ref m) => m.get_hidpi_factor() as f64, &MonitorHandle::Wayland(ref m) => m.hidpi_factor() as f64,
} }
} }
} }
@ -134,7 +150,7 @@ impl Window {
window_target: &EventLoopWindowTarget<T>, window_target: &EventLoopWindowTarget<T>,
attribs: WindowAttributes, attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<Self, CreationError> { ) -> Result<Self, RootOsError> {
match *window_target { match *window_target {
EventLoopWindowTarget::Wayland(ref window_target) => { EventLoopWindowTarget::Wayland(ref window_target) => {
wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland) wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland)
@ -162,58 +178,50 @@ impl Window {
} }
#[inline] #[inline]
pub fn show(&self) { pub fn set_visible(&self, visible: bool) {
match self { match self {
&Window::X(ref w) => w.show(), &Window::X(ref w) => w.set_visible(visible),
&Window::Wayland(ref w) => w.show(), &Window::Wayland(ref w) => w.set_visible(visible),
} }
} }
#[inline] #[inline]
pub fn hide(&self) { pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
match self { match self {
&Window::X(ref w) => w.hide(), &Window::X(ref w) => w.outer_position(),
&Window::Wayland(ref w) => w.hide(), &Window::Wayland(ref w) => w.outer_position(),
} }
} }
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
match self { match self {
&Window::X(ref w) => w.get_position(), &Window::X(ref m) => m.inner_position(),
&Window::Wayland(ref w) => w.get_position(), &Window::Wayland(ref m) => m.inner_position(),
} }
} }
#[inline] #[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn set_outer_position(&self, position: LogicalPosition) {
match self { match self {
&Window::X(ref m) => m.get_inner_position(), &Window::X(ref w) => w.set_outer_position(position),
&Window::Wayland(ref m) => m.get_inner_position(), &Window::Wayland(ref w) => w.set_outer_position(position),
} }
} }
#[inline] #[inline]
pub fn set_position(&self, position: LogicalPosition) { pub fn inner_size(&self) -> LogicalSize {
match self { match self {
&Window::X(ref w) => w.set_position(position), &Window::X(ref w) => w.inner_size(),
&Window::Wayland(ref w) => w.set_position(position), &Window::Wayland(ref w) => w.inner_size(),
} }
} }
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn outer_size(&self) -> LogicalSize {
match self { match self {
&Window::X(ref w) => w.get_inner_size(), &Window::X(ref w) => w.outer_size(),
&Window::Wayland(ref w) => w.get_inner_size(), &Window::Wayland(ref w) => w.outer_size(),
}
}
#[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> {
match self {
&Window::X(ref w) => w.get_outer_size(),
&Window::Wayland(ref w) => w.get_outer_size(),
} }
} }
@ -226,18 +234,18 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
match self { match self {
&Window::X(ref w) => w.set_min_dimensions(dimensions), &Window::X(ref w) => w.set_min_inner_size(dimensions),
&Window::Wayland(ref w) => w.set_min_dimensions(dimensions), &Window::Wayland(ref w) => w.set_min_inner_size(dimensions),
} }
} }
#[inline] #[inline]
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
match self { match self {
&Window::X(ref w) => w.set_max_dimensions(dimensions), &Window::X(ref w) => w.set_max_inner_size(dimensions),
&Window::Wayland(ref w) => w.set_max_dimensions(dimensions), &Window::Wayland(ref w) => w.set_max_inner_size(dimensions),
} }
} }
@ -250,39 +258,39 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_cursor(&self, cursor: MouseCursor) { pub fn set_cursor_icon(&self, cursor: CursorIcon) {
match self { match self {
&Window::X(ref w) => w.set_cursor(cursor), &Window::X(ref w) => w.set_cursor_icon(cursor),
&Window::Wayland(ref w) => w.set_cursor(cursor) &Window::Wayland(ref w) => w.set_cursor_icon(cursor)
} }
} }
#[inline] #[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
match self { match self {
&Window::X(ref window) => window.grab_cursor(grab), &Window::X(ref window) => window.set_cursor_grab(grab),
&Window::Wayland(ref window) => window.grab_cursor(grab), &Window::Wayland(ref window) => window.set_cursor_grab(grab),
} }
} }
#[inline] #[inline]
pub fn hide_cursor(&self, hide: bool) { pub fn set_cursor_visible(&self, visible: bool) {
match self { match self {
&Window::X(ref window) => window.hide_cursor(hide), &Window::X(ref window) => window.set_cursor_visible(visible),
&Window::Wayland(ref window) => window.hide_cursor(hide), &Window::Wayland(ref window) => window.set_cursor_visible(visible),
} }
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
match self { match self {
&Window::X(ref w) => w.get_hidpi_factor(), &Window::X(ref w) => w.hidpi_factor(),
&Window::Wayland(ref w) => w.hidpi_factor() as f64, &Window::Wayland(ref w) => w.hidpi_factor() as f64,
} }
} }
#[inline] #[inline]
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> {
match self { match self {
&Window::X(ref w) => w.set_cursor_position(position), &Window::X(ref w) => w.set_cursor_position(position),
&Window::Wayland(ref w) => w.set_cursor_position(position), &Window::Wayland(ref w) => w.set_cursor_position(position),
@ -298,10 +306,10 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> { pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
match self { match self {
&Window::X(ref w) => w.get_fullscreen(), &Window::X(ref w) => w.fullscreen(),
&Window::Wayland(ref w) => w.get_fullscreen() &Window::Wayland(ref w) => w.fullscreen()
.map(|monitor_id| RootMonitorHandle { inner: MonitorHandle::Wayland(monitor_id) }) .map(|monitor_id| RootMonitorHandle { inner: MonitorHandle::Wayland(monitor_id) })
} }
} }
@ -339,9 +347,9 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_ime_spot(&self, position: LogicalPosition) { pub fn set_ime_position(&self, position: LogicalPosition) {
match self { match self {
&Window::X(ref w) => w.set_ime_spot(position), &Window::X(ref w) => w.set_ime_position(position),
&Window::Wayland(_) => (), &Window::Wayland(_) => (),
} }
} }
@ -355,21 +363,21 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle { pub fn current_monitor(&self) -> RootMonitorHandle {
match self { match self {
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.get_current_monitor()) }, &Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.current_monitor()) },
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.get_current_monitor()) }, &Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.current_monitor()) },
} }
} }
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
match self { match self {
&Window::X(ref window) => window.get_available_monitors() &Window::X(ref window) => window.available_monitors()
.into_iter() .into_iter()
.map(MonitorHandle::X) .map(MonitorHandle::X)
.collect(), .collect(),
&Window::Wayland(ref window) => window.get_available_monitors() &Window::Wayland(ref window) => window.available_monitors()
.into_iter() .into_iter()
.map(MonitorHandle::Wayland) .map(MonitorHandle::Wayland)
.collect(), .collect(),
@ -377,10 +385,10 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
match self { match self {
&Window::X(ref window) => MonitorHandle::X(window.get_primary_monitor()), &Window::X(ref window) => MonitorHandle::X(window.primary_monitor()),
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.get_primary_monitor()), &Window::Wayland(ref window) => MonitorHandle::Wayland(window.primary_monitor()),
} }
} }
} }
@ -481,16 +489,16 @@ impl<T:'static> EventLoop<T> {
} }
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
match *self { match *self {
EventLoop::Wayland(ref evlp) => evlp EventLoop::Wayland(ref evlp) => evlp
.get_available_monitors() .available_monitors()
.into_iter() .into_iter()
.map(MonitorHandle::Wayland) .map(MonitorHandle::Wayland)
.collect(), .collect(),
EventLoop::X(ref evlp) => evlp EventLoop::X(ref evlp) => evlp
.x_connection() .x_connection()
.get_available_monitors() .available_monitors()
.into_iter() .into_iter()
.map(MonitorHandle::X) .map(MonitorHandle::X)
.collect(), .collect(),
@ -498,10 +506,10 @@ impl<T:'static> EventLoop<T> {
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
match *self { match *self {
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.get_primary_monitor()), EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.primary_monitor()),
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().get_primary_monitor()), EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().primary_monitor()),
} }
} }
@ -574,4 +582,4 @@ fn sticky_exit_callback<T, F>(
}; };
// user callback // user callback
callback(evt, target, cf) callback(evt, target, cf)
} }

View file

@ -296,15 +296,15 @@ impl<T: 'static> EventLoop<T> {
callback(::event::Event::LoopDestroyed, &self.window_target, &mut control_flow); callback(::event::Event::LoopDestroyed, &self.window_target, &mut control_flow);
} }
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
get_primary_monitor(&self.outputs) primary_monitor(&self.outputs)
} }
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors(&self.outputs) available_monitors(&self.outputs)
} }
pub fn get_display(&self) -> &Display { pub fn display(&self) -> &Display {
&*self.display &*self.display
} }
@ -532,11 +532,11 @@ impl fmt::Debug for MonitorHandle {
} }
let monitor_id_proxy = MonitorHandle { let monitor_id_proxy = MonitorHandle {
name: self.get_name(), name: self.name(),
native_identifier: self.get_native_identifier(), native_identifier: self.native_identifier(),
dimensions: self.get_dimensions(), dimensions: self.dimensions(),
position: self.get_position(), position: self.position(),
hidpi_factor: self.get_hidpi_factor(), hidpi_factor: self.hidpi_factor(),
}; };
monitor_id_proxy.fmt(f) monitor_id_proxy.fmt(f)
@ -544,18 +544,18 @@ impl fmt::Debug for MonitorHandle {
} }
impl MonitorHandle { impl MonitorHandle {
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
self.mgr.with_info(&self.proxy, |_, info| { self.mgr.with_info(&self.proxy, |_, info| {
format!("{} ({})", info.model, info.make) format!("{} ({})", info.model, info.make)
}) })
} }
#[inline] #[inline]
pub fn get_native_identifier(&self) -> u32 { pub fn native_identifier(&self) -> u32 {
self.mgr.with_info(&self.proxy, |id, _| id).unwrap_or(0) self.mgr.with_info(&self.proxy, |id, _| id).unwrap_or(0)
} }
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
match self.mgr.with_info(&self.proxy, |_, info| { match self.mgr.with_info(&self.proxy, |_, info| {
info.modes info.modes
.iter() .iter()
@ -567,7 +567,7 @@ impl MonitorHandle {
}.into() }.into()
} }
pub fn get_position(&self) -> PhysicalPosition { pub fn position(&self) -> PhysicalPosition {
self.mgr self.mgr
.with_info(&self.proxy, |_, info| info.location) .with_info(&self.proxy, |_, info| info.location)
.unwrap_or((0, 0)) .unwrap_or((0, 0))
@ -575,14 +575,14 @@ impl MonitorHandle {
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> i32 { pub fn hidpi_factor(&self) -> i32 {
self.mgr self.mgr
.with_info(&self.proxy, |_, info| info.scale_factor) .with_info(&self.proxy, |_, info| info.scale_factor)
.unwrap_or(1) .unwrap_or(1)
} }
} }
pub fn get_primary_monitor(outputs: &OutputMgr) -> MonitorHandle { pub fn primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
outputs.with_all(|list| { outputs.with_all(|list| {
if let Some(&(_, ref proxy, _)) = list.first() { if let Some(&(_, ref proxy, _)) = list.first() {
MonitorHandle { MonitorHandle {
@ -595,7 +595,7 @@ pub fn get_primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
}) })
} }
pub fn get_available_monitors(outputs: &OutputMgr) -> VecDeque<MonitorHandle> { pub fn available_monitors(outputs: &OutputMgr) -> VecDeque<MonitorHandle> {
outputs.with_all(|list| { outputs.with_all(|list| {
list.iter() list.iter()
.map(|&(_, ref proxy, _)| MonitorHandle { .map(|&(_, ref proxy, _)| MonitorHandle {

View file

@ -2,9 +2,10 @@ use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak}; use std::sync::{Arc, Mutex, Weak};
use dpi::{LogicalPosition, LogicalSize}; use dpi::{LogicalPosition, LogicalSize};
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes}; use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
use monitor::MonitorHandle as RootMonitorHandle; use monitor::MonitorHandle as RootMonitorHandle;
use window::{CreationError, WindowAttributes, MouseCursor}; use window::{WindowAttributes, CursorIcon};
use sctk::surface::{get_dpi_factor, get_outputs}; use sctk::surface::{get_dpi_factor, get_outputs};
use sctk::window::{ConceptFrame, Event as WEvent, State as WState, Window as SWindow, Theme}; use sctk::window::{ConceptFrame, Event as WEvent, State as WState, Window as SWindow, Theme};
@ -13,7 +14,7 @@ use sctk::reexports::client::protocol::{wl_seat, wl_surface};
use sctk::output::OutputMgr; use sctk::output::OutputMgr;
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId}; use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
use platform_impl::platform::wayland::event_loop::{get_available_monitors, get_primary_monitor}; use platform_impl::platform::wayland::event_loop::{available_monitors, primary_monitor};
pub struct Window { pub struct Window {
surface: wl_surface::WlSurface, surface: wl_surface::WlSurface,
@ -28,8 +29,8 @@ pub struct Window {
} }
impl Window { impl Window {
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> { pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, RootOsError> {
let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600)); let (width, height) = attributes.inner_size.map(Into::into).unwrap_or((800, 600));
// Create the window // Create the window
let size = Arc::new(Mutex::new((width, height))); let size = Arc::new(Mutex::new((width, height)));
let fullscreen = Arc::new(Mutex::new(false)); let fullscreen = Arc::new(Mutex::new(false));
@ -109,8 +110,8 @@ impl Window {
frame.set_title(attributes.title); frame.set_title(attributes.title);
// min-max dimensions // min-max dimensions
frame.set_min_size(attributes.min_dimensions.map(Into::into)); frame.set_min_size(attributes.min_inner_size.map(Into::into));
frame.set_max_size(attributes.max_dimensions.map(Into::into)); frame.set_max_size(attributes.max_inner_size.map(Into::into));
let kill_switch = Arc::new(Mutex::new(false)); let kill_switch = Arc::new(Mutex::new(false));
let need_frame_refresh = Arc::new(Mutex::new(true)); let need_frame_refresh = Arc::new(Mutex::new(true));
@ -154,35 +155,27 @@ impl Window {
self.frame.lock().unwrap().set_title(title.into()); self.frame.lock().unwrap().set_title(title.into());
} }
#[inline] pub fn set_visible(&self, _visible: bool) {
pub fn show(&self) {
// TODO // TODO
} }
#[inline] #[inline]
pub fn hide(&self) { pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
// TODO Err(NotSupportedError::new())
} }
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
// Not possible with wayland Err(NotSupportedError::new())
None
} }
#[inline] #[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn set_outer_position(&self, _pos: LogicalPosition) {
// Not possible with wayland
None
}
#[inline]
pub fn set_position(&self, _pos: LogicalPosition) {
// Not possible with wayland // Not possible with wayland
} }
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn inner_size(&self) -> LogicalSize {
Some(self.size.lock().unwrap().clone().into()) self.size.lock().unwrap().clone().into()
} }
pub fn request_redraw(&self) { pub fn request_redraw(&self) {
@ -190,10 +183,10 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn outer_size(&self) -> LogicalSize {
let (w, h) = self.size.lock().unwrap().clone(); let (w, h) = self.size.lock().unwrap().clone();
// let (w, h) = super::wayland_window::add_borders(w as i32, h as i32); // let (w, h) = super::wayland_window::add_borders(w as i32, h as i32);
Some((w, h).into()) (w, h).into()
} }
#[inline] #[inline]
@ -205,12 +198,12 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
self.frame.lock().unwrap().set_min_size(dimensions.map(Into::into)); self.frame.lock().unwrap().set_min_size(dimensions.map(Into::into));
} }
#[inline] #[inline]
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
self.frame.lock().unwrap().set_max_size(dimensions.map(Into::into)); self.frame.lock().unwrap().set_max_size(dimensions.map(Into::into));
} }
@ -237,9 +230,9 @@ impl Window {
} }
} }
pub fn get_fullscreen(&self) -> Option<MonitorHandle> { pub fn fullscreen(&self) -> Option<MonitorHandle> {
if *(self.fullscreen.lock().unwrap()) { if *(self.fullscreen.lock().unwrap()) {
Some(self.get_current_monitor()) Some(self.current_monitor())
} else { } else {
None None
} }
@ -265,34 +258,34 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_cursor(&self, _cursor: MouseCursor) { pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
// TODO // TODO
} }
#[inline] #[inline]
pub fn hide_cursor(&self, _hide: bool) { pub fn set_cursor_visible(&self, _visible: bool) {
// TODO: This isn't possible on Wayland yet // TODO: This isn't possible on Wayland yet
} }
#[inline] #[inline]
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> { pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
Err("Cursor grabbing is not yet possible on Wayland.".to_owned()) Err(ExternalError::NotSupported(NotSupportedError::new()))
} }
#[inline] #[inline]
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), ExternalError> {
Err("Setting the cursor position is not yet possible on Wayland.".to_owned()) Err(ExternalError::NotSupported(NotSupportedError::new()))
} }
pub fn get_display(&self) -> &Display { pub fn display(&self) -> &Display {
&*self.display &*self.display
} }
pub fn get_surface(&self) -> &wl_surface::WlSurface { pub fn surface(&self) -> &wl_surface::WlSurface {
&self.surface &self.surface
} }
pub fn get_current_monitor(&self) -> MonitorHandle { pub fn current_monitor(&self) -> MonitorHandle {
let output = get_outputs(&self.surface).last().unwrap().clone(); let output = get_outputs(&self.surface).last().unwrap().clone();
MonitorHandle { MonitorHandle {
proxy: output, proxy: output,
@ -300,12 +293,12 @@ impl Window {
} }
} }
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors(&self.outputs) available_monitors(&self.outputs)
} }
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
get_primary_monitor(&self.outputs) primary_monitor(&self.outputs)
} }
} }

View file

@ -270,7 +270,7 @@ impl<T: 'static> EventProcessor<T> {
let new_inner_size = (xev.width as u32, xev.height as u32); let new_inner_size = (xev.width as u32, xev.height as u32);
let new_inner_position = (xev.x as i32, xev.y as i32); let new_inner_position = (xev.x as i32, xev.y as i32);
let mut monitor = window.get_current_monitor(); // This must be done *before* locking! let mut monitor = window.current_monitor(); // This must be done *before* locking!
let mut shared_state_lock = window.shared_state.lock(); let mut shared_state_lock = window.shared_state.lock();
let (mut resized, moved) = { let (mut resized, moved) = {
@ -534,10 +534,7 @@ impl<T: 'static> EventProcessor<T> {
let device_id = mkdid(xev.deviceid); let device_id = mkdid(xev.deviceid);
if (xev.flags & ffi::XIPointerEmulated) != 0 { if (xev.flags & ffi::XIPointerEmulated) != 0 {
// Deliver multi-touch events instead of emulated mouse events. // Deliver multi-touch events instead of emulated mouse events.
let return_now = self return;
.with_window(xev.event, |window| window.multitouch)
.unwrap_or(true);
if return_now { return; }
} }
let modifiers = ModifiersState::from(xev.mods); let modifiers = ModifiersState::from(xev.mods);
@ -622,7 +619,7 @@ impl<T: 'static> EventProcessor<T> {
}); });
if cursor_moved == Some(true) { if cursor_moved == Some(true) {
let dpi_factor = self.with_window(xev.event, |window| { let dpi_factor = self.with_window(xev.event, |window| {
window.get_hidpi_factor() window.hidpi_factor()
}); });
if let Some(dpi_factor) = dpi_factor { if let Some(dpi_factor) = dpi_factor {
let position = LogicalPosition::from_physical( let position = LogicalPosition::from_physical(
@ -721,7 +718,7 @@ impl<T: 'static> EventProcessor<T> {
}); });
if let Some(dpi_factor) = self.with_window(xev.event, |window| { if let Some(dpi_factor) = self.with_window(xev.event, |window| {
window.get_hidpi_factor() window.hidpi_factor()
}) { }) {
let position = LogicalPosition::from_physical( let position = LogicalPosition::from_physical(
(xev.event_x as f64, xev.event_y as f64), (xev.event_x as f64, xev.event_y as f64),
@ -767,7 +764,7 @@ impl<T: 'static> EventProcessor<T> {
let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) }; let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) };
let dpi_factor = match self.with_window(xev.event, |window| { let dpi_factor = match self.with_window(xev.event, |window| {
window.get_hidpi_factor() window.hidpi_factor()
}) { }) {
Some(dpi_factor) => dpi_factor, Some(dpi_factor) => dpi_factor,
None => return, None => return,
@ -825,7 +822,7 @@ impl<T: 'static> EventProcessor<T> {
_ => unreachable!() _ => unreachable!()
}; };
let dpi_factor = self.with_window(xev.event, |window| { let dpi_factor = self.with_window(xev.event, |window| {
window.get_hidpi_factor() window.hidpi_factor()
}); });
if let Some(dpi_factor) = dpi_factor { if let Some(dpi_factor) = dpi_factor {
let location = LogicalPosition::from_physical( let location = LogicalPosition::from_physical(
@ -960,7 +957,7 @@ impl<T: 'static> EventProcessor<T> {
// In the future, it would be quite easy to emit monitor hotplug events. // In the future, it would be quite easy to emit monitor hotplug events.
let prev_list = monitor::invalidate_cached_monitor_list(); let prev_list = monitor::invalidate_cached_monitor_list();
if let Some(prev_list) = prev_list { if let Some(prev_list) = prev_list {
let new_list = wt.xconn.get_available_monitors(); let new_list = wt.xconn.available_monitors();
for new_monitor in new_list { for new_monitor in new_list {
prev_list prev_list
.iter() .iter()
@ -970,7 +967,7 @@ impl<T: 'static> EventProcessor<T> {
for (window_id, window) in wt.windows.borrow().iter() { for (window_id, window) in wt.windows.borrow().iter() {
if let Some(window) = window.upgrade() { if let Some(window) = window.upgrade() {
// Check if the window is on this monitor // Check if the window is on this monitor
let monitor = window.get_current_monitor(); let monitor = window.current_monitor();
if monitor.name == new_monitor.name { if monitor.name == new_monitor.name {
callback(Event::WindowEvent { callback(Event::WindowEvent {
window_id: mkwid(window_id.0), window_id: mkwid(window_id.0),
@ -978,10 +975,7 @@ impl<T: 'static> EventProcessor<T> {
new_monitor.hidpi_factor new_monitor.hidpi_factor
), ),
}); });
let (width, height) = match window.get_inner_size_physical() { let (width, height) = window.inner_size_physical();
Some(result) => result,
None => continue,
};
let (_, _, flusher) = window.adjust_for_dpi( let (_, _, flusher) = window.adjust_for_dpi(
prev_monitor.hidpi_factor, prev_monitor.hidpi_factor,
new_monitor.hidpi_factor, new_monitor.hidpi_factor,
@ -1007,4 +1001,4 @@ impl<T: 'static> EventProcessor<T> {
Err(_) => (), Err(_) => (),
} }
} }
} }

View file

@ -12,8 +12,9 @@ use super::{ffi, util, XConnection, XError};
use self::inner::{close_im, ImeInner}; use self::inner::{close_im, ImeInner};
use self::input_method::PotentialInputMethods; use self::input_method::PotentialInputMethods;
use self::context::{ImeContextCreationError, ImeContext}; use self::context::ImeContext;
use self::callbacks::*; use self::callbacks::*;
pub use self::context::ImeContextCreationError;
pub type ImeReceiver = Receiver<(ffi::Window, i16, i16)>; pub type ImeReceiver = Receiver<(ffi::Window, i16, i16)>;
pub type ImeSender = Sender<(ffi::Window, i16, i16)>; pub type ImeSender = Sender<(ffi::Window, i16, i16)>;

View file

@ -25,11 +25,12 @@ use std::sync::{Arc, mpsc, Weak, Mutex};
use libc::{self, setlocale, LC_CTYPE}; use libc::{self, setlocale, LC_CTYPE};
use error::OsError as RootOsError;
use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW}; use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW};
use event::{WindowEvent, Event}; use event::{WindowEvent, Event};
use platform_impl::PlatformSpecificWindowBuilderAttributes; use platform_impl::PlatformSpecificWindowBuilderAttributes;
use platform_impl::platform::sticky_exit_callback; use platform_impl::platform::sticky_exit_callback;
use window::{CreationError, WindowAttributes}; use window::{WindowAttributes};
use self::dnd::{Dnd, DndState}; use self::dnd::{Dnd, DndState};
use self::ime::{ImeReceiver, ImeSender, ImeCreationError, Ime}; use self::ime::{ImeReceiver, ImeSender, ImeCreationError, Ime};
use self::event_processor::EventProcessor; use self::event_processor::EventProcessor;
@ -427,7 +428,7 @@ impl Window {
event_loop: &EventLoopWindowTarget<T>, event_loop: &EventLoopWindowTarget<T>,
attribs: WindowAttributes, attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes pl_attribs: PlatformSpecificWindowBuilderAttributes
) -> Result<Self, CreationError> { ) -> Result<Self, RootOsError> {
let window = Arc::new(UnownedWindow::new(&event_loop, attribs, pl_attribs)?); let window = Arc::new(UnownedWindow::new(&event_loop, attribs, pl_attribs)?);
event_loop.windows event_loop.windows
.borrow_mut() .borrow_mut()

View file

@ -67,7 +67,7 @@ impl MonitorHandle {
primary: bool, primary: bool,
) -> Option<Self> { ) -> Option<Self> {
let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr)? }; let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr)? };
let (dimensions, position) = unsafe { (repr.get_dimensions(), repr.get_position()) }; let (dimensions, position) = unsafe { (repr.dimensions(), repr.position()) };
let rect = util::AaRect::new(position, dimensions); let rect = util::AaRect::new(position, dimensions);
Some(MonitorHandle { Some(MonitorHandle {
id, id,
@ -80,32 +80,32 @@ impl MonitorHandle {
}) })
} }
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
Some(self.name.clone()) Some(self.name.clone())
} }
#[inline] #[inline]
pub fn get_native_identifier(&self) -> u32 { pub fn native_identifier(&self) -> u32 {
self.id as u32 self.id as u32
} }
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
self.dimensions.into() self.dimensions.into()
} }
pub fn get_position(&self) -> PhysicalPosition { pub fn position(&self) -> PhysicalPosition {
self.position.into() self.position.into()
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
self.hidpi_factor self.hidpi_factor
} }
} }
impl XConnection { impl XConnection {
pub fn get_monitor_for_window(&self, window_rect: Option<util::AaRect>) -> MonitorHandle { pub fn get_monitor_for_window(&self, window_rect: Option<util::AaRect>) -> MonitorHandle {
let monitors = self.get_available_monitors(); let monitors = self.available_monitors();
let default = monitors let default = monitors
.get(0) .get(0)
.expect("[winit] Failed to find any monitors using XRandR."); .expect("[winit] Failed to find any monitors using XRandR.");
@ -206,7 +206,7 @@ impl XConnection {
} }
} }
pub fn get_available_monitors(&self) -> Vec<MonitorHandle> { pub fn available_monitors(&self) -> Vec<MonitorHandle> {
let mut monitors_lock = MONITORS.lock(); let mut monitors_lock = MONITORS.lock();
(*monitors_lock) (*monitors_lock)
.as_ref() .as_ref()
@ -222,8 +222,8 @@ impl XConnection {
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
self.get_available_monitors() self.available_monitors()
.into_iter() .into_iter()
.find(|monitor| monitor.primary) .find(|monitor| monitor.primary)
.expect("[winit] Failed to find any monitors using XRandR.") .expect("[winit] Failed to find any monitors using XRandR.")

View file

@ -152,7 +152,7 @@ impl FrameExtentsHeuristic {
} }
impl XConnection { impl XConnection {
// This is adequate for get_inner_position // This is adequate for inner_position
pub fn translate_coords(&self, window: ffi::Window, root: ffi::Window) -> Result<TranslatedCoords, XError> { pub fn translate_coords(&self, window: ffi::Window, root: ffi::Window) -> Result<TranslatedCoords, XError> {
let mut translated_coords: TranslatedCoords = unsafe { mem::uninitialized() }; let mut translated_coords: TranslatedCoords = unsafe { mem::uninitialized() };
unsafe { unsafe {
@ -171,7 +171,7 @@ impl XConnection {
self.check_errors().map(|_| translated_coords) self.check_errors().map(|_| translated_coords)
} }
// This is adequate for get_inner_size // This is adequate for inner_size
pub fn get_geometry(&self, window: ffi::Window) -> Result<Geometry, XError> { pub fn get_geometry(&self, window: ffi::Window) -> Result<Geometry, XError> {
let mut geometry: Geometry = unsafe { mem::uninitialized() }; let mut geometry: Geometry = unsafe { mem::uninitialized() };
let _status = unsafe { let _status = unsafe {

View file

@ -51,14 +51,14 @@ impl MonitorRepr {
} }
} }
pub unsafe fn get_dimensions(&self) -> (u32, u32) { pub unsafe fn dimensions(&self) -> (u32, u32) {
match *self { match *self {
MonitorRepr::Monitor(monitor) => ((*monitor).width as u32, (*monitor).height as u32), MonitorRepr::Monitor(monitor) => ((*monitor).width as u32, (*monitor).height as u32),
MonitorRepr::Crtc(crtc) => ((*crtc).width as u32, (*crtc).height as u32), MonitorRepr::Crtc(crtc) => ((*crtc).width as u32, (*crtc).height as u32),
} }
} }
pub unsafe fn get_position(&self) -> (i32, i32) { pub unsafe fn position(&self) -> (i32, i32) {
match *self { match *self {
MonitorRepr::Monitor(monitor) => ((*monitor).x as i32, (*monitor).y as i32), MonitorRepr::Monitor(monitor) => ((*monitor).x as i32, (*monitor).y as i32),
MonitorRepr::Crtc(crtc) => ((*crtc).x as i32, (*crtc).y as i32), MonitorRepr::Crtc(crtc) => ((*crtc).x as i32, (*crtc).y as i32),
@ -123,7 +123,7 @@ impl XConnection {
dpi / 96. dpi / 96.
} else { } else {
calc_dpi_factor( calc_dpi_factor(
repr.get_dimensions(), repr.dimensions(),
((*output_info).mm_width as u64, (*output_info).mm_height as u64), ((*output_info).mm_width as u64, (*output_info).mm_height as u64),
) )
}; };

View file

@ -8,11 +8,12 @@ use std::sync::Arc;
use libc; use libc;
use parking_lot::Mutex; use parking_lot::Mutex;
use window::{Icon, MouseCursor, WindowAttributes}; use error::{ExternalError, NotSupportedError, OsError as RootOsError};
use window::CreationError::{self, OsError}; use window::{Icon, CursorIcon, WindowAttributes};
use dpi::{LogicalPosition, LogicalSize}; use dpi::{LogicalPosition, LogicalSize};
use platform_impl::MonitorHandle as PlatformMonitorHandle; use platform_impl::MonitorHandle as PlatformMonitorHandle;
use platform_impl::PlatformSpecificWindowBuilderAttributes; use platform_impl::{OsError, PlatformSpecificWindowBuilderAttributes};
use platform_impl::x11::ime::ImeContextCreationError;
use platform_impl::x11::MonitorHandle as X11MonitorHandle; use platform_impl::x11::MonitorHandle as X11MonitorHandle;
use monitor::MonitorHandle as RootMonitorHandle; use monitor::MonitorHandle as RootMonitorHandle;
@ -42,8 +43,8 @@ pub struct SharedState {
// Used to restore position after exiting fullscreen. // Used to restore position after exiting fullscreen.
pub restore_position: Option<(i32, i32)>, pub restore_position: Option<(i32, i32)>,
pub frame_extents: Option<util::FrameExtentsHeuristic>, pub frame_extents: Option<util::FrameExtentsHeuristic>,
pub min_dimensions: Option<LogicalSize>, pub min_inner_size: Option<LogicalSize>,
pub max_dimensions: Option<LogicalSize>, pub max_inner_size: Option<LogicalSize>,
} }
impl SharedState { impl SharedState {
@ -62,11 +63,10 @@ pub struct UnownedWindow {
xwindow: ffi::Window, // never changes xwindow: ffi::Window, // never changes
root: ffi::Window, // never changes root: ffi::Window, // never changes
screen_id: i32, // never changes screen_id: i32, // never changes
cursor: Mutex<MouseCursor>, cursor: Mutex<CursorIcon>,
cursor_grabbed: Mutex<bool>, cursor_grabbed: Mutex<bool>,
cursor_hidden: Mutex<bool>, cursor_visible: Mutex<bool>,
ime_sender: Mutex<ImeSender>, ime_sender: Mutex<ImeSender>,
pub multitouch: bool, // never changes
pub shared_state: Mutex<SharedState>, pub shared_state: Mutex<SharedState>,
pending_redraws: Arc<::std::sync::Mutex<HashSet<WindowId>>>, pending_redraws: Arc<::std::sync::Mutex<HashSet<WindowId>>>,
} }
@ -76,15 +76,15 @@ impl UnownedWindow {
event_loop: &EventLoopWindowTarget<T>, event_loop: &EventLoopWindowTarget<T>,
window_attrs: WindowAttributes, window_attrs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<UnownedWindow, CreationError> { ) -> Result<UnownedWindow, RootOsError> {
let xconn = &event_loop.xconn; let xconn = &event_loop.xconn;
let root = event_loop.root; let root = event_loop.root;
let monitors = xconn.get_available_monitors(); let monitors = xconn.available_monitors();
let dpi_factor = if !monitors.is_empty() { let dpi_factor = if !monitors.is_empty() {
let mut dpi_factor = Some(monitors[0].get_hidpi_factor()); let mut dpi_factor = Some(monitors[0].hidpi_factor());
for monitor in &monitors { for monitor in &monitors {
if Some(monitor.get_hidpi_factor()) != dpi_factor { if Some(monitor.hidpi_factor()) != dpi_factor {
dpi_factor = None; dpi_factor = None;
} }
} }
@ -96,7 +96,7 @@ impl UnownedWindow {
let mut dpi_factor = None; let mut dpi_factor = None;
for monitor in &monitors { for monitor in &monitors {
if monitor.rect.contains_point(x, y) { if monitor.rect.contains_point(x, y) {
dpi_factor = Some(monitor.get_hidpi_factor()); dpi_factor = Some(monitor.hidpi_factor());
break; break;
} }
} }
@ -105,31 +105,31 @@ impl UnownedWindow {
.unwrap_or(1.0) .unwrap_or(1.0)
}) })
} else { } else {
return Err(OsError(format!("No monitors were detected."))); return Err(os_error!(OsError::XMisc("No monitors were detected.")));
}; };
info!("Guessed window DPI factor: {}", dpi_factor); info!("Guessed window DPI factor: {}", dpi_factor);
let max_dimensions: Option<(u32, u32)> = window_attrs.max_dimensions.map(|size| { let max_inner_size: Option<(u32, u32)> = window_attrs.max_inner_size.map(|size| {
size.to_physical(dpi_factor).into() size.to_physical(dpi_factor).into()
}); });
let min_dimensions: Option<(u32, u32)> = window_attrs.min_dimensions.map(|size| { let min_inner_size: Option<(u32, u32)> = window_attrs.min_inner_size.map(|size| {
size.to_physical(dpi_factor).into() size.to_physical(dpi_factor).into()
}); });
let dimensions = { let dimensions = {
// x11 only applies constraints when the window is actively resized // x11 only applies constraints when the window is actively resized
// by the user, so we have to manually apply the initial constraints // by the user, so we have to manually apply the initial constraints
let mut dimensions: (u32, u32) = window_attrs.dimensions let mut dimensions: (u32, u32) = window_attrs.inner_size
.or_else(|| Some((800, 600).into())) .or_else(|| Some((800, 600).into()))
.map(|size| size.to_physical(dpi_factor)) .map(|size| size.to_physical(dpi_factor))
.map(Into::into) .map(Into::into)
.unwrap(); .unwrap();
if let Some(max) = max_dimensions { if let Some(max) = max_inner_size {
dimensions.0 = cmp::min(dimensions.0, max.0); dimensions.0 = cmp::min(dimensions.0, max.0);
dimensions.1 = cmp::min(dimensions.1, max.1); dimensions.1 = cmp::min(dimensions.1, max.1);
} }
if let Some(min) = min_dimensions { if let Some(min) = min_inner_size {
dimensions.0 = cmp::max(dimensions.0, min.0); dimensions.0 = cmp::max(dimensions.0, min.0);
dimensions.1 = cmp::max(dimensions.1, min.1); dimensions.1 = cmp::max(dimensions.1, min.1);
} }
@ -209,10 +209,9 @@ impl UnownedWindow {
root, root,
screen_id, screen_id,
cursor: Default::default(), cursor: Default::default(),
cursor_grabbed: Default::default(), cursor_grabbed: Mutex::new(false),
cursor_hidden: Default::default(), cursor_visible: Mutex::new(true),
ime_sender: Mutex::new(event_loop.ime_sender.clone()), ime_sender: Mutex::new(event_loop.ime_sender.clone()),
multitouch: window_attrs.multitouch,
shared_state: SharedState::new(dpi_factor), shared_state: SharedState::new(dpi_factor),
pending_redraws: event_loop.pending_redraws.clone(), pending_redraws: event_loop.pending_redraws.clone(),
}; };
@ -290,27 +289,27 @@ impl UnownedWindow {
// set size hints // set size hints
{ {
let mut min_dimensions = window_attrs.min_dimensions let mut min_inner_size = window_attrs.min_inner_size
.map(|size| size.to_physical(dpi_factor)); .map(|size| size.to_physical(dpi_factor));
let mut max_dimensions = window_attrs.max_dimensions let mut max_inner_size = window_attrs.max_inner_size
.map(|size| size.to_physical(dpi_factor)); .map(|size| size.to_physical(dpi_factor));
if !window_attrs.resizable { if !window_attrs.resizable {
if util::wm_name_is_one_of(&["Xfwm4"]) { if util::wm_name_is_one_of(&["Xfwm4"]) {
warn!("To avoid a WM bug, disabling resizing has no effect on Xfwm4"); warn!("To avoid a WM bug, disabling resizing has no effect on Xfwm4");
} else { } else {
max_dimensions = Some(dimensions.into()); max_inner_size = Some(dimensions.into());
min_dimensions = Some(dimensions.into()); min_inner_size = Some(dimensions.into());
let mut shared_state_lock = window.shared_state.lock(); let mut shared_state_lock = window.shared_state.lock();
shared_state_lock.min_dimensions = window_attrs.min_dimensions; shared_state_lock.min_inner_size = window_attrs.min_inner_size;
shared_state_lock.max_dimensions = window_attrs.max_dimensions; shared_state_lock.max_inner_size = window_attrs.max_inner_size;
} }
} }
let mut normal_hints = util::NormalHints::new(xconn); let mut normal_hints = util::NormalHints::new(xconn);
normal_hints.set_size(Some(dimensions)); normal_hints.set_size(Some(dimensions));
normal_hints.set_min_size(min_dimensions.map(Into::into)); normal_hints.set_min_size(min_inner_size.map(Into::into));
normal_hints.set_max_size(max_dimensions.map(Into::into)); normal_hints.set_max_size(max_inner_size.map(Into::into));
normal_hints.set_resize_increments(pl_attribs.resize_increments); normal_hints.set_resize_increments(pl_attribs.resize_increments);
normal_hints.set_base_size(pl_attribs.base_size); normal_hints.set_base_size(pl_attribs.base_size);
xconn.set_normal_hints(window.xwindow, normal_hints).queue(); xconn.set_normal_hints(window.xwindow, normal_hints).queue();
@ -347,13 +346,13 @@ impl UnownedWindow {
&mut supported_ptr, &mut supported_ptr,
); );
if supported_ptr == ffi::False { if supported_ptr == ffi::False {
return Err(OsError(format!("`XkbSetDetectableAutoRepeat` failed"))); return Err(os_error!(OsError::XMisc("`XkbSetDetectableAutoRepeat` failed")));
} }
} }
// Select XInput2 events // Select XInput2 events
let mask = { let mask = {
let mut mask = ffi::XI_MotionMask let mask = ffi::XI_MotionMask
| ffi::XI_ButtonPressMask | ffi::XI_ButtonPressMask
| ffi::XI_ButtonReleaseMask | ffi::XI_ButtonReleaseMask
//| ffi::XI_KeyPressMask //| ffi::XI_KeyPressMask
@ -361,12 +360,10 @@ impl UnownedWindow {
| ffi::XI_EnterMask | ffi::XI_EnterMask
| ffi::XI_LeaveMask | ffi::XI_LeaveMask
| ffi::XI_FocusInMask | ffi::XI_FocusInMask
| ffi::XI_FocusOutMask; | ffi::XI_FocusOutMask
if window_attrs.multitouch { | ffi::XI_TouchBeginMask
mask |= ffi::XI_TouchBeginMask | ffi::XI_TouchUpdateMask
| ffi::XI_TouchUpdateMask | ffi::XI_TouchEndMask;
| ffi::XI_TouchEndMask;
}
mask mask
}; };
xconn.select_xinput_events(window.xwindow, ffi::XIAllMasterDevices, mask).queue(); xconn.select_xinput_events(window.xwindow, ffi::XIAllMasterDevices, mask).queue();
@ -376,7 +373,11 @@ impl UnownedWindow {
.borrow_mut() .borrow_mut()
.create_context(window.xwindow); .create_context(window.xwindow);
if let Err(err) = result { if let Err(err) = result {
return Err(OsError(format!("Failed to create input context: {:?}", err))); let e = match err {
ImeContextCreationError::XError(err) => OsError::XError(err),
ImeContextCreationError::Null => OsError::XMisc("IME Context creation failed"),
};
return Err(os_error!(e));
} }
} }
@ -415,18 +416,16 @@ impl UnownedWindow {
// We never want to give the user a broken window, since by then, it's too late to handle. // We never want to give the user a broken window, since by then, it's too late to handle.
xconn.sync_with_server() xconn.sync_with_server()
.map(|_| window) .map(|_| window)
.map_err(|x_err| OsError( .map_err(|x_err| os_error!(OsError::XError(x_err)))
format!("X server returned error while building window: {:?}", x_err)
))
} }
fn logicalize_coords(&self, (x, y): (i32, i32)) -> LogicalPosition { fn logicalize_coords(&self, (x, y): (i32, i32)) -> LogicalPosition {
let dpi = self.get_hidpi_factor(); let dpi = self.hidpi_factor();
LogicalPosition::from_physical((x, y), dpi) LogicalPosition::from_physical((x, y), dpi)
} }
fn logicalize_size(&self, (width, height): (u32, u32)) -> LogicalSize { fn logicalize_size(&self, (width, height): (u32, u32)) -> LogicalSize {
let dpi = self.get_hidpi_factor(); let dpi = self.hidpi_factor();
LogicalSize::from_physical((width, height), dpi) LogicalSize::from_physical((width, height), dpi)
} }
@ -535,9 +534,9 @@ impl UnownedWindow {
flusher flusher
}, },
Some(RootMonitorHandle { inner: PlatformMonitorHandle::X(monitor) }) => { Some(RootMonitorHandle { inner: PlatformMonitorHandle::X(monitor) }) => {
let window_position = self.get_position_physical(); let window_position = self.outer_position_physical();
self.shared_state.lock().restore_position = window_position; self.shared_state.lock().restore_position = Some(window_position);
let monitor_origin: (i32, i32) = monitor.get_position().into(); let monitor_origin: (i32, i32) = monitor.position().into();
self.set_position_inner(monitor_origin.0, monitor_origin.1).queue(); self.set_position_inner(monitor_origin.0, monitor_origin.1).queue();
self.set_fullscreen_hint(true) self.set_fullscreen_hint(true)
} }
@ -546,7 +545,7 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> { pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
self.shared_state.lock().fullscreen.clone() self.shared_state.lock().fullscreen.clone()
} }
@ -559,17 +558,15 @@ impl UnownedWindow {
self.invalidate_cached_frame_extents(); self.invalidate_cached_frame_extents();
} }
fn get_rect(&self) -> Option<util::AaRect> { fn get_rect(&self) -> util::AaRect {
// TODO: This might round-trip more times than needed. // TODO: This might round-trip more times than needed.
if let (Some(position), Some(size)) = (self.get_position_physical(), self.get_outer_size_physical()) { let position = self.outer_position_physical();
Some(util::AaRect::new(position, size)) let size = self.outer_size_physical();
} else { util::AaRect::new(position, size)
None
}
} }
#[inline] #[inline]
pub fn get_current_monitor(&self) -> X11MonitorHandle { pub fn current_monitor(&self) -> X11MonitorHandle {
let monitor = self.shared_state let monitor = self.shared_state
.lock() .lock()
.last_monitor .last_monitor
@ -577,18 +574,18 @@ impl UnownedWindow {
.cloned(); .cloned();
monitor monitor
.unwrap_or_else(|| { .unwrap_or_else(|| {
let monitor = self.xconn.get_monitor_for_window(self.get_rect()).to_owned(); let monitor = self.xconn.get_monitor_for_window(Some(self.get_rect())).to_owned();
self.shared_state.lock().last_monitor = Some(monitor.clone()); self.shared_state.lock().last_monitor = Some(monitor.clone());
monitor monitor
}) })
} }
pub fn get_available_monitors(&self) -> Vec<X11MonitorHandle> { pub fn available_monitors(&self) -> Vec<X11MonitorHandle> {
self.xconn.get_available_monitors() self.xconn.available_monitors()
} }
pub fn get_primary_monitor(&self) -> X11MonitorHandle { pub fn primary_monitor(&self) -> X11MonitorHandle {
self.xconn.get_primary_monitor() self.xconn.primary_monitor()
} }
fn set_maximized_inner(&self, maximized: bool) -> util::Flusher { fn set_maximized_inner(&self, maximized: bool) -> util::Flusher {
@ -702,20 +699,18 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn show(&self) { pub fn set_visible(&self, visible: bool) {
unsafe { match visible {
(self.xconn.xlib.XMapRaised)(self.xconn.display, self.xwindow); true => unsafe {
self.xconn.flush_requests() (self.xconn.xlib.XMapRaised)(self.xconn.display, self.xwindow);
.expect("Failed to call XMapRaised"); self.xconn.flush_requests()
} .expect("Failed to call XMapRaised");
} },
false => unsafe {
#[inline] (self.xconn.xlib.XUnmapWindow)(self.xconn.display, self.xwindow);
pub fn hide(&self) { self.xconn.flush_requests()
unsafe { .expect("Failed to call XUnmapWindow");
(self.xconn.xlib.XUnmapWindow)(self.xconn.display, self.xwindow); }
self.xconn.flush_requests()
.expect("Failed to call XUnmapWindow");
} }
} }
@ -728,39 +723,40 @@ impl UnownedWindow {
(*self.shared_state.lock()).frame_extents.take(); (*self.shared_state.lock()).frame_extents.take();
} }
pub(crate) fn get_position_physical(&self) -> Option<(i32, i32)> { pub(crate) fn outer_position_physical(&self) -> (i32, i32) {
let extents = (*self.shared_state.lock()).frame_extents.clone(); let extents = (*self.shared_state.lock()).frame_extents.clone();
if let Some(extents) = extents { if let Some(extents) = extents {
self.get_inner_position_physical() let (x, y) = self.inner_position_physical();
.map(|(x, y)| extents.inner_pos_to_outer(x, y)) extents.inner_pos_to_outer(x, y)
} else { } else {
self.update_cached_frame_extents(); self.update_cached_frame_extents();
self.get_position_physical() self.outer_position_physical()
} }
} }
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
let extents = (*self.shared_state.lock()).frame_extents.clone(); let extents = (*self.shared_state.lock()).frame_extents.clone();
if let Some(extents) = extents { if let Some(extents) = extents {
self.get_inner_position() let logical = self.inner_position().unwrap();
.map(|logical| extents.inner_pos_to_outer_logical(logical, self.get_hidpi_factor())) Ok(extents.inner_pos_to_outer_logical(logical, self.hidpi_factor()))
} else { } else {
self.update_cached_frame_extents(); self.update_cached_frame_extents();
self.get_position() self.outer_position()
} }
} }
pub(crate) fn get_inner_position_physical(&self) -> Option<(i32, i32)> { pub(crate) fn inner_position_physical(&self) -> (i32, i32) {
// This should be okay to unwrap since the only error XTranslateCoordinates can return
// is BadWindow, and if the window handle is bad we have bigger problems.
self.xconn.translate_coords(self.xwindow, self.root) self.xconn.translate_coords(self.xwindow, self.root)
.ok()
.map(|coords| (coords.x_rel_root, coords.y_rel_root)) .map(|coords| (coords.x_rel_root, coords.y_rel_root))
.unwrap()
} }
#[inline] #[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
self.get_inner_position_physical() Ok(self.logicalize_coords(self.inner_position_physical()))
.map(|coords| self.logicalize_coords(coords))
} }
pub(crate) fn set_position_inner(&self, mut x: i32, mut y: i32) -> util::Flusher { pub(crate) fn set_position_inner(&self, mut x: i32, mut y: i32) -> util::Flusher {
@ -794,43 +790,44 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn set_position(&self, logical_position: LogicalPosition) { pub fn set_outer_position(&self, logical_position: LogicalPosition) {
let (x, y) = logical_position.to_physical(self.get_hidpi_factor()).into(); let (x, y) = logical_position.to_physical(self.hidpi_factor()).into();
self.set_position_physical(x, y); self.set_position_physical(x, y);
} }
pub(crate) fn get_inner_size_physical(&self) -> Option<(u32, u32)> { pub(crate) fn inner_size_physical(&self) -> (u32, u32) {
// This should be okay to unwrap since the only error XGetGeometry can return
// is BadWindow, and if the window handle is bad we have bigger problems.
self.xconn.get_geometry(self.xwindow) self.xconn.get_geometry(self.xwindow)
.ok()
.map(|geo| (geo.width, geo.height)) .map(|geo| (geo.width, geo.height))
.unwrap()
} }
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn inner_size(&self) -> LogicalSize {
self.get_inner_size_physical() self.logicalize_size(self.inner_size_physical())
.map(|size| self.logicalize_size(size))
} }
pub(crate) fn get_outer_size_physical(&self) -> Option<(u32, u32)> { pub(crate) fn outer_size_physical(&self) -> (u32, u32) {
let extents = self.shared_state.lock().frame_extents.clone(); let extents = self.shared_state.lock().frame_extents.clone();
if let Some(extents) = extents { if let Some(extents) = extents {
self.get_inner_size_physical() let (w, h) = self.inner_size_physical();
.map(|(w, h)| extents.inner_size_to_outer(w, h)) extents.inner_size_to_outer(w, h)
} else { } else {
self.update_cached_frame_extents(); self.update_cached_frame_extents();
self.get_outer_size_physical() self.outer_size_physical()
} }
} }
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn outer_size(&self) -> LogicalSize {
let extents = self.shared_state.lock().frame_extents.clone(); let extents = self.shared_state.lock().frame_extents.clone();
if let Some(extents) = extents { if let Some(extents) = extents {
self.get_inner_size() let logical = self.inner_size();
.map(|logical| extents.inner_size_to_outer_logical(logical, self.get_hidpi_factor())) extents.inner_size_to_outer_logical(logical, self.hidpi_factor())
} else { } else {
self.update_cached_frame_extents(); self.update_cached_frame_extents();
self.get_outer_size() self.outer_size()
} }
} }
@ -848,7 +845,7 @@ impl UnownedWindow {
#[inline] #[inline]
pub fn set_inner_size(&self, logical_size: LogicalSize) { pub fn set_inner_size(&self, logical_size: LogicalSize) {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
let (width, height) = logical_size.to_physical(dpi_factor).into(); let (width, height) = logical_size.to_physical(dpi_factor).into();
self.set_inner_size_physical(width, height); self.set_inner_size_physical(width, height);
} }
@ -861,32 +858,32 @@ impl UnownedWindow {
self.xconn.set_normal_hints(self.xwindow, normal_hints).flush() self.xconn.set_normal_hints(self.xwindow, normal_hints).flush()
} }
pub(crate) fn set_min_dimensions_physical(&self, dimensions: Option<(u32, u32)>) { pub(crate) fn set_min_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
self.update_normal_hints(|normal_hints| normal_hints.set_min_size(dimensions)) self.update_normal_hints(|normal_hints| normal_hints.set_min_size(dimensions))
.expect("Failed to call `XSetWMNormalHints`"); .expect("Failed to call `XSetWMNormalHints`");
} }
#[inline] #[inline]
pub fn set_min_dimensions(&self, logical_dimensions: Option<LogicalSize>) { pub fn set_min_inner_size(&self, logical_dimensions: Option<LogicalSize>) {
self.shared_state.lock().min_dimensions = logical_dimensions; self.shared_state.lock().min_inner_size = logical_dimensions;
let physical_dimensions = logical_dimensions.map(|logical_dimensions| { let physical_dimensions = logical_dimensions.map(|logical_dimensions| {
logical_dimensions.to_physical(self.get_hidpi_factor()).into() logical_dimensions.to_physical(self.hidpi_factor()).into()
}); });
self.set_min_dimensions_physical(physical_dimensions); self.set_min_inner_size_physical(physical_dimensions);
} }
pub(crate) fn set_max_dimensions_physical(&self, dimensions: Option<(u32, u32)>) { pub(crate) fn set_max_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
self.update_normal_hints(|normal_hints| normal_hints.set_max_size(dimensions)) self.update_normal_hints(|normal_hints| normal_hints.set_max_size(dimensions))
.expect("Failed to call `XSetWMNormalHints`"); .expect("Failed to call `XSetWMNormalHints`");
} }
#[inline] #[inline]
pub fn set_max_dimensions(&self, logical_dimensions: Option<LogicalSize>) { pub fn set_max_inner_size(&self, logical_dimensions: Option<LogicalSize>) {
self.shared_state.lock().max_dimensions = logical_dimensions; self.shared_state.lock().max_inner_size = logical_dimensions;
let physical_dimensions = logical_dimensions.map(|logical_dimensions| { let physical_dimensions = logical_dimensions.map(|logical_dimensions| {
logical_dimensions.to_physical(self.get_hidpi_factor()).into() logical_dimensions.to_physical(self.hidpi_factor()).into()
}); });
self.set_max_dimensions_physical(physical_dimensions); self.set_max_inner_size_physical(physical_dimensions);
} }
pub(crate) fn adjust_for_dpi( pub(crate) fn adjust_for_dpi(
@ -936,47 +933,47 @@ impl UnownedWindow {
let (logical_min, logical_max) = if resizable { let (logical_min, logical_max) = if resizable {
let shared_state_lock = self.shared_state.lock(); let shared_state_lock = self.shared_state.lock();
(shared_state_lock.min_dimensions, shared_state_lock.max_dimensions) (shared_state_lock.min_inner_size, shared_state_lock.max_inner_size)
} else { } else {
let window_size = self.get_inner_size(); let window_size = Some(self.inner_size());
(window_size.clone(), window_size) (window_size.clone(), window_size)
}; };
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
let min_dimensions = logical_min let min_inner_size = logical_min
.map(|logical_size| logical_size.to_physical(dpi_factor)) .map(|logical_size| logical_size.to_physical(dpi_factor))
.map(Into::into); .map(Into::into);
let max_dimensions = logical_max let max_inner_size = logical_max
.map(|logical_size| logical_size.to_physical(dpi_factor)) .map(|logical_size| logical_size.to_physical(dpi_factor))
.map(Into::into); .map(Into::into);
self.update_normal_hints(|normal_hints| { self.update_normal_hints(|normal_hints| {
normal_hints.set_min_size(min_dimensions); normal_hints.set_min_size(min_inner_size);
normal_hints.set_max_size(max_dimensions); normal_hints.set_max_size(max_inner_size);
}).expect("Failed to call `XSetWMNormalHints`"); }).expect("Failed to call `XSetWMNormalHints`");
} }
#[inline] #[inline]
pub fn get_xlib_display(&self) -> *mut c_void { pub fn xlib_display(&self) -> *mut c_void {
self.xconn.display as _ self.xconn.display as _
} }
#[inline] #[inline]
pub fn get_xlib_screen_id(&self) -> c_int { pub fn xlib_screen_id(&self) -> c_int {
self.screen_id self.screen_id
} }
#[inline] #[inline]
pub fn get_xlib_xconnection(&self) -> Arc<XConnection> { pub fn xlib_xconnection(&self) -> Arc<XConnection> {
Arc::clone(&self.xconn) Arc::clone(&self.xconn)
} }
#[inline] #[inline]
pub fn get_xlib_window(&self) -> c_ulong { pub fn xlib_window(&self) -> c_ulong {
self.xwindow self.xwindow
} }
#[inline] #[inline]
pub fn get_xcb_connection(&self) -> *mut c_void { pub fn xcb_connection(&self) -> *mut c_void {
unsafe { unsafe {
(self.xconn.xlib_xcb.XGetXCBConnection)(self.xconn.display) as *mut _ (self.xconn.xlib_xcb.XGetXCBConnection)(self.xconn.display) as *mut _
} }
@ -1001,7 +998,7 @@ impl UnownedWindow {
0 0
} }
fn get_cursor(&self, cursor: MouseCursor) -> ffi::Cursor { fn get_cursor(&self, cursor: CursorIcon) -> ffi::Cursor {
let load = |name: &[u8]| { let load = |name: &[u8]| {
self.load_cursor(name) self.load_cursor(name)
}; };
@ -1015,48 +1012,48 @@ impl UnownedWindow {
// //
// Try the better looking (or more suiting) names first. // Try the better looking (or more suiting) names first.
match cursor { match cursor {
MouseCursor::Alias => load(b"link\0"), CursorIcon::Alias => load(b"link\0"),
MouseCursor::Arrow => load(b"arrow\0"), CursorIcon::Arrow => load(b"arrow\0"),
MouseCursor::Cell => load(b"plus\0"), CursorIcon::Cell => load(b"plus\0"),
MouseCursor::Copy => load(b"copy\0"), CursorIcon::Copy => load(b"copy\0"),
MouseCursor::Crosshair => load(b"crosshair\0"), CursorIcon::Crosshair => load(b"crosshair\0"),
MouseCursor::Default => load(b"left_ptr\0"), CursorIcon::Default => load(b"left_ptr\0"),
MouseCursor::Hand => loadn(&[b"hand2\0", b"hand1\0"]), CursorIcon::Hand => loadn(&[b"hand2\0", b"hand1\0"]),
MouseCursor::Help => load(b"question_arrow\0"), CursorIcon::Help => load(b"question_arrow\0"),
MouseCursor::Move => load(b"move\0"), CursorIcon::Move => load(b"move\0"),
MouseCursor::Grab => loadn(&[b"openhand\0", b"grab\0"]), CursorIcon::Grab => loadn(&[b"openhand\0", b"grab\0"]),
MouseCursor::Grabbing => loadn(&[b"closedhand\0", b"grabbing\0"]), CursorIcon::Grabbing => loadn(&[b"closedhand\0", b"grabbing\0"]),
MouseCursor::Progress => load(b"left_ptr_watch\0"), CursorIcon::Progress => load(b"left_ptr_watch\0"),
MouseCursor::AllScroll => load(b"all-scroll\0"), CursorIcon::AllScroll => load(b"all-scroll\0"),
MouseCursor::ContextMenu => load(b"context-menu\0"), CursorIcon::ContextMenu => load(b"context-menu\0"),
MouseCursor::NoDrop => loadn(&[b"no-drop\0", b"circle\0"]), CursorIcon::NoDrop => loadn(&[b"no-drop\0", b"circle\0"]),
MouseCursor::NotAllowed => load(b"crossed_circle\0"), CursorIcon::NotAllowed => load(b"crossed_circle\0"),
// Resize cursors // Resize cursors
MouseCursor::EResize => load(b"right_side\0"), CursorIcon::EResize => load(b"right_side\0"),
MouseCursor::NResize => load(b"top_side\0"), CursorIcon::NResize => load(b"top_side\0"),
MouseCursor::NeResize => load(b"top_right_corner\0"), CursorIcon::NeResize => load(b"top_right_corner\0"),
MouseCursor::NwResize => load(b"top_left_corner\0"), CursorIcon::NwResize => load(b"top_left_corner\0"),
MouseCursor::SResize => load(b"bottom_side\0"), CursorIcon::SResize => load(b"bottom_side\0"),
MouseCursor::SeResize => load(b"bottom_right_corner\0"), CursorIcon::SeResize => load(b"bottom_right_corner\0"),
MouseCursor::SwResize => load(b"bottom_left_corner\0"), CursorIcon::SwResize => load(b"bottom_left_corner\0"),
MouseCursor::WResize => load(b"left_side\0"), CursorIcon::WResize => load(b"left_side\0"),
MouseCursor::EwResize => load(b"h_double_arrow\0"), CursorIcon::EwResize => load(b"h_double_arrow\0"),
MouseCursor::NsResize => load(b"v_double_arrow\0"), CursorIcon::NsResize => load(b"v_double_arrow\0"),
MouseCursor::NwseResize => loadn(&[b"bd_double_arrow\0", b"size_bdiag\0"]), CursorIcon::NwseResize => loadn(&[b"bd_double_arrow\0", b"size_bdiag\0"]),
MouseCursor::NeswResize => loadn(&[b"fd_double_arrow\0", b"size_fdiag\0"]), CursorIcon::NeswResize => loadn(&[b"fd_double_arrow\0", b"size_fdiag\0"]),
MouseCursor::ColResize => loadn(&[b"split_h\0", b"h_double_arrow\0"]), CursorIcon::ColResize => loadn(&[b"split_h\0", b"h_double_arrow\0"]),
MouseCursor::RowResize => loadn(&[b"split_v\0", b"v_double_arrow\0"]), CursorIcon::RowResize => loadn(&[b"split_v\0", b"v_double_arrow\0"]),
MouseCursor::Text => loadn(&[b"text\0", b"xterm\0"]), CursorIcon::Text => loadn(&[b"text\0", b"xterm\0"]),
MouseCursor::VerticalText => load(b"vertical-text\0"), CursorIcon::VerticalText => load(b"vertical-text\0"),
MouseCursor::Wait => load(b"watch\0"), CursorIcon::Wait => load(b"watch\0"),
MouseCursor::ZoomIn => load(b"zoom-in\0"), CursorIcon::ZoomIn => load(b"zoom-in\0"),
MouseCursor::ZoomOut => load(b"zoom-out\0"), CursorIcon::ZoomOut => load(b"zoom-out\0"),
} }
} }
@ -1071,9 +1068,9 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn set_cursor(&self, cursor: MouseCursor) { pub fn set_cursor_icon(&self, cursor: CursorIcon) {
*self.cursor.lock() = cursor; *self.cursor.lock() = cursor;
if !*self.cursor_hidden.lock() { if *self.cursor_visible.lock() {
self.update_cursor(self.get_cursor(cursor)); self.update_cursor(self.get_cursor(cursor));
} }
} }
@ -1117,7 +1114,7 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
let mut grabbed_lock = self.cursor_grabbed.lock(); let mut grabbed_lock = self.cursor_grabbed.lock();
if grab == *grabbed_lock { return Ok(()); } if grab == *grabbed_lock { return Ok(()); }
unsafe { unsafe {
@ -1161,10 +1158,10 @@ impl UnownedWindow {
ffi::GrabNotViewable => Err("Cursor could not be grabbed: grab location not viewable"), ffi::GrabNotViewable => Err("Cursor could not be grabbed: grab location not viewable"),
ffi::GrabFrozen => Err("Cursor could not be grabbed: frozen by another client"), ffi::GrabFrozen => Err("Cursor could not be grabbed: frozen by another client"),
_ => unreachable!(), _ => unreachable!(),
}.map_err(|err| err.to_owned()) }.map_err(|err| ExternalError::Os(os_error!(OsError::XMisc(err))))
} else { } else {
self.xconn.flush_requests() self.xconn.flush_requests()
.map_err(|err| format!("Failed to call `XUngrabPointer`: {:?}", err)) .map_err(|err| ExternalError::Os(os_error!(OsError::XError(err))))
}; };
if result.is_ok() { if result.is_ok() {
*grabbed_lock = grab; *grabbed_lock = grab;
@ -1173,25 +1170,25 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn hide_cursor(&self, hide: bool) { pub fn set_cursor_visible(&self, visible: bool) {
let mut hidden_lock = self.cursor_hidden.lock(); let mut visible_lock = self.cursor_visible.lock();
if hide == *hidden_lock {return; } if visible == *visible_lock {return; }
let cursor = if hide { let cursor = if visible {
self.create_empty_cursor().expect("Failed to create empty cursor")
} else {
self.get_cursor(*self.cursor.lock()) self.get_cursor(*self.cursor.lock())
} else {
self.create_empty_cursor().expect("Failed to create empty cursor")
}; };
*hidden_lock = hide; *visible_lock = visible;
drop(hidden_lock); drop(visible_lock);
self.update_cursor(cursor); self.update_cursor(cursor);
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
self.get_current_monitor().hidpi_factor self.current_monitor().hidpi_factor
} }
pub fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), String> { pub fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), ExternalError> {
unsafe { unsafe {
(self.xconn.xlib.XWarpPointer)( (self.xconn.xlib.XWarpPointer)(
self.xconn.display, self.xconn.display,
@ -1204,26 +1201,26 @@ impl UnownedWindow {
x, x,
y, y,
); );
self.xconn.flush_requests().map_err(|e| format!("`XWarpPointer` failed: {:?}", e)) self.xconn.flush_requests().map_err(|e| ExternalError::Os(os_error!(OsError::XError(e))))
} }
} }
#[inline] #[inline]
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), ExternalError> {
let (x, y) = logical_position.to_physical(self.get_hidpi_factor()).into(); let (x, y) = logical_position.to_physical(self.hidpi_factor()).into();
self.set_cursor_position_physical(x, y) self.set_cursor_position_physical(x, y)
} }
pub(crate) fn set_ime_spot_physical(&self, x: i32, y: i32) { pub(crate) fn set_ime_position_physical(&self, x: i32, y: i32) {
let _ = self.ime_sender let _ = self.ime_sender
.lock() .lock()
.send((self.xwindow, x as i16, y as i16)); .send((self.xwindow, x as i16, y as i16));
} }
#[inline] #[inline]
pub fn set_ime_spot(&self, logical_spot: LogicalPosition) { pub fn set_ime_position(&self, logical_spot: LogicalPosition) {
let (x, y) = logical_spot.to_physical(self.get_hidpi_factor()).into(); let (x, y) = logical_spot.to_physical(self.hidpi_factor()).into();
self.set_ime_spot_physical(x, y); self.set_ime_position_physical(x, y);
} }
#[inline] #[inline]

View file

@ -61,13 +61,13 @@ impl<T> EventLoop<T> {
} }
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
monitor::get_available_monitors() monitor::available_monitors()
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
monitor::get_primary_monitor() monitor::primary_monitor()
} }
pub fn window_target(&self) -> &RootWindowTarget<T> { pub fn window_target(&self) -> &RootWindowTarget<T> {

View file

@ -13,10 +13,11 @@ mod view;
mod window; mod window;
mod window_delegate; mod window_delegate;
use std::{ops::Deref, sync::Arc}; use std::{fmt, ops::Deref, sync::Arc};
use { use {
event::DeviceId as RootDeviceId, window::{CreationError, WindowAttributes}, event::DeviceId as RootDeviceId, window::WindowAttributes,
error::OsError as RootOsError,
}; };
pub use self::{ pub use self::{
event_loop::{EventLoop, EventLoopWindowTarget, Proxy as EventLoopProxy}, event_loop::{EventLoop, EventLoopWindowTarget, Proxy as EventLoopProxy},
@ -44,6 +45,12 @@ pub struct Window {
_delegate: util::IdRef, _delegate: util::IdRef,
} }
#[derive(Debug)]
pub enum OsError {
CGError(core_graphics::base::CGError),
CreationError(&'static str)
}
unsafe impl Send for Window {} unsafe impl Send for Window {}
unsafe impl Sync for Window {} unsafe impl Sync for Window {}
@ -60,8 +67,17 @@ impl Window {
_window_target: &EventLoopWindowTarget<T>, _window_target: &EventLoopWindowTarget<T>,
attributes: WindowAttributes, attributes: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<Self, CreationError> { ) -> Result<Self, RootOsError> {
let (window, _delegate) = UnownedWindow::new(attributes, pl_attribs)?; let (window, _delegate) = UnownedWindow::new(attributes, pl_attribs)?;
Ok(Window { window, _delegate }) Ok(Window { window, _delegate })
} }
} }
impl fmt::Display for OsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
OsError::CGError(e) => f.pad(&format!("CGError {}", e)),
OsError::CreationError(e) => f.pad(e),
}
}
}

View file

@ -9,7 +9,7 @@ use platform_impl::platform::util::IdRef;
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub struct MonitorHandle(CGDirectDisplayID); pub struct MonitorHandle(CGDirectDisplayID);
pub fn get_available_monitors() -> VecDeque<MonitorHandle> { pub fn available_monitors() -> VecDeque<MonitorHandle> {
if let Ok(displays) = CGDisplay::active_displays() { if let Ok(displays) = CGDisplay::active_displays() {
let mut monitors = VecDeque::with_capacity(displays.len()); let mut monitors = VecDeque::with_capacity(displays.len());
for display in displays { for display in displays {
@ -21,7 +21,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
} }
} }
pub fn get_primary_monitor() -> MonitorHandle { pub fn primary_monitor() -> MonitorHandle {
MonitorHandle(CGDisplay::main().id) MonitorHandle(CGDisplay::main().id)
} }
@ -38,11 +38,11 @@ impl fmt::Debug for MonitorHandle {
} }
let monitor_id_proxy = MonitorHandle { let monitor_id_proxy = MonitorHandle {
name: self.get_name(), name: self.name(),
native_identifier: self.get_native_identifier(), native_identifier: self.native_identifier(),
dimensions: self.get_dimensions(), dimensions: self.dimensions(),
position: self.get_position(), position: self.position(),
hidpi_factor: self.get_hidpi_factor(), hidpi_factor: self.hidpi_factor(),
}; };
monitor_id_proxy.fmt(f) monitor_id_proxy.fmt(f)
@ -54,48 +54,48 @@ impl MonitorHandle {
MonitorHandle(id) MonitorHandle(id)
} }
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
let MonitorHandle(display_id) = *self; let MonitorHandle(display_id) = *self;
let screen_num = CGDisplay::new(display_id).model_number(); let screen_num = CGDisplay::new(display_id).model_number();
Some(format!("Monitor #{}", screen_num)) Some(format!("Monitor #{}", screen_num))
} }
#[inline] #[inline]
pub fn get_native_identifier(&self) -> u32 { pub fn native_identifier(&self) -> u32 {
self.0 self.0
} }
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
let MonitorHandle(display_id) = *self; let MonitorHandle(display_id) = *self;
let display = CGDisplay::new(display_id); let display = CGDisplay::new(display_id);
let height = display.pixels_high(); let height = display.pixels_high();
let width = display.pixels_wide(); let width = display.pixels_wide();
PhysicalSize::from_logical( PhysicalSize::from_logical(
(width as f64, height as f64), (width as f64, height as f64),
self.get_hidpi_factor(), self.hidpi_factor(),
) )
} }
#[inline] #[inline]
pub fn get_position(&self) -> PhysicalPosition { pub fn position(&self) -> PhysicalPosition {
let bounds = unsafe { CGDisplayBounds(self.get_native_identifier()) }; let bounds = unsafe { CGDisplayBounds(self.native_identifier()) };
PhysicalPosition::from_logical( PhysicalPosition::from_logical(
(bounds.origin.x as f64, bounds.origin.y as f64), (bounds.origin.x as f64, bounds.origin.y as f64),
self.get_hidpi_factor(), self.hidpi_factor(),
) )
} }
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
let screen = match self.get_nsscreen() { let screen = match self.nsscreen() {
Some(screen) => screen, Some(screen) => screen,
None => return 1.0, // default to 1.0 when we can't find the screen None => return 1.0, // default to 1.0 when we can't find the screen
}; };
unsafe { NSScreen::backingScaleFactor(screen) as f64 } unsafe { NSScreen::backingScaleFactor(screen) as f64 }
} }
pub(crate) fn get_nsscreen(&self) -> Option<id> { pub(crate) fn nsscreen(&self) -> Option<id> {
unsafe { unsafe {
let native_id = self.get_native_identifier(); let native_id = self.native_identifier();
let screens = NSScreen::screens(nil); let screens = NSScreen::screens(nil);
let count: NSUInteger = msg_send![screens, count]; let count: NSUInteger = msg_send![screens, count];
let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber")); let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber"));

View file

@ -4,7 +4,7 @@ use cocoa::{
}; };
use objc::runtime::Sel; use objc::runtime::Sel;
use window::MouseCursor; use window::CursorIcon;
pub enum Cursor { pub enum Cursor {
Native(&'static str), Native(&'static str),
@ -12,54 +12,54 @@ pub enum Cursor {
WebKit(&'static str), WebKit(&'static str),
} }
impl From<MouseCursor> for Cursor { impl From<CursorIcon> for Cursor {
fn from(cursor: MouseCursor) -> Self { fn from(cursor: CursorIcon) -> Self {
match cursor { match cursor {
MouseCursor::Arrow | MouseCursor::Default => Cursor::Native("arrowCursor"), CursorIcon::Arrow | CursorIcon::Default => Cursor::Native("arrowCursor"),
MouseCursor::Hand => Cursor::Native("pointingHandCursor"), CursorIcon::Hand => Cursor::Native("pointingHandCursor"),
MouseCursor::Grabbing | MouseCursor::Grab => Cursor::Native("closedHandCursor"), CursorIcon::Grabbing | CursorIcon::Grab => Cursor::Native("closedHandCursor"),
MouseCursor::Text => Cursor::Native("IBeamCursor"), CursorIcon::Text => Cursor::Native("IBeamCursor"),
MouseCursor::VerticalText => Cursor::Native("IBeamCursorForVerticalLayout"), CursorIcon::VerticalText => Cursor::Native("IBeamCursorForVerticalLayout"),
MouseCursor::Copy => Cursor::Native("dragCopyCursor"), CursorIcon::Copy => Cursor::Native("dragCopyCursor"),
MouseCursor::Alias => Cursor::Native("dragLinkCursor"), CursorIcon::Alias => Cursor::Native("dragLinkCursor"),
MouseCursor::NotAllowed | MouseCursor::NoDrop => Cursor::Native("operationNotAllowedCursor"), CursorIcon::NotAllowed | CursorIcon::NoDrop => Cursor::Native("operationNotAllowedCursor"),
MouseCursor::ContextMenu => Cursor::Native("contextualMenuCursor"), CursorIcon::ContextMenu => Cursor::Native("contextualMenuCursor"),
MouseCursor::Crosshair => Cursor::Native("crosshairCursor"), CursorIcon::Crosshair => Cursor::Native("crosshairCursor"),
MouseCursor::EResize => Cursor::Native("resizeRightCursor"), CursorIcon::EResize => Cursor::Native("resizeRightCursor"),
MouseCursor::NResize => Cursor::Native("resizeUpCursor"), CursorIcon::NResize => Cursor::Native("resizeUpCursor"),
MouseCursor::WResize => Cursor::Native("resizeLeftCursor"), CursorIcon::WResize => Cursor::Native("resizeLeftCursor"),
MouseCursor::SResize => Cursor::Native("resizeDownCursor"), CursorIcon::SResize => Cursor::Native("resizeDownCursor"),
MouseCursor::EwResize | MouseCursor::ColResize => Cursor::Native("resizeLeftRightCursor"), CursorIcon::EwResize | CursorIcon::ColResize => Cursor::Native("resizeLeftRightCursor"),
MouseCursor::NsResize | MouseCursor::RowResize => Cursor::Native("resizeUpDownCursor"), CursorIcon::NsResize | CursorIcon::RowResize => Cursor::Native("resizeUpDownCursor"),
// Undocumented cursors: https://stackoverflow.com/a/46635398/5435443 // Undocumented cursors: https://stackoverflow.com/a/46635398/5435443
MouseCursor::Help => Cursor::Undocumented("_helpCursor"), CursorIcon::Help => Cursor::Undocumented("_helpCursor"),
MouseCursor::ZoomIn => Cursor::Undocumented("_zoomInCursor"), CursorIcon::ZoomIn => Cursor::Undocumented("_zoomInCursor"),
MouseCursor::ZoomOut => Cursor::Undocumented("_zoomOutCursor"), CursorIcon::ZoomOut => Cursor::Undocumented("_zoomOutCursor"),
MouseCursor::NeResize => Cursor::Undocumented("_windowResizeNorthEastCursor"), CursorIcon::NeResize => Cursor::Undocumented("_windowResizeNorthEastCursor"),
MouseCursor::NwResize => Cursor::Undocumented("_windowResizeNorthWestCursor"), CursorIcon::NwResize => Cursor::Undocumented("_windowResizeNorthWestCursor"),
MouseCursor::SeResize => Cursor::Undocumented("_windowResizeSouthEastCursor"), CursorIcon::SeResize => Cursor::Undocumented("_windowResizeSouthEastCursor"),
MouseCursor::SwResize => Cursor::Undocumented("_windowResizeSouthWestCursor"), CursorIcon::SwResize => Cursor::Undocumented("_windowResizeSouthWestCursor"),
MouseCursor::NeswResize => Cursor::Undocumented("_windowResizeNorthEastSouthWestCursor"), CursorIcon::NeswResize => Cursor::Undocumented("_windowResizeNorthEastSouthWestCursor"),
MouseCursor::NwseResize => Cursor::Undocumented("_windowResizeNorthWestSouthEastCursor"), CursorIcon::NwseResize => Cursor::Undocumented("_windowResizeNorthWestSouthEastCursor"),
// While these are available, the former just loads a white arrow, // While these are available, the former just loads a white arrow,
// and the latter loads an ugly deflated beachball! // and the latter loads an ugly deflated beachball!
// MouseCursor::Move => Cursor::Undocumented("_moveCursor"), // CursorIcon::Move => Cursor::Undocumented("_moveCursor"),
// MouseCursor::Wait => Cursor::Undocumented("_waitCursor"), // CursorIcon::Wait => Cursor::Undocumented("_waitCursor"),
// An even more undocumented cursor... // An even more undocumented cursor...
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=522349 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=522349
// This is the wrong semantics for `Wait`, but it's the same as // This is the wrong semantics for `Wait`, but it's the same as
// what's used in Safari and Chrome. // what's used in Safari and Chrome.
MouseCursor::Wait | MouseCursor::Progress => Cursor::Undocumented("busyButClickableCursor"), CursorIcon::Wait | CursorIcon::Progress => Cursor::Undocumented("busyButClickableCursor"),
// For the rest, we can just snatch the cursors from WebKit... // For the rest, we can just snatch the cursors from WebKit...
// They fit the style of the native cursors, and will seem // They fit the style of the native cursors, and will seem
// completely standard to macOS users. // completely standard to macOS users.
// https://stackoverflow.com/a/21786835/5435443 // https://stackoverflow.com/a/21786835/5435443
MouseCursor::Move | MouseCursor::AllScroll => Cursor::WebKit("move"), CursorIcon::Move | CursorIcon::AllScroll => Cursor::WebKit("move"),
MouseCursor::Cell => Cursor::WebKit("cell"), CursorIcon::Cell => Cursor::WebKit("cell"),
} }
} }
} }

View file

@ -58,7 +58,7 @@ pub fn new_view(nswindow: id) -> (IdRef, Weak<Mutex<util::Cursor>>) {
} }
} }
pub unsafe fn set_ime_spot(nsview: id, input_context: id, x: f64, y: f64) { pub unsafe fn set_ime_position(nsview: id, input_context: id, x: f64, y: f64) {
let state_ptr: *mut c_void = *(*nsview).get_mut_ivar("winitState"); let state_ptr: *mut c_void = *(*nsview).get_mut_ivar("winitState");
let state = &mut *(state_ptr as *mut ViewState); let state = &mut *(state_ptr as *mut ViewState);
let content_rect = NSWindow::contentRectForFrameRect_( let content_rect = NSWindow::contentRectForFrameRect_(

View file

@ -17,13 +17,15 @@ use objc::{runtime::{Class, Object, Sel, BOOL, YES, NO}, declare::ClassDecl};
use { use {
dpi::{LogicalPosition, LogicalSize}, icon::Icon, dpi::{LogicalPosition, LogicalSize}, icon::Icon,
error::{ExternalError, NotSupportedError, OsError as RootOsError},
monitor::MonitorHandle as RootMonitorHandle, monitor::MonitorHandle as RootMonitorHandle,
window::{ window::{
CreationError, MouseCursor, WindowAttributes, WindowId as RootWindowId, CursorIcon, WindowAttributes, WindowId as RootWindowId,
}, },
}; };
use platform::macos::{ActivationPolicy, WindowExtMacOS}; use platform::macos::{ActivationPolicy, WindowExtMacOS};
use platform_impl::platform::{ use platform_impl::platform::{
OsError,
app_state::AppState, ffi, monitor::{self, MonitorHandle}, app_state::AppState, ffi, monitor::{self, MonitorHandle},
util::{self, IdRef}, view::{self, new_view}, util::{self, IdRef}, view::{self, new_view},
window_delegate::new_delegate, window_delegate::new_delegate,
@ -102,7 +104,7 @@ fn create_window(
let pool = NSAutoreleasePool::new(nil); let pool = NSAutoreleasePool::new(nil);
let screen = match attrs.fullscreen { let screen = match attrs.fullscreen {
Some(ref monitor_id) => { Some(ref monitor_id) => {
let monitor_screen = monitor_id.inner.get_nsscreen(); let monitor_screen = monitor_id.inner.nsscreen();
Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil))) Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil)))
}, },
_ => None, _ => None,
@ -110,7 +112,7 @@ fn create_window(
let frame = match screen { let frame = match screen {
Some(screen) => appkit::NSScreen::frame(screen), Some(screen) => appkit::NSScreen::frame(screen),
None => { None => {
let (width, height) = attrs.dimensions let (width, height) = attrs.inner_size
.map(|logical| (logical.width, logical.height)) .map(|logical| (logical.width, logical.height))
.unwrap_or_else(|| (800.0, 600.0)); .unwrap_or_else(|| (800.0, 600.0));
NSRect::new(NSPoint::new(0.0, 0.0), NSSize::new(width, height)) NSRect::new(NSPoint::new(0.0, 0.0), NSSize::new(width, height))
@ -245,7 +247,7 @@ pub struct UnownedWindow {
pub shared_state: Arc<Mutex<SharedState>>, pub shared_state: Arc<Mutex<SharedState>>,
decorations: AtomicBool, decorations: AtomicBool,
cursor: Weak<Mutex<util::Cursor>>, cursor: Weak<Mutex<util::Cursor>>,
cursor_hidden: AtomicBool, cursor_visible: AtomicBool,
} }
unsafe impl Send for UnownedWindow {} unsafe impl Send for UnownedWindow {}
@ -255,7 +257,7 @@ impl UnownedWindow {
pub fn new( pub fn new(
mut win_attribs: WindowAttributes, mut win_attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<(Arc<Self>, IdRef), CreationError> { ) -> Result<(Arc<Self>, IdRef), RootOsError> {
unsafe { unsafe {
if !msg_send![class!(NSThread), isMainThread] { if !msg_send![class!(NSThread), isMainThread] {
panic!("Windows can only be created on the main thread on macOS"); panic!("Windows can only be created on the main thread on macOS");
@ -266,17 +268,17 @@ impl UnownedWindow {
let nsapp = create_app(pl_attribs.activation_policy).ok_or_else(|| { let nsapp = create_app(pl_attribs.activation_policy).ok_or_else(|| {
unsafe { pool.drain() }; unsafe { pool.drain() };
CreationError::OsError(format!("Couldn't create `NSApplication`")) os_error!(OsError::CreationError("Couldn't create `NSApplication`"))
})?; })?;
let nswindow = create_window(&win_attribs, &pl_attribs).ok_or_else(|| { let nswindow = create_window(&win_attribs, &pl_attribs).ok_or_else(|| {
unsafe { pool.drain() }; unsafe { pool.drain() };
CreationError::OsError(format!("Couldn't create `NSWindow`")) os_error!(OsError::CreationError("Couldn't create `NSWindow`"))
})?; })?;
let (nsview, cursor) = unsafe { create_view(*nswindow) }.ok_or_else(|| { let (nsview, cursor) = unsafe { create_view(*nswindow) }.ok_or_else(|| {
unsafe { pool.drain() }; unsafe { pool.drain() };
CreationError::OsError(format!("Couldn't create `NSView`")) os_error!(OsError::CreationError("Couldn't create `NSView`"))
})?; })?;
let input_context = unsafe { util::create_input_context(*nsview) }; let input_context = unsafe { util::create_input_context(*nsview) };
@ -289,8 +291,8 @@ impl UnownedWindow {
nsapp.activateIgnoringOtherApps_(YES); nsapp.activateIgnoringOtherApps_(YES);
win_attribs.min_dimensions.map(|dim| set_min_dimensions(*nswindow, dim)); win_attribs.min_inner_size.map(|dim| set_min_inner_size(*nswindow, dim));
win_attribs.max_dimensions.map(|dim| set_max_dimensions(*nswindow, dim)); win_attribs.max_inner_size.map(|dim| set_max_inner_size(*nswindow, dim));
use cocoa::foundation::NSArray; use cocoa::foundation::NSArray;
// register for drag and drop operations. // register for drag and drop operations.
@ -317,14 +319,14 @@ impl UnownedWindow {
shared_state: Arc::new(Mutex::new(win_attribs.into())), shared_state: Arc::new(Mutex::new(win_attribs.into())),
decorations: AtomicBool::new(decorations), decorations: AtomicBool::new(decorations),
cursor, cursor,
cursor_hidden: Default::default(), cursor_visible: AtomicBool::new(true),
}); });
let delegate = new_delegate(&window, fullscreen.is_some()); let delegate = new_delegate(&window, fullscreen.is_some());
// Set fullscreen mode after we setup everything // Set fullscreen mode after we setup everything
if let Some(monitor) = fullscreen { if let Some(monitor) = fullscreen {
if monitor.inner != window.get_current_monitor().inner { if monitor.inner != window.current_monitor().inner {
// To do this with native fullscreen, we probably need to // To do this with native fullscreen, we probably need to
// warp the window... while we could use // warp the window... while we could use
// `enterFullScreenMode`, they're idiomatically different // `enterFullScreenMode`, they're idiomatically different
@ -381,42 +383,39 @@ impl UnownedWindow {
} }
} }
#[inline] pub fn set_visible(&self, visible: bool) {
pub fn show(&self) { match visible {
unsafe { util::make_key_and_order_front_async(*self.nswindow) }; true => unsafe { util::make_key_and_order_front_async(*self.nswindow) },
} false => unsafe { util::order_out_async(*self.nswindow) },
}
#[inline]
pub fn hide(&self) {
unsafe { util::order_out_async(*self.nswindow) };
} }
pub fn request_redraw(&self) { pub fn request_redraw(&self) {
AppState::queue_redraw(RootWindowId(self.id())); AppState::queue_redraw(RootWindowId(self.id()));
} }
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
let frame_rect = unsafe { NSWindow::frame(*self.nswindow) }; let frame_rect = unsafe { NSWindow::frame(*self.nswindow) };
Some(( Ok((
frame_rect.origin.x as f64, frame_rect.origin.x as f64,
util::bottom_left_to_top_left(frame_rect), util::bottom_left_to_top_left(frame_rect),
).into()) ).into())
} }
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
let content_rect = unsafe { let content_rect = unsafe {
NSWindow::contentRectForFrameRect_( NSWindow::contentRectForFrameRect_(
*self.nswindow, *self.nswindow,
NSWindow::frame(*self.nswindow), NSWindow::frame(*self.nswindow),
) )
}; };
Some(( Ok((
content_rect.origin.x as f64, content_rect.origin.x as f64,
util::bottom_left_to_top_left(content_rect), util::bottom_left_to_top_left(content_rect),
).into()) ).into())
} }
pub fn set_position(&self, position: LogicalPosition) { pub fn set_outer_position(&self, position: LogicalPosition) {
let dummy = NSRect::new( let dummy = NSRect::new(
NSPoint::new( NSPoint::new(
position.x, position.x,
@ -432,15 +431,15 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn inner_size(&self) -> LogicalSize {
let view_frame = unsafe { NSView::frame(*self.nsview) }; let view_frame = unsafe { NSView::frame(*self.nsview) };
Some((view_frame.size.width as f64, view_frame.size.height as f64).into()) (view_frame.size.width as f64, view_frame.size.height as f64).into()
} }
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn outer_size(&self) -> LogicalSize {
let view_frame = unsafe { NSWindow::frame(*self.nswindow) }; let view_frame = unsafe { NSWindow::frame(*self.nswindow) };
Some((view_frame.size.width as f64, view_frame.size.height as f64).into()) (view_frame.size.width as f64, view_frame.size.height as f64).into()
} }
#[inline] #[inline]
@ -450,17 +449,17 @@ impl UnownedWindow {
} }
} }
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
unsafe { unsafe {
let dimensions = dimensions.unwrap_or_else(|| (0, 0).into()); let dimensions = dimensions.unwrap_or_else(|| (0, 0).into());
set_min_dimensions(*self.nswindow, dimensions); set_min_inner_size(*self.nswindow, dimensions);
} }
} }
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
unsafe { unsafe {
let dimensions = dimensions.unwrap_or_else(|| (!0, !0).into()); let dimensions = dimensions.unwrap_or_else(|| (!0, !0).into());
set_max_dimensions(*self.nswindow, dimensions); set_max_inner_size(*self.nswindow, dimensions);
} }
} }
@ -484,7 +483,7 @@ impl UnownedWindow {
} // Otherwise, we don't change the mask until we exit fullscreen. } // Otherwise, we don't change the mask until we exit fullscreen.
} }
pub fn set_cursor(&self, cursor: MouseCursor) { pub fn set_cursor_icon(&self, cursor: CursorIcon) {
let cursor = util::Cursor::from(cursor); let cursor = util::Cursor::from(cursor);
if let Some(cursor_access) = self.cursor.upgrade() { if let Some(cursor_access) = self.cursor.upgrade() {
*cursor_access.lock().unwrap() = cursor; *cursor_access.lock().unwrap() = cursor;
@ -497,44 +496,43 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
// TODO: Do this for real https://stackoverflow.com/a/40922095/5435443 // TODO: Do this for real https://stackoverflow.com/a/40922095/5435443
CGDisplay::associate_mouse_and_mouse_cursor_position(!grab) CGDisplay::associate_mouse_and_mouse_cursor_position(!grab)
.map_err(|status| format!("Failed to grab cursor: `CGError` {:?}", status)) .map_err(|status| ExternalError::Os(os_error!(OsError::CGError(status))))
} }
#[inline] #[inline]
pub fn hide_cursor(&self, hide: bool) { pub fn set_cursor_visible(&self, visible: bool) {
let cursor_class = class!(NSCursor); let cursor_class = class!(NSCursor);
// macOS uses a "hide counter" like Windows does, so we avoid incrementing it more than once. // macOS uses a "hide counter" like Windows does, so we avoid incrementing it more than once.
// (otherwise, `hide_cursor(false)` would need to be called n times!) // (otherwise, `hide_cursor(false)` would need to be called n times!)
if hide != self.cursor_hidden.load(Ordering::Acquire) { if visible != self.cursor_visible.load(Ordering::Acquire) {
if hide { if visible {
let _: () = unsafe { msg_send![cursor_class, hide] };
} else {
let _: () = unsafe { msg_send![cursor_class, unhide] }; let _: () = unsafe { msg_send![cursor_class, unhide] };
} else {
let _: () = unsafe { msg_send![cursor_class, hide] };
} }
self.cursor_hidden.store(hide, Ordering::Release); self.cursor_visible.store(visible, Ordering::Release);
} }
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
unsafe { NSWindow::backingScaleFactor(*self.nswindow) as _ } unsafe { NSWindow::backingScaleFactor(*self.nswindow) as _ }
} }
#[inline] #[inline]
pub fn set_cursor_position(&self, cursor_position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, cursor_position: LogicalPosition) -> Result<(), ExternalError> {
let window_position = self.get_inner_position() let window_position = self.inner_position().unwrap();
.ok_or("`get_inner_position` failed".to_owned())?;
let point = appkit::CGPoint { let point = appkit::CGPoint {
x: (cursor_position.x + window_position.x) as CGFloat, x: (cursor_position.x + window_position.x) as CGFloat,
y: (cursor_position.y + window_position.y) as CGFloat, y: (cursor_position.y + window_position.y) as CGFloat,
}; };
CGDisplay::warp_mouse_cursor_position(point) CGDisplay::warp_mouse_cursor_position(point)
.map_err(|e| format!("`CGWarpMouseCursorPosition` failed: {:?}", e))?; .map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?;
CGDisplay::associate_mouse_and_mouse_cursor_position(true) CGDisplay::associate_mouse_and_mouse_cursor_position(true)
.map_err(|e| format!("`CGAssociateMouseAndMouseCursorPosition` failed: {:?}", e))?; .map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?;
Ok(()) Ok(())
} }
@ -637,7 +635,7 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> { pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
let shared_state_lock = self.shared_state.lock().unwrap(); let shared_state_lock = self.shared_state.lock().unwrap();
shared_state_lock.fullscreen.clone() shared_state_lock.fullscreen.clone()
} }
@ -736,9 +734,9 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn set_ime_spot(&self, logical_spot: LogicalPosition) { pub fn set_ime_position(&self, logical_spot: LogicalPosition) {
unsafe { unsafe {
view::set_ime_spot( view::set_ime_position(
*self.nsview, *self.nsview,
*self.input_context, *self.input_context,
logical_spot.x, logical_spot.x,
@ -748,7 +746,7 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle { pub fn current_monitor(&self) -> RootMonitorHandle {
unsafe { unsafe {
let screen: id = msg_send![*self.nswindow, screen]; let screen: id = msg_send![*self.nswindow, screen];
let desc = NSScreen::deviceDescription(screen); let desc = NSScreen::deviceDescription(screen);
@ -760,24 +758,24 @@ impl UnownedWindow {
} }
#[inline] #[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
monitor::get_available_monitors() monitor::available_monitors()
} }
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
monitor::get_primary_monitor() monitor::primary_monitor()
} }
} }
impl WindowExtMacOS for UnownedWindow { impl WindowExtMacOS for UnownedWindow {
#[inline] #[inline]
fn get_nswindow(&self) -> *mut c_void { fn nswindow(&self) -> *mut c_void {
*self.nswindow as *mut _ *self.nswindow as *mut _
} }
#[inline] #[inline]
fn get_nsview(&self) -> *mut c_void { fn nsview(&self) -> *mut c_void {
*self.nsview as *mut _ *self.nsview as *mut _
} }
@ -792,7 +790,7 @@ impl WindowExtMacOS for UnownedWindow {
} }
#[inline] #[inline]
fn get_simple_fullscreen(&self) -> bool { fn simple_fullscreen(&self) -> bool {
let shared_state_lock = self.shared_state.lock().unwrap(); let shared_state_lock = self.shared_state.lock().unwrap();
shared_state_lock.is_simple_fullscreen shared_state_lock.is_simple_fullscreen
} }
@ -869,7 +867,7 @@ impl Drop for UnownedWindow {
} }
} }
unsafe fn set_min_dimensions<V: NSWindow + Copy>(window: V, mut min_size: LogicalSize) { unsafe fn set_min_inner_size<V: NSWindow + Copy>(window: V, mut min_size: LogicalSize) {
let mut current_rect = NSWindow::frame(window); let mut current_rect = NSWindow::frame(window);
let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window)); let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
// Convert from client area size to window size // Convert from client area size to window size
@ -893,7 +891,7 @@ unsafe fn set_min_dimensions<V: NSWindow + Copy>(window: V, mut min_size: Logica
} }
} }
unsafe fn set_max_dimensions<V: NSWindow + Copy>(window: V, mut max_size: LogicalSize) { unsafe fn set_max_inner_size<V: NSWindow + Copy>(window: V, mut max_size: LogicalSize) {
let mut current_rect = NSWindow::frame(window); let mut current_rect = NSWindow::frame(window);
let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window)); let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
// Convert from client area size to window size // Convert from client area size to window size

View file

@ -37,7 +37,7 @@ impl WindowDelegateState {
window: &Arc<UnownedWindow>, window: &Arc<UnownedWindow>,
initial_fullscreen: bool, initial_fullscreen: bool,
) -> Self { ) -> Self {
let dpi_factor = window.get_hidpi_factor(); let dpi_factor = window.hidpi_factor();
let mut delegate_state = WindowDelegateState { let mut delegate_state = WindowDelegateState {
nswindow: window.nswindow.clone(), nswindow: window.nswindow.clone(),
@ -408,7 +408,7 @@ extern fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
trace!("Triggered `windowDidEnterFullscreen:`"); trace!("Triggered `windowDidEnterFullscreen:`");
with_state(this, |state| { with_state(this, |state| {
state.with_window(|window| { state.with_window(|window| {
let monitor = window.get_current_monitor(); let monitor = window.current_monitor();
trace!("Locked shared state in `window_did_enter_fullscreen`"); trace!("Locked shared state in `window_did_enter_fullscreen`");
window.shared_state.lock().unwrap().fullscreen = Some(monitor); window.shared_state.lock().unwrap().fullscreen = Some(monitor);
trace!("Unlocked shared state in `window_will_enter_fullscreen`"); trace!("Unlocked shared state in `window_will_enter_fullscreen`");

View file

@ -144,7 +144,7 @@ pub fn dpi_to_scale_factor(dpi: u32) -> f64 {
dpi as f64 / BASE_DPI as f64 dpi as f64 / BASE_DPI as f64
} }
pub unsafe fn get_hwnd_dpi(hwnd: HWND) -> u32 { pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 {
let hdc = winuser::GetDC(hwnd); let hdc = winuser::GetDC(hwnd);
if hdc.is_null() { if hdc.is_null() {
panic!("[winit] `GetDC` returned null!"); panic!("[winit] `GetDC` returned null!");
@ -184,6 +184,6 @@ pub unsafe fn get_hwnd_dpi(hwnd: HWND) -> u32 {
} }
} }
pub fn get_hwnd_scale_factor(hwnd: HWND) -> f64 { pub fn hwnd_scale_factor(hwnd: HWND) -> f64 {
dpi_to_scale_factor(unsafe { get_hwnd_dpi(hwnd) }) dpi_to_scale_factor(unsafe { hwnd_dpi(hwnd) })
} }

View file

@ -52,7 +52,7 @@ use platform_impl::platform::dpi::{
become_dpi_aware, become_dpi_aware,
dpi_to_scale_factor, dpi_to_scale_factor,
enable_non_client_dpi_scaling, enable_non_client_dpi_scaling,
get_hwnd_scale_factor, hwnd_scale_factor,
}; };
use platform_impl::platform::drop_handler::FileDropHandler; use platform_impl::platform::drop_handler::FileDropHandler;
use platform_impl::platform::event::{handle_extended_keys, process_key_params, vkey_to_winit_vkey}; use platform_impl::platform::event::{handle_extended_keys, process_key_params, vkey_to_winit_vkey};
@ -869,7 +869,7 @@ unsafe extern "system" fn public_window_callback<T>(
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 {
let dpi_factor = get_hwnd_scale_factor(window); let dpi_factor = hwnd_scale_factor(window);
let logical_position = LogicalPosition::from_physical( let logical_position = LogicalPosition::from_physical(
((*windowpos).x, (*windowpos).y), ((*windowpos).x, (*windowpos).y),
dpi_factor, dpi_factor,
@ -889,7 +889,7 @@ unsafe extern "system" fn public_window_callback<T>(
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 = 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: RootWindowId(WindowId(window)), window_id: RootWindowId(WindowId(window)),
@ -954,7 +954,7 @@ unsafe extern "system" fn public_window_callback<T>(
let x = windowsx::GET_X_LPARAM(lparam) as f64; let x = windowsx::GET_X_LPARAM(lparam) as f64;
let y = windowsx::GET_Y_LPARAM(lparam) as f64; let y = windowsx::GET_Y_LPARAM(lparam) as f64;
let dpi_factor = get_hwnd_scale_factor(window); let dpi_factor = hwnd_scale_factor(window);
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 {
@ -1305,7 +1305,7 @@ unsafe extern "system" fn public_window_callback<T>(
inputs.as_mut_ptr(), inputs.as_mut_ptr(),
mem::size_of::<winuser::TOUCHINPUT>() as INT, mem::size_of::<winuser::TOUCHINPUT>() as INT,
) > 0 { ) > 0 {
let dpi_factor = get_hwnd_scale_factor(window); let dpi_factor = hwnd_scale_factor(window);
for input in &inputs { for input in &inputs {
let x = (input.x as f64) / 100f64; let x = (input.x as f64) / 100f64;
let y = (input.y as f64) / 100f64; let y = (input.y as f64) / 100f64;

View file

@ -1,4 +1,4 @@
use std::{self, mem, ptr}; use std::{mem, ptr, io};
use std::os::windows::ffi::OsStrExt; use std::os::windows::ffi::OsStrExt;
use std::path::Path; use std::path::Path;
@ -8,7 +8,6 @@ use winapi::shared::windef::{HICON, HWND};
use winapi::um::winuser; use winapi::um::winuser;
use icon::{Pixel, PIXEL_SIZE, Icon}; use icon::{Pixel, PIXEL_SIZE, Icon};
use platform_impl::platform::util;
impl Pixel { impl Pixel {
fn to_bgra(&mut self) { fn to_bgra(&mut self) {
@ -31,7 +30,7 @@ unsafe impl Send for WinIcon {}
impl WinIcon { impl WinIcon {
#[allow(dead_code)] #[allow(dead_code)]
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, util::WinError> { pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> {
let wide_path: Vec<u16> = path.as_ref().as_os_str().encode_wide().collect(); let wide_path: Vec<u16> = path.as_ref().as_os_str().encode_wide().collect();
let handle = unsafe { let handle = unsafe {
winuser::LoadImageW( winuser::LoadImageW(
@ -46,15 +45,15 @@ impl WinIcon {
if !handle.is_null() { if !handle.is_null() {
Ok(WinIcon { handle }) Ok(WinIcon { handle })
} else { } else {
Err(util::WinError::from_last_error()) Err(io::Error::last_os_error())
} }
} }
pub fn from_icon(icon: Icon) -> Result<Self, util::WinError> { pub fn from_icon(icon: Icon) -> Result<Self, io::Error> {
Self::from_rgba(icon.rgba, icon.width, icon.height) Self::from_rgba(icon.rgba, icon.width, icon.height)
} }
pub fn from_rgba(mut rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, util::WinError> { pub fn from_rgba(mut rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, io::Error> {
assert_eq!(rgba.len() % PIXEL_SIZE, 0); assert_eq!(rgba.len() % PIXEL_SIZE, 0);
let pixel_count = rgba.len() / PIXEL_SIZE; let pixel_count = rgba.len() / PIXEL_SIZE;
assert_eq!(pixel_count, (width * height) as usize); assert_eq!(pixel_count, (width * height) as usize);
@ -80,7 +79,7 @@ impl WinIcon {
if !handle.is_null() { if !handle.is_null() {
Ok(WinIcon { handle }) Ok(WinIcon { handle })
} else { } else {
Err(util::WinError::from_last_error()) Err(io::Error::last_os_error())
} }
} }

View file

@ -36,7 +36,7 @@ impl DeviceId {
} }
impl DeviceId { impl DeviceId {
pub fn get_persistent_identifier(&self) -> Option<String> { pub fn persistent_identifier(&self) -> Option<String> {
if self.0 != 0 { if self.0 != 0 {
raw_input::get_raw_input_device_name(self.0 as _) raw_input::get_raw_input_device_name(self.0 as _)
} else { } else {
@ -52,6 +52,8 @@ fn wrap_device_id(id: u32) -> RootDeviceId {
RootDeviceId(DeviceId(id)) RootDeviceId(DeviceId(id))
} }
pub type OsError = std::io::Error;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WindowId(HWND); pub struct WindowId(HWND);
unsafe impl Send for WindowId {} unsafe impl Send for WindowId {}

View file

@ -3,7 +3,7 @@ use winapi::shared::windef::{HDC, HMONITOR, HWND, LPRECT, POINT};
use winapi::um::winnt::LONG; use winapi::um::winnt::LONG;
use winapi::um::winuser; use winapi::um::winuser;
use std::{mem, ptr}; use std::{mem, ptr, io};
use std::collections::VecDeque; use std::collections::VecDeque;
use super::{EventLoop, util}; use super::{EventLoop, util};
@ -50,7 +50,7 @@ unsafe extern "system" fn monitor_enum_proc(
TRUE // continue enumeration TRUE // continue enumeration
} }
pub fn get_available_monitors() -> VecDeque<MonitorHandle> { pub fn available_monitors() -> VecDeque<MonitorHandle> {
let mut monitors: VecDeque<MonitorHandle> = VecDeque::new(); let mut monitors: VecDeque<MonitorHandle> = VecDeque::new();
unsafe { unsafe {
winuser::EnumDisplayMonitors( winuser::EnumDisplayMonitors(
@ -63,7 +63,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
monitors monitors
} }
pub fn get_primary_monitor() -> MonitorHandle { pub fn primary_monitor() -> MonitorHandle {
const ORIGIN: POINT = POINT { x: 0, y: 0 }; const ORIGIN: POINT = POINT { x: 0, y: 0 };
let hmonitor = unsafe { let hmonitor = unsafe {
winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY) winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY)
@ -71,7 +71,7 @@ pub fn get_primary_monitor() -> MonitorHandle {
MonitorHandle::from_hmonitor(hmonitor) MonitorHandle::from_hmonitor(hmonitor)
} }
pub fn get_current_monitor(hwnd: HWND) -> MonitorHandle { pub fn current_monitor(hwnd: HWND) -> MonitorHandle {
let hmonitor = unsafe { let hmonitor = unsafe {
winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST) winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST)
}; };
@ -80,26 +80,26 @@ pub fn get_current_monitor(hwnd: HWND) -> MonitorHandle {
impl<T> EventLoop<T> { impl<T> EventLoop<T> {
// TODO: Investigate opportunities for caching // TODO: Investigate opportunities for caching
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors() available_monitors()
} }
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
get_primary_monitor() primary_monitor()
} }
} }
impl Window { impl Window {
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors() available_monitors()
} }
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
get_primary_monitor() primary_monitor()
} }
} }
pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINFOEXW, util::WinError> { pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINFOEXW, io::Error> {
let mut monitor_info: winuser::MONITORINFOEXW = unsafe { mem::uninitialized() }; let mut monitor_info: winuser::MONITORINFOEXW = unsafe { mem::uninitialized() };
monitor_info.cbSize = mem::size_of::<winuser::MONITORINFOEXW>() as DWORD; monitor_info.cbSize = mem::size_of::<winuser::MONITORINFOEXW>() as DWORD;
let status = unsafe { let status = unsafe {
@ -109,7 +109,7 @@ pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINF
) )
}; };
if status == 0 { if status == 0 {
Err(util::WinError::from_last_error()) Err(io::Error::last_os_error())
} else { } else {
Ok(monitor_info) Ok(monitor_info)
} }
@ -142,32 +142,32 @@ impl MonitorHandle {
} }
#[inline] #[inline]
pub fn get_name(&self) -> Option<String> { pub fn name(&self) -> Option<String> {
Some(self.monitor_name.clone()) Some(self.monitor_name.clone())
} }
#[inline] #[inline]
pub fn get_native_identifier(&self) -> String { pub fn native_identifier(&self) -> String {
self.monitor_name.clone() self.monitor_name.clone()
} }
#[inline] #[inline]
pub fn get_hmonitor(&self) -> HMONITOR { pub fn hmonitor(&self) -> HMONITOR {
self.hmonitor.0 self.hmonitor.0
} }
#[inline] #[inline]
pub fn get_dimensions(&self) -> PhysicalSize { pub fn dimensions(&self) -> PhysicalSize {
self.dimensions.into() self.dimensions.into()
} }
#[inline] #[inline]
pub fn get_position(&self) -> PhysicalPosition { pub fn position(&self) -> PhysicalPosition {
self.position.into() self.position.into()
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
self.hidpi_factor self.hidpi_factor
} }
} }

View file

@ -1,26 +1,12 @@
use std::{self, mem, ptr, slice, io}; use std::{mem, ptr, slice, io};
use std::ops::BitAnd; use std::ops::BitAnd;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use window::MouseCursor; use window::CursorIcon;
use winapi::ctypes::wchar_t; use winapi::ctypes::wchar_t;
use winapi::shared::minwindef::{BOOL, DWORD}; use winapi::shared::minwindef::{BOOL, DWORD};
use winapi::shared::windef::{HWND, POINT, RECT}; use winapi::shared::windef::{HWND, POINT, RECT};
use winapi::um::errhandlingapi::GetLastError; use winapi::um::winbase::lstrlenW;
use winapi::um::winbase::{
FormatMessageW,
FORMAT_MESSAGE_ALLOCATE_BUFFER,
FORMAT_MESSAGE_FROM_SYSTEM,
FORMAT_MESSAGE_IGNORE_INSERTS,
lstrlenW,
LocalFree,
};
use winapi::um::winnt::{
LPCWSTR,
MAKELANGID,
LANG_NEUTRAL,
SUBLANG_DEFAULT,
};
use winapi::um::winuser; use winapi::um::winuser;
pub fn has_flag<T>(bitset: T, flag: T) -> bool pub fn has_flag<T>(bitset: T, flag: T) -> bool
@ -117,66 +103,27 @@ pub fn is_focused(window: HWND) -> bool {
window == unsafe{ winuser::GetActiveWindow() } window == unsafe{ winuser::GetActiveWindow() }
} }
#[derive(Debug, Default, Clone, PartialEq, Eq)] impl CursorIcon {
pub struct WinError(Option<String>);
impl WinError {
pub fn from_last_error() -> Self {
WinError(unsafe { get_last_error() })
}
}
pub unsafe fn get_last_error() -> Option<String> {
let err = GetLastError();
if err != 0 {
let buf_addr: LPCWSTR = {
let mut buf_addr: LPCWSTR = mem::uninitialized();
FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
ptr::null(),
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) as DWORD,
// This is a pointer to a pointer
&mut buf_addr as *mut LPCWSTR as *mut _,
0,
ptr::null_mut(),
);
buf_addr
};
if !buf_addr.is_null() {
let buf_len = lstrlenW(buf_addr) as usize;
let buf_slice = std::slice::from_raw_parts(buf_addr, buf_len);
let string = wchar_to_string(buf_slice);
LocalFree(buf_addr as *mut _);
return Some(string);
}
}
None
}
impl MouseCursor {
pub(crate) fn to_windows_cursor(self) -> *const wchar_t { pub(crate) fn to_windows_cursor(self) -> *const wchar_t {
match self { match self {
MouseCursor::Arrow | MouseCursor::Default => winuser::IDC_ARROW, CursorIcon::Arrow | CursorIcon::Default => winuser::IDC_ARROW,
MouseCursor::Hand => winuser::IDC_HAND, CursorIcon::Hand => winuser::IDC_HAND,
MouseCursor::Crosshair => winuser::IDC_CROSS, CursorIcon::Crosshair => winuser::IDC_CROSS,
MouseCursor::Text | MouseCursor::VerticalText => winuser::IDC_IBEAM, CursorIcon::Text | CursorIcon::VerticalText => winuser::IDC_IBEAM,
MouseCursor::NotAllowed | MouseCursor::NoDrop => winuser::IDC_NO, CursorIcon::NotAllowed | CursorIcon::NoDrop => winuser::IDC_NO,
MouseCursor::Grab | MouseCursor::Grabbing | CursorIcon::Grab | CursorIcon::Grabbing |
MouseCursor::Move | MouseCursor::AllScroll => winuser::IDC_SIZEALL, CursorIcon::Move | CursorIcon::AllScroll => winuser::IDC_SIZEALL,
MouseCursor::EResize | MouseCursor::WResize | CursorIcon::EResize | CursorIcon::WResize |
MouseCursor::EwResize | MouseCursor::ColResize => winuser::IDC_SIZEWE, CursorIcon::EwResize | CursorIcon::ColResize => winuser::IDC_SIZEWE,
MouseCursor::NResize | MouseCursor::SResize | CursorIcon::NResize | CursorIcon::SResize |
MouseCursor::NsResize | MouseCursor::RowResize => winuser::IDC_SIZENS, CursorIcon::NsResize | CursorIcon::RowResize => winuser::IDC_SIZENS,
MouseCursor::NeResize | MouseCursor::SwResize | CursorIcon::NeResize | CursorIcon::SwResize |
MouseCursor::NeswResize => winuser::IDC_SIZENESW, CursorIcon::NeswResize => winuser::IDC_SIZENESW,
MouseCursor::NwResize | MouseCursor::SeResize | CursorIcon::NwResize | CursorIcon::SeResize |
MouseCursor::NwseResize => winuser::IDC_SIZENWSE, CursorIcon::NwseResize => winuser::IDC_SIZENWSE,
MouseCursor::Wait => winuser::IDC_WAIT, CursorIcon::Wait => winuser::IDC_WAIT,
MouseCursor::Progress => winuser::IDC_APPSTARTING, CursorIcon::Progress => winuser::IDC_APPSTARTING,
MouseCursor::Help => winuser::IDC_HELP, CursorIcon::Help => winuser::IDC_HELP,
_ => winuser::IDC_ARROW, // use arrow for the missing cases. _ => winuser::IDC_ARROW, // use arrow for the missing cases.
} }
} }

View file

@ -18,12 +18,13 @@ 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 window::{CreationError, Icon, MouseCursor, WindowAttributes}; use window::{Icon, CursorIcon, WindowAttributes};
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
use dpi::{LogicalPosition, LogicalSize, PhysicalSize}; use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
use monitor::MonitorHandle as RootMonitorHandle; use monitor::MonitorHandle as RootMonitorHandle;
use platform_impl::platform::{ use platform_impl::platform::{
{PlatformSpecificWindowBuilderAttributes, WindowId}, {PlatformSpecificWindowBuilderAttributes, WindowId},
dpi::{dpi_to_scale_factor, get_hwnd_dpi}, dpi::{dpi_to_scale_factor, hwnd_dpi},
drop_handler::FileDropHandler, drop_handler::FileDropHandler,
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID}, event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID},
icon::{self, IconType, WinIcon}, icon::{self, IconType, WinIcon},
@ -50,7 +51,7 @@ impl Window {
event_loop: &EventLoopWindowTarget<T>, event_loop: &EventLoopWindowTarget<T>,
w_attr: WindowAttributes, w_attr: WindowAttributes,
pl_attr: PlatformSpecificWindowBuilderAttributes, pl_attr: PlatformSpecificWindowBuilderAttributes,
) -> Result<Window, CreationError> { ) -> Result<Window, RootOsError> {
// We dispatch an `init` function because of code style. // We dispatch an `init` function because of code style.
// First person to remove the need for cloning here gets a cookie! // First person to remove the need for cloning here gets a cookie!
// //
@ -103,16 +104,10 @@ impl Window {
} }
#[inline] #[inline]
pub fn show(&self) { pub fn set_visible(&self, visible: bool) {
unsafe { match visible {
winuser::ShowWindow(self.window.0, winuser::SW_SHOW); true => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_SHOW); },
} false => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_HIDE); },
}
#[inline]
pub fn hide(&self) {
unsafe {
winuser::ShowWindow(self.window.0, winuser::SW_HIDE);
} }
} }
@ -132,35 +127,32 @@ impl Window {
} }
} }
pub(crate) fn get_position_physical(&self) -> Option<(i32, i32)> { pub(crate) fn outer_position_physical(&self) -> (i32, i32) {
util::get_window_rect(self.window.0) util::get_window_rect(self.window.0)
.map(|rect| (rect.left as i32, rect.top as i32)) .map(|rect| (rect.left as i32, rect.top as i32))
.unwrap()
} }
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
self.get_position_physical() let physical_position = self.outer_position_physical();
.map(|physical_position| { let dpi_factor = self.hidpi_factor();
let dpi_factor = self.get_hidpi_factor(); Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
LogicalPosition::from_physical(physical_position, dpi_factor)
})
} }
pub(crate) fn get_inner_position_physical(&self) -> Option<(i32, i32)> { pub(crate) fn inner_position_physical(&self) -> (i32, i32) {
let mut position: POINT = unsafe { mem::zeroed() }; let mut position: POINT = unsafe { mem::zeroed() };
if unsafe { winuser::ClientToScreen(self.window.0, &mut position) } == 0 { if unsafe { winuser::ClientToScreen(self.window.0, &mut position) } == 0 {
return None; panic!("Unexpected ClientToScreen failure: please report this error to https://github.com/rust-windowing/winit")
} }
Some((position.x, position.y)) (position.x, position.y)
} }
#[inline] #[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> { pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
self.get_inner_position_physical() let physical_position = self.inner_position_physical();
.map(|physical_position| { let dpi_factor = self.hidpi_factor();
let dpi_factor = self.get_hidpi_factor(); Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
LogicalPosition::from_physical(physical_position, dpi_factor)
})
} }
pub(crate) fn set_position_physical(&self, x: i32, y: i32) { pub(crate) fn set_position_physical(&self, x: i32, y: i32) {
@ -179,47 +171,44 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_position(&self, logical_position: LogicalPosition) { pub fn set_outer_position(&self, logical_position: LogicalPosition) {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
let (x, y) = logical_position.to_physical(dpi_factor).into(); let (x, y) = logical_position.to_physical(dpi_factor).into();
self.set_position_physical(x, y); self.set_position_physical(x, y);
} }
pub(crate) fn get_inner_size_physical(&self) -> Option<(u32, u32)> { pub(crate) fn inner_size_physical(&self) -> (u32, u32) {
let mut rect: RECT = unsafe { mem::uninitialized() }; let mut rect: RECT = unsafe { mem::uninitialized() };
if unsafe { winuser::GetClientRect(self.window.0, &mut rect) } == 0 { if unsafe { winuser::GetClientRect(self.window.0, &mut rect) } == 0 {
return None; panic!("Unexpected GetClientRect failure: please report this error to https://github.com/rust-windowing/winit")
} }
Some(( (
(rect.right - rect.left) as u32, (rect.right - rect.left) as u32,
(rect.bottom - rect.top) as u32, (rect.bottom - rect.top) as u32,
)) )
} }
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn inner_size(&self) -> LogicalSize {
self.get_inner_size_physical() let physical_size = self.inner_size_physical();
.map(|physical_size| { let dpi_factor = self.hidpi_factor();
let dpi_factor = self.get_hidpi_factor(); LogicalSize::from_physical(physical_size, dpi_factor)
LogicalSize::from_physical(physical_size, dpi_factor)
})
} }
pub(crate) fn get_outer_size_physical(&self) -> Option<(u32, u32)> { pub(crate) fn outer_size_physical(&self) -> (u32, u32) {
util::get_window_rect(self.window.0) util::get_window_rect(self.window.0)
.map(|rect| ( .map(|rect| (
(rect.right - rect.left) as u32, (rect.right - rect.left) as u32,
(rect.bottom - rect.top) as u32, (rect.bottom - rect.top) as u32,
)) ))
.unwrap()
} }
#[inline] #[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> { pub fn outer_size(&self) -> LogicalSize {
self.get_outer_size_physical() let physical_size = self.outer_size_physical();
.map(|physical_size| { let dpi_factor = self.hidpi_factor();
let dpi_factor = self.get_hidpi_factor(); LogicalSize::from_physical(physical_size, dpi_factor)
LogicalSize::from_physical(physical_size, dpi_factor)
})
} }
pub(crate) fn set_inner_size_physical(&self, x: u32, y: u32) { pub(crate) fn set_inner_size_physical(&self, x: u32, y: u32) {
@ -254,41 +243,41 @@ impl Window {
#[inline] #[inline]
pub fn set_inner_size(&self, logical_size: LogicalSize) { pub fn set_inner_size(&self, logical_size: LogicalSize) {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
let (width, height) = logical_size.to_physical(dpi_factor).into(); let (width, height) = logical_size.to_physical(dpi_factor).into();
self.set_inner_size_physical(width, height); self.set_inner_size_physical(width, height);
} }
pub(crate) fn set_min_dimensions_physical(&self, dimensions: Option<(u32, u32)>) { pub(crate) fn set_min_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
self.window_state.lock().min_size = dimensions.map(Into::into); self.window_state.lock().min_size = dimensions.map(Into::into);
// Make windows re-check the window size bounds. // Make windows re-check the window size bounds.
self.get_inner_size_physical() let (width, height) = self.inner_size_physical();
.map(|(width, height)| self.set_inner_size_physical(width, height)); self.set_inner_size_physical(width, height);
} }
#[inline] #[inline]
pub fn set_min_dimensions(&self, logical_size: Option<LogicalSize>) { pub fn set_min_inner_size(&self, logical_size: Option<LogicalSize>) {
let physical_size = logical_size.map(|logical_size| { let physical_size = logical_size.map(|logical_size| {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
logical_size.to_physical(dpi_factor).into() logical_size.to_physical(dpi_factor).into()
}); });
self.set_min_dimensions_physical(physical_size); self.set_min_inner_size_physical(physical_size);
} }
pub fn set_max_dimensions_physical(&self, dimensions: Option<(u32, u32)>) { pub fn set_max_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
self.window_state.lock().max_size = dimensions.map(Into::into); self.window_state.lock().max_size = dimensions.map(Into::into);
// Make windows re-check the window size bounds. // Make windows re-check the window size bounds.
self.get_inner_size_physical() let (width, height) = self.inner_size_physical();
.map(|(width, height)| self.set_inner_size_physical(width, height)); self.set_inner_size_physical(width, height);
} }
#[inline] #[inline]
pub fn set_max_dimensions(&self, logical_size: Option<LogicalSize>) { pub fn set_max_inner_size(&self, logical_size: Option<LogicalSize>) {
let physical_size = logical_size.map(|logical_size| { let physical_size = logical_size.map(|logical_size| {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
logical_size.to_physical(dpi_factor).into() logical_size.to_physical(dpi_factor).into()
}); });
self.set_max_dimensions_physical(physical_size); self.set_max_inner_size_physical(physical_size);
} }
#[inline] #[inline]
@ -313,7 +302,7 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_cursor(&self, cursor: MouseCursor) { pub fn set_cursor_icon(&self, cursor: CursorIcon) {
self.window_state.lock().mouse.cursor = cursor; self.window_state.lock().mouse.cursor = cursor;
self.thread_executor.execute_in_thread(move || unsafe { self.thread_executor.execute_in_thread(move || unsafe {
let cursor = winuser::LoadCursorW( let cursor = winuser::LoadCursorW(
@ -325,7 +314,7 @@ impl Window {
} }
#[inline] #[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
let window = self.window.clone(); let window = self.window.clone();
let window_state = Arc::clone(&self.window_state); let window_state = Arc::clone(&self.window_state);
let (tx, rx) = channel(); let (tx, rx) = channel();
@ -333,21 +322,21 @@ impl Window {
self.thread_executor.execute_in_thread(move || { self.thread_executor.execute_in_thread(move || {
let result = window_state.lock().mouse let result = window_state.lock().mouse
.set_cursor_flags(window.0, |f| f.set(CursorFlags::GRABBED, grab)) .set_cursor_flags(window.0, |f| f.set(CursorFlags::GRABBED, grab))
.map_err(|e| e.to_string()); .map_err(|e| ExternalError::Os(os_error!(e)));
let _ = tx.send(result); let _ = tx.send(result);
}); });
rx.recv().unwrap() rx.recv().unwrap()
} }
#[inline] #[inline]
pub fn hide_cursor(&self, hide: bool) { pub fn set_cursor_visible(&self, visible: bool) {
let window = self.window.clone(); let window = self.window.clone();
let window_state = Arc::clone(&self.window_state); let window_state = Arc::clone(&self.window_state);
let (tx, rx) = channel(); let (tx, rx) = channel();
self.thread_executor.execute_in_thread(move || { self.thread_executor.execute_in_thread(move || {
let result = window_state.lock().mouse let result = window_state.lock().mouse
.set_cursor_flags(window.0, |f| f.set(CursorFlags::HIDDEN, hide)) .set_cursor_flags(window.0, |f| f.set(CursorFlags::HIDDEN, !visible))
.map_err(|e| e.to_string()); .map_err(|e| e.to_string());
let _ = tx.send(result); let _ = tx.send(result);
}); });
@ -355,26 +344,26 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn hidpi_factor(&self) -> f64 {
self.window_state.lock().dpi_factor self.window_state.lock().dpi_factor
} }
fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), String> { fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), ExternalError> {
let mut point = POINT { x, y }; let mut point = POINT { x, y };
unsafe { unsafe {
if winuser::ClientToScreen(self.window.0, &mut point) == 0 { if winuser::ClientToScreen(self.window.0, &mut point) == 0 {
return Err("`ClientToScreen` failed".to_owned()); return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
} }
if winuser::SetCursorPos(point.x, point.y) == 0 { if winuser::SetCursorPos(point.x, point.y) == 0 {
return Err("`SetCursorPos` failed".to_owned()); return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
} }
} }
Ok(()) Ok(())
} }
#[inline] #[inline]
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), String> { pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), ExternalError> {
let dpi_factor = self.get_hidpi_factor(); let dpi_factor = self.hidpi_factor();
let (x, y) = logical_position.to_physical(dpi_factor).into(); let (x, y) = logical_position.to_physical(dpi_factor).into();
self.set_cursor_position_physical(x, y) self.set_cursor_position_physical(x, y)
} }
@ -400,7 +389,7 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> { pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
let window_state = self.window_state.lock(); let window_state = self.window_state.lock();
window_state.fullscreen.clone() window_state.fullscreen.clone()
} }
@ -413,8 +402,8 @@ impl Window {
match &monitor { match &monitor {
&Some(RootMonitorHandle { ref inner }) => { &Some(RootMonitorHandle { ref inner }) => {
let (x, y): (i32, i32) = inner.get_position().into(); let (x, y): (i32, i32) = inner.position().into();
let (width, height): (u32, u32) = inner.get_dimensions().into(); let (width, height): (u32, u32) = inner.dimensions().into();
let mut monitor = monitor.clone(); let mut monitor = monitor.clone();
self.thread_executor.execute_in_thread(move || { self.thread_executor.execute_in_thread(move || {
@ -496,9 +485,9 @@ impl Window {
} }
#[inline] #[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle { pub fn current_monitor(&self) -> RootMonitorHandle {
RootMonitorHandle { RootMonitorHandle {
inner: monitor::get_current_monitor(self.window.0), inner: monitor::current_monitor(self.window.0),
} }
} }
@ -529,7 +518,7 @@ impl Window {
} }
#[inline] #[inline]
pub fn set_ime_spot(&self, _logical_spot: LogicalPosition) { pub fn set_ime_position(&self, _logical_spot: LogicalPosition) {
unimplemented!(); unimplemented!();
} }
} }
@ -575,9 +564,9 @@ pub unsafe fn adjust_size(
unsafe fn init<T: 'static>( unsafe fn init<T: 'static>(
mut attributes: WindowAttributes, mut attributes: WindowAttributes,
mut pl_attribs: PlatformSpecificWindowBuilderAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes,
event_loop: &EventLoopWindowTarget<T>, event_loop: &EventLoopWindowTarget<T>,
) -> Result<Window, CreationError> { ) -> Result<Window, RootOsError> {
let title = OsStr::new(&attributes.title) let title = OsStr::new(&attributes.title)
.encode_wide() .encode_wide()
.chain(Some(0).into_iter()) .chain(Some(0).into_iter())
@ -587,22 +576,18 @@ unsafe fn init<T: 'static>(
let icon = attributes.window_icon let icon = attributes.window_icon
.take() .take()
.map(WinIcon::from_icon); .map(WinIcon::from_icon);
if icon.is_some() { if let Some(icon) = icon {
Some(icon.unwrap().map_err(|err| { Some(icon.map_err(|e| os_error!(e))?)
CreationError::OsError(format!("Failed to create `ICON_SMALL`: {:?}", err))
})?)
} else { } else {
None None
} }
}; };
let taskbar_icon = { let taskbar_icon = {
let icon = pl_attribs.taskbar_icon let icon = attributes.window_icon
.take() .take()
.map(WinIcon::from_icon); .map(WinIcon::from_icon);
if icon.is_some() { if let Some(icon) = icon {
Some(icon.unwrap().map_err(|err| { Some(icon.map_err(|e| os_error!(e))?)
CreationError::OsError(format!("Failed to create `ICON_BIG`: {:?}", err))
})?)
} else { } else {
None None
} }
@ -612,17 +597,17 @@ unsafe fn init<T: 'static>(
let class_name = register_window_class(&window_icon, &taskbar_icon); let class_name = register_window_class(&window_icon, &taskbar_icon);
let guessed_dpi_factor = { let guessed_dpi_factor = {
let monitors = monitor::get_available_monitors(); let monitors = monitor::available_monitors();
let dpi_factor = if !monitors.is_empty() { let dpi_factor = if !monitors.is_empty() {
let mut dpi_factor = Some(monitors[0].get_hidpi_factor()); let mut dpi_factor = Some(monitors[0].hidpi_factor());
for monitor in &monitors { for monitor in &monitors {
if Some(monitor.get_hidpi_factor()) != dpi_factor { if Some(monitor.hidpi_factor()) != dpi_factor {
dpi_factor = None; dpi_factor = None;
} }
} }
dpi_factor dpi_factor
} else { } else {
return Err(CreationError::OsError(format!("No monitors were detected."))); return Err(os_error!(io::Error::new(io::ErrorKind::NotFound, "No monitors were detected.")));
}; };
dpi_factor.unwrap_or_else(|| { dpi_factor.unwrap_or_else(|| {
util::get_cursor_pos() util::get_cursor_pos()
@ -630,7 +615,7 @@ unsafe fn init<T: 'static>(
let mut dpi_factor = None; let mut dpi_factor = None;
for monitor in &monitors { for monitor in &monitors {
if monitor.contains_point(&cursor_pos) { if monitor.contains_point(&cursor_pos) {
dpi_factor = Some(monitor.get_hidpi_factor()); dpi_factor = Some(monitor.hidpi_factor());
break; break;
} }
} }
@ -641,7 +626,7 @@ unsafe fn init<T: 'static>(
}; };
info!("Guessed window DPI factor: {}", guessed_dpi_factor); info!("Guessed window DPI factor: {}", guessed_dpi_factor);
let dimensions = attributes.dimensions.unwrap_or_else(|| (1024, 768).into()); let dimensions = attributes.inner_size.unwrap_or_else(|| (1024, 768).into());
let mut window_flags = WindowFlags::empty(); let mut window_flags = WindowFlags::empty();
window_flags.set(WindowFlags::DECORATIONS, attributes.decorations); window_flags.set(WindowFlags::DECORATIONS, attributes.decorations);
@ -670,8 +655,7 @@ unsafe fn init<T: 'static>(
); );
if handle.is_null() { if handle.is_null() {
return Err(CreationError::OsError(format!("CreateWindowEx function failed: {}", return Err(os_error!(io::Error::last_os_error()));
format!("{}", io::Error::last_os_error()))));
} }
WindowWrapper(handle) WindowWrapper(handle)
@ -688,7 +672,7 @@ unsafe fn init<T: 'static>(
} }
} }
let dpi = get_hwnd_dpi(real_window.0); let dpi = hwnd_dpi(real_window.0);
let dpi_factor = dpi_to_scale_factor(dpi); let dpi_factor = dpi_to_scale_factor(dpi);
if dpi_factor != guessed_dpi_factor { if dpi_factor != guessed_dpi_factor {
let (width, height): (u32, u32) = dimensions.into(); let (width, height): (u32, u32) = dimensions.into();
@ -763,7 +747,7 @@ unsafe fn init<T: 'static>(
force_window_active(win.window.0); force_window_active(win.window.0);
} }
if let Some(dimensions) = attributes.dimensions { if let Some(dimensions) = attributes.inner_size {
win.set_inner_size(dimensions); win.set_inner_size(dimensions);
} }

View file

@ -1,5 +1,5 @@
use monitor::MonitorHandle; use monitor::MonitorHandle;
use window::{MouseCursor, WindowAttributes}; use window::{CursorIcon, WindowAttributes};
use std::{io, ptr}; use std::{io, ptr};
use parking_lot::MutexGuard; use parking_lot::MutexGuard;
use dpi::LogicalSize; use dpi::LogicalSize;
@ -36,7 +36,7 @@ pub struct SavedWindow {
#[derive(Clone)] #[derive(Clone)]
pub struct MouseProperties { pub struct MouseProperties {
pub cursor: MouseCursor, pub cursor: CursorIcon,
pub buttons_down: u32, pub buttons_down: u32,
cursor_flags: CursorFlags, cursor_flags: CursorFlags,
} }
@ -90,13 +90,13 @@ impl WindowState {
) -> WindowState { ) -> WindowState {
WindowState { WindowState {
mouse: MouseProperties { mouse: MouseProperties {
cursor: MouseCursor::default(), cursor: CursorIcon::default(),
buttons_down: 0, buttons_down: 0,
cursor_flags: CursorFlags::empty(), cursor_flags: CursorFlags::empty(),
}, },
min_size: attributes.min_dimensions, min_size: attributes.min_inner_size,
max_size: attributes.max_dimensions, max_size: attributes.max_inner_size,
window_icon, window_icon,
taskbar_icon, taskbar_icon,

View file

View file

@ -1,7 +1,8 @@
//! The `Window` struct and associated types. //! The `Window` struct and associated types.
use std::{fmt, error}; use std::fmt;
use platform_impl; use platform_impl;
use error::{ExternalError, NotSupportedError, OsError};
use event_loop::EventLoopWindowTarget; use event_loop::EventLoopWindowTarget;
use monitor::{AvailableMonitorsIter, MonitorHandle}; use monitor::{AvailableMonitorsIter, MonitorHandle};
use dpi::{LogicalPosition, LogicalSize}; use dpi::{LogicalPosition, LogicalSize};
@ -84,17 +85,17 @@ pub struct WindowAttributes {
/// used. /// used.
/// ///
/// The default is `None`. /// The default is `None`.
pub dimensions: Option<LogicalSize>, pub inner_size: Option<LogicalSize>,
/// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved). /// 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`. /// The default is `None`.
pub min_dimensions: Option<LogicalSize>, pub min_inner_size: 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 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`. /// The default is `None`.
pub max_dimensions: Option<LogicalSize>, pub max_inner_size: Option<LogicalSize>,
/// Whether the window is resizable or not. /// Whether the window is resizable or not.
/// ///
@ -141,19 +142,15 @@ pub struct WindowAttributes {
/// ///
/// The default is `None`. /// The default is `None`.
pub window_icon: Option<Icon>, 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 { impl Default for WindowAttributes {
#[inline] #[inline]
fn default() -> WindowAttributes { fn default() -> WindowAttributes {
WindowAttributes { WindowAttributes {
dimensions: None, inner_size: None,
min_dimensions: None, min_inner_size: None,
max_dimensions: None, max_inner_size: None,
resizable: true, resizable: true,
title: "winit window".to_owned(), title: "winit window".to_owned(),
maximized: false, maximized: false,
@ -163,7 +160,6 @@ impl Default for WindowAttributes {
decorations: true, decorations: true,
always_on_top: false, always_on_top: false,
window_icon: None, window_icon: None,
multitouch: false,
} }
} }
} }
@ -179,22 +175,22 @@ impl WindowBuilder {
/// Requests the window to be of specific dimensions. /// Requests the window to be of specific dimensions.
#[inline] #[inline]
pub fn with_dimensions(mut self, size: LogicalSize) -> WindowBuilder { pub fn with_inner_size(mut self, size: LogicalSize) -> WindowBuilder {
self.window.dimensions = Some(size); self.window.inner_size = Some(size);
self self
} }
/// Sets a minimum dimension size for the window /// Sets a minimum dimension size for the window
#[inline] #[inline]
pub fn with_min_dimensions(mut self, min_size: LogicalSize) -> WindowBuilder { pub fn with_min_inner_size(mut self, min_size: LogicalSize) -> WindowBuilder {
self.window.min_dimensions = Some(min_size); self.window.min_inner_size = Some(min_size);
self self
} }
/// Sets a maximum dimension size for the window /// Sets a maximum dimension size for the window
#[inline] #[inline]
pub fn with_max_dimensions(mut self, max_size: LogicalSize) -> WindowBuilder { pub fn with_max_inner_size(mut self, max_size: LogicalSize) -> WindowBuilder {
self.window.max_dimensions = Some(max_size); self.window.max_inner_size = Some(max_size);
self self
} }
@ -282,23 +278,16 @@ impl WindowBuilder {
self self
} }
/// Enables multitouch.
#[inline]
pub fn with_multitouch(mut self) -> WindowBuilder {
self.window.multitouch = true;
self
}
/// Builds the window. /// Builds the window.
/// ///
/// Error should be very rare and only occur in case of permission denied, incompatible system, /// Error should be very rare and only occur in case of permission denied, incompatible system,
/// out of memory, etc. /// out of memory, etc.
#[inline] #[inline]
pub fn build<T: 'static>(mut self, window_target: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> { pub fn build<T: 'static>(mut self, window_target: &EventLoopWindowTarget<T>) -> Result<Window, OsError> {
self.window.dimensions = Some(self.window.dimensions.unwrap_or_else(|| { self.window.inner_size = Some(self.window.inner_size.unwrap_or_else(|| {
if let Some(ref monitor) = self.window.fullscreen { if let Some(ref monitor) = self.window.fullscreen {
// resizing the window to the dimensions of the monitor when fullscreen // resizing the window to the dimensions of the monitor when fullscreen
LogicalSize::from_physical(monitor.get_dimensions(), 1.0) LogicalSize::from_physical(monitor.dimensions(), 1.0)
} else { } else {
// default dimensions // default dimensions
(1024, 768).into() (1024, 768).into()
@ -314,6 +303,7 @@ impl WindowBuilder {
} }
} }
/// Base Window functions.
impl Window { impl Window {
/// Creates a new Window for platforms where this is appropriate. /// Creates a new Window for platforms where this is appropriate.
/// ///
@ -322,43 +312,36 @@ impl Window {
/// Error should be very rare and only occur in case of permission denied, incompatible system, /// Error should be very rare and only occur in case of permission denied, incompatible system,
/// out of memory, etc. /// out of memory, etc.
#[inline] #[inline]
pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> { pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, OsError> {
let builder = WindowBuilder::new(); let builder = WindowBuilder::new();
builder.build(event_loop) builder.build(event_loop)
} }
/// Modifies the title of the window. /// Returns an identifier unique to the window.
///
/// This is a no-op if the window has already been closed.
///
/// ## Platform-specific
///
/// - Has no effect on iOS.
#[inline] #[inline]
pub fn set_title(&self, title: &str) { pub fn id(&self) -> WindowId {
self.window.set_title(title) WindowId(self.window.id())
} }
/// Shows the window if it was hidden. /// 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.
///
/// Note that this value can change depending on user action (for example if the window is
/// moved to another screen); as such, tracking `WindowEvent::HiDpiFactorChanged` events is
/// the most robust way to track the DPI you need to use to draw.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **Android:** Has no effect. /// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
/// - **iOS:** Can only be called on the main thread. /// - **Android:** Always returns 1.0.
#[inline] /// - **iOS:** Can only be called on the main thread. Returns the underlying `UIView`'s
pub fn show(&self) { /// [`contentScaleFactor`].
self.window.show()
}
/// Hides the window if it was visible.
/// ///
/// ## Platform-specific /// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
///
/// - **Android:** Has no effect.
/// - **iOS:** Can only be called on the main thread.
#[inline] #[inline]
pub fn hide(&self) { pub fn hidpi_factor(&self) -> f64 {
self.window.hide() self.window.hidpi_factor()
} }
/// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS /// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
@ -376,9 +359,29 @@ impl Window {
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Can only be called on the main thread. /// - **iOS:** Can only be called on the main thread.
#[inline]
pub fn request_redraw(&self) { pub fn request_redraw(&self) {
self.window.request_redraw() self.window.request_redraw()
} }
}
/// Position and size functions.
impl Window {
/// Returns the position of the top-left hand corner of the window's client area relative to the
/// top-left hand corner of the desktop.
///
/// The same conditions that apply to `outer_position` apply to this method.
///
/// ## Platform-specific
///
/// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
/// window's [safe area] in the screen space coordinate system.
///
/// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
#[inline]
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
self.window.inner_position()
}
/// Returns the position of the top-left hand corner of the window relative to the /// Returns the position of the top-left hand corner of the window relative to the
/// top-left hand corner of the desktop. /// top-left hand corner of the desktop.
@ -390,36 +393,18 @@ impl Window {
/// The coordinates can be negative if the top-left hand corner of the window is outside /// The coordinates can be negative if the top-left hand corner of the window is outside
/// of the visible screen region. /// of the visible screen region.
/// ///
/// Returns `None` if the window no longer exists.
///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
/// window in the screen space coordinate system. /// window in the screen space coordinate system.
#[inline] #[inline]
pub fn get_position(&self) -> Option<LogicalPosition> { pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
self.window.get_position() self.window.outer_position()
}
/// Returns the position of the top-left hand corner of the window's client area relative to the
/// top-left hand corner of the desktop.
///
/// The same conditions that apply to `get_position` apply to this method.
///
/// ## Platform-specific
///
/// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
/// window's [safe area] in the screen space coordinate system.
///
/// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
#[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
self.window.get_inner_position()
} }
/// Modifies the position of the window. /// Modifies the position of the window.
/// ///
/// See `get_position` for more information about the coordinates. /// See `outer_position` for more information about the coordinates.
/// ///
/// This is a no-op if the window has already been closed. /// This is a no-op if the window has already been closed.
/// ///
@ -428,8 +413,8 @@ impl Window {
/// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the /// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the
/// window in the screen space coordinate system. /// window in the screen space coordinate system.
#[inline] #[inline]
pub fn set_position(&self, position: LogicalPosition) { pub fn set_outer_position(&self, position: LogicalPosition) {
self.window.set_position(position) self.window.set_outer_position(position)
} }
/// Returns the logical size of the window's client area. /// Returns the logical size of the window's client area.
@ -438,40 +423,20 @@ impl Window {
/// ///
/// Converting the returned `LogicalSize` to `PhysicalSize` produces the size your framebuffer should be. /// Converting the returned `LogicalSize` to `PhysicalSize` produces the size your framebuffer should be.
/// ///
/// Returns `None` if the window no longer exists.
///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window's /// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window's
/// [safe area] in screen space coordinates. /// [safe area] in screen space coordinates.
/// ///
/// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
#[inline] #[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> { pub fn inner_size(&self) -> LogicalSize {
self.window.get_inner_size() self.window.inner_size()
}
/// Returns the logical size of the entire window.
///
/// These dimensions include the title bar and borders. If you don't want that (and you usually don't),
/// use `get_inner_size` instead.
///
/// Returns `None` if the window no longer exists.
///
/// ## Platform-specific
///
/// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window in
/// screen space coordinates.
#[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> {
self.window.get_outer_size()
} }
/// Modifies the inner size of the window. /// Modifies the inner size of the window.
/// ///
/// See `get_inner_size` for more information about the values. /// See `inner_size` for more information about the values.
///
/// This is a no-op if the window has already been closed.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
@ -482,14 +447,28 @@ impl Window {
self.window.set_inner_size(size) self.window.set_inner_size(size)
} }
/// Returns the logical size of the entire window.
///
/// These dimensions include the title bar and borders. If you don't want that (and you usually don't),
/// use `inner_size` instead.
///
/// ## Platform-specific
///
/// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window in
/// screen space coordinates.
#[inline]
pub fn outer_size(&self) -> LogicalSize {
self.window.outer_size()
}
/// Sets a minimum dimension size for the window. /// Sets a minimum dimension size for the window.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Has no effect. /// - **iOS:** Has no effect.
#[inline] #[inline]
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
self.window.set_min_dimensions(dimensions) self.window.set_min_inner_size(dimensions)
} }
/// Sets a maximum dimension size for the window. /// Sets a maximum dimension size for the window.
@ -498,8 +477,33 @@ impl Window {
/// ///
/// - **iOS:** Has no effect. /// - **iOS:** Has no effect.
#[inline] #[inline]
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) { pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
self.window.set_max_dimensions(dimensions) self.window.set_max_inner_size(dimensions)
}
}
/// Misc. attribute functions.
impl Window {
/// Modifies the title of the window.
///
/// ## Platform-specific
///
/// - Has no effect on iOS.
#[inline]
pub fn set_title(&self, title: &str) {
self.window.set_title(title)
}
/// Modifies the window's visibility.
///
/// If `false`, this will hide the window. If `true`, this will show the window.
/// ## Platform-specific
///
/// - **Android:** Has no effect.
/// - **iOS:** Can only be called on the main thread.
#[inline]
pub fn set_visible(&self, visible: bool) {
self.window.set_visible(visible)
} }
/// Sets whether the window is resizable or not. /// Sets whether the window is resizable or not.
@ -521,80 +525,10 @@ impl Window {
self.window.set_resizable(resizable) self.window.set_resizable(resizable)
} }
/// 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.
///
/// Note that this value can change depending on user action (for example if the window is
/// moved to another screen); as such, tracking `WindowEvent::HiDpiFactorChanged` events is
/// the most robust way to track the DPI you need to use to draw.
///
/// ## Platform-specific
///
/// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
/// - **Android:** Always returns 1.0.
/// - **iOS:** Can only be called on the main thread. Returns the underlying `UIView`'s
/// [`contentScaleFactor`].
///
/// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
self.window.get_hidpi_factor()
}
/// Modifies the mouse cursor of the window.
///
/// ## Platform-specific
///
/// - **iOS:** Has no effect.
/// - **Android:** Has no effect.
#[inline]
pub fn set_cursor(&self, cursor: MouseCursor) {
self.window.set_cursor(cursor);
}
/// Changes the position of the cursor in window coordinates.
///
/// ## Platform-specific
///
/// - **iOS:** Always returns an `Err`.
#[inline]
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
self.window.set_cursor_position(position)
}
/// Grabs the cursor, preventing it from leaving the window.
///
/// ## Platform-specific
///
/// - **macOS:** This presently merely locks the cursor in a fixed location, which looks visually
/// awkward.
/// - **Android:** Has no effect.
/// - **iOS:** Always returns an Err.
#[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
self.window.grab_cursor(grab)
}
/// Hides the cursor, making it invisible but still usable.
///
/// ## Platform-specific
///
/// - **Windows:** The cursor is only hidden within the confines of the window.
/// - **X11:** The cursor is only hidden within the confines of the window.
/// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
/// outside of the window.
/// - **iOS:** Has no effect.
/// - **Android:** Has no effect.
#[inline]
pub fn hide_cursor(&self, hide: bool) {
self.window.hide_cursor(hide)
}
/// Sets the window to maximized or back. /// Sets the window to maximized or back.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Has no effect. /// - **iOS:** Has no effect.
#[inline] #[inline]
pub fn set_maximized(&self, maximized: bool) { pub fn set_maximized(&self, maximized: bool) {
@ -604,7 +538,7 @@ impl Window {
/// Sets the window to fullscreen or back. /// Sets the window to fullscreen or back.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Can only be called on the main thread. /// - **iOS:** Can only be called on the main thread.
#[inline] #[inline]
pub fn set_fullscreen(&self, monitor: Option<MonitorHandle>) { pub fn set_fullscreen(&self, monitor: Option<MonitorHandle>) {
@ -614,20 +548,20 @@ impl Window {
/// Gets the window's current fullscreen state. /// Gets the window's current fullscreen state.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Can only be called on the main thread. /// - **iOS:** Can only be called on the main thread.
#[inline] #[inline]
pub fn get_fullscreen(&self) -> Option<MonitorHandle> { pub fn fullscreen(&self) -> Option<MonitorHandle> {
self.window.get_fullscreen() self.window.fullscreen()
} }
/// Turn window decorations on or off. /// Turn window decorations on or off.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Can only be called on the main thread. Controls whether the status bar is hidden /// - **iOS:** Can only be called on the main thread. Controls whether the status bar is hidden
/// via [`setPrefersStatusBarHidden`]. /// via [`setPrefersStatusBarHidden`].
/// ///
/// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc /// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc
#[inline] #[inline]
pub fn set_decorations(&self, decorations: bool) { pub fn set_decorations(&self, decorations: bool) {
@ -637,7 +571,7 @@ impl Window {
/// Change whether or not the window will always be on top of other windows. /// Change whether or not the window will always be on top of other windows.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **iOS:** Has no effect. /// - **iOS:** Has no effect.
#[inline] #[inline]
pub fn set_always_on_top(&self, always_on_top: bool) { pub fn set_always_on_top(&self, always_on_top: bool) {
@ -663,85 +597,105 @@ impl Window {
/// ///
/// **iOS:** Has no effect. /// **iOS:** Has no effect.
#[inline] #[inline]
pub fn set_ime_spot(&self, position: LogicalPosition) { pub fn set_ime_position(&self, position: LogicalPosition) {
self.window.set_ime_spot(position) self.window.set_ime_position(position)
}
}
/// Cursor functions.
impl Window {
/// Modifies the cursor icon of the window.
///
/// ## Platform-specific
///
/// - **iOS:** Has no effect.
/// - **Android:** Has no effect.
#[inline]
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
self.window.set_cursor_icon(cursor);
} }
/// Changes the position of the cursor in window coordinates.
///
/// ## Platform-specific
///
/// - **iOS:** Always returns an `Err`.
#[inline]
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> {
self.window.set_cursor_position(position)
}
/// Grabs the cursor, preventing it from leaving the window.
///
/// ## Platform-specific
///
/// - **macOS:** This presently merely locks the cursor in a fixed location, which looks visually
/// awkward.
/// - **Android:** Has no effect.
/// - **iOS:** Always returns an Err.
#[inline]
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
self.window.set_cursor_grab(grab)
}
/// Hides the cursor, making it invisible but still usable.
///
/// ## Platform-specific
///
/// - **Windows:** The cursor is only hidden within the confines of the window.
/// - **X11:** The cursor is only hidden within the confines of the window.
/// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
/// outside of the window.
/// - **iOS:** Has no effect.
/// - **Android:** Has no effect.
#[inline]
pub fn set_cursor_visible(&self, visible: bool) {
self.window.set_cursor_visible(visible)
}
}
/// Monitor info functions.
impl Window {
/// Returns the monitor on which the window currently resides /// Returns the monitor on which the window currently resides
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// **iOS:** Can only be called on the main thread. /// **iOS:** Can only be called on the main thread.
#[inline] #[inline]
pub fn get_current_monitor(&self) -> MonitorHandle { pub fn current_monitor(&self) -> MonitorHandle {
self.window.get_current_monitor() self.window.current_monitor()
} }
/// Returns the list of all the monitors available on the system. /// Returns the list of all the monitors available on the system.
/// ///
/// This is the same as `EventLoop::get_available_monitors`, and is provided for convenience. /// This is the same as `EventLoop::available_monitors`, and is provided for convenience.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// **iOS:** Can only be called on the main thread. /// **iOS:** Can only be called on the main thread.
#[inline] #[inline]
pub fn get_available_monitors(&self) -> AvailableMonitorsIter { pub fn available_monitors(&self) -> AvailableMonitorsIter {
let data = self.window.get_available_monitors(); let data = self.window.available_monitors();
AvailableMonitorsIter { data: data.into_iter() } AvailableMonitorsIter { data: data.into_iter() }
} }
/// Returns the primary monitor of the system. /// Returns the primary monitor of the system.
/// ///
/// This is the same as `EventLoop::get_primary_monitor`, and is provided for convenience. /// This is the same as `EventLoop::primary_monitor`, and is provided for convenience.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// **iOS:** Can only be called on the main thread. /// **iOS:** Can only be called on the main thread.
#[inline] #[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle { inner: self.window.get_primary_monitor() } MonitorHandle { inner: self.window.primary_monitor() }
}
/// Returns an identifier unique to the window.
#[inline]
pub fn id(&self) -> WindowId {
WindowId(self.window.id())
}
}
/// 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 fmt::Display for CreationError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(self.to_string())
}
}
impl error::Error for CreationError {
fn description(&self) -> &str {
self.to_string()
} }
} }
/// Describes the appearance of the mouse cursor. /// Describes the appearance of the mouse cursor.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum MouseCursor { pub enum CursorIcon {
/// The platform-dependent default cursor. /// The platform-dependent default cursor.
Default, Default,
/// A simple crosshair. /// A simple crosshair.
@ -795,8 +749,8 @@ pub enum MouseCursor {
RowResize, RowResize,
} }
impl Default for MouseCursor { impl Default for CursorIcon {
fn default() -> Self { fn default() -> Self {
MouseCursor::Default CursorIcon::Default
} }
} }

View file

@ -3,7 +3,7 @@
extern crate serde; extern crate serde;
extern crate winit; extern crate winit;
use winit::window::{MouseCursor}; use winit::window::{CursorIcon};
use winit::event::{ use winit::event::{
KeyboardInput, TouchPhase, ElementState, MouseButton, MouseScrollDelta, VirtualKeyCode, KeyboardInput, TouchPhase, ElementState, MouseButton, MouseScrollDelta, VirtualKeyCode,
ModifiersState ModifiersState
@ -15,7 +15,7 @@ fn needs_serde<S: Serialize + Deserialize<'static>>() {}
#[test] #[test]
fn window_serde() { fn window_serde() {
needs_serde::<MouseCursor>(); needs_serde::<CursorIcon>();
} }
#[test] #[test]