Various Monitor/VideoModeHandle methods now return an Option
`VideoModeHandle::refresh_rate_millihertz()` and `bit_depth()` now return a `Option<NonZero*>`. `MonitorHandle::position()` now returns an `Option`. On Orbital `MonitorHandle::name()` now returns `None` instead of a dummy name.
This commit is contained in:
parent
0ffcfd8a3a
commit
58142680ce
15 changed files with 259 additions and 195 deletions
|
|
@ -304,31 +304,30 @@ impl Application {
|
|||
|
||||
if let Some(current_mode) = monitor.current_video_mode() {
|
||||
let PhysicalSize { width, height } = current_mode.size();
|
||||
info!(
|
||||
" Current mode: {width}x{height}{}",
|
||||
if let Some(m_hz) = current_mode.refresh_rate_millihertz() {
|
||||
format!(" @ {}.{} Hz", m_hz / 1000, m_hz % 1000)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
);
|
||||
let bits =
|
||||
current_mode.bit_depth().map(|bits| format!("x{bits}")).unwrap_or_default();
|
||||
let m_hz = current_mode
|
||||
.refresh_rate_millihertz()
|
||||
.map(|m_hz| format!(" @ {}.{} Hz", m_hz.get() / 1000, m_hz.get() % 1000))
|
||||
.unwrap_or_default();
|
||||
info!(" {width}x{height}{bits}{m_hz}");
|
||||
}
|
||||
|
||||
let PhysicalPosition { x, y } = monitor.position();
|
||||
info!(" Position: {x},{y}");
|
||||
if let Some(PhysicalPosition { x, y }) = monitor.position() {
|
||||
info!(" Position: {x},{y}");
|
||||
}
|
||||
|
||||
info!(" Scale factor: {}", monitor.scale_factor());
|
||||
|
||||
info!(" Available modes (width x height x bit-depth):");
|
||||
for mode in monitor.video_modes() {
|
||||
let PhysicalSize { width, height } = mode.size();
|
||||
let bits = mode.bit_depth();
|
||||
let m_hz = if let Some(m_hz) = mode.refresh_rate_millihertz() {
|
||||
format!(" @ {}.{} Hz", m_hz / 1000, m_hz % 1000)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
info!(" {width}x{height}x{bits}{m_hz}");
|
||||
let bits = mode.bit_depth().map(|bits| format!("x{bits}")).unwrap_or_default();
|
||||
let m_hz = mode
|
||||
.refresh_rate_millihertz()
|
||||
.map(|m_hz| format!(" @ {}.{} Hz", m_hz.get() / 1000, m_hz.get() % 1000))
|
||||
.unwrap_or_default();
|
||||
info!(" {width}x{height}{bits}{m_hz}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ changelog entry.
|
|||
accelerated, if the browser supports it.
|
||||
- `(Active)EventLoop::create_custom_cursor()` now returns a `Result<CustomCursor, ExternalError>`.
|
||||
- Changed how `ModifiersState` is serialized by Serde.
|
||||
- `VideoModeHandle::refresh_rate_millihertz()` now returns an `Option`.
|
||||
- `VideoModeHandle::refresh_rate_millihertz()` and `bit_depth()` now return a `Option<NonZero*>`.
|
||||
- `MonitorHandle::position()` now returns an `Option`.
|
||||
|
||||
### Removed
|
||||
|
||||
|
|
@ -127,3 +128,4 @@ changelog entry.
|
|||
- On Web, pen events are now routed through to `WindowEvent::Cursor*`.
|
||||
- On macOS, fix panic when releasing not available monitor.
|
||||
- On MacOS, return the system theme in `Window::theme()` if no theme override is set.
|
||||
- On Orbital, `MonitorHandle::name()` now returns `None` instead of a dummy name.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
//! methods, which return an iterator of [`MonitorHandle`]:
|
||||
//! - [`ActiveEventLoop::available_monitors`][crate::event_loop::ActiveEventLoop::available_monitors].
|
||||
//! - [`Window::available_monitors`][crate::window::Window::available_monitors].
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use crate::platform_impl;
|
||||
|
||||
|
|
@ -44,7 +46,10 @@ impl Ord for VideoModeHandle {
|
|||
}
|
||||
|
||||
impl VideoModeHandle {
|
||||
/// Returns the resolution of this video mode.
|
||||
/// Returns the resolution of this video mode. This **must not** be used to create your
|
||||
/// rendering surface. Use [`Window::inner_size()`] instead.
|
||||
///
|
||||
/// [`Window::inner_size()`]: crate::window::Window::inner_size
|
||||
#[inline]
|
||||
pub fn size(&self) -> PhysicalSize<u32> {
|
||||
self.video_mode.size()
|
||||
|
|
@ -53,19 +58,14 @@ impl VideoModeHandle {
|
|||
/// Returns the bit depth of this video mode, as in how many bits you have
|
||||
/// available per color. This is generally 24 bits or 32 bits on modern
|
||||
/// systems, depending on whether the alpha channel is counted or not.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Wayland / Orbital:** Always returns 32.
|
||||
/// - **iOS:** Always returns 32.
|
||||
#[inline]
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
self.video_mode.bit_depth()
|
||||
}
|
||||
|
||||
/// Returns the refresh rate of this video mode in mHz.
|
||||
#[inline]
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
self.video_mode.refresh_rate_millihertz()
|
||||
}
|
||||
|
||||
|
|
@ -81,11 +81,11 @@ impl std::fmt::Display for VideoModeHandle {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}x{} {}({} bpp)",
|
||||
"{}x{} {}{}",
|
||||
self.size().width,
|
||||
self.size().height,
|
||||
self.refresh_rate_millihertz().map(|rate| format!("@ {rate} mHz ")).unwrap_or_default(),
|
||||
self.bit_depth()
|
||||
self.bit_depth().map(|bit_depth| format!("({bit_depth} bpp)")).unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -112,11 +112,17 @@ impl std::fmt::Display for VideoModeHandle {
|
|||
/// to check.
|
||||
///
|
||||
/// [`Window`]: crate::window::Window
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct MonitorHandle {
|
||||
pub(crate) inner: platform_impl::MonitorHandle,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for MonitorHandle {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.inner.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl MonitorHandle {
|
||||
/// Returns a human-readable name of the monitor.
|
||||
///
|
||||
|
|
@ -140,14 +146,14 @@ impl MonitorHandle {
|
|||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// **Web:** Always returns [`Default`] without
|
||||
/// **Web:** Always returns [`None`] without
|
||||
#[cfg_attr(
|
||||
any(web_platform, docsrs),
|
||||
doc = "[detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]."
|
||||
)]
|
||||
#[cfg_attr(not(any(web_platform, docsrs)), doc = "detailed monitor permissions.")]
|
||||
#[inline]
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
self.inner.position()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::any::Any;
|
|||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::hash::Hash;
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
|
|
@ -980,8 +981,8 @@ impl MonitorHandle {
|
|||
Some("Android Device".to_owned())
|
||||
}
|
||||
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
(0, 0).into()
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
|
|
@ -989,12 +990,7 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
pub fn current_video_mode(&self) -> Option<VideoModeHandle> {
|
||||
Some(VideoModeHandle {
|
||||
size: screen_size(&self.app),
|
||||
// FIXME: it is guaranteed to support 32 bit color though
|
||||
bit_depth: 32,
|
||||
monitor: self.clone(),
|
||||
})
|
||||
Some(VideoModeHandle { size: screen_size(&self.app), monitor: self.clone() })
|
||||
}
|
||||
|
||||
pub fn video_modes(&self) -> impl Iterator<Item = VideoModeHandle> {
|
||||
|
|
@ -1005,7 +1001,6 @@ impl MonitorHandle {
|
|||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct VideoModeHandle {
|
||||
size: PhysicalSize<u32>,
|
||||
bit_depth: u16,
|
||||
monitor: MonitorHandle,
|
||||
}
|
||||
|
||||
|
|
@ -1014,11 +1009,11 @@ impl VideoModeHandle {
|
|||
self.size
|
||||
}
|
||||
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
self.bit_depth
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
None
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt;
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
|
||||
use core_foundation::array::{CFArrayGetCount, CFArrayGetValueAtIndex};
|
||||
use core_foundation::base::{CFRelease, TCFType};
|
||||
|
|
@ -20,8 +21,8 @@ use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
|||
#[derive(Clone)]
|
||||
pub struct VideoModeHandle {
|
||||
size: PhysicalSize<u32>,
|
||||
bit_depth: u16,
|
||||
refresh_rate_millihertz: Option<u32>,
|
||||
bit_depth: Option<NonZeroU16>,
|
||||
refresh_rate_millihertz: Option<NonZeroU32>,
|
||||
pub(crate) monitor: MonitorHandle,
|
||||
pub(crate) native_mode: NativeDisplayMode,
|
||||
}
|
||||
|
|
@ -83,7 +84,7 @@ impl VideoModeHandle {
|
|||
fn new(
|
||||
monitor: MonitorHandle,
|
||||
mode: NativeDisplayMode,
|
||||
refresh_rate_millihertz: Option<u32>,
|
||||
refresh_rate_millihertz: Option<NonZeroU32>,
|
||||
) -> Self {
|
||||
unsafe {
|
||||
let pixel_encoding =
|
||||
|
|
@ -105,7 +106,7 @@ impl VideoModeHandle {
|
|||
ffi::CGDisplayModeGetPixelHeight(mode.0) as u32,
|
||||
),
|
||||
refresh_rate_millihertz,
|
||||
bit_depth,
|
||||
bit_depth: NonZeroU16::new(bit_depth),
|
||||
monitor: monitor.clone(),
|
||||
native_mode: mode,
|
||||
}
|
||||
|
|
@ -116,11 +117,11 @@ impl VideoModeHandle {
|
|||
self.size
|
||||
}
|
||||
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
self.bit_depth
|
||||
}
|
||||
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
self.refresh_rate_millihertz
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +193,6 @@ impl fmt::Debug for MonitorHandle {
|
|||
.field("native_identifier", &self.native_identifier())
|
||||
.field("position", &self.position())
|
||||
.field("scale_factor", &self.scale_factor())
|
||||
.field("refresh_rate_millihertz", &self.refresh_rate_millihertz())
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
|
@ -216,13 +216,13 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
// This is already in screen coordinates. If we were using `NSScreen`,
|
||||
// then a conversion would've been needed:
|
||||
// flip_window_screen_coordinates(self.ns_screen(mtm)?.frame())
|
||||
let bounds = unsafe { CGDisplayBounds(self.native_identifier()) };
|
||||
let position = LogicalPosition::new(bounds.origin.x, bounds.origin.y);
|
||||
position.to_physical(self.scale_factor())
|
||||
Some(position.to_physical(self.scale_factor()))
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
|
|
@ -234,7 +234,7 @@ impl MonitorHandle {
|
|||
})
|
||||
}
|
||||
|
||||
fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
let current_display_mode =
|
||||
NativeDisplayMode(unsafe { CGDisplayCopyDisplayMode(self.0) } as _);
|
||||
refresh_rate_millihertz(self.0, ¤t_display_mode)
|
||||
|
|
@ -272,7 +272,7 @@ impl MonitorHandle {
|
|||
// CGDisplayModeGetRefreshRate returns 0.0 for any display that
|
||||
// isn't a CRT
|
||||
let refresh_rate_millihertz = if cg_refresh_rate_hertz > 0 {
|
||||
Some((cg_refresh_rate_hertz * 1000) as u32)
|
||||
NonZeroU32::new((cg_refresh_rate_hertz * 1000) as u32)
|
||||
} else {
|
||||
refresh_rate_millihertz
|
||||
};
|
||||
|
|
@ -341,11 +341,11 @@ pub(crate) fn flip_window_screen_coordinates(frame: NSRect) -> NSPoint {
|
|||
NSPoint::new(frame.origin.x, y)
|
||||
}
|
||||
|
||||
fn refresh_rate_millihertz(id: CGDirectDisplayID, mode: &NativeDisplayMode) -> Option<u32> {
|
||||
fn refresh_rate_millihertz(id: CGDirectDisplayID, mode: &NativeDisplayMode) -> Option<NonZeroU32> {
|
||||
unsafe {
|
||||
let refresh_rate = ffi::CGDisplayModeGetRefreshRate(mode.0);
|
||||
if refresh_rate > 0.0 {
|
||||
return Some((refresh_rate * 1000.0).round() as u32);
|
||||
return NonZeroU32::new((refresh_rate * 1000.0).round() as u32);
|
||||
}
|
||||
|
||||
let mut display_link = std::ptr::null_mut();
|
||||
|
|
@ -360,6 +360,9 @@ fn refresh_rate_millihertz(id: CGDirectDisplayID, mode: &NativeDisplayMode) -> O
|
|||
return None;
|
||||
}
|
||||
|
||||
(time.time_scale as i64).checked_div(time.time_value).map(|v| (v * 1000) as u32)
|
||||
(time.time_scale as i64)
|
||||
.checked_div(time.time_value)
|
||||
.map(|v| (v * 1000) as u32)
|
||||
.and_then(NonZeroU32::new)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(clippy::unnecessary_cast)]
|
||||
|
||||
use std::collections::{BTreeSet, VecDeque};
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::{fmt, hash, ptr};
|
||||
|
||||
use objc2::mutability::IsRetainable;
|
||||
|
|
@ -44,8 +45,7 @@ impl<T: IsRetainable + Message> Eq for MainThreadBoundDelegateImpls<T> {}
|
|||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct VideoModeHandle {
|
||||
pub(crate) size: (u32, u32),
|
||||
pub(crate) bit_depth: u16,
|
||||
pub(crate) refresh_rate_millihertz: u32,
|
||||
pub(crate) refresh_rate_millihertz: Option<NonZeroU32>,
|
||||
screen_mode: MainThreadBoundDelegateImpls<UIScreenMode>,
|
||||
pub(crate) monitor: MonitorHandle,
|
||||
}
|
||||
|
|
@ -60,7 +60,6 @@ impl VideoModeHandle {
|
|||
let size = screen_mode.size();
|
||||
VideoModeHandle {
|
||||
size: (size.width as u32, size.height as u32),
|
||||
bit_depth: 32,
|
||||
refresh_rate_millihertz,
|
||||
screen_mode: MainThreadBoundDelegateImpls(MainThreadBound::new(screen_mode, mtm)),
|
||||
monitor: MonitorHandle::new(uiscreen),
|
||||
|
|
@ -71,12 +70,12 @@ impl VideoModeHandle {
|
|||
self.size.into()
|
||||
}
|
||||
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
self.bit_depth
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
Some(self.refresh_rate_millihertz)
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
self.refresh_rate_millihertz
|
||||
}
|
||||
|
||||
pub fn monitor(&self) -> MonitorHandle {
|
||||
|
|
@ -162,9 +161,9 @@ impl MonitorHandle {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
let bounds = self.ui_screen.get_on_main(|ui_screen| ui_screen.nativeBounds());
|
||||
(bounds.origin.x as f64, bounds.origin.y as f64).into()
|
||||
Some((bounds.origin.x as f64, bounds.origin.y as f64).into())
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
|
|
@ -213,7 +212,7 @@ impl MonitorHandle {
|
|||
}
|
||||
}
|
||||
|
||||
fn refresh_rate_millihertz(uiscreen: &UIScreen) -> u32 {
|
||||
fn refresh_rate_millihertz(uiscreen: &UIScreen) -> Option<NonZeroU32> {
|
||||
let refresh_rate_millihertz: NSInteger = {
|
||||
let os_capabilities = app_state::os_capabilities();
|
||||
if os_capabilities.maximum_frames_per_second {
|
||||
|
|
@ -234,7 +233,7 @@ fn refresh_rate_millihertz(uiscreen: &UIScreen) -> u32 {
|
|||
}
|
||||
};
|
||||
|
||||
refresh_rate_millihertz as u32 * 1000
|
||||
NonZeroU32::new(refresh_rate_millihertz as u32 * 1000)
|
||||
}
|
||||
|
||||
pub fn uiscreens(mtm: MainThreadMarker) -> VecDeque<MonitorHandle> {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
compile_error!("Please select a feature to build for unix: `x11`, `wayland`");
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
|
@ -242,7 +243,7 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
x11_or_wayland!(match self; MonitorHandle(m) => m.position())
|
||||
}
|
||||
|
||||
|
|
@ -277,12 +278,12 @@ impl VideoModeHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
x11_or_wayland!(match self; VideoModeHandle(m) => m.bit_depth())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
x11_or_wayland!(match self; VideoModeHandle(m) => m.refresh_rate_millihertz())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
|
||||
use sctk::output::{Mode, OutputData};
|
||||
use sctk::reexports::client::protocol::wl_output::WlOutput;
|
||||
use sctk::reexports::client::Proxy;
|
||||
|
|
@ -29,9 +31,9 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
let output_data = self.proxy.data::<OutputData>().unwrap();
|
||||
output_data.with_output_info(|info| {
|
||||
Some(output_data.with_output_info(|info| {
|
||||
info.logical_position.map_or_else(
|
||||
|| {
|
||||
LogicalPosition::<i32>::from(info.location)
|
||||
|
|
@ -42,7 +44,7 @@ impl MonitorHandle {
|
|||
.to_physical(info.scale_factor as f64)
|
||||
},
|
||||
)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -105,8 +107,7 @@ impl std::hash::Hash for MonitorHandle {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct VideoModeHandle {
|
||||
pub(crate) size: PhysicalSize<u32>,
|
||||
pub(crate) bit_depth: u16,
|
||||
pub(crate) refresh_rate_millihertz: u32,
|
||||
pub(crate) refresh_rate_millihertz: Option<NonZeroU32>,
|
||||
pub(crate) monitor: MonitorHandle,
|
||||
}
|
||||
|
||||
|
|
@ -114,8 +115,7 @@ impl VideoModeHandle {
|
|||
fn new(monitor: MonitorHandle, mode: Mode) -> Self {
|
||||
VideoModeHandle {
|
||||
size: (mode.dimensions.0 as u32, mode.dimensions.1 as u32).into(),
|
||||
refresh_rate_millihertz: mode.refresh_rate as u32,
|
||||
bit_depth: 32,
|
||||
refresh_rate_millihertz: NonZeroU32::new(mode.refresh_rate as u32),
|
||||
monitor: monitor.clone(),
|
||||
}
|
||||
}
|
||||
|
|
@ -126,13 +126,13 @@ impl VideoModeHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
self.bit_depth
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
Some(self.refresh_rate_millihertz)
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
self.refresh_rate_millihertz
|
||||
}
|
||||
|
||||
pub fn monitor(&self) -> MonitorHandle {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
|
||||
use x11rb::connection::RequestConnection;
|
||||
use x11rb::protocol::randr::{self, ConnectionExt as _};
|
||||
use x11rb::protocol::xproto;
|
||||
|
|
@ -20,8 +22,8 @@ impl XConnection {
|
|||
pub struct VideoModeHandle {
|
||||
pub(crate) current: bool,
|
||||
pub(crate) size: (u32, u32),
|
||||
pub(crate) bit_depth: u16,
|
||||
pub(crate) refresh_rate_millihertz: Option<u32>,
|
||||
pub(crate) bit_depth: Option<NonZeroU16>,
|
||||
pub(crate) refresh_rate_millihertz: Option<NonZeroU32>,
|
||||
pub(crate) native_mode: randr::Mode,
|
||||
pub(crate) monitor: Option<MonitorHandle>,
|
||||
}
|
||||
|
|
@ -33,12 +35,12 @@ impl VideoModeHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
self.bit_depth
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
self.refresh_rate_millihertz
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +57,7 @@ pub struct MonitorHandle {
|
|||
/// The name of the monitor
|
||||
pub(crate) name: String,
|
||||
/// The position of the monitor in the X screen
|
||||
position: (i32, i32),
|
||||
pub(crate) position: (i32, i32),
|
||||
/// If the monitor is the primary one
|
||||
primary: bool,
|
||||
/// The DPI scale factor
|
||||
|
|
@ -93,10 +95,12 @@ impl std::hash::Hash for MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mode_refresh_rate_millihertz(mode: &randr::ModeInfo) -> Option<u32> {
|
||||
pub fn mode_refresh_rate_millihertz(mode: &randr::ModeInfo) -> Option<NonZeroU32> {
|
||||
if mode.dot_clock > 0 && mode.htotal > 0 && mode.vtotal > 0 {
|
||||
#[allow(clippy::unnecessary_cast)]
|
||||
Some((mode.dot_clock as u64 * 1000 / (mode.htotal as u64 * mode.vtotal as u64)) as u32)
|
||||
NonZeroU32::new(
|
||||
(mode.dot_clock as u64 * 1000 / (mode.htotal as u64 * mode.vtotal as u64)) as u32,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -145,8 +149,8 @@ impl MonitorHandle {
|
|||
self.id as _
|
||||
}
|
||||
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
self.position.into()
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
Some(self.position.into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::num::NonZeroU16;
|
||||
use std::str::FromStr;
|
||||
use std::{env, str};
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ impl XConnection {
|
|||
current: mode.id == current_mode,
|
||||
size: (mode.width.into(), mode.height.into()),
|
||||
refresh_rate_millihertz: monitor::mode_refresh_rate_millihertz(mode),
|
||||
bit_depth: bit_depth as u16,
|
||||
bit_depth: NonZeroU16::new(bit_depth as u16),
|
||||
native_mode: mode.id,
|
||||
// This is populated in `MonitorHandle::video_modes` as the
|
||||
// video mode is returned to the user
|
||||
|
|
|
|||
|
|
@ -822,7 +822,7 @@ impl UnownedWindow {
|
|||
|
||||
let window_position = self.outer_position_physical();
|
||||
self.shared_state_lock().restore_position = Some(window_position);
|
||||
let monitor_origin: (i32, i32) = monitor.position().into();
|
||||
let monitor_origin: (i32, i32) = monitor.position;
|
||||
self.set_position_inner(monitor_origin.0, monitor_origin.1)
|
||||
.expect_then_ignore_error("Failed to set window position");
|
||||
self.set_fullscreen_hint(true).map(Some)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#![cfg(target_os = "redox")]
|
||||
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
|
@ -197,11 +198,11 @@ pub struct MonitorHandle;
|
|||
|
||||
impl MonitorHandle {
|
||||
pub fn name(&self) -> Option<String> {
|
||||
Some("Redox Device".to_owned())
|
||||
None
|
||||
}
|
||||
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
(0, 0).into()
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
|
|
@ -210,11 +211,7 @@ impl MonitorHandle {
|
|||
|
||||
pub fn current_video_mode(&self) -> Option<VideoModeHandle> {
|
||||
// (it is guaranteed to support 32 bit color though)
|
||||
Some(VideoModeHandle {
|
||||
size: PhysicalSize::default(), // TODO
|
||||
bit_depth: 32,
|
||||
monitor: self.clone(),
|
||||
})
|
||||
Some(VideoModeHandle { monitor: self.clone() })
|
||||
}
|
||||
|
||||
pub fn video_modes(&self) -> impl Iterator<Item = VideoModeHandle> {
|
||||
|
|
@ -224,21 +221,20 @@ impl MonitorHandle {
|
|||
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct VideoModeHandle {
|
||||
size: PhysicalSize<u32>,
|
||||
bit_depth: u16,
|
||||
monitor: MonitorHandle,
|
||||
}
|
||||
|
||||
impl VideoModeHandle {
|
||||
pub fn size(&self) -> PhysicalSize<u32> {
|
||||
self.size
|
||||
// TODO
|
||||
PhysicalSize::default()
|
||||
}
|
||||
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
self.bit_depth
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
// TODO
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use std::cell::{OnceCell, Ref, RefCell};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::future::Future;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::{self, Once};
|
||||
use std::mem;
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::pin::Pin;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
|
@ -31,7 +33,7 @@ use crate::platform::web::{
|
|||
MonitorPermissionError, Orientation, OrientationData, OrientationLock, OrientationLockError,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
#[derive(Clone, Eq)]
|
||||
pub struct MonitorHandle {
|
||||
/// [`None`] means [`web_sys::Screen`], which is always the same.
|
||||
id: Option<u64>,
|
||||
|
|
@ -45,30 +47,15 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
self.inner.queue(|inner| match &inner.screen {
|
||||
Screen::Screen(_) => 0.,
|
||||
Screen::Detailed { screen, .. } => screen.device_pixel_ratio(),
|
||||
})
|
||||
self.inner.queue(|inner| inner.scale_factor())
|
||||
}
|
||||
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
self.inner.queue(|inner| {
|
||||
if let Screen::Detailed { screen, .. } = &inner.screen {
|
||||
PhysicalPosition::new(screen.left(), screen.top())
|
||||
} else {
|
||||
PhysicalPosition::default()
|
||||
}
|
||||
})
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
self.inner.queue(|inner| inner.position())
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Option<String> {
|
||||
self.inner.queue(|inner| {
|
||||
if let Screen::Detailed { screen, .. } = &inner.screen {
|
||||
Some(screen.label())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
self.inner.queue(|inner| inner.name())
|
||||
}
|
||||
|
||||
pub fn current_video_mode(&self) -> Option<VideoModeHandle> {
|
||||
|
|
@ -80,36 +67,7 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
pub fn orientation(&self) -> OrientationData {
|
||||
self.inner.queue(|inner| {
|
||||
let orientation = inner.orientation();
|
||||
let angle = orientation.angle().unwrap();
|
||||
|
||||
match orientation.type_().unwrap() {
|
||||
OrientationType::LandscapePrimary => OrientationData {
|
||||
orientation: Orientation::Landscape,
|
||||
flipped: false,
|
||||
natural: angle == 0,
|
||||
},
|
||||
OrientationType::LandscapeSecondary => OrientationData {
|
||||
orientation: Orientation::Landscape,
|
||||
flipped: true,
|
||||
natural: angle == 180,
|
||||
},
|
||||
OrientationType::PortraitPrimary => OrientationData {
|
||||
orientation: Orientation::Portrait,
|
||||
flipped: false,
|
||||
natural: angle == 0,
|
||||
},
|
||||
OrientationType::PortraitSecondary => OrientationData {
|
||||
orientation: Orientation::Portrait,
|
||||
flipped: true,
|
||||
natural: angle == 180,
|
||||
},
|
||||
_ => {
|
||||
unreachable!("found unrecognized orientation: {}", orientation.type_string())
|
||||
},
|
||||
}
|
||||
})
|
||||
self.inner.queue(|inner| inner.orientation())
|
||||
}
|
||||
|
||||
pub fn request_lock(&self, orientation_lock: OrientationLock) -> OrientationLockFuture {
|
||||
|
|
@ -126,7 +84,7 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
let future =
|
||||
JsFuture::from(inner.orientation().lock(orientation_lock.to_js()).unwrap());
|
||||
JsFuture::from(inner.orientation_raw().lock(orientation_lock.to_js()).unwrap());
|
||||
let notifier = Notifier::new();
|
||||
let notified = notifier.notified();
|
||||
|
||||
|
|
@ -151,22 +109,16 @@ impl MonitorHandle {
|
|||
return Err(OrientationLockError::Unsupported);
|
||||
}
|
||||
|
||||
inner.orientation().unlock().map_err(OrientationLockError::from_js)
|
||||
inner.orientation_raw().unlock().map_err(OrientationLockError::from_js)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_internal(&self) -> Option<bool> {
|
||||
self.inner.queue(|inner| {
|
||||
if let Screen::Detailed { screen, .. } = &inner.screen {
|
||||
Some(screen.is_internal())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
self.inner.queue(|inner| inner.is_internal())
|
||||
}
|
||||
|
||||
pub fn is_detailed(&self) -> bool {
|
||||
self.inner.queue(|inner| matches!(inner.screen, Screen::Detailed { .. }))
|
||||
self.inner.queue(|inner| inner.is_detailed())
|
||||
}
|
||||
|
||||
pub(crate) fn detailed(
|
||||
|
|
@ -187,6 +139,31 @@ impl MonitorHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl Debug for MonitorHandle {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let (name, position, scale_factor, orientation, is_internal, is_detailed) =
|
||||
self.inner.queue(|this| {
|
||||
(
|
||||
this.name(),
|
||||
this.position(),
|
||||
this.scale_factor(),
|
||||
this.orientation(),
|
||||
this.is_internal(),
|
||||
this.is_detailed(),
|
||||
)
|
||||
});
|
||||
|
||||
f.debug_struct("MonitorHandle")
|
||||
.field("name", &name)
|
||||
.field("position", &position)
|
||||
.field("scale_factor", &scale_factor)
|
||||
.field("orientation", &orientation)
|
||||
.field("is_internal", &is_internal)
|
||||
.field("is_detailed", &is_detailed)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for MonitorHandle {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.id.hash(state)
|
||||
|
|
@ -268,29 +245,19 @@ impl OrientationLockError {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct VideoModeHandle(pub(super) MonitorHandle);
|
||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
pub struct VideoModeHandle(MonitorHandle);
|
||||
|
||||
impl VideoModeHandle {
|
||||
pub fn size(&self) -> PhysicalSize<u32> {
|
||||
self.0.inner.queue(|inner| {
|
||||
let width = inner.screen.width().unwrap();
|
||||
let height = inner.screen.height().unwrap();
|
||||
|
||||
if let Some(Engine::Chromium) = inner.engine {
|
||||
PhysicalSize::new(width, height).cast()
|
||||
} else {
|
||||
LogicalSize::new(width, height)
|
||||
.to_physical(super::web_sys::scale_factor(&inner.window))
|
||||
}
|
||||
})
|
||||
self.0.inner.queue(|inner| inner.size())
|
||||
}
|
||||
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
self.0.inner.queue(|inner| inner.screen.color_depth().unwrap()).try_into().unwrap()
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
self.0.inner.queue(|inner| inner.bit_depth())
|
||||
}
|
||||
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
None
|
||||
}
|
||||
|
||||
|
|
@ -299,6 +266,14 @@ impl VideoModeHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl Debug for VideoModeHandle {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let (size, bit_depth) = self.0.inner.queue(|this| (this.size(), this.bit_depth()));
|
||||
|
||||
f.debug_struct("MonitorHandle").field("size", &size).field("bit_depth", &bit_depth).finish()
|
||||
}
|
||||
}
|
||||
|
||||
struct Inner {
|
||||
window: WindowExt,
|
||||
engine: Option<Engine>,
|
||||
|
|
@ -311,12 +286,94 @@ impl Inner {
|
|||
Self { window, engine, screen, orientation: OnceCell::new() }
|
||||
}
|
||||
|
||||
fn orientation(&self) -> &ScreenOrientationExt {
|
||||
fn scale_factor(&self) -> f64 {
|
||||
match &self.screen {
|
||||
Screen::Screen(_) => 0.,
|
||||
Screen::Detailed { screen, .. } => screen.device_pixel_ratio(),
|
||||
}
|
||||
}
|
||||
|
||||
fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
if let Screen::Detailed { screen, .. } = &self.screen {
|
||||
Some(PhysicalPosition::new(screen.left(), screen.top()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> Option<String> {
|
||||
if let Screen::Detailed { screen, .. } = &self.screen {
|
||||
Some(screen.label())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn orientation_raw(&self) -> &ScreenOrientationExt {
|
||||
self.orientation.get_or_init(|| self.screen.orientation().unchecked_into())
|
||||
}
|
||||
|
||||
fn orientation(&self) -> OrientationData {
|
||||
let orientation = self.orientation_raw();
|
||||
|
||||
let angle = orientation.angle().unwrap();
|
||||
|
||||
match orientation.type_().unwrap() {
|
||||
OrientationType::LandscapePrimary => OrientationData {
|
||||
orientation: Orientation::Landscape,
|
||||
flipped: false,
|
||||
natural: angle == 0,
|
||||
},
|
||||
OrientationType::LandscapeSecondary => OrientationData {
|
||||
orientation: Orientation::Landscape,
|
||||
flipped: true,
|
||||
natural: angle == 180,
|
||||
},
|
||||
OrientationType::PortraitPrimary => OrientationData {
|
||||
orientation: Orientation::Portrait,
|
||||
flipped: false,
|
||||
natural: angle == 0,
|
||||
},
|
||||
OrientationType::PortraitSecondary => OrientationData {
|
||||
orientation: Orientation::Portrait,
|
||||
flipped: true,
|
||||
natural: angle == 180,
|
||||
},
|
||||
_ => {
|
||||
unreachable!("found unrecognized orientation: {}", orientation.type_string())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn is_internal(&self) -> Option<bool> {
|
||||
if let Screen::Detailed { screen, .. } = &self.screen {
|
||||
Some(screen.is_internal())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn is_detailed(&self) -> bool {
|
||||
matches!(self.screen, Screen::Detailed { .. })
|
||||
}
|
||||
|
||||
fn size(&self) -> PhysicalSize<u32> {
|
||||
let width = self.screen.width().unwrap();
|
||||
let height = self.screen.height().unwrap();
|
||||
|
||||
if let Some(Engine::Chromium) = self.engine {
|
||||
PhysicalSize::new(width, height).cast()
|
||||
} else {
|
||||
LogicalSize::new(width, height).to_physical(super::web_sys::scale_factor(&self.window))
|
||||
}
|
||||
}
|
||||
|
||||
fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
NonZeroU16::new(self.screen.color_depth().unwrap().try_into().unwrap())
|
||||
}
|
||||
|
||||
fn has_lock_support(&self) -> bool {
|
||||
*HAS_LOCK_SUPPORT.get_or_init(|| !self.orientation().has_lock().is_undefined())
|
||||
*HAS_LOCK_SUPPORT.get_or_init(|| !self.orientation_raw().has_lock().is_undefined())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::collections::{BTreeSet, VecDeque};
|
||||
use std::hash::Hash;
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::{io, mem, ptr};
|
||||
|
||||
use windows_sys::Win32::Foundation::{BOOL, HWND, LPARAM, POINT, RECT};
|
||||
|
|
@ -20,8 +21,8 @@ use crate::platform_impl::platform::window::Window;
|
|||
#[derive(Clone)]
|
||||
pub struct VideoModeHandle {
|
||||
pub(crate) size: (u32, u32),
|
||||
pub(crate) bit_depth: u16,
|
||||
pub(crate) refresh_rate_millihertz: u32,
|
||||
pub(crate) bit_depth: Option<NonZeroU16>,
|
||||
pub(crate) refresh_rate_millihertz: Option<NonZeroU32>,
|
||||
pub(crate) monitor: MonitorHandle,
|
||||
// DEVMODEW is huge so we box it to avoid blowing up the size of winit::window::Fullscreen
|
||||
pub(crate) native_video_mode: Box<DEVMODEW>,
|
||||
|
|
@ -66,8 +67,8 @@ impl VideoModeHandle {
|
|||
|
||||
VideoModeHandle {
|
||||
size: (mode.dmPelsWidth, mode.dmPelsHeight),
|
||||
bit_depth: mode.dmBitsPerPel as u16,
|
||||
refresh_rate_millihertz: mode.dmDisplayFrequency * 1000,
|
||||
bit_depth: NonZeroU16::new(mode.dmBitsPerPel as u16),
|
||||
refresh_rate_millihertz: NonZeroU32::new(mode.dmDisplayFrequency * 1000),
|
||||
monitor,
|
||||
native_video_mode: Box::new(mode),
|
||||
}
|
||||
|
|
@ -77,12 +78,12 @@ impl VideoModeHandle {
|
|||
self.size.into()
|
||||
}
|
||||
|
||||
pub fn bit_depth(&self) -> u16 {
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
self.bit_depth
|
||||
}
|
||||
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<u32> {
|
||||
Some(self.refresh_rate_millihertz)
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
self.refresh_rate_millihertz
|
||||
}
|
||||
|
||||
pub fn monitor(&self) -> MonitorHandle {
|
||||
|
|
@ -189,13 +190,13 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn position(&self) -> PhysicalPosition<i32> {
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
get_monitor_info(self.0)
|
||||
.map(|info| {
|
||||
let rc_monitor = info.monitorInfo.rcMonitor;
|
||||
PhysicalPosition { x: rc_monitor.left, y: rc_monitor.top }
|
||||
})
|
||||
.unwrap_or(PhysicalPosition { x: 0, y: 0 })
|
||||
.ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -786,7 +786,7 @@ impl Window {
|
|||
Fullscreen::Borderless(None) => monitor::current_monitor(window),
|
||||
};
|
||||
|
||||
let position: (i32, i32) = monitor.position().into();
|
||||
let position: (i32, i32) = monitor.position().unwrap_or_default().into();
|
||||
let size: (u32, u32) = monitor.size().into();
|
||||
|
||||
unsafe {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue