Skip to content

Commit

Permalink
VideoModeHandle::size() and bit_depth() now return an Option
Browse files Browse the repository at this point in the history
On Android and Orbital `MonitorHandle::name()` now returns `None` instead of a dummy name.
  • Loading branch information
daxpedda committed Jul 24, 2024
1 parent c3ebe8a commit 6d4bbd2
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 184 deletions.
41 changes: 23 additions & 18 deletions examples/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,32 +285,37 @@ 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.get() / 1000, m_hz.get() % 1000)
} else {
String::new()
}
);
if let Some(PhysicalSize { width, height }) = current_mode.size() {
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}");
} else {
info!(" {current_mode:?}");
}
}

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.get() / 1000, m_hz.get() % 1000)
if let Some(PhysicalSize { width, height }) = mode.size() {
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}");
} else {
String::new()
};
info!(" {width}x{height}x{bits}{m_hz}");
info!(" {mode:?}");
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/changelog/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ changelog entry.
- On Web, `CursorGrabMode::Locked` now lets `DeviceEvent::MouseMotion` return raw data, not OS
accelerated, if the browser supports it.
- `VideoModeHandle::refresh_rate_millihertz()` now returns an `Option<NonZeroU32>`.
- `VideoModeHandle::size()` and `bit_depth()` now return an `Option`.

### Removed

Expand All @@ -104,3 +105,4 @@ changelog entry.

- On MacOS, fix building with `feature = "rwh_04"`.
- On Web, pen events are now routed through to `WindowEvent::Cursor*`.
- On Android and Orbital, `MonitorHandle::name()` now returns `None` instead of a dummy name.
26 changes: 4 additions & 22 deletions src/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,15 @@ impl VideoModeHandle {
///
/// [`Window::inner_size()`]: crate::window::Window::inner_size
#[inline]
pub fn size(&self) -> PhysicalSize<u32> {
pub fn size(&self) -> Option<PhysicalSize<u32>> {
self.video_mode.size()
}

/// 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<u16> {
self.video_mode.bit_depth()
}

Expand All @@ -86,19 +81,6 @@ impl VideoModeHandle {
}
}

impl std::fmt::Display for VideoModeHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}x{} {}({} bpp)",
self.size().width,
self.size().height,
self.refresh_rate_millihertz().map(|rate| format!("@ {rate} mHz ")).unwrap_or_default(),
self.bit_depth()
)
}
}

/// Handle to a monitor.
///
/// Allows you to retrieve information about a given monitor and can be used in [`Window`] creation.
Expand Down Expand Up @@ -132,14 +114,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()
}

Expand Down
23 changes: 8 additions & 15 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,24 +992,19 @@ impl MonitorHandle {
}

pub fn name(&self) -> Option<String> {
Some("Android 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 {
self.app.config().density().map(|dpi| dpi as f64 / 160.0).unwrap_or(1.0)
}

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 { monitor: self.clone() })
}

pub fn video_modes(&self) -> impl Iterator<Item = VideoModeHandle> {
Expand All @@ -1020,18 +1015,16 @@ 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
pub fn size(&self) -> Option<PhysicalSize<u32>> {
None
}

pub fn bit_depth(&self) -> u16 {
self.bit_depth
pub fn bit_depth(&self) -> Option<u16> {
None
}

pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
Expand Down
12 changes: 6 additions & 6 deletions src/platform_impl/apple/appkit/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ impl VideoModeHandle {
}
}

pub fn size(&self) -> PhysicalSize<u32> {
self.size
pub fn size(&self) -> Option<PhysicalSize<u32>> {
Some(self.size)
}

pub fn bit_depth(&self) -> u16 {
self.bit_depth
pub fn bit_depth(&self) -> Option<u16> {
Some(self.bit_depth)
}

pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
Expand Down Expand Up @@ -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 {
Expand Down
14 changes: 6 additions & 8 deletions src/platform_impl/apple/uikit/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ 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: Option<NonZeroU32>,
screen_mode: MainThreadBoundDelegateImpls<UIScreenMode>,
pub(crate) monitor: MonitorHandle,
Expand All @@ -61,19 +60,18 @@ 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),
}
}

pub fn size(&self) -> PhysicalSize<u32> {
self.size.into()
pub fn size(&self) -> Option<PhysicalSize<u32>> {
Some(self.size.into())
}

pub fn bit_depth(&self) -> u16 {
self.bit_depth
pub fn bit_depth(&self) -> Option<u16> {
None
}

pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
Expand Down Expand Up @@ -163,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 {
Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,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())
}

Expand Down Expand Up @@ -256,12 +256,12 @@ pub enum VideoModeHandle {

impl VideoModeHandle {
#[inline]
pub fn size(&self) -> PhysicalSize<u32> {
pub fn size(&self) -> Option<PhysicalSize<u32>> {
x11_or_wayland!(match self; VideoModeHandle(m) => m.size())
}

#[inline]
pub fn bit_depth(&self) -> u16 {
pub fn bit_depth(&self) -> Option<u16> {
x11_or_wayland!(match self; VideoModeHandle(m) => m.bit_depth())
}

Expand Down
16 changes: 7 additions & 9 deletions src/platform_impl/linux/wayland/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,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)
Expand All @@ -58,7 +58,7 @@ impl MonitorHandle {
.to_physical(info.scale_factor as f64)
},
)
})
}))
}

#[inline]
Expand Down Expand Up @@ -121,7 +121,6 @@ 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: Option<NonZeroU32>,
pub(crate) monitor: MonitorHandle,
}
Expand All @@ -131,19 +130,18 @@ impl VideoModeHandle {
VideoModeHandle {
size: (mode.dimensions.0 as u32, mode.dimensions.1 as u32).into(),
refresh_rate_millihertz: NonZeroU32::new(mode.refresh_rate as u32),
bit_depth: 32,
monitor: monitor.clone(),
}
}

#[inline]
pub fn size(&self) -> PhysicalSize<u32> {
self.size
pub fn size(&self) -> Option<PhysicalSize<u32>> {
Some(self.size)
}

#[inline]
pub fn bit_depth(&self) -> u16 {
self.bit_depth
pub fn bit_depth(&self) -> Option<u16> {
None
}

#[inline]
Expand Down
14 changes: 7 additions & 7 deletions src/platform_impl/linux/x11/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ pub struct VideoModeHandle {

impl VideoModeHandle {
#[inline]
pub fn size(&self) -> PhysicalSize<u32> {
self.size.into()
pub fn size(&self) -> Option<PhysicalSize<u32>> {
Some(self.size.into())
}

#[inline]
pub fn bit_depth(&self) -> u16 {
self.bit_depth
pub fn bit_depth(&self) -> Option<u16> {
Some(self.bit_depth)
}

#[inline]
Expand All @@ -57,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
Expand Down Expand Up @@ -149,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]
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/linux/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 6d4bbd2

Please sign in to comment.