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
|
|
@ -15,7 +15,7 @@ use {
|
|||
Event,
|
||||
LogicalPosition,
|
||||
LogicalSize,
|
||||
MouseCursor,
|
||||
CursorIcon,
|
||||
PhysicalPosition,
|
||||
PhysicalSize,
|
||||
WindowAttributes,
|
||||
|
|
@ -23,9 +23,12 @@ use {
|
|||
WindowId as RootWindowId,
|
||||
};
|
||||
use CreationError::OsError;
|
||||
use error::{ExternalError, NotSupportedError};
|
||||
use events::{Touch, TouchPhase};
|
||||
use window::MonitorHandle as RootMonitorHandle;
|
||||
|
||||
pub type OsError = std::io::Error;
|
||||
|
||||
pub struct EventLoop {
|
||||
event_rx: Receiver<android_glue::Event>,
|
||||
suspend_callback: RefCell<Option<Box<Fn(bool) -> ()>>>,
|
||||
|
|
@ -45,14 +48,14 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
let mut rb = VecDeque::with_capacity(1);
|
||||
rb.push_back(MonitorHandle);
|
||||
rb
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
MonitorHandle
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +65,7 @@ impl EventLoop {
|
|||
while let Ok(event) = self.event_rx.try_recv() {
|
||||
let e = match event{
|
||||
android_glue::Event::EventMotion(motion) => {
|
||||
let dpi_factor = MonitorHandle.get_hidpi_factor();
|
||||
let dpi_factor = MonitorHandle.hidpi_factor();
|
||||
let location = LogicalPosition::from_physical(
|
||||
(motion.x as f64, motion.y as f64),
|
||||
dpi_factor,
|
||||
|
|
@ -99,12 +102,12 @@ impl EventLoop {
|
|||
android_glue::Event::WindowResized |
|
||||
android_glue::Event::ConfigChanged => {
|
||||
// Activity Orientation changed or resized.
|
||||
let native_window = unsafe { android_glue::get_native_window() };
|
||||
let native_window = unsafe { android_glue::native_window() };
|
||||
if native_window.is_null() {
|
||||
None
|
||||
} else {
|
||||
let dpi_factor = MonitorHandle.get_hidpi_factor();
|
||||
let physical_size = MonitorHandle.get_dimensions();
|
||||
let dpi_factor = MonitorHandle.hidpi_factor();
|
||||
let physical_size = MonitorHandle.dimensions();
|
||||
let size = LogicalSize::from_physical(physical_size, dpi_factor);
|
||||
Some(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId),
|
||||
|
|
@ -203,10 +206,10 @@ impl fmt::Debug for MonitorHandle {
|
|||
}
|
||||
|
||||
let monitor_id_proxy = MonitorHandle {
|
||||
name: self.get_name(),
|
||||
dimensions: self.get_dimensions(),
|
||||
position: self.get_position(),
|
||||
hidpi_factor: self.get_hidpi_factor(),
|
||||
name: self.name(),
|
||||
dimensions: self.dimensions(),
|
||||
position: self.outer_position(),
|
||||
hidpi_factor: self.hidpi_factor(),
|
||||
};
|
||||
|
||||
monitor_id_proxy.fmt(f)
|
||||
|
|
@ -215,14 +218,14 @@ impl fmt::Debug for MonitorHandle {
|
|||
|
||||
impl MonitorHandle {
|
||||
#[inline]
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
Some("Primary".to_string())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
pub fn dimensions(&self) -> PhysicalSize {
|
||||
unsafe {
|
||||
let window = android_glue::get_native_window();
|
||||
let window = android_glue::native_window();
|
||||
(
|
||||
ffi::ANativeWindow_getWidth(window) as f64,
|
||||
ffi::ANativeWindow_getHeight(window) as f64,
|
||||
|
|
@ -231,13 +234,13 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
pub fn outer_position(&self) -> PhysicalPosition {
|
||||
// Android assumes single screen
|
||||
(0, 0).into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
1.0
|
||||
}
|
||||
}
|
||||
|
|
@ -252,12 +255,12 @@ impl Window {
|
|||
_: PlatformSpecificWindowBuilderAttributes)
|
||||
-> Result<Window, CreationError>
|
||||
{
|
||||
let native_window = unsafe { android_glue::get_native_window() };
|
||||
let native_window = unsafe { android_glue::native_window() };
|
||||
if native_window.is_null() {
|
||||
return Err(OsError(format!("Android's native window is null")));
|
||||
}
|
||||
|
||||
android_glue::set_multitouch(win_attribs.multitouch);
|
||||
android_glue::set_multitouch(true);
|
||||
|
||||
Ok(Window {
|
||||
native_window: native_window as *const _,
|
||||
|
|
@ -265,7 +268,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_native_window(&self) -> *const c_void {
|
||||
pub fn native_window(&self) -> *const c_void {
|
||||
self.native_window
|
||||
}
|
||||
|
||||
|
|
@ -285,29 +288,29 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn outer_position(&self) -> Option<LogicalPosition> {
|
||||
// N/A
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn inner_position(&self) -> Option<LogicalPosition> {
|
||||
// N/A
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_position(&self, _position: LogicalPosition) {
|
||||
pub fn set_outer_position(&self, _position: LogicalPosition) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
||||
pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
||||
pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
|
|
@ -317,19 +320,19 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
pub fn inner_size(&self) -> Option<LogicalSize> {
|
||||
if self.native_window.is_null() {
|
||||
None
|
||||
} else {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
let physical_size = self.get_current_monitor().get_dimensions();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let physical_size = self.current_monitor().dimensions();
|
||||
Some(LogicalSize::from_physical(physical_size, dpi_factor))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
self.get_inner_size()
|
||||
pub fn outer_size(&self) -> Option<LogicalSize> {
|
||||
self.inner_size()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -338,18 +341,18 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
self.get_current_monitor().get_hidpi_factor()
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
self.current_monitor().hidpi_factor()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, _: MouseCursor) {
|
||||
pub fn set_cursor_icon(&self, _: CursorIcon) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> {
|
||||
Err("Cursor grabbing is not possible on Android.".to_owned())
|
||||
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -358,8 +361,8 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> {
|
||||
Err("Setting cursor position is not possible on Android.".to_owned())
|
||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -369,7 +372,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
// N/A
|
||||
// Android has single screen maximized apps so nothing to do
|
||||
None
|
||||
|
|
@ -397,24 +400,24 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_spot(&self, _spot: LogicalPosition) {
|
||||
pub fn set_ime_position(&self, _spot: LogicalPosition) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
||||
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||
RootMonitorHandle { inner: MonitorHandle }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
let mut rb = VecDeque::with_capacity(1);
|
||||
rb.push_back(MonitorHandle);
|
||||
rb
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
MonitorHandle
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,12 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||
use std::sync::{Mutex, Arc};
|
||||
|
||||
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
||||
use error::{ExternalError, NotSupportedError};
|
||||
use window::MonitorHandle as RootMonitorHandle;
|
||||
|
||||
const DOCUMENT_NAME: &'static str = "#document\0";
|
||||
|
||||
fn get_hidpi_factor() -> f64 {
|
||||
fn hidpi_factor() -> f64 {
|
||||
unsafe { ffi::emscripten_get_device_pixel_ratio() as f64 }
|
||||
}
|
||||
|
||||
|
|
@ -24,6 +25,8 @@ pub struct PlatformSpecificWindowBuilderAttributes;
|
|||
unsafe impl Send for PlatformSpecificWindowBuilderAttributes {}
|
||||
unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {}
|
||||
|
||||
pub type OsError = std::io::Error;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct DeviceId;
|
||||
|
||||
|
|
@ -41,23 +44,23 @@ pub struct MonitorHandle;
|
|||
|
||||
impl MonitorHandle {
|
||||
#[inline]
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
Some("Canvas".to_owned())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
pub fn outer_position(&self) -> PhysicalPosition {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
pub fn dimensions(&self) -> PhysicalSize {
|
||||
(0, 0).into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
get_hidpi_factor()
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
hidpi_factor()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,14 +116,14 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
let mut list = VecDeque::with_capacity(1);
|
||||
list.push_back(MonitorHandle);
|
||||
list
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
MonitorHandle
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +166,7 @@ impl WindowId {
|
|||
|
||||
pub struct Window2 {
|
||||
cursor_grabbed: Mutex<bool>,
|
||||
cursor_hidden: Mutex<bool>,
|
||||
cursor_visible: Mutex<bool>,
|
||||
is_fullscreen: bool,
|
||||
events: Box<Mutex<VecDeque<::Event>>>,
|
||||
}
|
||||
|
|
@ -208,7 +211,7 @@ extern "C" fn mouse_callback(
|
|||
|
||||
match event_type {
|
||||
ffi::EMSCRIPTEN_EVENT_MOUSEMOVE => {
|
||||
let dpi_factor = get_hidpi_factor();
|
||||
let dpi_factor = hidpi_factor();
|
||||
let position = LogicalPosition::from_physical(
|
||||
((*event).canvasX as f64, (*event).canvasY as f64),
|
||||
dpi_factor,
|
||||
|
|
@ -328,7 +331,7 @@ extern fn touch_callback(
|
|||
for touch in 0..(*event).numTouches as usize {
|
||||
let touch = (*event).touches[touch];
|
||||
if touch.isChanged == ffi::EM_TRUE {
|
||||
let dpi_factor = get_hidpi_factor();
|
||||
let dpi_factor = hidpi_factor();
|
||||
let location = LogicalPosition::from_physical(
|
||||
(touch.canvasX as f64, touch.canvasY as f64),
|
||||
dpi_factor,
|
||||
|
|
@ -387,8 +390,8 @@ impl Window {
|
|||
}
|
||||
|
||||
let w = Window2 {
|
||||
cursor_grabbed: Default::default(),
|
||||
cursor_hidden: Default::default(),
|
||||
cursor_grabbed: Mutex::new(false),
|
||||
cursor_visible: Mutex::new(true),
|
||||
events: Default::default(),
|
||||
is_fullscreen: attribs.fullscreen.is_some(),
|
||||
};
|
||||
|
|
@ -427,7 +430,7 @@ impl Window {
|
|||
em_try(ffi::emscripten_set_fullscreenchange_callback(ptr::null(), 0 as *mut c_void, ffi::EM_FALSE, Some(fullscreen_callback)))
|
||||
.map_err(|e| ::CreationError::OsError(e))?;
|
||||
}
|
||||
} else if let Some(size) = attribs.dimensions {
|
||||
} else if let Some(size) = attribs.inner_size {
|
||||
window.set_inner_size(size);
|
||||
}
|
||||
|
||||
|
|
@ -445,21 +448,21 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn outer_position(&self) -> Option<LogicalPosition> {
|
||||
Some((0, 0).into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn inner_position(&self) -> Option<LogicalPosition> {
|
||||
Some((0, 0).into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_position(&self, _: LogicalPosition) {
|
||||
pub fn set_outer_position(&self, _: LogicalPosition) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
pub fn inner_size(&self) -> Option<LogicalSize> {
|
||||
unsafe {
|
||||
let mut width = 0;
|
||||
let mut height = 0;
|
||||
|
|
@ -470,7 +473,7 @@ impl Window {
|
|||
{
|
||||
None
|
||||
} else {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let logical = LogicalSize::from_physical((width as u32, height as u32), dpi_factor);
|
||||
Some(logical)
|
||||
}
|
||||
|
|
@ -478,14 +481,14 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
self.get_inner_size()
|
||||
pub fn outer_size(&self) -> Option<LogicalSize> {
|
||||
self.inner_size()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_inner_size(&self, size: LogicalSize) {
|
||||
unsafe {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let physical = PhysicalSize::from_logical(size, dpi_factor);
|
||||
let (width, height): (u32, u32) = physical.into();
|
||||
ffi::emscripten_set_element_css_size(
|
||||
|
|
@ -497,12 +500,12 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
||||
pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
||||
pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
|
|
@ -522,12 +525,12 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, _cursor: ::MouseCursor) {
|
||||
pub fn set_cursor_icon(&self, _cursor: ::CursorIcon) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
||||
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||
let mut grabbed_lock = self.window.cursor_grabbed.lock().unwrap();
|
||||
if grab == *grabbed_lock { return Ok(()); }
|
||||
unsafe {
|
||||
|
|
@ -554,24 +557,24 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide_cursor(&self, hide: bool) {
|
||||
let mut hidden_lock = self.window.cursor_hidden.lock().unwrap();
|
||||
if hide == *hidden_lock { return; }
|
||||
if hide {
|
||||
unsafe { ffi::emscripten_hide_mouse() };
|
||||
} else {
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
let mut visible_lock = self.window.cursor_visible.lock().unwrap();
|
||||
if visible == *visible_lock { return; }
|
||||
if visible {
|
||||
show_mouse();
|
||||
} else {
|
||||
unsafe { ffi::emscripten_hide_mouse() };
|
||||
}
|
||||
*hidden_lock = hide;
|
||||
*visible_lock = visible;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
get_hidpi_factor()
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
hidpi_factor()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> {
|
||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
|
||||
Err("Setting cursor position is not possible on Emscripten.".to_owned())
|
||||
}
|
||||
|
||||
|
|
@ -581,7 +584,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_fullscreen(&self) -> Option<::MonitorHandle> {
|
||||
pub fn fullscreen(&self) -> Option<::MonitorHandle> {
|
||||
None
|
||||
}
|
||||
|
||||
|
|
@ -606,24 +609,24 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_spot(&self, _logical_spot: LogicalPosition) {
|
||||
pub fn set_ime_position(&self, _logical_spot: LogicalPosition) {
|
||||
// N/A
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
||||
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||
RootMonitorHandle { inner: MonitorHandle }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
let mut list = VecDeque::with_capacity(1);
|
||||
list.push_back(MonitorHandle);
|
||||
list
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
MonitorHandle
|
||||
}
|
||||
}
|
||||
|
|
@ -639,7 +642,7 @@ impl Drop for Window {
|
|||
unsafe {
|
||||
// Return back to normal cursor state
|
||||
self.hide_cursor(false);
|
||||
self.grab_cursor(false);
|
||||
self.set_cursor_grab(false);
|
||||
|
||||
// Exit fullscreen if on
|
||||
if self.window.is_fullscreen {
|
||||
|
|
|
|||
|
|
@ -119,14 +119,14 @@ impl<T: 'static> EventLoop<T> {
|
|||
EventLoopProxy::new(self.window_target.p.sender_to_clone.clone())
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
// guaranteed to be on main thread
|
||||
unsafe {
|
||||
monitor::uiscreens()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
// guaranteed to be on main thread
|
||||
unsafe {
|
||||
monitor::main_uiscreen()
|
||||
|
|
@ -140,7 +140,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
|
||||
// EventLoopExtIOS
|
||||
impl<T: 'static> EventLoop<T> {
|
||||
pub fn get_idiom(&self) -> Idiom {
|
||||
pub fn idiom(&self) -> Idiom {
|
||||
// guaranteed to be on main thread
|
||||
unsafe {
|
||||
self::get_idiom()
|
||||
|
|
@ -331,4 +331,4 @@ impl From<NSOperatingSystemVersion> for Capabilities {
|
|||
|
||||
Capabilities { supports_safe_area }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ mod monitor;
|
|||
mod view;
|
||||
mod window;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
|
||||
pub use self::monitor::MonitorHandle;
|
||||
pub use self::window::{
|
||||
|
|
@ -99,3 +101,14 @@ impl DeviceId {
|
|||
|
||||
unsafe impl Send for DeviceId {}
|
||||
unsafe impl Sync for DeviceId {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum OsError {}
|
||||
|
||||
impl fmt::Display for OsError {
|
||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,10 +78,10 @@ impl fmt::Debug for MonitorHandle {
|
|||
}
|
||||
|
||||
let monitor_id_proxy = MonitorHandle {
|
||||
name: self.get_name(),
|
||||
dimensions: self.get_dimensions(),
|
||||
position: self.get_position(),
|
||||
hidpi_factor: self.get_hidpi_factor(),
|
||||
name: self.name(),
|
||||
dimensions: self.dimensions(),
|
||||
position: self.position(),
|
||||
hidpi_factor: self.hidpi_factor(),
|
||||
};
|
||||
|
||||
monitor_id_proxy.fmt(f)
|
||||
|
|
@ -99,7 +99,7 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
impl Inner {
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
unsafe {
|
||||
if self.uiscreen == main_uiscreen().uiscreen {
|
||||
Some("Primary".to_string())
|
||||
|
|
@ -113,24 +113,24 @@ impl Inner {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
|
||||
pub fn dimensions(&self) -> PhysicalSize {
|
||||
unsafe {
|
||||
let bounds: CGRect = msg_send![self.get_uiscreen(), nativeBounds];
|
||||
let bounds: CGRect = msg_send![self.ui_screen(), nativeBounds];
|
||||
(bounds.size.width as f64, bounds.size.height as f64).into()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
|
||||
pub fn position(&self) -> PhysicalPosition {
|
||||
unsafe {
|
||||
let bounds: CGRect = msg_send![self.get_uiscreen(), nativeBounds];
|
||||
let bounds: CGRect = msg_send![self.ui_screen(), nativeBounds];
|
||||
(bounds.origin.x as f64, bounds.origin.y as f64).into()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
unsafe {
|
||||
let scale: CGFloat = msg_send![self.get_uiscreen(), nativeScale];
|
||||
let scale: CGFloat = msg_send![self.ui_screen(), nativeScale];
|
||||
scale as f64
|
||||
}
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ impl Inner {
|
|||
|
||||
// MonitorHandleExtIOS
|
||||
impl Inner {
|
||||
pub fn get_uiscreen(&self) -> id {
|
||||
pub fn ui_screen(&self) -> id {
|
||||
self.uiscreen
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ use platform_impl::platform::window::{PlatformSpecificWindowBuilderAttributes};
|
|||
unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
|
||||
static mut CLASSES: Option<HashMap<*const Class, &'static Class>> = None;
|
||||
static mut ID: usize = 0;
|
||||
|
||||
|
||||
if CLASSES.is_none() {
|
||||
CLASSES = Some(HashMap::default());
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ unsafe fn get_window_class() -> &'static Class {
|
|||
|
||||
// requires main thread
|
||||
pub unsafe fn create_view(
|
||||
window_attributes: &WindowAttributes,
|
||||
_window_attributes: &WindowAttributes,
|
||||
platform_attributes: &PlatformSpecificWindowBuilderAttributes,
|
||||
frame: CGRect,
|
||||
) -> id {
|
||||
|
|
@ -265,9 +265,7 @@ pub unsafe fn create_view(
|
|||
assert!(!view.is_null(), "Failed to create `UIView` instance");
|
||||
let view: id = msg_send![view, initWithFrame:frame];
|
||||
assert!(!view.is_null(), "Failed to initialize `UIView` instance");
|
||||
if window_attributes.multitouch {
|
||||
let () = msg_send![view, setMultipleTouchEnabled:YES];
|
||||
}
|
||||
let () = msg_send![view, setMultipleTouchEnabled:YES];
|
||||
|
||||
view
|
||||
}
|
||||
|
|
@ -318,7 +316,7 @@ pub unsafe fn create_window(
|
|||
let () = msg_send![window, setContentScaleFactor:hidpi_factor as CGFloat];
|
||||
}
|
||||
if let &Some(ref monitor) = &window_attributes.fullscreen {
|
||||
let () = msg_send![window, setScreen:monitor.get_uiscreen()];
|
||||
let () = msg_send![window, setScreen:monitor.ui_screen()];
|
||||
}
|
||||
|
||||
window
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ use std::{
|
|||
use objc::runtime::{Class, NO, Object, YES};
|
||||
|
||||
use dpi::{self, LogicalPosition, LogicalSize};
|
||||
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use icon::Icon;
|
||||
use monitor::MonitorHandle as RootMonitorHandle;
|
||||
use platform::ios::{MonitorHandleExtIOS, ValidOrientations};
|
||||
use window::{
|
||||
CreationError,
|
||||
MouseCursor,
|
||||
CursorIcon,
|
||||
WindowAttributes,
|
||||
};
|
||||
use platform_impl::{
|
||||
|
|
@ -56,15 +56,14 @@ impl Inner {
|
|||
debug!("`Window::set_title` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn show(&self) {
|
||||
unsafe {
|
||||
let () = msg_send![self.window, setHidden:NO];
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hide(&self) {
|
||||
unsafe {
|
||||
let () = msg_send![self.window, setHidden:YES];
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
match visible {
|
||||
true => unsafe {
|
||||
let () = msg_send![self.window, setHidden:NO];
|
||||
},
|
||||
false => unsafe {
|
||||
let () = msg_send![self.window, setHidden:YES];
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,28 +72,28 @@ impl Inner {
|
|||
let () = msg_send![self.view, setNeedsDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
|
||||
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
unsafe {
|
||||
let safe_area = self.safe_area_screen_space();
|
||||
Some(LogicalPosition {
|
||||
Ok(LogicalPosition {
|
||||
x: safe_area.origin.x,
|
||||
y: safe_area.origin.y,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
unsafe {
|
||||
let screen_frame = self.screen_frame();
|
||||
Some(LogicalPosition {
|
||||
Ok(LogicalPosition {
|
||||
x: screen_frame.origin.x,
|
||||
y: screen_frame.origin.y,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_position(&self, position: LogicalPosition) {
|
||||
pub fn set_outer_position(&self, position: LogicalPosition) {
|
||||
unsafe {
|
||||
let screen_frame = self.screen_frame();
|
||||
let new_screen_frame = CGRect {
|
||||
|
|
@ -109,23 +108,23 @@ impl Inner {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
pub fn inner_size(&self) -> LogicalSize {
|
||||
unsafe {
|
||||
let safe_area = self.safe_area_screen_space();
|
||||
Some(LogicalSize {
|
||||
LogicalSize {
|
||||
width: safe_area.size.width,
|
||||
height: safe_area.size.height,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
pub fn outer_size(&self) -> LogicalSize {
|
||||
unsafe {
|
||||
let screen_frame = self.screen_frame();
|
||||
Some(LogicalSize {
|
||||
LogicalSize {
|
||||
width: screen_frame.size.width,
|
||||
height: screen_frame.size.height,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -133,39 +132,39 @@ impl Inner {
|
|||
unimplemented!("not clear what `Window::set_inner_size` means on iOS");
|
||||
}
|
||||
|
||||
pub fn set_min_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
||||
warn!("`Window::set_min_dimensions` is ignored on iOS")
|
||||
pub fn set_min_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||
warn!("`Window::set_min_inner_size` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn set_max_dimensions(&self, _dimensions: Option<LogicalSize>) {
|
||||
warn!("`Window::set_max_dimensions` is ignored on iOS")
|
||||
pub fn set_max_inner_size(&self, _dimensions: Option<LogicalSize>) {
|
||||
warn!("`Window::set_max_inner_size` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn set_resizable(&self, _resizable: bool) {
|
||||
warn!("`Window::set_resizable` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
unsafe {
|
||||
let hidpi: CGFloat = msg_send![self.view, contentScaleFactor];
|
||||
hidpi as _
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_cursor(&self, _cursor: MouseCursor) {
|
||||
debug!("`Window::set_cursor` ignored on iOS")
|
||||
pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
|
||||
debug!("`Window::set_cursor_icon` ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), String> {
|
||||
Err("Setting cursor position is not possible on iOS.".to_owned())
|
||||
pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> {
|
||||
Err("Cursor grabbing is not possible on iOS.".to_owned())
|
||||
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn hide_cursor(&self, _hide: bool) {
|
||||
debug!("`Window::hide_cursor` is ignored on iOS")
|
||||
pub fn set_cursor_visible(&self, _visible: bool) {
|
||||
debug!("`Window::set_cursor_visible` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn set_maximized(&self, _maximized: bool) {
|
||||
|
|
@ -176,7 +175,7 @@ impl Inner {
|
|||
unsafe {
|
||||
match monitor {
|
||||
Some(monitor) => {
|
||||
let uiscreen = monitor.get_uiscreen() as id;
|
||||
let uiscreen = monitor.ui_screen() as id;
|
||||
let current: id = msg_send![self.window, screen];
|
||||
let bounds: CGRect = msg_send![uiscreen, bounds];
|
||||
|
||||
|
|
@ -191,10 +190,10 @@ impl Inner {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
unsafe {
|
||||
let monitor = self.get_current_monitor();
|
||||
let uiscreen = monitor.inner.get_uiscreen();
|
||||
let monitor = self.current_monitor();
|
||||
let uiscreen = monitor.inner.ui_screen();
|
||||
let screen_space_bounds = self.screen_frame();
|
||||
let screen_bounds: CGRect = msg_send![uiscreen, bounds];
|
||||
|
||||
|
|
@ -226,24 +225,24 @@ impl Inner {
|
|||
warn!("`Window::set_window_icon` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn set_ime_spot(&self, _position: LogicalPosition) {
|
||||
warn!("`Window::set_ime_spot` is ignored on iOS")
|
||||
pub fn set_ime_position(&self, _position: LogicalPosition) {
|
||||
warn!("`Window::set_ime_position` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
||||
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||
unsafe {
|
||||
let uiscreen: id = msg_send![self.window, screen];
|
||||
RootMonitorHandle { inner: MonitorHandle::retained_new(uiscreen) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
unsafe {
|
||||
monitor::uiscreens()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
unsafe {
|
||||
monitor::main_uiscreen()
|
||||
}
|
||||
|
|
@ -294,12 +293,12 @@ impl Window {
|
|||
event_loop: &EventLoopWindowTarget<T>,
|
||||
window_attributes: WindowAttributes,
|
||||
platform_attributes: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Window, CreationError> {
|
||||
if let Some(_) = window_attributes.min_dimensions {
|
||||
warn!("`WindowAttributes::min_dimensions` is ignored on iOS");
|
||||
) -> Result<Window, RootOsError> {
|
||||
if let Some(_) = window_attributes.min_inner_size {
|
||||
warn!("`WindowAttributes::min_inner_size` is ignored on iOS");
|
||||
}
|
||||
if let Some(_) = window_attributes.max_dimensions {
|
||||
warn!("`WindowAttributes::max_dimensions` is ignored on iOS");
|
||||
if let Some(_) = window_attributes.max_inner_size {
|
||||
warn!("`WindowAttributes::max_inner_size` is ignored on iOS");
|
||||
}
|
||||
if window_attributes.always_on_top {
|
||||
warn!("`WindowAttributes::always_on_top` is unsupported on iOS");
|
||||
|
|
@ -309,11 +308,11 @@ impl Window {
|
|||
unsafe {
|
||||
let screen = window_attributes.fullscreen
|
||||
.as_ref()
|
||||
.map(|screen| screen.get_uiscreen() as _)
|
||||
.unwrap_or_else(|| monitor::main_uiscreen().get_uiscreen());
|
||||
.map(|screen| screen.ui_screen() as _)
|
||||
.unwrap_or_else(|| monitor::main_uiscreen().ui_screen());
|
||||
let screen_bounds: CGRect = msg_send![screen, bounds];
|
||||
|
||||
let frame = match window_attributes.dimensions {
|
||||
let frame = match window_attributes.inner_size {
|
||||
Some(dim) => CGRect {
|
||||
origin: screen_bounds.origin,
|
||||
size: CGSize { width: dim.width, height: dim.height },
|
||||
|
|
@ -343,9 +342,9 @@ impl Window {
|
|||
|
||||
// WindowExtIOS
|
||||
impl Inner {
|
||||
pub fn get_uiwindow(&self) -> id { self.window }
|
||||
pub fn get_uiviewcontroller(&self) -> id { self.view_controller }
|
||||
pub fn get_uiview(&self) -> id { self.view }
|
||||
pub fn ui_window(&self) -> id { self.window }
|
||||
pub fn ui_view_controller(&self) -> id { self.view_controller }
|
||||
pub fn ui_view(&self) -> id { self.view }
|
||||
|
||||
pub fn set_hidpi_factor(&self, hidpi_factor: f64) {
|
||||
unsafe {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::{env, mem};
|
||||
use std::{env, mem, fmt};
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::*;
|
||||
use std::sync::Arc;
|
||||
|
|
@ -11,10 +11,11 @@ use sctk::reexports::client::ConnectError;
|
|||
|
||||
use dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
||||
use icon::Icon;
|
||||
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use event::Event;
|
||||
use event_loop::{EventLoopClosed, ControlFlow, EventLoopWindowTarget as RootELW};
|
||||
use monitor::MonitorHandle as RootMonitorHandle;
|
||||
use window::{WindowAttributes, CreationError, MouseCursor};
|
||||
use window::{WindowAttributes, CursorIcon};
|
||||
use self::x11::{XConnection, XError};
|
||||
use self::x11::ffi::XVisualInfo;
|
||||
pub use self::x11::XNotSupported;
|
||||
|
|
@ -51,6 +52,21 @@ lazy_static!(
|
|||
};
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum OsError {
|
||||
XError(XError),
|
||||
XMisc(&'static str),
|
||||
}
|
||||
|
||||
impl fmt::Display for OsError {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
match self {
|
||||
OsError::XError(e) => formatter.pad(&e.description),
|
||||
OsError::XMisc(e) => formatter.pad(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Window {
|
||||
X(x11::Window),
|
||||
Wayland(wayland::Window),
|
||||
|
|
@ -88,42 +104,42 @@ pub enum MonitorHandle {
|
|||
|
||||
impl MonitorHandle {
|
||||
#[inline]
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_name(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_name(),
|
||||
&MonitorHandle::X(ref m) => m.name(),
|
||||
&MonitorHandle::Wayland(ref m) => m.name(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_native_identifier(&self) -> u32 {
|
||||
pub fn native_identifier(&self) -> u32 {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_native_identifier(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_native_identifier(),
|
||||
&MonitorHandle::X(ref m) => m.native_identifier(),
|
||||
&MonitorHandle::Wayland(ref m) => m.native_identifier(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
pub fn dimensions(&self) -> PhysicalSize {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_dimensions(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_dimensions(),
|
||||
&MonitorHandle::X(ref m) => m.dimensions(),
|
||||
&MonitorHandle::Wayland(ref m) => m.dimensions(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
pub fn position(&self) -> PhysicalPosition {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_position(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_position(),
|
||||
&MonitorHandle::X(ref m) => m.position(),
|
||||
&MonitorHandle::Wayland(ref m) => m.position(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
match self {
|
||||
&MonitorHandle::X(ref m) => m.get_hidpi_factor(),
|
||||
&MonitorHandle::Wayland(ref m) => m.get_hidpi_factor() as f64,
|
||||
&MonitorHandle::X(ref m) => m.hidpi_factor(),
|
||||
&MonitorHandle::Wayland(ref m) => m.hidpi_factor() as f64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -134,7 +150,7 @@ impl Window {
|
|||
window_target: &EventLoopWindowTarget<T>,
|
||||
attribs: WindowAttributes,
|
||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Self, CreationError> {
|
||||
) -> Result<Self, RootOsError> {
|
||||
match *window_target {
|
||||
EventLoopWindowTarget::Wayland(ref window_target) => {
|
||||
wayland::Window::new(window_target, attribs, pl_attribs).map(Window::Wayland)
|
||||
|
|
@ -162,58 +178,50 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show(&self) {
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.show(),
|
||||
&Window::Wayland(ref w) => w.show(),
|
||||
&Window::X(ref w) => w.set_visible(visible),
|
||||
&Window::Wayland(ref w) => w.set_visible(visible),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide(&self) {
|
||||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.hide(),
|
||||
&Window::Wayland(ref w) => w.hide(),
|
||||
&Window::X(ref w) => w.outer_position(),
|
||||
&Window::Wayland(ref w) => w.outer_position(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_position(),
|
||||
&Window::Wayland(ref w) => w.get_position(),
|
||||
&Window::X(ref m) => m.inner_position(),
|
||||
&Window::Wayland(ref m) => m.inner_position(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn set_outer_position(&self, position: LogicalPosition) {
|
||||
match self {
|
||||
&Window::X(ref m) => m.get_inner_position(),
|
||||
&Window::Wayland(ref m) => m.get_inner_position(),
|
||||
&Window::X(ref w) => w.set_outer_position(position),
|
||||
&Window::Wayland(ref w) => w.set_outer_position(position),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_position(&self, position: LogicalPosition) {
|
||||
pub fn inner_size(&self) -> LogicalSize {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_position(position),
|
||||
&Window::Wayland(ref w) => w.set_position(position),
|
||||
&Window::X(ref w) => w.inner_size(),
|
||||
&Window::Wayland(ref w) => w.inner_size(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
pub fn outer_size(&self) -> LogicalSize {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_inner_size(),
|
||||
&Window::Wayland(ref w) => w.get_inner_size(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_outer_size(),
|
||||
&Window::Wayland(ref w) => w.get_outer_size(),
|
||||
&Window::X(ref w) => w.outer_size(),
|
||||
&Window::Wayland(ref w) => w.outer_size(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -226,18 +234,18 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_min_dimensions(dimensions),
|
||||
&Window::Wayland(ref w) => w.set_min_dimensions(dimensions),
|
||||
&Window::X(ref w) => w.set_min_inner_size(dimensions),
|
||||
&Window::Wayland(ref w) => w.set_min_inner_size(dimensions),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_max_dimensions(dimensions),
|
||||
&Window::Wayland(ref w) => w.set_max_dimensions(dimensions),
|
||||
&Window::X(ref w) => w.set_max_inner_size(dimensions),
|
||||
&Window::Wayland(ref w) => w.set_max_inner_size(dimensions),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -250,39 +258,39 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
||||
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_cursor(cursor),
|
||||
&Window::Wayland(ref w) => w.set_cursor(cursor)
|
||||
&Window::X(ref w) => w.set_cursor_icon(cursor),
|
||||
&Window::Wayland(ref w) => w.set_cursor_icon(cursor)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
||||
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||
match self {
|
||||
&Window::X(ref window) => window.grab_cursor(grab),
|
||||
&Window::Wayland(ref window) => window.grab_cursor(grab),
|
||||
&Window::X(ref window) => window.set_cursor_grab(grab),
|
||||
&Window::Wayland(ref window) => window.set_cursor_grab(grab),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide_cursor(&self, hide: bool) {
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
match self {
|
||||
&Window::X(ref window) => window.hide_cursor(hide),
|
||||
&Window::Wayland(ref window) => window.hide_cursor(hide),
|
||||
&Window::X(ref window) => window.set_cursor_visible(visible),
|
||||
&Window::Wayland(ref window) => window.set_cursor_visible(visible),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_hidpi_factor(),
|
||||
&Window::X(ref w) => w.hidpi_factor(),
|
||||
&Window::Wayland(ref w) => w.hidpi_factor() as f64,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), String> {
|
||||
pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_cursor_position(position),
|
||||
&Window::Wayland(ref w) => w.set_cursor_position(position),
|
||||
|
|
@ -298,10 +306,10 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
match self {
|
||||
&Window::X(ref w) => w.get_fullscreen(),
|
||||
&Window::Wayland(ref w) => w.get_fullscreen()
|
||||
&Window::X(ref w) => w.fullscreen(),
|
||||
&Window::Wayland(ref w) => w.fullscreen()
|
||||
.map(|monitor_id| RootMonitorHandle { inner: MonitorHandle::Wayland(monitor_id) })
|
||||
}
|
||||
}
|
||||
|
|
@ -339,9 +347,9 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_spot(&self, position: LogicalPosition) {
|
||||
pub fn set_ime_position(&self, position: LogicalPosition) {
|
||||
match self {
|
||||
&Window::X(ref w) => w.set_ime_spot(position),
|
||||
&Window::X(ref w) => w.set_ime_position(position),
|
||||
&Window::Wayland(_) => (),
|
||||
}
|
||||
}
|
||||
|
|
@ -355,21 +363,21 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
||||
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||
match self {
|
||||
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.get_current_monitor()) },
|
||||
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.get_current_monitor()) },
|
||||
&Window::X(ref window) => RootMonitorHandle { inner: MonitorHandle::X(window.current_monitor()) },
|
||||
&Window::Wayland(ref window) => RootMonitorHandle { inner: MonitorHandle::Wayland(window.current_monitor()) },
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
match self {
|
||||
&Window::X(ref window) => window.get_available_monitors()
|
||||
&Window::X(ref window) => window.available_monitors()
|
||||
.into_iter()
|
||||
.map(MonitorHandle::X)
|
||||
.collect(),
|
||||
&Window::Wayland(ref window) => window.get_available_monitors()
|
||||
&Window::Wayland(ref window) => window.available_monitors()
|
||||
.into_iter()
|
||||
.map(MonitorHandle::Wayland)
|
||||
.collect(),
|
||||
|
|
@ -377,10 +385,10 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
match self {
|
||||
&Window::X(ref window) => MonitorHandle::X(window.get_primary_monitor()),
|
||||
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.get_primary_monitor()),
|
||||
&Window::X(ref window) => MonitorHandle::X(window.primary_monitor()),
|
||||
&Window::Wayland(ref window) => MonitorHandle::Wayland(window.primary_monitor()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -481,16 +489,16 @@ impl<T:'static> EventLoop<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
match *self {
|
||||
EventLoop::Wayland(ref evlp) => evlp
|
||||
.get_available_monitors()
|
||||
.available_monitors()
|
||||
.into_iter()
|
||||
.map(MonitorHandle::Wayland)
|
||||
.collect(),
|
||||
EventLoop::X(ref evlp) => evlp
|
||||
.x_connection()
|
||||
.get_available_monitors()
|
||||
.available_monitors()
|
||||
.into_iter()
|
||||
.map(MonitorHandle::X)
|
||||
.collect(),
|
||||
|
|
@ -498,10 +506,10 @@ impl<T:'static> EventLoop<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
match *self {
|
||||
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.get_primary_monitor()),
|
||||
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().get_primary_monitor()),
|
||||
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.primary_monitor()),
|
||||
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().primary_monitor()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -574,4 +582,4 @@ fn sticky_exit_callback<T, F>(
|
|||
};
|
||||
// user callback
|
||||
callback(evt, target, cf)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,15 +296,15 @@ impl<T: 'static> EventLoop<T> {
|
|||
callback(::event::Event::LoopDestroyed, &self.window_target, &mut control_flow);
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
get_primary_monitor(&self.outputs)
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
primary_monitor(&self.outputs)
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
get_available_monitors(&self.outputs)
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
available_monitors(&self.outputs)
|
||||
}
|
||||
|
||||
pub fn get_display(&self) -> &Display {
|
||||
pub fn display(&self) -> &Display {
|
||||
&*self.display
|
||||
}
|
||||
|
||||
|
|
@ -532,11 +532,11 @@ impl fmt::Debug for MonitorHandle {
|
|||
}
|
||||
|
||||
let monitor_id_proxy = MonitorHandle {
|
||||
name: self.get_name(),
|
||||
native_identifier: self.get_native_identifier(),
|
||||
dimensions: self.get_dimensions(),
|
||||
position: self.get_position(),
|
||||
hidpi_factor: self.get_hidpi_factor(),
|
||||
name: self.name(),
|
||||
native_identifier: self.native_identifier(),
|
||||
dimensions: self.dimensions(),
|
||||
position: self.position(),
|
||||
hidpi_factor: self.hidpi_factor(),
|
||||
};
|
||||
|
||||
monitor_id_proxy.fmt(f)
|
||||
|
|
@ -544,18 +544,18 @@ impl fmt::Debug for MonitorHandle {
|
|||
}
|
||||
|
||||
impl MonitorHandle {
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
self.mgr.with_info(&self.proxy, |_, info| {
|
||||
format!("{} ({})", info.model, info.make)
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_native_identifier(&self) -> u32 {
|
||||
pub fn native_identifier(&self) -> u32 {
|
||||
self.mgr.with_info(&self.proxy, |id, _| id).unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
pub fn dimensions(&self) -> PhysicalSize {
|
||||
match self.mgr.with_info(&self.proxy, |_, info| {
|
||||
info.modes
|
||||
.iter()
|
||||
|
|
@ -567,7 +567,7 @@ impl MonitorHandle {
|
|||
}.into()
|
||||
}
|
||||
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
pub fn position(&self) -> PhysicalPosition {
|
||||
self.mgr
|
||||
.with_info(&self.proxy, |_, info| info.location)
|
||||
.unwrap_or((0, 0))
|
||||
|
|
@ -575,14 +575,14 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> i32 {
|
||||
pub fn hidpi_factor(&self) -> i32 {
|
||||
self.mgr
|
||||
.with_info(&self.proxy, |_, info| info.scale_factor)
|
||||
.unwrap_or(1)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
|
||||
pub fn primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
|
||||
outputs.with_all(|list| {
|
||||
if let Some(&(_, ref proxy, _)) = list.first() {
|
||||
MonitorHandle {
|
||||
|
|
@ -595,7 +595,7 @@ pub fn get_primary_monitor(outputs: &OutputMgr) -> MonitorHandle {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(outputs: &OutputMgr) -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors(outputs: &OutputMgr) -> VecDeque<MonitorHandle> {
|
||||
outputs.with_all(|list| {
|
||||
list.iter()
|
||||
.map(|&(_, ref proxy, _)| MonitorHandle {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use std::collections::VecDeque;
|
|||
use std::sync::{Arc, Mutex, Weak};
|
||||
|
||||
use dpi::{LogicalPosition, LogicalSize};
|
||||
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
|
||||
use monitor::MonitorHandle as RootMonitorHandle;
|
||||
use window::{CreationError, WindowAttributes, MouseCursor};
|
||||
use window::{WindowAttributes, CursorIcon};
|
||||
|
||||
use sctk::surface::{get_dpi_factor, get_outputs};
|
||||
use sctk::window::{ConceptFrame, Event as WEvent, State as WState, Window as SWindow, Theme};
|
||||
|
|
@ -13,7 +14,7 @@ use sctk::reexports::client::protocol::{wl_seat, wl_surface};
|
|||
use sctk::output::OutputMgr;
|
||||
|
||||
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
|
||||
use platform_impl::platform::wayland::event_loop::{get_available_monitors, get_primary_monitor};
|
||||
use platform_impl::platform::wayland::event_loop::{available_monitors, primary_monitor};
|
||||
|
||||
pub struct Window {
|
||||
surface: wl_surface::WlSurface,
|
||||
|
|
@ -28,8 +29,8 @@ pub struct Window {
|
|||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> {
|
||||
let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600));
|
||||
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, RootOsError> {
|
||||
let (width, height) = attributes.inner_size.map(Into::into).unwrap_or((800, 600));
|
||||
// Create the window
|
||||
let size = Arc::new(Mutex::new((width, height)));
|
||||
let fullscreen = Arc::new(Mutex::new(false));
|
||||
|
|
@ -109,8 +110,8 @@ impl Window {
|
|||
frame.set_title(attributes.title);
|
||||
|
||||
// min-max dimensions
|
||||
frame.set_min_size(attributes.min_dimensions.map(Into::into));
|
||||
frame.set_max_size(attributes.max_dimensions.map(Into::into));
|
||||
frame.set_min_size(attributes.min_inner_size.map(Into::into));
|
||||
frame.set_max_size(attributes.max_inner_size.map(Into::into));
|
||||
|
||||
let kill_switch = Arc::new(Mutex::new(false));
|
||||
let need_frame_refresh = Arc::new(Mutex::new(true));
|
||||
|
|
@ -154,35 +155,27 @@ impl Window {
|
|||
self.frame.lock().unwrap().set_title(title.into());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show(&self) {
|
||||
pub fn set_visible(&self, _visible: bool) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide(&self) {
|
||||
// TODO
|
||||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
Err(NotSupportedError::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
// Not possible with wayland
|
||||
None
|
||||
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
Err(NotSupportedError::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
// Not possible with wayland
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_position(&self, _pos: LogicalPosition) {
|
||||
pub fn set_outer_position(&self, _pos: LogicalPosition) {
|
||||
// Not possible with wayland
|
||||
}
|
||||
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
Some(self.size.lock().unwrap().clone().into())
|
||||
pub fn inner_size(&self) -> LogicalSize {
|
||||
self.size.lock().unwrap().clone().into()
|
||||
}
|
||||
|
||||
pub fn request_redraw(&self) {
|
||||
|
|
@ -190,10 +183,10 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
pub fn outer_size(&self) -> LogicalSize {
|
||||
let (w, h) = self.size.lock().unwrap().clone();
|
||||
// let (w, h) = super::wayland_window::add_borders(w as i32, h as i32);
|
||||
Some((w, h).into())
|
||||
(w, h).into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -205,12 +198,12 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
self.frame.lock().unwrap().set_min_size(dimensions.map(Into::into));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
self.frame.lock().unwrap().set_max_size(dimensions.map(Into::into));
|
||||
}
|
||||
|
||||
|
|
@ -237,9 +230,9 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_fullscreen(&self) -> Option<MonitorHandle> {
|
||||
pub fn fullscreen(&self) -> Option<MonitorHandle> {
|
||||
if *(self.fullscreen.lock().unwrap()) {
|
||||
Some(self.get_current_monitor())
|
||||
Some(self.current_monitor())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -265,34 +258,34 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, _cursor: MouseCursor) {
|
||||
pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide_cursor(&self, _hide: bool) {
|
||||
pub fn set_cursor_visible(&self, _visible: bool) {
|
||||
// TODO: This isn't possible on Wayland yet
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> {
|
||||
Err("Cursor grabbing is not yet possible on Wayland.".to_owned())
|
||||
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), String> {
|
||||
Err("Setting the cursor position is not yet possible on Wayland.".to_owned())
|
||||
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn get_display(&self) -> &Display {
|
||||
pub fn display(&self) -> &Display {
|
||||
&*self.display
|
||||
}
|
||||
|
||||
pub fn get_surface(&self) -> &wl_surface::WlSurface {
|
||||
pub fn surface(&self) -> &wl_surface::WlSurface {
|
||||
&self.surface
|
||||
}
|
||||
|
||||
pub fn get_current_monitor(&self) -> MonitorHandle {
|
||||
pub fn current_monitor(&self) -> MonitorHandle {
|
||||
let output = get_outputs(&self.surface).last().unwrap().clone();
|
||||
MonitorHandle {
|
||||
proxy: output,
|
||||
|
|
@ -300,12 +293,12 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
get_available_monitors(&self.outputs)
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
available_monitors(&self.outputs)
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
get_primary_monitor(&self.outputs)
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
primary_monitor(&self.outputs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let new_inner_size = (xev.width as u32, xev.height as u32);
|
||||
let new_inner_position = (xev.x as i32, xev.y as i32);
|
||||
|
||||
let mut monitor = window.get_current_monitor(); // This must be done *before* locking!
|
||||
let mut monitor = window.current_monitor(); // This must be done *before* locking!
|
||||
let mut shared_state_lock = window.shared_state.lock();
|
||||
|
||||
let (mut resized, moved) = {
|
||||
|
|
@ -534,10 +534,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let device_id = mkdid(xev.deviceid);
|
||||
if (xev.flags & ffi::XIPointerEmulated) != 0 {
|
||||
// Deliver multi-touch events instead of emulated mouse events.
|
||||
let return_now = self
|
||||
.with_window(xev.event, |window| window.multitouch)
|
||||
.unwrap_or(true);
|
||||
if return_now { return; }
|
||||
return;
|
||||
}
|
||||
|
||||
let modifiers = ModifiersState::from(xev.mods);
|
||||
|
|
@ -622,7 +619,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
});
|
||||
if cursor_moved == Some(true) {
|
||||
let dpi_factor = self.with_window(xev.event, |window| {
|
||||
window.get_hidpi_factor()
|
||||
window.hidpi_factor()
|
||||
});
|
||||
if let Some(dpi_factor) = dpi_factor {
|
||||
let position = LogicalPosition::from_physical(
|
||||
|
|
@ -721,7 +718,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
});
|
||||
|
||||
if let Some(dpi_factor) = self.with_window(xev.event, |window| {
|
||||
window.get_hidpi_factor()
|
||||
window.hidpi_factor()
|
||||
}) {
|
||||
let position = LogicalPosition::from_physical(
|
||||
(xev.event_x as f64, xev.event_y as f64),
|
||||
|
|
@ -767,7 +764,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) };
|
||||
|
||||
let dpi_factor = match self.with_window(xev.event, |window| {
|
||||
window.get_hidpi_factor()
|
||||
window.hidpi_factor()
|
||||
}) {
|
||||
Some(dpi_factor) => dpi_factor,
|
||||
None => return,
|
||||
|
|
@ -825,7 +822,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
_ => unreachable!()
|
||||
};
|
||||
let dpi_factor = self.with_window(xev.event, |window| {
|
||||
window.get_hidpi_factor()
|
||||
window.hidpi_factor()
|
||||
});
|
||||
if let Some(dpi_factor) = dpi_factor {
|
||||
let location = LogicalPosition::from_physical(
|
||||
|
|
@ -960,7 +957,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
// In the future, it would be quite easy to emit monitor hotplug events.
|
||||
let prev_list = monitor::invalidate_cached_monitor_list();
|
||||
if let Some(prev_list) = prev_list {
|
||||
let new_list = wt.xconn.get_available_monitors();
|
||||
let new_list = wt.xconn.available_monitors();
|
||||
for new_monitor in new_list {
|
||||
prev_list
|
||||
.iter()
|
||||
|
|
@ -970,7 +967,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
for (window_id, window) in wt.windows.borrow().iter() {
|
||||
if let Some(window) = window.upgrade() {
|
||||
// Check if the window is on this monitor
|
||||
let monitor = window.get_current_monitor();
|
||||
let monitor = window.current_monitor();
|
||||
if monitor.name == new_monitor.name {
|
||||
callback(Event::WindowEvent {
|
||||
window_id: mkwid(window_id.0),
|
||||
|
|
@ -978,10 +975,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
new_monitor.hidpi_factor
|
||||
),
|
||||
});
|
||||
let (width, height) = match window.get_inner_size_physical() {
|
||||
Some(result) => result,
|
||||
None => continue,
|
||||
};
|
||||
let (width, height) = window.inner_size_physical();
|
||||
let (_, _, flusher) = window.adjust_for_dpi(
|
||||
prev_monitor.hidpi_factor,
|
||||
new_monitor.hidpi_factor,
|
||||
|
|
@ -1007,4 +1001,4 @@ impl<T: 'static> EventProcessor<T> {
|
|||
Err(_) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ use super::{ffi, util, XConnection, XError};
|
|||
|
||||
use self::inner::{close_im, ImeInner};
|
||||
use self::input_method::PotentialInputMethods;
|
||||
use self::context::{ImeContextCreationError, ImeContext};
|
||||
use self::context::ImeContext;
|
||||
use self::callbacks::*;
|
||||
pub use self::context::ImeContextCreationError;
|
||||
|
||||
pub type ImeReceiver = Receiver<(ffi::Window, i16, i16)>;
|
||||
pub type ImeSender = Sender<(ffi::Window, i16, i16)>;
|
||||
|
|
|
|||
|
|
@ -25,11 +25,12 @@ use std::sync::{Arc, mpsc, Weak, Mutex};
|
|||
|
||||
use libc::{self, setlocale, LC_CTYPE};
|
||||
|
||||
use error::OsError as RootOsError;
|
||||
use event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW};
|
||||
use event::{WindowEvent, Event};
|
||||
use platform_impl::PlatformSpecificWindowBuilderAttributes;
|
||||
use platform_impl::platform::sticky_exit_callback;
|
||||
use window::{CreationError, WindowAttributes};
|
||||
use window::{WindowAttributes};
|
||||
use self::dnd::{Dnd, DndState};
|
||||
use self::ime::{ImeReceiver, ImeSender, ImeCreationError, Ime};
|
||||
use self::event_processor::EventProcessor;
|
||||
|
|
@ -427,7 +428,7 @@ impl Window {
|
|||
event_loop: &EventLoopWindowTarget<T>,
|
||||
attribs: WindowAttributes,
|
||||
pl_attribs: PlatformSpecificWindowBuilderAttributes
|
||||
) -> Result<Self, CreationError> {
|
||||
) -> Result<Self, RootOsError> {
|
||||
let window = Arc::new(UnownedWindow::new(&event_loop, attribs, pl_attribs)?);
|
||||
event_loop.windows
|
||||
.borrow_mut()
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ impl MonitorHandle {
|
|||
primary: bool,
|
||||
) -> Option<Self> {
|
||||
let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr)? };
|
||||
let (dimensions, position) = unsafe { (repr.get_dimensions(), repr.get_position()) };
|
||||
let (dimensions, position) = unsafe { (repr.dimensions(), repr.position()) };
|
||||
let rect = util::AaRect::new(position, dimensions);
|
||||
Some(MonitorHandle {
|
||||
id,
|
||||
|
|
@ -80,32 +80,32 @@ impl MonitorHandle {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
Some(self.name.clone())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_native_identifier(&self) -> u32 {
|
||||
pub fn native_identifier(&self) -> u32 {
|
||||
self.id as u32
|
||||
}
|
||||
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
pub fn dimensions(&self) -> PhysicalSize {
|
||||
self.dimensions.into()
|
||||
}
|
||||
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
pub fn position(&self) -> PhysicalPosition {
|
||||
self.position.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
self.hidpi_factor
|
||||
}
|
||||
}
|
||||
|
||||
impl XConnection {
|
||||
pub fn get_monitor_for_window(&self, window_rect: Option<util::AaRect>) -> MonitorHandle {
|
||||
let monitors = self.get_available_monitors();
|
||||
let monitors = self.available_monitors();
|
||||
let default = monitors
|
||||
.get(0)
|
||||
.expect("[winit] Failed to find any monitors using XRandR.");
|
||||
|
|
@ -206,7 +206,7 @@ impl XConnection {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(&self) -> Vec<MonitorHandle> {
|
||||
pub fn available_monitors(&self) -> Vec<MonitorHandle> {
|
||||
let mut monitors_lock = MONITORS.lock();
|
||||
(*monitors_lock)
|
||||
.as_ref()
|
||||
|
|
@ -222,8 +222,8 @@ impl XConnection {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
self.get_available_monitors()
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
self.available_monitors()
|
||||
.into_iter()
|
||||
.find(|monitor| monitor.primary)
|
||||
.expect("[winit] Failed to find any monitors using XRandR.")
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ impl FrameExtentsHeuristic {
|
|||
}
|
||||
|
||||
impl XConnection {
|
||||
// This is adequate for get_inner_position
|
||||
// This is adequate for inner_position
|
||||
pub fn translate_coords(&self, window: ffi::Window, root: ffi::Window) -> Result<TranslatedCoords, XError> {
|
||||
let mut translated_coords: TranslatedCoords = unsafe { mem::uninitialized() };
|
||||
unsafe {
|
||||
|
|
@ -171,7 +171,7 @@ impl XConnection {
|
|||
self.check_errors().map(|_| translated_coords)
|
||||
}
|
||||
|
||||
// This is adequate for get_inner_size
|
||||
// This is adequate for inner_size
|
||||
pub fn get_geometry(&self, window: ffi::Window) -> Result<Geometry, XError> {
|
||||
let mut geometry: Geometry = unsafe { mem::uninitialized() };
|
||||
let _status = unsafe {
|
||||
|
|
|
|||
|
|
@ -51,14 +51,14 @@ impl MonitorRepr {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_dimensions(&self) -> (u32, u32) {
|
||||
pub unsafe fn dimensions(&self) -> (u32, u32) {
|
||||
match *self {
|
||||
MonitorRepr::Monitor(monitor) => ((*monitor).width as u32, (*monitor).height as u32),
|
||||
MonitorRepr::Crtc(crtc) => ((*crtc).width as u32, (*crtc).height as u32),
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_position(&self) -> (i32, i32) {
|
||||
pub unsafe fn position(&self) -> (i32, i32) {
|
||||
match *self {
|
||||
MonitorRepr::Monitor(monitor) => ((*monitor).x as i32, (*monitor).y as i32),
|
||||
MonitorRepr::Crtc(crtc) => ((*crtc).x as i32, (*crtc).y as i32),
|
||||
|
|
@ -123,7 +123,7 @@ impl XConnection {
|
|||
dpi / 96.
|
||||
} else {
|
||||
calc_dpi_factor(
|
||||
repr.get_dimensions(),
|
||||
repr.dimensions(),
|
||||
((*output_info).mm_width as u64, (*output_info).mm_height as u64),
|
||||
)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ use std::sync::Arc;
|
|||
use libc;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use window::{Icon, MouseCursor, WindowAttributes};
|
||||
use window::CreationError::{self, OsError};
|
||||
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use window::{Icon, CursorIcon, WindowAttributes};
|
||||
use dpi::{LogicalPosition, LogicalSize};
|
||||
use platform_impl::MonitorHandle as PlatformMonitorHandle;
|
||||
use platform_impl::PlatformSpecificWindowBuilderAttributes;
|
||||
use platform_impl::{OsError, PlatformSpecificWindowBuilderAttributes};
|
||||
use platform_impl::x11::ime::ImeContextCreationError;
|
||||
use platform_impl::x11::MonitorHandle as X11MonitorHandle;
|
||||
use monitor::MonitorHandle as RootMonitorHandle;
|
||||
|
||||
|
|
@ -42,8 +43,8 @@ pub struct SharedState {
|
|||
// Used to restore position after exiting fullscreen.
|
||||
pub restore_position: Option<(i32, i32)>,
|
||||
pub frame_extents: Option<util::FrameExtentsHeuristic>,
|
||||
pub min_dimensions: Option<LogicalSize>,
|
||||
pub max_dimensions: Option<LogicalSize>,
|
||||
pub min_inner_size: Option<LogicalSize>,
|
||||
pub max_inner_size: Option<LogicalSize>,
|
||||
}
|
||||
|
||||
impl SharedState {
|
||||
|
|
@ -62,11 +63,10 @@ pub struct UnownedWindow {
|
|||
xwindow: ffi::Window, // never changes
|
||||
root: ffi::Window, // never changes
|
||||
screen_id: i32, // never changes
|
||||
cursor: Mutex<MouseCursor>,
|
||||
cursor: Mutex<CursorIcon>,
|
||||
cursor_grabbed: Mutex<bool>,
|
||||
cursor_hidden: Mutex<bool>,
|
||||
cursor_visible: Mutex<bool>,
|
||||
ime_sender: Mutex<ImeSender>,
|
||||
pub multitouch: bool, // never changes
|
||||
pub shared_state: Mutex<SharedState>,
|
||||
pending_redraws: Arc<::std::sync::Mutex<HashSet<WindowId>>>,
|
||||
}
|
||||
|
|
@ -76,15 +76,15 @@ impl UnownedWindow {
|
|||
event_loop: &EventLoopWindowTarget<T>,
|
||||
window_attrs: WindowAttributes,
|
||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<UnownedWindow, CreationError> {
|
||||
) -> Result<UnownedWindow, RootOsError> {
|
||||
let xconn = &event_loop.xconn;
|
||||
let root = event_loop.root;
|
||||
|
||||
let monitors = xconn.get_available_monitors();
|
||||
let monitors = xconn.available_monitors();
|
||||
let dpi_factor = if !monitors.is_empty() {
|
||||
let mut dpi_factor = Some(monitors[0].get_hidpi_factor());
|
||||
let mut dpi_factor = Some(monitors[0].hidpi_factor());
|
||||
for monitor in &monitors {
|
||||
if Some(monitor.get_hidpi_factor()) != dpi_factor {
|
||||
if Some(monitor.hidpi_factor()) != dpi_factor {
|
||||
dpi_factor = None;
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ impl UnownedWindow {
|
|||
let mut dpi_factor = None;
|
||||
for monitor in &monitors {
|
||||
if monitor.rect.contains_point(x, y) {
|
||||
dpi_factor = Some(monitor.get_hidpi_factor());
|
||||
dpi_factor = Some(monitor.hidpi_factor());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -105,31 +105,31 @@ impl UnownedWindow {
|
|||
.unwrap_or(1.0)
|
||||
})
|
||||
} else {
|
||||
return Err(OsError(format!("No monitors were detected.")));
|
||||
return Err(os_error!(OsError::XMisc("No monitors were detected.")));
|
||||
};
|
||||
|
||||
info!("Guessed window DPI factor: {}", dpi_factor);
|
||||
|
||||
let max_dimensions: Option<(u32, u32)> = window_attrs.max_dimensions.map(|size| {
|
||||
let max_inner_size: Option<(u32, u32)> = window_attrs.max_inner_size.map(|size| {
|
||||
size.to_physical(dpi_factor).into()
|
||||
});
|
||||
let min_dimensions: Option<(u32, u32)> = window_attrs.min_dimensions.map(|size| {
|
||||
let min_inner_size: Option<(u32, u32)> = window_attrs.min_inner_size.map(|size| {
|
||||
size.to_physical(dpi_factor).into()
|
||||
});
|
||||
|
||||
let dimensions = {
|
||||
// x11 only applies constraints when the window is actively resized
|
||||
// by the user, so we have to manually apply the initial constraints
|
||||
let mut dimensions: (u32, u32) = window_attrs.dimensions
|
||||
let mut dimensions: (u32, u32) = window_attrs.inner_size
|
||||
.or_else(|| Some((800, 600).into()))
|
||||
.map(|size| size.to_physical(dpi_factor))
|
||||
.map(Into::into)
|
||||
.unwrap();
|
||||
if let Some(max) = max_dimensions {
|
||||
if let Some(max) = max_inner_size {
|
||||
dimensions.0 = cmp::min(dimensions.0, max.0);
|
||||
dimensions.1 = cmp::min(dimensions.1, max.1);
|
||||
}
|
||||
if let Some(min) = min_dimensions {
|
||||
if let Some(min) = min_inner_size {
|
||||
dimensions.0 = cmp::max(dimensions.0, min.0);
|
||||
dimensions.1 = cmp::max(dimensions.1, min.1);
|
||||
}
|
||||
|
|
@ -209,10 +209,9 @@ impl UnownedWindow {
|
|||
root,
|
||||
screen_id,
|
||||
cursor: Default::default(),
|
||||
cursor_grabbed: Default::default(),
|
||||
cursor_hidden: Default::default(),
|
||||
cursor_grabbed: Mutex::new(false),
|
||||
cursor_visible: Mutex::new(true),
|
||||
ime_sender: Mutex::new(event_loop.ime_sender.clone()),
|
||||
multitouch: window_attrs.multitouch,
|
||||
shared_state: SharedState::new(dpi_factor),
|
||||
pending_redraws: event_loop.pending_redraws.clone(),
|
||||
};
|
||||
|
|
@ -290,27 +289,27 @@ impl UnownedWindow {
|
|||
|
||||
// set size hints
|
||||
{
|
||||
let mut min_dimensions = window_attrs.min_dimensions
|
||||
let mut min_inner_size = window_attrs.min_inner_size
|
||||
.map(|size| size.to_physical(dpi_factor));
|
||||
let mut max_dimensions = window_attrs.max_dimensions
|
||||
let mut max_inner_size = window_attrs.max_inner_size
|
||||
.map(|size| size.to_physical(dpi_factor));
|
||||
if !window_attrs.resizable {
|
||||
if util::wm_name_is_one_of(&["Xfwm4"]) {
|
||||
warn!("To avoid a WM bug, disabling resizing has no effect on Xfwm4");
|
||||
} else {
|
||||
max_dimensions = Some(dimensions.into());
|
||||
min_dimensions = Some(dimensions.into());
|
||||
max_inner_size = Some(dimensions.into());
|
||||
min_inner_size = Some(dimensions.into());
|
||||
|
||||
let mut shared_state_lock = window.shared_state.lock();
|
||||
shared_state_lock.min_dimensions = window_attrs.min_dimensions;
|
||||
shared_state_lock.max_dimensions = window_attrs.max_dimensions;
|
||||
shared_state_lock.min_inner_size = window_attrs.min_inner_size;
|
||||
shared_state_lock.max_inner_size = window_attrs.max_inner_size;
|
||||
}
|
||||
}
|
||||
|
||||
let mut normal_hints = util::NormalHints::new(xconn);
|
||||
normal_hints.set_size(Some(dimensions));
|
||||
normal_hints.set_min_size(min_dimensions.map(Into::into));
|
||||
normal_hints.set_max_size(max_dimensions.map(Into::into));
|
||||
normal_hints.set_min_size(min_inner_size.map(Into::into));
|
||||
normal_hints.set_max_size(max_inner_size.map(Into::into));
|
||||
normal_hints.set_resize_increments(pl_attribs.resize_increments);
|
||||
normal_hints.set_base_size(pl_attribs.base_size);
|
||||
xconn.set_normal_hints(window.xwindow, normal_hints).queue();
|
||||
|
|
@ -347,13 +346,13 @@ impl UnownedWindow {
|
|||
&mut supported_ptr,
|
||||
);
|
||||
if supported_ptr == ffi::False {
|
||||
return Err(OsError(format!("`XkbSetDetectableAutoRepeat` failed")));
|
||||
return Err(os_error!(OsError::XMisc("`XkbSetDetectableAutoRepeat` failed")));
|
||||
}
|
||||
}
|
||||
|
||||
// Select XInput2 events
|
||||
let mask = {
|
||||
let mut mask = ffi::XI_MotionMask
|
||||
let mask = ffi::XI_MotionMask
|
||||
| ffi::XI_ButtonPressMask
|
||||
| ffi::XI_ButtonReleaseMask
|
||||
//| ffi::XI_KeyPressMask
|
||||
|
|
@ -361,12 +360,10 @@ impl UnownedWindow {
|
|||
| ffi::XI_EnterMask
|
||||
| ffi::XI_LeaveMask
|
||||
| ffi::XI_FocusInMask
|
||||
| ffi::XI_FocusOutMask;
|
||||
if window_attrs.multitouch {
|
||||
mask |= ffi::XI_TouchBeginMask
|
||||
| ffi::XI_TouchUpdateMask
|
||||
| ffi::XI_TouchEndMask;
|
||||
}
|
||||
| ffi::XI_FocusOutMask
|
||||
| ffi::XI_TouchBeginMask
|
||||
| ffi::XI_TouchUpdateMask
|
||||
| ffi::XI_TouchEndMask;
|
||||
mask
|
||||
};
|
||||
xconn.select_xinput_events(window.xwindow, ffi::XIAllMasterDevices, mask).queue();
|
||||
|
|
@ -376,7 +373,11 @@ impl UnownedWindow {
|
|||
.borrow_mut()
|
||||
.create_context(window.xwindow);
|
||||
if let Err(err) = result {
|
||||
return Err(OsError(format!("Failed to create input context: {:?}", err)));
|
||||
let e = match err {
|
||||
ImeContextCreationError::XError(err) => OsError::XError(err),
|
||||
ImeContextCreationError::Null => OsError::XMisc("IME Context creation failed"),
|
||||
};
|
||||
return Err(os_error!(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -415,18 +416,16 @@ impl UnownedWindow {
|
|||
// We never want to give the user a broken window, since by then, it's too late to handle.
|
||||
xconn.sync_with_server()
|
||||
.map(|_| window)
|
||||
.map_err(|x_err| OsError(
|
||||
format!("X server returned error while building window: {:?}", x_err)
|
||||
))
|
||||
.map_err(|x_err| os_error!(OsError::XError(x_err)))
|
||||
}
|
||||
|
||||
fn logicalize_coords(&self, (x, y): (i32, i32)) -> LogicalPosition {
|
||||
let dpi = self.get_hidpi_factor();
|
||||
let dpi = self.hidpi_factor();
|
||||
LogicalPosition::from_physical((x, y), dpi)
|
||||
}
|
||||
|
||||
fn logicalize_size(&self, (width, height): (u32, u32)) -> LogicalSize {
|
||||
let dpi = self.get_hidpi_factor();
|
||||
let dpi = self.hidpi_factor();
|
||||
LogicalSize::from_physical((width, height), dpi)
|
||||
}
|
||||
|
||||
|
|
@ -535,9 +534,9 @@ impl UnownedWindow {
|
|||
flusher
|
||||
},
|
||||
Some(RootMonitorHandle { inner: PlatformMonitorHandle::X(monitor) }) => {
|
||||
let window_position = self.get_position_physical();
|
||||
self.shared_state.lock().restore_position = window_position;
|
||||
let monitor_origin: (i32, i32) = monitor.get_position().into();
|
||||
let window_position = self.outer_position_physical();
|
||||
self.shared_state.lock().restore_position = Some(window_position);
|
||||
let monitor_origin: (i32, i32) = monitor.position().into();
|
||||
self.set_position_inner(monitor_origin.0, monitor_origin.1).queue();
|
||||
self.set_fullscreen_hint(true)
|
||||
}
|
||||
|
|
@ -546,7 +545,7 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
self.shared_state.lock().fullscreen.clone()
|
||||
}
|
||||
|
||||
|
|
@ -559,17 +558,15 @@ impl UnownedWindow {
|
|||
self.invalidate_cached_frame_extents();
|
||||
}
|
||||
|
||||
fn get_rect(&self) -> Option<util::AaRect> {
|
||||
fn get_rect(&self) -> util::AaRect {
|
||||
// TODO: This might round-trip more times than needed.
|
||||
if let (Some(position), Some(size)) = (self.get_position_physical(), self.get_outer_size_physical()) {
|
||||
Some(util::AaRect::new(position, size))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let position = self.outer_position_physical();
|
||||
let size = self.outer_size_physical();
|
||||
util::AaRect::new(position, size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_current_monitor(&self) -> X11MonitorHandle {
|
||||
pub fn current_monitor(&self) -> X11MonitorHandle {
|
||||
let monitor = self.shared_state
|
||||
.lock()
|
||||
.last_monitor
|
||||
|
|
@ -577,18 +574,18 @@ impl UnownedWindow {
|
|||
.cloned();
|
||||
monitor
|
||||
.unwrap_or_else(|| {
|
||||
let monitor = self.xconn.get_monitor_for_window(self.get_rect()).to_owned();
|
||||
let monitor = self.xconn.get_monitor_for_window(Some(self.get_rect())).to_owned();
|
||||
self.shared_state.lock().last_monitor = Some(monitor.clone());
|
||||
monitor
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_available_monitors(&self) -> Vec<X11MonitorHandle> {
|
||||
self.xconn.get_available_monitors()
|
||||
pub fn available_monitors(&self) -> Vec<X11MonitorHandle> {
|
||||
self.xconn.available_monitors()
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(&self) -> X11MonitorHandle {
|
||||
self.xconn.get_primary_monitor()
|
||||
pub fn primary_monitor(&self) -> X11MonitorHandle {
|
||||
self.xconn.primary_monitor()
|
||||
}
|
||||
|
||||
fn set_maximized_inner(&self, maximized: bool) -> util::Flusher {
|
||||
|
|
@ -702,20 +699,18 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show(&self) {
|
||||
unsafe {
|
||||
(self.xconn.xlib.XMapRaised)(self.xconn.display, self.xwindow);
|
||||
self.xconn.flush_requests()
|
||||
.expect("Failed to call XMapRaised");
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide(&self) {
|
||||
unsafe {
|
||||
(self.xconn.xlib.XUnmapWindow)(self.xconn.display, self.xwindow);
|
||||
self.xconn.flush_requests()
|
||||
.expect("Failed to call XUnmapWindow");
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
match visible {
|
||||
true => unsafe {
|
||||
(self.xconn.xlib.XMapRaised)(self.xconn.display, self.xwindow);
|
||||
self.xconn.flush_requests()
|
||||
.expect("Failed to call XMapRaised");
|
||||
},
|
||||
false => unsafe {
|
||||
(self.xconn.xlib.XUnmapWindow)(self.xconn.display, self.xwindow);
|
||||
self.xconn.flush_requests()
|
||||
.expect("Failed to call XUnmapWindow");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -728,39 +723,40 @@ impl UnownedWindow {
|
|||
(*self.shared_state.lock()).frame_extents.take();
|
||||
}
|
||||
|
||||
pub(crate) fn get_position_physical(&self) -> Option<(i32, i32)> {
|
||||
pub(crate) fn outer_position_physical(&self) -> (i32, i32) {
|
||||
let extents = (*self.shared_state.lock()).frame_extents.clone();
|
||||
if let Some(extents) = extents {
|
||||
self.get_inner_position_physical()
|
||||
.map(|(x, y)| extents.inner_pos_to_outer(x, y))
|
||||
let (x, y) = self.inner_position_physical();
|
||||
extents.inner_pos_to_outer(x, y)
|
||||
} else {
|
||||
self.update_cached_frame_extents();
|
||||
self.get_position_physical()
|
||||
self.outer_position_physical()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
let extents = (*self.shared_state.lock()).frame_extents.clone();
|
||||
if let Some(extents) = extents {
|
||||
self.get_inner_position()
|
||||
.map(|logical| extents.inner_pos_to_outer_logical(logical, self.get_hidpi_factor()))
|
||||
let logical = self.inner_position().unwrap();
|
||||
Ok(extents.inner_pos_to_outer_logical(logical, self.hidpi_factor()))
|
||||
} else {
|
||||
self.update_cached_frame_extents();
|
||||
self.get_position()
|
||||
self.outer_position()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_inner_position_physical(&self) -> Option<(i32, i32)> {
|
||||
pub(crate) fn inner_position_physical(&self) -> (i32, i32) {
|
||||
// This should be okay to unwrap since the only error XTranslateCoordinates can return
|
||||
// is BadWindow, and if the window handle is bad we have bigger problems.
|
||||
self.xconn.translate_coords(self.xwindow, self.root)
|
||||
.ok()
|
||||
.map(|coords| (coords.x_rel_root, coords.y_rel_root))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
self.get_inner_position_physical()
|
||||
.map(|coords| self.logicalize_coords(coords))
|
||||
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
Ok(self.logicalize_coords(self.inner_position_physical()))
|
||||
}
|
||||
|
||||
pub(crate) fn set_position_inner(&self, mut x: i32, mut y: i32) -> util::Flusher {
|
||||
|
|
@ -794,43 +790,44 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_position(&self, logical_position: LogicalPosition) {
|
||||
let (x, y) = logical_position.to_physical(self.get_hidpi_factor()).into();
|
||||
pub fn set_outer_position(&self, logical_position: LogicalPosition) {
|
||||
let (x, y) = logical_position.to_physical(self.hidpi_factor()).into();
|
||||
self.set_position_physical(x, y);
|
||||
}
|
||||
|
||||
pub(crate) fn get_inner_size_physical(&self) -> Option<(u32, u32)> {
|
||||
pub(crate) fn inner_size_physical(&self) -> (u32, u32) {
|
||||
// This should be okay to unwrap since the only error XGetGeometry can return
|
||||
// is BadWindow, and if the window handle is bad we have bigger problems.
|
||||
self.xconn.get_geometry(self.xwindow)
|
||||
.ok()
|
||||
.map(|geo| (geo.width, geo.height))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
self.get_inner_size_physical()
|
||||
.map(|size| self.logicalize_size(size))
|
||||
pub fn inner_size(&self) -> LogicalSize {
|
||||
self.logicalize_size(self.inner_size_physical())
|
||||
}
|
||||
|
||||
pub(crate) fn get_outer_size_physical(&self) -> Option<(u32, u32)> {
|
||||
pub(crate) fn outer_size_physical(&self) -> (u32, u32) {
|
||||
let extents = self.shared_state.lock().frame_extents.clone();
|
||||
if let Some(extents) = extents {
|
||||
self.get_inner_size_physical()
|
||||
.map(|(w, h)| extents.inner_size_to_outer(w, h))
|
||||
let (w, h) = self.inner_size_physical();
|
||||
extents.inner_size_to_outer(w, h)
|
||||
} else {
|
||||
self.update_cached_frame_extents();
|
||||
self.get_outer_size_physical()
|
||||
self.outer_size_physical()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
pub fn outer_size(&self) -> LogicalSize {
|
||||
let extents = self.shared_state.lock().frame_extents.clone();
|
||||
if let Some(extents) = extents {
|
||||
self.get_inner_size()
|
||||
.map(|logical| extents.inner_size_to_outer_logical(logical, self.get_hidpi_factor()))
|
||||
let logical = self.inner_size();
|
||||
extents.inner_size_to_outer_logical(logical, self.hidpi_factor())
|
||||
} else {
|
||||
self.update_cached_frame_extents();
|
||||
self.get_outer_size()
|
||||
self.outer_size()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -848,7 +845,7 @@ impl UnownedWindow {
|
|||
|
||||
#[inline]
|
||||
pub fn set_inner_size(&self, logical_size: LogicalSize) {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let (width, height) = logical_size.to_physical(dpi_factor).into();
|
||||
self.set_inner_size_physical(width, height);
|
||||
}
|
||||
|
|
@ -861,32 +858,32 @@ impl UnownedWindow {
|
|||
self.xconn.set_normal_hints(self.xwindow, normal_hints).flush()
|
||||
}
|
||||
|
||||
pub(crate) fn set_min_dimensions_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||
pub(crate) fn set_min_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||
self.update_normal_hints(|normal_hints| normal_hints.set_min_size(dimensions))
|
||||
.expect("Failed to call `XSetWMNormalHints`");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_dimensions(&self, logical_dimensions: Option<LogicalSize>) {
|
||||
self.shared_state.lock().min_dimensions = logical_dimensions;
|
||||
pub fn set_min_inner_size(&self, logical_dimensions: Option<LogicalSize>) {
|
||||
self.shared_state.lock().min_inner_size = logical_dimensions;
|
||||
let physical_dimensions = logical_dimensions.map(|logical_dimensions| {
|
||||
logical_dimensions.to_physical(self.get_hidpi_factor()).into()
|
||||
logical_dimensions.to_physical(self.hidpi_factor()).into()
|
||||
});
|
||||
self.set_min_dimensions_physical(physical_dimensions);
|
||||
self.set_min_inner_size_physical(physical_dimensions);
|
||||
}
|
||||
|
||||
pub(crate) fn set_max_dimensions_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||
pub(crate) fn set_max_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||
self.update_normal_hints(|normal_hints| normal_hints.set_max_size(dimensions))
|
||||
.expect("Failed to call `XSetWMNormalHints`");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_dimensions(&self, logical_dimensions: Option<LogicalSize>) {
|
||||
self.shared_state.lock().max_dimensions = logical_dimensions;
|
||||
pub fn set_max_inner_size(&self, logical_dimensions: Option<LogicalSize>) {
|
||||
self.shared_state.lock().max_inner_size = logical_dimensions;
|
||||
let physical_dimensions = logical_dimensions.map(|logical_dimensions| {
|
||||
logical_dimensions.to_physical(self.get_hidpi_factor()).into()
|
||||
logical_dimensions.to_physical(self.hidpi_factor()).into()
|
||||
});
|
||||
self.set_max_dimensions_physical(physical_dimensions);
|
||||
self.set_max_inner_size_physical(physical_dimensions);
|
||||
}
|
||||
|
||||
pub(crate) fn adjust_for_dpi(
|
||||
|
|
@ -936,47 +933,47 @@ impl UnownedWindow {
|
|||
|
||||
let (logical_min, logical_max) = if resizable {
|
||||
let shared_state_lock = self.shared_state.lock();
|
||||
(shared_state_lock.min_dimensions, shared_state_lock.max_dimensions)
|
||||
(shared_state_lock.min_inner_size, shared_state_lock.max_inner_size)
|
||||
} else {
|
||||
let window_size = self.get_inner_size();
|
||||
let window_size = Some(self.inner_size());
|
||||
(window_size.clone(), window_size)
|
||||
};
|
||||
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
let min_dimensions = logical_min
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let min_inner_size = logical_min
|
||||
.map(|logical_size| logical_size.to_physical(dpi_factor))
|
||||
.map(Into::into);
|
||||
let max_dimensions = logical_max
|
||||
let max_inner_size = logical_max
|
||||
.map(|logical_size| logical_size.to_physical(dpi_factor))
|
||||
.map(Into::into);
|
||||
self.update_normal_hints(|normal_hints| {
|
||||
normal_hints.set_min_size(min_dimensions);
|
||||
normal_hints.set_max_size(max_dimensions);
|
||||
normal_hints.set_min_size(min_inner_size);
|
||||
normal_hints.set_max_size(max_inner_size);
|
||||
}).expect("Failed to call `XSetWMNormalHints`");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_xlib_display(&self) -> *mut c_void {
|
||||
pub fn xlib_display(&self) -> *mut c_void {
|
||||
self.xconn.display as _
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_xlib_screen_id(&self) -> c_int {
|
||||
pub fn xlib_screen_id(&self) -> c_int {
|
||||
self.screen_id
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_xlib_xconnection(&self) -> Arc<XConnection> {
|
||||
pub fn xlib_xconnection(&self) -> Arc<XConnection> {
|
||||
Arc::clone(&self.xconn)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_xlib_window(&self) -> c_ulong {
|
||||
pub fn xlib_window(&self) -> c_ulong {
|
||||
self.xwindow
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_xcb_connection(&self) -> *mut c_void {
|
||||
pub fn xcb_connection(&self) -> *mut c_void {
|
||||
unsafe {
|
||||
(self.xconn.xlib_xcb.XGetXCBConnection)(self.xconn.display) as *mut _
|
||||
}
|
||||
|
|
@ -1001,7 +998,7 @@ impl UnownedWindow {
|
|||
0
|
||||
}
|
||||
|
||||
fn get_cursor(&self, cursor: MouseCursor) -> ffi::Cursor {
|
||||
fn get_cursor(&self, cursor: CursorIcon) -> ffi::Cursor {
|
||||
let load = |name: &[u8]| {
|
||||
self.load_cursor(name)
|
||||
};
|
||||
|
|
@ -1015,48 +1012,48 @@ impl UnownedWindow {
|
|||
//
|
||||
// Try the better looking (or more suiting) names first.
|
||||
match cursor {
|
||||
MouseCursor::Alias => load(b"link\0"),
|
||||
MouseCursor::Arrow => load(b"arrow\0"),
|
||||
MouseCursor::Cell => load(b"plus\0"),
|
||||
MouseCursor::Copy => load(b"copy\0"),
|
||||
MouseCursor::Crosshair => load(b"crosshair\0"),
|
||||
MouseCursor::Default => load(b"left_ptr\0"),
|
||||
MouseCursor::Hand => loadn(&[b"hand2\0", b"hand1\0"]),
|
||||
MouseCursor::Help => load(b"question_arrow\0"),
|
||||
MouseCursor::Move => load(b"move\0"),
|
||||
MouseCursor::Grab => loadn(&[b"openhand\0", b"grab\0"]),
|
||||
MouseCursor::Grabbing => loadn(&[b"closedhand\0", b"grabbing\0"]),
|
||||
MouseCursor::Progress => load(b"left_ptr_watch\0"),
|
||||
MouseCursor::AllScroll => load(b"all-scroll\0"),
|
||||
MouseCursor::ContextMenu => load(b"context-menu\0"),
|
||||
CursorIcon::Alias => load(b"link\0"),
|
||||
CursorIcon::Arrow => load(b"arrow\0"),
|
||||
CursorIcon::Cell => load(b"plus\0"),
|
||||
CursorIcon::Copy => load(b"copy\0"),
|
||||
CursorIcon::Crosshair => load(b"crosshair\0"),
|
||||
CursorIcon::Default => load(b"left_ptr\0"),
|
||||
CursorIcon::Hand => loadn(&[b"hand2\0", b"hand1\0"]),
|
||||
CursorIcon::Help => load(b"question_arrow\0"),
|
||||
CursorIcon::Move => load(b"move\0"),
|
||||
CursorIcon::Grab => loadn(&[b"openhand\0", b"grab\0"]),
|
||||
CursorIcon::Grabbing => loadn(&[b"closedhand\0", b"grabbing\0"]),
|
||||
CursorIcon::Progress => load(b"left_ptr_watch\0"),
|
||||
CursorIcon::AllScroll => load(b"all-scroll\0"),
|
||||
CursorIcon::ContextMenu => load(b"context-menu\0"),
|
||||
|
||||
MouseCursor::NoDrop => loadn(&[b"no-drop\0", b"circle\0"]),
|
||||
MouseCursor::NotAllowed => load(b"crossed_circle\0"),
|
||||
CursorIcon::NoDrop => loadn(&[b"no-drop\0", b"circle\0"]),
|
||||
CursorIcon::NotAllowed => load(b"crossed_circle\0"),
|
||||
|
||||
|
||||
// Resize cursors
|
||||
MouseCursor::EResize => load(b"right_side\0"),
|
||||
MouseCursor::NResize => load(b"top_side\0"),
|
||||
MouseCursor::NeResize => load(b"top_right_corner\0"),
|
||||
MouseCursor::NwResize => load(b"top_left_corner\0"),
|
||||
MouseCursor::SResize => load(b"bottom_side\0"),
|
||||
MouseCursor::SeResize => load(b"bottom_right_corner\0"),
|
||||
MouseCursor::SwResize => load(b"bottom_left_corner\0"),
|
||||
MouseCursor::WResize => load(b"left_side\0"),
|
||||
MouseCursor::EwResize => load(b"h_double_arrow\0"),
|
||||
MouseCursor::NsResize => load(b"v_double_arrow\0"),
|
||||
MouseCursor::NwseResize => loadn(&[b"bd_double_arrow\0", b"size_bdiag\0"]),
|
||||
MouseCursor::NeswResize => loadn(&[b"fd_double_arrow\0", b"size_fdiag\0"]),
|
||||
MouseCursor::ColResize => loadn(&[b"split_h\0", b"h_double_arrow\0"]),
|
||||
MouseCursor::RowResize => loadn(&[b"split_v\0", b"v_double_arrow\0"]),
|
||||
CursorIcon::EResize => load(b"right_side\0"),
|
||||
CursorIcon::NResize => load(b"top_side\0"),
|
||||
CursorIcon::NeResize => load(b"top_right_corner\0"),
|
||||
CursorIcon::NwResize => load(b"top_left_corner\0"),
|
||||
CursorIcon::SResize => load(b"bottom_side\0"),
|
||||
CursorIcon::SeResize => load(b"bottom_right_corner\0"),
|
||||
CursorIcon::SwResize => load(b"bottom_left_corner\0"),
|
||||
CursorIcon::WResize => load(b"left_side\0"),
|
||||
CursorIcon::EwResize => load(b"h_double_arrow\0"),
|
||||
CursorIcon::NsResize => load(b"v_double_arrow\0"),
|
||||
CursorIcon::NwseResize => loadn(&[b"bd_double_arrow\0", b"size_bdiag\0"]),
|
||||
CursorIcon::NeswResize => loadn(&[b"fd_double_arrow\0", b"size_fdiag\0"]),
|
||||
CursorIcon::ColResize => loadn(&[b"split_h\0", b"h_double_arrow\0"]),
|
||||
CursorIcon::RowResize => loadn(&[b"split_v\0", b"v_double_arrow\0"]),
|
||||
|
||||
MouseCursor::Text => loadn(&[b"text\0", b"xterm\0"]),
|
||||
MouseCursor::VerticalText => load(b"vertical-text\0"),
|
||||
CursorIcon::Text => loadn(&[b"text\0", b"xterm\0"]),
|
||||
CursorIcon::VerticalText => load(b"vertical-text\0"),
|
||||
|
||||
MouseCursor::Wait => load(b"watch\0"),
|
||||
CursorIcon::Wait => load(b"watch\0"),
|
||||
|
||||
MouseCursor::ZoomIn => load(b"zoom-in\0"),
|
||||
MouseCursor::ZoomOut => load(b"zoom-out\0"),
|
||||
CursorIcon::ZoomIn => load(b"zoom-in\0"),
|
||||
CursorIcon::ZoomOut => load(b"zoom-out\0"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1071,9 +1068,9 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
||||
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||
*self.cursor.lock() = cursor;
|
||||
if !*self.cursor_hidden.lock() {
|
||||
if *self.cursor_visible.lock() {
|
||||
self.update_cursor(self.get_cursor(cursor));
|
||||
}
|
||||
}
|
||||
|
|
@ -1117,7 +1114,7 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
||||
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||
let mut grabbed_lock = self.cursor_grabbed.lock();
|
||||
if grab == *grabbed_lock { return Ok(()); }
|
||||
unsafe {
|
||||
|
|
@ -1161,10 +1158,10 @@ impl UnownedWindow {
|
|||
ffi::GrabNotViewable => Err("Cursor could not be grabbed: grab location not viewable"),
|
||||
ffi::GrabFrozen => Err("Cursor could not be grabbed: frozen by another client"),
|
||||
_ => unreachable!(),
|
||||
}.map_err(|err| err.to_owned())
|
||||
}.map_err(|err| ExternalError::Os(os_error!(OsError::XMisc(err))))
|
||||
} else {
|
||||
self.xconn.flush_requests()
|
||||
.map_err(|err| format!("Failed to call `XUngrabPointer`: {:?}", err))
|
||||
.map_err(|err| ExternalError::Os(os_error!(OsError::XError(err))))
|
||||
};
|
||||
if result.is_ok() {
|
||||
*grabbed_lock = grab;
|
||||
|
|
@ -1173,25 +1170,25 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide_cursor(&self, hide: bool) {
|
||||
let mut hidden_lock = self.cursor_hidden.lock();
|
||||
if hide == *hidden_lock {return; }
|
||||
let cursor = if hide {
|
||||
self.create_empty_cursor().expect("Failed to create empty cursor")
|
||||
} else {
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
let mut visible_lock = self.cursor_visible.lock();
|
||||
if visible == *visible_lock {return; }
|
||||
let cursor = if visible {
|
||||
self.get_cursor(*self.cursor.lock())
|
||||
} else {
|
||||
self.create_empty_cursor().expect("Failed to create empty cursor")
|
||||
};
|
||||
*hidden_lock = hide;
|
||||
drop(hidden_lock);
|
||||
*visible_lock = visible;
|
||||
drop(visible_lock);
|
||||
self.update_cursor(cursor);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
self.get_current_monitor().hidpi_factor
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
self.current_monitor().hidpi_factor
|
||||
}
|
||||
|
||||
pub fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), String> {
|
||||
pub fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), ExternalError> {
|
||||
unsafe {
|
||||
(self.xconn.xlib.XWarpPointer)(
|
||||
self.xconn.display,
|
||||
|
|
@ -1204,26 +1201,26 @@ impl UnownedWindow {
|
|||
x,
|
||||
y,
|
||||
);
|
||||
self.xconn.flush_requests().map_err(|e| format!("`XWarpPointer` failed: {:?}", e))
|
||||
self.xconn.flush_requests().map_err(|e| ExternalError::Os(os_error!(OsError::XError(e))))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), String> {
|
||||
let (x, y) = logical_position.to_physical(self.get_hidpi_factor()).into();
|
||||
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), ExternalError> {
|
||||
let (x, y) = logical_position.to_physical(self.hidpi_factor()).into();
|
||||
self.set_cursor_position_physical(x, y)
|
||||
}
|
||||
|
||||
pub(crate) fn set_ime_spot_physical(&self, x: i32, y: i32) {
|
||||
pub(crate) fn set_ime_position_physical(&self, x: i32, y: i32) {
|
||||
let _ = self.ime_sender
|
||||
.lock()
|
||||
.send((self.xwindow, x as i16, y as i16));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_spot(&self, logical_spot: LogicalPosition) {
|
||||
let (x, y) = logical_spot.to_physical(self.get_hidpi_factor()).into();
|
||||
self.set_ime_spot_physical(x, y);
|
||||
pub fn set_ime_position(&self, logical_spot: LogicalPosition) {
|
||||
let (x, y) = logical_spot.to_physical(self.hidpi_factor()).into();
|
||||
self.set_ime_position_physical(x, y);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ impl<T> EventLoop<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::get_available_monitors()
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::available_monitors()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
monitor::get_primary_monitor()
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
monitor::primary_monitor()
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootWindowTarget<T> {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@ mod view;
|
|||
mod window;
|
||||
mod window_delegate;
|
||||
|
||||
use std::{ops::Deref, sync::Arc};
|
||||
use std::{fmt, ops::Deref, sync::Arc};
|
||||
|
||||
use {
|
||||
event::DeviceId as RootDeviceId, window::{CreationError, WindowAttributes},
|
||||
event::DeviceId as RootDeviceId, window::WindowAttributes,
|
||||
error::OsError as RootOsError,
|
||||
};
|
||||
pub use self::{
|
||||
event_loop::{EventLoop, EventLoopWindowTarget, Proxy as EventLoopProxy},
|
||||
|
|
@ -44,6 +45,12 @@ pub struct Window {
|
|||
_delegate: util::IdRef,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum OsError {
|
||||
CGError(core_graphics::base::CGError),
|
||||
CreationError(&'static str)
|
||||
}
|
||||
|
||||
unsafe impl Send for Window {}
|
||||
unsafe impl Sync for Window {}
|
||||
|
||||
|
|
@ -60,8 +67,17 @@ impl Window {
|
|||
_window_target: &EventLoopWindowTarget<T>,
|
||||
attributes: WindowAttributes,
|
||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Self, CreationError> {
|
||||
) -> Result<Self, RootOsError> {
|
||||
let (window, _delegate) = UnownedWindow::new(attributes, pl_attribs)?;
|
||||
Ok(Window { window, _delegate })
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for OsError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
OsError::CGError(e) => f.pad(&format!("CGError {}", e)),
|
||||
OsError::CreationError(e) => f.pad(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use platform_impl::platform::util::IdRef;
|
|||
#[derive(Clone, PartialEq)]
|
||||
pub struct MonitorHandle(CGDirectDisplayID);
|
||||
|
||||
pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors() -> VecDeque<MonitorHandle> {
|
||||
if let Ok(displays) = CGDisplay::active_displays() {
|
||||
let mut monitors = VecDeque::with_capacity(displays.len());
|
||||
for display in displays {
|
||||
|
|
@ -21,7 +21,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor() -> MonitorHandle {
|
||||
pub fn primary_monitor() -> MonitorHandle {
|
||||
MonitorHandle(CGDisplay::main().id)
|
||||
}
|
||||
|
||||
|
|
@ -38,11 +38,11 @@ impl fmt::Debug for MonitorHandle {
|
|||
}
|
||||
|
||||
let monitor_id_proxy = MonitorHandle {
|
||||
name: self.get_name(),
|
||||
native_identifier: self.get_native_identifier(),
|
||||
dimensions: self.get_dimensions(),
|
||||
position: self.get_position(),
|
||||
hidpi_factor: self.get_hidpi_factor(),
|
||||
name: self.name(),
|
||||
native_identifier: self.native_identifier(),
|
||||
dimensions: self.dimensions(),
|
||||
position: self.position(),
|
||||
hidpi_factor: self.hidpi_factor(),
|
||||
};
|
||||
|
||||
monitor_id_proxy.fmt(f)
|
||||
|
|
@ -54,48 +54,48 @@ impl MonitorHandle {
|
|||
MonitorHandle(id)
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
let MonitorHandle(display_id) = *self;
|
||||
let screen_num = CGDisplay::new(display_id).model_number();
|
||||
Some(format!("Monitor #{}", screen_num))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_native_identifier(&self) -> u32 {
|
||||
pub fn native_identifier(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
pub fn dimensions(&self) -> PhysicalSize {
|
||||
let MonitorHandle(display_id) = *self;
|
||||
let display = CGDisplay::new(display_id);
|
||||
let height = display.pixels_high();
|
||||
let width = display.pixels_wide();
|
||||
PhysicalSize::from_logical(
|
||||
(width as f64, height as f64),
|
||||
self.get_hidpi_factor(),
|
||||
self.hidpi_factor(),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
let bounds = unsafe { CGDisplayBounds(self.get_native_identifier()) };
|
||||
pub fn position(&self) -> PhysicalPosition {
|
||||
let bounds = unsafe { CGDisplayBounds(self.native_identifier()) };
|
||||
PhysicalPosition::from_logical(
|
||||
(bounds.origin.x as f64, bounds.origin.y as f64),
|
||||
self.get_hidpi_factor(),
|
||||
self.hidpi_factor(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
let screen = match self.get_nsscreen() {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
let screen = match self.nsscreen() {
|
||||
Some(screen) => screen,
|
||||
None => return 1.0, // default to 1.0 when we can't find the screen
|
||||
};
|
||||
unsafe { NSScreen::backingScaleFactor(screen) as f64 }
|
||||
}
|
||||
|
||||
pub(crate) fn get_nsscreen(&self) -> Option<id> {
|
||||
pub(crate) fn nsscreen(&self) -> Option<id> {
|
||||
unsafe {
|
||||
let native_id = self.get_native_identifier();
|
||||
let native_id = self.native_identifier();
|
||||
let screens = NSScreen::screens(nil);
|
||||
let count: NSUInteger = msg_send![screens, count];
|
||||
let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber"));
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use cocoa::{
|
|||
};
|
||||
use objc::runtime::Sel;
|
||||
|
||||
use window::MouseCursor;
|
||||
use window::CursorIcon;
|
||||
|
||||
pub enum Cursor {
|
||||
Native(&'static str),
|
||||
|
|
@ -12,54 +12,54 @@ pub enum Cursor {
|
|||
WebKit(&'static str),
|
||||
}
|
||||
|
||||
impl From<MouseCursor> for Cursor {
|
||||
fn from(cursor: MouseCursor) -> Self {
|
||||
impl From<CursorIcon> for Cursor {
|
||||
fn from(cursor: CursorIcon) -> Self {
|
||||
match cursor {
|
||||
MouseCursor::Arrow | MouseCursor::Default => Cursor::Native("arrowCursor"),
|
||||
MouseCursor::Hand => Cursor::Native("pointingHandCursor"),
|
||||
MouseCursor::Grabbing | MouseCursor::Grab => Cursor::Native("closedHandCursor"),
|
||||
MouseCursor::Text => Cursor::Native("IBeamCursor"),
|
||||
MouseCursor::VerticalText => Cursor::Native("IBeamCursorForVerticalLayout"),
|
||||
MouseCursor::Copy => Cursor::Native("dragCopyCursor"),
|
||||
MouseCursor::Alias => Cursor::Native("dragLinkCursor"),
|
||||
MouseCursor::NotAllowed | MouseCursor::NoDrop => Cursor::Native("operationNotAllowedCursor"),
|
||||
MouseCursor::ContextMenu => Cursor::Native("contextualMenuCursor"),
|
||||
MouseCursor::Crosshair => Cursor::Native("crosshairCursor"),
|
||||
MouseCursor::EResize => Cursor::Native("resizeRightCursor"),
|
||||
MouseCursor::NResize => Cursor::Native("resizeUpCursor"),
|
||||
MouseCursor::WResize => Cursor::Native("resizeLeftCursor"),
|
||||
MouseCursor::SResize => Cursor::Native("resizeDownCursor"),
|
||||
MouseCursor::EwResize | MouseCursor::ColResize => Cursor::Native("resizeLeftRightCursor"),
|
||||
MouseCursor::NsResize | MouseCursor::RowResize => Cursor::Native("resizeUpDownCursor"),
|
||||
CursorIcon::Arrow | CursorIcon::Default => Cursor::Native("arrowCursor"),
|
||||
CursorIcon::Hand => Cursor::Native("pointingHandCursor"),
|
||||
CursorIcon::Grabbing | CursorIcon::Grab => Cursor::Native("closedHandCursor"),
|
||||
CursorIcon::Text => Cursor::Native("IBeamCursor"),
|
||||
CursorIcon::VerticalText => Cursor::Native("IBeamCursorForVerticalLayout"),
|
||||
CursorIcon::Copy => Cursor::Native("dragCopyCursor"),
|
||||
CursorIcon::Alias => Cursor::Native("dragLinkCursor"),
|
||||
CursorIcon::NotAllowed | CursorIcon::NoDrop => Cursor::Native("operationNotAllowedCursor"),
|
||||
CursorIcon::ContextMenu => Cursor::Native("contextualMenuCursor"),
|
||||
CursorIcon::Crosshair => Cursor::Native("crosshairCursor"),
|
||||
CursorIcon::EResize => Cursor::Native("resizeRightCursor"),
|
||||
CursorIcon::NResize => Cursor::Native("resizeUpCursor"),
|
||||
CursorIcon::WResize => Cursor::Native("resizeLeftCursor"),
|
||||
CursorIcon::SResize => Cursor::Native("resizeDownCursor"),
|
||||
CursorIcon::EwResize | CursorIcon::ColResize => Cursor::Native("resizeLeftRightCursor"),
|
||||
CursorIcon::NsResize | CursorIcon::RowResize => Cursor::Native("resizeUpDownCursor"),
|
||||
|
||||
// Undocumented cursors: https://stackoverflow.com/a/46635398/5435443
|
||||
MouseCursor::Help => Cursor::Undocumented("_helpCursor"),
|
||||
MouseCursor::ZoomIn => Cursor::Undocumented("_zoomInCursor"),
|
||||
MouseCursor::ZoomOut => Cursor::Undocumented("_zoomOutCursor"),
|
||||
MouseCursor::NeResize => Cursor::Undocumented("_windowResizeNorthEastCursor"),
|
||||
MouseCursor::NwResize => Cursor::Undocumented("_windowResizeNorthWestCursor"),
|
||||
MouseCursor::SeResize => Cursor::Undocumented("_windowResizeSouthEastCursor"),
|
||||
MouseCursor::SwResize => Cursor::Undocumented("_windowResizeSouthWestCursor"),
|
||||
MouseCursor::NeswResize => Cursor::Undocumented("_windowResizeNorthEastSouthWestCursor"),
|
||||
MouseCursor::NwseResize => Cursor::Undocumented("_windowResizeNorthWestSouthEastCursor"),
|
||||
CursorIcon::Help => Cursor::Undocumented("_helpCursor"),
|
||||
CursorIcon::ZoomIn => Cursor::Undocumented("_zoomInCursor"),
|
||||
CursorIcon::ZoomOut => Cursor::Undocumented("_zoomOutCursor"),
|
||||
CursorIcon::NeResize => Cursor::Undocumented("_windowResizeNorthEastCursor"),
|
||||
CursorIcon::NwResize => Cursor::Undocumented("_windowResizeNorthWestCursor"),
|
||||
CursorIcon::SeResize => Cursor::Undocumented("_windowResizeSouthEastCursor"),
|
||||
CursorIcon::SwResize => Cursor::Undocumented("_windowResizeSouthWestCursor"),
|
||||
CursorIcon::NeswResize => Cursor::Undocumented("_windowResizeNorthEastSouthWestCursor"),
|
||||
CursorIcon::NwseResize => Cursor::Undocumented("_windowResizeNorthWestSouthEastCursor"),
|
||||
|
||||
// While these are available, the former just loads a white arrow,
|
||||
// and the latter loads an ugly deflated beachball!
|
||||
// MouseCursor::Move => Cursor::Undocumented("_moveCursor"),
|
||||
// MouseCursor::Wait => Cursor::Undocumented("_waitCursor"),
|
||||
// CursorIcon::Move => Cursor::Undocumented("_moveCursor"),
|
||||
// CursorIcon::Wait => Cursor::Undocumented("_waitCursor"),
|
||||
|
||||
// An even more undocumented cursor...
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=522349
|
||||
// This is the wrong semantics for `Wait`, but it's the same as
|
||||
// what's used in Safari and Chrome.
|
||||
MouseCursor::Wait | MouseCursor::Progress => Cursor::Undocumented("busyButClickableCursor"),
|
||||
CursorIcon::Wait | CursorIcon::Progress => Cursor::Undocumented("busyButClickableCursor"),
|
||||
|
||||
// For the rest, we can just snatch the cursors from WebKit...
|
||||
// They fit the style of the native cursors, and will seem
|
||||
// completely standard to macOS users.
|
||||
// https://stackoverflow.com/a/21786835/5435443
|
||||
MouseCursor::Move | MouseCursor::AllScroll => Cursor::WebKit("move"),
|
||||
MouseCursor::Cell => Cursor::WebKit("cell"),
|
||||
CursorIcon::Move | CursorIcon::AllScroll => Cursor::WebKit("move"),
|
||||
CursorIcon::Cell => Cursor::WebKit("cell"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ pub fn new_view(nswindow: id) -> (IdRef, Weak<Mutex<util::Cursor>>) {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn set_ime_spot(nsview: id, input_context: id, x: f64, y: f64) {
|
||||
pub unsafe fn set_ime_position(nsview: id, input_context: id, x: f64, y: f64) {
|
||||
let state_ptr: *mut c_void = *(*nsview).get_mut_ivar("winitState");
|
||||
let state = &mut *(state_ptr as *mut ViewState);
|
||||
let content_rect = NSWindow::contentRectForFrameRect_(
|
||||
|
|
|
|||
|
|
@ -17,13 +17,15 @@ use objc::{runtime::{Class, Object, Sel, BOOL, YES, NO}, declare::ClassDecl};
|
|||
|
||||
use {
|
||||
dpi::{LogicalPosition, LogicalSize}, icon::Icon,
|
||||
error::{ExternalError, NotSupportedError, OsError as RootOsError},
|
||||
monitor::MonitorHandle as RootMonitorHandle,
|
||||
window::{
|
||||
CreationError, MouseCursor, WindowAttributes, WindowId as RootWindowId,
|
||||
CursorIcon, WindowAttributes, WindowId as RootWindowId,
|
||||
},
|
||||
};
|
||||
use platform::macos::{ActivationPolicy, WindowExtMacOS};
|
||||
use platform_impl::platform::{
|
||||
OsError,
|
||||
app_state::AppState, ffi, monitor::{self, MonitorHandle},
|
||||
util::{self, IdRef}, view::{self, new_view},
|
||||
window_delegate::new_delegate,
|
||||
|
|
@ -102,7 +104,7 @@ fn create_window(
|
|||
let pool = NSAutoreleasePool::new(nil);
|
||||
let screen = match attrs.fullscreen {
|
||||
Some(ref monitor_id) => {
|
||||
let monitor_screen = monitor_id.inner.get_nsscreen();
|
||||
let monitor_screen = monitor_id.inner.nsscreen();
|
||||
Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil)))
|
||||
},
|
||||
_ => None,
|
||||
|
|
@ -110,7 +112,7 @@ fn create_window(
|
|||
let frame = match screen {
|
||||
Some(screen) => appkit::NSScreen::frame(screen),
|
||||
None => {
|
||||
let (width, height) = attrs.dimensions
|
||||
let (width, height) = attrs.inner_size
|
||||
.map(|logical| (logical.width, logical.height))
|
||||
.unwrap_or_else(|| (800.0, 600.0));
|
||||
NSRect::new(NSPoint::new(0.0, 0.0), NSSize::new(width, height))
|
||||
|
|
@ -245,7 +247,7 @@ pub struct UnownedWindow {
|
|||
pub shared_state: Arc<Mutex<SharedState>>,
|
||||
decorations: AtomicBool,
|
||||
cursor: Weak<Mutex<util::Cursor>>,
|
||||
cursor_hidden: AtomicBool,
|
||||
cursor_visible: AtomicBool,
|
||||
}
|
||||
|
||||
unsafe impl Send for UnownedWindow {}
|
||||
|
|
@ -255,7 +257,7 @@ impl UnownedWindow {
|
|||
pub fn new(
|
||||
mut win_attribs: WindowAttributes,
|
||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<(Arc<Self>, IdRef), CreationError> {
|
||||
) -> Result<(Arc<Self>, IdRef), RootOsError> {
|
||||
unsafe {
|
||||
if !msg_send![class!(NSThread), isMainThread] {
|
||||
panic!("Windows can only be created on the main thread on macOS");
|
||||
|
|
@ -266,17 +268,17 @@ impl UnownedWindow {
|
|||
|
||||
let nsapp = create_app(pl_attribs.activation_policy).ok_or_else(|| {
|
||||
unsafe { pool.drain() };
|
||||
CreationError::OsError(format!("Couldn't create `NSApplication`"))
|
||||
os_error!(OsError::CreationError("Couldn't create `NSApplication`"))
|
||||
})?;
|
||||
|
||||
let nswindow = create_window(&win_attribs, &pl_attribs).ok_or_else(|| {
|
||||
unsafe { pool.drain() };
|
||||
CreationError::OsError(format!("Couldn't create `NSWindow`"))
|
||||
os_error!(OsError::CreationError("Couldn't create `NSWindow`"))
|
||||
})?;
|
||||
|
||||
let (nsview, cursor) = unsafe { create_view(*nswindow) }.ok_or_else(|| {
|
||||
unsafe { pool.drain() };
|
||||
CreationError::OsError(format!("Couldn't create `NSView`"))
|
||||
os_error!(OsError::CreationError("Couldn't create `NSView`"))
|
||||
})?;
|
||||
|
||||
let input_context = unsafe { util::create_input_context(*nsview) };
|
||||
|
|
@ -289,8 +291,8 @@ impl UnownedWindow {
|
|||
|
||||
nsapp.activateIgnoringOtherApps_(YES);
|
||||
|
||||
win_attribs.min_dimensions.map(|dim| set_min_dimensions(*nswindow, dim));
|
||||
win_attribs.max_dimensions.map(|dim| set_max_dimensions(*nswindow, dim));
|
||||
win_attribs.min_inner_size.map(|dim| set_min_inner_size(*nswindow, dim));
|
||||
win_attribs.max_inner_size.map(|dim| set_max_inner_size(*nswindow, dim));
|
||||
|
||||
use cocoa::foundation::NSArray;
|
||||
// register for drag and drop operations.
|
||||
|
|
@ -317,14 +319,14 @@ impl UnownedWindow {
|
|||
shared_state: Arc::new(Mutex::new(win_attribs.into())),
|
||||
decorations: AtomicBool::new(decorations),
|
||||
cursor,
|
||||
cursor_hidden: Default::default(),
|
||||
cursor_visible: AtomicBool::new(true),
|
||||
});
|
||||
|
||||
let delegate = new_delegate(&window, fullscreen.is_some());
|
||||
|
||||
// Set fullscreen mode after we setup everything
|
||||
if let Some(monitor) = fullscreen {
|
||||
if monitor.inner != window.get_current_monitor().inner {
|
||||
if monitor.inner != window.current_monitor().inner {
|
||||
// To do this with native fullscreen, we probably need to
|
||||
// warp the window... while we could use
|
||||
// `enterFullScreenMode`, they're idiomatically different
|
||||
|
|
@ -381,42 +383,39 @@ impl UnownedWindow {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show(&self) {
|
||||
unsafe { util::make_key_and_order_front_async(*self.nswindow) };
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide(&self) {
|
||||
unsafe { util::order_out_async(*self.nswindow) };
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
match visible {
|
||||
true => unsafe { util::make_key_and_order_front_async(*self.nswindow) },
|
||||
false => unsafe { util::order_out_async(*self.nswindow) },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request_redraw(&self) {
|
||||
AppState::queue_redraw(RootWindowId(self.id()));
|
||||
}
|
||||
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
let frame_rect = unsafe { NSWindow::frame(*self.nswindow) };
|
||||
Some((
|
||||
Ok((
|
||||
frame_rect.origin.x as f64,
|
||||
util::bottom_left_to_top_left(frame_rect),
|
||||
).into())
|
||||
}
|
||||
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
let content_rect = unsafe {
|
||||
NSWindow::contentRectForFrameRect_(
|
||||
*self.nswindow,
|
||||
NSWindow::frame(*self.nswindow),
|
||||
)
|
||||
};
|
||||
Some((
|
||||
Ok((
|
||||
content_rect.origin.x as f64,
|
||||
util::bottom_left_to_top_left(content_rect),
|
||||
).into())
|
||||
}
|
||||
|
||||
pub fn set_position(&self, position: LogicalPosition) {
|
||||
pub fn set_outer_position(&self, position: LogicalPosition) {
|
||||
let dummy = NSRect::new(
|
||||
NSPoint::new(
|
||||
position.x,
|
||||
|
|
@ -432,15 +431,15 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
pub fn inner_size(&self) -> LogicalSize {
|
||||
let view_frame = unsafe { NSView::frame(*self.nsview) };
|
||||
Some((view_frame.size.width as f64, view_frame.size.height as f64).into())
|
||||
(view_frame.size.width as f64, view_frame.size.height as f64).into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
pub fn outer_size(&self) -> LogicalSize {
|
||||
let view_frame = unsafe { NSWindow::frame(*self.nswindow) };
|
||||
Some((view_frame.size.width as f64, view_frame.size.height as f64).into())
|
||||
(view_frame.size.width as f64, view_frame.size.height as f64).into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -450,17 +449,17 @@ impl UnownedWindow {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
unsafe {
|
||||
let dimensions = dimensions.unwrap_or_else(|| (0, 0).into());
|
||||
set_min_dimensions(*self.nswindow, dimensions);
|
||||
set_min_inner_size(*self.nswindow, dimensions);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
|
||||
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
unsafe {
|
||||
let dimensions = dimensions.unwrap_or_else(|| (!0, !0).into());
|
||||
set_max_dimensions(*self.nswindow, dimensions);
|
||||
set_max_inner_size(*self.nswindow, dimensions);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -484,7 +483,7 @@ impl UnownedWindow {
|
|||
} // Otherwise, we don't change the mask until we exit fullscreen.
|
||||
}
|
||||
|
||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
||||
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||
let cursor = util::Cursor::from(cursor);
|
||||
if let Some(cursor_access) = self.cursor.upgrade() {
|
||||
*cursor_access.lock().unwrap() = cursor;
|
||||
|
|
@ -497,44 +496,43 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
||||
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||
// TODO: Do this for real https://stackoverflow.com/a/40922095/5435443
|
||||
CGDisplay::associate_mouse_and_mouse_cursor_position(!grab)
|
||||
.map_err(|status| format!("Failed to grab cursor: `CGError` {:?}", status))
|
||||
.map_err(|status| ExternalError::Os(os_error!(OsError::CGError(status))))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide_cursor(&self, hide: bool) {
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
let cursor_class = class!(NSCursor);
|
||||
// macOS uses a "hide counter" like Windows does, so we avoid incrementing it more than once.
|
||||
// (otherwise, `hide_cursor(false)` would need to be called n times!)
|
||||
if hide != self.cursor_hidden.load(Ordering::Acquire) {
|
||||
if hide {
|
||||
let _: () = unsafe { msg_send![cursor_class, hide] };
|
||||
} else {
|
||||
if visible != self.cursor_visible.load(Ordering::Acquire) {
|
||||
if visible {
|
||||
let _: () = unsafe { msg_send![cursor_class, unhide] };
|
||||
} else {
|
||||
let _: () = unsafe { msg_send![cursor_class, hide] };
|
||||
}
|
||||
self.cursor_hidden.store(hide, Ordering::Release);
|
||||
self.cursor_visible.store(visible, Ordering::Release);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
unsafe { NSWindow::backingScaleFactor(*self.nswindow) as _ }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, cursor_position: LogicalPosition) -> Result<(), String> {
|
||||
let window_position = self.get_inner_position()
|
||||
.ok_or("`get_inner_position` failed".to_owned())?;
|
||||
pub fn set_cursor_position(&self, cursor_position: LogicalPosition) -> Result<(), ExternalError> {
|
||||
let window_position = self.inner_position().unwrap();
|
||||
let point = appkit::CGPoint {
|
||||
x: (cursor_position.x + window_position.x) as CGFloat,
|
||||
y: (cursor_position.y + window_position.y) as CGFloat,
|
||||
};
|
||||
CGDisplay::warp_mouse_cursor_position(point)
|
||||
.map_err(|e| format!("`CGWarpMouseCursorPosition` failed: {:?}", e))?;
|
||||
.map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?;
|
||||
CGDisplay::associate_mouse_and_mouse_cursor_position(true)
|
||||
.map_err(|e| format!("`CGAssociateMouseAndMouseCursorPosition` failed: {:?}", e))?;
|
||||
.map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -637,7 +635,7 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
let shared_state_lock = self.shared_state.lock().unwrap();
|
||||
shared_state_lock.fullscreen.clone()
|
||||
}
|
||||
|
|
@ -736,9 +734,9 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_spot(&self, logical_spot: LogicalPosition) {
|
||||
pub fn set_ime_position(&self, logical_spot: LogicalPosition) {
|
||||
unsafe {
|
||||
view::set_ime_spot(
|
||||
view::set_ime_position(
|
||||
*self.nsview,
|
||||
*self.input_context,
|
||||
logical_spot.x,
|
||||
|
|
@ -748,7 +746,7 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
||||
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||
unsafe {
|
||||
let screen: id = msg_send![*self.nswindow, screen];
|
||||
let desc = NSScreen::deviceDescription(screen);
|
||||
|
|
@ -760,24 +758,24 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::get_available_monitors()
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::available_monitors()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
monitor::get_primary_monitor()
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
monitor::primary_monitor()
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowExtMacOS for UnownedWindow {
|
||||
#[inline]
|
||||
fn get_nswindow(&self) -> *mut c_void {
|
||||
fn nswindow(&self) -> *mut c_void {
|
||||
*self.nswindow as *mut _
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_nsview(&self) -> *mut c_void {
|
||||
fn nsview(&self) -> *mut c_void {
|
||||
*self.nsview as *mut _
|
||||
}
|
||||
|
||||
|
|
@ -792,7 +790,7 @@ impl WindowExtMacOS for UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn get_simple_fullscreen(&self) -> bool {
|
||||
fn simple_fullscreen(&self) -> bool {
|
||||
let shared_state_lock = self.shared_state.lock().unwrap();
|
||||
shared_state_lock.is_simple_fullscreen
|
||||
}
|
||||
|
|
@ -869,7 +867,7 @@ impl Drop for UnownedWindow {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn set_min_dimensions<V: NSWindow + Copy>(window: V, mut min_size: LogicalSize) {
|
||||
unsafe fn set_min_inner_size<V: NSWindow + Copy>(window: V, mut min_size: LogicalSize) {
|
||||
let mut current_rect = NSWindow::frame(window);
|
||||
let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
|
||||
// Convert from client area size to window size
|
||||
|
|
@ -893,7 +891,7 @@ unsafe fn set_min_dimensions<V: NSWindow + Copy>(window: V, mut min_size: Logica
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn set_max_dimensions<V: NSWindow + Copy>(window: V, mut max_size: LogicalSize) {
|
||||
unsafe fn set_max_inner_size<V: NSWindow + Copy>(window: V, mut max_size: LogicalSize) {
|
||||
let mut current_rect = NSWindow::frame(window);
|
||||
let content_rect = NSWindow::contentRectForFrameRect_(window, NSWindow::frame(window));
|
||||
// Convert from client area size to window size
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ impl WindowDelegateState {
|
|||
window: &Arc<UnownedWindow>,
|
||||
initial_fullscreen: bool,
|
||||
) -> Self {
|
||||
let dpi_factor = window.get_hidpi_factor();
|
||||
let dpi_factor = window.hidpi_factor();
|
||||
|
||||
let mut delegate_state = WindowDelegateState {
|
||||
nswindow: window.nswindow.clone(),
|
||||
|
|
@ -408,7 +408,7 @@ extern fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
|||
trace!("Triggered `windowDidEnterFullscreen:`");
|
||||
with_state(this, |state| {
|
||||
state.with_window(|window| {
|
||||
let monitor = window.get_current_monitor();
|
||||
let monitor = window.current_monitor();
|
||||
trace!("Locked shared state in `window_did_enter_fullscreen`");
|
||||
window.shared_state.lock().unwrap().fullscreen = Some(monitor);
|
||||
trace!("Unlocked shared state in `window_will_enter_fullscreen`");
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ pub fn dpi_to_scale_factor(dpi: u32) -> f64 {
|
|||
dpi as f64 / BASE_DPI as f64
|
||||
}
|
||||
|
||||
pub unsafe fn get_hwnd_dpi(hwnd: HWND) -> u32 {
|
||||
pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 {
|
||||
let hdc = winuser::GetDC(hwnd);
|
||||
if hdc.is_null() {
|
||||
panic!("[winit] `GetDC` returned null!");
|
||||
|
|
@ -184,6 +184,6 @@ pub unsafe fn get_hwnd_dpi(hwnd: HWND) -> u32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_hwnd_scale_factor(hwnd: HWND) -> f64 {
|
||||
dpi_to_scale_factor(unsafe { get_hwnd_dpi(hwnd) })
|
||||
pub fn hwnd_scale_factor(hwnd: HWND) -> f64 {
|
||||
dpi_to_scale_factor(unsafe { hwnd_dpi(hwnd) })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ use platform_impl::platform::dpi::{
|
|||
become_dpi_aware,
|
||||
dpi_to_scale_factor,
|
||||
enable_non_client_dpi_scaling,
|
||||
get_hwnd_scale_factor,
|
||||
hwnd_scale_factor,
|
||||
};
|
||||
use platform_impl::platform::drop_handler::FileDropHandler;
|
||||
use platform_impl::platform::event::{handle_extended_keys, process_key_params, vkey_to_winit_vkey};
|
||||
|
|
@ -869,7 +869,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||
|
||||
let windowpos = lparam as *const winuser::WINDOWPOS;
|
||||
if (*windowpos).flags & winuser::SWP_NOMOVE != winuser::SWP_NOMOVE {
|
||||
let dpi_factor = get_hwnd_scale_factor(window);
|
||||
let dpi_factor = hwnd_scale_factor(window);
|
||||
let logical_position = LogicalPosition::from_physical(
|
||||
((*windowpos).x, (*windowpos).y),
|
||||
dpi_factor,
|
||||
|
|
@ -889,7 +889,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||
let w = LOWORD(lparam as DWORD) as u32;
|
||||
let h = HIWORD(lparam as DWORD) as u32;
|
||||
|
||||
let dpi_factor = get_hwnd_scale_factor(window);
|
||||
let dpi_factor = hwnd_scale_factor(window);
|
||||
let logical_size = LogicalSize::from_physical((w, h), dpi_factor);
|
||||
let event = Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
|
|
@ -954,7 +954,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||
|
||||
let x = windowsx::GET_X_LPARAM(lparam) as f64;
|
||||
let y = windowsx::GET_Y_LPARAM(lparam) as f64;
|
||||
let dpi_factor = get_hwnd_scale_factor(window);
|
||||
let dpi_factor = hwnd_scale_factor(window);
|
||||
let position = LogicalPosition::from_physical((x, y), dpi_factor);
|
||||
|
||||
subclass_input.send_event(Event::WindowEvent {
|
||||
|
|
@ -1305,7 +1305,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||
inputs.as_mut_ptr(),
|
||||
mem::size_of::<winuser::TOUCHINPUT>() as INT,
|
||||
) > 0 {
|
||||
let dpi_factor = get_hwnd_scale_factor(window);
|
||||
let dpi_factor = hwnd_scale_factor(window);
|
||||
for input in &inputs {
|
||||
let x = (input.x as f64) / 100f64;
|
||||
let y = (input.y as f64) / 100f64;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{self, mem, ptr};
|
||||
use std::{mem, ptr, io};
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::path::Path;
|
||||
|
||||
|
|
@ -8,7 +8,6 @@ use winapi::shared::windef::{HICON, HWND};
|
|||
use winapi::um::winuser;
|
||||
|
||||
use icon::{Pixel, PIXEL_SIZE, Icon};
|
||||
use platform_impl::platform::util;
|
||||
|
||||
impl Pixel {
|
||||
fn to_bgra(&mut self) {
|
||||
|
|
@ -31,7 +30,7 @@ unsafe impl Send for WinIcon {}
|
|||
|
||||
impl WinIcon {
|
||||
#[allow(dead_code)]
|
||||
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, util::WinError> {
|
||||
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> {
|
||||
let wide_path: Vec<u16> = path.as_ref().as_os_str().encode_wide().collect();
|
||||
let handle = unsafe {
|
||||
winuser::LoadImageW(
|
||||
|
|
@ -46,15 +45,15 @@ impl WinIcon {
|
|||
if !handle.is_null() {
|
||||
Ok(WinIcon { handle })
|
||||
} else {
|
||||
Err(util::WinError::from_last_error())
|
||||
Err(io::Error::last_os_error())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_icon(icon: Icon) -> Result<Self, util::WinError> {
|
||||
pub fn from_icon(icon: Icon) -> Result<Self, io::Error> {
|
||||
Self::from_rgba(icon.rgba, icon.width, icon.height)
|
||||
}
|
||||
|
||||
pub fn from_rgba(mut rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, util::WinError> {
|
||||
pub fn from_rgba(mut rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, io::Error> {
|
||||
assert_eq!(rgba.len() % PIXEL_SIZE, 0);
|
||||
let pixel_count = rgba.len() / PIXEL_SIZE;
|
||||
assert_eq!(pixel_count, (width * height) as usize);
|
||||
|
|
@ -80,7 +79,7 @@ impl WinIcon {
|
|||
if !handle.is_null() {
|
||||
Ok(WinIcon { handle })
|
||||
} else {
|
||||
Err(util::WinError::from_last_error())
|
||||
Err(io::Error::last_os_error())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ impl DeviceId {
|
|||
}
|
||||
|
||||
impl DeviceId {
|
||||
pub fn get_persistent_identifier(&self) -> Option<String> {
|
||||
pub fn persistent_identifier(&self) -> Option<String> {
|
||||
if self.0 != 0 {
|
||||
raw_input::get_raw_input_device_name(self.0 as _)
|
||||
} else {
|
||||
|
|
@ -52,6 +52,8 @@ fn wrap_device_id(id: u32) -> RootDeviceId {
|
|||
RootDeviceId(DeviceId(id))
|
||||
}
|
||||
|
||||
pub type OsError = std::io::Error;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct WindowId(HWND);
|
||||
unsafe impl Send for WindowId {}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use winapi::shared::windef::{HDC, HMONITOR, HWND, LPRECT, POINT};
|
|||
use winapi::um::winnt::LONG;
|
||||
use winapi::um::winuser;
|
||||
|
||||
use std::{mem, ptr};
|
||||
use std::{mem, ptr, io};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use super::{EventLoop, util};
|
||||
|
|
@ -50,7 +50,7 @@ unsafe extern "system" fn monitor_enum_proc(
|
|||
TRUE // continue enumeration
|
||||
}
|
||||
|
||||
pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
|
||||
pub fn available_monitors() -> VecDeque<MonitorHandle> {
|
||||
let mut monitors: VecDeque<MonitorHandle> = VecDeque::new();
|
||||
unsafe {
|
||||
winuser::EnumDisplayMonitors(
|
||||
|
|
@ -63,7 +63,7 @@ pub fn get_available_monitors() -> VecDeque<MonitorHandle> {
|
|||
monitors
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor() -> MonitorHandle {
|
||||
pub fn primary_monitor() -> MonitorHandle {
|
||||
const ORIGIN: POINT = POINT { x: 0, y: 0 };
|
||||
let hmonitor = unsafe {
|
||||
winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY)
|
||||
|
|
@ -71,7 +71,7 @@ pub fn get_primary_monitor() -> MonitorHandle {
|
|||
MonitorHandle::from_hmonitor(hmonitor)
|
||||
}
|
||||
|
||||
pub fn get_current_monitor(hwnd: HWND) -> MonitorHandle {
|
||||
pub fn current_monitor(hwnd: HWND) -> MonitorHandle {
|
||||
let hmonitor = unsafe {
|
||||
winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST)
|
||||
};
|
||||
|
|
@ -80,26 +80,26 @@ pub fn get_current_monitor(hwnd: HWND) -> MonitorHandle {
|
|||
|
||||
impl<T> EventLoop<T> {
|
||||
// TODO: Investigate opportunities for caching
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
get_available_monitors()
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
available_monitors()
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
get_primary_monitor()
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
primary_monitor()
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
get_available_monitors()
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
available_monitors()
|
||||
}
|
||||
|
||||
pub fn get_primary_monitor(&self) -> MonitorHandle {
|
||||
get_primary_monitor()
|
||||
pub fn primary_monitor(&self) -> MonitorHandle {
|
||||
primary_monitor()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINFOEXW, util::WinError> {
|
||||
pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINFOEXW, io::Error> {
|
||||
let mut monitor_info: winuser::MONITORINFOEXW = unsafe { mem::uninitialized() };
|
||||
monitor_info.cbSize = mem::size_of::<winuser::MONITORINFOEXW>() as DWORD;
|
||||
let status = unsafe {
|
||||
|
|
@ -109,7 +109,7 @@ pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<winuser::MONITORINF
|
|||
)
|
||||
};
|
||||
if status == 0 {
|
||||
Err(util::WinError::from_last_error())
|
||||
Err(io::Error::last_os_error())
|
||||
} else {
|
||||
Ok(monitor_info)
|
||||
}
|
||||
|
|
@ -142,32 +142,32 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
Some(self.monitor_name.clone())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_native_identifier(&self) -> String {
|
||||
pub fn native_identifier(&self) -> String {
|
||||
self.monitor_name.clone()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hmonitor(&self) -> HMONITOR {
|
||||
pub fn hmonitor(&self) -> HMONITOR {
|
||||
self.hmonitor.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_dimensions(&self) -> PhysicalSize {
|
||||
pub fn dimensions(&self) -> PhysicalSize {
|
||||
self.dimensions.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> PhysicalPosition {
|
||||
pub fn position(&self) -> PhysicalPosition {
|
||||
self.position.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
self.hidpi_factor
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,12 @@
|
|||
use std::{self, mem, ptr, slice, io};
|
||||
use std::{mem, ptr, slice, io};
|
||||
use std::ops::BitAnd;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use window::MouseCursor;
|
||||
use window::CursorIcon;
|
||||
use winapi::ctypes::wchar_t;
|
||||
use winapi::shared::minwindef::{BOOL, DWORD};
|
||||
use winapi::shared::windef::{HWND, POINT, RECT};
|
||||
use winapi::um::errhandlingapi::GetLastError;
|
||||
use winapi::um::winbase::{
|
||||
FormatMessageW,
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
lstrlenW,
|
||||
LocalFree,
|
||||
};
|
||||
use winapi::um::winnt::{
|
||||
LPCWSTR,
|
||||
MAKELANGID,
|
||||
LANG_NEUTRAL,
|
||||
SUBLANG_DEFAULT,
|
||||
};
|
||||
use winapi::um::winbase::lstrlenW;
|
||||
use winapi::um::winuser;
|
||||
|
||||
pub fn has_flag<T>(bitset: T, flag: T) -> bool
|
||||
|
|
@ -117,66 +103,27 @@ pub fn is_focused(window: HWND) -> bool {
|
|||
window == unsafe{ winuser::GetActiveWindow() }
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub struct WinError(Option<String>);
|
||||
|
||||
impl WinError {
|
||||
pub fn from_last_error() -> Self {
|
||||
WinError(unsafe { get_last_error() })
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_last_error() -> Option<String> {
|
||||
let err = GetLastError();
|
||||
if err != 0 {
|
||||
let buf_addr: LPCWSTR = {
|
||||
let mut buf_addr: LPCWSTR = mem::uninitialized();
|
||||
FormatMessageW(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
| FORMAT_MESSAGE_FROM_SYSTEM
|
||||
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
ptr::null(),
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) as DWORD,
|
||||
// This is a pointer to a pointer
|
||||
&mut buf_addr as *mut LPCWSTR as *mut _,
|
||||
0,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
buf_addr
|
||||
};
|
||||
if !buf_addr.is_null() {
|
||||
let buf_len = lstrlenW(buf_addr) as usize;
|
||||
let buf_slice = std::slice::from_raw_parts(buf_addr, buf_len);
|
||||
let string = wchar_to_string(buf_slice);
|
||||
LocalFree(buf_addr as *mut _);
|
||||
return Some(string);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
impl MouseCursor {
|
||||
impl CursorIcon {
|
||||
pub(crate) fn to_windows_cursor(self) -> *const wchar_t {
|
||||
match self {
|
||||
MouseCursor::Arrow | MouseCursor::Default => winuser::IDC_ARROW,
|
||||
MouseCursor::Hand => winuser::IDC_HAND,
|
||||
MouseCursor::Crosshair => winuser::IDC_CROSS,
|
||||
MouseCursor::Text | MouseCursor::VerticalText => winuser::IDC_IBEAM,
|
||||
MouseCursor::NotAllowed | MouseCursor::NoDrop => winuser::IDC_NO,
|
||||
MouseCursor::Grab | MouseCursor::Grabbing |
|
||||
MouseCursor::Move | MouseCursor::AllScroll => winuser::IDC_SIZEALL,
|
||||
MouseCursor::EResize | MouseCursor::WResize |
|
||||
MouseCursor::EwResize | MouseCursor::ColResize => winuser::IDC_SIZEWE,
|
||||
MouseCursor::NResize | MouseCursor::SResize |
|
||||
MouseCursor::NsResize | MouseCursor::RowResize => winuser::IDC_SIZENS,
|
||||
MouseCursor::NeResize | MouseCursor::SwResize |
|
||||
MouseCursor::NeswResize => winuser::IDC_SIZENESW,
|
||||
MouseCursor::NwResize | MouseCursor::SeResize |
|
||||
MouseCursor::NwseResize => winuser::IDC_SIZENWSE,
|
||||
MouseCursor::Wait => winuser::IDC_WAIT,
|
||||
MouseCursor::Progress => winuser::IDC_APPSTARTING,
|
||||
MouseCursor::Help => winuser::IDC_HELP,
|
||||
CursorIcon::Arrow | CursorIcon::Default => winuser::IDC_ARROW,
|
||||
CursorIcon::Hand => winuser::IDC_HAND,
|
||||
CursorIcon::Crosshair => winuser::IDC_CROSS,
|
||||
CursorIcon::Text | CursorIcon::VerticalText => winuser::IDC_IBEAM,
|
||||
CursorIcon::NotAllowed | CursorIcon::NoDrop => winuser::IDC_NO,
|
||||
CursorIcon::Grab | CursorIcon::Grabbing |
|
||||
CursorIcon::Move | CursorIcon::AllScroll => winuser::IDC_SIZEALL,
|
||||
CursorIcon::EResize | CursorIcon::WResize |
|
||||
CursorIcon::EwResize | CursorIcon::ColResize => winuser::IDC_SIZEWE,
|
||||
CursorIcon::NResize | CursorIcon::SResize |
|
||||
CursorIcon::NsResize | CursorIcon::RowResize => winuser::IDC_SIZENS,
|
||||
CursorIcon::NeResize | CursorIcon::SwResize |
|
||||
CursorIcon::NeswResize => winuser::IDC_SIZENESW,
|
||||
CursorIcon::NwResize | CursorIcon::SeResize |
|
||||
CursorIcon::NwseResize => winuser::IDC_SIZENWSE,
|
||||
CursorIcon::Wait => winuser::IDC_WAIT,
|
||||
CursorIcon::Progress => winuser::IDC_APPSTARTING,
|
||||
CursorIcon::Help => winuser::IDC_HELP,
|
||||
_ => winuser::IDC_ARROW, // use arrow for the missing cases.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,13 @@ use winapi::um::wingdi::{CreateRectRgn, DeleteObject};
|
|||
use winapi::um::oleidl::LPDROPTARGET;
|
||||
use winapi::um::winnt::{LONG, LPCWSTR};
|
||||
|
||||
use window::{CreationError, Icon, MouseCursor, WindowAttributes};
|
||||
use window::{Icon, CursorIcon, WindowAttributes};
|
||||
use error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||
use monitor::MonitorHandle as RootMonitorHandle;
|
||||
use platform_impl::platform::{
|
||||
{PlatformSpecificWindowBuilderAttributes, WindowId},
|
||||
dpi::{dpi_to_scale_factor, get_hwnd_dpi},
|
||||
dpi::{dpi_to_scale_factor, hwnd_dpi},
|
||||
drop_handler::FileDropHandler,
|
||||
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID},
|
||||
icon::{self, IconType, WinIcon},
|
||||
|
|
@ -50,7 +51,7 @@ impl Window {
|
|||
event_loop: &EventLoopWindowTarget<T>,
|
||||
w_attr: WindowAttributes,
|
||||
pl_attr: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Window, CreationError> {
|
||||
) -> Result<Window, RootOsError> {
|
||||
// We dispatch an `init` function because of code style.
|
||||
// First person to remove the need for cloning here gets a cookie!
|
||||
//
|
||||
|
|
@ -103,16 +104,10 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show(&self) {
|
||||
unsafe {
|
||||
winuser::ShowWindow(self.window.0, winuser::SW_SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide(&self) {
|
||||
unsafe {
|
||||
winuser::ShowWindow(self.window.0, winuser::SW_HIDE);
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
match visible {
|
||||
true => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_SHOW); },
|
||||
false => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_HIDE); },
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,35 +127,32 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_position_physical(&self) -> Option<(i32, i32)> {
|
||||
pub(crate) fn outer_position_physical(&self) -> (i32, i32) {
|
||||
util::get_window_rect(self.window.0)
|
||||
.map(|rect| (rect.left as i32, rect.top as i32))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_position(&self) -> Option<LogicalPosition> {
|
||||
self.get_position_physical()
|
||||
.map(|physical_position| {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
LogicalPosition::from_physical(physical_position, dpi_factor)
|
||||
})
|
||||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
let physical_position = self.outer_position_physical();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
|
||||
}
|
||||
|
||||
pub(crate) fn get_inner_position_physical(&self) -> Option<(i32, i32)> {
|
||||
pub(crate) fn inner_position_physical(&self) -> (i32, i32) {
|
||||
let mut position: POINT = unsafe { mem::zeroed() };
|
||||
if unsafe { winuser::ClientToScreen(self.window.0, &mut position) } == 0 {
|
||||
return None;
|
||||
panic!("Unexpected ClientToScreen failure: please report this error to https://github.com/rust-windowing/winit")
|
||||
}
|
||||
Some((position.x, position.y))
|
||||
(position.x, position.y)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
|
||||
self.get_inner_position_physical()
|
||||
.map(|physical_position| {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
LogicalPosition::from_physical(physical_position, dpi_factor)
|
||||
})
|
||||
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
let physical_position = self.inner_position_physical();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
|
||||
}
|
||||
|
||||
pub(crate) fn set_position_physical(&self, x: i32, y: i32) {
|
||||
|
|
@ -179,47 +171,44 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_position(&self, logical_position: LogicalPosition) {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
pub fn set_outer_position(&self, logical_position: LogicalPosition) {
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let (x, y) = logical_position.to_physical(dpi_factor).into();
|
||||
self.set_position_physical(x, y);
|
||||
}
|
||||
|
||||
pub(crate) fn get_inner_size_physical(&self) -> Option<(u32, u32)> {
|
||||
pub(crate) fn inner_size_physical(&self) -> (u32, u32) {
|
||||
let mut rect: RECT = unsafe { mem::uninitialized() };
|
||||
if unsafe { winuser::GetClientRect(self.window.0, &mut rect) } == 0 {
|
||||
return None;
|
||||
panic!("Unexpected GetClientRect failure: please report this error to https://github.com/rust-windowing/winit")
|
||||
}
|
||||
Some((
|
||||
(
|
||||
(rect.right - rect.left) as u32,
|
||||
(rect.bottom - rect.top) as u32,
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner_size(&self) -> Option<LogicalSize> {
|
||||
self.get_inner_size_physical()
|
||||
.map(|physical_size| {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
LogicalSize::from_physical(physical_size, dpi_factor)
|
||||
})
|
||||
pub fn inner_size(&self) -> LogicalSize {
|
||||
let physical_size = self.inner_size_physical();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
LogicalSize::from_physical(physical_size, dpi_factor)
|
||||
}
|
||||
|
||||
pub(crate) fn get_outer_size_physical(&self) -> Option<(u32, u32)> {
|
||||
pub(crate) fn outer_size_physical(&self) -> (u32, u32) {
|
||||
util::get_window_rect(self.window.0)
|
||||
.map(|rect| (
|
||||
(rect.right - rect.left) as u32,
|
||||
(rect.bottom - rect.top) as u32,
|
||||
))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_outer_size(&self) -> Option<LogicalSize> {
|
||||
self.get_outer_size_physical()
|
||||
.map(|physical_size| {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
LogicalSize::from_physical(physical_size, dpi_factor)
|
||||
})
|
||||
pub fn outer_size(&self) -> LogicalSize {
|
||||
let physical_size = self.outer_size_physical();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
LogicalSize::from_physical(physical_size, dpi_factor)
|
||||
}
|
||||
|
||||
pub(crate) fn set_inner_size_physical(&self, x: u32, y: u32) {
|
||||
|
|
@ -254,41 +243,41 @@ impl Window {
|
|||
|
||||
#[inline]
|
||||
pub fn set_inner_size(&self, logical_size: LogicalSize) {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let (width, height) = logical_size.to_physical(dpi_factor).into();
|
||||
self.set_inner_size_physical(width, height);
|
||||
}
|
||||
|
||||
pub(crate) fn set_min_dimensions_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||
pub(crate) fn set_min_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||
self.window_state.lock().min_size = dimensions.map(Into::into);
|
||||
// Make windows re-check the window size bounds.
|
||||
self.get_inner_size_physical()
|
||||
.map(|(width, height)| self.set_inner_size_physical(width, height));
|
||||
let (width, height) = self.inner_size_physical();
|
||||
self.set_inner_size_physical(width, height);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_dimensions(&self, logical_size: Option<LogicalSize>) {
|
||||
pub fn set_min_inner_size(&self, logical_size: Option<LogicalSize>) {
|
||||
let physical_size = logical_size.map(|logical_size| {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
logical_size.to_physical(dpi_factor).into()
|
||||
});
|
||||
self.set_min_dimensions_physical(physical_size);
|
||||
self.set_min_inner_size_physical(physical_size);
|
||||
}
|
||||
|
||||
pub fn set_max_dimensions_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||
pub fn set_max_inner_size_physical(&self, dimensions: Option<(u32, u32)>) {
|
||||
self.window_state.lock().max_size = dimensions.map(Into::into);
|
||||
// Make windows re-check the window size bounds.
|
||||
self.get_inner_size_physical()
|
||||
.map(|(width, height)| self.set_inner_size_physical(width, height));
|
||||
let (width, height) = self.inner_size_physical();
|
||||
self.set_inner_size_physical(width, height);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_dimensions(&self, logical_size: Option<LogicalSize>) {
|
||||
pub fn set_max_inner_size(&self, logical_size: Option<LogicalSize>) {
|
||||
let physical_size = logical_size.map(|logical_size| {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
logical_size.to_physical(dpi_factor).into()
|
||||
});
|
||||
self.set_max_dimensions_physical(physical_size);
|
||||
self.set_max_inner_size_physical(physical_size);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -313,7 +302,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: MouseCursor) {
|
||||
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||
self.window_state.lock().mouse.cursor = cursor;
|
||||
self.thread_executor.execute_in_thread(move || unsafe {
|
||||
let cursor = winuser::LoadCursorW(
|
||||
|
|
@ -325,7 +314,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn grab_cursor(&self, grab: bool) -> Result<(), String> {
|
||||
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||
let window = self.window.clone();
|
||||
let window_state = Arc::clone(&self.window_state);
|
||||
let (tx, rx) = channel();
|
||||
|
|
@ -333,21 +322,21 @@ impl Window {
|
|||
self.thread_executor.execute_in_thread(move || {
|
||||
let result = window_state.lock().mouse
|
||||
.set_cursor_flags(window.0, |f| f.set(CursorFlags::GRABBED, grab))
|
||||
.map_err(|e| e.to_string());
|
||||
.map_err(|e| ExternalError::Os(os_error!(e)));
|
||||
let _ = tx.send(result);
|
||||
});
|
||||
rx.recv().unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide_cursor(&self, hide: bool) {
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
let window = self.window.clone();
|
||||
let window_state = Arc::clone(&self.window_state);
|
||||
let (tx, rx) = channel();
|
||||
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
let result = window_state.lock().mouse
|
||||
.set_cursor_flags(window.0, |f| f.set(CursorFlags::HIDDEN, hide))
|
||||
.set_cursor_flags(window.0, |f| f.set(CursorFlags::HIDDEN, !visible))
|
||||
.map_err(|e| e.to_string());
|
||||
let _ = tx.send(result);
|
||||
});
|
||||
|
|
@ -355,26 +344,26 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_hidpi_factor(&self) -> f64 {
|
||||
pub fn hidpi_factor(&self) -> f64 {
|
||||
self.window_state.lock().dpi_factor
|
||||
}
|
||||
|
||||
fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), String> {
|
||||
fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), ExternalError> {
|
||||
let mut point = POINT { x, y };
|
||||
unsafe {
|
||||
if winuser::ClientToScreen(self.window.0, &mut point) == 0 {
|
||||
return Err("`ClientToScreen` failed".to_owned());
|
||||
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||
}
|
||||
if winuser::SetCursorPos(point.x, point.y) == 0 {
|
||||
return Err("`SetCursorPos` failed".to_owned());
|
||||
return Err(ExternalError::Os(os_error!(io::Error::last_os_error())));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), String> {
|
||||
let dpi_factor = self.get_hidpi_factor();
|
||||
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), ExternalError> {
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let (x, y) = logical_position.to_physical(dpi_factor).into();
|
||||
self.set_cursor_position_physical(x, y)
|
||||
}
|
||||
|
|
@ -400,7 +389,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
pub fn fullscreen(&self) -> Option<RootMonitorHandle> {
|
||||
let window_state = self.window_state.lock();
|
||||
window_state.fullscreen.clone()
|
||||
}
|
||||
|
|
@ -413,8 +402,8 @@ impl Window {
|
|||
|
||||
match &monitor {
|
||||
&Some(RootMonitorHandle { ref inner }) => {
|
||||
let (x, y): (i32, i32) = inner.get_position().into();
|
||||
let (width, height): (u32, u32) = inner.get_dimensions().into();
|
||||
let (x, y): (i32, i32) = inner.position().into();
|
||||
let (width, height): (u32, u32) = inner.dimensions().into();
|
||||
|
||||
let mut monitor = monitor.clone();
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
|
|
@ -496,9 +485,9 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_current_monitor(&self) -> RootMonitorHandle {
|
||||
pub fn current_monitor(&self) -> RootMonitorHandle {
|
||||
RootMonitorHandle {
|
||||
inner: monitor::get_current_monitor(self.window.0),
|
||||
inner: monitor::current_monitor(self.window.0),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +518,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_spot(&self, _logical_spot: LogicalPosition) {
|
||||
pub fn set_ime_position(&self, _logical_spot: LogicalPosition) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
|
@ -575,9 +564,9 @@ pub unsafe fn adjust_size(
|
|||
|
||||
unsafe fn init<T: 'static>(
|
||||
mut attributes: WindowAttributes,
|
||||
mut pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
event_loop: &EventLoopWindowTarget<T>,
|
||||
) -> Result<Window, CreationError> {
|
||||
) -> Result<Window, RootOsError> {
|
||||
let title = OsStr::new(&attributes.title)
|
||||
.encode_wide()
|
||||
.chain(Some(0).into_iter())
|
||||
|
|
@ -587,22 +576,18 @@ unsafe fn init<T: 'static>(
|
|||
let icon = attributes.window_icon
|
||||
.take()
|
||||
.map(WinIcon::from_icon);
|
||||
if icon.is_some() {
|
||||
Some(icon.unwrap().map_err(|err| {
|
||||
CreationError::OsError(format!("Failed to create `ICON_SMALL`: {:?}", err))
|
||||
})?)
|
||||
if let Some(icon) = icon {
|
||||
Some(icon.map_err(|e| os_error!(e))?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
let taskbar_icon = {
|
||||
let icon = pl_attribs.taskbar_icon
|
||||
let icon = attributes.window_icon
|
||||
.take()
|
||||
.map(WinIcon::from_icon);
|
||||
if icon.is_some() {
|
||||
Some(icon.unwrap().map_err(|err| {
|
||||
CreationError::OsError(format!("Failed to create `ICON_BIG`: {:?}", err))
|
||||
})?)
|
||||
if let Some(icon) = icon {
|
||||
Some(icon.map_err(|e| os_error!(e))?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -612,17 +597,17 @@ unsafe fn init<T: 'static>(
|
|||
let class_name = register_window_class(&window_icon, &taskbar_icon);
|
||||
|
||||
let guessed_dpi_factor = {
|
||||
let monitors = monitor::get_available_monitors();
|
||||
let monitors = monitor::available_monitors();
|
||||
let dpi_factor = if !monitors.is_empty() {
|
||||
let mut dpi_factor = Some(monitors[0].get_hidpi_factor());
|
||||
let mut dpi_factor = Some(monitors[0].hidpi_factor());
|
||||
for monitor in &monitors {
|
||||
if Some(monitor.get_hidpi_factor()) != dpi_factor {
|
||||
if Some(monitor.hidpi_factor()) != dpi_factor {
|
||||
dpi_factor = None;
|
||||
}
|
||||
}
|
||||
dpi_factor
|
||||
} else {
|
||||
return Err(CreationError::OsError(format!("No monitors were detected.")));
|
||||
return Err(os_error!(io::Error::new(io::ErrorKind::NotFound, "No monitors were detected.")));
|
||||
};
|
||||
dpi_factor.unwrap_or_else(|| {
|
||||
util::get_cursor_pos()
|
||||
|
|
@ -630,7 +615,7 @@ unsafe fn init<T: 'static>(
|
|||
let mut dpi_factor = None;
|
||||
for monitor in &monitors {
|
||||
if monitor.contains_point(&cursor_pos) {
|
||||
dpi_factor = Some(monitor.get_hidpi_factor());
|
||||
dpi_factor = Some(monitor.hidpi_factor());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -641,7 +626,7 @@ unsafe fn init<T: 'static>(
|
|||
};
|
||||
info!("Guessed window DPI factor: {}", guessed_dpi_factor);
|
||||
|
||||
let dimensions = attributes.dimensions.unwrap_or_else(|| (1024, 768).into());
|
||||
let dimensions = attributes.inner_size.unwrap_or_else(|| (1024, 768).into());
|
||||
|
||||
let mut window_flags = WindowFlags::empty();
|
||||
window_flags.set(WindowFlags::DECORATIONS, attributes.decorations);
|
||||
|
|
@ -670,8 +655,7 @@ unsafe fn init<T: 'static>(
|
|||
);
|
||||
|
||||
if handle.is_null() {
|
||||
return Err(CreationError::OsError(format!("CreateWindowEx function failed: {}",
|
||||
format!("{}", io::Error::last_os_error()))));
|
||||
return Err(os_error!(io::Error::last_os_error()));
|
||||
}
|
||||
|
||||
WindowWrapper(handle)
|
||||
|
|
@ -688,7 +672,7 @@ unsafe fn init<T: 'static>(
|
|||
}
|
||||
}
|
||||
|
||||
let dpi = get_hwnd_dpi(real_window.0);
|
||||
let dpi = hwnd_dpi(real_window.0);
|
||||
let dpi_factor = dpi_to_scale_factor(dpi);
|
||||
if dpi_factor != guessed_dpi_factor {
|
||||
let (width, height): (u32, u32) = dimensions.into();
|
||||
|
|
@ -763,7 +747,7 @@ unsafe fn init<T: 'static>(
|
|||
force_window_active(win.window.0);
|
||||
}
|
||||
|
||||
if let Some(dimensions) = attributes.dimensions {
|
||||
if let Some(dimensions) = attributes.inner_size {
|
||||
win.set_inner_size(dimensions);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use monitor::MonitorHandle;
|
||||
use window::{MouseCursor, WindowAttributes};
|
||||
use window::{CursorIcon, WindowAttributes};
|
||||
use std::{io, ptr};
|
||||
use parking_lot::MutexGuard;
|
||||
use dpi::LogicalSize;
|
||||
|
|
@ -36,7 +36,7 @@ pub struct SavedWindow {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct MouseProperties {
|
||||
pub cursor: MouseCursor,
|
||||
pub cursor: CursorIcon,
|
||||
pub buttons_down: u32,
|
||||
cursor_flags: CursorFlags,
|
||||
}
|
||||
|
|
@ -90,13 +90,13 @@ impl WindowState {
|
|||
) -> WindowState {
|
||||
WindowState {
|
||||
mouse: MouseProperties {
|
||||
cursor: MouseCursor::default(),
|
||||
cursor: CursorIcon::default(),
|
||||
buttons_down: 0,
|
||||
cursor_flags: CursorFlags::empty(),
|
||||
},
|
||||
|
||||
min_size: attributes.min_dimensions,
|
||||
max_size: attributes.max_dimensions,
|
||||
min_size: attributes.min_inner_size,
|
||||
max_size: attributes.max_inner_size,
|
||||
|
||||
window_icon,
|
||||
taskbar_icon,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue