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.
- Rename `MonitorId` to `MonitorHandle`.
- 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)

View file

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

View file

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

View file

@ -82,16 +82,16 @@ fn main() {
if !is_fullscreen {
window.set_fullscreen(None);
} else {
window.set_fullscreen(Some(window.get_current_monitor()));
window.set_fullscreen(Some(window.current_monitor()));
}
}
(VirtualKeyCode::S, ElementState::Pressed) => {
println!("window.get_fullscreen {:?}", window.get_fullscreen());
println!("window.fullscreen {:?}", window.fullscreen());
#[cfg(target_os = "macos")]
{
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) => {
@ -113,8 +113,8 @@ fn main() {
// Enumerate monitors and prompt user to choose one
fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle {
for (num, monitor) in event_loop.get_available_monitors().enumerate() {
println!("Monitor #{}: {:?}", num, monitor.get_name());
for (num, monitor) in event_loop.available_monitors().enumerate() {
println!("Monitor #{}: {:?}", num, monitor.name());
}
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();
io::stdin().read_line(&mut num).unwrap();
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
}

View file

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

View file

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

View file

@ -10,7 +10,7 @@ fn main() {
let window = WindowBuilder::new()
.with_title("Hit space to toggle resizability.")
.with_dimensions((400, 200).into())
.with_inner_size((400, 200).into())
.with_resizable(resizable)
.build(&event_loop)
.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,
//! or because the user changed the configuration of their screen.
//! - 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
//! [`Window::get_hidpi_factor`](../window/struct.Window.html#method.get_hidpi_factor), which is roughly equivalent
//! to `window.get_current_monitor().get_hidpi_factor()`.
//! [`Window::hidpi_factor`](../window/struct.Window.html#method.hidpi_factor), which is roughly equivalent
//! to `window.current_monitor().hidpi_factor()`.
//!
//! 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,

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<()> {
/// Builds a new event loop with a `()` as the user event type.
///
///
/// ## Platform-specific
///
///
/// - **iOS:** Can only be called on the main thread.
pub fn new() -> EventLoop<()> {
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`.
/// 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.
///
///
/// ## Platform-specific
///
///
/// - **iOS:** Can only be called on the main thread.
pub fn new_user_event() -> EventLoop<T> {
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
/// closure. Since the closure is `'static`, it must be a `move` closure if it needs to
/// access any data from the calling context.
@ -153,13 +138,27 @@ impl<T> EventLoop<T> {
self.event_loop.run(event_handler)
}
/// Creates an `EventLoopProxy` that can be used to wake up the `EventLoop` from another
/// thread.
/// Creates an `EventLoopProxy` that can be used to dispatch user events to the main event loop.
pub fn create_proxy(&self) -> EventLoopProxy<T> {
EventLoopProxy {
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> {

View file

@ -113,6 +113,8 @@ extern crate smithay_client_toolkit as sctk;
extern crate calloop;
pub mod dpi;
#[macro_use]
pub mod error;
pub mod event;
pub mod event_loop;
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]
//! type. This is retreived from an [`AvailableMonitorsIter`][monitor_iter], which can be acquired
//! with:
//! - [`EventLoop::get_available_monitors`][loop_get]
//! - [`Window::get_available_monitors`][window_get].
//! - [`EventLoop::available_monitors`][loop_get]
//! - [`Window::available_monitors`][window_get].
//!
//! [monitor_id]: ./struct.MonitorHandle.html
//! [monitor_iter]: ./struct.AvailableMonitorsIter.html
//! [loop_get]: ../event_loop/struct.EventLoop.html#method.get_available_monitors
//! [window_get]: ../window/struct.Window.html#method.get_available_monitors
//! [loop_get]: ../event_loop/struct.EventLoop.html#method.available_monitors
//! [window_get]: ../window/struct.Window.html#method.available_monitors
use std::collections::vec_deque::IntoIter as VecDequeIter;
use platform_impl;
@ -18,11 +18,11 @@ use dpi::{PhysicalPosition, PhysicalSize};
/// An iterator over all available monitors.
///
/// Can be acquired with:
/// - [`EventLoop::get_available_monitors`][loop_get]
/// - [`Window::get_available_monitors`][window_get].
/// - [`EventLoop::available_monitors`][loop_get]
/// - [`Window::available_monitors`][window_get].
///
/// [loop_get]: ../event_loop/struct.EventLoop.html#method.get_available_monitors
/// [window_get]: ../window/struct.Window.html#method.get_available_monitors
/// [loop_get]: ../event_loop/struct.EventLoop.html#method.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.
// This may change in the future.
#[derive(Debug)]
@ -59,21 +59,21 @@ impl MonitorHandle {
///
/// Returns `None` if the monitor doesn't exist anymore.
#[inline]
pub fn get_name(&self) -> Option<String> {
self.inner.get_name()
pub fn name(&self) -> Option<String> {
self.inner.name()
}
/// Returns the monitor's resolution.
#[inline]
pub fn get_dimensions(&self) -> PhysicalSize {
self.inner.get_dimensions()
pub fn dimensions(&self) -> PhysicalSize {
self.inner.dimensions()
}
/// Returns the top-left corner position of the monitor relative to the larger full
/// screen area.
#[inline]
pub fn get_position(&self) -> PhysicalPosition {
self.inner.get_position()
pub fn position(&self) -> PhysicalPosition {
self.inner.position()
}
/// 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.
/// - **Android:** Always returns 1.0.
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
self.inner.get_hidpi_factor()
pub fn hidpi_factor(&self) -> f64 {
self.inner.hidpi_factor()
}
}

View file

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

View file

@ -9,12 +9,12 @@ use window::{Window, WindowBuilder};
/// Additional methods on `EventLoop` that are specific to iOS.
pub trait EventLoopExtIOS {
/// 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> {
fn get_idiom(&self) -> Idiom {
self.event_loop.get_idiom()
fn idiom(&self) -> Idiom {
self.event_loop.idiom()
}
}
@ -23,43 +23,43 @@ pub trait WindowExtIOS {
/// Returns a pointer to the `UIWindow` that is used by this window.
///
/// 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.
///
/// 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.
///
/// 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.
///
///
/// This translates to `-[UIWindow setContentScaleFactor:hidpi_factor]`.
fn set_hidpi_factor(&self, hidpi_factor: f64);
/// Sets the valid orientations for screens showing this `Window`.
///
///
/// On iPhones and iPods upside down portrait is never enabled.
fn set_valid_orientations(&self, valid_orientations: ValidOrientations);
}
impl WindowExtIOS for Window {
#[inline]
fn get_uiwindow(&self) -> *mut c_void {
self.window.get_uiwindow() as _
fn ui_window(&self) -> *mut c_void {
self.window.ui_window() as _
}
#[inline]
fn get_uiviewcontroller(&self) -> *mut c_void {
self.window.get_uiviewcontroller() as _
fn ui_view_controller(&self) -> *mut c_void {
self.window.ui_view_controller() as _
}
#[inline]
fn get_uiview(&self) -> *mut c_void {
self.window.get_uiview() as _
fn ui_view(&self) -> *mut c_void {
self.window.ui_view() as _
}
#[inline]
@ -79,13 +79,13 @@ pub trait WindowBuilderExtIOS {
///
/// The class will be initialized by calling `[root_view initWithFrame:CGRect]`
fn with_root_view_class(self, root_view_class: *const c_void) -> WindowBuilder;
/// 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
/// this to `MonitorHandle::get_hidpi_factor()`.
/// this to `MonitorHandle::hidpi_factor()`.
fn with_hidpi_factor(self, hidpi_factor: f64) -> WindowBuilder;
/// Sets the valid orientations for the `Window`.
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.
pub trait MonitorHandleExtIOS {
/// 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 {
#[inline]
fn get_uiscreen(&self) -> *mut c_void {
self.inner.get_uiscreen() as _
fn ui_screen(&self) -> *mut c_void {
self.inner.ui_screen() as _
}
}
@ -130,7 +130,7 @@ pub enum ValidOrientations {
LandscapeAndPortrait,
Landscape,
/// Excludes `PortraitUpsideDown` on iphone
Portrait,
}
@ -143,7 +143,7 @@ impl Default for ValidOrientations {
}
/// The device [idiom].
///
///
/// [idiom]: https://developer.apple.com/documentation/uikit/uidevice/1620037-userinterfaceidiom?language=objc
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
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.
///
/// 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.
///
/// 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.
/// 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);
/// 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.
/// Returns a boolean indicating whether the transition was successful (this
@ -41,13 +41,13 @@ pub trait WindowExtMacOS {
impl WindowExtMacOS for Window {
#[inline]
fn get_nswindow(&self) -> *mut c_void {
self.window.get_nswindow()
fn nswindow(&self) -> *mut c_void {
self.window.nswindow()
}
#[inline]
fn get_nsview(&self) -> *mut c_void {
self.window.get_nsview()
fn nsview(&self) -> *mut c_void {
self.window.nsview()
}
#[inline]
@ -56,8 +56,8 @@ impl WindowExtMacOS for Window {
}
#[inline]
fn get_simple_fullscreen(&self) -> bool {
self.window.get_simple_fullscreen()
fn simple_fullscreen(&self) -> bool {
self.window.simple_fullscreen()
}
#[inline]
@ -167,16 +167,16 @@ pub trait MonitorHandleExtMacOS {
/// Returns the identifier of the monitor for Cocoa.
fn native_id(&self) -> u32;
/// 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 {
#[inline]
fn native_id(&self) -> u32 {
self.inner.get_native_identifier()
self.inner.native_identifier()
}
fn get_nsscreen(&self) -> Option<*mut c_void> {
self.inner.get_nsscreen().map(|s| s as *mut c_void)
fn nsscreen(&self) -> Option<*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;
#[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 `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.
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> {
@ -154,7 +154,7 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
#[inline]
#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
fn xlib_xconnection(&self) -> Option<Arc<XConnection>> {
match self.event_loop {
LinuxEventLoop::X(ref e) => Some(e.x_connection().clone()),
_ => None
@ -162,9 +162,9 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
}
#[inline]
fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
fn wayland_display(&self) -> Option<*mut raw::c_void> {
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
}
}
@ -175,19 +175,19 @@ pub trait WindowExtUnix {
/// 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).
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 `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.
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)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
fn xlib_xconnection(&self) -> Option<Arc<XConnection>>;
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
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).
///
/// 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 `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.
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 `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.
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
fn set_wayland_theme(&self, theme: WaylandTheme);
@ -228,42 +228,42 @@ pub trait WindowExtUnix {
impl WindowExtUnix for Window {
#[inline]
fn get_xlib_window(&self) -> Option<raw::c_ulong> {
fn xlib_window(&self) -> Option<raw::c_ulong> {
match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_window()),
LinuxWindow::X(ref w) => Some(w.xlib_window()),
_ => None
}
}
#[inline]
fn get_xlib_display(&self) -> Option<*mut raw::c_void> {
fn xlib_display(&self) -> Option<*mut raw::c_void> {
match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_display()),
LinuxWindow::X(ref w) => Some(w.xlib_display()),
_ => None
}
}
#[inline]
fn get_xlib_screen_id(&self) -> Option<raw::c_int> {
fn xlib_screen_id(&self) -> Option<raw::c_int> {
match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
LinuxWindow::X(ref w) => Some(w.xlib_screen_id()),
_ => None
}
}
#[inline]
#[doc(hidden)]
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
fn xlib_xconnection(&self) -> Option<Arc<XConnection>> {
match self.window {
LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
LinuxWindow::X(ref w) => Some(w.xlib_xconnection()),
_ => None
}
}
#[inline]
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> {
fn xcb_connection(&self) -> Option<*mut raw::c_void> {
match self.window {
LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
LinuxWindow::X(ref w) => Some(w.xcb_connection()),
_ => None
}
}
@ -276,17 +276,17 @@ impl WindowExtUnix for Window {
}
#[inline]
fn get_wayland_surface(&self) -> Option<*mut raw::c_void> {
fn wayland_surface(&self) -> Option<*mut raw::c_void> {
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
}
}
#[inline]
fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
fn wayland_display(&self) -> Option<*mut raw::c_void> {
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
}
}
@ -398,6 +398,6 @@ pub trait MonitorHandleExtUnix {
impl MonitorHandleExtUnix for MonitorHandle {
#[inline]
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.
///
/// 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.
fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>);
@ -41,7 +41,7 @@ pub trait WindowExtWindows {
impl WindowExtWindows for Window {
#[inline]
fn get_hwnd(&self) -> *mut libc::c_void {
fn hwnd(&self) -> *mut libc::c_void {
self.window.hwnd() as *mut _
}
@ -95,12 +95,12 @@ pub trait MonitorHandleExtWindows {
impl MonitorHandleExtWindows for MonitorHandle {
#[inline]
fn native_id(&self) -> String {
self.inner.get_native_identifier()
self.inner.native_identifier()
}
#[inline]
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.
///
/// 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 {
#[inline]
fn get_persistent_identifier(&self) -> Option<String> {
self.0.get_persistent_identifier()
fn persistent_identifier(&self) -> Option<String> {
self.0.persistent_identifier()
}
}

View file

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

View file

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

View file

@ -76,6 +76,8 @@ mod monitor;
mod view;
mod window;
use std::fmt;
pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
pub use self::monitor::MonitorHandle;
pub use self::window::{
@ -99,3 +101,14 @@ impl DeviceId {
unsafe impl Send 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 {
name: self.get_name(),
dimensions: self.get_dimensions(),
position: self.get_position(),
hidpi_factor: self.get_hidpi_factor(),
name: self.name(),
dimensions: self.dimensions(),
position: self.position(),
hidpi_factor: self.hidpi_factor(),
};
monitor_id_proxy.fmt(f)
@ -99,7 +99,7 @@ impl MonitorHandle {
}
impl Inner {
pub fn get_name(&self) -> Option<String> {
pub fn name(&self) -> Option<String> {
unsafe {
if self.uiscreen == main_uiscreen().uiscreen {
Some("Primary".to_string())
@ -113,24 +113,24 @@ impl Inner {
}
}
}
pub fn get_dimensions(&self) -> PhysicalSize {
pub fn dimensions(&self) -> PhysicalSize {
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()
}
}
pub fn get_position(&self) -> PhysicalPosition {
pub fn position(&self) -> PhysicalPosition {
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()
}
}
pub fn get_hidpi_factor(&self) -> f64 {
pub fn hidpi_factor(&self) -> f64 {
unsafe {
let scale: CGFloat = msg_send![self.get_uiscreen(), nativeScale];
let scale: CGFloat = msg_send![self.ui_screen(), nativeScale];
scale as f64
}
}
@ -138,7 +138,7 @@ impl Inner {
// MonitorHandleExtIOS
impl Inner {
pub fn get_uiscreen(&self) -> id {
pub fn ui_screen(&self) -> id {
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 {
static mut CLASSES: Option<HashMap<*const Class, &'static Class>> = None;
static mut ID: usize = 0;
if CLASSES.is_none() {
CLASSES = Some(HashMap::default());
}
@ -255,7 +255,7 @@ unsafe fn get_window_class() -> &'static Class {
// requires main thread
pub unsafe fn create_view(
window_attributes: &WindowAttributes,
_window_attributes: &WindowAttributes,
platform_attributes: &PlatformSpecificWindowBuilderAttributes,
frame: CGRect,
) -> id {
@ -265,9 +265,7 @@ pub unsafe fn create_view(
assert!(!view.is_null(), "Failed to create `UIView` instance");
let view: id = msg_send![view, initWithFrame:frame];
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
}
@ -318,7 +316,7 @@ pub unsafe fn create_window(
let () = msg_send![window, setContentScaleFactor:hidpi_factor as CGFloat];
}
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

View file

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

View file

@ -1,7 +1,7 @@
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
use std::collections::VecDeque;
use std::{env, mem};
use std::{env, mem, fmt};
use std::ffi::CStr;
use std::os::raw::*;
use std::sync::Arc;
@ -11,10 +11,11 @@ use sctk::reexports::client::ConnectError;
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
use icon::Icon;
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
use event::Event;
use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
use monitor::MonitorHandle as RootMonitorHandle;
use window::{WindowAttributes, CreationError, MouseCursor};
use window::{WindowAttributes, CursorIcon};
use self::x11::{XConnection, XError};
use self::x11::ffi::XVisualInfo;
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 {
X(x11::Window),
Wayland(wayland::Window),
@ -88,42 +104,42 @@ pub enum MonitorHandle {
impl MonitorHandle {
#[inline]
pub fn get_name(&self) -> Option<String> {
pub fn name(&self) -> Option<String> {
match self {
&MonitorHandle::X(ref m) => m.get_name(),
&MonitorHandle::Wayland(ref m) => m.get_name(),
&MonitorHandle::X(ref m) => m.name(),
&MonitorHandle::Wayland(ref m) => m.name(),
}
}
#[inline]
pub fn get_native_identifier(&self) -> u32 {
pub fn native_identifier(&self) -> u32 {
match self {
&MonitorHandle::X(ref m) => m.get_native_identifier(),
&MonitorHandle::Wayland(ref m) => m.get_native_identifier(),
&MonitorHandle::X(ref m) => m.native_identifier(),
&MonitorHandle::Wayland(ref m) => m.native_identifier(),
}
}
#[inline]
pub fn get_dimensions(&self) -> PhysicalSize {
pub fn dimensions(&self) -> PhysicalSize {
match self {
&MonitorHandle::X(ref m) => m.get_dimensions(),
&MonitorHandle::Wayland(ref m) => m.get_dimensions(),
&MonitorHandle::X(ref m) => m.dimensions(),
&MonitorHandle::Wayland(ref m) => m.dimensions(),
}
}
#[inline]
pub fn get_position(&self) -> PhysicalPosition {
pub fn position(&self) -> PhysicalPosition {
match self {
&MonitorHandle::X(ref m) => m.get_position(),
&MonitorHandle::Wayland(ref m) => m.get_position(),
&MonitorHandle::X(ref m) => m.position(),
&MonitorHandle::Wayland(ref m) => m.position(),
}
}
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
pub fn hidpi_factor(&self) -> f64 {
match self {
&MonitorHandle::X(ref m) => m.get_hidpi_factor(),
&MonitorHandle::Wayland(ref m) => m.get_hidpi_factor() as f64,
&MonitorHandle::X(ref m) => m.hidpi_factor(),
&MonitorHandle::Wayland(ref m) => m.hidpi_factor() as f64,
}
}
}
@ -134,7 +150,7 @@ impl Window {
window_target: &EventLoopWindowTarget<T>,
attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<Self, CreationError> {
) -> Result<Self, RootOsError> {
match *window_target {
EventLoopWindowTarget::Wayland(ref window_target) => {
wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland)
@ -162,58 +178,50 @@ impl Window {
}
#[inline]
pub fn show(&self) {
pub fn set_visible(&self, visible: bool) {
match self {
&Window::X(ref w) => w.show(),
&Window::Wayland(ref w) => w.show(),
&Window::X(ref w) => w.set_visible(visible),
&Window::Wayland(ref w) => w.set_visible(visible),
}
}
#[inline]
pub fn hide(&self) {
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
match self {
&Window::X(ref w) => w.hide(),
&Window::Wayland(ref w) => w.hide(),
&Window::X(ref w) => w.outer_position(),
&Window::Wayland(ref w) => w.outer_position(),
}
}
#[inline]
pub fn get_position(&self) -> Option<LogicalPosition> {
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
match self {
&Window::X(ref w) => w.get_position(),
&Window::Wayland(ref w) => w.get_position(),
&Window::X(ref m) => m.inner_position(),
&Window::Wayland(ref m) => m.inner_position(),
}
}
#[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
pub fn set_outer_position(&self, position: LogicalPosition) {
match self {
&Window::X(ref m) => m.get_inner_position(),
&Window::Wayland(ref m) => m.get_inner_position(),
&Window::X(ref w) => w.set_outer_position(position),
&Window::Wayland(ref w) => w.set_outer_position(position),
}
}
#[inline]
pub fn set_position(&self, position: LogicalPosition) {
pub fn inner_size(&self) -> LogicalSize {
match self {
&Window::X(ref w) => w.set_position(position),
&Window::Wayland(ref w) => w.set_position(position),
&Window::X(ref w) => w.inner_size(),
&Window::Wayland(ref w) => w.inner_size(),
}
}
#[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> {
pub fn outer_size(&self) -> LogicalSize {
match self {
&Window::X(ref w) => w.get_inner_size(),
&Window::Wayland(ref w) => w.get_inner_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(),
&Window::X(ref w) => w.outer_size(),
&Window::Wayland(ref w) => w.outer_size(),
}
}
@ -226,18 +234,18 @@ impl Window {
}
#[inline]
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
match self {
&Window::X(ref w) => w.set_min_dimensions(dimensions),
&Window::Wayland(ref w) => w.set_min_dimensions(dimensions),
&Window::X(ref w) => w.set_min_inner_size(dimensions),
&Window::Wayland(ref w) => w.set_min_inner_size(dimensions),
}
}
#[inline]
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
match self {
&Window::X(ref w) => w.set_max_dimensions(dimensions),
&Window::Wayland(ref w) => w.set_max_dimensions(dimensions),
&Window::X(ref w) => w.set_max_inner_size(dimensions),
&Window::Wayland(ref w) => w.set_max_inner_size(dimensions),
}
}
@ -250,39 +258,39 @@ impl Window {
}
#[inline]
pub fn set_cursor(&self, cursor: MouseCursor) {
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
match self {
&Window::X(ref w) => w.set_cursor(cursor),
&Window::Wayland(ref w) => w.set_cursor(cursor)
&Window::X(ref w) => w.set_cursor_icon(cursor),
&Window::Wayland(ref w) => w.set_cursor_icon(cursor)
}
}
#[inline]
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
match self {
&Window::X(ref window) => window.grab_cursor(grab),
&Window::Wayland(ref window) => window.grab_cursor(grab),
&Window::X(ref window) => window.set_cursor_grab(grab),
&Window::Wayland(ref window) => window.set_cursor_grab(grab),
}
}
#[inline]
pub fn hide_cursor(&self, hide: bool) {
pub fn set_cursor_visible(&self, visible: bool) {
match self {
&Window::X(ref window) => window.hide_cursor(hide),
&Window::Wayland(ref window) => window.hide_cursor(hide),
&Window::X(ref window) => window.set_cursor_visible(visible),
&Window::Wayland(ref window) => window.set_cursor_visible(visible),
}
}
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
pub fn hidpi_factor(&self) -> f64 {
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,
}
}
#[inline]
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> {
match self {
&Window::X(ref w) => w.set_cursor_position(position),
&Window::Wayland(ref w) => w.set_cursor_position(position),
@ -298,10 +306,10 @@ impl Window {
}
#[inline]
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
match self {
&Window::X(ref w) => w.get_fullscreen(),
&Window::Wayland(ref w) => w.get_fullscreen()
&Window::X(ref w) => w.fullscreen(),
&Window::Wayland(ref w) => w.fullscreen()
.map(|monitor_id| RootMonitorHandle { inner: MonitorHandle::Wayland(monitor_id) })
}
}
@ -339,9 +347,9 @@ impl Window {
}
#[inline]
pub fn set_ime_spot(&self, position: LogicalPosition) {
pub fn set_ime_position(&self, position: LogicalPosition) {
match self {
&Window::X(ref w) => w.set_ime_spot(position),
&Window::X(ref w) => w.set_ime_position(position),
&Window::Wayland(_) => (),
}
}
@ -355,21 +363,21 @@ impl Window {
}
#[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle {
pub fn current_monitor(&self) -> RootMonitorHandle {
match self {
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.get_current_monitor()) },
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.get_current_monitor()) },
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.current_monitor()) },
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.current_monitor()) },
}
}
#[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
match self {
&Window::X(ref window) => window.get_available_monitors()
&Window::X(ref window) => window.available_monitors()
.into_iter()
.map(MonitorHandle::X)
.collect(),
&Window::Wayland(ref window) => window.get_available_monitors()
&Window::Wayland(ref window) => window.available_monitors()
.into_iter()
.map(MonitorHandle::Wayland)
.collect(),
@ -377,10 +385,10 @@ impl Window {
}
#[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle {
pub fn primary_monitor(&self) -> MonitorHandle {
match self {
&Window::X(ref window) => MonitorHandle::X(window.get_primary_monitor()),
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.get_primary_monitor()),
&Window::X(ref window) => MonitorHandle::X(window.primary_monitor()),
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.primary_monitor()),
}
}
}
@ -481,16 +489,16 @@ impl<T:'static> EventLoop<T> {
}
#[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
match *self {
EventLoop::Wayland(ref evlp) => evlp
.get_available_monitors()
.available_monitors()
.into_iter()
.map(MonitorHandle::Wayland)
.collect(),
EventLoop::X(ref evlp) => evlp
.x_connection()
.get_available_monitors()
.available_monitors()
.into_iter()
.map(MonitorHandle::X)
.collect(),
@ -498,10 +506,10 @@ impl<T:'static> EventLoop<T> {
}
#[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle {
pub fn primary_monitor(&self) -> MonitorHandle {
match *self {
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.get_primary_monitor()),
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().get_primary_monitor()),
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.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
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);
}
pub fn get_primary_monitor(&self) -> MonitorHandle {
get_primary_monitor(&self.outputs)
pub fn primary_monitor(&self) -> MonitorHandle {
primary_monitor(&self.outputs)
}
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors(&self.outputs)
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
available_monitors(&self.outputs)
}
pub fn get_display(&self) -> &Display {
pub fn display(&self) -> &Display {
&*self.display
}
@ -532,11 +532,11 @@ impl fmt::Debug for MonitorHandle {
}
let monitor_id_proxy = MonitorHandle {
name: self.get_name(),
native_identifier: self.get_native_identifier(),
dimensions: self.get_dimensions(),
position: self.get_position(),
hidpi_factor: self.get_hidpi_factor(),
name: self.name(),
native_identifier: self.native_identifier(),
dimensions: self.dimensions(),
position: self.position(),
hidpi_factor: self.hidpi_factor(),
};
monitor_id_proxy.fmt(f)
@ -544,18 +544,18 @@ impl fmt::Debug for MonitorHandle {
}
impl MonitorHandle {
pub fn get_name(&self) -> Option<String> {
pub fn name(&self) -> Option<String> {
self.mgr.with_info(&self.proxy, |_, info| {
format!("{} ({})", info.model, info.make)
})
}
#[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)
}
pub fn get_dimensions(&self) -> PhysicalSize {
pub fn dimensions(&self) -> PhysicalSize {
match self.mgr.with_info(&self.proxy, |_, info| {
info.modes
.iter()
@ -567,7 +567,7 @@ impl MonitorHandle {
}.into()
}
pub fn get_position(&self) -> PhysicalPosition {
pub fn position(&self) -> PhysicalPosition {
self.mgr
.with_info(&self.proxy, |_, info| info.location)
.unwrap_or((0, 0))
@ -575,14 +575,14 @@ impl MonitorHandle {
}
#[inline]
pub fn get_hidpi_factor(&self) -> i32 {
pub fn hidpi_factor(&self) -> i32 {
self.mgr
.with_info(&self.proxy, |_, info| info.scale_factor)
.unwrap_or(1)
}
}
pub fn get_primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
pub fn primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
outputs.with_all(|list| {
if let Some(&(_, ref proxy, _)) = list.first() {
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| {
list.iter()
.map(|&(_, ref proxy, _)| MonitorHandle {

View file

@ -2,9 +2,10 @@ use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak};
use dpi::{LogicalPosition, LogicalSize};
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
use monitor::MonitorHandle as RootMonitorHandle;
use window::{CreationError, WindowAttributes, MouseCursor};
use window::{WindowAttributes, CursorIcon};
use sctk::surface::{get_dpi_factor, get_outputs};
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 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 {
surface: wl_surface::WlSurface,
@ -28,8 +29,8 @@ pub struct Window {
}
impl Window {
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> {
let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600));
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, RootOsError> {
let (width, height) = attributes.inner_size.map(Into::into).unwrap_or((800, 600));
// Create the window
let size = Arc::new(Mutex::new((width, height)));
let fullscreen = Arc::new(Mutex::new(false));
@ -109,8 +110,8 @@ impl Window {
frame.set_title(attributes.title);
// min-max dimensions
frame.set_min_size(attributes.min_dimensions.map(Into::into));
frame.set_max_size(attributes.max_dimensions.map(Into::into));
frame.set_min_size(attributes.min_inner_size.map(Into::into));
frame.set_max_size(attributes.max_inner_size.map(Into::into));
let kill_switch = Arc::new(Mutex::new(false));
let need_frame_refresh = Arc::new(Mutex::new(true));
@ -154,35 +155,27 @@ impl Window {
self.frame.lock().unwrap().set_title(title.into());
}
#[inline]
pub fn show(&self) {
pub fn set_visible(&self, _visible: bool) {
// TODO
}
#[inline]
pub fn hide(&self) {
// TODO
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
Err(NotSupportedError::new())
}
#[inline]
pub fn get_position(&self) -> Option<LogicalPosition> {
// Not possible with wayland
None
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
Err(NotSupportedError::new())
}
#[inline]
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
// Not possible with wayland
None
}
#[inline]
pub fn set_position(&self, _pos: LogicalPosition) {
pub fn set_outer_position(&self, _pos: LogicalPosition) {
// Not possible with wayland
}
pub fn get_inner_size(&self) -> Option<LogicalSize> {
Some(self.size.lock().unwrap().clone().into())
pub fn inner_size(&self) -> LogicalSize {
self.size.lock().unwrap().clone().into()
}
pub fn request_redraw(&self) {
@ -190,10 +183,10 @@ impl Window {
}
#[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) = super::wayland_window::add_borders(w as i32, h as i32);
Some((w, h).into())
(w, h).into()
}
#[inline]
@ -205,12 +198,12 @@ impl Window {
}
#[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));
}
#[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));
}
@ -237,9 +230,9 @@ impl Window {
}
}
pub fn get_fullscreen(&self) -> Option<MonitorHandle> {
pub fn fullscreen(&self) -> Option<MonitorHandle> {
if *(self.fullscreen.lock().unwrap()) {
Some(self.get_current_monitor())
Some(self.current_monitor())
} else {
None
}
@ -265,34 +258,34 @@ impl Window {
}
#[inline]
pub fn set_cursor(&self, _cursor: MouseCursor) {
pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
// TODO
}
#[inline]
pub fn hide_cursor(&self, _hide: bool) {
pub fn set_cursor_visible(&self, _visible: bool) {
// TODO: This isn't possible on Wayland yet
}
#[inline]
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> {
Err("Cursor grabbing is not yet possible on Wayland.".to_owned())
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
Err(ExternalError::NotSupported(NotSupportedError::new()))
}
#[inline]
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), String> {
Err("Setting the cursor position is not yet possible on Wayland.".to_owned())
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), ExternalError> {
Err(ExternalError::NotSupported(NotSupportedError::new()))
}
pub fn get_display(&self) -> &Display {
pub fn display(&self) -> &Display {
&*self.display
}
pub fn get_surface(&self) -> &wl_surface::WlSurface {
pub fn surface(&self) -> &wl_surface::WlSurface {
&self.surface
}
pub fn get_current_monitor(&self) -> MonitorHandle {
pub fn current_monitor(&self) -> MonitorHandle {
let output = get_outputs(&self.surface).last().unwrap().clone();
MonitorHandle {
proxy: output,
@ -300,12 +293,12 @@ impl Window {
}
}
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors(&self.outputs)
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
available_monitors(&self.outputs)
}
pub fn get_primary_monitor(&self) -> MonitorHandle {
get_primary_monitor(&self.outputs)
pub fn primary_monitor(&self) -> MonitorHandle {
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_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 resized, moved) = {
@ -534,10 +534,7 @@ impl<T: 'static> EventProcessor<T> {
let device_id = mkdid(xev.deviceid);
if (xev.flags & ffi::XIPointerEmulated) != 0 {
// Deliver multi-touch events instead of emulated mouse events.
let return_now = self
.with_window(xev.event, |window| window.multitouch)
.unwrap_or(true);
if return_now { return; }
return;
}
let modifiers = ModifiersState::from(xev.mods);
@ -622,7 +619,7 @@ impl<T: 'static> EventProcessor<T> {
});
if cursor_moved == Some(true) {
let dpi_factor = self.with_window(xev.event, |window| {
window.get_hidpi_factor()
window.hidpi_factor()
});
if let Some(dpi_factor) = dpi_factor {
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| {
window.get_hidpi_factor()
window.hidpi_factor()
}) {
let position = LogicalPosition::from_physical(
(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 dpi_factor = match self.with_window(xev.event, |window| {
window.get_hidpi_factor()
window.hidpi_factor()
}) {
Some(dpi_factor) => dpi_factor,
None => return,
@ -825,7 +822,7 @@ impl<T: 'static> EventProcessor<T> {
_ => unreachable!()
};
let dpi_factor = self.with_window(xev.event, |window| {
window.get_hidpi_factor()
window.hidpi_factor()
});
if let Some(dpi_factor) = dpi_factor {
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.
let prev_list = monitor::invalidate_cached_monitor_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 {
prev_list
.iter()
@ -970,7 +967,7 @@ impl<T: 'static> EventProcessor<T> {
for (window_id, window) in wt.windows.borrow().iter() {
if let Some(window) = window.upgrade() {
// 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 {
callback(Event::WindowEvent {
window_id: mkwid(window_id.0),
@ -978,10 +975,7 @@ impl<T: 'static> EventProcessor<T> {
new_monitor.hidpi_factor
),
});
let (width, height) = match window.get_inner_size_physical() {
Some(result) => result,
None => continue,
};
let (width, height) = window.inner_size_physical();
let (_, _, flusher) = window.adjust_for_dpi(
prev_monitor.hidpi_factor,
new_monitor.hidpi_factor,
@ -1007,4 +1001,4 @@ impl<T: 'static> EventProcessor<T> {
Err(_) => (),
}
}
}
}

View file

@ -12,8 +12,9 @@ use super::{ffi, util, XConnection, XError};
use self::inner::{close_im, ImeInner};
use self::input_method::PotentialInputMethods;
use self::context::{ImeContextCreationError, ImeContext};
use self::context::ImeContext;
use self::callbacks::*;
pub use self::context::ImeContextCreationError;
pub type ImeReceiver = Receiver<(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 error::OsError as RootOsError;
use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW};
use event::{WindowEvent, Event};
use platform_impl::PlatformSpecificWindowBuilderAttributes;
use platform_impl::platform::sticky_exit_callback;
use window::{CreationError, WindowAttributes};
use window::{WindowAttributes};
use self::dnd::{Dnd, DndState};
use self::ime::{ImeReceiver, ImeSender, ImeCreationError, Ime};
use self::event_processor::EventProcessor;
@ -427,7 +428,7 @@ impl Window {
event_loop: &EventLoopWindowTarget<T>,
attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes
) -> Result<Self, CreationError> {
) -> Result<Self, RootOsError> {
let window = Arc::new(UnownedWindow::new(&event_loop, attribs, pl_attribs)?);
event_loop.windows
.borrow_mut()

View file

@ -67,7 +67,7 @@ impl MonitorHandle {
primary: bool,
) -> Option<Self> {
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);
Some(MonitorHandle {
id,
@ -80,32 +80,32 @@ impl MonitorHandle {
})
}
pub fn get_name(&self) -> Option<String> {
pub fn name(&self) -> Option<String> {
Some(self.name.clone())
}
#[inline]
pub fn get_native_identifier(&self) -> u32 {
pub fn native_identifier(&self) -> u32 {
self.id as u32
}
pub fn get_dimensions(&self) -> PhysicalSize {
pub fn dimensions(&self) -> PhysicalSize {
self.dimensions.into()
}
pub fn get_position(&self) -> PhysicalPosition {
pub fn position(&self) -> PhysicalPosition {
self.position.into()
}
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
pub fn hidpi_factor(&self) -> f64 {
self.hidpi_factor
}
}
impl XConnection {
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
.get(0)
.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();
(*monitors_lock)
.as_ref()
@ -222,8 +222,8 @@ impl XConnection {
}
#[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle {
self.get_available_monitors()
pub fn primary_monitor(&self) -> MonitorHandle {
self.available_monitors()
.into_iter()
.find(|monitor| monitor.primary)
.expect("[winit] Failed to find any monitors using XRandR.")

View file

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

View file

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

View file

@ -13,10 +13,11 @@ mod view;
mod window;
mod window_delegate;
use std::{ops::Deref, sync::Arc};
use std::{fmt, ops::Deref, sync::Arc};
use {
event::DeviceId as RootDeviceId, window::{CreationError, WindowAttributes},
event::DeviceId as RootDeviceId, window::WindowAttributes,
error::OsError as RootOsError,
};
pub use self::{
event_loop::{EventLoop, EventLoopWindowTarget, Proxy as EventLoopProxy},
@ -44,6 +45,12 @@ pub struct Window {
_delegate: util::IdRef,
}
#[derive(Debug)]
pub enum OsError {
CGError(core_graphics::base::CGError),
CreationError(&'static str)
}
unsafe impl Send for Window {}
unsafe impl Sync for Window {}
@ -60,8 +67,17 @@ impl Window {
_window_target: &EventLoopWindowTarget<T>,
attributes: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<Self, CreationError> {
) -> Result<Self, RootOsError> {
let (window, _delegate) = UnownedWindow::new(attributes, pl_attribs)?;
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)]
pub struct MonitorHandle(CGDirectDisplayID);
pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
pub fn available_monitors() -> VecDeque<MonitorHandle> {
if let Ok(displays) = CGDisplay::active_displays() {
let mut monitors = VecDeque::with_capacity(displays.len());
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)
}
@ -38,11 +38,11 @@ impl fmt::Debug for MonitorHandle {
}
let monitor_id_proxy = MonitorHandle {
name: self.get_name(),
native_identifier: self.get_native_identifier(),
dimensions: self.get_dimensions(),
position: self.get_position(),
hidpi_factor: self.get_hidpi_factor(),
name: self.name(),
native_identifier: self.native_identifier(),
dimensions: self.dimensions(),
position: self.position(),
hidpi_factor: self.hidpi_factor(),
};
monitor_id_proxy.fmt(f)
@ -54,48 +54,48 @@ impl MonitorHandle {
MonitorHandle(id)
}
pub fn get_name(&self) -> Option<String> {
pub fn name(&self) -> Option<String> {
let MonitorHandle(display_id) = *self;
let screen_num = CGDisplay::new(display_id).model_number();
Some(format!("Monitor #{}", screen_num))
}
#[inline]
pub fn get_native_identifier(&self) -> u32 {
pub fn native_identifier(&self) -> u32 {
self.0
}
pub fn get_dimensions(&self) -> PhysicalSize {
pub fn dimensions(&self) -> PhysicalSize {
let MonitorHandle(display_id) = *self;
let display = CGDisplay::new(display_id);
let height = display.pixels_high();
let width = display.pixels_wide();
PhysicalSize::from_logical(
(width as f64, height as f64),
self.get_hidpi_factor(),
self.hidpi_factor(),
)
}
#[inline]
pub fn get_position(&self) -> PhysicalPosition {
let bounds = unsafe { CGDisplayBounds(self.get_native_identifier()) };
pub fn position(&self) -> PhysicalPosition {
let bounds = unsafe { CGDisplayBounds(self.native_identifier()) };
PhysicalPosition::from_logical(
(bounds.origin.x as f64, bounds.origin.y as f64),
self.get_hidpi_factor(),
self.hidpi_factor(),
)
}
pub fn get_hidpi_factor(&self) -> f64 {
let screen = match self.get_nsscreen() {
pub fn hidpi_factor(&self) -> f64 {
let screen = match self.nsscreen() {
Some(screen) => screen,
None => return 1.0, // default to 1.0 when we can't find the screen
};
unsafe { NSScreen::backingScaleFactor(screen) as f64 }
}
pub(crate) fn get_nsscreen(&self) -> Option<id> {
pub(crate) fn nsscreen(&self) -> Option<id> {
unsafe {
let native_id = self.get_native_identifier();
let native_id = self.native_identifier();
let screens = NSScreen::screens(nil);
let count: NSUInteger = msg_send![screens, count];
let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber"));

View file

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

View file

@ -17,13 +17,15 @@ use objc::{runtime::{Class, Object, Sel, BOOL, YES, NO}, declare::ClassDecl};
use {
dpi::{LogicalPosition, LogicalSize}, icon::Icon,
error::{ExternalError, NotSupportedError, OsError as RootOsError},
monitor::MonitorHandle as RootMonitorHandle,
window::{
CreationError, MouseCursor, WindowAttributes, WindowId as RootWindowId,
CursorIcon, WindowAttributes, WindowId as RootWindowId,
},
};
use platform::macos::{ActivationPolicy, WindowExtMacOS};
use platform_impl::platform::{
OsError,
app_state::AppState, ffi, monitor::{self, MonitorHandle},
util::{self, IdRef}, view::{self, new_view},
window_delegate::new_delegate,
@ -102,7 +104,7 @@ fn create_window(
let pool = NSAutoreleasePool::new(nil);
let screen = match attrs.fullscreen {
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)))
},
_ => None,
@ -110,7 +112,7 @@ fn create_window(
let frame = match screen {
Some(screen) => appkit::NSScreen::frame(screen),
None => {
let (width, height) = attrs.dimensions
let (width, height) = attrs.inner_size
.map(|logical| (logical.width, logical.height))
.unwrap_or_else(|| (800.0, 600.0));
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>>,
decorations: AtomicBool,
cursor: Weak<Mutex<util::Cursor>>,
cursor_hidden: AtomicBool,
cursor_visible: AtomicBool,
}
unsafe impl Send for UnownedWindow {}
@ -255,7 +257,7 @@ impl UnownedWindow {
pub fn new(
mut win_attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<(Arc<Self>, IdRef), CreationError> {
) -> Result<(Arc<Self>, IdRef), RootOsError> {
unsafe {
if !msg_send![class!(NSThread), isMainThread] {
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(|| {
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(|| {
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(|| {
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) };
@ -289,8 +291,8 @@ impl UnownedWindow {
nsapp.activateIgnoringOtherApps_(YES);
win_attribs.min_dimensions.map(|dim| set_min_dimensions(*nswindow, dim));
win_attribs.max_dimensions.map(|dim| set_max_dimensions(*nswindow, dim));
win_attribs.min_inner_size.map(|dim| set_min_inner_size(*nswindow, dim));
win_attribs.max_inner_size.map(|dim| set_max_inner_size(*nswindow, dim));
use cocoa::foundation::NSArray;
// register for drag and drop operations.
@ -317,14 +319,14 @@ impl UnownedWindow {
shared_state: Arc::new(Mutex::new(win_attribs.into())),
decorations: AtomicBool::new(decorations),
cursor,
cursor_hidden: Default::default(),
cursor_visible: AtomicBool::new(true),
});
let delegate = new_delegate(&window, fullscreen.is_some());
// Set fullscreen mode after we setup everything
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
// warp the window... while we could use
// `enterFullScreenMode`, they're idiomatically different
@ -381,42 +383,39 @@ impl UnownedWindow {
}
}
#[inline]
pub fn show(&self) {
unsafe { util::make_key_and_order_front_async(*self.nswindow) };
}
#[inline]
pub fn hide(&self) {
unsafe { util::order_out_async(*self.nswindow) };
pub fn set_visible(&self, visible: bool) {
match visible {
true => unsafe { util::make_key_and_order_front_async(*self.nswindow) },
false => unsafe { util::order_out_async(*self.nswindow) },
}
}
pub fn request_redraw(&self) {
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) };
Some((
Ok((
frame_rect.origin.x as f64,
util::bottom_left_to_top_left(frame_rect),
).into())
}
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
let content_rect = unsafe {
NSWindow::contentRectForFrameRect_(
*self.nswindow,
NSWindow::frame(*self.nswindow),
)
};
Some((
Ok((
content_rect.origin.x as f64,
util::bottom_left_to_top_left(content_rect),
).into())
}
pub fn set_position(&self, position: LogicalPosition) {
pub fn set_outer_position(&self, position: LogicalPosition) {
let dummy = NSRect::new(
NSPoint::new(
position.x,
@ -432,15 +431,15 @@ impl UnownedWindow {
}
#[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> {
pub fn inner_size(&self) -> LogicalSize {
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]
pub fn get_outer_size(&self) -> Option<LogicalSize> {
pub fn outer_size(&self) -> LogicalSize {
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]
@ -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 {
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 {
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.
}
pub fn set_cursor(&self, cursor: MouseCursor) {
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
let cursor = util::Cursor::from(cursor);
if let Some(cursor_access) = self.cursor.upgrade() {
*cursor_access.lock().unwrap() = cursor;
@ -497,44 +496,43 @@ impl UnownedWindow {
}
#[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
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]
pub fn hide_cursor(&self, hide: bool) {
pub fn set_cursor_visible(&self, visible: bool) {
let cursor_class = class!(NSCursor);
// 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!)
if hide != self.cursor_hidden.load(Ordering::Acquire) {
if hide {
let _: () = unsafe { msg_send![cursor_class, hide] };
} else {
if visible != self.cursor_visible.load(Ordering::Acquire) {
if visible {
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]
pub fn get_hidpi_factor(&self) -> f64 {
pub fn hidpi_factor(&self) -> f64 {
unsafe { NSWindow::backingScaleFactor(*self.nswindow) as _ }
}
#[inline]
pub fn set_cursor_position(&self, cursor_position: LogicalPosition) -> Result<(), String> {
let window_position = self.get_inner_position()
.ok_or("`get_inner_position` failed".to_owned())?;
pub fn set_cursor_position(&self, cursor_position: LogicalPosition) -> Result<(), ExternalError> {
let window_position = self.inner_position().unwrap();
let point = appkit::CGPoint {
x: (cursor_position.x + window_position.x) as CGFloat,
y: (cursor_position.y + window_position.y) as CGFloat,
};
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)
.map_err(|e| format!("`CGAssociateMouseAndMouseCursorPosition` failed: {:?}", e))?;
.map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?;
Ok(())
}
@ -637,7 +635,7 @@ impl UnownedWindow {
}
#[inline]
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
let shared_state_lock = self.shared_state.lock().unwrap();
shared_state_lock.fullscreen.clone()
}
@ -736,9 +734,9 @@ impl UnownedWindow {
}
#[inline]
pub fn set_ime_spot(&self, logical_spot: LogicalPosition) {
pub fn set_ime_position(&self, logical_spot: LogicalPosition) {
unsafe {
view::set_ime_spot(
view::set_ime_position(
*self.nsview,
*self.input_context,
logical_spot.x,
@ -748,7 +746,7 @@ impl UnownedWindow {
}
#[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle {
pub fn current_monitor(&self) -> RootMonitorHandle {
unsafe {
let screen: id = msg_send![*self.nswindow, screen];
let desc = NSScreen::deviceDescription(screen);
@ -760,24 +758,24 @@ impl UnownedWindow {
}
#[inline]
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
monitor::get_available_monitors()
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
monitor::available_monitors()
}
#[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle {
monitor::get_primary_monitor()
pub fn primary_monitor(&self) -> MonitorHandle {
monitor::primary_monitor()
}
}
impl WindowExtMacOS for UnownedWindow {
#[inline]
fn get_nswindow(&self) -> *mut c_void {
fn nswindow(&self) -> *mut c_void {
*self.nswindow as *mut _
}
#[inline]
fn get_nsview(&self) -> *mut c_void {
fn nsview(&self) -> *mut c_void {
*self.nsview as *mut _
}
@ -792,7 +790,7 @@ impl WindowExtMacOS for UnownedWindow {
}
#[inline]
fn get_simple_fullscreen(&self) -> bool {
fn simple_fullscreen(&self) -> bool {
let shared_state_lock = self.shared_state.lock().unwrap();
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 content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
// 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 content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
// Convert from client area size to window size

View file

@ -37,7 +37,7 @@ impl WindowDelegateState {
window: &Arc<UnownedWindow>,
initial_fullscreen: bool,
) -> Self {
let dpi_factor = window.get_hidpi_factor();
let dpi_factor = window.hidpi_factor();
let mut delegate_state = WindowDelegateState {
nswindow: window.nswindow.clone(),
@ -408,7 +408,7 @@ extern fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
trace!("Triggered `windowDidEnterFullscreen:`");
with_state(this, |state| {
state.with_window(|window| {
let monitor = window.get_current_monitor();
let monitor = window.current_monitor();
trace!("Locked shared state in `window_did_enter_fullscreen`");
window.shared_state.lock().unwrap().fullscreen = Some(monitor);
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
}
pub unsafe fn get_hwnd_dpi(hwnd: HWND) -> u32 {
pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 {
let hdc = winuser::GetDC(hwnd);
if hdc.is_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 {
dpi_to_scale_factor(unsafe { get_hwnd_dpi(hwnd) })
pub fn hwnd_scale_factor(hwnd: HWND) -> f64 {
dpi_to_scale_factor(unsafe { hwnd_dpi(hwnd) })
}

View file

@ -52,7 +52,7 @@ use platform_impl::platform::dpi::{
become_dpi_aware,
dpi_to_scale_factor,
enable_non_client_dpi_scaling,
get_hwnd_scale_factor,
hwnd_scale_factor,
};
use platform_impl::platform::drop_handler::FileDropHandler;
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;
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(
((*windowpos).x, (*windowpos).y),
dpi_factor,
@ -889,7 +889,7 @@ unsafe extern "system" fn public_window_callback<T>(
let w = LOWORD(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 event = Event::WindowEvent {
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 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);
subclass_input.send_event(Event::WindowEvent {
@ -1305,7 +1305,7 @@ unsafe extern "system" fn public_window_callback<T>(
inputs.as_mut_ptr(),
mem::size_of::<winuser::TOUCHINPUT>() as INT,
) > 0 {
let dpi_factor = get_hwnd_scale_factor(window);
let dpi_factor = hwnd_scale_factor(window);
for input in &inputs {
let x = (input.x 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::path::Path;
@ -8,7 +8,6 @@ use winapi::shared::windef::{HICON, HWND};
use winapi::um::winuser;
use icon::{Pixel, PIXEL_SIZE, Icon};
use platform_impl::platform::util;
impl Pixel {
fn to_bgra(&mut self) {
@ -31,7 +30,7 @@ unsafe impl Send for WinIcon {}
impl WinIcon {
#[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 handle = unsafe {
winuser::LoadImageW(
@ -46,15 +45,15 @@ impl WinIcon {
if !handle.is_null() {
Ok(WinIcon { handle })
} 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)
}
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);
let pixel_count = rgba.len() / PIXEL_SIZE;
assert_eq!(pixel_count, (width * height) as usize);
@ -80,7 +79,7 @@ impl WinIcon {
if !handle.is_null() {
Ok(WinIcon { handle })
} else {
Err(util::WinError::from_last_error())
Err(io::Error::last_os_error())
}
}

View file

@ -36,7 +36,7 @@ impl DeviceId {
}
impl DeviceId {
pub fn get_persistent_identifier(&self) -> Option<String> {
pub fn persistent_identifier(&self) -> Option<String> {
if self.0 != 0 {
raw_input::get_raw_input_device_name(self.0 as _)
} else {
@ -52,6 +52,8 @@ fn wrap_device_id(id: u32) -> RootDeviceId {
RootDeviceId(DeviceId(id))
}
pub type OsError = std::io::Error;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WindowId(HWND);
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::winuser;
use std::{mem, ptr};
use std::{mem, ptr, io};
use std::collections::VecDeque;
use super::{EventLoop, util};
@ -50,7 +50,7 @@ unsafe extern "system" fn monitor_enum_proc(
TRUE // continue enumeration
}
pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
pub fn available_monitors() -> VecDeque<MonitorHandle> {
let mut monitors: VecDeque<MonitorHandle> = VecDeque::new();
unsafe {
winuser::EnumDisplayMonitors(
@ -63,7 +63,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
monitors
}
pub fn get_primary_monitor() -> MonitorHandle {
pub fn primary_monitor() -> MonitorHandle {
const ORIGIN: POINT = POINT { x: 0, y: 0 };
let hmonitor = unsafe {
winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY)
@ -71,7 +71,7 @@ pub fn get_primary_monitor() -> MonitorHandle {
MonitorHandle::from_hmonitor(hmonitor)
}
pub fn get_current_monitor(hwnd: HWND) -> MonitorHandle {
pub fn current_monitor(hwnd: HWND) -> MonitorHandle {
let hmonitor = unsafe {
winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST)
};
@ -80,26 +80,26 @@ pub fn get_current_monitor(hwnd: HWND) -> MonitorHandle {
impl<T> EventLoop<T> {
// TODO: Investigate opportunities for caching
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors()
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
available_monitors()
}
pub fn get_primary_monitor(&self) -> MonitorHandle {
get_primary_monitor()
pub fn primary_monitor(&self) -> MonitorHandle {
primary_monitor()
}
}
impl Window {
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors()
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
available_monitors()
}
pub fn get_primary_monitor(&self) -> MonitorHandle {
get_primary_monitor()
pub fn primary_monitor(&self) -> MonitorHandle {
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() };
monitor_info.cbSize = mem::size_of::<winuser::MONITORINFOEXW>() as DWORD;
let status = unsafe {
@ -109,7 +109,7 @@ pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINF
)
};
if status == 0 {
Err(util::WinError::from_last_error())
Err(io::Error::last_os_error())
} else {
Ok(monitor_info)
}
@ -142,32 +142,32 @@ impl MonitorHandle {
}
#[inline]
pub fn get_name(&self) -> Option<String> {
pub fn name(&self) -> Option<String> {
Some(self.monitor_name.clone())
}
#[inline]
pub fn get_native_identifier(&self) -> String {
pub fn native_identifier(&self) -> String {
self.monitor_name.clone()
}
#[inline]
pub fn get_hmonitor(&self) -> HMONITOR {
pub fn hmonitor(&self) -> HMONITOR {
self.hmonitor.0
}
#[inline]
pub fn get_dimensions(&self) -> PhysicalSize {
pub fn dimensions(&self) -> PhysicalSize {
self.dimensions.into()
}
#[inline]
pub fn get_position(&self) -> PhysicalPosition {
pub fn position(&self) -> PhysicalPosition {
self.position.into()
}
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
pub fn hidpi_factor(&self) -> f64 {
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::sync::atomic::{AtomicBool, Ordering};
use window::MouseCursor;
use window::CursorIcon;
use winapi::ctypes::wchar_t;
use winapi::shared::minwindef::{BOOL, DWORD};
use winapi::shared::windef::{HWND, POINT, RECT};
use winapi::um::errhandlingapi::GetLastError;
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::winbase::lstrlenW;
use winapi::um::winuser;
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() }
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
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 {
impl CursorIcon {
pub(crate) fn to_windows_cursor(self) -> *const wchar_t {
match self {
MouseCursor::Arrow | MouseCursor::Default => winuser::IDC_ARROW,
MouseCursor::Hand => winuser::IDC_HAND,
MouseCursor::Crosshair => winuser::IDC_CROSS,
MouseCursor::Text | MouseCursor::VerticalText => winuser::IDC_IBEAM,
MouseCursor::NotAllowed | MouseCursor::NoDrop => winuser::IDC_NO,
MouseCursor::Grab | MouseCursor::Grabbing |
MouseCursor::Move | MouseCursor::AllScroll => winuser::IDC_SIZEALL,
MouseCursor::EResize | MouseCursor::WResize |
MouseCursor::EwResize | MouseCursor::ColResize => winuser::IDC_SIZEWE,
MouseCursor::NResize | MouseCursor::SResize |
MouseCursor::NsResize | MouseCursor::RowResize => winuser::IDC_SIZENS,
MouseCursor::NeResize | MouseCursor::SwResize |
MouseCursor::NeswResize => winuser::IDC_SIZENESW,
MouseCursor::NwResize | MouseCursor::SeResize |
MouseCursor::NwseResize => winuser::IDC_SIZENWSE,
MouseCursor::Wait => winuser::IDC_WAIT,
MouseCursor::Progress => winuser::IDC_APPSTARTING,
MouseCursor::Help => winuser::IDC_HELP,
CursorIcon::Arrow | CursorIcon::Default => winuser::IDC_ARROW,
CursorIcon::Hand => winuser::IDC_HAND,
CursorIcon::Crosshair => winuser::IDC_CROSS,
CursorIcon::Text | CursorIcon::VerticalText => winuser::IDC_IBEAM,
CursorIcon::NotAllowed | CursorIcon::NoDrop => winuser::IDC_NO,
CursorIcon::Grab | CursorIcon::Grabbing |
CursorIcon::Move | CursorIcon::AllScroll => winuser::IDC_SIZEALL,
CursorIcon::EResize | CursorIcon::WResize |
CursorIcon::EwResize | CursorIcon::ColResize => winuser::IDC_SIZEWE,
CursorIcon::NResize | CursorIcon::SResize |
CursorIcon::NsResize | CursorIcon::RowResize => winuser::IDC_SIZENS,
CursorIcon::NeResize | CursorIcon::SwResize |
CursorIcon::NeswResize => winuser::IDC_SIZENESW,
CursorIcon::NwResize | CursorIcon::SeResize |
CursorIcon::NwseResize => winuser::IDC_SIZENWSE,
CursorIcon::Wait => winuser::IDC_WAIT,
CursorIcon::Progress => winuser::IDC_APPSTARTING,
CursorIcon::Help => winuser::IDC_HELP,
_ => 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::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 monitor::MonitorHandle as RootMonitorHandle;
use platform_impl::platform::{
{PlatformSpecificWindowBuilderAttributes, WindowId},
dpi::{dpi_to_scale_factor, get_hwnd_dpi},
dpi::{dpi_to_scale_factor, hwnd_dpi},
drop_handler::FileDropHandler,
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID},
icon::{self, IconType, WinIcon},
@ -50,7 +51,7 @@ impl Window {
event_loop: &EventLoopWindowTarget<T>,
w_attr: WindowAttributes,
pl_attr: PlatformSpecificWindowBuilderAttributes,
) -> Result<Window, CreationError> {
) -> Result<Window, RootOsError> {
// We dispatch an `init` function because of code style.
// First person to remove the need for cloning here gets a cookie!
//
@ -103,16 +104,10 @@ impl Window {
}
#[inline]
pub fn show(&self) {
unsafe {
winuser::ShowWindow(self.window.0, winuser::SW_SHOW);
}
}
#[inline]
pub fn hide(&self) {
unsafe {
winuser::ShowWindow(self.window.0, winuser::SW_HIDE);
pub fn set_visible(&self, visible: bool) {
match visible {
true => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_SHOW); },
false => 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)
.map(|rect| (rect.left as i32, rect.top as i32))
.unwrap()
}
#[inline]
pub fn get_position(&self) -> Option<LogicalPosition> {
self.get_position_physical()
.map(|physical_position| {
let dpi_factor = self.get_hidpi_factor();
LogicalPosition::from_physical(physical_position, dpi_factor)
})
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
let physical_position = self.outer_position_physical();
let dpi_factor = self.hidpi_factor();
Ok(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() };
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]
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
self.get_inner_position_physical()
.map(|physical_position| {
let dpi_factor = self.get_hidpi_factor();
LogicalPosition::from_physical(physical_position, dpi_factor)
})
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
let physical_position = self.inner_position_physical();
let dpi_factor = self.hidpi_factor();
Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
}
pub(crate) fn set_position_physical(&self, x: i32, y: i32) {
@ -179,47 +171,44 @@ impl Window {
}
#[inline]
pub fn set_position(&self, logical_position: LogicalPosition) {
let dpi_factor = self.get_hidpi_factor();
pub fn set_outer_position(&self, logical_position: LogicalPosition) {
let dpi_factor = self.hidpi_factor();
let (x, y) = logical_position.to_physical(dpi_factor).into();
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() };
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.bottom - rect.top) as u32,
))
)
}
#[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> {
self.get_inner_size_physical()
.map(|physical_size| {
let dpi_factor = self.get_hidpi_factor();
LogicalSize::from_physical(physical_size, dpi_factor)
})
pub fn inner_size(&self) -> LogicalSize {
let physical_size = self.inner_size_physical();
let dpi_factor = self.hidpi_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)
.map(|rect| (
(rect.right - rect.left) as u32,
(rect.bottom - rect.top) as u32,
))
.unwrap()
}
#[inline]
pub fn get_outer_size(&self) -> Option<LogicalSize> {
self.get_outer_size_physical()
.map(|physical_size| {
let dpi_factor = self.get_hidpi_factor();
LogicalSize::from_physical(physical_size, dpi_factor)
})
pub fn outer_size(&self) -> LogicalSize {
let physical_size = self.outer_size_physical();
let dpi_factor = self.hidpi_factor();
LogicalSize::from_physical(physical_size, dpi_factor)
}
pub(crate) fn set_inner_size_physical(&self, x: u32, y: u32) {
@ -254,41 +243,41 @@ impl Window {
#[inline]
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();
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);
// Make windows re-check the window size bounds.
self.get_inner_size_physical()
.map(|(width, height)| self.set_inner_size_physical(width, height));
let (width, height) = self.inner_size_physical();
self.set_inner_size_physical(width, height);
}
#[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 dpi_factor = self.get_hidpi_factor();
let dpi_factor = self.hidpi_factor();
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);
// Make windows re-check the window size bounds.
self.get_inner_size_physical()
.map(|(width, height)| self.set_inner_size_physical(width, height));
let (width, height) = self.inner_size_physical();
self.set_inner_size_physical(width, height);
}
#[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 dpi_factor = self.get_hidpi_factor();
let dpi_factor = self.hidpi_factor();
logical_size.to_physical(dpi_factor).into()
});
self.set_max_dimensions_physical(physical_size);
self.set_max_inner_size_physical(physical_size);
}
#[inline]
@ -313,7 +302,7 @@ impl Window {
}
#[inline]
pub fn set_cursor(&self, cursor: MouseCursor) {
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
self.window_state.lock().mouse.cursor = cursor;
self.thread_executor.execute_in_thread(move || unsafe {
let cursor = winuser::LoadCursorW(
@ -325,7 +314,7 @@ impl Window {
}
#[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_state = Arc::clone(&self.window_state);
let (tx, rx) = channel();
@ -333,21 +322,21 @@ impl Window {
self.thread_executor.execute_in_thread(move || {
let result = window_state.lock().mouse
.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);
});
rx.recv().unwrap()
}
#[inline]
pub fn hide_cursor(&self, hide: bool) {
pub fn set_cursor_visible(&self, visible: bool) {
let window = self.window.clone();
let window_state = Arc::clone(&self.window_state);
let (tx, rx) = channel();
self.thread_executor.execute_in_thread(move || {
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());
let _ = tx.send(result);
});
@ -355,26 +344,26 @@ impl Window {
}
#[inline]
pub fn get_hidpi_factor(&self) -> f64 {
pub fn hidpi_factor(&self) -> f64 {
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 };
unsafe {
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 {
return Err("`SetCursorPos` failed".to_owned());
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
}
}
Ok(())
}
#[inline]
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), String> {
let dpi_factor = self.get_hidpi_factor();
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), ExternalError> {
let dpi_factor = self.hidpi_factor();
let (x, y) = logical_position.to_physical(dpi_factor).into();
self.set_cursor_position_physical(x, y)
}
@ -400,7 +389,7 @@ impl Window {
}
#[inline]
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
let window_state = self.window_state.lock();
window_state.fullscreen.clone()
}
@ -413,8 +402,8 @@ impl Window {
match &monitor {
&Some(RootMonitorHandle { ref inner }) => {
let (x, y): (i32, i32) = inner.get_position().into();
let (width, height): (u32, u32) = inner.get_dimensions().into();
let (x, y): (i32, i32) = inner.position().into();
let (width, height): (u32, u32) = inner.dimensions().into();
let mut monitor = monitor.clone();
self.thread_executor.execute_in_thread(move || {
@ -496,9 +485,9 @@ impl Window {
}
#[inline]
pub fn get_current_monitor(&self) -> RootMonitorHandle {
pub fn current_monitor(&self) -> RootMonitorHandle {
RootMonitorHandle {
inner: monitor::get_current_monitor(self.window.0),
inner: monitor::current_monitor(self.window.0),
}
}
@ -529,7 +518,7 @@ impl Window {
}
#[inline]
pub fn set_ime_spot(&self, _logical_spot: LogicalPosition) {
pub fn set_ime_position(&self, _logical_spot: LogicalPosition) {
unimplemented!();
}
}
@ -575,9 +564,9 @@ pub unsafe fn adjust_size(
unsafe fn init<T: 'static>(
mut attributes: WindowAttributes,
mut pl_attribs: PlatformSpecificWindowBuilderAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes,
event_loop: &EventLoopWindowTarget<T>,
) -> Result<Window, CreationError> {
) -> Result<Window, RootOsError> {
let title = OsStr::new(&attributes.title)
.encode_wide()
.chain(Some(0).into_iter())
@ -587,22 +576,18 @@ unsafe fn init<T: 'static>(
let icon = attributes.window_icon
.take()
.map(WinIcon::from_icon);
if icon.is_some() {
Some(icon.unwrap().map_err(|err| {
CreationError::OsError(format!("Failed to create `ICON_SMALL`: {:?}", err))
})?)
if let Some(icon) = icon {
Some(icon.map_err(|e| os_error!(e))?)
} else {
None
}
};
let taskbar_icon = {
let icon = pl_attribs.taskbar_icon
let icon = attributes.window_icon
.take()
.map(WinIcon::from_icon);
if icon.is_some() {
Some(icon.unwrap().map_err(|err| {
CreationError::OsError(format!("Failed to create `ICON_BIG`: {:?}", err))
})?)
if let Some(icon) = icon {
Some(icon.map_err(|e| os_error!(e))?)
} else {
None
}
@ -612,17 +597,17 @@ unsafe fn init<T: 'static>(
let class_name = register_window_class(&window_icon, &taskbar_icon);
let guessed_dpi_factor = {
let monitors = monitor::get_available_monitors();
let monitors = monitor::available_monitors();
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 {
if Some(monitor.get_hidpi_factor()) != dpi_factor {
if Some(monitor.hidpi_factor()) != dpi_factor {
dpi_factor = None;
}
}
dpi_factor
} 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(|| {
util::get_cursor_pos()
@ -630,7 +615,7 @@ unsafe fn init<T: 'static>(
let mut dpi_factor = None;
for monitor in &monitors {
if monitor.contains_point(&cursor_pos) {
dpi_factor = Some(monitor.get_hidpi_factor());
dpi_factor = Some(monitor.hidpi_factor());
break;
}
}
@ -641,7 +626,7 @@ unsafe fn init<T: 'static>(
};
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();
window_flags.set(WindowFlags::DECORATIONS, attributes.decorations);
@ -670,8 +655,7 @@ unsafe fn init<T: 'static>(
);
if handle.is_null() {
return Err(CreationError::OsError(format!("CreateWindowEx function failed: {}",
format!("{}", io::Error::last_os_error()))));
return Err(os_error!(io::Error::last_os_error()));
}
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);
if dpi_factor != guessed_dpi_factor {
let (width, height): (u32, u32) = dimensions.into();
@ -763,7 +747,7 @@ unsafe fn init<T: 'static>(
force_window_active(win.window.0);
}
if let Some(dimensions) = attributes.dimensions {
if let Some(dimensions) = attributes.inner_size {
win.set_inner_size(dimensions);
}

View file

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

View file

View file

@ -1,7 +1,8 @@
//! The `Window` struct and associated types.
use std::{fmt, error};
use std::fmt;
use platform_impl;
use error::{ExternalError, NotSupportedError, OsError};
use event_loop::EventLoopWindowTarget;
use monitor::{AvailableMonitorsIter, MonitorHandle};
use dpi::{LogicalPosition, LogicalSize};
@ -84,17 +85,17 @@ pub struct WindowAttributes {
/// used.
///
/// 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 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 default is `None`.
pub max_dimensions: Option<LogicalSize>,
pub max_inner_size: Option<LogicalSize>,
/// Whether the window is resizable or not.
///
@ -141,19 +142,15 @@ pub struct WindowAttributes {
///
/// The default is `None`.
pub window_icon: Option<Icon>,
/// [iOS only] Enable multitouch,
/// see [multipleTouchEnabled](https://developer.apple.com/documentation/uikit/uiview/1622519-multipletouchenabled)
pub multitouch: bool,
}
impl Default for WindowAttributes {
#[inline]
fn default() -> WindowAttributes {
WindowAttributes {
dimensions: None,
min_dimensions: None,
max_dimensions: None,
inner_size: None,
min_inner_size: None,
max_inner_size: None,
resizable: true,
title: "winit window".to_owned(),
maximized: false,
@ -163,7 +160,6 @@ impl Default for WindowAttributes {
decorations: true,
always_on_top: false,
window_icon: None,
multitouch: false,
}
}
}
@ -179,22 +175,22 @@ impl WindowBuilder {
/// Requests the window to be of specific dimensions.
#[inline]
pub fn with_dimensions(mut self, size: LogicalSize) -> WindowBuilder {
self.window.dimensions = Some(size);
pub fn with_inner_size(mut self, size: LogicalSize) -> WindowBuilder {
self.window.inner_size = Some(size);
self
}
/// Sets a minimum dimension size for the window
#[inline]
pub fn with_min_dimensions(mut self, min_size: LogicalSize) -> WindowBuilder {
self.window.min_dimensions = Some(min_size);
pub fn with_min_inner_size(mut self, min_size: LogicalSize) -> WindowBuilder {
self.window.min_inner_size = Some(min_size);
self
}
/// Sets a maximum dimension size for the window
#[inline]
pub fn with_max_dimensions(mut self, max_size: LogicalSize) -> WindowBuilder {
self.window.max_dimensions = Some(max_size);
pub fn with_max_inner_size(mut self, max_size: LogicalSize) -> WindowBuilder {
self.window.max_inner_size = Some(max_size);
self
}
@ -282,23 +278,16 @@ impl WindowBuilder {
self
}
/// Enables multitouch.
#[inline]
pub fn with_multitouch(mut self) -> WindowBuilder {
self.window.multitouch = true;
self
}
/// Builds the window.
///
/// Error should be very rare and only occur in case of permission denied, incompatible system,
/// out of memory, etc.
#[inline]
pub fn build<T: 'static>(mut self, window_target: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> {
self.window.dimensions = Some(self.window.dimensions.unwrap_or_else(|| {
pub fn build<T: 'static>(mut self, window_target: &EventLoopWindowTarget<T>) -> Result<Window, OsError> {
self.window.inner_size = Some(self.window.inner_size.unwrap_or_else(|| {
if let Some(ref monitor) = self.window.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 {
// default dimensions
(1024, 768).into()
@ -314,6 +303,7 @@ impl WindowBuilder {
}
}
/// Base Window functions.
impl Window {
/// 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,
/// out of memory, etc.
#[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();
builder.build(event_loop)
}
/// Modifies the title of the window.
///
/// This is a no-op if the window has already been closed.
///
/// ## Platform-specific
///
/// - Has no effect on iOS.
/// Returns an identifier unique to the window.
#[inline]
pub fn set_title(&self, title: &str) {
self.window.set_title(title)
pub fn id(&self) -> WindowId {
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
///
/// - **Android:** Has no effect.
/// - **iOS:** Can only be called on the main thread.
#[inline]
pub fn show(&self) {
self.window.show()
}
/// Hides the window if it was visible.
/// - **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`].
///
/// ## Platform-specific
///
/// - **Android:** Has no effect.
/// - **iOS:** Can only be called on the main thread.
/// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
#[inline]
pub fn hide(&self) {
self.window.hide()
pub fn hidpi_factor(&self) -> f64 {
self.window.hidpi_factor()
}
/// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
@ -376,9 +359,29 @@ impl Window {
/// ## Platform-specific
///
/// - **iOS:** Can only be called on the main thread.
#[inline]
pub fn request_redraw(&self) {
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
/// 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
/// of the visible screen region.
///
/// Returns `None` if the window no longer exists.
///
/// ## Platform-specific
///
/// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
/// window in the screen space coordinate system.
#[inline]
pub fn get_position(&self) -> Option<LogicalPosition> {
self.window.get_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()
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
self.window.outer_position()
}
/// 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.
///
@ -428,8 +413,8 @@ impl Window {
/// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the
/// window in the screen space coordinate system.
#[inline]
pub fn set_position(&self, position: LogicalPosition) {
self.window.set_position(position)
pub fn set_outer_position(&self, position: LogicalPosition) {
self.window.set_outer_position(position)
}
/// 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.
///
/// 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's
/// [safe area] in screen space coordinates.
///
///
/// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
#[inline]
pub fn get_inner_size(&self) -> Option<LogicalSize> {
self.window.get_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()
pub fn inner_size(&self) -> LogicalSize {
self.window.inner_size()
}
/// Modifies the inner size of the window.
///
/// See `get_inner_size` for more information about the values.
///
/// This is a no-op if the window has already been closed.
/// See `inner_size` for more information about the values.
///
/// ## Platform-specific
///
@ -482,14 +447,28 @@ impl Window {
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.
///
/// ## Platform-specific
///
/// - **iOS:** Has no effect.
#[inline]
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
self.window.set_min_dimensions(dimensions)
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
self.window.set_min_inner_size(dimensions)
}
/// Sets a maximum dimension size for the window.
@ -498,8 +477,33 @@ impl Window {
///
/// - **iOS:** Has no effect.
#[inline]
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
self.window.set_max_dimensions(dimensions)
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
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.
@ -521,80 +525,10 @@ impl Window {
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.
///
/// ## Platform-specific
///
///
/// - **iOS:** Has no effect.
#[inline]
pub fn set_maximized(&self, maximized: bool) {
@ -604,7 +538,7 @@ impl Window {
/// Sets the window to fullscreen or back.
///
/// ## Platform-specific
///
///
/// - **iOS:** Can only be called on the main thread.
#[inline]
pub fn set_fullscreen(&self, monitor: Option<MonitorHandle>) {
@ -614,20 +548,20 @@ impl Window {
/// Gets the window's current fullscreen state.
///
/// ## Platform-specific
///
///
/// - **iOS:** Can only be called on the main thread.
#[inline]
pub fn get_fullscreen(&self) -> Option<MonitorHandle> {
self.window.get_fullscreen()
pub fn fullscreen(&self) -> Option<MonitorHandle> {
self.window.fullscreen()
}
/// Turn window decorations on or off.
///
/// ## Platform-specific
///
///
/// - **iOS:** Can only be called on the main thread. Controls whether the status bar is hidden
/// via [`setPrefersStatusBarHidden`].
///
///
/// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc
#[inline]
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.
///
/// ## Platform-specific
///
///
/// - **iOS:** Has no effect.
#[inline]
pub fn set_always_on_top(&self, always_on_top: bool) {
@ -663,85 +597,105 @@ impl Window {
///
/// **iOS:** Has no effect.
#[inline]
pub fn set_ime_spot(&self, position: LogicalPosition) {
self.window.set_ime_spot(position)
pub fn set_ime_position(&self, position: LogicalPosition) {
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
///
/// ## Platform-specific
///
/// **iOS:** Can only be called on the main thread.
#[inline]
pub fn get_current_monitor(&self) -> MonitorHandle {
self.window.get_current_monitor()
pub fn current_monitor(&self) -> MonitorHandle {
self.window.current_monitor()
}
/// 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
///
/// **iOS:** Can only be called on the main thread.
#[inline]
pub fn get_available_monitors(&self) -> AvailableMonitorsIter {
let data = self.window.get_available_monitors();
pub fn available_monitors(&self) -> AvailableMonitorsIter {
let data = self.window.available_monitors();
AvailableMonitorsIter { data: data.into_iter() }
}
/// 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
///
/// **iOS:** Can only be called on the main thread.
#[inline]
pub fn get_primary_monitor(&self) -> MonitorHandle {
MonitorHandle { inner: self.window.get_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()
pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle { inner: self.window.primary_monitor() }
}
}
/// Describes the appearance of the mouse cursor.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum MouseCursor {
pub enum CursorIcon {
/// The platform-dependent default cursor.
Default,
/// A simple crosshair.
@ -795,8 +749,8 @@ pub enum MouseCursor {
RowResize,
}
impl Default for MouseCursor {
impl Default for CursorIcon {
fn default() -> Self {
MouseCursor::Default
CursorIcon::Default
}
}

View file

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