mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-23 02:16:33 +11:00
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:
parent
ae63fbdbbb
commit
0df436901a
53 changed files with 1249 additions and 1250 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
];
|
||||
|
|
|
@ -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),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
86
src/error.rs
Normal 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 {}
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,17 +23,17 @@ 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.
|
||||
///
|
||||
|
@ -48,18 +48,18 @@ pub trait WindowExtIOS {
|
|||
|
||||
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]
|
||||
|
@ -83,7 +83,7 @@ pub trait WindowBuilderExtIOS {
|
|||
/// 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`.
|
||||
|
@ -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 _
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
@ -114,23 +114,23 @@ 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,27 +73,27 @@ impl Inner {
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)>;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
};
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`");
|
||||
|
|
|
@ -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) })
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
568
src/window.rs
568
src/window.rs
|
@ -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,203 +312,15 @@ 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)
|
||||
}
|
||||
|
||||
/// Shows the window if it was hidden.
|
||||
///
|
||||
/// ## 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.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Android:** Has no effect.
|
||||
/// - **iOS:** Can only be called on the main thread.
|
||||
#[inline]
|
||||
pub fn hide(&self) {
|
||||
self.window.hide()
|
||||
}
|
||||
|
||||
/// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
|
||||
/// events have been processed by the event loop.
|
||||
///
|
||||
/// This is the **strongly encouraged** method of redrawing windows, as it can integrates with
|
||||
/// OS-requested redraws (e.g. when a window gets resized).
|
||||
///
|
||||
/// This function can cause `RedrawRequested` events to be emitted after `Event::EventsCleared`
|
||||
/// but before `Event::NewEvents` if called in the following circumstances:
|
||||
/// * While processing `EventsCleared`.
|
||||
/// * While processing a `RedrawRequested` event that was sent during `EventsCleared` or any
|
||||
/// directly subsequent `RedrawRequested` event.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS:** Can only be called on the main thread.
|
||||
pub fn request_redraw(&self) {
|
||||
self.window.request_redraw()
|
||||
}
|
||||
|
||||
/// Returns the position of the top-left hand corner of the window relative to the
|
||||
/// top-left hand corner of the desktop.
|
||||
///
|
||||
/// Note that the top-left hand corner of the desktop is not necessarily the same as
|
||||
/// the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
|
||||
/// of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
|
||||
///
|
||||
/// 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()
|
||||
}
|
||||
|
||||
/// Modifies the position of the window.
|
||||
///
|
||||
/// See `get_position` for more information about the coordinates.
|
||||
///
|
||||
/// This is a no-op if the window has already been closed.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **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)
|
||||
}
|
||||
|
||||
/// Returns the logical size of the window's client area.
|
||||
///
|
||||
/// The client area is the content of the window, excluding the title bar and borders.
|
||||
///
|
||||
/// 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()
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS:** Unimplemented. Currently this panics, as it's not clear what `set_inner_size`
|
||||
/// would mean for iOS.
|
||||
#[inline]
|
||||
pub fn set_inner_size(&self, size: LogicalSize) {
|
||||
self.window.set_inner_size(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)
|
||||
}
|
||||
|
||||
/// Sets a maximum dimension size for the window.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS:** Has no effect.
|
||||
#[inline]
|
||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
self.window.set_max_dimensions(dimensions)
|
||||
}
|
||||
|
||||
/// Sets whether the window is resizable or not.
|
||||
///
|
||||
/// Note that making the window unresizable doesn't exempt you from handling `Resized`, as that event can still be
|
||||
/// triggered by DPI scaling, entering fullscreen mode, etc.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// This only has an effect on desktop platforms.
|
||||
///
|
||||
/// Due to a bug in XFCE, this has no effect on Xfwm.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS:** Has no effect.
|
||||
#[inline]
|
||||
pub fn set_resizable(&self, resizable: bool) {
|
||||
self.window.set_resizable(resizable)
|
||||
pub fn id(&self) -> WindowId {
|
||||
WindowId(self.window.id())
|
||||
}
|
||||
|
||||
/// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa.
|
||||
|
@ -538,57 +340,189 @@ impl Window {
|
|||
///
|
||||
/// [`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()
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
self.window.hidpi_factor()
|
||||
}
|
||||
|
||||
/// Modifies the mouse cursor of the window.
|
||||
/// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
|
||||
/// events have been processed by the event loop.
|
||||
///
|
||||
/// This is the **strongly encouraged** method of redrawing windows, as it can integrates with
|
||||
/// OS-requested redraws (e.g. when a window gets resized).
|
||||
///
|
||||
/// This function can cause `RedrawRequested` events to be emitted after `Event::EventsCleared`
|
||||
/// but before `Event::NewEvents` if called in the following circumstances:
|
||||
/// * While processing `EventsCleared`.
|
||||
/// * While processing a `RedrawRequested` event that was sent during `EventsCleared` or any
|
||||
/// directly subsequent `RedrawRequested` event.
|
||||
///
|
||||
/// ## 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.
|
||||
///
|
||||
/// Note that the top-left hand corner of the desktop is not necessarily the same as
|
||||
/// the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
|
||||
/// of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
|
||||
///
|
||||
/// The coordinates can be negative if the top-left hand corner of the window is outside
|
||||
/// of the visible screen region.
|
||||
///
|
||||
/// ## 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 outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
self.window.outer_position()
|
||||
}
|
||||
|
||||
/// Modifies the position of the window.
|
||||
///
|
||||
/// See `outer_position` for more information about the coordinates.
|
||||
///
|
||||
/// This is a no-op if the window has already been closed.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **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_outer_position(&self, position: LogicalPosition) {
|
||||
self.window.set_outer_position(position)
|
||||
}
|
||||
|
||||
/// Returns the logical size of the window's client area.
|
||||
///
|
||||
/// The client area is the content of the window, excluding the title bar and borders.
|
||||
///
|
||||
/// Converting the returned `LogicalSize` to `PhysicalSize` produces the size your framebuffer should be.
|
||||
///
|
||||
/// ## 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 inner_size(&self) -> LogicalSize {
|
||||
self.window.inner_size()
|
||||
}
|
||||
|
||||
/// Modifies the inner size of the window.
|
||||
///
|
||||
/// See `inner_size` for more information about the values.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS:** Unimplemented. Currently this panics, as it's not clear what `set_inner_size`
|
||||
/// would mean for iOS.
|
||||
#[inline]
|
||||
pub fn set_inner_size(&self, size: LogicalSize) {
|
||||
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.
|
||||
/// - **Android:** Has no effect.
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
||||
self.window.set_cursor(cursor);
|
||||
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
self.window.set_min_inner_size(dimensions)
|
||||
}
|
||||
|
||||
/// Changes the position of the cursor in window coordinates.
|
||||
/// Sets a maximum dimension size for the window.
|
||||
///
|
||||
/// ## 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)
|
||||
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.
|
||||
///
|
||||
/// Note that making the window unresizable doesn't exempt you from handling `Resized`, as that event can still be
|
||||
/// triggered by DPI scaling, entering fullscreen mode, etc.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// This only has an effect on desktop platforms.
|
||||
///
|
||||
/// Due to a bug in XFCE, this has no effect on Xfwm.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS:** Has no effect.
|
||||
#[inline]
|
||||
pub fn set_resizable(&self, resizable: bool) {
|
||||
self.window.set_resizable(resizable)
|
||||
}
|
||||
|
||||
/// Sets the window to maximized or back.
|
||||
|
@ -617,8 +551,8 @@ impl Window {
|
|||
///
|
||||
/// - **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.
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Add table
Reference in a new issue