mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-23 10:26:34 +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.
|
- `LoopDestroyed` is emitted when the `run` or `run_return` method is about to exit.
|
||||||
- Rename `MonitorId` to `MonitorHandle`.
|
- Rename `MonitorId` to `MonitorHandle`.
|
||||||
- Removed `serde` implementations from `ControlFlow`.
|
- Removed `serde` implementations from `ControlFlow`.
|
||||||
|
- Rename several functions to improve both internal consistency and compliance with Rust API guidelines.
|
||||||
|
- Remove `WindowBuilder::multitouch` field, since it was only implemented on a few platforms. Multitouch is always enabled now.
|
||||||
|
|
||||||
# Version 0.19.1 (2019-04-08)
|
# Version 0.19.1 (2019-04-08)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
use winit::window::{WindowBuilder, MouseCursor};
|
use winit::window::{WindowBuilder, CursorIcon};
|
||||||
use winit::event::{Event, WindowEvent, ElementState, KeyboardInput};
|
use winit::event::{Event, WindowEvent, ElementState, KeyboardInput};
|
||||||
use winit::event_loop::{EventLoop, ControlFlow};
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ fn main() {
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event: WindowEvent::KeyboardInput { input: KeyboardInput { state: ElementState::Pressed, .. }, .. }, .. } => {
|
Event::WindowEvent { event: WindowEvent::KeyboardInput { input: KeyboardInput { state: ElementState::Pressed, .. }, .. }, .. } => {
|
||||||
println!("Setting cursor to \"{:?}\"", CURSORS[cursor_idx]);
|
println!("Setting cursor to \"{:?}\"", CURSORS[cursor_idx]);
|
||||||
window.set_cursor(CURSORS[cursor_idx]);
|
window.set_cursor_icon(CURSORS[cursor_idx]);
|
||||||
if cursor_idx < CURSORS.len() - 1 {
|
if cursor_idx < CURSORS.len() - 1 {
|
||||||
cursor_idx += 1;
|
cursor_idx += 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -32,17 +32,17 @@ fn main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const CURSORS: &[MouseCursor] = &[
|
const CURSORS: &[CursorIcon] = &[
|
||||||
MouseCursor::Default, MouseCursor::Crosshair, MouseCursor::Hand,
|
CursorIcon::Default, CursorIcon::Crosshair, CursorIcon::Hand,
|
||||||
MouseCursor::Arrow, MouseCursor::Move, MouseCursor::Text,
|
CursorIcon::Arrow, CursorIcon::Move, CursorIcon::Text,
|
||||||
MouseCursor::Wait, MouseCursor::Help, MouseCursor::Progress,
|
CursorIcon::Wait, CursorIcon::Help, CursorIcon::Progress,
|
||||||
MouseCursor::NotAllowed, MouseCursor::ContextMenu, MouseCursor::Cell,
|
CursorIcon::NotAllowed, CursorIcon::ContextMenu, CursorIcon::Cell,
|
||||||
MouseCursor::VerticalText, MouseCursor::Alias, MouseCursor::Copy,
|
CursorIcon::VerticalText, CursorIcon::Alias, CursorIcon::Copy,
|
||||||
MouseCursor::NoDrop, MouseCursor::Grab, MouseCursor::Grabbing,
|
CursorIcon::NoDrop, CursorIcon::Grab, CursorIcon::Grabbing,
|
||||||
MouseCursor::AllScroll, MouseCursor::ZoomIn, MouseCursor::ZoomOut,
|
CursorIcon::AllScroll, CursorIcon::ZoomIn, CursorIcon::ZoomOut,
|
||||||
MouseCursor::EResize, MouseCursor::NResize, MouseCursor::NeResize,
|
CursorIcon::EResize, CursorIcon::NResize, CursorIcon::NeResize,
|
||||||
MouseCursor::NwResize, MouseCursor::SResize, MouseCursor::SeResize,
|
CursorIcon::NwResize, CursorIcon::SResize, CursorIcon::SeResize,
|
||||||
MouseCursor::SwResize, MouseCursor::WResize, MouseCursor::EwResize,
|
CursorIcon::SwResize, CursorIcon::WResize, CursorIcon::EwResize,
|
||||||
MouseCursor::NsResize, MouseCursor::NeswResize, MouseCursor::NwseResize,
|
CursorIcon::NsResize, CursorIcon::NeswResize, CursorIcon::NwseResize,
|
||||||
MouseCursor::ColResize, MouseCursor::RowResize
|
CursorIcon::ColResize, CursorIcon::RowResize
|
||||||
];
|
];
|
||||||
|
|
|
@ -29,8 +29,8 @@ fn main() {
|
||||||
use winit::event::VirtualKeyCode::*;
|
use winit::event::VirtualKeyCode::*;
|
||||||
match key {
|
match key {
|
||||||
Escape => *control_flow = ControlFlow::Exit,
|
Escape => *control_flow = ControlFlow::Exit,
|
||||||
G => window.grab_cursor(!modifiers.shift).unwrap(),
|
G => window.set_cursor_grab(!modifiers.shift).unwrap(),
|
||||||
H => window.hide_cursor(!modifiers.shift),
|
H => window.set_cursor_visible(modifiers.shift),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,16 +82,16 @@ fn main() {
|
||||||
if !is_fullscreen {
|
if !is_fullscreen {
|
||||||
window.set_fullscreen(None);
|
window.set_fullscreen(None);
|
||||||
} else {
|
} else {
|
||||||
window.set_fullscreen(Some(window.get_current_monitor()));
|
window.set_fullscreen(Some(window.current_monitor()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(VirtualKeyCode::S, ElementState::Pressed) => {
|
(VirtualKeyCode::S, ElementState::Pressed) => {
|
||||||
println!("window.get_fullscreen {:?}", window.get_fullscreen());
|
println!("window.fullscreen {:?}", window.fullscreen());
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
use winit::platform::macos::WindowExtMacOS;
|
use winit::platform::macos::WindowExtMacOS;
|
||||||
println!("window.get_simple_fullscreen {:?}", WindowExtMacOS::get_simple_fullscreen(&window));
|
println!("window.simple_fullscreen {:?}", WindowExtMacOS::simple_fullscreen(&window));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(VirtualKeyCode::M, ElementState::Pressed) => {
|
(VirtualKeyCode::M, ElementState::Pressed) => {
|
||||||
|
@ -113,8 +113,8 @@ fn main() {
|
||||||
|
|
||||||
// Enumerate monitors and prompt user to choose one
|
// Enumerate monitors and prompt user to choose one
|
||||||
fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle {
|
fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle {
|
||||||
for (num, monitor) in event_loop.get_available_monitors().enumerate() {
|
for (num, monitor) in event_loop.available_monitors().enumerate() {
|
||||||
println!("Monitor #{}: {:?}", num, monitor.get_name());
|
println!("Monitor #{}: {:?}", num, monitor.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
print!("Please write the number of the monitor to use: ");
|
print!("Please write the number of the monitor to use: ");
|
||||||
|
@ -123,9 +123,9 @@ fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle {
|
||||||
let mut num = String::new();
|
let mut num = String::new();
|
||||||
io::stdin().read_line(&mut num).unwrap();
|
io::stdin().read_line(&mut num).unwrap();
|
||||||
let num = num.trim().parse().ok().expect("Please enter a number");
|
let num = num.trim().parse().ok().expect("Please enter a number");
|
||||||
let monitor = event_loop.get_available_monitors().nth(num).expect("Please enter a valid ID");
|
let monitor = event_loop.available_monitors().nth(num).expect("Please enter a valid ID");
|
||||||
|
|
||||||
println!("Using {:?}", monitor.get_name());
|
println!("Using {:?}", monitor.name());
|
||||||
|
|
||||||
monitor
|
monitor
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ fn main() {
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
window.set_min_dimensions(Some(LogicalSize::new(400.0, 200.0)));
|
window.set_min_inner_size(Some(LogicalSize::new(400.0, 200.0)));
|
||||||
window.set_max_dimensions(Some(LogicalSize::new(800.0, 400.0)));
|
window.set_max_inner_size(Some(LogicalSize::new(800.0, 400.0)));
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
println!("{:?}", event);
|
println!("{:?}", event);
|
||||||
|
|
|
@ -5,5 +5,5 @@ use winit::window::WindowBuilder;
|
||||||
fn main() {
|
fn main() {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
println!("{:#?}\nPrimary: {:#?}", window.get_available_monitors(), window.get_primary_monitor());
|
println!("{:#?}\nPrimary: {:#?}", window.available_monitors(), window.primary_monitor());
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{collections::HashMap, sync::mpsc, thread, time::Duration};
|
||||||
|
|
||||||
use winit::{
|
use winit::{
|
||||||
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop}, window::{MouseCursor, WindowBuilder},
|
event_loop::{ControlFlow, EventLoop}, window::{CursorIcon, WindowBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
const WINDOW_COUNT: usize = 3;
|
const WINDOW_COUNT: usize = 3;
|
||||||
|
@ -17,7 +17,7 @@ fn main() {
|
||||||
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
|
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
|
||||||
for _ in 0..WINDOW_COUNT {
|
for _ in 0..WINDOW_COUNT {
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_dimensions(WINDOW_SIZE.into())
|
.with_inner_size(WINDOW_SIZE.into())
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
@ -36,31 +36,31 @@ fn main() {
|
||||||
use self::VirtualKeyCode::*;
|
use self::VirtualKeyCode::*;
|
||||||
match key {
|
match key {
|
||||||
A => window.set_always_on_top(state),
|
A => window.set_always_on_top(state),
|
||||||
C => window.set_cursor(match state {
|
C => window.set_cursor_icon(match state {
|
||||||
true => MouseCursor::Progress,
|
true => CursorIcon::Progress,
|
||||||
false => MouseCursor::Default,
|
false => CursorIcon::Default,
|
||||||
}),
|
}),
|
||||||
D => window.set_decorations(!state),
|
D => window.set_decorations(!state),
|
||||||
F => window.set_fullscreen(match state {
|
F => window.set_fullscreen(match state {
|
||||||
true => Some(window.get_current_monitor()),
|
true => Some(window.current_monitor()),
|
||||||
false => None,
|
false => None,
|
||||||
}),
|
}),
|
||||||
G => window.grab_cursor(state).unwrap(),
|
G => window.set_cursor_grab(state).unwrap(),
|
||||||
H => window.hide_cursor(state),
|
H => window.set_cursor_visible(!state),
|
||||||
I => {
|
I => {
|
||||||
println!("Info:");
|
println!("Info:");
|
||||||
println!("-> position : {:?}", window.get_position());
|
println!("-> outer_position : {:?}", window.outer_position());
|
||||||
println!("-> inner_position : {:?}", window.get_inner_position());
|
println!("-> inner_position : {:?}", window.inner_position());
|
||||||
println!("-> outer_size : {:?}", window.get_outer_size());
|
println!("-> outer_size : {:?}", window.outer_size());
|
||||||
println!("-> inner_size : {:?}", window.get_inner_size());
|
println!("-> inner_size : {:?}", window.inner_size());
|
||||||
},
|
},
|
||||||
L => window.set_min_dimensions(match state {
|
L => window.set_min_inner_size(match state {
|
||||||
true => Some(WINDOW_SIZE.into()),
|
true => Some(WINDOW_SIZE.into()),
|
||||||
false => None,
|
false => None,
|
||||||
}),
|
}),
|
||||||
M => window.set_maximized(state),
|
M => window.set_maximized(state),
|
||||||
P => window.set_position({
|
P => window.set_outer_position({
|
||||||
let mut position = window.get_position().unwrap();
|
let mut position = window.outer_position().unwrap();
|
||||||
let sign = if state { 1.0 } else { -1.0 };
|
let sign = if state { 1.0 } else { -1.0 };
|
||||||
position.x += 10.0 * sign;
|
position.x += 10.0 * sign;
|
||||||
position.y += 10.0 * sign;
|
position.y += 10.0 * sign;
|
||||||
|
@ -77,9 +77,9 @@ fn main() {
|
||||||
WINDOW_SIZE.1 as i32 / 2,
|
WINDOW_SIZE.1 as i32 / 2,
|
||||||
).into()).unwrap(),
|
).into()).unwrap(),
|
||||||
Z => {
|
Z => {
|
||||||
window.hide();
|
window.set_visible(false);
|
||||||
thread::sleep(Duration::from_secs(1));
|
thread::sleep(Duration::from_secs(1));
|
||||||
window.show();
|
window.set_visible(true);
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ fn main() {
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Hit space to toggle resizability.")
|
.with_title("Hit space to toggle resizability.")
|
||||||
.with_dimensions((400, 200).into())
|
.with_inner_size((400, 200).into())
|
||||||
.with_resizable(resizable)
|
.with_resizable(resizable)
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -33,10 +33,10 @@
|
||||||
//! windows. This event is sent any time the DPI factor changes, either because the window moved to another monitor,
|
//! windows. This event is sent any time the DPI factor changes, either because the window moved to another monitor,
|
||||||
//! or because the user changed the configuration of their screen.
|
//! or because the user changed the configuration of their screen.
|
||||||
//! - You can also retrieve the DPI factor of a monitor by calling
|
//! - You can also retrieve the DPI factor of a monitor by calling
|
||||||
//! [`MonitorHandle::get_hidpi_factor`](../monitor/struct.MonitorHandle.html#method.get_hidpi_factor), or the
|
//! [`MonitorHandle::hidpi_factor`](../monitor/struct.MonitorHandle.html#method.hidpi_factor), or the
|
||||||
//! current DPI factor applied to a window by calling
|
//! current DPI factor applied to a window by calling
|
||||||
//! [`Window::get_hidpi_factor`](../window/struct.Window.html#method.get_hidpi_factor), which is roughly equivalent
|
//! [`Window::hidpi_factor`](../window/struct.Window.html#method.hidpi_factor), which is roughly equivalent
|
||||||
//! to `window.get_current_monitor().get_hidpi_factor()`.
|
//! to `window.current_monitor().hidpi_factor()`.
|
||||||
//!
|
//!
|
||||||
//! Depending on the platform, the window's actual DPI factor may only be known after
|
//! Depending on the platform, the window's actual DPI factor may only be known after
|
||||||
//! the event loop has started and your window has been drawn once. To properly handle these cases,
|
//! the event loop has started and your window has been drawn once. To properly handle these cases,
|
||||||
|
|
86
src/error.rs
Normal file
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 {}
|
|
@ -94,9 +94,9 @@ impl Default for ControlFlow {
|
||||||
|
|
||||||
impl EventLoop<()> {
|
impl EventLoop<()> {
|
||||||
/// Builds a new event loop with a `()` as the user event type.
|
/// Builds a new event loop with a `()` as the user event type.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Can only be called on the main thread.
|
/// - **iOS:** Can only be called on the main thread.
|
||||||
pub fn new() -> EventLoop<()> {
|
pub fn new() -> EventLoop<()> {
|
||||||
EventLoop::<()>::new_user_event()
|
EventLoop::<()>::new_user_event()
|
||||||
|
@ -110,9 +110,9 @@ impl<T> EventLoop<T> {
|
||||||
/// using an environment variable `WINIT_UNIX_BACKEND`. Legal values are `x11` and `wayland`.
|
/// using an environment variable `WINIT_UNIX_BACKEND`. Legal values are `x11` and `wayland`.
|
||||||
/// If it is not set, winit will try to connect to a wayland connection, and if it fails will
|
/// If it is not set, winit will try to connect to a wayland connection, and if it fails will
|
||||||
/// fallback on x11. If this variable is set with any other value, winit will panic.
|
/// fallback on x11. If this variable is set with any other value, winit will panic.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Can only be called on the main thread.
|
/// - **iOS:** Can only be called on the main thread.
|
||||||
pub fn new_user_event() -> EventLoop<T> {
|
pub fn new_user_event() -> EventLoop<T> {
|
||||||
EventLoop {
|
EventLoop {
|
||||||
|
@ -121,21 +121,6 @@ impl<T> EventLoop<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the list of all the monitors available on the system.
|
|
||||||
///
|
|
||||||
// Note: should be replaced with `-> impl Iterator` once stable.
|
|
||||||
#[inline]
|
|
||||||
pub fn get_available_monitors(&self) -> AvailableMonitorsIter {
|
|
||||||
let data = self.event_loop.get_available_monitors();
|
|
||||||
AvailableMonitorsIter{ data: data.into_iter() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the primary monitor of the system.
|
|
||||||
#[inline]
|
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
|
||||||
MonitorHandle { inner: self.event_loop.get_primary_monitor() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hijacks the calling thread and initializes the `winit` event loop with the provided
|
/// Hijacks the calling thread and initializes the `winit` event loop with the provided
|
||||||
/// closure. Since the closure is `'static`, it must be a `move` closure if it needs to
|
/// closure. Since the closure is `'static`, it must be a `move` closure if it needs to
|
||||||
/// access any data from the calling context.
|
/// access any data from the calling context.
|
||||||
|
@ -153,13 +138,27 @@ impl<T> EventLoop<T> {
|
||||||
self.event_loop.run(event_handler)
|
self.event_loop.run(event_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an `EventLoopProxy` that can be used to wake up the `EventLoop` from another
|
/// Creates an `EventLoopProxy` that can be used to dispatch user events to the main event loop.
|
||||||
/// thread.
|
|
||||||
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
||||||
EventLoopProxy {
|
EventLoopProxy {
|
||||||
event_loop_proxy: self.event_loop.create_proxy(),
|
event_loop_proxy: self.event_loop.create_proxy(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the list of all the monitors available on the system.
|
||||||
|
///
|
||||||
|
// Note: should be replaced with `-> impl Iterator` once stable.
|
||||||
|
#[inline]
|
||||||
|
pub fn available_monitors(&self) -> AvailableMonitorsIter {
|
||||||
|
let data = self.event_loop.available_monitors();
|
||||||
|
AvailableMonitorsIter{ data: data.into_iter() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the primary monitor of the system.
|
||||||
|
#[inline]
|
||||||
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
|
MonitorHandle { inner: self.event_loop.primary_monitor() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Deref for EventLoop<T> {
|
impl<T> Deref for EventLoop<T> {
|
||||||
|
|
|
@ -113,6 +113,8 @@ extern crate smithay_client_toolkit as sctk;
|
||||||
extern crate calloop;
|
extern crate calloop;
|
||||||
|
|
||||||
pub mod dpi;
|
pub mod dpi;
|
||||||
|
#[macro_use]
|
||||||
|
pub mod error;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod event_loop;
|
pub mod event_loop;
|
||||||
mod icon;
|
mod icon;
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
//! If you want to get basic information about a monitor, you can use the [`MonitorHandle`][monitor_id]
|
//! If you want to get basic information about a monitor, you can use the [`MonitorHandle`][monitor_id]
|
||||||
//! type. This is retreived from an [`AvailableMonitorsIter`][monitor_iter], which can be acquired
|
//! type. This is retreived from an [`AvailableMonitorsIter`][monitor_iter], which can be acquired
|
||||||
//! with:
|
//! with:
|
||||||
//! - [`EventLoop::get_available_monitors`][loop_get]
|
//! - [`EventLoop::available_monitors`][loop_get]
|
||||||
//! - [`Window::get_available_monitors`][window_get].
|
//! - [`Window::available_monitors`][window_get].
|
||||||
//!
|
//!
|
||||||
//! [monitor_id]: ./struct.MonitorHandle.html
|
//! [monitor_id]: ./struct.MonitorHandle.html
|
||||||
//! [monitor_iter]: ./struct.AvailableMonitorsIter.html
|
//! [monitor_iter]: ./struct.AvailableMonitorsIter.html
|
||||||
//! [loop_get]: ../event_loop/struct.EventLoop.html#method.get_available_monitors
|
//! [loop_get]: ../event_loop/struct.EventLoop.html#method.available_monitors
|
||||||
//! [window_get]: ../window/struct.Window.html#method.get_available_monitors
|
//! [window_get]: ../window/struct.Window.html#method.available_monitors
|
||||||
use std::collections::vec_deque::IntoIter as VecDequeIter;
|
use std::collections::vec_deque::IntoIter as VecDequeIter;
|
||||||
|
|
||||||
use platform_impl;
|
use platform_impl;
|
||||||
|
@ -18,11 +18,11 @@ use dpi::{PhysicalPosition, PhysicalSize};
|
||||||
/// An iterator over all available monitors.
|
/// An iterator over all available monitors.
|
||||||
///
|
///
|
||||||
/// Can be acquired with:
|
/// Can be acquired with:
|
||||||
/// - [`EventLoop::get_available_monitors`][loop_get]
|
/// - [`EventLoop::available_monitors`][loop_get]
|
||||||
/// - [`Window::get_available_monitors`][window_get].
|
/// - [`Window::available_monitors`][window_get].
|
||||||
///
|
///
|
||||||
/// [loop_get]: ../event_loop/struct.EventLoop.html#method.get_available_monitors
|
/// [loop_get]: ../event_loop/struct.EventLoop.html#method.available_monitors
|
||||||
/// [window_get]: ../window/struct.Window.html#method.get_available_monitors
|
/// [window_get]: ../window/struct.Window.html#method.available_monitors
|
||||||
// Implementation note: we retrieve the list once, then serve each element by one by one.
|
// Implementation note: we retrieve the list once, then serve each element by one by one.
|
||||||
// This may change in the future.
|
// This may change in the future.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -59,21 +59,21 @@ impl MonitorHandle {
|
||||||
///
|
///
|
||||||
/// Returns `None` if the monitor doesn't exist anymore.
|
/// Returns `None` if the monitor doesn't exist anymore.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
self.inner.get_name()
|
self.inner.name()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the monitor's resolution.
|
/// Returns the monitor's resolution.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
self.inner.get_dimensions()
|
self.inner.dimensions()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the top-left corner position of the monitor relative to the larger full
|
/// Returns the top-left corner position of the monitor relative to the larger full
|
||||||
/// screen area.
|
/// screen area.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn position(&self) -> PhysicalPosition {
|
||||||
self.inner.get_position()
|
self.inner.position()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa.
|
/// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa.
|
||||||
|
@ -85,7 +85,7 @@ impl MonitorHandle {
|
||||||
/// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
|
/// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
|
||||||
/// - **Android:** Always returns 1.0.
|
/// - **Android:** Always returns 1.0.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
self.inner.get_hidpi_factor()
|
self.inner.hidpi_factor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,13 @@ impl EventLoopExtAndroid for EventLoop {
|
||||||
|
|
||||||
/// Additional methods on `Window` that are specific to Android.
|
/// Additional methods on `Window` that are specific to Android.
|
||||||
pub trait WindowExtAndroid {
|
pub trait WindowExtAndroid {
|
||||||
fn get_native_window(&self) -> *const c_void;
|
fn native_window(&self) -> *const c_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowExtAndroid for Window {
|
impl WindowExtAndroid for Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_native_window(&self) -> *const c_void {
|
fn native_window(&self) -> *const c_void {
|
||||||
self.window.get_native_window()
|
self.window.native_window()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,12 @@ use window::{Window, WindowBuilder};
|
||||||
/// Additional methods on `EventLoop` that are specific to iOS.
|
/// Additional methods on `EventLoop` that are specific to iOS.
|
||||||
pub trait EventLoopExtIOS {
|
pub trait EventLoopExtIOS {
|
||||||
/// Returns the idiom (phone/tablet/tv/etc) for the current device.
|
/// Returns the idiom (phone/tablet/tv/etc) for the current device.
|
||||||
fn get_idiom(&self) -> Idiom;
|
fn idiom(&self) -> Idiom;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> EventLoopExtIOS for EventLoop<T> {
|
impl<T: 'static> EventLoopExtIOS for EventLoop<T> {
|
||||||
fn get_idiom(&self) -> Idiom {
|
fn idiom(&self) -> Idiom {
|
||||||
self.event_loop.get_idiom()
|
self.event_loop.idiom()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,43 +23,43 @@ pub trait WindowExtIOS {
|
||||||
/// Returns a pointer to the `UIWindow` that is used by this window.
|
/// Returns a pointer to the `UIWindow` that is used by this window.
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the `Window` is destroyed.
|
/// The pointer will become invalid when the `Window` is destroyed.
|
||||||
fn get_uiwindow(&self) -> *mut c_void;
|
fn ui_window(&self) -> *mut c_void;
|
||||||
|
|
||||||
/// Returns a pointer to the `UIViewController` that is used by this window.
|
/// Returns a pointer to the `UIViewController` that is used by this window.
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the `Window` is destroyed.
|
/// The pointer will become invalid when the `Window` is destroyed.
|
||||||
fn get_uiviewcontroller(&self) -> *mut c_void;
|
fn ui_view_controller(&self) -> *mut c_void;
|
||||||
|
|
||||||
/// Returns a pointer to the `UIView` that is used by this window.
|
/// Returns a pointer to the `UIView` that is used by this window.
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the `Window` is destroyed.
|
/// The pointer will become invalid when the `Window` is destroyed.
|
||||||
fn get_uiview(&self) -> *mut c_void;
|
fn ui_view(&self) -> *mut c_void;
|
||||||
|
|
||||||
/// Sets the HiDpi factor used by this window.
|
/// Sets the HiDpi factor used by this window.
|
||||||
///
|
///
|
||||||
/// This translates to `-[UIWindow setContentScaleFactor:hidpi_factor]`.
|
/// This translates to `-[UIWindow setContentScaleFactor:hidpi_factor]`.
|
||||||
fn set_hidpi_factor(&self, hidpi_factor: f64);
|
fn set_hidpi_factor(&self, hidpi_factor: f64);
|
||||||
|
|
||||||
/// Sets the valid orientations for screens showing this `Window`.
|
/// Sets the valid orientations for screens showing this `Window`.
|
||||||
///
|
///
|
||||||
/// On iPhones and iPods upside down portrait is never enabled.
|
/// On iPhones and iPods upside down portrait is never enabled.
|
||||||
fn set_valid_orientations(&self, valid_orientations: ValidOrientations);
|
fn set_valid_orientations(&self, valid_orientations: ValidOrientations);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowExtIOS for Window {
|
impl WindowExtIOS for Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_uiwindow(&self) -> *mut c_void {
|
fn ui_window(&self) -> *mut c_void {
|
||||||
self.window.get_uiwindow() as _
|
self.window.ui_window() as _
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_uiviewcontroller(&self) -> *mut c_void {
|
fn ui_view_controller(&self) -> *mut c_void {
|
||||||
self.window.get_uiviewcontroller() as _
|
self.window.ui_view_controller() as _
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_uiview(&self) -> *mut c_void {
|
fn ui_view(&self) -> *mut c_void {
|
||||||
self.window.get_uiview() as _
|
self.window.ui_view() as _
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -79,13 +79,13 @@ pub trait WindowBuilderExtIOS {
|
||||||
///
|
///
|
||||||
/// The class will be initialized by calling `[root_view initWithFrame:CGRect]`
|
/// The class will be initialized by calling `[root_view initWithFrame:CGRect]`
|
||||||
fn with_root_view_class(self, root_view_class: *const c_void) -> WindowBuilder;
|
fn with_root_view_class(self, root_view_class: *const c_void) -> WindowBuilder;
|
||||||
|
|
||||||
/// Sets the `contentScaleFactor` of the underlying `UIWindow` to `hidpi_factor`.
|
/// Sets the `contentScaleFactor` of the underlying `UIWindow` to `hidpi_factor`.
|
||||||
///
|
///
|
||||||
/// The default value is device dependent, and it's recommended GLES or Metal applications set
|
/// The default value is device dependent, and it's recommended GLES or Metal applications set
|
||||||
/// this to `MonitorHandle::get_hidpi_factor()`.
|
/// this to `MonitorHandle::hidpi_factor()`.
|
||||||
fn with_hidpi_factor(self, hidpi_factor: f64) -> WindowBuilder;
|
fn with_hidpi_factor(self, hidpi_factor: f64) -> WindowBuilder;
|
||||||
|
|
||||||
/// Sets the valid orientations for the `Window`.
|
/// Sets the valid orientations for the `Window`.
|
||||||
fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> WindowBuilder;
|
fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> WindowBuilder;
|
||||||
}
|
}
|
||||||
|
@ -113,13 +113,13 @@ impl WindowBuilderExtIOS for WindowBuilder {
|
||||||
/// Additional methods on `MonitorHandle` that are specific to iOS.
|
/// Additional methods on `MonitorHandle` that are specific to iOS.
|
||||||
pub trait MonitorHandleExtIOS {
|
pub trait MonitorHandleExtIOS {
|
||||||
/// Returns a pointer to the `UIScreen` that is used by this monitor.
|
/// Returns a pointer to the `UIScreen` that is used by this monitor.
|
||||||
fn get_uiscreen(&self) -> *mut c_void;
|
fn ui_screen(&self) -> *mut c_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitorHandleExtIOS for MonitorHandle {
|
impl MonitorHandleExtIOS for MonitorHandle {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_uiscreen(&self) -> *mut c_void {
|
fn ui_screen(&self) -> *mut c_void {
|
||||||
self.inner.get_uiscreen() as _
|
self.inner.ui_screen() as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ pub enum ValidOrientations {
|
||||||
LandscapeAndPortrait,
|
LandscapeAndPortrait,
|
||||||
|
|
||||||
Landscape,
|
Landscape,
|
||||||
|
|
||||||
/// Excludes `PortraitUpsideDown` on iphone
|
/// Excludes `PortraitUpsideDown` on iphone
|
||||||
Portrait,
|
Portrait,
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ impl Default for ValidOrientations {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The device [idiom].
|
/// The device [idiom].
|
||||||
///
|
///
|
||||||
/// [idiom]: https://developer.apple.com/documentation/uikit/uidevice/1620037-userinterfaceidiom?language=objc
|
/// [idiom]: https://developer.apple.com/documentation/uikit/uidevice/1620037-userinterfaceidiom?language=objc
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum Idiom {
|
pub enum Idiom {
|
||||||
|
|
|
@ -11,12 +11,12 @@ pub trait WindowExtMacOS {
|
||||||
/// Returns a pointer to the cocoa `NSWindow` that is used by this window.
|
/// Returns a pointer to the cocoa `NSWindow` that is used by this window.
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the `Window` is destroyed.
|
/// The pointer will become invalid when the `Window` is destroyed.
|
||||||
fn get_nswindow(&self) -> *mut c_void;
|
fn nswindow(&self) -> *mut c_void;
|
||||||
|
|
||||||
/// Returns a pointer to the cocoa `NSView` that is used by this window.
|
/// Returns a pointer to the cocoa `NSView` that is used by this window.
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the `Window` is destroyed.
|
/// The pointer will become invalid when the `Window` is destroyed.
|
||||||
fn get_nsview(&self) -> *mut c_void;
|
fn nsview(&self) -> *mut c_void;
|
||||||
|
|
||||||
/// Request user attention, causing the application's dock icon to bounce.
|
/// Request user attention, causing the application's dock icon to bounce.
|
||||||
/// Note that this has no effect if the application is already focused.
|
/// Note that this has no effect if the application is already focused.
|
||||||
|
@ -27,7 +27,7 @@ pub trait WindowExtMacOS {
|
||||||
fn request_user_attention(&self, is_critical: bool);
|
fn request_user_attention(&self, is_critical: bool);
|
||||||
|
|
||||||
/// Returns whether or not the window is in simple fullscreen mode.
|
/// Returns whether or not the window is in simple fullscreen mode.
|
||||||
fn get_simple_fullscreen(&self) -> bool;
|
fn simple_fullscreen(&self) -> bool;
|
||||||
|
|
||||||
/// Toggles a fullscreen mode that doesn't require a new macOS space.
|
/// Toggles a fullscreen mode that doesn't require a new macOS space.
|
||||||
/// Returns a boolean indicating whether the transition was successful (this
|
/// Returns a boolean indicating whether the transition was successful (this
|
||||||
|
@ -41,13 +41,13 @@ pub trait WindowExtMacOS {
|
||||||
|
|
||||||
impl WindowExtMacOS for Window {
|
impl WindowExtMacOS for Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_nswindow(&self) -> *mut c_void {
|
fn nswindow(&self) -> *mut c_void {
|
||||||
self.window.get_nswindow()
|
self.window.nswindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_nsview(&self) -> *mut c_void {
|
fn nsview(&self) -> *mut c_void {
|
||||||
self.window.get_nsview()
|
self.window.nsview()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -56,8 +56,8 @@ impl WindowExtMacOS for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_simple_fullscreen(&self) -> bool {
|
fn simple_fullscreen(&self) -> bool {
|
||||||
self.window.get_simple_fullscreen()
|
self.window.simple_fullscreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -167,16 +167,16 @@ pub trait MonitorHandleExtMacOS {
|
||||||
/// Returns the identifier of the monitor for Cocoa.
|
/// Returns the identifier of the monitor for Cocoa.
|
||||||
fn native_id(&self) -> u32;
|
fn native_id(&self) -> u32;
|
||||||
/// Returns a pointer to the NSScreen representing this monitor.
|
/// Returns a pointer to the NSScreen representing this monitor.
|
||||||
fn get_nsscreen(&self) -> Option<*mut c_void>;
|
fn nsscreen(&self) -> Option<*mut c_void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitorHandleExtMacOS for MonitorHandle {
|
impl MonitorHandleExtMacOS for MonitorHandle {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn native_id(&self) -> u32 {
|
fn native_id(&self) -> u32 {
|
||||||
self.inner.get_native_identifier()
|
self.inner.native_identifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_nsscreen(&self) -> Option<*mut c_void> {
|
fn nsscreen(&self) -> Option<*mut c_void> {
|
||||||
self.inner.get_nsscreen().map(|s| s as *mut c_void)
|
self.inner.nsscreen().map(|s| s as *mut c_void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,14 +110,14 @@ pub trait EventLoopExtUnix {
|
||||||
fn is_x11(&self) -> bool;
|
fn is_x11(&self) -> bool;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
fn xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
||||||
|
|
||||||
/// Returns a pointer to the `wl_display` object of wayland that is used by this `EventLoop`.
|
/// Returns a pointer to the `wl_display` object of wayland that is used by this `EventLoop`.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the `EventLoop` doesn't use wayland (if it uses xlib for example).
|
/// Returns `None` if the `EventLoop` doesn't use wayland (if it uses xlib for example).
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the glutin `EventLoop` is destroyed.
|
/// The pointer will become invalid when the glutin `EventLoop` is destroyed.
|
||||||
fn get_wayland_display(&self) -> Option<*mut raw::c_void>;
|
fn wayland_display(&self) -> Option<*mut raw::c_void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EventLoopExtUnix for EventLoop<T> {
|
impl<T> EventLoopExtUnix for EventLoop<T> {
|
||||||
|
@ -154,7 +154,7 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
fn xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
||||||
match self.event_loop {
|
match self.event_loop {
|
||||||
LinuxEventLoop::X(ref e) => Some(e.x_connection().clone()),
|
LinuxEventLoop::X(ref e) => Some(e.x_connection().clone()),
|
||||||
_ => None
|
_ => None
|
||||||
|
@ -162,9 +162,9 @@ impl<T> EventLoopExtUnix for EventLoop<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
|
fn wayland_display(&self) -> Option<*mut raw::c_void> {
|
||||||
match self.event_loop {
|
match self.event_loop {
|
||||||
LinuxEventLoop::Wayland(ref e) => Some(e.get_display().get_display_ptr() as *mut _),
|
LinuxEventLoop::Wayland(ref e) => Some(e.display().get_display_ptr() as *mut _),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,19 +175,19 @@ pub trait WindowExtUnix {
|
||||||
/// Returns the ID of the `Window` xlib object that is used by this window.
|
/// Returns the ID of the `Window` xlib object that is used by this window.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
|
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
|
||||||
fn get_xlib_window(&self) -> Option<raw::c_ulong>;
|
fn xlib_window(&self) -> Option<raw::c_ulong>;
|
||||||
|
|
||||||
/// Returns a pointer to the `Display` object of xlib that is used by this window.
|
/// Returns a pointer to the `Display` object of xlib that is used by this window.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
|
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the glutin `Window` is destroyed.
|
/// The pointer will become invalid when the glutin `Window` is destroyed.
|
||||||
fn get_xlib_display(&self) -> Option<*mut raw::c_void>;
|
fn xlib_display(&self) -> Option<*mut raw::c_void>;
|
||||||
|
|
||||||
fn get_xlib_screen_id(&self) -> Option<raw::c_int>;
|
fn xlib_screen_id(&self) -> Option<raw::c_int>;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
fn xlib_xconnection(&self) -> Option<Arc<XConnection>>;
|
||||||
|
|
||||||
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
|
/// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
|
||||||
fn set_urgent(&self, is_urgent: bool);
|
fn set_urgent(&self, is_urgent: bool);
|
||||||
|
@ -197,21 +197,21 @@ pub trait WindowExtUnix {
|
||||||
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
|
/// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the glutin `Window` is destroyed.
|
/// The pointer will become invalid when the glutin `Window` is destroyed.
|
||||||
fn get_xcb_connection(&self) -> Option<*mut raw::c_void>;
|
fn xcb_connection(&self) -> Option<*mut raw::c_void>;
|
||||||
|
|
||||||
/// Returns a pointer to the `wl_surface` object of wayland that is used by this window.
|
/// Returns a pointer to the `wl_surface` object of wayland that is used by this window.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
|
/// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the glutin `Window` is destroyed.
|
/// The pointer will become invalid when the glutin `Window` is destroyed.
|
||||||
fn get_wayland_surface(&self) -> Option<*mut raw::c_void>;
|
fn wayland_surface(&self) -> Option<*mut raw::c_void>;
|
||||||
|
|
||||||
/// Returns a pointer to the `wl_display` object of wayland that is used by this window.
|
/// Returns a pointer to the `wl_display` object of wayland that is used by this window.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
|
/// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the glutin `Window` is destroyed.
|
/// The pointer will become invalid when the glutin `Window` is destroyed.
|
||||||
fn get_wayland_display(&self) -> Option<*mut raw::c_void>;
|
fn wayland_display(&self) -> Option<*mut raw::c_void>;
|
||||||
|
|
||||||
/// Sets the color theme of the client side window decorations on wayland
|
/// Sets the color theme of the client side window decorations on wayland
|
||||||
fn set_wayland_theme(&self, theme: WaylandTheme);
|
fn set_wayland_theme(&self, theme: WaylandTheme);
|
||||||
|
@ -228,42 +228,42 @@ pub trait WindowExtUnix {
|
||||||
|
|
||||||
impl WindowExtUnix for Window {
|
impl WindowExtUnix for Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_xlib_window(&self) -> Option<raw::c_ulong> {
|
fn xlib_window(&self) -> Option<raw::c_ulong> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::X(ref w) => Some(w.get_xlib_window()),
|
LinuxWindow::X(ref w) => Some(w.xlib_window()),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_xlib_display(&self) -> Option<*mut raw::c_void> {
|
fn xlib_display(&self) -> Option<*mut raw::c_void> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::X(ref w) => Some(w.get_xlib_display()),
|
LinuxWindow::X(ref w) => Some(w.xlib_display()),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_xlib_screen_id(&self) -> Option<raw::c_int> {
|
fn xlib_screen_id(&self) -> Option<raw::c_int> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::X(ref w) => Some(w.get_xlib_screen_id()),
|
LinuxWindow::X(ref w) => Some(w.xlib_screen_id()),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn get_xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
fn xlib_xconnection(&self) -> Option<Arc<XConnection>> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::X(ref w) => Some(w.get_xlib_xconnection()),
|
LinuxWindow::X(ref w) => Some(w.xlib_xconnection()),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_xcb_connection(&self) -> Option<*mut raw::c_void> {
|
fn xcb_connection(&self) -> Option<*mut raw::c_void> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::X(ref w) => Some(w.get_xcb_connection()),
|
LinuxWindow::X(ref w) => Some(w.xcb_connection()),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,17 +276,17 @@ impl WindowExtUnix for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_wayland_surface(&self) -> Option<*mut raw::c_void> {
|
fn wayland_surface(&self) -> Option<*mut raw::c_void> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::Wayland(ref w) => Some(w.get_surface().as_ref().c_ptr() as *mut _),
|
LinuxWindow::Wayland(ref w) => Some(w.surface().as_ref().c_ptr() as *mut _),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_wayland_display(&self) -> Option<*mut raw::c_void> {
|
fn wayland_display(&self) -> Option<*mut raw::c_void> {
|
||||||
match self.window {
|
match self.window {
|
||||||
LinuxWindow::Wayland(ref w) => Some(w.get_display().as_ref().c_ptr() as *mut _),
|
LinuxWindow::Wayland(ref w) => Some(w.display().as_ref().c_ptr() as *mut _),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,6 +398,6 @@ pub trait MonitorHandleExtUnix {
|
||||||
impl MonitorHandleExtUnix for MonitorHandle {
|
impl MonitorHandleExtUnix for MonitorHandle {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn native_id(&self) -> u32 {
|
fn native_id(&self) -> u32 {
|
||||||
self.inner.get_native_identifier()
|
self.inner.native_identifier()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub trait WindowExtWindows {
|
||||||
/// Returns the native handle that is used by this window.
|
/// Returns the native handle that is used by this window.
|
||||||
///
|
///
|
||||||
/// The pointer will become invalid when the native window was destroyed.
|
/// The pointer will become invalid when the native window was destroyed.
|
||||||
fn get_hwnd(&self) -> *mut libc::c_void;
|
fn hwnd(&self) -> *mut libc::c_void;
|
||||||
|
|
||||||
/// This sets `ICON_BIG`. A good ceiling here is 256x256.
|
/// This sets `ICON_BIG`. A good ceiling here is 256x256.
|
||||||
fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>);
|
fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>);
|
||||||
|
@ -41,7 +41,7 @@ pub trait WindowExtWindows {
|
||||||
|
|
||||||
impl WindowExtWindows for Window {
|
impl WindowExtWindows for Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_hwnd(&self) -> *mut libc::c_void {
|
fn hwnd(&self) -> *mut libc::c_void {
|
||||||
self.window.hwnd() as *mut _
|
self.window.hwnd() as *mut _
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,12 +95,12 @@ pub trait MonitorHandleExtWindows {
|
||||||
impl MonitorHandleExtWindows for MonitorHandle {
|
impl MonitorHandleExtWindows for MonitorHandle {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn native_id(&self) -> String {
|
fn native_id(&self) -> String {
|
||||||
self.inner.get_native_identifier()
|
self.inner.native_identifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hmonitor(&self) -> *mut c_void {
|
fn hmonitor(&self) -> *mut c_void {
|
||||||
self.inner.get_hmonitor() as *mut _
|
self.inner.hmonitor() as *mut _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,12 +109,12 @@ pub trait DeviceIdExtWindows {
|
||||||
/// Returns an identifier that persistently refers to this specific device.
|
/// Returns an identifier that persistently refers to this specific device.
|
||||||
///
|
///
|
||||||
/// Will return `None` if the device is no longer available.
|
/// Will return `None` if the device is no longer available.
|
||||||
fn get_persistent_identifier(&self) -> Option<String>;
|
fn persistent_identifier(&self) -> Option<String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceIdExtWindows for DeviceId {
|
impl DeviceIdExtWindows for DeviceId {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_persistent_identifier(&self) -> Option<String> {
|
fn persistent_identifier(&self) -> Option<String> {
|
||||||
self.0.get_persistent_identifier()
|
self.0.persistent_identifier()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use {
|
||||||
Event,
|
Event,
|
||||||
LogicalPosition,
|
LogicalPosition,
|
||||||
LogicalSize,
|
LogicalSize,
|
||||||
MouseCursor,
|
CursorIcon,
|
||||||
PhysicalPosition,
|
PhysicalPosition,
|
||||||
PhysicalSize,
|
PhysicalSize,
|
||||||
WindowAttributes,
|
WindowAttributes,
|
||||||
|
@ -23,9 +23,12 @@ use {
|
||||||
WindowId as RootWindowId,
|
WindowId as RootWindowId,
|
||||||
};
|
};
|
||||||
use CreationError::OsError;
|
use CreationError::OsError;
|
||||||
|
use error::{ExternalError, NotSupportedError};
|
||||||
use events::{Touch, TouchPhase};
|
use events::{Touch, TouchPhase};
|
||||||
use window::MonitorHandle as RootMonitorHandle;
|
use window::MonitorHandle as RootMonitorHandle;
|
||||||
|
|
||||||
|
pub type OsError = std::io::Error;
|
||||||
|
|
||||||
pub struct EventLoop {
|
pub struct EventLoop {
|
||||||
event_rx: Receiver<android_glue::Event>,
|
event_rx: Receiver<android_glue::Event>,
|
||||||
suspend_callback: RefCell<Option<Box<Fn(bool) -> ()>>>,
|
suspend_callback: RefCell<Option<Box<Fn(bool) -> ()>>>,
|
||||||
|
@ -45,14 +48,14 @@ impl EventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
let mut rb = VecDeque::with_capacity(1);
|
let mut rb = VecDeque::with_capacity(1);
|
||||||
rb.push_back(MonitorHandle);
|
rb.push_back(MonitorHandle);
|
||||||
rb
|
rb
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
MonitorHandle
|
MonitorHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +65,7 @@ impl EventLoop {
|
||||||
while let Ok(event) = self.event_rx.try_recv() {
|
while let Ok(event) = self.event_rx.try_recv() {
|
||||||
let e = match event{
|
let e = match event{
|
||||||
android_glue::Event::EventMotion(motion) => {
|
android_glue::Event::EventMotion(motion) => {
|
||||||
let dpi_factor = MonitorHandle.get_hidpi_factor();
|
let dpi_factor = MonitorHandle.hidpi_factor();
|
||||||
let location = LogicalPosition::from_physical(
|
let location = LogicalPosition::from_physical(
|
||||||
(motion.x as f64, motion.y as f64),
|
(motion.x as f64, motion.y as f64),
|
||||||
dpi_factor,
|
dpi_factor,
|
||||||
|
@ -99,12 +102,12 @@ impl EventLoop {
|
||||||
android_glue::Event::WindowResized |
|
android_glue::Event::WindowResized |
|
||||||
android_glue::Event::ConfigChanged => {
|
android_glue::Event::ConfigChanged => {
|
||||||
// Activity Orientation changed or resized.
|
// Activity Orientation changed or resized.
|
||||||
let native_window = unsafe { android_glue::get_native_window() };
|
let native_window = unsafe { android_glue::native_window() };
|
||||||
if native_window.is_null() {
|
if native_window.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let dpi_factor = MonitorHandle.get_hidpi_factor();
|
let dpi_factor = MonitorHandle.hidpi_factor();
|
||||||
let physical_size = MonitorHandle.get_dimensions();
|
let physical_size = MonitorHandle.dimensions();
|
||||||
let size = LogicalSize::from_physical(physical_size, dpi_factor);
|
let size = LogicalSize::from_physical(physical_size, dpi_factor);
|
||||||
Some(Event::WindowEvent {
|
Some(Event::WindowEvent {
|
||||||
window_id: RootWindowId(WindowId),
|
window_id: RootWindowId(WindowId),
|
||||||
|
@ -203,10 +206,10 @@ impl fmt::Debug for MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
let monitor_id_proxy = MonitorHandle {
|
let monitor_id_proxy = MonitorHandle {
|
||||||
name: self.get_name(),
|
name: self.name(),
|
||||||
dimensions: self.get_dimensions(),
|
dimensions: self.dimensions(),
|
||||||
position: self.get_position(),
|
position: self.outer_position(),
|
||||||
hidpi_factor: self.get_hidpi_factor(),
|
hidpi_factor: self.hidpi_factor(),
|
||||||
};
|
};
|
||||||
|
|
||||||
monitor_id_proxy.fmt(f)
|
monitor_id_proxy.fmt(f)
|
||||||
|
@ -215,14 +218,14 @@ impl fmt::Debug for MonitorHandle {
|
||||||
|
|
||||||
impl MonitorHandle {
|
impl MonitorHandle {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
Some("Primary".to_string())
|
Some("Primary".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let window = android_glue::get_native_window();
|
let window = android_glue::native_window();
|
||||||
(
|
(
|
||||||
ffi::ANativeWindow_getWidth(window) as f64,
|
ffi::ANativeWindow_getWidth(window) as f64,
|
||||||
ffi::ANativeWindow_getHeight(window) as f64,
|
ffi::ANativeWindow_getHeight(window) as f64,
|
||||||
|
@ -231,13 +234,13 @@ impl MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn outer_position(&self) -> PhysicalPosition {
|
||||||
// Android assumes single screen
|
// Android assumes single screen
|
||||||
(0, 0).into()
|
(0, 0).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
1.0
|
1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,12 +255,12 @@ impl Window {
|
||||||
_: PlatformSpecificWindowBuilderAttributes)
|
_: PlatformSpecificWindowBuilderAttributes)
|
||||||
-> Result<Window, CreationError>
|
-> Result<Window, CreationError>
|
||||||
{
|
{
|
||||||
let native_window = unsafe { android_glue::get_native_window() };
|
let native_window = unsafe { android_glue::native_window() };
|
||||||
if native_window.is_null() {
|
if native_window.is_null() {
|
||||||
return Err(OsError(format!("Android's native window is null")));
|
return Err(OsError(format!("Android's native window is null")));
|
||||||
}
|
}
|
||||||
|
|
||||||
android_glue::set_multitouch(win_attribs.multitouch);
|
android_glue::set_multitouch(true);
|
||||||
|
|
||||||
Ok(Window {
|
Ok(Window {
|
||||||
native_window: native_window as *const _,
|
native_window: native_window as *const _,
|
||||||
|
@ -265,7 +268,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_native_window(&self) -> *const c_void {
|
pub fn native_window(&self) -> *const c_void {
|
||||||
self.native_window
|
self.native_window
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,29 +288,29 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn outer_position(&self) -> Option<LogicalPosition> {
|
||||||
// N/A
|
// N/A
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
pub fn inner_position(&self) -> Option<LogicalPosition> {
|
||||||
// N/A
|
// N/A
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_position(&self, _position: LogicalPosition) {
|
pub fn set_outer_position(&self, _position: LogicalPosition) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,19 +320,19 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn inner_size(&self) -> Option<LogicalSize> {
|
||||||
if self.native_window.is_null() {
|
if self.native_window.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
let physical_size = self.get_current_monitor().get_dimensions();
|
let physical_size = self.current_monitor().dimensions();
|
||||||
Some(LogicalSize::from_physical(physical_size, dpi_factor))
|
Some(LogicalSize::from_physical(physical_size, dpi_factor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
pub fn outer_size(&self) -> Option<LogicalSize> {
|
||||||
self.get_inner_size()
|
self.inner_size()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -338,18 +341,18 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
self.get_current_monitor().get_hidpi_factor()
|
self.current_monitor().hidpi_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor(&self, _: MouseCursor) {
|
pub fn set_cursor_icon(&self, _: CursorIcon) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> {
|
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
|
||||||
Err("Cursor grabbing is not possible on Android.".to_owned())
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -358,8 +361,8 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> {
|
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
Err("Setting cursor position is not possible on Android.".to_owned())
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -369,7 +372,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||||
// N/A
|
// N/A
|
||||||
// Android has single screen maximized apps so nothing to do
|
// Android has single screen maximized apps so nothing to do
|
||||||
None
|
None
|
||||||
|
@ -397,24 +400,24 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_spot(&self, _spot: LogicalPosition) {
|
pub fn set_ime_position(&self, _spot: LogicalPosition) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||||
RootMonitorHandle { inner: MonitorHandle }
|
RootMonitorHandle { inner: MonitorHandle }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
let mut rb = VecDeque::with_capacity(1);
|
let mut rb = VecDeque::with_capacity(1);
|
||||||
rb.push_back(MonitorHandle);
|
rb.push_back(MonitorHandle);
|
||||||
rb
|
rb
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
MonitorHandle
|
MonitorHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,12 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Mutex, Arc};
|
use std::sync::{Mutex, Arc};
|
||||||
|
|
||||||
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
||||||
|
use error::{ExternalError, NotSupportedError};
|
||||||
use window::MonitorHandle as RootMonitorHandle;
|
use window::MonitorHandle as RootMonitorHandle;
|
||||||
|
|
||||||
const DOCUMENT_NAME: &'static str = "#document\0";
|
const DOCUMENT_NAME: &'static str = "#document\0";
|
||||||
|
|
||||||
fn get_hidpi_factor() -> f64 {
|
fn hidpi_factor() -> f64 {
|
||||||
unsafe { ffi::emscripten_get_device_pixel_ratio() as f64 }
|
unsafe { ffi::emscripten_get_device_pixel_ratio() as f64 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +25,8 @@ pub struct PlatformSpecificWindowBuilderAttributes;
|
||||||
unsafe impl Send for PlatformSpecificWindowBuilderAttributes {}
|
unsafe impl Send for PlatformSpecificWindowBuilderAttributes {}
|
||||||
unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {}
|
unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {}
|
||||||
|
|
||||||
|
pub type OsError = std::io::Error;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct DeviceId;
|
pub struct DeviceId;
|
||||||
|
|
||||||
|
@ -41,23 +44,23 @@ pub struct MonitorHandle;
|
||||||
|
|
||||||
impl MonitorHandle {
|
impl MonitorHandle {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
Some("Canvas".to_owned())
|
Some("Canvas".to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn outer_position(&self) -> PhysicalPosition {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
(0, 0).into()
|
(0, 0).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
get_hidpi_factor()
|
hidpi_factor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,14 +116,14 @@ impl EventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
let mut list = VecDeque::with_capacity(1);
|
let mut list = VecDeque::with_capacity(1);
|
||||||
list.push_back(MonitorHandle);
|
list.push_back(MonitorHandle);
|
||||||
list
|
list
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
MonitorHandle
|
MonitorHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +166,7 @@ impl WindowId {
|
||||||
|
|
||||||
pub struct Window2 {
|
pub struct Window2 {
|
||||||
cursor_grabbed: Mutex<bool>,
|
cursor_grabbed: Mutex<bool>,
|
||||||
cursor_hidden: Mutex<bool>,
|
cursor_visible: Mutex<bool>,
|
||||||
is_fullscreen: bool,
|
is_fullscreen: bool,
|
||||||
events: Box<Mutex<VecDeque<::Event>>>,
|
events: Box<Mutex<VecDeque<::Event>>>,
|
||||||
}
|
}
|
||||||
|
@ -208,7 +211,7 @@ extern "C" fn mouse_callback(
|
||||||
|
|
||||||
match event_type {
|
match event_type {
|
||||||
ffi::EMSCRIPTEN_EVENT_MOUSEMOVE => {
|
ffi::EMSCRIPTEN_EVENT_MOUSEMOVE => {
|
||||||
let dpi_factor = get_hidpi_factor();
|
let dpi_factor = hidpi_factor();
|
||||||
let position = LogicalPosition::from_physical(
|
let position = LogicalPosition::from_physical(
|
||||||
((*event).canvasX as f64, (*event).canvasY as f64),
|
((*event).canvasX as f64, (*event).canvasY as f64),
|
||||||
dpi_factor,
|
dpi_factor,
|
||||||
|
@ -328,7 +331,7 @@ extern fn touch_callback(
|
||||||
for touch in 0..(*event).numTouches as usize {
|
for touch in 0..(*event).numTouches as usize {
|
||||||
let touch = (*event).touches[touch];
|
let touch = (*event).touches[touch];
|
||||||
if touch.isChanged == ffi::EM_TRUE {
|
if touch.isChanged == ffi::EM_TRUE {
|
||||||
let dpi_factor = get_hidpi_factor();
|
let dpi_factor = hidpi_factor();
|
||||||
let location = LogicalPosition::from_physical(
|
let location = LogicalPosition::from_physical(
|
||||||
(touch.canvasX as f64, touch.canvasY as f64),
|
(touch.canvasX as f64, touch.canvasY as f64),
|
||||||
dpi_factor,
|
dpi_factor,
|
||||||
|
@ -387,8 +390,8 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
let w = Window2 {
|
let w = Window2 {
|
||||||
cursor_grabbed: Default::default(),
|
cursor_grabbed: Mutex::new(false),
|
||||||
cursor_hidden: Default::default(),
|
cursor_visible: Mutex::new(true),
|
||||||
events: Default::default(),
|
events: Default::default(),
|
||||||
is_fullscreen: attribs.fullscreen.is_some(),
|
is_fullscreen: attribs.fullscreen.is_some(),
|
||||||
};
|
};
|
||||||
|
@ -427,7 +430,7 @@ impl Window {
|
||||||
em_try(ffi::emscripten_set_fullscreenchange_callback(ptr::null(), 0 as *mut c_void, ffi::EM_FALSE, Some(fullscreen_callback)))
|
em_try(ffi::emscripten_set_fullscreenchange_callback(ptr::null(), 0 as *mut c_void, ffi::EM_FALSE, Some(fullscreen_callback)))
|
||||||
.map_err(|e| ::CreationError::OsError(e))?;
|
.map_err(|e| ::CreationError::OsError(e))?;
|
||||||
}
|
}
|
||||||
} else if let Some(size) = attribs.dimensions {
|
} else if let Some(size) = attribs.inner_size {
|
||||||
window.set_inner_size(size);
|
window.set_inner_size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,21 +448,21 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn outer_position(&self) -> Option<LogicalPosition> {
|
||||||
Some((0, 0).into())
|
Some((0, 0).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
pub fn inner_position(&self) -> Option<LogicalPosition> {
|
||||||
Some((0, 0).into())
|
Some((0, 0).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_position(&self, _: LogicalPosition) {
|
pub fn set_outer_position(&self, _: LogicalPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn inner_size(&self) -> Option<LogicalSize> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut width = 0;
|
let mut width = 0;
|
||||||
let mut height = 0;
|
let mut height = 0;
|
||||||
|
@ -470,7 +473,7 @@ impl Window {
|
||||||
{
|
{
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
let logical = LogicalSize::from_physical((width as u32, height as u32), dpi_factor);
|
let logical = LogicalSize::from_physical((width as u32, height as u32), dpi_factor);
|
||||||
Some(logical)
|
Some(logical)
|
||||||
}
|
}
|
||||||
|
@ -478,14 +481,14 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
pub fn outer_size(&self) -> Option<LogicalSize> {
|
||||||
self.get_inner_size()
|
self.inner_size()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_inner_size(&self, size: LogicalSize) {
|
pub fn set_inner_size(&self, size: LogicalSize) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
let physical = PhysicalSize::from_logical(size, dpi_factor);
|
let physical = PhysicalSize::from_logical(size, dpi_factor);
|
||||||
let (width, height): (u32, u32) = physical.into();
|
let (width, height): (u32, u32) = physical.into();
|
||||||
ffi::emscripten_set_element_css_size(
|
ffi::emscripten_set_element_css_size(
|
||||||
|
@ -497,12 +500,12 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,12 +525,12 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor(&self, _cursor: ::MouseCursor) {
|
pub fn set_cursor_icon(&self, _cursor: ::CursorIcon) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
let mut grabbed_lock = self.window.cursor_grabbed.lock().unwrap();
|
let mut grabbed_lock = self.window.cursor_grabbed.lock().unwrap();
|
||||||
if grab == *grabbed_lock { return Ok(()); }
|
if grab == *grabbed_lock { return Ok(()); }
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -554,24 +557,24 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide_cursor(&self, hide: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
let mut hidden_lock = self.window.cursor_hidden.lock().unwrap();
|
let mut visible_lock = self.window.cursor_visible.lock().unwrap();
|
||||||
if hide == *hidden_lock { return; }
|
if visible == *visible_lock { return; }
|
||||||
if hide {
|
if visible {
|
||||||
unsafe { ffi::emscripten_hide_mouse() };
|
|
||||||
} else {
|
|
||||||
show_mouse();
|
show_mouse();
|
||||||
|
} else {
|
||||||
|
unsafe { ffi::emscripten_hide_mouse() };
|
||||||
}
|
}
|
||||||
*hidden_lock = hide;
|
*visible_lock = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
get_hidpi_factor()
|
hidpi_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> {
|
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
Err("Setting cursor position is not possible on Emscripten.".to_owned())
|
Err("Setting cursor position is not possible on Emscripten.".to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +584,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_fullscreen(&self) -> Option<::MonitorHandle> {
|
pub fn fullscreen(&self) -> Option<::MonitorHandle> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,24 +609,24 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_spot(&self, _logical_spot: LogicalPosition) {
|
pub fn set_ime_position(&self, _logical_spot: LogicalPosition) {
|
||||||
// N/A
|
// N/A
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||||
RootMonitorHandle { inner: MonitorHandle }
|
RootMonitorHandle { inner: MonitorHandle }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
let mut list = VecDeque::with_capacity(1);
|
let mut list = VecDeque::with_capacity(1);
|
||||||
list.push_back(MonitorHandle);
|
list.push_back(MonitorHandle);
|
||||||
list
|
list
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
MonitorHandle
|
MonitorHandle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -639,7 +642,7 @@ impl Drop for Window {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Return back to normal cursor state
|
// Return back to normal cursor state
|
||||||
self.hide_cursor(false);
|
self.hide_cursor(false);
|
||||||
self.grab_cursor(false);
|
self.set_cursor_grab(false);
|
||||||
|
|
||||||
// Exit fullscreen if on
|
// Exit fullscreen if on
|
||||||
if self.window.is_fullscreen {
|
if self.window.is_fullscreen {
|
||||||
|
|
|
@ -119,14 +119,14 @@ impl<T: 'static> EventLoop<T> {
|
||||||
EventLoopProxy::new(self.window_target.p.sender_to_clone.clone())
|
EventLoopProxy::new(self.window_target.p.sender_to_clone.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
// guaranteed to be on main thread
|
// guaranteed to be on main thread
|
||||||
unsafe {
|
unsafe {
|
||||||
monitor::uiscreens()
|
monitor::uiscreens()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
// guaranteed to be on main thread
|
// guaranteed to be on main thread
|
||||||
unsafe {
|
unsafe {
|
||||||
monitor::main_uiscreen()
|
monitor::main_uiscreen()
|
||||||
|
@ -140,7 +140,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
// EventLoopExtIOS
|
// EventLoopExtIOS
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub fn get_idiom(&self) -> Idiom {
|
pub fn idiom(&self) -> Idiom {
|
||||||
// guaranteed to be on main thread
|
// guaranteed to be on main thread
|
||||||
unsafe {
|
unsafe {
|
||||||
self::get_idiom()
|
self::get_idiom()
|
||||||
|
@ -331,4 +331,4 @@ impl From<NSOperatingSystemVersion> for Capabilities {
|
||||||
|
|
||||||
Capabilities { supports_safe_area }
|
Capabilities { supports_safe_area }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,8 @@ mod monitor;
|
||||||
mod view;
|
mod view;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
|
pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
|
||||||
pub use self::monitor::MonitorHandle;
|
pub use self::monitor::MonitorHandle;
|
||||||
pub use self::window::{
|
pub use self::window::{
|
||||||
|
@ -99,3 +101,14 @@ impl DeviceId {
|
||||||
|
|
||||||
unsafe impl Send for DeviceId {}
|
unsafe impl Send for DeviceId {}
|
||||||
unsafe impl Sync for DeviceId {}
|
unsafe impl Sync for DeviceId {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum OsError {}
|
||||||
|
|
||||||
|
impl fmt::Display for OsError {
|
||||||
|
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -78,10 +78,10 @@ impl fmt::Debug for MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
let monitor_id_proxy = MonitorHandle {
|
let monitor_id_proxy = MonitorHandle {
|
||||||
name: self.get_name(),
|
name: self.name(),
|
||||||
dimensions: self.get_dimensions(),
|
dimensions: self.dimensions(),
|
||||||
position: self.get_position(),
|
position: self.position(),
|
||||||
hidpi_factor: self.get_hidpi_factor(),
|
hidpi_factor: self.hidpi_factor(),
|
||||||
};
|
};
|
||||||
|
|
||||||
monitor_id_proxy.fmt(f)
|
monitor_id_proxy.fmt(f)
|
||||||
|
@ -99,7 +99,7 @@ impl MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Inner {
|
impl Inner {
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.uiscreen == main_uiscreen().uiscreen {
|
if self.uiscreen == main_uiscreen().uiscreen {
|
||||||
Some("Primary".to_string())
|
Some("Primary".to_string())
|
||||||
|
@ -113,24 +113,24 @@ impl Inner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let bounds: CGRect = msg_send![self.get_uiscreen(), nativeBounds];
|
let bounds: CGRect = msg_send![self.ui_screen(), nativeBounds];
|
||||||
(bounds.size.width as f64, bounds.size.height as f64).into()
|
(bounds.size.width as f64, bounds.size.height as f64).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn position(&self) -> PhysicalPosition {
|
||||||
unsafe {
|
unsafe {
|
||||||
let bounds: CGRect = msg_send![self.get_uiscreen(), nativeBounds];
|
let bounds: CGRect = msg_send![self.ui_screen(), nativeBounds];
|
||||||
(bounds.origin.x as f64, bounds.origin.y as f64).into()
|
(bounds.origin.x as f64, bounds.origin.y as f64).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let scale: CGFloat = msg_send![self.get_uiscreen(), nativeScale];
|
let scale: CGFloat = msg_send![self.ui_screen(), nativeScale];
|
||||||
scale as f64
|
scale as f64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ impl Inner {
|
||||||
|
|
||||||
// MonitorHandleExtIOS
|
// MonitorHandleExtIOS
|
||||||
impl Inner {
|
impl Inner {
|
||||||
pub fn get_uiscreen(&self) -> id {
|
pub fn ui_screen(&self) -> id {
|
||||||
self.uiscreen
|
self.uiscreen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ use platform_impl::platform::window::{PlatformSpecificWindowBuilderAttributes};
|
||||||
unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
|
unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
|
||||||
static mut CLASSES: Option<HashMap<*const Class, &'static Class>> = None;
|
static mut CLASSES: Option<HashMap<*const Class, &'static Class>> = None;
|
||||||
static mut ID: usize = 0;
|
static mut ID: usize = 0;
|
||||||
|
|
||||||
if CLASSES.is_none() {
|
if CLASSES.is_none() {
|
||||||
CLASSES = Some(HashMap::default());
|
CLASSES = Some(HashMap::default());
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ unsafe fn get_window_class() -> &'static Class {
|
||||||
|
|
||||||
// requires main thread
|
// requires main thread
|
||||||
pub unsafe fn create_view(
|
pub unsafe fn create_view(
|
||||||
window_attributes: &WindowAttributes,
|
_window_attributes: &WindowAttributes,
|
||||||
platform_attributes: &PlatformSpecificWindowBuilderAttributes,
|
platform_attributes: &PlatformSpecificWindowBuilderAttributes,
|
||||||
frame: CGRect,
|
frame: CGRect,
|
||||||
) -> id {
|
) -> id {
|
||||||
|
@ -265,9 +265,7 @@ pub unsafe fn create_view(
|
||||||
assert!(!view.is_null(), "Failed to create `UIView` instance");
|
assert!(!view.is_null(), "Failed to create `UIView` instance");
|
||||||
let view: id = msg_send![view, initWithFrame:frame];
|
let view: id = msg_send![view, initWithFrame:frame];
|
||||||
assert!(!view.is_null(), "Failed to initialize `UIView` instance");
|
assert!(!view.is_null(), "Failed to initialize `UIView` instance");
|
||||||
if window_attributes.multitouch {
|
let () = msg_send![view, setMultipleTouchEnabled:YES];
|
||||||
let () = msg_send![view, setMultipleTouchEnabled:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
view
|
view
|
||||||
}
|
}
|
||||||
|
@ -318,7 +316,7 @@ pub unsafe fn create_window(
|
||||||
let () = msg_send![window, setContentScaleFactor:hidpi_factor as CGFloat];
|
let () = msg_send![window, setContentScaleFactor:hidpi_factor as CGFloat];
|
||||||
}
|
}
|
||||||
if let &Some(ref monitor) = &window_attributes.fullscreen {
|
if let &Some(ref monitor) = &window_attributes.fullscreen {
|
||||||
let () = msg_send![window, setScreen:monitor.get_uiscreen()];
|
let () = msg_send![window, setScreen:monitor.ui_screen()];
|
||||||
}
|
}
|
||||||
|
|
||||||
window
|
window
|
||||||
|
|
|
@ -6,12 +6,12 @@ use std::{
|
||||||
use objc::runtime::{Class, NO, Object, YES};
|
use objc::runtime::{Class, NO, Object, YES};
|
||||||
|
|
||||||
use dpi::{self, LogicalPosition, LogicalSize};
|
use dpi::{self, LogicalPosition, LogicalSize};
|
||||||
|
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||||
use icon::Icon;
|
use icon::Icon;
|
||||||
use monitor::MonitorHandle as RootMonitorHandle;
|
use monitor::MonitorHandle as RootMonitorHandle;
|
||||||
use platform::ios::{MonitorHandleExtIOS, ValidOrientations};
|
use platform::ios::{MonitorHandleExtIOS, ValidOrientations};
|
||||||
use window::{
|
use window::{
|
||||||
CreationError,
|
CursorIcon,
|
||||||
MouseCursor,
|
|
||||||
WindowAttributes,
|
WindowAttributes,
|
||||||
};
|
};
|
||||||
use platform_impl::{
|
use platform_impl::{
|
||||||
|
@ -56,15 +56,14 @@ impl Inner {
|
||||||
debug!("`Window::set_title` is ignored on iOS")
|
debug!("`Window::set_title` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(&self) {
|
pub fn set_visible(&self, visible: bool) {
|
||||||
unsafe {
|
match visible {
|
||||||
let () = msg_send![self.window, setHidden:NO];
|
true => unsafe {
|
||||||
}
|
let () = msg_send![self.window, setHidden:NO];
|
||||||
}
|
},
|
||||||
|
false => unsafe {
|
||||||
pub fn hide(&self) {
|
let () = msg_send![self.window, setHidden:YES];
|
||||||
unsafe {
|
},
|
||||||
let () = msg_send![self.window, setHidden:YES];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,28 +72,28 @@ impl Inner {
|
||||||
let () = msg_send![self.view, setNeedsDisplay];
|
let () = msg_send![self.view, setNeedsDisplay];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let safe_area = self.safe_area_screen_space();
|
let safe_area = self.safe_area_screen_space();
|
||||||
Some(LogicalPosition {
|
Ok(LogicalPosition {
|
||||||
x: safe_area.origin.x,
|
x: safe_area.origin.x,
|
||||||
y: safe_area.origin.y,
|
y: safe_area.origin.y,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let screen_frame = self.screen_frame();
|
let screen_frame = self.screen_frame();
|
||||||
Some(LogicalPosition {
|
Ok(LogicalPosition {
|
||||||
x: screen_frame.origin.x,
|
x: screen_frame.origin.x,
|
||||||
y: screen_frame.origin.y,
|
y: screen_frame.origin.y,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&self, position: LogicalPosition) {
|
pub fn set_outer_position(&self, position: LogicalPosition) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let screen_frame = self.screen_frame();
|
let screen_frame = self.screen_frame();
|
||||||
let new_screen_frame = CGRect {
|
let new_screen_frame = CGRect {
|
||||||
|
@ -109,23 +108,23 @@ impl Inner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn inner_size(&self) -> LogicalSize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let safe_area = self.safe_area_screen_space();
|
let safe_area = self.safe_area_screen_space();
|
||||||
Some(LogicalSize {
|
LogicalSize {
|
||||||
width: safe_area.size.width,
|
width: safe_area.size.width,
|
||||||
height: safe_area.size.height,
|
height: safe_area.size.height,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
pub fn outer_size(&self) -> LogicalSize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let screen_frame = self.screen_frame();
|
let screen_frame = self.screen_frame();
|
||||||
Some(LogicalSize {
|
LogicalSize {
|
||||||
width: screen_frame.size.width,
|
width: screen_frame.size.width,
|
||||||
height: screen_frame.size.height,
|
height: screen_frame.size.height,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,39 +132,39 @@ impl Inner {
|
||||||
unimplemented!("not clear what `Window::set_inner_size` means on iOS");
|
unimplemented!("not clear what `Window::set_inner_size` means on iOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||||
warn!("`Window::set_min_dimensions` is ignored on iOS")
|
warn!("`Window::set_min_inner_size` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||||
warn!("`Window::set_max_dimensions` is ignored on iOS")
|
warn!("`Window::set_max_inner_size` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_resizable(&self, _resizable: bool) {
|
pub fn set_resizable(&self, _resizable: bool) {
|
||||||
warn!("`Window::set_resizable` is ignored on iOS")
|
warn!("`Window::set_resizable` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let hidpi: CGFloat = msg_send![self.view, contentScaleFactor];
|
let hidpi: CGFloat = msg_send![self.view, contentScaleFactor];
|
||||||
hidpi as _
|
hidpi as _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cursor(&self, _cursor: MouseCursor) {
|
pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
|
||||||
debug!("`Window::set_cursor` ignored on iOS")
|
debug!("`Window::set_cursor_icon` ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> {
|
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
Err("Setting cursor position is not possible on iOS.".to_owned())
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> {
|
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
|
||||||
Err("Cursor grabbing is not possible on iOS.".to_owned())
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hide_cursor(&self, _hide: bool) {
|
pub fn set_cursor_visible(&self, _visible: bool) {
|
||||||
debug!("`Window::hide_cursor` is ignored on iOS")
|
debug!("`Window::set_cursor_visible` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_maximized(&self, _maximized: bool) {
|
pub fn set_maximized(&self, _maximized: bool) {
|
||||||
|
@ -176,7 +175,7 @@ impl Inner {
|
||||||
unsafe {
|
unsafe {
|
||||||
match monitor {
|
match monitor {
|
||||||
Some(monitor) => {
|
Some(monitor) => {
|
||||||
let uiscreen = monitor.get_uiscreen() as id;
|
let uiscreen = monitor.ui_screen() as id;
|
||||||
let current: id = msg_send![self.window, screen];
|
let current: id = msg_send![self.window, screen];
|
||||||
let bounds: CGRect = msg_send![uiscreen, bounds];
|
let bounds: CGRect = msg_send![uiscreen, bounds];
|
||||||
|
|
||||||
|
@ -191,10 +190,10 @@ impl Inner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let monitor = self.get_current_monitor();
|
let monitor = self.current_monitor();
|
||||||
let uiscreen = monitor.inner.get_uiscreen();
|
let uiscreen = monitor.inner.ui_screen();
|
||||||
let screen_space_bounds = self.screen_frame();
|
let screen_space_bounds = self.screen_frame();
|
||||||
let screen_bounds: CGRect = msg_send![uiscreen, bounds];
|
let screen_bounds: CGRect = msg_send![uiscreen, bounds];
|
||||||
|
|
||||||
|
@ -226,24 +225,24 @@ impl Inner {
|
||||||
warn!("`Window::set_window_icon` is ignored on iOS")
|
warn!("`Window::set_window_icon` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ime_spot(&self, _position: LogicalPosition) {
|
pub fn set_ime_position(&self, _position: LogicalPosition) {
|
||||||
warn!("`Window::set_ime_spot` is ignored on iOS")
|
warn!("`Window::set_ime_position` is ignored on iOS")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||||
unsafe {
|
unsafe {
|
||||||
let uiscreen: id = msg_send![self.window, screen];
|
let uiscreen: id = msg_send![self.window, screen];
|
||||||
RootMonitorHandle { inner: MonitorHandle::retained_new(uiscreen) }
|
RootMonitorHandle { inner: MonitorHandle::retained_new(uiscreen) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
unsafe {
|
unsafe {
|
||||||
monitor::uiscreens()
|
monitor::uiscreens()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
unsafe {
|
unsafe {
|
||||||
monitor::main_uiscreen()
|
monitor::main_uiscreen()
|
||||||
}
|
}
|
||||||
|
@ -294,12 +293,12 @@ impl Window {
|
||||||
event_loop: &EventLoopWindowTarget<T>,
|
event_loop: &EventLoopWindowTarget<T>,
|
||||||
window_attributes: WindowAttributes,
|
window_attributes: WindowAttributes,
|
||||||
platform_attributes: PlatformSpecificWindowBuilderAttributes,
|
platform_attributes: PlatformSpecificWindowBuilderAttributes,
|
||||||
) -> Result<Window, CreationError> {
|
) -> Result<Window, RootOsError> {
|
||||||
if let Some(_) = window_attributes.min_dimensions {
|
if let Some(_) = window_attributes.min_inner_size {
|
||||||
warn!("`WindowAttributes::min_dimensions` is ignored on iOS");
|
warn!("`WindowAttributes::min_inner_size` is ignored on iOS");
|
||||||
}
|
}
|
||||||
if let Some(_) = window_attributes.max_dimensions {
|
if let Some(_) = window_attributes.max_inner_size {
|
||||||
warn!("`WindowAttributes::max_dimensions` is ignored on iOS");
|
warn!("`WindowAttributes::max_inner_size` is ignored on iOS");
|
||||||
}
|
}
|
||||||
if window_attributes.always_on_top {
|
if window_attributes.always_on_top {
|
||||||
warn!("`WindowAttributes::always_on_top` is unsupported on iOS");
|
warn!("`WindowAttributes::always_on_top` is unsupported on iOS");
|
||||||
|
@ -309,11 +308,11 @@ impl Window {
|
||||||
unsafe {
|
unsafe {
|
||||||
let screen = window_attributes.fullscreen
|
let screen = window_attributes.fullscreen
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|screen| screen.get_uiscreen() as _)
|
.map(|screen| screen.ui_screen() as _)
|
||||||
.unwrap_or_else(|| monitor::main_uiscreen().get_uiscreen());
|
.unwrap_or_else(|| monitor::main_uiscreen().ui_screen());
|
||||||
let screen_bounds: CGRect = msg_send![screen, bounds];
|
let screen_bounds: CGRect = msg_send![screen, bounds];
|
||||||
|
|
||||||
let frame = match window_attributes.dimensions {
|
let frame = match window_attributes.inner_size {
|
||||||
Some(dim) => CGRect {
|
Some(dim) => CGRect {
|
||||||
origin: screen_bounds.origin,
|
origin: screen_bounds.origin,
|
||||||
size: CGSize { width: dim.width, height: dim.height },
|
size: CGSize { width: dim.width, height: dim.height },
|
||||||
|
@ -343,9 +342,9 @@ impl Window {
|
||||||
|
|
||||||
// WindowExtIOS
|
// WindowExtIOS
|
||||||
impl Inner {
|
impl Inner {
|
||||||
pub fn get_uiwindow(&self) -> id { self.window }
|
pub fn ui_window(&self) -> id { self.window }
|
||||||
pub fn get_uiviewcontroller(&self) -> id { self.view_controller }
|
pub fn ui_view_controller(&self) -> id { self.view_controller }
|
||||||
pub fn get_uiview(&self) -> id { self.view }
|
pub fn ui_view(&self) -> id { self.view }
|
||||||
|
|
||||||
pub fn set_hidpi_factor(&self, hidpi_factor: f64) {
|
pub fn set_hidpi_factor(&self, hidpi_factor: f64) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
|
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::{env, mem};
|
use std::{env, mem, fmt};
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::os::raw::*;
|
use std::os::raw::*;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -11,10 +11,11 @@ use sctk::reexports::client::ConnectError;
|
||||||
|
|
||||||
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
||||||
use icon::Icon;
|
use icon::Icon;
|
||||||
|
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||||
use event::Event;
|
use event::Event;
|
||||||
use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
|
use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
|
||||||
use monitor::MonitorHandle as RootMonitorHandle;
|
use monitor::MonitorHandle as RootMonitorHandle;
|
||||||
use window::{WindowAttributes, CreationError, MouseCursor};
|
use window::{WindowAttributes, CursorIcon};
|
||||||
use self::x11::{XConnection, XError};
|
use self::x11::{XConnection, XError};
|
||||||
use self::x11::ffi::XVisualInfo;
|
use self::x11::ffi::XVisualInfo;
|
||||||
pub use self::x11::XNotSupported;
|
pub use self::x11::XNotSupported;
|
||||||
|
@ -51,6 +52,21 @@ lazy_static!(
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum OsError {
|
||||||
|
XError(XError),
|
||||||
|
XMisc(&'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for OsError {
|
||||||
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
match self {
|
||||||
|
OsError::XError(e) => formatter.pad(&e.description),
|
||||||
|
OsError::XMisc(e) => formatter.pad(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum Window {
|
pub enum Window {
|
||||||
X(x11::Window),
|
X(x11::Window),
|
||||||
Wayland(wayland::Window),
|
Wayland(wayland::Window),
|
||||||
|
@ -88,42 +104,42 @@ pub enum MonitorHandle {
|
||||||
|
|
||||||
impl MonitorHandle {
|
impl MonitorHandle {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
match self {
|
match self {
|
||||||
&MonitorHandle::X(ref m) => m.get_name(),
|
&MonitorHandle::X(ref m) => m.name(),
|
||||||
&MonitorHandle::Wayland(ref m) => m.get_name(),
|
&MonitorHandle::Wayland(ref m) => m.name(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_native_identifier(&self) -> u32 {
|
pub fn native_identifier(&self) -> u32 {
|
||||||
match self {
|
match self {
|
||||||
&MonitorHandle::X(ref m) => m.get_native_identifier(),
|
&MonitorHandle::X(ref m) => m.native_identifier(),
|
||||||
&MonitorHandle::Wayland(ref m) => m.get_native_identifier(),
|
&MonitorHandle::Wayland(ref m) => m.native_identifier(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
match self {
|
match self {
|
||||||
&MonitorHandle::X(ref m) => m.get_dimensions(),
|
&MonitorHandle::X(ref m) => m.dimensions(),
|
||||||
&MonitorHandle::Wayland(ref m) => m.get_dimensions(),
|
&MonitorHandle::Wayland(ref m) => m.dimensions(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn position(&self) -> PhysicalPosition {
|
||||||
match self {
|
match self {
|
||||||
&MonitorHandle::X(ref m) => m.get_position(),
|
&MonitorHandle::X(ref m) => m.position(),
|
||||||
&MonitorHandle::Wayland(ref m) => m.get_position(),
|
&MonitorHandle::Wayland(ref m) => m.position(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
match self {
|
match self {
|
||||||
&MonitorHandle::X(ref m) => m.get_hidpi_factor(),
|
&MonitorHandle::X(ref m) => m.hidpi_factor(),
|
||||||
&MonitorHandle::Wayland(ref m) => m.get_hidpi_factor() as f64,
|
&MonitorHandle::Wayland(ref m) => m.hidpi_factor() as f64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +150,7 @@ impl Window {
|
||||||
window_target: &EventLoopWindowTarget<T>,
|
window_target: &EventLoopWindowTarget<T>,
|
||||||
attribs: WindowAttributes,
|
attribs: WindowAttributes,
|
||||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||||
) -> Result<Self, CreationError> {
|
) -> Result<Self, RootOsError> {
|
||||||
match *window_target {
|
match *window_target {
|
||||||
EventLoopWindowTarget::Wayland(ref window_target) => {
|
EventLoopWindowTarget::Wayland(ref window_target) => {
|
||||||
wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland)
|
wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland)
|
||||||
|
@ -162,58 +178,50 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn show(&self) {
|
pub fn set_visible(&self, visible: bool) {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.show(),
|
&Window::X(ref w) => w.set_visible(visible),
|
||||||
&Window::Wayland(ref w) => w.show(),
|
&Window::Wayland(ref w) => w.set_visible(visible),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide(&self) {
|
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.hide(),
|
&Window::X(ref w) => w.outer_position(),
|
||||||
&Window::Wayland(ref w) => w.hide(),
|
&Window::Wayland(ref w) => w.outer_position(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.get_position(),
|
&Window::X(ref m) => m.inner_position(),
|
||||||
&Window::Wayland(ref w) => w.get_position(),
|
&Window::Wayland(ref m) => m.inner_position(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
pub fn set_outer_position(&self, position: LogicalPosition) {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref m) => m.get_inner_position(),
|
&Window::X(ref w) => w.set_outer_position(position),
|
||||||
&Window::Wayland(ref m) => m.get_inner_position(),
|
&Window::Wayland(ref w) => w.set_outer_position(position),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_position(&self, position: LogicalPosition) {
|
pub fn inner_size(&self) -> LogicalSize {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.set_position(position),
|
&Window::X(ref w) => w.inner_size(),
|
||||||
&Window::Wayland(ref w) => w.set_position(position),
|
&Window::Wayland(ref w) => w.inner_size(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn outer_size(&self) -> LogicalSize {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.get_inner_size(),
|
&Window::X(ref w) => w.outer_size(),
|
||||||
&Window::Wayland(ref w) => w.get_inner_size(),
|
&Window::Wayland(ref w) => w.outer_size(),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
|
||||||
match self {
|
|
||||||
&Window::X(ref w) => w.get_outer_size(),
|
|
||||||
&Window::Wayland(ref w) => w.get_outer_size(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,18 +234,18 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.set_min_dimensions(dimensions),
|
&Window::X(ref w) => w.set_min_inner_size(dimensions),
|
||||||
&Window::Wayland(ref w) => w.set_min_dimensions(dimensions),
|
&Window::Wayland(ref w) => w.set_min_inner_size(dimensions),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.set_max_dimensions(dimensions),
|
&Window::X(ref w) => w.set_max_inner_size(dimensions),
|
||||||
&Window::Wayland(ref w) => w.set_max_dimensions(dimensions),
|
&Window::Wayland(ref w) => w.set_max_inner_size(dimensions),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,39 +258,39 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.set_cursor(cursor),
|
&Window::X(ref w) => w.set_cursor_icon(cursor),
|
||||||
&Window::Wayland(ref w) => w.set_cursor(cursor)
|
&Window::Wayland(ref w) => w.set_cursor_icon(cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref window) => window.grab_cursor(grab),
|
&Window::X(ref window) => window.set_cursor_grab(grab),
|
||||||
&Window::Wayland(ref window) => window.grab_cursor(grab),
|
&Window::Wayland(ref window) => window.set_cursor_grab(grab),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide_cursor(&self, hide: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref window) => window.hide_cursor(hide),
|
&Window::X(ref window) => window.set_cursor_visible(visible),
|
||||||
&Window::Wayland(ref window) => window.hide_cursor(hide),
|
&Window::Wayland(ref window) => window.set_cursor_visible(visible),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.get_hidpi_factor(),
|
&Window::X(ref w) => w.hidpi_factor(),
|
||||||
&Window::Wayland(ref w) => w.hidpi_factor() as f64,
|
&Window::Wayland(ref w) => w.hidpi_factor() as f64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
|
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.set_cursor_position(position),
|
&Window::X(ref w) => w.set_cursor_position(position),
|
||||||
&Window::Wayland(ref w) => w.set_cursor_position(position),
|
&Window::Wayland(ref w) => w.set_cursor_position(position),
|
||||||
|
@ -298,10 +306,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.get_fullscreen(),
|
&Window::X(ref w) => w.fullscreen(),
|
||||||
&Window::Wayland(ref w) => w.get_fullscreen()
|
&Window::Wayland(ref w) => w.fullscreen()
|
||||||
.map(|monitor_id| RootMonitorHandle { inner: MonitorHandle::Wayland(monitor_id) })
|
.map(|monitor_id| RootMonitorHandle { inner: MonitorHandle::Wayland(monitor_id) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,9 +347,9 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_spot(&self, position: LogicalPosition) {
|
pub fn set_ime_position(&self, position: LogicalPosition) {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref w) => w.set_ime_spot(position),
|
&Window::X(ref w) => w.set_ime_position(position),
|
||||||
&Window::Wayland(_) => (),
|
&Window::Wayland(_) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,21 +363,21 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.get_current_monitor()) },
|
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.current_monitor()) },
|
||||||
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.get_current_monitor()) },
|
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.current_monitor()) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref window) => window.get_available_monitors()
|
&Window::X(ref window) => window.available_monitors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(MonitorHandle::X)
|
.map(MonitorHandle::X)
|
||||||
.collect(),
|
.collect(),
|
||||||
&Window::Wayland(ref window) => window.get_available_monitors()
|
&Window::Wayland(ref window) => window.available_monitors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(MonitorHandle::Wayland)
|
.map(MonitorHandle::Wayland)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -377,10 +385,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
match self {
|
match self {
|
||||||
&Window::X(ref window) => MonitorHandle::X(window.get_primary_monitor()),
|
&Window::X(ref window) => MonitorHandle::X(window.primary_monitor()),
|
||||||
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.get_primary_monitor()),
|
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.primary_monitor()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,16 +489,16 @@ impl<T:'static> EventLoop<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
match *self {
|
match *self {
|
||||||
EventLoop::Wayland(ref evlp) => evlp
|
EventLoop::Wayland(ref evlp) => evlp
|
||||||
.get_available_monitors()
|
.available_monitors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(MonitorHandle::Wayland)
|
.map(MonitorHandle::Wayland)
|
||||||
.collect(),
|
.collect(),
|
||||||
EventLoop::X(ref evlp) => evlp
|
EventLoop::X(ref evlp) => evlp
|
||||||
.x_connection()
|
.x_connection()
|
||||||
.get_available_monitors()
|
.available_monitors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(MonitorHandle::X)
|
.map(MonitorHandle::X)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -498,10 +506,10 @@ impl<T:'static> EventLoop<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
match *self {
|
match *self {
|
||||||
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.get_primary_monitor()),
|
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.primary_monitor()),
|
||||||
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().get_primary_monitor()),
|
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().primary_monitor()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,4 +582,4 @@ fn sticky_exit_callback<T, F>(
|
||||||
};
|
};
|
||||||
// user callback
|
// user callback
|
||||||
callback(evt, target, cf)
|
callback(evt, target, cf)
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,15 +296,15 @@ impl<T: 'static> EventLoop<T> {
|
||||||
callback(::event::Event::LoopDestroyed, &self.window_target, &mut control_flow);
|
callback(::event::Event::LoopDestroyed, &self.window_target, &mut control_flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
get_primary_monitor(&self.outputs)
|
primary_monitor(&self.outputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
get_available_monitors(&self.outputs)
|
available_monitors(&self.outputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_display(&self) -> &Display {
|
pub fn display(&self) -> &Display {
|
||||||
&*self.display
|
&*self.display
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,11 +532,11 @@ impl fmt::Debug for MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
let monitor_id_proxy = MonitorHandle {
|
let monitor_id_proxy = MonitorHandle {
|
||||||
name: self.get_name(),
|
name: self.name(),
|
||||||
native_identifier: self.get_native_identifier(),
|
native_identifier: self.native_identifier(),
|
||||||
dimensions: self.get_dimensions(),
|
dimensions: self.dimensions(),
|
||||||
position: self.get_position(),
|
position: self.position(),
|
||||||
hidpi_factor: self.get_hidpi_factor(),
|
hidpi_factor: self.hidpi_factor(),
|
||||||
};
|
};
|
||||||
|
|
||||||
monitor_id_proxy.fmt(f)
|
monitor_id_proxy.fmt(f)
|
||||||
|
@ -544,18 +544,18 @@ impl fmt::Debug for MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitorHandle {
|
impl MonitorHandle {
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
self.mgr.with_info(&self.proxy, |_, info| {
|
self.mgr.with_info(&self.proxy, |_, info| {
|
||||||
format!("{} ({})", info.model, info.make)
|
format!("{} ({})", info.model, info.make)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_native_identifier(&self) -> u32 {
|
pub fn native_identifier(&self) -> u32 {
|
||||||
self.mgr.with_info(&self.proxy, |id, _| id).unwrap_or(0)
|
self.mgr.with_info(&self.proxy, |id, _| id).unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
match self.mgr.with_info(&self.proxy, |_, info| {
|
match self.mgr.with_info(&self.proxy, |_, info| {
|
||||||
info.modes
|
info.modes
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -567,7 +567,7 @@ impl MonitorHandle {
|
||||||
}.into()
|
}.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn position(&self) -> PhysicalPosition {
|
||||||
self.mgr
|
self.mgr
|
||||||
.with_info(&self.proxy, |_, info| info.location)
|
.with_info(&self.proxy, |_, info| info.location)
|
||||||
.unwrap_or((0, 0))
|
.unwrap_or((0, 0))
|
||||||
|
@ -575,14 +575,14 @@ impl MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> i32 {
|
pub fn hidpi_factor(&self) -> i32 {
|
||||||
self.mgr
|
self.mgr
|
||||||
.with_info(&self.proxy, |_, info| info.scale_factor)
|
.with_info(&self.proxy, |_, info| info.scale_factor)
|
||||||
.unwrap_or(1)
|
.unwrap_or(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
|
pub fn primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
|
||||||
outputs.with_all(|list| {
|
outputs.with_all(|list| {
|
||||||
if let Some(&(_, ref proxy, _)) = list.first() {
|
if let Some(&(_, ref proxy, _)) = list.first() {
|
||||||
MonitorHandle {
|
MonitorHandle {
|
||||||
|
@ -595,7 +595,7 @@ pub fn get_primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(outputs: &OutputMgr) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(outputs: &OutputMgr) -> VecDeque<MonitorHandle> {
|
||||||
outputs.with_all(|list| {
|
outputs.with_all(|list| {
|
||||||
list.iter()
|
list.iter()
|
||||||
.map(|&(_, ref proxy, _)| MonitorHandle {
|
.map(|&(_, ref proxy, _)| MonitorHandle {
|
||||||
|
|
|
@ -2,9 +2,10 @@ use std::collections::VecDeque;
|
||||||
use std::sync::{Arc, Mutex, Weak};
|
use std::sync::{Arc, Mutex, Weak};
|
||||||
|
|
||||||
use dpi::{LogicalPosition, LogicalSize};
|
use dpi::{LogicalPosition, LogicalSize};
|
||||||
|
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||||
use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
|
use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
|
||||||
use monitor::MonitorHandle as RootMonitorHandle;
|
use monitor::MonitorHandle as RootMonitorHandle;
|
||||||
use window::{CreationError, WindowAttributes, MouseCursor};
|
use window::{WindowAttributes, CursorIcon};
|
||||||
|
|
||||||
use sctk::surface::{get_dpi_factor, get_outputs};
|
use sctk::surface::{get_dpi_factor, get_outputs};
|
||||||
use sctk::window::{ConceptFrame, Event as WEvent, State as WState, Window as SWindow, Theme};
|
use sctk::window::{ConceptFrame, Event as WEvent, State as WState, Window as SWindow, Theme};
|
||||||
|
@ -13,7 +14,7 @@ use sctk::reexports::client::protocol::{wl_seat, wl_surface};
|
||||||
use sctk::output::OutputMgr;
|
use sctk::output::OutputMgr;
|
||||||
|
|
||||||
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
|
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
|
||||||
use platform_impl::platform::wayland::event_loop::{get_available_monitors, get_primary_monitor};
|
use platform_impl::platform::wayland::event_loop::{available_monitors, primary_monitor};
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
surface: wl_surface::WlSurface,
|
surface: wl_surface::WlSurface,
|
||||||
|
@ -28,8 +29,8 @@ pub struct Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> {
|
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, RootOsError> {
|
||||||
let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600));
|
let (width, height) = attributes.inner_size.map(Into::into).unwrap_or((800, 600));
|
||||||
// Create the window
|
// Create the window
|
||||||
let size = Arc::new(Mutex::new((width, height)));
|
let size = Arc::new(Mutex::new((width, height)));
|
||||||
let fullscreen = Arc::new(Mutex::new(false));
|
let fullscreen = Arc::new(Mutex::new(false));
|
||||||
|
@ -109,8 +110,8 @@ impl Window {
|
||||||
frame.set_title(attributes.title);
|
frame.set_title(attributes.title);
|
||||||
|
|
||||||
// min-max dimensions
|
// min-max dimensions
|
||||||
frame.set_min_size(attributes.min_dimensions.map(Into::into));
|
frame.set_min_size(attributes.min_inner_size.map(Into::into));
|
||||||
frame.set_max_size(attributes.max_dimensions.map(Into::into));
|
frame.set_max_size(attributes.max_inner_size.map(Into::into));
|
||||||
|
|
||||||
let kill_switch = Arc::new(Mutex::new(false));
|
let kill_switch = Arc::new(Mutex::new(false));
|
||||||
let need_frame_refresh = Arc::new(Mutex::new(true));
|
let need_frame_refresh = Arc::new(Mutex::new(true));
|
||||||
|
@ -154,35 +155,27 @@ impl Window {
|
||||||
self.frame.lock().unwrap().set_title(title.into());
|
self.frame.lock().unwrap().set_title(title.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
pub fn set_visible(&self, _visible: bool) {
|
||||||
pub fn show(&self) {
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide(&self) {
|
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
// TODO
|
Err(NotSupportedError::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
// Not possible with wayland
|
Err(NotSupportedError::new())
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
pub fn set_outer_position(&self, _pos: LogicalPosition) {
|
||||||
// Not possible with wayland
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_position(&self, _pos: LogicalPosition) {
|
|
||||||
// Not possible with wayland
|
// Not possible with wayland
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn inner_size(&self) -> LogicalSize {
|
||||||
Some(self.size.lock().unwrap().clone().into())
|
self.size.lock().unwrap().clone().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_redraw(&self) {
|
pub fn request_redraw(&self) {
|
||||||
|
@ -190,10 +183,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
pub fn outer_size(&self) -> LogicalSize {
|
||||||
let (w, h) = self.size.lock().unwrap().clone();
|
let (w, h) = self.size.lock().unwrap().clone();
|
||||||
// let (w, h) = super::wayland_window::add_borders(w as i32, h as i32);
|
// let (w, h) = super::wayland_window::add_borders(w as i32, h as i32);
|
||||||
Some((w, h).into())
|
(w, h).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -205,12 +198,12 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||||
self.frame.lock().unwrap().set_min_size(dimensions.map(Into::into));
|
self.frame.lock().unwrap().set_min_size(dimensions.map(Into::into));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||||
self.frame.lock().unwrap().set_max_size(dimensions.map(Into::into));
|
self.frame.lock().unwrap().set_max_size(dimensions.map(Into::into));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,9 +230,9 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fullscreen(&self) -> Option<MonitorHandle> {
|
pub fn fullscreen(&self) -> Option<MonitorHandle> {
|
||||||
if *(self.fullscreen.lock().unwrap()) {
|
if *(self.fullscreen.lock().unwrap()) {
|
||||||
Some(self.get_current_monitor())
|
Some(self.current_monitor())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -265,34 +258,34 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor(&self, _cursor: MouseCursor) {
|
pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide_cursor(&self, _hide: bool) {
|
pub fn set_cursor_visible(&self, _visible: bool) {
|
||||||
// TODO: This isn't possible on Wayland yet
|
// TODO: This isn't possible on Wayland yet
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> {
|
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
|
||||||
Err("Cursor grabbing is not yet possible on Wayland.".to_owned())
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), String> {
|
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
Err("Setting the cursor position is not yet possible on Wayland.".to_owned())
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_display(&self) -> &Display {
|
pub fn display(&self) -> &Display {
|
||||||
&*self.display
|
&*self.display
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_surface(&self) -> &wl_surface::WlSurface {
|
pub fn surface(&self) -> &wl_surface::WlSurface {
|
||||||
&self.surface
|
&self.surface
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_monitor(&self) -> MonitorHandle {
|
pub fn current_monitor(&self) -> MonitorHandle {
|
||||||
let output = get_outputs(&self.surface).last().unwrap().clone();
|
let output = get_outputs(&self.surface).last().unwrap().clone();
|
||||||
MonitorHandle {
|
MonitorHandle {
|
||||||
proxy: output,
|
proxy: output,
|
||||||
|
@ -300,12 +293,12 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
get_available_monitors(&self.outputs)
|
available_monitors(&self.outputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
get_primary_monitor(&self.outputs)
|
primary_monitor(&self.outputs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,7 +270,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
let new_inner_size = (xev.width as u32, xev.height as u32);
|
let new_inner_size = (xev.width as u32, xev.height as u32);
|
||||||
let new_inner_position = (xev.x as i32, xev.y as i32);
|
let new_inner_position = (xev.x as i32, xev.y as i32);
|
||||||
|
|
||||||
let mut monitor = window.get_current_monitor(); // This must be done *before* locking!
|
let mut monitor = window.current_monitor(); // This must be done *before* locking!
|
||||||
let mut shared_state_lock = window.shared_state.lock();
|
let mut shared_state_lock = window.shared_state.lock();
|
||||||
|
|
||||||
let (mut resized, moved) = {
|
let (mut resized, moved) = {
|
||||||
|
@ -534,10 +534,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
let device_id = mkdid(xev.deviceid);
|
let device_id = mkdid(xev.deviceid);
|
||||||
if (xev.flags & ffi::XIPointerEmulated) != 0 {
|
if (xev.flags & ffi::XIPointerEmulated) != 0 {
|
||||||
// Deliver multi-touch events instead of emulated mouse events.
|
// Deliver multi-touch events instead of emulated mouse events.
|
||||||
let return_now = self
|
return;
|
||||||
.with_window(xev.event, |window| window.multitouch)
|
|
||||||
.unwrap_or(true);
|
|
||||||
if return_now { return; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let modifiers = ModifiersState::from(xev.mods);
|
let modifiers = ModifiersState::from(xev.mods);
|
||||||
|
@ -622,7 +619,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
});
|
});
|
||||||
if cursor_moved == Some(true) {
|
if cursor_moved == Some(true) {
|
||||||
let dpi_factor = self.with_window(xev.event, |window| {
|
let dpi_factor = self.with_window(xev.event, |window| {
|
||||||
window.get_hidpi_factor()
|
window.hidpi_factor()
|
||||||
});
|
});
|
||||||
if let Some(dpi_factor) = dpi_factor {
|
if let Some(dpi_factor) = dpi_factor {
|
||||||
let position = LogicalPosition::from_physical(
|
let position = LogicalPosition::from_physical(
|
||||||
|
@ -721,7 +718,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(dpi_factor) = self.with_window(xev.event, |window| {
|
if let Some(dpi_factor) = self.with_window(xev.event, |window| {
|
||||||
window.get_hidpi_factor()
|
window.hidpi_factor()
|
||||||
}) {
|
}) {
|
||||||
let position = LogicalPosition::from_physical(
|
let position = LogicalPosition::from_physical(
|
||||||
(xev.event_x as f64, xev.event_y as f64),
|
(xev.event_x as f64, xev.event_y as f64),
|
||||||
|
@ -767,7 +764,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) };
|
let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) };
|
||||||
|
|
||||||
let dpi_factor = match self.with_window(xev.event, |window| {
|
let dpi_factor = match self.with_window(xev.event, |window| {
|
||||||
window.get_hidpi_factor()
|
window.hidpi_factor()
|
||||||
}) {
|
}) {
|
||||||
Some(dpi_factor) => dpi_factor,
|
Some(dpi_factor) => dpi_factor,
|
||||||
None => return,
|
None => return,
|
||||||
|
@ -825,7 +822,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
let dpi_factor = self.with_window(xev.event, |window| {
|
let dpi_factor = self.with_window(xev.event, |window| {
|
||||||
window.get_hidpi_factor()
|
window.hidpi_factor()
|
||||||
});
|
});
|
||||||
if let Some(dpi_factor) = dpi_factor {
|
if let Some(dpi_factor) = dpi_factor {
|
||||||
let location = LogicalPosition::from_physical(
|
let location = LogicalPosition::from_physical(
|
||||||
|
@ -960,7 +957,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
// In the future, it would be quite easy to emit monitor hotplug events.
|
// In the future, it would be quite easy to emit monitor hotplug events.
|
||||||
let prev_list = monitor::invalidate_cached_monitor_list();
|
let prev_list = monitor::invalidate_cached_monitor_list();
|
||||||
if let Some(prev_list) = prev_list {
|
if let Some(prev_list) = prev_list {
|
||||||
let new_list = wt.xconn.get_available_monitors();
|
let new_list = wt.xconn.available_monitors();
|
||||||
for new_monitor in new_list {
|
for new_monitor in new_list {
|
||||||
prev_list
|
prev_list
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -970,7 +967,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
for (window_id, window) in wt.windows.borrow().iter() {
|
for (window_id, window) in wt.windows.borrow().iter() {
|
||||||
if let Some(window) = window.upgrade() {
|
if let Some(window) = window.upgrade() {
|
||||||
// Check if the window is on this monitor
|
// Check if the window is on this monitor
|
||||||
let monitor = window.get_current_monitor();
|
let monitor = window.current_monitor();
|
||||||
if monitor.name == new_monitor.name {
|
if monitor.name == new_monitor.name {
|
||||||
callback(Event::WindowEvent {
|
callback(Event::WindowEvent {
|
||||||
window_id: mkwid(window_id.0),
|
window_id: mkwid(window_id.0),
|
||||||
|
@ -978,10 +975,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
new_monitor.hidpi_factor
|
new_monitor.hidpi_factor
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
let (width, height) = match window.get_inner_size_physical() {
|
let (width, height) = window.inner_size_physical();
|
||||||
Some(result) => result,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
let (_, _, flusher) = window.adjust_for_dpi(
|
let (_, _, flusher) = window.adjust_for_dpi(
|
||||||
prev_monitor.hidpi_factor,
|
prev_monitor.hidpi_factor,
|
||||||
new_monitor.hidpi_factor,
|
new_monitor.hidpi_factor,
|
||||||
|
@ -1007,4 +1001,4 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
Err(_) => (),
|
Err(_) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,9 @@ use super::{ffi, util, XConnection, XError};
|
||||||
|
|
||||||
use self::inner::{close_im, ImeInner};
|
use self::inner::{close_im, ImeInner};
|
||||||
use self::input_method::PotentialInputMethods;
|
use self::input_method::PotentialInputMethods;
|
||||||
use self::context::{ImeContextCreationError, ImeContext};
|
use self::context::ImeContext;
|
||||||
use self::callbacks::*;
|
use self::callbacks::*;
|
||||||
|
pub use self::context::ImeContextCreationError;
|
||||||
|
|
||||||
pub type ImeReceiver = Receiver<(ffi::Window, i16, i16)>;
|
pub type ImeReceiver = Receiver<(ffi::Window, i16, i16)>;
|
||||||
pub type ImeSender = Sender<(ffi::Window, i16, i16)>;
|
pub type ImeSender = Sender<(ffi::Window, i16, i16)>;
|
||||||
|
|
|
@ -25,11 +25,12 @@ use std::sync::{Arc, mpsc, Weak, Mutex};
|
||||||
|
|
||||||
use libc::{self, setlocale, LC_CTYPE};
|
use libc::{self, setlocale, LC_CTYPE};
|
||||||
|
|
||||||
|
use error::OsError as RootOsError;
|
||||||
use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW};
|
use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW};
|
||||||
use event::{WindowEvent, Event};
|
use event::{WindowEvent, Event};
|
||||||
use platform_impl::PlatformSpecificWindowBuilderAttributes;
|
use platform_impl::PlatformSpecificWindowBuilderAttributes;
|
||||||
use platform_impl::platform::sticky_exit_callback;
|
use platform_impl::platform::sticky_exit_callback;
|
||||||
use window::{CreationError, WindowAttributes};
|
use window::{WindowAttributes};
|
||||||
use self::dnd::{Dnd, DndState};
|
use self::dnd::{Dnd, DndState};
|
||||||
use self::ime::{ImeReceiver, ImeSender, ImeCreationError, Ime};
|
use self::ime::{ImeReceiver, ImeSender, ImeCreationError, Ime};
|
||||||
use self::event_processor::EventProcessor;
|
use self::event_processor::EventProcessor;
|
||||||
|
@ -427,7 +428,7 @@ impl Window {
|
||||||
event_loop: &EventLoopWindowTarget<T>,
|
event_loop: &EventLoopWindowTarget<T>,
|
||||||
attribs: WindowAttributes,
|
attribs: WindowAttributes,
|
||||||
pl_attribs: PlatformSpecificWindowBuilderAttributes
|
pl_attribs: PlatformSpecificWindowBuilderAttributes
|
||||||
) -> Result<Self, CreationError> {
|
) -> Result<Self, RootOsError> {
|
||||||
let window = Arc::new(UnownedWindow::new(&event_loop, attribs, pl_attribs)?);
|
let window = Arc::new(UnownedWindow::new(&event_loop, attribs, pl_attribs)?);
|
||||||
event_loop.windows
|
event_loop.windows
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl MonitorHandle {
|
||||||
primary: bool,
|
primary: bool,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr)? };
|
let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr)? };
|
||||||
let (dimensions, position) = unsafe { (repr.get_dimensions(), repr.get_position()) };
|
let (dimensions, position) = unsafe { (repr.dimensions(), repr.position()) };
|
||||||
let rect = util::AaRect::new(position, dimensions);
|
let rect = util::AaRect::new(position, dimensions);
|
||||||
Some(MonitorHandle {
|
Some(MonitorHandle {
|
||||||
id,
|
id,
|
||||||
|
@ -80,32 +80,32 @@ impl MonitorHandle {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
Some(self.name.clone())
|
Some(self.name.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_native_identifier(&self) -> u32 {
|
pub fn native_identifier(&self) -> u32 {
|
||||||
self.id as u32
|
self.id as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
self.dimensions.into()
|
self.dimensions.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn position(&self) -> PhysicalPosition {
|
||||||
self.position.into()
|
self.position.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
self.hidpi_factor
|
self.hidpi_factor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XConnection {
|
impl XConnection {
|
||||||
pub fn get_monitor_for_window(&self, window_rect: Option<util::AaRect>) -> MonitorHandle {
|
pub fn get_monitor_for_window(&self, window_rect: Option<util::AaRect>) -> MonitorHandle {
|
||||||
let monitors = self.get_available_monitors();
|
let monitors = self.available_monitors();
|
||||||
let default = monitors
|
let default = monitors
|
||||||
.get(0)
|
.get(0)
|
||||||
.expect("[winit] Failed to find any monitors using XRandR.");
|
.expect("[winit] Failed to find any monitors using XRandR.");
|
||||||
|
@ -206,7 +206,7 @@ impl XConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(&self) -> Vec<MonitorHandle> {
|
pub fn available_monitors(&self) -> Vec<MonitorHandle> {
|
||||||
let mut monitors_lock = MONITORS.lock();
|
let mut monitors_lock = MONITORS.lock();
|
||||||
(*monitors_lock)
|
(*monitors_lock)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -222,8 +222,8 @@ impl XConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
self.get_available_monitors()
|
self.available_monitors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|monitor| monitor.primary)
|
.find(|monitor| monitor.primary)
|
||||||
.expect("[winit] Failed to find any monitors using XRandR.")
|
.expect("[winit] Failed to find any monitors using XRandR.")
|
||||||
|
|
|
@ -152,7 +152,7 @@ impl FrameExtentsHeuristic {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XConnection {
|
impl XConnection {
|
||||||
// This is adequate for get_inner_position
|
// This is adequate for inner_position
|
||||||
pub fn translate_coords(&self, window: ffi::Window, root: ffi::Window) -> Result<TranslatedCoords, XError> {
|
pub fn translate_coords(&self, window: ffi::Window, root: ffi::Window) -> Result<TranslatedCoords, XError> {
|
||||||
let mut translated_coords: TranslatedCoords = unsafe { mem::uninitialized() };
|
let mut translated_coords: TranslatedCoords = unsafe { mem::uninitialized() };
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -171,7 +171,7 @@ impl XConnection {
|
||||||
self.check_errors().map(|_| translated_coords)
|
self.check_errors().map(|_| translated_coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is adequate for get_inner_size
|
// This is adequate for inner_size
|
||||||
pub fn get_geometry(&self, window: ffi::Window) -> Result<Geometry, XError> {
|
pub fn get_geometry(&self, window: ffi::Window) -> Result<Geometry, XError> {
|
||||||
let mut geometry: Geometry = unsafe { mem::uninitialized() };
|
let mut geometry: Geometry = unsafe { mem::uninitialized() };
|
||||||
let _status = unsafe {
|
let _status = unsafe {
|
||||||
|
|
|
@ -51,14 +51,14 @@ impl MonitorRepr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn get_dimensions(&self) -> (u32, u32) {
|
pub unsafe fn dimensions(&self) -> (u32, u32) {
|
||||||
match *self {
|
match *self {
|
||||||
MonitorRepr::Monitor(monitor) => ((*monitor).width as u32, (*monitor).height as u32),
|
MonitorRepr::Monitor(monitor) => ((*monitor).width as u32, (*monitor).height as u32),
|
||||||
MonitorRepr::Crtc(crtc) => ((*crtc).width as u32, (*crtc).height as u32),
|
MonitorRepr::Crtc(crtc) => ((*crtc).width as u32, (*crtc).height as u32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn get_position(&self) -> (i32, i32) {
|
pub unsafe fn position(&self) -> (i32, i32) {
|
||||||
match *self {
|
match *self {
|
||||||
MonitorRepr::Monitor(monitor) => ((*monitor).x as i32, (*monitor).y as i32),
|
MonitorRepr::Monitor(monitor) => ((*monitor).x as i32, (*monitor).y as i32),
|
||||||
MonitorRepr::Crtc(crtc) => ((*crtc).x as i32, (*crtc).y as i32),
|
MonitorRepr::Crtc(crtc) => ((*crtc).x as i32, (*crtc).y as i32),
|
||||||
|
@ -123,7 +123,7 @@ impl XConnection {
|
||||||
dpi / 96.
|
dpi / 96.
|
||||||
} else {
|
} else {
|
||||||
calc_dpi_factor(
|
calc_dpi_factor(
|
||||||
repr.get_dimensions(),
|
repr.dimensions(),
|
||||||
((*output_info).mm_width as u64, (*output_info).mm_height as u64),
|
((*output_info).mm_width as u64, (*output_info).mm_height as u64),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,11 +8,12 @@ use std::sync::Arc;
|
||||||
use libc;
|
use libc;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use window::{Icon, MouseCursor, WindowAttributes};
|
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||||
use window::CreationError::{self, OsError};
|
use window::{Icon, CursorIcon, WindowAttributes};
|
||||||
use dpi::{LogicalPosition, LogicalSize};
|
use dpi::{LogicalPosition, LogicalSize};
|
||||||
use platform_impl::MonitorHandle as PlatformMonitorHandle;
|
use platform_impl::MonitorHandle as PlatformMonitorHandle;
|
||||||
use platform_impl::PlatformSpecificWindowBuilderAttributes;
|
use platform_impl::{OsError, PlatformSpecificWindowBuilderAttributes};
|
||||||
|
use platform_impl::x11::ime::ImeContextCreationError;
|
||||||
use platform_impl::x11::MonitorHandle as X11MonitorHandle;
|
use platform_impl::x11::MonitorHandle as X11MonitorHandle;
|
||||||
use monitor::MonitorHandle as RootMonitorHandle;
|
use monitor::MonitorHandle as RootMonitorHandle;
|
||||||
|
|
||||||
|
@ -42,8 +43,8 @@ pub struct SharedState {
|
||||||
// Used to restore position after exiting fullscreen.
|
// Used to restore position after exiting fullscreen.
|
||||||
pub restore_position: Option<(i32, i32)>,
|
pub restore_position: Option<(i32, i32)>,
|
||||||
pub frame_extents: Option<util::FrameExtentsHeuristic>,
|
pub frame_extents: Option<util::FrameExtentsHeuristic>,
|
||||||
pub min_dimensions: Option<LogicalSize>,
|
pub min_inner_size: Option<LogicalSize>,
|
||||||
pub max_dimensions: Option<LogicalSize>,
|
pub max_inner_size: Option<LogicalSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SharedState {
|
impl SharedState {
|
||||||
|
@ -62,11 +63,10 @@ pub struct UnownedWindow {
|
||||||
xwindow: ffi::Window, // never changes
|
xwindow: ffi::Window, // never changes
|
||||||
root: ffi::Window, // never changes
|
root: ffi::Window, // never changes
|
||||||
screen_id: i32, // never changes
|
screen_id: i32, // never changes
|
||||||
cursor: Mutex<MouseCursor>,
|
cursor: Mutex<CursorIcon>,
|
||||||
cursor_grabbed: Mutex<bool>,
|
cursor_grabbed: Mutex<bool>,
|
||||||
cursor_hidden: Mutex<bool>,
|
cursor_visible: Mutex<bool>,
|
||||||
ime_sender: Mutex<ImeSender>,
|
ime_sender: Mutex<ImeSender>,
|
||||||
pub multitouch: bool, // never changes
|
|
||||||
pub shared_state: Mutex<SharedState>,
|
pub shared_state: Mutex<SharedState>,
|
||||||
pending_redraws: Arc<::std::sync::Mutex<HashSet<WindowId>>>,
|
pending_redraws: Arc<::std::sync::Mutex<HashSet<WindowId>>>,
|
||||||
}
|
}
|
||||||
|
@ -76,15 +76,15 @@ impl UnownedWindow {
|
||||||
event_loop: &EventLoopWindowTarget<T>,
|
event_loop: &EventLoopWindowTarget<T>,
|
||||||
window_attrs: WindowAttributes,
|
window_attrs: WindowAttributes,
|
||||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||||
) -> Result<UnownedWindow, CreationError> {
|
) -> Result<UnownedWindow, RootOsError> {
|
||||||
let xconn = &event_loop.xconn;
|
let xconn = &event_loop.xconn;
|
||||||
let root = event_loop.root;
|
let root = event_loop.root;
|
||||||
|
|
||||||
let monitors = xconn.get_available_monitors();
|
let monitors = xconn.available_monitors();
|
||||||
let dpi_factor = if !monitors.is_empty() {
|
let dpi_factor = if !monitors.is_empty() {
|
||||||
let mut dpi_factor = Some(monitors[0].get_hidpi_factor());
|
let mut dpi_factor = Some(monitors[0].hidpi_factor());
|
||||||
for monitor in &monitors {
|
for monitor in &monitors {
|
||||||
if Some(monitor.get_hidpi_factor()) != dpi_factor {
|
if Some(monitor.hidpi_factor()) != dpi_factor {
|
||||||
dpi_factor = None;
|
dpi_factor = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ impl UnownedWindow {
|
||||||
let mut dpi_factor = None;
|
let mut dpi_factor = None;
|
||||||
for monitor in &monitors {
|
for monitor in &monitors {
|
||||||
if monitor.rect.contains_point(x, y) {
|
if monitor.rect.contains_point(x, y) {
|
||||||
dpi_factor = Some(monitor.get_hidpi_factor());
|
dpi_factor = Some(monitor.hidpi_factor());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,31 +105,31 @@ impl UnownedWindow {
|
||||||
.unwrap_or(1.0)
|
.unwrap_or(1.0)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return Err(OsError(format!("No monitors were detected.")));
|
return Err(os_error!(OsError::XMisc("No monitors were detected.")));
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Guessed window DPI factor: {}", dpi_factor);
|
info!("Guessed window DPI factor: {}", dpi_factor);
|
||||||
|
|
||||||
let max_dimensions: Option<(u32, u32)> = window_attrs.max_dimensions.map(|size| {
|
let max_inner_size: Option<(u32, u32)> = window_attrs.max_inner_size.map(|size| {
|
||||||
size.to_physical(dpi_factor).into()
|
size.to_physical(dpi_factor).into()
|
||||||
});
|
});
|
||||||
let min_dimensions: Option<(u32, u32)> = window_attrs.min_dimensions.map(|size| {
|
let min_inner_size: Option<(u32, u32)> = window_attrs.min_inner_size.map(|size| {
|
||||||
size.to_physical(dpi_factor).into()
|
size.to_physical(dpi_factor).into()
|
||||||
});
|
});
|
||||||
|
|
||||||
let dimensions = {
|
let dimensions = {
|
||||||
// x11 only applies constraints when the window is actively resized
|
// x11 only applies constraints when the window is actively resized
|
||||||
// by the user, so we have to manually apply the initial constraints
|
// by the user, so we have to manually apply the initial constraints
|
||||||
let mut dimensions: (u32, u32) = window_attrs.dimensions
|
let mut dimensions: (u32, u32) = window_attrs.inner_size
|
||||||
.or_else(|| Some((800, 600).into()))
|
.or_else(|| Some((800, 600).into()))
|
||||||
.map(|size| size.to_physical(dpi_factor))
|
.map(|size| size.to_physical(dpi_factor))
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if let Some(max) = max_dimensions {
|
if let Some(max) = max_inner_size {
|
||||||
dimensions.0 = cmp::min(dimensions.0, max.0);
|
dimensions.0 = cmp::min(dimensions.0, max.0);
|
||||||
dimensions.1 = cmp::min(dimensions.1, max.1);
|
dimensions.1 = cmp::min(dimensions.1, max.1);
|
||||||
}
|
}
|
||||||
if let Some(min) = min_dimensions {
|
if let Some(min) = min_inner_size {
|
||||||
dimensions.0 = cmp::max(dimensions.0, min.0);
|
dimensions.0 = cmp::max(dimensions.0, min.0);
|
||||||
dimensions.1 = cmp::max(dimensions.1, min.1);
|
dimensions.1 = cmp::max(dimensions.1, min.1);
|
||||||
}
|
}
|
||||||
|
@ -209,10 +209,9 @@ impl UnownedWindow {
|
||||||
root,
|
root,
|
||||||
screen_id,
|
screen_id,
|
||||||
cursor: Default::default(),
|
cursor: Default::default(),
|
||||||
cursor_grabbed: Default::default(),
|
cursor_grabbed: Mutex::new(false),
|
||||||
cursor_hidden: Default::default(),
|
cursor_visible: Mutex::new(true),
|
||||||
ime_sender: Mutex::new(event_loop.ime_sender.clone()),
|
ime_sender: Mutex::new(event_loop.ime_sender.clone()),
|
||||||
multitouch: window_attrs.multitouch,
|
|
||||||
shared_state: SharedState::new(dpi_factor),
|
shared_state: SharedState::new(dpi_factor),
|
||||||
pending_redraws: event_loop.pending_redraws.clone(),
|
pending_redraws: event_loop.pending_redraws.clone(),
|
||||||
};
|
};
|
||||||
|
@ -290,27 +289,27 @@ impl UnownedWindow {
|
||||||
|
|
||||||
// set size hints
|
// set size hints
|
||||||
{
|
{
|
||||||
let mut min_dimensions = window_attrs.min_dimensions
|
let mut min_inner_size = window_attrs.min_inner_size
|
||||||
.map(|size| size.to_physical(dpi_factor));
|
.map(|size| size.to_physical(dpi_factor));
|
||||||
let mut max_dimensions = window_attrs.max_dimensions
|
let mut max_inner_size = window_attrs.max_inner_size
|
||||||
.map(|size| size.to_physical(dpi_factor));
|
.map(|size| size.to_physical(dpi_factor));
|
||||||
if !window_attrs.resizable {
|
if !window_attrs.resizable {
|
||||||
if util::wm_name_is_one_of(&["Xfwm4"]) {
|
if util::wm_name_is_one_of(&["Xfwm4"]) {
|
||||||
warn!("To avoid a WM bug, disabling resizing has no effect on Xfwm4");
|
warn!("To avoid a WM bug, disabling resizing has no effect on Xfwm4");
|
||||||
} else {
|
} else {
|
||||||
max_dimensions = Some(dimensions.into());
|
max_inner_size = Some(dimensions.into());
|
||||||
min_dimensions = Some(dimensions.into());
|
min_inner_size = Some(dimensions.into());
|
||||||
|
|
||||||
let mut shared_state_lock = window.shared_state.lock();
|
let mut shared_state_lock = window.shared_state.lock();
|
||||||
shared_state_lock.min_dimensions = window_attrs.min_dimensions;
|
shared_state_lock.min_inner_size = window_attrs.min_inner_size;
|
||||||
shared_state_lock.max_dimensions = window_attrs.max_dimensions;
|
shared_state_lock.max_inner_size = window_attrs.max_inner_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut normal_hints = util::NormalHints::new(xconn);
|
let mut normal_hints = util::NormalHints::new(xconn);
|
||||||
normal_hints.set_size(Some(dimensions));
|
normal_hints.set_size(Some(dimensions));
|
||||||
normal_hints.set_min_size(min_dimensions.map(Into::into));
|
normal_hints.set_min_size(min_inner_size.map(Into::into));
|
||||||
normal_hints.set_max_size(max_dimensions.map(Into::into));
|
normal_hints.set_max_size(max_inner_size.map(Into::into));
|
||||||
normal_hints.set_resize_increments(pl_attribs.resize_increments);
|
normal_hints.set_resize_increments(pl_attribs.resize_increments);
|
||||||
normal_hints.set_base_size(pl_attribs.base_size);
|
normal_hints.set_base_size(pl_attribs.base_size);
|
||||||
xconn.set_normal_hints(window.xwindow, normal_hints).queue();
|
xconn.set_normal_hints(window.xwindow, normal_hints).queue();
|
||||||
|
@ -347,13 +346,13 @@ impl UnownedWindow {
|
||||||
&mut supported_ptr,
|
&mut supported_ptr,
|
||||||
);
|
);
|
||||||
if supported_ptr == ffi::False {
|
if supported_ptr == ffi::False {
|
||||||
return Err(OsError(format!("`XkbSetDetectableAutoRepeat` failed")));
|
return Err(os_error!(OsError::XMisc("`XkbSetDetectableAutoRepeat` failed")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select XInput2 events
|
// Select XInput2 events
|
||||||
let mask = {
|
let mask = {
|
||||||
let mut mask = ffi::XI_MotionMask
|
let mask = ffi::XI_MotionMask
|
||||||
| ffi::XI_ButtonPressMask
|
| ffi::XI_ButtonPressMask
|
||||||
| ffi::XI_ButtonReleaseMask
|
| ffi::XI_ButtonReleaseMask
|
||||||
//| ffi::XI_KeyPressMask
|
//| ffi::XI_KeyPressMask
|
||||||
|
@ -361,12 +360,10 @@ impl UnownedWindow {
|
||||||
| ffi::XI_EnterMask
|
| ffi::XI_EnterMask
|
||||||
| ffi::XI_LeaveMask
|
| ffi::XI_LeaveMask
|
||||||
| ffi::XI_FocusInMask
|
| ffi::XI_FocusInMask
|
||||||
| ffi::XI_FocusOutMask;
|
| ffi::XI_FocusOutMask
|
||||||
if window_attrs.multitouch {
|
| ffi::XI_TouchBeginMask
|
||||||
mask |= ffi::XI_TouchBeginMask
|
| ffi::XI_TouchUpdateMask
|
||||||
| ffi::XI_TouchUpdateMask
|
| ffi::XI_TouchEndMask;
|
||||||
| ffi::XI_TouchEndMask;
|
|
||||||
}
|
|
||||||
mask
|
mask
|
||||||
};
|
};
|
||||||
xconn.select_xinput_events(window.xwindow, ffi::XIAllMasterDevices, mask).queue();
|
xconn.select_xinput_events(window.xwindow, ffi::XIAllMasterDevices, mask).queue();
|
||||||
|
@ -376,7 +373,11 @@ impl UnownedWindow {
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.create_context(window.xwindow);
|
.create_context(window.xwindow);
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
return Err(OsError(format!("Failed to create input context: {:?}", err)));
|
let e = match err {
|
||||||
|
ImeContextCreationError::XError(err) => OsError::XError(err),
|
||||||
|
ImeContextCreationError::Null => OsError::XMisc("IME Context creation failed"),
|
||||||
|
};
|
||||||
|
return Err(os_error!(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,18 +416,16 @@ impl UnownedWindow {
|
||||||
// We never want to give the user a broken window, since by then, it's too late to handle.
|
// We never want to give the user a broken window, since by then, it's too late to handle.
|
||||||
xconn.sync_with_server()
|
xconn.sync_with_server()
|
||||||
.map(|_| window)
|
.map(|_| window)
|
||||||
.map_err(|x_err| OsError(
|
.map_err(|x_err| os_error!(OsError::XError(x_err)))
|
||||||
format!("X server returned error while building window: {:?}", x_err)
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn logicalize_coords(&self, (x, y): (i32, i32)) -> LogicalPosition {
|
fn logicalize_coords(&self, (x, y): (i32, i32)) -> LogicalPosition {
|
||||||
let dpi = self.get_hidpi_factor();
|
let dpi = self.hidpi_factor();
|
||||||
LogicalPosition::from_physical((x, y), dpi)
|
LogicalPosition::from_physical((x, y), dpi)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn logicalize_size(&self, (width, height): (u32, u32)) -> LogicalSize {
|
fn logicalize_size(&self, (width, height): (u32, u32)) -> LogicalSize {
|
||||||
let dpi = self.get_hidpi_factor();
|
let dpi = self.hidpi_factor();
|
||||||
LogicalSize::from_physical((width, height), dpi)
|
LogicalSize::from_physical((width, height), dpi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,9 +534,9 @@ impl UnownedWindow {
|
||||||
flusher
|
flusher
|
||||||
},
|
},
|
||||||
Some(RootMonitorHandle { inner: PlatformMonitorHandle::X(monitor) }) => {
|
Some(RootMonitorHandle { inner: PlatformMonitorHandle::X(monitor) }) => {
|
||||||
let window_position = self.get_position_physical();
|
let window_position = self.outer_position_physical();
|
||||||
self.shared_state.lock().restore_position = window_position;
|
self.shared_state.lock().restore_position = Some(window_position);
|
||||||
let monitor_origin: (i32, i32) = monitor.get_position().into();
|
let monitor_origin: (i32, i32) = monitor.position().into();
|
||||||
self.set_position_inner(monitor_origin.0, monitor_origin.1).queue();
|
self.set_position_inner(monitor_origin.0, monitor_origin.1).queue();
|
||||||
self.set_fullscreen_hint(true)
|
self.set_fullscreen_hint(true)
|
||||||
}
|
}
|
||||||
|
@ -546,7 +545,7 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||||
self.shared_state.lock().fullscreen.clone()
|
self.shared_state.lock().fullscreen.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,17 +558,15 @@ impl UnownedWindow {
|
||||||
self.invalidate_cached_frame_extents();
|
self.invalidate_cached_frame_extents();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rect(&self) -> Option<util::AaRect> {
|
fn get_rect(&self) -> util::AaRect {
|
||||||
// TODO: This might round-trip more times than needed.
|
// TODO: This might round-trip more times than needed.
|
||||||
if let (Some(position), Some(size)) = (self.get_position_physical(), self.get_outer_size_physical()) {
|
let position = self.outer_position_physical();
|
||||||
Some(util::AaRect::new(position, size))
|
let size = self.outer_size_physical();
|
||||||
} else {
|
util::AaRect::new(position, size)
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_current_monitor(&self) -> X11MonitorHandle {
|
pub fn current_monitor(&self) -> X11MonitorHandle {
|
||||||
let monitor = self.shared_state
|
let monitor = self.shared_state
|
||||||
.lock()
|
.lock()
|
||||||
.last_monitor
|
.last_monitor
|
||||||
|
@ -577,18 +574,18 @@ impl UnownedWindow {
|
||||||
.cloned();
|
.cloned();
|
||||||
monitor
|
monitor
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
let monitor = self.xconn.get_monitor_for_window(self.get_rect()).to_owned();
|
let monitor = self.xconn.get_monitor_for_window(Some(self.get_rect())).to_owned();
|
||||||
self.shared_state.lock().last_monitor = Some(monitor.clone());
|
self.shared_state.lock().last_monitor = Some(monitor.clone());
|
||||||
monitor
|
monitor
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(&self) -> Vec<X11MonitorHandle> {
|
pub fn available_monitors(&self) -> Vec<X11MonitorHandle> {
|
||||||
self.xconn.get_available_monitors()
|
self.xconn.available_monitors()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor(&self) -> X11MonitorHandle {
|
pub fn primary_monitor(&self) -> X11MonitorHandle {
|
||||||
self.xconn.get_primary_monitor()
|
self.xconn.primary_monitor()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_maximized_inner(&self, maximized: bool) -> util::Flusher {
|
fn set_maximized_inner(&self, maximized: bool) -> util::Flusher {
|
||||||
|
@ -702,20 +699,18 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn show(&self) {
|
pub fn set_visible(&self, visible: bool) {
|
||||||
unsafe {
|
match visible {
|
||||||
(self.xconn.xlib.XMapRaised)(self.xconn.display, self.xwindow);
|
true => unsafe {
|
||||||
self.xconn.flush_requests()
|
(self.xconn.xlib.XMapRaised)(self.xconn.display, self.xwindow);
|
||||||
.expect("Failed to call XMapRaised");
|
self.xconn.flush_requests()
|
||||||
}
|
.expect("Failed to call XMapRaised");
|
||||||
}
|
},
|
||||||
|
false => unsafe {
|
||||||
#[inline]
|
(self.xconn.xlib.XUnmapWindow)(self.xconn.display, self.xwindow);
|
||||||
pub fn hide(&self) {
|
self.xconn.flush_requests()
|
||||||
unsafe {
|
.expect("Failed to call XUnmapWindow");
|
||||||
(self.xconn.xlib.XUnmapWindow)(self.xconn.display, self.xwindow);
|
}
|
||||||
self.xconn.flush_requests()
|
|
||||||
.expect("Failed to call XUnmapWindow");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,39 +723,40 @@ impl UnownedWindow {
|
||||||
(*self.shared_state.lock()).frame_extents.take();
|
(*self.shared_state.lock()).frame_extents.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_position_physical(&self) -> Option<(i32, i32)> {
|
pub(crate) fn outer_position_physical(&self) -> (i32, i32) {
|
||||||
let extents = (*self.shared_state.lock()).frame_extents.clone();
|
let extents = (*self.shared_state.lock()).frame_extents.clone();
|
||||||
if let Some(extents) = extents {
|
if let Some(extents) = extents {
|
||||||
self.get_inner_position_physical()
|
let (x, y) = self.inner_position_physical();
|
||||||
.map(|(x, y)| extents.inner_pos_to_outer(x, y))
|
extents.inner_pos_to_outer(x, y)
|
||||||
} else {
|
} else {
|
||||||
self.update_cached_frame_extents();
|
self.update_cached_frame_extents();
|
||||||
self.get_position_physical()
|
self.outer_position_physical()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
let extents = (*self.shared_state.lock()).frame_extents.clone();
|
let extents = (*self.shared_state.lock()).frame_extents.clone();
|
||||||
if let Some(extents) = extents {
|
if let Some(extents) = extents {
|
||||||
self.get_inner_position()
|
let logical = self.inner_position().unwrap();
|
||||||
.map(|logical| extents.inner_pos_to_outer_logical(logical, self.get_hidpi_factor()))
|
Ok(extents.inner_pos_to_outer_logical(logical, self.hidpi_factor()))
|
||||||
} else {
|
} else {
|
||||||
self.update_cached_frame_extents();
|
self.update_cached_frame_extents();
|
||||||
self.get_position()
|
self.outer_position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_inner_position_physical(&self) -> Option<(i32, i32)> {
|
pub(crate) fn inner_position_physical(&self) -> (i32, i32) {
|
||||||
|
// This should be okay to unwrap since the only error XTranslateCoordinates can return
|
||||||
|
// is BadWindow, and if the window handle is bad we have bigger problems.
|
||||||
self.xconn.translate_coords(self.xwindow, self.root)
|
self.xconn.translate_coords(self.xwindow, self.root)
|
||||||
.ok()
|
|
||||||
.map(|coords| (coords.x_rel_root, coords.y_rel_root))
|
.map(|coords| (coords.x_rel_root, coords.y_rel_root))
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
self.get_inner_position_physical()
|
Ok(self.logicalize_coords(self.inner_position_physical()))
|
||||||
.map(|coords| self.logicalize_coords(coords))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_position_inner(&self, mut x: i32, mut y: i32) -> util::Flusher {
|
pub(crate) fn set_position_inner(&self, mut x: i32, mut y: i32) -> util::Flusher {
|
||||||
|
@ -794,43 +790,44 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_position(&self, logical_position: LogicalPosition) {
|
pub fn set_outer_position(&self, logical_position: LogicalPosition) {
|
||||||
let (x, y) = logical_position.to_physical(self.get_hidpi_factor()).into();
|
let (x, y) = logical_position.to_physical(self.hidpi_factor()).into();
|
||||||
self.set_position_physical(x, y);
|
self.set_position_physical(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_inner_size_physical(&self) -> Option<(u32, u32)> {
|
pub(crate) fn inner_size_physical(&self) -> (u32, u32) {
|
||||||
|
// This should be okay to unwrap since the only error XGetGeometry can return
|
||||||
|
// is BadWindow, and if the window handle is bad we have bigger problems.
|
||||||
self.xconn.get_geometry(self.xwindow)
|
self.xconn.get_geometry(self.xwindow)
|
||||||
.ok()
|
|
||||||
.map(|geo| (geo.width, geo.height))
|
.map(|geo| (geo.width, geo.height))
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn inner_size(&self) -> LogicalSize {
|
||||||
self.get_inner_size_physical()
|
self.logicalize_size(self.inner_size_physical())
|
||||||
.map(|size| self.logicalize_size(size))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_outer_size_physical(&self) -> Option<(u32, u32)> {
|
pub(crate) fn outer_size_physical(&self) -> (u32, u32) {
|
||||||
let extents = self.shared_state.lock().frame_extents.clone();
|
let extents = self.shared_state.lock().frame_extents.clone();
|
||||||
if let Some(extents) = extents {
|
if let Some(extents) = extents {
|
||||||
self.get_inner_size_physical()
|
let (w, h) = self.inner_size_physical();
|
||||||
.map(|(w, h)| extents.inner_size_to_outer(w, h))
|
extents.inner_size_to_outer(w, h)
|
||||||
} else {
|
} else {
|
||||||
self.update_cached_frame_extents();
|
self.update_cached_frame_extents();
|
||||||
self.get_outer_size_physical()
|
self.outer_size_physical()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
pub fn outer_size(&self) -> LogicalSize {
|
||||||
let extents = self.shared_state.lock().frame_extents.clone();
|
let extents = self.shared_state.lock().frame_extents.clone();
|
||||||
if let Some(extents) = extents {
|
if let Some(extents) = extents {
|
||||||
self.get_inner_size()
|
let logical = self.inner_size();
|
||||||
.map(|logical| extents.inner_size_to_outer_logical(logical, self.get_hidpi_factor()))
|
extents.inner_size_to_outer_logical(logical, self.hidpi_factor())
|
||||||
} else {
|
} else {
|
||||||
self.update_cached_frame_extents();
|
self.update_cached_frame_extents();
|
||||||
self.get_outer_size()
|
self.outer_size()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,7 +845,7 @@ impl UnownedWindow {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_inner_size(&self, logical_size: LogicalSize) {
|
pub fn set_inner_size(&self, logical_size: LogicalSize) {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
let (width, height) = logical_size.to_physical(dpi_factor).into();
|
let (width, height) = logical_size.to_physical(dpi_factor).into();
|
||||||
self.set_inner_size_physical(width, height);
|
self.set_inner_size_physical(width, height);
|
||||||
}
|
}
|
||||||
|
@ -861,32 +858,32 @@ impl UnownedWindow {
|
||||||
self.xconn.set_normal_hints(self.xwindow, normal_hints).flush()
|
self.xconn.set_normal_hints(self.xwindow, normal_hints).flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_min_dimensions_physical(&self, dimensions: Option<(u32, u32)>) {
|
pub(crate) fn set_min_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||||
self.update_normal_hints(|normal_hints| normal_hints.set_min_size(dimensions))
|
self.update_normal_hints(|normal_hints| normal_hints.set_min_size(dimensions))
|
||||||
.expect("Failed to call `XSetWMNormalHints`");
|
.expect("Failed to call `XSetWMNormalHints`");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_min_dimensions(&self, logical_dimensions: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, logical_dimensions: Option<LogicalSize>) {
|
||||||
self.shared_state.lock().min_dimensions = logical_dimensions;
|
self.shared_state.lock().min_inner_size = logical_dimensions;
|
||||||
let physical_dimensions = logical_dimensions.map(|logical_dimensions| {
|
let physical_dimensions = logical_dimensions.map(|logical_dimensions| {
|
||||||
logical_dimensions.to_physical(self.get_hidpi_factor()).into()
|
logical_dimensions.to_physical(self.hidpi_factor()).into()
|
||||||
});
|
});
|
||||||
self.set_min_dimensions_physical(physical_dimensions);
|
self.set_min_inner_size_physical(physical_dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_max_dimensions_physical(&self, dimensions: Option<(u32, u32)>) {
|
pub(crate) fn set_max_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||||
self.update_normal_hints(|normal_hints| normal_hints.set_max_size(dimensions))
|
self.update_normal_hints(|normal_hints| normal_hints.set_max_size(dimensions))
|
||||||
.expect("Failed to call `XSetWMNormalHints`");
|
.expect("Failed to call `XSetWMNormalHints`");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_max_dimensions(&self, logical_dimensions: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, logical_dimensions: Option<LogicalSize>) {
|
||||||
self.shared_state.lock().max_dimensions = logical_dimensions;
|
self.shared_state.lock().max_inner_size = logical_dimensions;
|
||||||
let physical_dimensions = logical_dimensions.map(|logical_dimensions| {
|
let physical_dimensions = logical_dimensions.map(|logical_dimensions| {
|
||||||
logical_dimensions.to_physical(self.get_hidpi_factor()).into()
|
logical_dimensions.to_physical(self.hidpi_factor()).into()
|
||||||
});
|
});
|
||||||
self.set_max_dimensions_physical(physical_dimensions);
|
self.set_max_inner_size_physical(physical_dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn adjust_for_dpi(
|
pub(crate) fn adjust_for_dpi(
|
||||||
|
@ -936,47 +933,47 @@ impl UnownedWindow {
|
||||||
|
|
||||||
let (logical_min, logical_max) = if resizable {
|
let (logical_min, logical_max) = if resizable {
|
||||||
let shared_state_lock = self.shared_state.lock();
|
let shared_state_lock = self.shared_state.lock();
|
||||||
(shared_state_lock.min_dimensions, shared_state_lock.max_dimensions)
|
(shared_state_lock.min_inner_size, shared_state_lock.max_inner_size)
|
||||||
} else {
|
} else {
|
||||||
let window_size = self.get_inner_size();
|
let window_size = Some(self.inner_size());
|
||||||
(window_size.clone(), window_size)
|
(window_size.clone(), window_size)
|
||||||
};
|
};
|
||||||
|
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
let min_dimensions = logical_min
|
let min_inner_size = logical_min
|
||||||
.map(|logical_size| logical_size.to_physical(dpi_factor))
|
.map(|logical_size| logical_size.to_physical(dpi_factor))
|
||||||
.map(Into::into);
|
.map(Into::into);
|
||||||
let max_dimensions = logical_max
|
let max_inner_size = logical_max
|
||||||
.map(|logical_size| logical_size.to_physical(dpi_factor))
|
.map(|logical_size| logical_size.to_physical(dpi_factor))
|
||||||
.map(Into::into);
|
.map(Into::into);
|
||||||
self.update_normal_hints(|normal_hints| {
|
self.update_normal_hints(|normal_hints| {
|
||||||
normal_hints.set_min_size(min_dimensions);
|
normal_hints.set_min_size(min_inner_size);
|
||||||
normal_hints.set_max_size(max_dimensions);
|
normal_hints.set_max_size(max_inner_size);
|
||||||
}).expect("Failed to call `XSetWMNormalHints`");
|
}).expect("Failed to call `XSetWMNormalHints`");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_xlib_display(&self) -> *mut c_void {
|
pub fn xlib_display(&self) -> *mut c_void {
|
||||||
self.xconn.display as _
|
self.xconn.display as _
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_xlib_screen_id(&self) -> c_int {
|
pub fn xlib_screen_id(&self) -> c_int {
|
||||||
self.screen_id
|
self.screen_id
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_xlib_xconnection(&self) -> Arc<XConnection> {
|
pub fn xlib_xconnection(&self) -> Arc<XConnection> {
|
||||||
Arc::clone(&self.xconn)
|
Arc::clone(&self.xconn)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_xlib_window(&self) -> c_ulong {
|
pub fn xlib_window(&self) -> c_ulong {
|
||||||
self.xwindow
|
self.xwindow
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_xcb_connection(&self) -> *mut c_void {
|
pub fn xcb_connection(&self) -> *mut c_void {
|
||||||
unsafe {
|
unsafe {
|
||||||
(self.xconn.xlib_xcb.XGetXCBConnection)(self.xconn.display) as *mut _
|
(self.xconn.xlib_xcb.XGetXCBConnection)(self.xconn.display) as *mut _
|
||||||
}
|
}
|
||||||
|
@ -1001,7 +998,7 @@ impl UnownedWindow {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cursor(&self, cursor: MouseCursor) -> ffi::Cursor {
|
fn get_cursor(&self, cursor: CursorIcon) -> ffi::Cursor {
|
||||||
let load = |name: &[u8]| {
|
let load = |name: &[u8]| {
|
||||||
self.load_cursor(name)
|
self.load_cursor(name)
|
||||||
};
|
};
|
||||||
|
@ -1015,48 +1012,48 @@ impl UnownedWindow {
|
||||||
//
|
//
|
||||||
// Try the better looking (or more suiting) names first.
|
// Try the better looking (or more suiting) names first.
|
||||||
match cursor {
|
match cursor {
|
||||||
MouseCursor::Alias => load(b"link\0"),
|
CursorIcon::Alias => load(b"link\0"),
|
||||||
MouseCursor::Arrow => load(b"arrow\0"),
|
CursorIcon::Arrow => load(b"arrow\0"),
|
||||||
MouseCursor::Cell => load(b"plus\0"),
|
CursorIcon::Cell => load(b"plus\0"),
|
||||||
MouseCursor::Copy => load(b"copy\0"),
|
CursorIcon::Copy => load(b"copy\0"),
|
||||||
MouseCursor::Crosshair => load(b"crosshair\0"),
|
CursorIcon::Crosshair => load(b"crosshair\0"),
|
||||||
MouseCursor::Default => load(b"left_ptr\0"),
|
CursorIcon::Default => load(b"left_ptr\0"),
|
||||||
MouseCursor::Hand => loadn(&[b"hand2\0", b"hand1\0"]),
|
CursorIcon::Hand => loadn(&[b"hand2\0", b"hand1\0"]),
|
||||||
MouseCursor::Help => load(b"question_arrow\0"),
|
CursorIcon::Help => load(b"question_arrow\0"),
|
||||||
MouseCursor::Move => load(b"move\0"),
|
CursorIcon::Move => load(b"move\0"),
|
||||||
MouseCursor::Grab => loadn(&[b"openhand\0", b"grab\0"]),
|
CursorIcon::Grab => loadn(&[b"openhand\0", b"grab\0"]),
|
||||||
MouseCursor::Grabbing => loadn(&[b"closedhand\0", b"grabbing\0"]),
|
CursorIcon::Grabbing => loadn(&[b"closedhand\0", b"grabbing\0"]),
|
||||||
MouseCursor::Progress => load(b"left_ptr_watch\0"),
|
CursorIcon::Progress => load(b"left_ptr_watch\0"),
|
||||||
MouseCursor::AllScroll => load(b"all-scroll\0"),
|
CursorIcon::AllScroll => load(b"all-scroll\0"),
|
||||||
MouseCursor::ContextMenu => load(b"context-menu\0"),
|
CursorIcon::ContextMenu => load(b"context-menu\0"),
|
||||||
|
|
||||||
MouseCursor::NoDrop => loadn(&[b"no-drop\0", b"circle\0"]),
|
CursorIcon::NoDrop => loadn(&[b"no-drop\0", b"circle\0"]),
|
||||||
MouseCursor::NotAllowed => load(b"crossed_circle\0"),
|
CursorIcon::NotAllowed => load(b"crossed_circle\0"),
|
||||||
|
|
||||||
|
|
||||||
// Resize cursors
|
// Resize cursors
|
||||||
MouseCursor::EResize => load(b"right_side\0"),
|
CursorIcon::EResize => load(b"right_side\0"),
|
||||||
MouseCursor::NResize => load(b"top_side\0"),
|
CursorIcon::NResize => load(b"top_side\0"),
|
||||||
MouseCursor::NeResize => load(b"top_right_corner\0"),
|
CursorIcon::NeResize => load(b"top_right_corner\0"),
|
||||||
MouseCursor::NwResize => load(b"top_left_corner\0"),
|
CursorIcon::NwResize => load(b"top_left_corner\0"),
|
||||||
MouseCursor::SResize => load(b"bottom_side\0"),
|
CursorIcon::SResize => load(b"bottom_side\0"),
|
||||||
MouseCursor::SeResize => load(b"bottom_right_corner\0"),
|
CursorIcon::SeResize => load(b"bottom_right_corner\0"),
|
||||||
MouseCursor::SwResize => load(b"bottom_left_corner\0"),
|
CursorIcon::SwResize => load(b"bottom_left_corner\0"),
|
||||||
MouseCursor::WResize => load(b"left_side\0"),
|
CursorIcon::WResize => load(b"left_side\0"),
|
||||||
MouseCursor::EwResize => load(b"h_double_arrow\0"),
|
CursorIcon::EwResize => load(b"h_double_arrow\0"),
|
||||||
MouseCursor::NsResize => load(b"v_double_arrow\0"),
|
CursorIcon::NsResize => load(b"v_double_arrow\0"),
|
||||||
MouseCursor::NwseResize => loadn(&[b"bd_double_arrow\0", b"size_bdiag\0"]),
|
CursorIcon::NwseResize => loadn(&[b"bd_double_arrow\0", b"size_bdiag\0"]),
|
||||||
MouseCursor::NeswResize => loadn(&[b"fd_double_arrow\0", b"size_fdiag\0"]),
|
CursorIcon::NeswResize => loadn(&[b"fd_double_arrow\0", b"size_fdiag\0"]),
|
||||||
MouseCursor::ColResize => loadn(&[b"split_h\0", b"h_double_arrow\0"]),
|
CursorIcon::ColResize => loadn(&[b"split_h\0", b"h_double_arrow\0"]),
|
||||||
MouseCursor::RowResize => loadn(&[b"split_v\0", b"v_double_arrow\0"]),
|
CursorIcon::RowResize => loadn(&[b"split_v\0", b"v_double_arrow\0"]),
|
||||||
|
|
||||||
MouseCursor::Text => loadn(&[b"text\0", b"xterm\0"]),
|
CursorIcon::Text => loadn(&[b"text\0", b"xterm\0"]),
|
||||||
MouseCursor::VerticalText => load(b"vertical-text\0"),
|
CursorIcon::VerticalText => load(b"vertical-text\0"),
|
||||||
|
|
||||||
MouseCursor::Wait => load(b"watch\0"),
|
CursorIcon::Wait => load(b"watch\0"),
|
||||||
|
|
||||||
MouseCursor::ZoomIn => load(b"zoom-in\0"),
|
CursorIcon::ZoomIn => load(b"zoom-in\0"),
|
||||||
MouseCursor::ZoomOut => load(b"zoom-out\0"),
|
CursorIcon::ZoomOut => load(b"zoom-out\0"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,9 +1068,9 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||||
*self.cursor.lock() = cursor;
|
*self.cursor.lock() = cursor;
|
||||||
if !*self.cursor_hidden.lock() {
|
if *self.cursor_visible.lock() {
|
||||||
self.update_cursor(self.get_cursor(cursor));
|
self.update_cursor(self.get_cursor(cursor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1117,7 +1114,7 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
let mut grabbed_lock = self.cursor_grabbed.lock();
|
let mut grabbed_lock = self.cursor_grabbed.lock();
|
||||||
if grab == *grabbed_lock { return Ok(()); }
|
if grab == *grabbed_lock { return Ok(()); }
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -1161,10 +1158,10 @@ impl UnownedWindow {
|
||||||
ffi::GrabNotViewable => Err("Cursor could not be grabbed: grab location not viewable"),
|
ffi::GrabNotViewable => Err("Cursor could not be grabbed: grab location not viewable"),
|
||||||
ffi::GrabFrozen => Err("Cursor could not be grabbed: frozen by another client"),
|
ffi::GrabFrozen => Err("Cursor could not be grabbed: frozen by another client"),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}.map_err(|err| err.to_owned())
|
}.map_err(|err| ExternalError::Os(os_error!(OsError::XMisc(err))))
|
||||||
} else {
|
} else {
|
||||||
self.xconn.flush_requests()
|
self.xconn.flush_requests()
|
||||||
.map_err(|err| format!("Failed to call `XUngrabPointer`: {:?}", err))
|
.map_err(|err| ExternalError::Os(os_error!(OsError::XError(err))))
|
||||||
};
|
};
|
||||||
if result.is_ok() {
|
if result.is_ok() {
|
||||||
*grabbed_lock = grab;
|
*grabbed_lock = grab;
|
||||||
|
@ -1173,25 +1170,25 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide_cursor(&self, hide: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
let mut hidden_lock = self.cursor_hidden.lock();
|
let mut visible_lock = self.cursor_visible.lock();
|
||||||
if hide == *hidden_lock {return; }
|
if visible == *visible_lock {return; }
|
||||||
let cursor = if hide {
|
let cursor = if visible {
|
||||||
self.create_empty_cursor().expect("Failed to create empty cursor")
|
|
||||||
} else {
|
|
||||||
self.get_cursor(*self.cursor.lock())
|
self.get_cursor(*self.cursor.lock())
|
||||||
|
} else {
|
||||||
|
self.create_empty_cursor().expect("Failed to create empty cursor")
|
||||||
};
|
};
|
||||||
*hidden_lock = hide;
|
*visible_lock = visible;
|
||||||
drop(hidden_lock);
|
drop(visible_lock);
|
||||||
self.update_cursor(cursor);
|
self.update_cursor(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
self.get_current_monitor().hidpi_factor
|
self.current_monitor().hidpi_factor
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), String> {
|
pub fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), ExternalError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
(self.xconn.xlib.XWarpPointer)(
|
(self.xconn.xlib.XWarpPointer)(
|
||||||
self.xconn.display,
|
self.xconn.display,
|
||||||
|
@ -1204,26 +1201,26 @@ impl UnownedWindow {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
);
|
);
|
||||||
self.xconn.flush_requests().map_err(|e| format!("`XWarpPointer` failed: {:?}", e))
|
self.xconn.flush_requests().map_err(|e| ExternalError::Os(os_error!(OsError::XError(e))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), String> {
|
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
let (x, y) = logical_position.to_physical(self.get_hidpi_factor()).into();
|
let (x, y) = logical_position.to_physical(self.hidpi_factor()).into();
|
||||||
self.set_cursor_position_physical(x, y)
|
self.set_cursor_position_physical(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_ime_spot_physical(&self, x: i32, y: i32) {
|
pub(crate) fn set_ime_position_physical(&self, x: i32, y: i32) {
|
||||||
let _ = self.ime_sender
|
let _ = self.ime_sender
|
||||||
.lock()
|
.lock()
|
||||||
.send((self.xwindow, x as i16, y as i16));
|
.send((self.xwindow, x as i16, y as i16));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_spot(&self, logical_spot: LogicalPosition) {
|
pub fn set_ime_position(&self, logical_spot: LogicalPosition) {
|
||||||
let (x, y) = logical_spot.to_physical(self.get_hidpi_factor()).into();
|
let (x, y) = logical_spot.to_physical(self.hidpi_factor()).into();
|
||||||
self.set_ime_spot_physical(x, y);
|
self.set_ime_position_physical(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -61,13 +61,13 @@ impl<T> EventLoop<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
monitor::get_available_monitors()
|
monitor::available_monitors()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
monitor::get_primary_monitor()
|
monitor::primary_monitor()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_target(&self) -> &RootWindowTarget<T> {
|
pub fn window_target(&self) -> &RootWindowTarget<T> {
|
||||||
|
|
|
@ -13,10 +13,11 @@ mod view;
|
||||||
mod window;
|
mod window;
|
||||||
mod window_delegate;
|
mod window_delegate;
|
||||||
|
|
||||||
use std::{ops::Deref, sync::Arc};
|
use std::{fmt, ops::Deref, sync::Arc};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
event::DeviceId as RootDeviceId, window::{CreationError, WindowAttributes},
|
event::DeviceId as RootDeviceId, window::WindowAttributes,
|
||||||
|
error::OsError as RootOsError,
|
||||||
};
|
};
|
||||||
pub use self::{
|
pub use self::{
|
||||||
event_loop::{EventLoop, EventLoopWindowTarget, Proxy as EventLoopProxy},
|
event_loop::{EventLoop, EventLoopWindowTarget, Proxy as EventLoopProxy},
|
||||||
|
@ -44,6 +45,12 @@ pub struct Window {
|
||||||
_delegate: util::IdRef,
|
_delegate: util::IdRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum OsError {
|
||||||
|
CGError(core_graphics::base::CGError),
|
||||||
|
CreationError(&'static str)
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl Send for Window {}
|
unsafe impl Send for Window {}
|
||||||
unsafe impl Sync for Window {}
|
unsafe impl Sync for Window {}
|
||||||
|
|
||||||
|
@ -60,8 +67,17 @@ impl Window {
|
||||||
_window_target: &EventLoopWindowTarget<T>,
|
_window_target: &EventLoopWindowTarget<T>,
|
||||||
attributes: WindowAttributes,
|
attributes: WindowAttributes,
|
||||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||||
) -> Result<Self, CreationError> {
|
) -> Result<Self, RootOsError> {
|
||||||
let (window, _delegate) = UnownedWindow::new(attributes, pl_attribs)?;
|
let (window, _delegate) = UnownedWindow::new(attributes, pl_attribs)?;
|
||||||
Ok(Window { window, _delegate })
|
Ok(Window { window, _delegate })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for OsError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
OsError::CGError(e) => f.pad(&format!("CGError {}", e)),
|
||||||
|
OsError::CreationError(e) => f.pad(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use platform_impl::platform::util::IdRef;
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct MonitorHandle(CGDirectDisplayID);
|
pub struct MonitorHandle(CGDirectDisplayID);
|
||||||
|
|
||||||
pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
|
pub fn available_monitors() -> VecDeque<MonitorHandle> {
|
||||||
if let Ok(displays) = CGDisplay::active_displays() {
|
if let Ok(displays) = CGDisplay::active_displays() {
|
||||||
let mut monitors = VecDeque::with_capacity(displays.len());
|
let mut monitors = VecDeque::with_capacity(displays.len());
|
||||||
for display in displays {
|
for display in displays {
|
||||||
|
@ -21,7 +21,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor() -> MonitorHandle {
|
pub fn primary_monitor() -> MonitorHandle {
|
||||||
MonitorHandle(CGDisplay::main().id)
|
MonitorHandle(CGDisplay::main().id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,11 +38,11 @@ impl fmt::Debug for MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
let monitor_id_proxy = MonitorHandle {
|
let monitor_id_proxy = MonitorHandle {
|
||||||
name: self.get_name(),
|
name: self.name(),
|
||||||
native_identifier: self.get_native_identifier(),
|
native_identifier: self.native_identifier(),
|
||||||
dimensions: self.get_dimensions(),
|
dimensions: self.dimensions(),
|
||||||
position: self.get_position(),
|
position: self.position(),
|
||||||
hidpi_factor: self.get_hidpi_factor(),
|
hidpi_factor: self.hidpi_factor(),
|
||||||
};
|
};
|
||||||
|
|
||||||
monitor_id_proxy.fmt(f)
|
monitor_id_proxy.fmt(f)
|
||||||
|
@ -54,48 +54,48 @@ impl MonitorHandle {
|
||||||
MonitorHandle(id)
|
MonitorHandle(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
let MonitorHandle(display_id) = *self;
|
let MonitorHandle(display_id) = *self;
|
||||||
let screen_num = CGDisplay::new(display_id).model_number();
|
let screen_num = CGDisplay::new(display_id).model_number();
|
||||||
Some(format!("Monitor #{}", screen_num))
|
Some(format!("Monitor #{}", screen_num))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_native_identifier(&self) -> u32 {
|
pub fn native_identifier(&self) -> u32 {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
let MonitorHandle(display_id) = *self;
|
let MonitorHandle(display_id) = *self;
|
||||||
let display = CGDisplay::new(display_id);
|
let display = CGDisplay::new(display_id);
|
||||||
let height = display.pixels_high();
|
let height = display.pixels_high();
|
||||||
let width = display.pixels_wide();
|
let width = display.pixels_wide();
|
||||||
PhysicalSize::from_logical(
|
PhysicalSize::from_logical(
|
||||||
(width as f64, height as f64),
|
(width as f64, height as f64),
|
||||||
self.get_hidpi_factor(),
|
self.hidpi_factor(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn position(&self) -> PhysicalPosition {
|
||||||
let bounds = unsafe { CGDisplayBounds(self.get_native_identifier()) };
|
let bounds = unsafe { CGDisplayBounds(self.native_identifier()) };
|
||||||
PhysicalPosition::from_logical(
|
PhysicalPosition::from_logical(
|
||||||
(bounds.origin.x as f64, bounds.origin.y as f64),
|
(bounds.origin.x as f64, bounds.origin.y as f64),
|
||||||
self.get_hidpi_factor(),
|
self.hidpi_factor(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
let screen = match self.get_nsscreen() {
|
let screen = match self.nsscreen() {
|
||||||
Some(screen) => screen,
|
Some(screen) => screen,
|
||||||
None => return 1.0, // default to 1.0 when we can't find the screen
|
None => return 1.0, // default to 1.0 when we can't find the screen
|
||||||
};
|
};
|
||||||
unsafe { NSScreen::backingScaleFactor(screen) as f64 }
|
unsafe { NSScreen::backingScaleFactor(screen) as f64 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_nsscreen(&self) -> Option<id> {
|
pub(crate) fn nsscreen(&self) -> Option<id> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let native_id = self.get_native_identifier();
|
let native_id = self.native_identifier();
|
||||||
let screens = NSScreen::screens(nil);
|
let screens = NSScreen::screens(nil);
|
||||||
let count: NSUInteger = msg_send![screens, count];
|
let count: NSUInteger = msg_send![screens, count];
|
||||||
let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber"));
|
let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber"));
|
||||||
|
|
|
@ -4,7 +4,7 @@ use cocoa::{
|
||||||
};
|
};
|
||||||
use objc::runtime::Sel;
|
use objc::runtime::Sel;
|
||||||
|
|
||||||
use window::MouseCursor;
|
use window::CursorIcon;
|
||||||
|
|
||||||
pub enum Cursor {
|
pub enum Cursor {
|
||||||
Native(&'static str),
|
Native(&'static str),
|
||||||
|
@ -12,54 +12,54 @@ pub enum Cursor {
|
||||||
WebKit(&'static str),
|
WebKit(&'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MouseCursor> for Cursor {
|
impl From<CursorIcon> for Cursor {
|
||||||
fn from(cursor: MouseCursor) -> Self {
|
fn from(cursor: CursorIcon) -> Self {
|
||||||
match cursor {
|
match cursor {
|
||||||
MouseCursor::Arrow | MouseCursor::Default => Cursor::Native("arrowCursor"),
|
CursorIcon::Arrow | CursorIcon::Default => Cursor::Native("arrowCursor"),
|
||||||
MouseCursor::Hand => Cursor::Native("pointingHandCursor"),
|
CursorIcon::Hand => Cursor::Native("pointingHandCursor"),
|
||||||
MouseCursor::Grabbing | MouseCursor::Grab => Cursor::Native("closedHandCursor"),
|
CursorIcon::Grabbing | CursorIcon::Grab => Cursor::Native("closedHandCursor"),
|
||||||
MouseCursor::Text => Cursor::Native("IBeamCursor"),
|
CursorIcon::Text => Cursor::Native("IBeamCursor"),
|
||||||
MouseCursor::VerticalText => Cursor::Native("IBeamCursorForVerticalLayout"),
|
CursorIcon::VerticalText => Cursor::Native("IBeamCursorForVerticalLayout"),
|
||||||
MouseCursor::Copy => Cursor::Native("dragCopyCursor"),
|
CursorIcon::Copy => Cursor::Native("dragCopyCursor"),
|
||||||
MouseCursor::Alias => Cursor::Native("dragLinkCursor"),
|
CursorIcon::Alias => Cursor::Native("dragLinkCursor"),
|
||||||
MouseCursor::NotAllowed | MouseCursor::NoDrop => Cursor::Native("operationNotAllowedCursor"),
|
CursorIcon::NotAllowed | CursorIcon::NoDrop => Cursor::Native("operationNotAllowedCursor"),
|
||||||
MouseCursor::ContextMenu => Cursor::Native("contextualMenuCursor"),
|
CursorIcon::ContextMenu => Cursor::Native("contextualMenuCursor"),
|
||||||
MouseCursor::Crosshair => Cursor::Native("crosshairCursor"),
|
CursorIcon::Crosshair => Cursor::Native("crosshairCursor"),
|
||||||
MouseCursor::EResize => Cursor::Native("resizeRightCursor"),
|
CursorIcon::EResize => Cursor::Native("resizeRightCursor"),
|
||||||
MouseCursor::NResize => Cursor::Native("resizeUpCursor"),
|
CursorIcon::NResize => Cursor::Native("resizeUpCursor"),
|
||||||
MouseCursor::WResize => Cursor::Native("resizeLeftCursor"),
|
CursorIcon::WResize => Cursor::Native("resizeLeftCursor"),
|
||||||
MouseCursor::SResize => Cursor::Native("resizeDownCursor"),
|
CursorIcon::SResize => Cursor::Native("resizeDownCursor"),
|
||||||
MouseCursor::EwResize | MouseCursor::ColResize => Cursor::Native("resizeLeftRightCursor"),
|
CursorIcon::EwResize | CursorIcon::ColResize => Cursor::Native("resizeLeftRightCursor"),
|
||||||
MouseCursor::NsResize | MouseCursor::RowResize => Cursor::Native("resizeUpDownCursor"),
|
CursorIcon::NsResize | CursorIcon::RowResize => Cursor::Native("resizeUpDownCursor"),
|
||||||
|
|
||||||
// Undocumented cursors: https://stackoverflow.com/a/46635398/5435443
|
// Undocumented cursors: https://stackoverflow.com/a/46635398/5435443
|
||||||
MouseCursor::Help => Cursor::Undocumented("_helpCursor"),
|
CursorIcon::Help => Cursor::Undocumented("_helpCursor"),
|
||||||
MouseCursor::ZoomIn => Cursor::Undocumented("_zoomInCursor"),
|
CursorIcon::ZoomIn => Cursor::Undocumented("_zoomInCursor"),
|
||||||
MouseCursor::ZoomOut => Cursor::Undocumented("_zoomOutCursor"),
|
CursorIcon::ZoomOut => Cursor::Undocumented("_zoomOutCursor"),
|
||||||
MouseCursor::NeResize => Cursor::Undocumented("_windowResizeNorthEastCursor"),
|
CursorIcon::NeResize => Cursor::Undocumented("_windowResizeNorthEastCursor"),
|
||||||
MouseCursor::NwResize => Cursor::Undocumented("_windowResizeNorthWestCursor"),
|
CursorIcon::NwResize => Cursor::Undocumented("_windowResizeNorthWestCursor"),
|
||||||
MouseCursor::SeResize => Cursor::Undocumented("_windowResizeSouthEastCursor"),
|
CursorIcon::SeResize => Cursor::Undocumented("_windowResizeSouthEastCursor"),
|
||||||
MouseCursor::SwResize => Cursor::Undocumented("_windowResizeSouthWestCursor"),
|
CursorIcon::SwResize => Cursor::Undocumented("_windowResizeSouthWestCursor"),
|
||||||
MouseCursor::NeswResize => Cursor::Undocumented("_windowResizeNorthEastSouthWestCursor"),
|
CursorIcon::NeswResize => Cursor::Undocumented("_windowResizeNorthEastSouthWestCursor"),
|
||||||
MouseCursor::NwseResize => Cursor::Undocumented("_windowResizeNorthWestSouthEastCursor"),
|
CursorIcon::NwseResize => Cursor::Undocumented("_windowResizeNorthWestSouthEastCursor"),
|
||||||
|
|
||||||
// While these are available, the former just loads a white arrow,
|
// While these are available, the former just loads a white arrow,
|
||||||
// and the latter loads an ugly deflated beachball!
|
// and the latter loads an ugly deflated beachball!
|
||||||
// MouseCursor::Move => Cursor::Undocumented("_moveCursor"),
|
// CursorIcon::Move => Cursor::Undocumented("_moveCursor"),
|
||||||
// MouseCursor::Wait => Cursor::Undocumented("_waitCursor"),
|
// CursorIcon::Wait => Cursor::Undocumented("_waitCursor"),
|
||||||
|
|
||||||
// An even more undocumented cursor...
|
// An even more undocumented cursor...
|
||||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=522349
|
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=522349
|
||||||
// This is the wrong semantics for `Wait`, but it's the same as
|
// This is the wrong semantics for `Wait`, but it's the same as
|
||||||
// what's used in Safari and Chrome.
|
// what's used in Safari and Chrome.
|
||||||
MouseCursor::Wait | MouseCursor::Progress => Cursor::Undocumented("busyButClickableCursor"),
|
CursorIcon::Wait | CursorIcon::Progress => Cursor::Undocumented("busyButClickableCursor"),
|
||||||
|
|
||||||
// For the rest, we can just snatch the cursors from WebKit...
|
// For the rest, we can just snatch the cursors from WebKit...
|
||||||
// They fit the style of the native cursors, and will seem
|
// They fit the style of the native cursors, and will seem
|
||||||
// completely standard to macOS users.
|
// completely standard to macOS users.
|
||||||
// https://stackoverflow.com/a/21786835/5435443
|
// https://stackoverflow.com/a/21786835/5435443
|
||||||
MouseCursor::Move | MouseCursor::AllScroll => Cursor::WebKit("move"),
|
CursorIcon::Move | CursorIcon::AllScroll => Cursor::WebKit("move"),
|
||||||
MouseCursor::Cell => Cursor::WebKit("cell"),
|
CursorIcon::Cell => Cursor::WebKit("cell"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ pub fn new_view(nswindow: id) -> (IdRef, Weak<Mutex<util::Cursor>>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn set_ime_spot(nsview: id, input_context: id, x: f64, y: f64) {
|
pub unsafe fn set_ime_position(nsview: id, input_context: id, x: f64, y: f64) {
|
||||||
let state_ptr: *mut c_void = *(*nsview).get_mut_ivar("winitState");
|
let state_ptr: *mut c_void = *(*nsview).get_mut_ivar("winitState");
|
||||||
let state = &mut *(state_ptr as *mut ViewState);
|
let state = &mut *(state_ptr as *mut ViewState);
|
||||||
let content_rect = NSWindow::contentRectForFrameRect_(
|
let content_rect = NSWindow::contentRectForFrameRect_(
|
||||||
|
|
|
@ -17,13 +17,15 @@ use objc::{runtime::{Class, Object, Sel, BOOL, YES, NO}, declare::ClassDecl};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
dpi::{LogicalPosition, LogicalSize}, icon::Icon,
|
dpi::{LogicalPosition, LogicalSize}, icon::Icon,
|
||||||
|
error::{ExternalError, NotSupportedError, OsError as RootOsError},
|
||||||
monitor::MonitorHandle as RootMonitorHandle,
|
monitor::MonitorHandle as RootMonitorHandle,
|
||||||
window::{
|
window::{
|
||||||
CreationError, MouseCursor, WindowAttributes, WindowId as RootWindowId,
|
CursorIcon, WindowAttributes, WindowId as RootWindowId,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use platform::macos::{ActivationPolicy, WindowExtMacOS};
|
use platform::macos::{ActivationPolicy, WindowExtMacOS};
|
||||||
use platform_impl::platform::{
|
use platform_impl::platform::{
|
||||||
|
OsError,
|
||||||
app_state::AppState, ffi, monitor::{self, MonitorHandle},
|
app_state::AppState, ffi, monitor::{self, MonitorHandle},
|
||||||
util::{self, IdRef}, view::{self, new_view},
|
util::{self, IdRef}, view::{self, new_view},
|
||||||
window_delegate::new_delegate,
|
window_delegate::new_delegate,
|
||||||
|
@ -102,7 +104,7 @@ fn create_window(
|
||||||
let pool = NSAutoreleasePool::new(nil);
|
let pool = NSAutoreleasePool::new(nil);
|
||||||
let screen = match attrs.fullscreen {
|
let screen = match attrs.fullscreen {
|
||||||
Some(ref monitor_id) => {
|
Some(ref monitor_id) => {
|
||||||
let monitor_screen = monitor_id.inner.get_nsscreen();
|
let monitor_screen = monitor_id.inner.nsscreen();
|
||||||
Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil)))
|
Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil)))
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -110,7 +112,7 @@ fn create_window(
|
||||||
let frame = match screen {
|
let frame = match screen {
|
||||||
Some(screen) => appkit::NSScreen::frame(screen),
|
Some(screen) => appkit::NSScreen::frame(screen),
|
||||||
None => {
|
None => {
|
||||||
let (width, height) = attrs.dimensions
|
let (width, height) = attrs.inner_size
|
||||||
.map(|logical| (logical.width, logical.height))
|
.map(|logical| (logical.width, logical.height))
|
||||||
.unwrap_or_else(|| (800.0, 600.0));
|
.unwrap_or_else(|| (800.0, 600.0));
|
||||||
NSRect::new(NSPoint::new(0.0, 0.0), NSSize::new(width, height))
|
NSRect::new(NSPoint::new(0.0, 0.0), NSSize::new(width, height))
|
||||||
|
@ -245,7 +247,7 @@ pub struct UnownedWindow {
|
||||||
pub shared_state: Arc<Mutex<SharedState>>,
|
pub shared_state: Arc<Mutex<SharedState>>,
|
||||||
decorations: AtomicBool,
|
decorations: AtomicBool,
|
||||||
cursor: Weak<Mutex<util::Cursor>>,
|
cursor: Weak<Mutex<util::Cursor>>,
|
||||||
cursor_hidden: AtomicBool,
|
cursor_visible: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for UnownedWindow {}
|
unsafe impl Send for UnownedWindow {}
|
||||||
|
@ -255,7 +257,7 @@ impl UnownedWindow {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut win_attribs: WindowAttributes,
|
mut win_attribs: WindowAttributes,
|
||||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||||
) -> Result<(Arc<Self>, IdRef), CreationError> {
|
) -> Result<(Arc<Self>, IdRef), RootOsError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !msg_send![class!(NSThread), isMainThread] {
|
if !msg_send![class!(NSThread), isMainThread] {
|
||||||
panic!("Windows can only be created on the main thread on macOS");
|
panic!("Windows can only be created on the main thread on macOS");
|
||||||
|
@ -266,17 +268,17 @@ impl UnownedWindow {
|
||||||
|
|
||||||
let nsapp = create_app(pl_attribs.activation_policy).ok_or_else(|| {
|
let nsapp = create_app(pl_attribs.activation_policy).ok_or_else(|| {
|
||||||
unsafe { pool.drain() };
|
unsafe { pool.drain() };
|
||||||
CreationError::OsError(format!("Couldn't create `NSApplication`"))
|
os_error!(OsError::CreationError("Couldn't create `NSApplication`"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let nswindow = create_window(&win_attribs, &pl_attribs).ok_or_else(|| {
|
let nswindow = create_window(&win_attribs, &pl_attribs).ok_or_else(|| {
|
||||||
unsafe { pool.drain() };
|
unsafe { pool.drain() };
|
||||||
CreationError::OsError(format!("Couldn't create `NSWindow`"))
|
os_error!(OsError::CreationError("Couldn't create `NSWindow`"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let (nsview, cursor) = unsafe { create_view(*nswindow) }.ok_or_else(|| {
|
let (nsview, cursor) = unsafe { create_view(*nswindow) }.ok_or_else(|| {
|
||||||
unsafe { pool.drain() };
|
unsafe { pool.drain() };
|
||||||
CreationError::OsError(format!("Couldn't create `NSView`"))
|
os_error!(OsError::CreationError("Couldn't create `NSView`"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let input_context = unsafe { util::create_input_context(*nsview) };
|
let input_context = unsafe { util::create_input_context(*nsview) };
|
||||||
|
@ -289,8 +291,8 @@ impl UnownedWindow {
|
||||||
|
|
||||||
nsapp.activateIgnoringOtherApps_(YES);
|
nsapp.activateIgnoringOtherApps_(YES);
|
||||||
|
|
||||||
win_attribs.min_dimensions.map(|dim| set_min_dimensions(*nswindow, dim));
|
win_attribs.min_inner_size.map(|dim| set_min_inner_size(*nswindow, dim));
|
||||||
win_attribs.max_dimensions.map(|dim| set_max_dimensions(*nswindow, dim));
|
win_attribs.max_inner_size.map(|dim| set_max_inner_size(*nswindow, dim));
|
||||||
|
|
||||||
use cocoa::foundation::NSArray;
|
use cocoa::foundation::NSArray;
|
||||||
// register for drag and drop operations.
|
// register for drag and drop operations.
|
||||||
|
@ -317,14 +319,14 @@ impl UnownedWindow {
|
||||||
shared_state: Arc::new(Mutex::new(win_attribs.into())),
|
shared_state: Arc::new(Mutex::new(win_attribs.into())),
|
||||||
decorations: AtomicBool::new(decorations),
|
decorations: AtomicBool::new(decorations),
|
||||||
cursor,
|
cursor,
|
||||||
cursor_hidden: Default::default(),
|
cursor_visible: AtomicBool::new(true),
|
||||||
});
|
});
|
||||||
|
|
||||||
let delegate = new_delegate(&window, fullscreen.is_some());
|
let delegate = new_delegate(&window, fullscreen.is_some());
|
||||||
|
|
||||||
// Set fullscreen mode after we setup everything
|
// Set fullscreen mode after we setup everything
|
||||||
if let Some(monitor) = fullscreen {
|
if let Some(monitor) = fullscreen {
|
||||||
if monitor.inner != window.get_current_monitor().inner {
|
if monitor.inner != window.current_monitor().inner {
|
||||||
// To do this with native fullscreen, we probably need to
|
// To do this with native fullscreen, we probably need to
|
||||||
// warp the window... while we could use
|
// warp the window... while we could use
|
||||||
// `enterFullScreenMode`, they're idiomatically different
|
// `enterFullScreenMode`, they're idiomatically different
|
||||||
|
@ -381,42 +383,39 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
pub fn set_visible(&self, visible: bool) {
|
||||||
pub fn show(&self) {
|
match visible {
|
||||||
unsafe { util::make_key_and_order_front_async(*self.nswindow) };
|
true => unsafe { util::make_key_and_order_front_async(*self.nswindow) },
|
||||||
}
|
false => unsafe { util::order_out_async(*self.nswindow) },
|
||||||
|
}
|
||||||
#[inline]
|
|
||||||
pub fn hide(&self) {
|
|
||||||
unsafe { util::order_out_async(*self.nswindow) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_redraw(&self) {
|
pub fn request_redraw(&self) {
|
||||||
AppState::queue_redraw(RootWindowId(self.id()));
|
AppState::queue_redraw(RootWindowId(self.id()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
let frame_rect = unsafe { NSWindow::frame(*self.nswindow) };
|
let frame_rect = unsafe { NSWindow::frame(*self.nswindow) };
|
||||||
Some((
|
Ok((
|
||||||
frame_rect.origin.x as f64,
|
frame_rect.origin.x as f64,
|
||||||
util::bottom_left_to_top_left(frame_rect),
|
util::bottom_left_to_top_left(frame_rect),
|
||||||
).into())
|
).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
let content_rect = unsafe {
|
let content_rect = unsafe {
|
||||||
NSWindow::contentRectForFrameRect_(
|
NSWindow::contentRectForFrameRect_(
|
||||||
*self.nswindow,
|
*self.nswindow,
|
||||||
NSWindow::frame(*self.nswindow),
|
NSWindow::frame(*self.nswindow),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
Some((
|
Ok((
|
||||||
content_rect.origin.x as f64,
|
content_rect.origin.x as f64,
|
||||||
util::bottom_left_to_top_left(content_rect),
|
util::bottom_left_to_top_left(content_rect),
|
||||||
).into())
|
).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&self, position: LogicalPosition) {
|
pub fn set_outer_position(&self, position: LogicalPosition) {
|
||||||
let dummy = NSRect::new(
|
let dummy = NSRect::new(
|
||||||
NSPoint::new(
|
NSPoint::new(
|
||||||
position.x,
|
position.x,
|
||||||
|
@ -432,15 +431,15 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn inner_size(&self) -> LogicalSize {
|
||||||
let view_frame = unsafe { NSView::frame(*self.nsview) };
|
let view_frame = unsafe { NSView::frame(*self.nsview) };
|
||||||
Some((view_frame.size.width as f64, view_frame.size.height as f64).into())
|
(view_frame.size.width as f64, view_frame.size.height as f64).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
pub fn outer_size(&self) -> LogicalSize {
|
||||||
let view_frame = unsafe { NSWindow::frame(*self.nswindow) };
|
let view_frame = unsafe { NSWindow::frame(*self.nswindow) };
|
||||||
Some((view_frame.size.width as f64, view_frame.size.height as f64).into())
|
(view_frame.size.width as f64, view_frame.size.height as f64).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -450,17 +449,17 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let dimensions = dimensions.unwrap_or_else(|| (0, 0).into());
|
let dimensions = dimensions.unwrap_or_else(|| (0, 0).into());
|
||||||
set_min_dimensions(*self.nswindow, dimensions);
|
set_min_inner_size(*self.nswindow, dimensions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let dimensions = dimensions.unwrap_or_else(|| (!0, !0).into());
|
let dimensions = dimensions.unwrap_or_else(|| (!0, !0).into());
|
||||||
set_max_dimensions(*self.nswindow, dimensions);
|
set_max_inner_size(*self.nswindow, dimensions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +483,7 @@ impl UnownedWindow {
|
||||||
} // Otherwise, we don't change the mask until we exit fullscreen.
|
} // Otherwise, we don't change the mask until we exit fullscreen.
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||||
let cursor = util::Cursor::from(cursor);
|
let cursor = util::Cursor::from(cursor);
|
||||||
if let Some(cursor_access) = self.cursor.upgrade() {
|
if let Some(cursor_access) = self.cursor.upgrade() {
|
||||||
*cursor_access.lock().unwrap() = cursor;
|
*cursor_access.lock().unwrap() = cursor;
|
||||||
|
@ -497,44 +496,43 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
// TODO: Do this for real https://stackoverflow.com/a/40922095/5435443
|
// TODO: Do this for real https://stackoverflow.com/a/40922095/5435443
|
||||||
CGDisplay::associate_mouse_and_mouse_cursor_position(!grab)
|
CGDisplay::associate_mouse_and_mouse_cursor_position(!grab)
|
||||||
.map_err(|status| format!("Failed to grab cursor: `CGError` {:?}", status))
|
.map_err(|status| ExternalError::Os(os_error!(OsError::CGError(status))))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide_cursor(&self, hide: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
let cursor_class = class!(NSCursor);
|
let cursor_class = class!(NSCursor);
|
||||||
// macOS uses a "hide counter" like Windows does, so we avoid incrementing it more than once.
|
// macOS uses a "hide counter" like Windows does, so we avoid incrementing it more than once.
|
||||||
// (otherwise, `hide_cursor(false)` would need to be called n times!)
|
// (otherwise, `hide_cursor(false)` would need to be called n times!)
|
||||||
if hide != self.cursor_hidden.load(Ordering::Acquire) {
|
if visible != self.cursor_visible.load(Ordering::Acquire) {
|
||||||
if hide {
|
if visible {
|
||||||
let _: () = unsafe { msg_send![cursor_class, hide] };
|
|
||||||
} else {
|
|
||||||
let _: () = unsafe { msg_send![cursor_class, unhide] };
|
let _: () = unsafe { msg_send![cursor_class, unhide] };
|
||||||
|
} else {
|
||||||
|
let _: () = unsafe { msg_send![cursor_class, hide] };
|
||||||
}
|
}
|
||||||
self.cursor_hidden.store(hide, Ordering::Release);
|
self.cursor_visible.store(visible, Ordering::Release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
unsafe { NSWindow::backingScaleFactor(*self.nswindow) as _ }
|
unsafe { NSWindow::backingScaleFactor(*self.nswindow) as _ }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_position(&self, cursor_position: LogicalPosition) -> Result<(), String> {
|
pub fn set_cursor_position(&self, cursor_position: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
let window_position = self.get_inner_position()
|
let window_position = self.inner_position().unwrap();
|
||||||
.ok_or("`get_inner_position` failed".to_owned())?;
|
|
||||||
let point = appkit::CGPoint {
|
let point = appkit::CGPoint {
|
||||||
x: (cursor_position.x + window_position.x) as CGFloat,
|
x: (cursor_position.x + window_position.x) as CGFloat,
|
||||||
y: (cursor_position.y + window_position.y) as CGFloat,
|
y: (cursor_position.y + window_position.y) as CGFloat,
|
||||||
};
|
};
|
||||||
CGDisplay::warp_mouse_cursor_position(point)
|
CGDisplay::warp_mouse_cursor_position(point)
|
||||||
.map_err(|e| format!("`CGWarpMouseCursorPosition` failed: {:?}", e))?;
|
.map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?;
|
||||||
CGDisplay::associate_mouse_and_mouse_cursor_position(true)
|
CGDisplay::associate_mouse_and_mouse_cursor_position(true)
|
||||||
.map_err(|e| format!("`CGAssociateMouseAndMouseCursorPosition` failed: {:?}", e))?;
|
.map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -637,7 +635,7 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||||
let shared_state_lock = self.shared_state.lock().unwrap();
|
let shared_state_lock = self.shared_state.lock().unwrap();
|
||||||
shared_state_lock.fullscreen.clone()
|
shared_state_lock.fullscreen.clone()
|
||||||
}
|
}
|
||||||
|
@ -736,9 +734,9 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_spot(&self, logical_spot: LogicalPosition) {
|
pub fn set_ime_position(&self, logical_spot: LogicalPosition) {
|
||||||
unsafe {
|
unsafe {
|
||||||
view::set_ime_spot(
|
view::set_ime_position(
|
||||||
*self.nsview,
|
*self.nsview,
|
||||||
*self.input_context,
|
*self.input_context,
|
||||||
logical_spot.x,
|
logical_spot.x,
|
||||||
|
@ -748,7 +746,7 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||||
unsafe {
|
unsafe {
|
||||||
let screen: id = msg_send![*self.nswindow, screen];
|
let screen: id = msg_send![*self.nswindow, screen];
|
||||||
let desc = NSScreen::deviceDescription(screen);
|
let desc = NSScreen::deviceDescription(screen);
|
||||||
|
@ -760,24 +758,24 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
monitor::get_available_monitors()
|
monitor::available_monitors()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
monitor::get_primary_monitor()
|
monitor::primary_monitor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowExtMacOS for UnownedWindow {
|
impl WindowExtMacOS for UnownedWindow {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_nswindow(&self) -> *mut c_void {
|
fn nswindow(&self) -> *mut c_void {
|
||||||
*self.nswindow as *mut _
|
*self.nswindow as *mut _
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_nsview(&self) -> *mut c_void {
|
fn nsview(&self) -> *mut c_void {
|
||||||
*self.nsview as *mut _
|
*self.nsview as *mut _
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,7 +790,7 @@ impl WindowExtMacOS for UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_simple_fullscreen(&self) -> bool {
|
fn simple_fullscreen(&self) -> bool {
|
||||||
let shared_state_lock = self.shared_state.lock().unwrap();
|
let shared_state_lock = self.shared_state.lock().unwrap();
|
||||||
shared_state_lock.is_simple_fullscreen
|
shared_state_lock.is_simple_fullscreen
|
||||||
}
|
}
|
||||||
|
@ -869,7 +867,7 @@ impl Drop for UnownedWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_min_dimensions<V: NSWindow + Copy>(window: V, mut min_size: LogicalSize) {
|
unsafe fn set_min_inner_size<V: NSWindow + Copy>(window: V, mut min_size: LogicalSize) {
|
||||||
let mut current_rect = NSWindow::frame(window);
|
let mut current_rect = NSWindow::frame(window);
|
||||||
let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
|
let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
|
||||||
// Convert from client area size to window size
|
// Convert from client area size to window size
|
||||||
|
@ -893,7 +891,7 @@ unsafe fn set_min_dimensions<V: NSWindow + Copy>(window: V, mut min_size: Logica
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_max_dimensions<V: NSWindow + Copy>(window: V, mut max_size: LogicalSize) {
|
unsafe fn set_max_inner_size<V: NSWindow + Copy>(window: V, mut max_size: LogicalSize) {
|
||||||
let mut current_rect = NSWindow::frame(window);
|
let mut current_rect = NSWindow::frame(window);
|
||||||
let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
|
let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
|
||||||
// Convert from client area size to window size
|
// Convert from client area size to window size
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl WindowDelegateState {
|
||||||
window: &Arc<UnownedWindow>,
|
window: &Arc<UnownedWindow>,
|
||||||
initial_fullscreen: bool,
|
initial_fullscreen: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let dpi_factor = window.get_hidpi_factor();
|
let dpi_factor = window.hidpi_factor();
|
||||||
|
|
||||||
let mut delegate_state = WindowDelegateState {
|
let mut delegate_state = WindowDelegateState {
|
||||||
nswindow: window.nswindow.clone(),
|
nswindow: window.nswindow.clone(),
|
||||||
|
@ -408,7 +408,7 @@ extern fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
trace!("Triggered `windowDidEnterFullscreen:`");
|
trace!("Triggered `windowDidEnterFullscreen:`");
|
||||||
with_state(this, |state| {
|
with_state(this, |state| {
|
||||||
state.with_window(|window| {
|
state.with_window(|window| {
|
||||||
let monitor = window.get_current_monitor();
|
let monitor = window.current_monitor();
|
||||||
trace!("Locked shared state in `window_did_enter_fullscreen`");
|
trace!("Locked shared state in `window_did_enter_fullscreen`");
|
||||||
window.shared_state.lock().unwrap().fullscreen = Some(monitor);
|
window.shared_state.lock().unwrap().fullscreen = Some(monitor);
|
||||||
trace!("Unlocked shared state in `window_will_enter_fullscreen`");
|
trace!("Unlocked shared state in `window_will_enter_fullscreen`");
|
||||||
|
|
|
@ -144,7 +144,7 @@ pub fn dpi_to_scale_factor(dpi: u32) -> f64 {
|
||||||
dpi as f64 / BASE_DPI as f64
|
dpi as f64 / BASE_DPI as f64
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn get_hwnd_dpi(hwnd: HWND) -> u32 {
|
pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 {
|
||||||
let hdc = winuser::GetDC(hwnd);
|
let hdc = winuser::GetDC(hwnd);
|
||||||
if hdc.is_null() {
|
if hdc.is_null() {
|
||||||
panic!("[winit] `GetDC` returned null!");
|
panic!("[winit] `GetDC` returned null!");
|
||||||
|
@ -184,6 +184,6 @@ pub unsafe fn get_hwnd_dpi(hwnd: HWND) -> u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_hwnd_scale_factor(hwnd: HWND) -> f64 {
|
pub fn hwnd_scale_factor(hwnd: HWND) -> f64 {
|
||||||
dpi_to_scale_factor(unsafe { get_hwnd_dpi(hwnd) })
|
dpi_to_scale_factor(unsafe { hwnd_dpi(hwnd) })
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ use platform_impl::platform::dpi::{
|
||||||
become_dpi_aware,
|
become_dpi_aware,
|
||||||
dpi_to_scale_factor,
|
dpi_to_scale_factor,
|
||||||
enable_non_client_dpi_scaling,
|
enable_non_client_dpi_scaling,
|
||||||
get_hwnd_scale_factor,
|
hwnd_scale_factor,
|
||||||
};
|
};
|
||||||
use platform_impl::platform::drop_handler::FileDropHandler;
|
use platform_impl::platform::drop_handler::FileDropHandler;
|
||||||
use platform_impl::platform::event::{handle_extended_keys, process_key_params, vkey_to_winit_vkey};
|
use platform_impl::platform::event::{handle_extended_keys, process_key_params, vkey_to_winit_vkey};
|
||||||
|
@ -869,7 +869,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
|
|
||||||
let windowpos = lparam as *const winuser::WINDOWPOS;
|
let windowpos = lparam as *const winuser::WINDOWPOS;
|
||||||
if (*windowpos).flags & winuser::SWP_NOMOVE != winuser::SWP_NOMOVE {
|
if (*windowpos).flags & winuser::SWP_NOMOVE != winuser::SWP_NOMOVE {
|
||||||
let dpi_factor = get_hwnd_scale_factor(window);
|
let dpi_factor = hwnd_scale_factor(window);
|
||||||
let logical_position = LogicalPosition::from_physical(
|
let logical_position = LogicalPosition::from_physical(
|
||||||
((*windowpos).x, (*windowpos).y),
|
((*windowpos).x, (*windowpos).y),
|
||||||
dpi_factor,
|
dpi_factor,
|
||||||
|
@ -889,7 +889,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
let w = LOWORD(lparam as DWORD) as u32;
|
let w = LOWORD(lparam as DWORD) as u32;
|
||||||
let h = HIWORD(lparam as DWORD) as u32;
|
let h = HIWORD(lparam as DWORD) as u32;
|
||||||
|
|
||||||
let dpi_factor = get_hwnd_scale_factor(window);
|
let dpi_factor = hwnd_scale_factor(window);
|
||||||
let logical_size = LogicalSize::from_physical((w, h), dpi_factor);
|
let logical_size = LogicalSize::from_physical((w, h), dpi_factor);
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
window_id: RootWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
|
@ -954,7 +954,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
|
|
||||||
let x = windowsx::GET_X_LPARAM(lparam) as f64;
|
let x = windowsx::GET_X_LPARAM(lparam) as f64;
|
||||||
let y = windowsx::GET_Y_LPARAM(lparam) as f64;
|
let y = windowsx::GET_Y_LPARAM(lparam) as f64;
|
||||||
let dpi_factor = get_hwnd_scale_factor(window);
|
let dpi_factor = hwnd_scale_factor(window);
|
||||||
let position = LogicalPosition::from_physical((x, y), dpi_factor);
|
let position = LogicalPosition::from_physical((x, y), dpi_factor);
|
||||||
|
|
||||||
subclass_input.send_event(Event::WindowEvent {
|
subclass_input.send_event(Event::WindowEvent {
|
||||||
|
@ -1305,7 +1305,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
inputs.as_mut_ptr(),
|
inputs.as_mut_ptr(),
|
||||||
mem::size_of::<winuser::TOUCHINPUT>() as INT,
|
mem::size_of::<winuser::TOUCHINPUT>() as INT,
|
||||||
) > 0 {
|
) > 0 {
|
||||||
let dpi_factor = get_hwnd_scale_factor(window);
|
let dpi_factor = hwnd_scale_factor(window);
|
||||||
for input in &inputs {
|
for input in &inputs {
|
||||||
let x = (input.x as f64) / 100f64;
|
let x = (input.x as f64) / 100f64;
|
||||||
let y = (input.y as f64) / 100f64;
|
let y = (input.y as f64) / 100f64;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{self, mem, ptr};
|
use std::{mem, ptr, io};
|
||||||
use std::os::windows::ffi::OsStrExt;
|
use std::os::windows::ffi::OsStrExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ use winapi::shared::windef::{HICON, HWND};
|
||||||
use winapi::um::winuser;
|
use winapi::um::winuser;
|
||||||
|
|
||||||
use icon::{Pixel, PIXEL_SIZE, Icon};
|
use icon::{Pixel, PIXEL_SIZE, Icon};
|
||||||
use platform_impl::platform::util;
|
|
||||||
|
|
||||||
impl Pixel {
|
impl Pixel {
|
||||||
fn to_bgra(&mut self) {
|
fn to_bgra(&mut self) {
|
||||||
|
@ -31,7 +30,7 @@ unsafe impl Send for WinIcon {}
|
||||||
|
|
||||||
impl WinIcon {
|
impl WinIcon {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, util::WinError> {
|
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> {
|
||||||
let wide_path: Vec<u16> = path.as_ref().as_os_str().encode_wide().collect();
|
let wide_path: Vec<u16> = path.as_ref().as_os_str().encode_wide().collect();
|
||||||
let handle = unsafe {
|
let handle = unsafe {
|
||||||
winuser::LoadImageW(
|
winuser::LoadImageW(
|
||||||
|
@ -46,15 +45,15 @@ impl WinIcon {
|
||||||
if !handle.is_null() {
|
if !handle.is_null() {
|
||||||
Ok(WinIcon { handle })
|
Ok(WinIcon { handle })
|
||||||
} else {
|
} else {
|
||||||
Err(util::WinError::from_last_error())
|
Err(io::Error::last_os_error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_icon(icon: Icon) -> Result<Self, util::WinError> {
|
pub fn from_icon(icon: Icon) -> Result<Self, io::Error> {
|
||||||
Self::from_rgba(icon.rgba, icon.width, icon.height)
|
Self::from_rgba(icon.rgba, icon.width, icon.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_rgba(mut rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, util::WinError> {
|
pub fn from_rgba(mut rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, io::Error> {
|
||||||
assert_eq!(rgba.len() % PIXEL_SIZE, 0);
|
assert_eq!(rgba.len() % PIXEL_SIZE, 0);
|
||||||
let pixel_count = rgba.len() / PIXEL_SIZE;
|
let pixel_count = rgba.len() / PIXEL_SIZE;
|
||||||
assert_eq!(pixel_count, (width * height) as usize);
|
assert_eq!(pixel_count, (width * height) as usize);
|
||||||
|
@ -80,7 +79,7 @@ impl WinIcon {
|
||||||
if !handle.is_null() {
|
if !handle.is_null() {
|
||||||
Ok(WinIcon { handle })
|
Ok(WinIcon { handle })
|
||||||
} else {
|
} else {
|
||||||
Err(util::WinError::from_last_error())
|
Err(io::Error::last_os_error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ impl DeviceId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceId {
|
impl DeviceId {
|
||||||
pub fn get_persistent_identifier(&self) -> Option<String> {
|
pub fn persistent_identifier(&self) -> Option<String> {
|
||||||
if self.0 != 0 {
|
if self.0 != 0 {
|
||||||
raw_input::get_raw_input_device_name(self.0 as _)
|
raw_input::get_raw_input_device_name(self.0 as _)
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,6 +52,8 @@ fn wrap_device_id(id: u32) -> RootDeviceId {
|
||||||
RootDeviceId(DeviceId(id))
|
RootDeviceId(DeviceId(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type OsError = std::io::Error;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct WindowId(HWND);
|
pub struct WindowId(HWND);
|
||||||
unsafe impl Send for WindowId {}
|
unsafe impl Send for WindowId {}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use winapi::shared::windef::{HDC, HMONITOR, HWND, LPRECT, POINT};
|
||||||
use winapi::um::winnt::LONG;
|
use winapi::um::winnt::LONG;
|
||||||
use winapi::um::winuser;
|
use winapi::um::winuser;
|
||||||
|
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr, io};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use super::{EventLoop, util};
|
use super::{EventLoop, util};
|
||||||
|
@ -50,7 +50,7 @@ unsafe extern "system" fn monitor_enum_proc(
|
||||||
TRUE // continue enumeration
|
TRUE // continue enumeration
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
|
pub fn available_monitors() -> VecDeque<MonitorHandle> {
|
||||||
let mut monitors: VecDeque<MonitorHandle> = VecDeque::new();
|
let mut monitors: VecDeque<MonitorHandle> = VecDeque::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
winuser::EnumDisplayMonitors(
|
winuser::EnumDisplayMonitors(
|
||||||
|
@ -63,7 +63,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
|
||||||
monitors
|
monitors
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor() -> MonitorHandle {
|
pub fn primary_monitor() -> MonitorHandle {
|
||||||
const ORIGIN: POINT = POINT { x: 0, y: 0 };
|
const ORIGIN: POINT = POINT { x: 0, y: 0 };
|
||||||
let hmonitor = unsafe {
|
let hmonitor = unsafe {
|
||||||
winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY)
|
winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY)
|
||||||
|
@ -71,7 +71,7 @@ pub fn get_primary_monitor() -> MonitorHandle {
|
||||||
MonitorHandle::from_hmonitor(hmonitor)
|
MonitorHandle::from_hmonitor(hmonitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_monitor(hwnd: HWND) -> MonitorHandle {
|
pub fn current_monitor(hwnd: HWND) -> MonitorHandle {
|
||||||
let hmonitor = unsafe {
|
let hmonitor = unsafe {
|
||||||
winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST)
|
winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST)
|
||||||
};
|
};
|
||||||
|
@ -80,26 +80,26 @@ pub fn get_current_monitor(hwnd: HWND) -> MonitorHandle {
|
||||||
|
|
||||||
impl<T> EventLoop<T> {
|
impl<T> EventLoop<T> {
|
||||||
// TODO: Investigate opportunities for caching
|
// TODO: Investigate opportunities for caching
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
get_available_monitors()
|
available_monitors()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
get_primary_monitor()
|
primary_monitor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||||
get_available_monitors()
|
available_monitors()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
get_primary_monitor()
|
primary_monitor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINFOEXW, util::WinError> {
|
pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINFOEXW, io::Error> {
|
||||||
let mut monitor_info: winuser::MONITORINFOEXW = unsafe { mem::uninitialized() };
|
let mut monitor_info: winuser::MONITORINFOEXW = unsafe { mem::uninitialized() };
|
||||||
monitor_info.cbSize = mem::size_of::<winuser::MONITORINFOEXW>() as DWORD;
|
monitor_info.cbSize = mem::size_of::<winuser::MONITORINFOEXW>() as DWORD;
|
||||||
let status = unsafe {
|
let status = unsafe {
|
||||||
|
@ -109,7 +109,7 @@ pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINF
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
if status == 0 {
|
if status == 0 {
|
||||||
Err(util::WinError::from_last_error())
|
Err(io::Error::last_os_error())
|
||||||
} else {
|
} else {
|
||||||
Ok(monitor_info)
|
Ok(monitor_info)
|
||||||
}
|
}
|
||||||
|
@ -142,32 +142,32 @@ impl MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
Some(self.monitor_name.clone())
|
Some(self.monitor_name.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_native_identifier(&self) -> String {
|
pub fn native_identifier(&self) -> String {
|
||||||
self.monitor_name.clone()
|
self.monitor_name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hmonitor(&self) -> HMONITOR {
|
pub fn hmonitor(&self) -> HMONITOR {
|
||||||
self.hmonitor.0
|
self.hmonitor.0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
pub fn dimensions(&self) -> PhysicalSize {
|
||||||
self.dimensions.into()
|
self.dimensions.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> PhysicalPosition {
|
pub fn position(&self) -> PhysicalPosition {
|
||||||
self.position.into()
|
self.position.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
self.hidpi_factor
|
self.hidpi_factor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,12 @@
|
||||||
use std::{self, mem, ptr, slice, io};
|
use std::{mem, ptr, slice, io};
|
||||||
use std::ops::BitAnd;
|
use std::ops::BitAnd;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use window::MouseCursor;
|
use window::CursorIcon;
|
||||||
use winapi::ctypes::wchar_t;
|
use winapi::ctypes::wchar_t;
|
||||||
use winapi::shared::minwindef::{BOOL, DWORD};
|
use winapi::shared::minwindef::{BOOL, DWORD};
|
||||||
use winapi::shared::windef::{HWND, POINT, RECT};
|
use winapi::shared::windef::{HWND, POINT, RECT};
|
||||||
use winapi::um::errhandlingapi::GetLastError;
|
use winapi::um::winbase::lstrlenW;
|
||||||
use winapi::um::winbase::{
|
|
||||||
FormatMessageW,
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
lstrlenW,
|
|
||||||
LocalFree,
|
|
||||||
};
|
|
||||||
use winapi::um::winnt::{
|
|
||||||
LPCWSTR,
|
|
||||||
MAKELANGID,
|
|
||||||
LANG_NEUTRAL,
|
|
||||||
SUBLANG_DEFAULT,
|
|
||||||
};
|
|
||||||
use winapi::um::winuser;
|
use winapi::um::winuser;
|
||||||
|
|
||||||
pub fn has_flag<T>(bitset: T, flag: T) -> bool
|
pub fn has_flag<T>(bitset: T, flag: T) -> bool
|
||||||
|
@ -117,66 +103,27 @@ pub fn is_focused(window: HWND) -> bool {
|
||||||
window == unsafe{ winuser::GetActiveWindow() }
|
window == unsafe{ winuser::GetActiveWindow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
impl CursorIcon {
|
||||||
pub struct WinError(Option<String>);
|
|
||||||
|
|
||||||
impl WinError {
|
|
||||||
pub fn from_last_error() -> Self {
|
|
||||||
WinError(unsafe { get_last_error() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn get_last_error() -> Option<String> {
|
|
||||||
let err = GetLastError();
|
|
||||||
if err != 0 {
|
|
||||||
let buf_addr: LPCWSTR = {
|
|
||||||
let mut buf_addr: LPCWSTR = mem::uninitialized();
|
|
||||||
FormatMessageW(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
|
||||||
| FORMAT_MESSAGE_FROM_SYSTEM
|
|
||||||
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
ptr::null(),
|
|
||||||
err,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) as DWORD,
|
|
||||||
// This is a pointer to a pointer
|
|
||||||
&mut buf_addr as *mut LPCWSTR as *mut _,
|
|
||||||
0,
|
|
||||||
ptr::null_mut(),
|
|
||||||
);
|
|
||||||
buf_addr
|
|
||||||
};
|
|
||||||
if !buf_addr.is_null() {
|
|
||||||
let buf_len = lstrlenW(buf_addr) as usize;
|
|
||||||
let buf_slice = std::slice::from_raw_parts(buf_addr, buf_len);
|
|
||||||
let string = wchar_to_string(buf_slice);
|
|
||||||
LocalFree(buf_addr as *mut _);
|
|
||||||
return Some(string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MouseCursor {
|
|
||||||
pub(crate) fn to_windows_cursor(self) -> *const wchar_t {
|
pub(crate) fn to_windows_cursor(self) -> *const wchar_t {
|
||||||
match self {
|
match self {
|
||||||
MouseCursor::Arrow | MouseCursor::Default => winuser::IDC_ARROW,
|
CursorIcon::Arrow | CursorIcon::Default => winuser::IDC_ARROW,
|
||||||
MouseCursor::Hand => winuser::IDC_HAND,
|
CursorIcon::Hand => winuser::IDC_HAND,
|
||||||
MouseCursor::Crosshair => winuser::IDC_CROSS,
|
CursorIcon::Crosshair => winuser::IDC_CROSS,
|
||||||
MouseCursor::Text | MouseCursor::VerticalText => winuser::IDC_IBEAM,
|
CursorIcon::Text | CursorIcon::VerticalText => winuser::IDC_IBEAM,
|
||||||
MouseCursor::NotAllowed | MouseCursor::NoDrop => winuser::IDC_NO,
|
CursorIcon::NotAllowed | CursorIcon::NoDrop => winuser::IDC_NO,
|
||||||
MouseCursor::Grab | MouseCursor::Grabbing |
|
CursorIcon::Grab | CursorIcon::Grabbing |
|
||||||
MouseCursor::Move | MouseCursor::AllScroll => winuser::IDC_SIZEALL,
|
CursorIcon::Move | CursorIcon::AllScroll => winuser::IDC_SIZEALL,
|
||||||
MouseCursor::EResize | MouseCursor::WResize |
|
CursorIcon::EResize | CursorIcon::WResize |
|
||||||
MouseCursor::EwResize | MouseCursor::ColResize => winuser::IDC_SIZEWE,
|
CursorIcon::EwResize | CursorIcon::ColResize => winuser::IDC_SIZEWE,
|
||||||
MouseCursor::NResize | MouseCursor::SResize |
|
CursorIcon::NResize | CursorIcon::SResize |
|
||||||
MouseCursor::NsResize | MouseCursor::RowResize => winuser::IDC_SIZENS,
|
CursorIcon::NsResize | CursorIcon::RowResize => winuser::IDC_SIZENS,
|
||||||
MouseCursor::NeResize | MouseCursor::SwResize |
|
CursorIcon::NeResize | CursorIcon::SwResize |
|
||||||
MouseCursor::NeswResize => winuser::IDC_SIZENESW,
|
CursorIcon::NeswResize => winuser::IDC_SIZENESW,
|
||||||
MouseCursor::NwResize | MouseCursor::SeResize |
|
CursorIcon::NwResize | CursorIcon::SeResize |
|
||||||
MouseCursor::NwseResize => winuser::IDC_SIZENWSE,
|
CursorIcon::NwseResize => winuser::IDC_SIZENWSE,
|
||||||
MouseCursor::Wait => winuser::IDC_WAIT,
|
CursorIcon::Wait => winuser::IDC_WAIT,
|
||||||
MouseCursor::Progress => winuser::IDC_APPSTARTING,
|
CursorIcon::Progress => winuser::IDC_APPSTARTING,
|
||||||
MouseCursor::Help => winuser::IDC_HELP,
|
CursorIcon::Help => winuser::IDC_HELP,
|
||||||
_ => winuser::IDC_ARROW, // use arrow for the missing cases.
|
_ => winuser::IDC_ARROW, // use arrow for the missing cases.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,13 @@ use winapi::um::wingdi::{CreateRectRgn, DeleteObject};
|
||||||
use winapi::um::oleidl::LPDROPTARGET;
|
use winapi::um::oleidl::LPDROPTARGET;
|
||||||
use winapi::um::winnt::{LONG, LPCWSTR};
|
use winapi::um::winnt::{LONG, LPCWSTR};
|
||||||
|
|
||||||
use window::{CreationError, Icon, MouseCursor, WindowAttributes};
|
use window::{Icon, CursorIcon, WindowAttributes};
|
||||||
|
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||||
use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||||
use monitor::MonitorHandle as RootMonitorHandle;
|
use monitor::MonitorHandle as RootMonitorHandle;
|
||||||
use platform_impl::platform::{
|
use platform_impl::platform::{
|
||||||
{PlatformSpecificWindowBuilderAttributes, WindowId},
|
{PlatformSpecificWindowBuilderAttributes, WindowId},
|
||||||
dpi::{dpi_to_scale_factor, get_hwnd_dpi},
|
dpi::{dpi_to_scale_factor, hwnd_dpi},
|
||||||
drop_handler::FileDropHandler,
|
drop_handler::FileDropHandler,
|
||||||
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID},
|
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID},
|
||||||
icon::{self, IconType, WinIcon},
|
icon::{self, IconType, WinIcon},
|
||||||
|
@ -50,7 +51,7 @@ impl Window {
|
||||||
event_loop: &EventLoopWindowTarget<T>,
|
event_loop: &EventLoopWindowTarget<T>,
|
||||||
w_attr: WindowAttributes,
|
w_attr: WindowAttributes,
|
||||||
pl_attr: PlatformSpecificWindowBuilderAttributes,
|
pl_attr: PlatformSpecificWindowBuilderAttributes,
|
||||||
) -> Result<Window, CreationError> {
|
) -> Result<Window, RootOsError> {
|
||||||
// We dispatch an `init` function because of code style.
|
// We dispatch an `init` function because of code style.
|
||||||
// First person to remove the need for cloning here gets a cookie!
|
// First person to remove the need for cloning here gets a cookie!
|
||||||
//
|
//
|
||||||
|
@ -103,16 +104,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn show(&self) {
|
pub fn set_visible(&self, visible: bool) {
|
||||||
unsafe {
|
match visible {
|
||||||
winuser::ShowWindow(self.window.0, winuser::SW_SHOW);
|
true => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_SHOW); },
|
||||||
}
|
false => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_HIDE); },
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn hide(&self) {
|
|
||||||
unsafe {
|
|
||||||
winuser::ShowWindow(self.window.0, winuser::SW_HIDE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,35 +127,32 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_position_physical(&self) -> Option<(i32, i32)> {
|
pub(crate) fn outer_position_physical(&self) -> (i32, i32) {
|
||||||
util::get_window_rect(self.window.0)
|
util::get_window_rect(self.window.0)
|
||||||
.map(|rect| (rect.left as i32, rect.top as i32))
|
.map(|rect| (rect.left as i32, rect.top as i32))
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
self.get_position_physical()
|
let physical_position = self.outer_position_physical();
|
||||||
.map(|physical_position| {
|
let dpi_factor = self.hidpi_factor();
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
|
||||||
LogicalPosition::from_physical(physical_position, dpi_factor)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_inner_position_physical(&self) -> Option<(i32, i32)> {
|
pub(crate) fn inner_position_physical(&self) -> (i32, i32) {
|
||||||
let mut position: POINT = unsafe { mem::zeroed() };
|
let mut position: POINT = unsafe { mem::zeroed() };
|
||||||
if unsafe { winuser::ClientToScreen(self.window.0, &mut position) } == 0 {
|
if unsafe { winuser::ClientToScreen(self.window.0, &mut position) } == 0 {
|
||||||
return None;
|
panic!("Unexpected ClientToScreen failure: please report this error to https://github.com/rust-windowing/winit")
|
||||||
}
|
}
|
||||||
Some((position.x, position.y))
|
(position.x, position.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
self.get_inner_position_physical()
|
let physical_position = self.inner_position_physical();
|
||||||
.map(|physical_position| {
|
let dpi_factor = self.hidpi_factor();
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
|
||||||
LogicalPosition::from_physical(physical_position, dpi_factor)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_position_physical(&self, x: i32, y: i32) {
|
pub(crate) fn set_position_physical(&self, x: i32, y: i32) {
|
||||||
|
@ -179,47 +171,44 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_position(&self, logical_position: LogicalPosition) {
|
pub fn set_outer_position(&self, logical_position: LogicalPosition) {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
let (x, y) = logical_position.to_physical(dpi_factor).into();
|
let (x, y) = logical_position.to_physical(dpi_factor).into();
|
||||||
self.set_position_physical(x, y);
|
self.set_position_physical(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_inner_size_physical(&self) -> Option<(u32, u32)> {
|
pub(crate) fn inner_size_physical(&self) -> (u32, u32) {
|
||||||
let mut rect: RECT = unsafe { mem::uninitialized() };
|
let mut rect: RECT = unsafe { mem::uninitialized() };
|
||||||
if unsafe { winuser::GetClientRect(self.window.0, &mut rect) } == 0 {
|
if unsafe { winuser::GetClientRect(self.window.0, &mut rect) } == 0 {
|
||||||
return None;
|
panic!("Unexpected GetClientRect failure: please report this error to https://github.com/rust-windowing/winit")
|
||||||
}
|
}
|
||||||
Some((
|
(
|
||||||
(rect.right - rect.left) as u32,
|
(rect.right - rect.left) as u32,
|
||||||
(rect.bottom - rect.top) as u32,
|
(rect.bottom - rect.top) as u32,
|
||||||
))
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn inner_size(&self) -> LogicalSize {
|
||||||
self.get_inner_size_physical()
|
let physical_size = self.inner_size_physical();
|
||||||
.map(|physical_size| {
|
let dpi_factor = self.hidpi_factor();
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
LogicalSize::from_physical(physical_size, dpi_factor)
|
||||||
LogicalSize::from_physical(physical_size, dpi_factor)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_outer_size_physical(&self) -> Option<(u32, u32)> {
|
pub(crate) fn outer_size_physical(&self) -> (u32, u32) {
|
||||||
util::get_window_rect(self.window.0)
|
util::get_window_rect(self.window.0)
|
||||||
.map(|rect| (
|
.map(|rect| (
|
||||||
(rect.right - rect.left) as u32,
|
(rect.right - rect.left) as u32,
|
||||||
(rect.bottom - rect.top) as u32,
|
(rect.bottom - rect.top) as u32,
|
||||||
))
|
))
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
pub fn outer_size(&self) -> LogicalSize {
|
||||||
self.get_outer_size_physical()
|
let physical_size = self.outer_size_physical();
|
||||||
.map(|physical_size| {
|
let dpi_factor = self.hidpi_factor();
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
LogicalSize::from_physical(physical_size, dpi_factor)
|
||||||
LogicalSize::from_physical(physical_size, dpi_factor)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_inner_size_physical(&self, x: u32, y: u32) {
|
pub(crate) fn set_inner_size_physical(&self, x: u32, y: u32) {
|
||||||
|
@ -254,41 +243,41 @@ impl Window {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_inner_size(&self, logical_size: LogicalSize) {
|
pub fn set_inner_size(&self, logical_size: LogicalSize) {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
let (width, height) = logical_size.to_physical(dpi_factor).into();
|
let (width, height) = logical_size.to_physical(dpi_factor).into();
|
||||||
self.set_inner_size_physical(width, height);
|
self.set_inner_size_physical(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_min_dimensions_physical(&self, dimensions: Option<(u32, u32)>) {
|
pub(crate) fn set_min_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||||
self.window_state.lock().min_size = dimensions.map(Into::into);
|
self.window_state.lock().min_size = dimensions.map(Into::into);
|
||||||
// Make windows re-check the window size bounds.
|
// Make windows re-check the window size bounds.
|
||||||
self.get_inner_size_physical()
|
let (width, height) = self.inner_size_physical();
|
||||||
.map(|(width, height)| self.set_inner_size_physical(width, height));
|
self.set_inner_size_physical(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_min_dimensions(&self, logical_size: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, logical_size: Option<LogicalSize>) {
|
||||||
let physical_size = logical_size.map(|logical_size| {
|
let physical_size = logical_size.map(|logical_size| {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
logical_size.to_physical(dpi_factor).into()
|
logical_size.to_physical(dpi_factor).into()
|
||||||
});
|
});
|
||||||
self.set_min_dimensions_physical(physical_size);
|
self.set_min_inner_size_physical(physical_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_max_dimensions_physical(&self, dimensions: Option<(u32, u32)>) {
|
pub fn set_max_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||||
self.window_state.lock().max_size = dimensions.map(Into::into);
|
self.window_state.lock().max_size = dimensions.map(Into::into);
|
||||||
// Make windows re-check the window size bounds.
|
// Make windows re-check the window size bounds.
|
||||||
self.get_inner_size_physical()
|
let (width, height) = self.inner_size_physical();
|
||||||
.map(|(width, height)| self.set_inner_size_physical(width, height));
|
self.set_inner_size_physical(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_max_dimensions(&self, logical_size: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, logical_size: Option<LogicalSize>) {
|
||||||
let physical_size = logical_size.map(|logical_size| {
|
let physical_size = logical_size.map(|logical_size| {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
logical_size.to_physical(dpi_factor).into()
|
logical_size.to_physical(dpi_factor).into()
|
||||||
});
|
});
|
||||||
self.set_max_dimensions_physical(physical_size);
|
self.set_max_inner_size_physical(physical_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -313,7 +302,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||||
self.window_state.lock().mouse.cursor = cursor;
|
self.window_state.lock().mouse.cursor = cursor;
|
||||||
self.thread_executor.execute_in_thread(move || unsafe {
|
self.thread_executor.execute_in_thread(move || unsafe {
|
||||||
let cursor = winuser::LoadCursorW(
|
let cursor = winuser::LoadCursorW(
|
||||||
|
@ -325,7 +314,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
let window = self.window.clone();
|
let window = self.window.clone();
|
||||||
let window_state = Arc::clone(&self.window_state);
|
let window_state = Arc::clone(&self.window_state);
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
@ -333,21 +322,21 @@ impl Window {
|
||||||
self.thread_executor.execute_in_thread(move || {
|
self.thread_executor.execute_in_thread(move || {
|
||||||
let result = window_state.lock().mouse
|
let result = window_state.lock().mouse
|
||||||
.set_cursor_flags(window.0, |f| f.set(CursorFlags::GRABBED, grab))
|
.set_cursor_flags(window.0, |f| f.set(CursorFlags::GRABBED, grab))
|
||||||
.map_err(|e| e.to_string());
|
.map_err(|e| ExternalError::Os(os_error!(e)));
|
||||||
let _ = tx.send(result);
|
let _ = tx.send(result);
|
||||||
});
|
});
|
||||||
rx.recv().unwrap()
|
rx.recv().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide_cursor(&self, hide: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
let window = self.window.clone();
|
let window = self.window.clone();
|
||||||
let window_state = Arc::clone(&self.window_state);
|
let window_state = Arc::clone(&self.window_state);
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
|
||||||
self.thread_executor.execute_in_thread(move || {
|
self.thread_executor.execute_in_thread(move || {
|
||||||
let result = window_state.lock().mouse
|
let result = window_state.lock().mouse
|
||||||
.set_cursor_flags(window.0, |f| f.set(CursorFlags::HIDDEN, hide))
|
.set_cursor_flags(window.0, |f| f.set(CursorFlags::HIDDEN, !visible))
|
||||||
.map_err(|e| e.to_string());
|
.map_err(|e| e.to_string());
|
||||||
let _ = tx.send(result);
|
let _ = tx.send(result);
|
||||||
});
|
});
|
||||||
|
@ -355,26 +344,26 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
self.window_state.lock().dpi_factor
|
self.window_state.lock().dpi_factor
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), String> {
|
fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), ExternalError> {
|
||||||
let mut point = POINT { x, y };
|
let mut point = POINT { x, y };
|
||||||
unsafe {
|
unsafe {
|
||||||
if winuser::ClientToScreen(self.window.0, &mut point) == 0 {
|
if winuser::ClientToScreen(self.window.0, &mut point) == 0 {
|
||||||
return Err("`ClientToScreen` failed".to_owned());
|
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||||
}
|
}
|
||||||
if winuser::SetCursorPos(point.x, point.y) == 0 {
|
if winuser::SetCursorPos(point.x, point.y) == 0 {
|
||||||
return Err("`SetCursorPos` failed".to_owned());
|
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), String> {
|
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
let dpi_factor = self.get_hidpi_factor();
|
let dpi_factor = self.hidpi_factor();
|
||||||
let (x, y) = logical_position.to_physical(dpi_factor).into();
|
let (x, y) = logical_position.to_physical(dpi_factor).into();
|
||||||
self.set_cursor_position_physical(x, y)
|
self.set_cursor_position_physical(x, y)
|
||||||
}
|
}
|
||||||
|
@ -400,7 +389,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||||
let window_state = self.window_state.lock();
|
let window_state = self.window_state.lock();
|
||||||
window_state.fullscreen.clone()
|
window_state.fullscreen.clone()
|
||||||
}
|
}
|
||||||
|
@ -413,8 +402,8 @@ impl Window {
|
||||||
|
|
||||||
match &monitor {
|
match &monitor {
|
||||||
&Some(RootMonitorHandle { ref inner }) => {
|
&Some(RootMonitorHandle { ref inner }) => {
|
||||||
let (x, y): (i32, i32) = inner.get_position().into();
|
let (x, y): (i32, i32) = inner.position().into();
|
||||||
let (width, height): (u32, u32) = inner.get_dimensions().into();
|
let (width, height): (u32, u32) = inner.dimensions().into();
|
||||||
|
|
||||||
let mut monitor = monitor.clone();
|
let mut monitor = monitor.clone();
|
||||||
self.thread_executor.execute_in_thread(move || {
|
self.thread_executor.execute_in_thread(move || {
|
||||||
|
@ -496,9 +485,9 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||||
RootMonitorHandle {
|
RootMonitorHandle {
|
||||||
inner: monitor::get_current_monitor(self.window.0),
|
inner: monitor::current_monitor(self.window.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,7 +518,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_spot(&self, _logical_spot: LogicalPosition) {
|
pub fn set_ime_position(&self, _logical_spot: LogicalPosition) {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,9 +564,9 @@ pub unsafe fn adjust_size(
|
||||||
|
|
||||||
unsafe fn init<T: 'static>(
|
unsafe fn init<T: 'static>(
|
||||||
mut attributes: WindowAttributes,
|
mut attributes: WindowAttributes,
|
||||||
mut pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||||
event_loop: &EventLoopWindowTarget<T>,
|
event_loop: &EventLoopWindowTarget<T>,
|
||||||
) -> Result<Window, CreationError> {
|
) -> Result<Window, RootOsError> {
|
||||||
let title = OsStr::new(&attributes.title)
|
let title = OsStr::new(&attributes.title)
|
||||||
.encode_wide()
|
.encode_wide()
|
||||||
.chain(Some(0).into_iter())
|
.chain(Some(0).into_iter())
|
||||||
|
@ -587,22 +576,18 @@ unsafe fn init<T: 'static>(
|
||||||
let icon = attributes.window_icon
|
let icon = attributes.window_icon
|
||||||
.take()
|
.take()
|
||||||
.map(WinIcon::from_icon);
|
.map(WinIcon::from_icon);
|
||||||
if icon.is_some() {
|
if let Some(icon) = icon {
|
||||||
Some(icon.unwrap().map_err(|err| {
|
Some(icon.map_err(|e| os_error!(e))?)
|
||||||
CreationError::OsError(format!("Failed to create `ICON_SMALL`: {:?}", err))
|
|
||||||
})?)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let taskbar_icon = {
|
let taskbar_icon = {
|
||||||
let icon = pl_attribs.taskbar_icon
|
let icon = attributes.window_icon
|
||||||
.take()
|
.take()
|
||||||
.map(WinIcon::from_icon);
|
.map(WinIcon::from_icon);
|
||||||
if icon.is_some() {
|
if let Some(icon) = icon {
|
||||||
Some(icon.unwrap().map_err(|err| {
|
Some(icon.map_err(|e| os_error!(e))?)
|
||||||
CreationError::OsError(format!("Failed to create `ICON_BIG`: {:?}", err))
|
|
||||||
})?)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -612,17 +597,17 @@ unsafe fn init<T: 'static>(
|
||||||
let class_name = register_window_class(&window_icon, &taskbar_icon);
|
let class_name = register_window_class(&window_icon, &taskbar_icon);
|
||||||
|
|
||||||
let guessed_dpi_factor = {
|
let guessed_dpi_factor = {
|
||||||
let monitors = monitor::get_available_monitors();
|
let monitors = monitor::available_monitors();
|
||||||
let dpi_factor = if !monitors.is_empty() {
|
let dpi_factor = if !monitors.is_empty() {
|
||||||
let mut dpi_factor = Some(monitors[0].get_hidpi_factor());
|
let mut dpi_factor = Some(monitors[0].hidpi_factor());
|
||||||
for monitor in &monitors {
|
for monitor in &monitors {
|
||||||
if Some(monitor.get_hidpi_factor()) != dpi_factor {
|
if Some(monitor.hidpi_factor()) != dpi_factor {
|
||||||
dpi_factor = None;
|
dpi_factor = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dpi_factor
|
dpi_factor
|
||||||
} else {
|
} else {
|
||||||
return Err(CreationError::OsError(format!("No monitors were detected.")));
|
return Err(os_error!(io::Error::new(io::ErrorKind::NotFound, "No monitors were detected.")));
|
||||||
};
|
};
|
||||||
dpi_factor.unwrap_or_else(|| {
|
dpi_factor.unwrap_or_else(|| {
|
||||||
util::get_cursor_pos()
|
util::get_cursor_pos()
|
||||||
|
@ -630,7 +615,7 @@ unsafe fn init<T: 'static>(
|
||||||
let mut dpi_factor = None;
|
let mut dpi_factor = None;
|
||||||
for monitor in &monitors {
|
for monitor in &monitors {
|
||||||
if monitor.contains_point(&cursor_pos) {
|
if monitor.contains_point(&cursor_pos) {
|
||||||
dpi_factor = Some(monitor.get_hidpi_factor());
|
dpi_factor = Some(monitor.hidpi_factor());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,7 +626,7 @@ unsafe fn init<T: 'static>(
|
||||||
};
|
};
|
||||||
info!("Guessed window DPI factor: {}", guessed_dpi_factor);
|
info!("Guessed window DPI factor: {}", guessed_dpi_factor);
|
||||||
|
|
||||||
let dimensions = attributes.dimensions.unwrap_or_else(|| (1024, 768).into());
|
let dimensions = attributes.inner_size.unwrap_or_else(|| (1024, 768).into());
|
||||||
|
|
||||||
let mut window_flags = WindowFlags::empty();
|
let mut window_flags = WindowFlags::empty();
|
||||||
window_flags.set(WindowFlags::DECORATIONS, attributes.decorations);
|
window_flags.set(WindowFlags::DECORATIONS, attributes.decorations);
|
||||||
|
@ -670,8 +655,7 @@ unsafe fn init<T: 'static>(
|
||||||
);
|
);
|
||||||
|
|
||||||
if handle.is_null() {
|
if handle.is_null() {
|
||||||
return Err(CreationError::OsError(format!("CreateWindowEx function failed: {}",
|
return Err(os_error!(io::Error::last_os_error()));
|
||||||
format!("{}", io::Error::last_os_error()))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowWrapper(handle)
|
WindowWrapper(handle)
|
||||||
|
@ -688,7 +672,7 @@ unsafe fn init<T: 'static>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let dpi = get_hwnd_dpi(real_window.0);
|
let dpi = hwnd_dpi(real_window.0);
|
||||||
let dpi_factor = dpi_to_scale_factor(dpi);
|
let dpi_factor = dpi_to_scale_factor(dpi);
|
||||||
if dpi_factor != guessed_dpi_factor {
|
if dpi_factor != guessed_dpi_factor {
|
||||||
let (width, height): (u32, u32) = dimensions.into();
|
let (width, height): (u32, u32) = dimensions.into();
|
||||||
|
@ -763,7 +747,7 @@ unsafe fn init<T: 'static>(
|
||||||
force_window_active(win.window.0);
|
force_window_active(win.window.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(dimensions) = attributes.dimensions {
|
if let Some(dimensions) = attributes.inner_size {
|
||||||
win.set_inner_size(dimensions);
|
win.set_inner_size(dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use monitor::MonitorHandle;
|
use monitor::MonitorHandle;
|
||||||
use window::{MouseCursor, WindowAttributes};
|
use window::{CursorIcon, WindowAttributes};
|
||||||
use std::{io, ptr};
|
use std::{io, ptr};
|
||||||
use parking_lot::MutexGuard;
|
use parking_lot::MutexGuard;
|
||||||
use dpi::LogicalSize;
|
use dpi::LogicalSize;
|
||||||
|
@ -36,7 +36,7 @@ pub struct SavedWindow {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MouseProperties {
|
pub struct MouseProperties {
|
||||||
pub cursor: MouseCursor,
|
pub cursor: CursorIcon,
|
||||||
pub buttons_down: u32,
|
pub buttons_down: u32,
|
||||||
cursor_flags: CursorFlags,
|
cursor_flags: CursorFlags,
|
||||||
}
|
}
|
||||||
|
@ -90,13 +90,13 @@ impl WindowState {
|
||||||
) -> WindowState {
|
) -> WindowState {
|
||||||
WindowState {
|
WindowState {
|
||||||
mouse: MouseProperties {
|
mouse: MouseProperties {
|
||||||
cursor: MouseCursor::default(),
|
cursor: CursorIcon::default(),
|
||||||
buttons_down: 0,
|
buttons_down: 0,
|
||||||
cursor_flags: CursorFlags::empty(),
|
cursor_flags: CursorFlags::empty(),
|
||||||
},
|
},
|
||||||
|
|
||||||
min_size: attributes.min_dimensions,
|
min_size: attributes.min_inner_size,
|
||||||
max_size: attributes.max_dimensions,
|
max_size: attributes.max_inner_size,
|
||||||
|
|
||||||
window_icon,
|
window_icon,
|
||||||
taskbar_icon,
|
taskbar_icon,
|
||||||
|
|
414
src/window.rs
414
src/window.rs
|
@ -1,7 +1,8 @@
|
||||||
//! The `Window` struct and associated types.
|
//! The `Window` struct and associated types.
|
||||||
use std::{fmt, error};
|
use std::fmt;
|
||||||
|
|
||||||
use platform_impl;
|
use platform_impl;
|
||||||
|
use error::{ExternalError, NotSupportedError, OsError};
|
||||||
use event_loop::EventLoopWindowTarget;
|
use event_loop::EventLoopWindowTarget;
|
||||||
use monitor::{AvailableMonitorsIter, MonitorHandle};
|
use monitor::{AvailableMonitorsIter, MonitorHandle};
|
||||||
use dpi::{LogicalPosition, LogicalSize};
|
use dpi::{LogicalPosition, LogicalSize};
|
||||||
|
@ -84,17 +85,17 @@ pub struct WindowAttributes {
|
||||||
/// used.
|
/// used.
|
||||||
///
|
///
|
||||||
/// The default is `None`.
|
/// The default is `None`.
|
||||||
pub dimensions: Option<LogicalSize>,
|
pub inner_size: Option<LogicalSize>,
|
||||||
|
|
||||||
/// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved).
|
/// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved).
|
||||||
///
|
///
|
||||||
/// The default is `None`.
|
/// The default is `None`.
|
||||||
pub min_dimensions: Option<LogicalSize>,
|
pub min_inner_size: Option<LogicalSize>,
|
||||||
|
|
||||||
/// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
|
/// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
|
||||||
///
|
///
|
||||||
/// The default is `None`.
|
/// The default is `None`.
|
||||||
pub max_dimensions: Option<LogicalSize>,
|
pub max_inner_size: Option<LogicalSize>,
|
||||||
|
|
||||||
/// Whether the window is resizable or not.
|
/// Whether the window is resizable or not.
|
||||||
///
|
///
|
||||||
|
@ -141,19 +142,15 @@ pub struct WindowAttributes {
|
||||||
///
|
///
|
||||||
/// The default is `None`.
|
/// The default is `None`.
|
||||||
pub window_icon: Option<Icon>,
|
pub window_icon: Option<Icon>,
|
||||||
|
|
||||||
/// [iOS only] Enable multitouch,
|
|
||||||
/// see [multipleTouchEnabled](https://developer.apple.com/documentation/uikit/uiview/1622519-multipletouchenabled)
|
|
||||||
pub multitouch: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WindowAttributes {
|
impl Default for WindowAttributes {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> WindowAttributes {
|
fn default() -> WindowAttributes {
|
||||||
WindowAttributes {
|
WindowAttributes {
|
||||||
dimensions: None,
|
inner_size: None,
|
||||||
min_dimensions: None,
|
min_inner_size: None,
|
||||||
max_dimensions: None,
|
max_inner_size: None,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
title: "winit window".to_owned(),
|
title: "winit window".to_owned(),
|
||||||
maximized: false,
|
maximized: false,
|
||||||
|
@ -163,7 +160,6 @@ impl Default for WindowAttributes {
|
||||||
decorations: true,
|
decorations: true,
|
||||||
always_on_top: false,
|
always_on_top: false,
|
||||||
window_icon: None,
|
window_icon: None,
|
||||||
multitouch: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,22 +175,22 @@ impl WindowBuilder {
|
||||||
|
|
||||||
/// Requests the window to be of specific dimensions.
|
/// Requests the window to be of specific dimensions.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_dimensions(mut self, size: LogicalSize) -> WindowBuilder {
|
pub fn with_inner_size(mut self, size: LogicalSize) -> WindowBuilder {
|
||||||
self.window.dimensions = Some(size);
|
self.window.inner_size = Some(size);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a minimum dimension size for the window
|
/// Sets a minimum dimension size for the window
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_min_dimensions(mut self, min_size: LogicalSize) -> WindowBuilder {
|
pub fn with_min_inner_size(mut self, min_size: LogicalSize) -> WindowBuilder {
|
||||||
self.window.min_dimensions = Some(min_size);
|
self.window.min_inner_size = Some(min_size);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a maximum dimension size for the window
|
/// Sets a maximum dimension size for the window
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_max_dimensions(mut self, max_size: LogicalSize) -> WindowBuilder {
|
pub fn with_max_inner_size(mut self, max_size: LogicalSize) -> WindowBuilder {
|
||||||
self.window.max_dimensions = Some(max_size);
|
self.window.max_inner_size = Some(max_size);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,23 +278,16 @@ impl WindowBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables multitouch.
|
|
||||||
#[inline]
|
|
||||||
pub fn with_multitouch(mut self) -> WindowBuilder {
|
|
||||||
self.window.multitouch = true;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the window.
|
/// Builds the window.
|
||||||
///
|
///
|
||||||
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
||||||
/// out of memory, etc.
|
/// out of memory, etc.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn build<T: 'static>(mut self, window_target: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> {
|
pub fn build<T: 'static>(mut self, window_target: &EventLoopWindowTarget<T>) -> Result<Window, OsError> {
|
||||||
self.window.dimensions = Some(self.window.dimensions.unwrap_or_else(|| {
|
self.window.inner_size = Some(self.window.inner_size.unwrap_or_else(|| {
|
||||||
if let Some(ref monitor) = self.window.fullscreen {
|
if let Some(ref monitor) = self.window.fullscreen {
|
||||||
// resizing the window to the dimensions of the monitor when fullscreen
|
// resizing the window to the dimensions of the monitor when fullscreen
|
||||||
LogicalSize::from_physical(monitor.get_dimensions(), 1.0)
|
LogicalSize::from_physical(monitor.dimensions(), 1.0)
|
||||||
} else {
|
} else {
|
||||||
// default dimensions
|
// default dimensions
|
||||||
(1024, 768).into()
|
(1024, 768).into()
|
||||||
|
@ -314,6 +303,7 @@ impl WindowBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Base Window functions.
|
||||||
impl Window {
|
impl Window {
|
||||||
/// Creates a new Window for platforms where this is appropriate.
|
/// Creates a new Window for platforms where this is appropriate.
|
||||||
///
|
///
|
||||||
|
@ -322,43 +312,36 @@ impl Window {
|
||||||
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
||||||
/// out of memory, etc.
|
/// out of memory, etc.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> {
|
pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, OsError> {
|
||||||
let builder = WindowBuilder::new();
|
let builder = WindowBuilder::new();
|
||||||
builder.build(event_loop)
|
builder.build(event_loop)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modifies the title of the window.
|
/// Returns an identifier unique to the window.
|
||||||
///
|
|
||||||
/// This is a no-op if the window has already been closed.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - Has no effect on iOS.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_title(&self, title: &str) {
|
pub fn id(&self) -> WindowId {
|
||||||
self.window.set_title(title)
|
WindowId(self.window.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shows the window if it was hidden.
|
/// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa.
|
||||||
|
///
|
||||||
|
/// See the [`dpi`](dpi/index.html) module for more information.
|
||||||
|
///
|
||||||
|
/// Note that this value can change depending on user action (for example if the window is
|
||||||
|
/// moved to another screen); as such, tracking `WindowEvent::HiDpiFactorChanged` events is
|
||||||
|
/// the most robust way to track the DPI you need to use to draw.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **Android:** Has no effect.
|
/// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
|
||||||
/// - **iOS:** Can only be called on the main thread.
|
/// - **Android:** Always returns 1.0.
|
||||||
#[inline]
|
/// - **iOS:** Can only be called on the main thread. Returns the underlying `UIView`'s
|
||||||
pub fn show(&self) {
|
/// [`contentScaleFactor`].
|
||||||
self.window.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hides the window if it was visible.
|
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
|
||||||
///
|
|
||||||
/// - **Android:** Has no effect.
|
|
||||||
/// - **iOS:** Can only be called on the main thread.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hide(&self) {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
self.window.hide()
|
self.window.hidpi_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
|
/// Emits a `WindowEvent::RedrawRequested` event in the associated event loop after all OS
|
||||||
|
@ -376,9 +359,29 @@ impl Window {
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Can only be called on the main thread.
|
/// - **iOS:** Can only be called on the main thread.
|
||||||
|
#[inline]
|
||||||
pub fn request_redraw(&self) {
|
pub fn request_redraw(&self) {
|
||||||
self.window.request_redraw()
|
self.window.request_redraw()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Position and size functions.
|
||||||
|
impl Window {
|
||||||
|
/// Returns the position of the top-left hand corner of the window's client area relative to the
|
||||||
|
/// top-left hand corner of the desktop.
|
||||||
|
///
|
||||||
|
/// The same conditions that apply to `outer_position` apply to this method.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
|
||||||
|
/// window's [safe area] in the screen space coordinate system.
|
||||||
|
///
|
||||||
|
/// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
|
||||||
|
#[inline]
|
||||||
|
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
|
self.window.inner_position()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the position of the top-left hand corner of the window relative to the
|
/// Returns the position of the top-left hand corner of the window relative to the
|
||||||
/// top-left hand corner of the desktop.
|
/// top-left hand corner of the desktop.
|
||||||
|
@ -390,36 +393,18 @@ impl Window {
|
||||||
/// The coordinates can be negative if the top-left hand corner of the window is outside
|
/// The coordinates can be negative if the top-left hand corner of the window is outside
|
||||||
/// of the visible screen region.
|
/// of the visible screen region.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the window no longer exists.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
|
/// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
|
||||||
/// window in the screen space coordinate system.
|
/// window in the screen space coordinate system.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||||
self.window.get_position()
|
self.window.outer_position()
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the position of the top-left hand corner of the window's client area relative to the
|
|
||||||
/// top-left hand corner of the desktop.
|
|
||||||
///
|
|
||||||
/// The same conditions that apply to `get_position` apply to this method.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the
|
|
||||||
/// window's [safe area] in the screen space coordinate system.
|
|
||||||
///
|
|
||||||
/// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
|
|
||||||
#[inline]
|
|
||||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
|
||||||
self.window.get_inner_position()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modifies the position of the window.
|
/// Modifies the position of the window.
|
||||||
///
|
///
|
||||||
/// See `get_position` for more information about the coordinates.
|
/// See `outer_position` for more information about the coordinates.
|
||||||
///
|
///
|
||||||
/// This is a no-op if the window has already been closed.
|
/// This is a no-op if the window has already been closed.
|
||||||
///
|
///
|
||||||
|
@ -428,8 +413,8 @@ impl Window {
|
||||||
/// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the
|
/// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the
|
||||||
/// window in the screen space coordinate system.
|
/// window in the screen space coordinate system.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_position(&self, position: LogicalPosition) {
|
pub fn set_outer_position(&self, position: LogicalPosition) {
|
||||||
self.window.set_position(position)
|
self.window.set_outer_position(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the logical size of the window's client area.
|
/// Returns the logical size of the window's client area.
|
||||||
|
@ -438,40 +423,20 @@ impl Window {
|
||||||
///
|
///
|
||||||
/// Converting the returned `LogicalSize` to `PhysicalSize` produces the size your framebuffer should be.
|
/// Converting the returned `LogicalSize` to `PhysicalSize` produces the size your framebuffer should be.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the window no longer exists.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window's
|
/// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window's
|
||||||
/// [safe area] in screen space coordinates.
|
/// [safe area] in screen space coordinates.
|
||||||
///
|
///
|
||||||
/// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
|
/// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
pub fn inner_size(&self) -> LogicalSize {
|
||||||
self.window.get_inner_size()
|
self.window.inner_size()
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the logical size of the entire window.
|
|
||||||
///
|
|
||||||
/// These dimensions include the title bar and borders. If you don't want that (and you usually don't),
|
|
||||||
/// use `get_inner_size` instead.
|
|
||||||
///
|
|
||||||
/// Returns `None` if the window no longer exists.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window in
|
|
||||||
/// screen space coordinates.
|
|
||||||
#[inline]
|
|
||||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
|
||||||
self.window.get_outer_size()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modifies the inner size of the window.
|
/// Modifies the inner size of the window.
|
||||||
///
|
///
|
||||||
/// See `get_inner_size` for more information about the values.
|
/// See `inner_size` for more information about the values.
|
||||||
///
|
|
||||||
/// This is a no-op if the window has already been closed.
|
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
|
@ -482,14 +447,28 @@ impl Window {
|
||||||
self.window.set_inner_size(size)
|
self.window.set_inner_size(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the logical size of the entire window.
|
||||||
|
///
|
||||||
|
/// These dimensions include the title bar and borders. If you don't want that (and you usually don't),
|
||||||
|
/// use `inner_size` instead.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window in
|
||||||
|
/// screen space coordinates.
|
||||||
|
#[inline]
|
||||||
|
pub fn outer_size(&self) -> LogicalSize {
|
||||||
|
self.window.outer_size()
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets a minimum dimension size for the window.
|
/// Sets a minimum dimension size for the window.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Has no effect.
|
/// - **iOS:** Has no effect.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
|
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||||
self.window.set_min_dimensions(dimensions)
|
self.window.set_min_inner_size(dimensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a maximum dimension size for the window.
|
/// Sets a maximum dimension size for the window.
|
||||||
|
@ -498,8 +477,33 @@ impl Window {
|
||||||
///
|
///
|
||||||
/// - **iOS:** Has no effect.
|
/// - **iOS:** Has no effect.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||||
self.window.set_max_dimensions(dimensions)
|
self.window.set_max_inner_size(dimensions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Misc. attribute functions.
|
||||||
|
impl Window {
|
||||||
|
/// Modifies the title of the window.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - Has no effect on iOS.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_title(&self, title: &str) {
|
||||||
|
self.window.set_title(title)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifies the window's visibility.
|
||||||
|
///
|
||||||
|
/// If `false`, this will hide the window. If `true`, this will show the window.
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Android:** Has no effect.
|
||||||
|
/// - **iOS:** Can only be called on the main thread.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_visible(&self, visible: bool) {
|
||||||
|
self.window.set_visible(visible)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets whether the window is resizable or not.
|
/// Sets whether the window is resizable or not.
|
||||||
|
@ -521,80 +525,10 @@ impl Window {
|
||||||
self.window.set_resizable(resizable)
|
self.window.set_resizable(resizable)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the DPI factor that can be used to map logical pixels to physical pixels, and vice versa.
|
|
||||||
///
|
|
||||||
/// See the [`dpi`](dpi/index.html) module for more information.
|
|
||||||
///
|
|
||||||
/// Note that this value can change depending on user action (for example if the window is
|
|
||||||
/// moved to another screen); as such, tracking `WindowEvent::HiDpiFactorChanged` events is
|
|
||||||
/// the most robust way to track the DPI you need to use to draw.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
|
|
||||||
/// - **Android:** Always returns 1.0.
|
|
||||||
/// - **iOS:** Can only be called on the main thread. Returns the underlying `UIView`'s
|
|
||||||
/// [`contentScaleFactor`].
|
|
||||||
///
|
|
||||||
/// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
|
|
||||||
#[inline]
|
|
||||||
pub fn get_hidpi_factor(&self) -> f64 {
|
|
||||||
self.window.get_hidpi_factor()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Modifies the mouse cursor of the window.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **iOS:** Has no effect.
|
|
||||||
/// - **Android:** Has no effect.
|
|
||||||
#[inline]
|
|
||||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
|
||||||
self.window.set_cursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Changes the position of the cursor in window coordinates.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **iOS:** Always returns an `Err`.
|
|
||||||
#[inline]
|
|
||||||
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
|
|
||||||
self.window.set_cursor_position(position)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Grabs the cursor, preventing it from leaving the window.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **macOS:** This presently merely locks the cursor in a fixed location, which looks visually
|
|
||||||
/// awkward.
|
|
||||||
/// - **Android:** Has no effect.
|
|
||||||
/// - **iOS:** Always returns an Err.
|
|
||||||
#[inline]
|
|
||||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
|
||||||
self.window.grab_cursor(grab)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hides the cursor, making it invisible but still usable.
|
|
||||||
///
|
|
||||||
/// ## Platform-specific
|
|
||||||
///
|
|
||||||
/// - **Windows:** The cursor is only hidden within the confines of the window.
|
|
||||||
/// - **X11:** The cursor is only hidden within the confines of the window.
|
|
||||||
/// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
|
|
||||||
/// outside of the window.
|
|
||||||
/// - **iOS:** Has no effect.
|
|
||||||
/// - **Android:** Has no effect.
|
|
||||||
#[inline]
|
|
||||||
pub fn hide_cursor(&self, hide: bool) {
|
|
||||||
self.window.hide_cursor(hide)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the window to maximized or back.
|
/// Sets the window to maximized or back.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Has no effect.
|
/// - **iOS:** Has no effect.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_maximized(&self, maximized: bool) {
|
pub fn set_maximized(&self, maximized: bool) {
|
||||||
|
@ -604,7 +538,7 @@ impl Window {
|
||||||
/// Sets the window to fullscreen or back.
|
/// Sets the window to fullscreen or back.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Can only be called on the main thread.
|
/// - **iOS:** Can only be called on the main thread.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_fullscreen(&self, monitor: Option<MonitorHandle>) {
|
pub fn set_fullscreen(&self, monitor: Option<MonitorHandle>) {
|
||||||
|
@ -614,20 +548,20 @@ impl Window {
|
||||||
/// Gets the window's current fullscreen state.
|
/// Gets the window's current fullscreen state.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Can only be called on the main thread.
|
/// - **iOS:** Can only be called on the main thread.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_fullscreen(&self) -> Option<MonitorHandle> {
|
pub fn fullscreen(&self) -> Option<MonitorHandle> {
|
||||||
self.window.get_fullscreen()
|
self.window.fullscreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn window decorations on or off.
|
/// Turn window decorations on or off.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Can only be called on the main thread. Controls whether the status bar is hidden
|
/// - **iOS:** Can only be called on the main thread. Controls whether the status bar is hidden
|
||||||
/// via [`setPrefersStatusBarHidden`].
|
/// via [`setPrefersStatusBarHidden`].
|
||||||
///
|
///
|
||||||
/// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc
|
/// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_decorations(&self, decorations: bool) {
|
pub fn set_decorations(&self, decorations: bool) {
|
||||||
|
@ -637,7 +571,7 @@ impl Window {
|
||||||
/// Change whether or not the window will always be on top of other windows.
|
/// Change whether or not the window will always be on top of other windows.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **iOS:** Has no effect.
|
/// - **iOS:** Has no effect.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_always_on_top(&self, always_on_top: bool) {
|
pub fn set_always_on_top(&self, always_on_top: bool) {
|
||||||
|
@ -663,85 +597,105 @@ impl Window {
|
||||||
///
|
///
|
||||||
/// **iOS:** Has no effect.
|
/// **iOS:** Has no effect.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_ime_spot(&self, position: LogicalPosition) {
|
pub fn set_ime_position(&self, position: LogicalPosition) {
|
||||||
self.window.set_ime_spot(position)
|
self.window.set_ime_position(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cursor functions.
|
||||||
|
impl Window {
|
||||||
|
/// Modifies the cursor icon of the window.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS:** Has no effect.
|
||||||
|
/// - **Android:** Has no effect.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||||
|
self.window.set_cursor_icon(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Changes the position of the cursor in window coordinates.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **iOS:** Always returns an `Err`.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> {
|
||||||
|
self.window.set_cursor_position(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Grabs the cursor, preventing it from leaving the window.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **macOS:** This presently merely locks the cursor in a fixed location, which looks visually
|
||||||
|
/// awkward.
|
||||||
|
/// - **Android:** Has no effect.
|
||||||
|
/// - **iOS:** Always returns an Err.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
|
self.window.set_cursor_grab(grab)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hides the cursor, making it invisible but still usable.
|
||||||
|
///
|
||||||
|
/// ## Platform-specific
|
||||||
|
///
|
||||||
|
/// - **Windows:** The cursor is only hidden within the confines of the window.
|
||||||
|
/// - **X11:** The cursor is only hidden within the confines of the window.
|
||||||
|
/// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
|
||||||
|
/// outside of the window.
|
||||||
|
/// - **iOS:** Has no effect.
|
||||||
|
/// - **Android:** Has no effect.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
|
self.window.set_cursor_visible(visible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Monitor info functions.
|
||||||
|
impl Window {
|
||||||
/// Returns the monitor on which the window currently resides
|
/// Returns the monitor on which the window currently resides
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// **iOS:** Can only be called on the main thread.
|
/// **iOS:** Can only be called on the main thread.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_current_monitor(&self) -> MonitorHandle {
|
pub fn current_monitor(&self) -> MonitorHandle {
|
||||||
self.window.get_current_monitor()
|
self.window.current_monitor()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the list of all the monitors available on the system.
|
/// Returns the list of all the monitors available on the system.
|
||||||
///
|
///
|
||||||
/// This is the same as `EventLoop::get_available_monitors`, and is provided for convenience.
|
/// This is the same as `EventLoop::available_monitors`, and is provided for convenience.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// **iOS:** Can only be called on the main thread.
|
/// **iOS:** Can only be called on the main thread.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_available_monitors(&self) -> AvailableMonitorsIter {
|
pub fn available_monitors(&self) -> AvailableMonitorsIter {
|
||||||
let data = self.window.get_available_monitors();
|
let data = self.window.available_monitors();
|
||||||
AvailableMonitorsIter { data: data.into_iter() }
|
AvailableMonitorsIter { data: data.into_iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the primary monitor of the system.
|
/// Returns the primary monitor of the system.
|
||||||
///
|
///
|
||||||
/// This is the same as `EventLoop::get_primary_monitor`, and is provided for convenience.
|
/// This is the same as `EventLoop::primary_monitor`, and is provided for convenience.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// **iOS:** Can only be called on the main thread.
|
/// **iOS:** Can only be called on the main thread.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||||
MonitorHandle { inner: self.window.get_primary_monitor() }
|
MonitorHandle { inner: self.window.primary_monitor() }
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an identifier unique to the window.
|
|
||||||
#[inline]
|
|
||||||
pub fn id(&self) -> WindowId {
|
|
||||||
WindowId(self.window.id())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error that can happen while creating a window or a headless renderer.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum CreationError {
|
|
||||||
OsError(String),
|
|
||||||
/// TODO: remove this error
|
|
||||||
NotSupported,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreationError {
|
|
||||||
fn to_string(&self) -> &str {
|
|
||||||
match *self {
|
|
||||||
CreationError::OsError(ref text) => &text,
|
|
||||||
CreationError::NotSupported => "Some of the requested attributes are not supported",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for CreationError {
|
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
formatter.write_str(self.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for CreationError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
self.to_string()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes the appearance of the mouse cursor.
|
/// Describes the appearance of the mouse cursor.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub enum MouseCursor {
|
pub enum CursorIcon {
|
||||||
/// The platform-dependent default cursor.
|
/// The platform-dependent default cursor.
|
||||||
Default,
|
Default,
|
||||||
/// A simple crosshair.
|
/// A simple crosshair.
|
||||||
|
@ -795,8 +749,8 @@ pub enum MouseCursor {
|
||||||
RowResize,
|
RowResize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MouseCursor {
|
impl Default for CursorIcon {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
MouseCursor::Default
|
CursorIcon::Default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
use winit::window::{MouseCursor};
|
use winit::window::{CursorIcon};
|
||||||
use winit::event::{
|
use winit::event::{
|
||||||
KeyboardInput, TouchPhase, ElementState, MouseButton, MouseScrollDelta, VirtualKeyCode,
|
KeyboardInput, TouchPhase, ElementState, MouseButton, MouseScrollDelta, VirtualKeyCode,
|
||||||
ModifiersState
|
ModifiersState
|
||||||
|
@ -15,7 +15,7 @@ fn needs_serde<S: Serialize + Deserialize<'static>>() {}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn window_serde() {
|
fn window_serde() {
|
||||||
needs_serde::<MouseCursor>();
|
needs_serde::<CursorIcon>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Reference in a new issue