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

@ -6,7 +6,7 @@ use x11rb::protocol::xproto;
use super::{util, X11Error, XConnection};
use crate::dpi::PhysicalPosition;
use crate::monitor::VideoMode;
use crate::monitor::{MonitorHandleProvider, VideoMode};
// Used for testing. This should always be committed as false.
const DISABLE_MONITOR_LIST_CACHING: bool = false;
@ -23,7 +23,6 @@ pub struct VideoModeHandle {
pub(crate) current: bool,
pub(crate) mode: VideoMode,
pub(crate) native_mode: randr::Mode,
pub(crate) monitor: Option<MonitorHandle>,
}
impl From<VideoModeHandle> for VideoMode {
@ -50,6 +49,36 @@ pub struct MonitorHandle {
pub(crate) video_modes: Vec<VideoModeHandle>,
}
impl MonitorHandleProvider for MonitorHandle {
fn id(&self) -> u128 {
self.native_id() as _
}
fn native_id(&self) -> u64 {
self.id as _
}
fn name(&self) -> Option<std::borrow::Cow<'_, str>> {
Some(self.name.as_str().into())
}
fn position(&self) -> Option<PhysicalPosition<i32>> {
Some(self.position.into())
}
fn scale_factor(&self) -> f64 {
self.scale_factor
}
fn current_video_mode(&self) -> Option<VideoMode> {
self.video_modes.iter().find_map(|mode| mode.current.then(|| mode.clone().into()))
}
fn video_modes(&self) -> Box<dyn Iterator<Item = VideoMode>> {
Box::new(self.video_modes.clone().into_iter().map(|mode| mode.into()))
}
}
impl PartialEq for MonitorHandle {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
@ -121,34 +150,6 @@ impl MonitorHandle {
// Zero is an invalid XID value; no real monitor will have it
self.id == 0
}
pub fn name(&self) -> Option<String> {
Some(self.name.clone())
}
#[inline]
pub fn native_identifier(&self) -> u32 {
self.id as _
}
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
Some(self.position.into())
}
#[inline]
pub fn scale_factor(&self) -> f64 {
self.scale_factor
}
#[inline]
pub fn current_video_mode(&self) -> Option<VideoMode> {
self.video_modes.iter().find(|mode| mode.current).cloned().map(Into::into)
}
#[inline]
pub fn video_modes(&self) -> impl Iterator<Item = VideoMode> {
self.video_modes.clone().into_iter().map(Into::into)
}
}
impl XConnection {