monitor: refactor MonitorHandle to store dyn object

This also alters `VideoMode` to be a regular object and not reference
the `MonitorHandle`, since it's a static data.

Given that `VideoMode` set may change during runtime keeping the
reference as a some sort of validity may not be idea and propagating
errors when changing video mode could be more reliable.
This commit is contained in:
Kirill Chibisov 2024-09-21 20:27:12 +03:00
parent be1baf164c
commit f1c5afd84e
43 changed files with 726 additions and 826 deletions

View file

@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::num::NonZeroU32;
use sctk::output::{Mode, OutputData};
@ -5,7 +6,7 @@ use sctk::reexports::client::protocol::wl_output::WlOutput;
use sctk::reexports::client::Proxy;
use crate::dpi::{LogicalPosition, PhysicalPosition};
use crate::monitor::VideoMode;
use crate::monitor::{MonitorHandleProvider as CoreMonitorHandle, VideoMode};
#[derive(Clone, Debug)]
pub struct MonitorHandle {
@ -17,21 +18,24 @@ impl MonitorHandle {
pub(crate) fn new(proxy: WlOutput) -> Self {
Self { proxy }
}
}
#[inline]
pub fn name(&self) -> Option<String> {
let output_data = self.proxy.data::<OutputData>().unwrap();
output_data.with_output_info(|info| info.name.clone())
impl CoreMonitorHandle for MonitorHandle {
fn id(&self) -> u128 {
self.native_id() as _
}
#[inline]
pub fn native_identifier(&self) -> u32 {
fn native_id(&self) -> u64 {
let output_data = self.proxy.data::<OutputData>().unwrap();
output_data.with_output_info(|info| info.id)
output_data.with_output_info(|info| info.id as u64)
}
#[inline]
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
fn name(&self) -> Option<Cow<'_, str>> {
let output_data = self.proxy.data::<OutputData>().unwrap();
output_data.with_output_info(|info| info.name.clone().map(Cow::Owned))
}
fn position(&self) -> Option<PhysicalPosition<i32>> {
let output_data = self.proxy.data::<OutputData>().unwrap();
Some(output_data.with_output_info(|info| {
info.logical_position.map_or_else(
@ -47,56 +51,37 @@ impl MonitorHandle {
}))
}
#[inline]
pub fn scale_factor(&self) -> i32 {
fn scale_factor(&self) -> f64 {
let output_data = self.proxy.data::<OutputData>().unwrap();
output_data.scale_factor()
output_data.scale_factor() as f64
}
#[inline]
pub fn current_video_mode(&self) -> Option<VideoMode> {
fn current_video_mode(&self) -> Option<crate::monitor::VideoMode> {
let output_data = self.proxy.data::<OutputData>().unwrap();
output_data.with_output_info(|info| {
let mode = info.modes.iter().find(|mode| mode.current).cloned();
mode.map(wayland_mode_to_core_mode)
})
}
#[inline]
pub fn video_modes(&self) -> impl Iterator<Item = VideoMode> {
fn video_modes(&self) -> Box<dyn Iterator<Item = VideoMode>> {
let output_data = self.proxy.data::<OutputData>().unwrap();
let modes = output_data.with_output_info(|info| info.modes.clone());
modes.into_iter().map(wayland_mode_to_core_mode)
Box::new(modes.into_iter().map(wayland_mode_to_core_mode))
}
}
impl PartialEq for MonitorHandle {
fn eq(&self, other: &Self) -> bool {
self.native_identifier() == other.native_identifier()
self.native_id() == other.native_id()
}
}
impl Eq for MonitorHandle {}
impl PartialOrd for MonitorHandle {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for MonitorHandle {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.native_identifier().cmp(&other.native_identifier())
}
}
impl std::hash::Hash for MonitorHandle {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.native_identifier().hash(state);
}
}
/// Convert Wayland's [`Mode`] to winit's [`VideoMode`].
/// Convert the wayland's [`Mode`] to winit's [`VideoMode`].
fn wayland_mode_to_core_mode(mode: Mode) -> VideoMode {
VideoMode {
size: (mode.dimensions.0, mode.dimensions.1).into(),