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:
parent
be1baf164c
commit
f1c5afd84e
43 changed files with 726 additions and 826 deletions
|
|
@ -11,7 +11,7 @@ use objc2_foundation::NSInteger;
|
|||
use objc2_ui_kit::{UIScreen, UIScreenMode};
|
||||
|
||||
use crate::dpi::PhysicalPosition;
|
||||
use crate::monitor::VideoMode;
|
||||
use crate::monitor::{MonitorHandleProvider, VideoMode};
|
||||
|
||||
// Workaround for `MainThreadBound` implementing almost no traits
|
||||
#[derive(Debug)]
|
||||
|
|
@ -76,6 +76,60 @@ pub struct MonitorHandle {
|
|||
ui_screen: MainThreadBound<Retained<UIScreen>>,
|
||||
}
|
||||
|
||||
impl MonitorHandleProvider for MonitorHandle {
|
||||
fn id(&self) -> u128 {
|
||||
self.native_id() as _
|
||||
}
|
||||
|
||||
fn native_id(&self) -> u64 {
|
||||
// SAFETY: Only getting the pointer.
|
||||
let mtm = unsafe { MainThreadMarker::new_unchecked() };
|
||||
Retained::as_ptr(self.ui_screen.get(mtm)) as u64
|
||||
}
|
||||
|
||||
fn name(&self) -> Option<std::borrow::Cow<'_, str>> {
|
||||
run_on_main(|mtm| {
|
||||
#[allow(deprecated)]
|
||||
let main = UIScreen::mainScreen(mtm);
|
||||
if *self.ui_screen(mtm) == main {
|
||||
Some("Primary".into())
|
||||
} else if Some(self.ui_screen(mtm)) == main.mirroredScreen().as_ref() {
|
||||
Some("Mirrored".into())
|
||||
} else {
|
||||
#[allow(deprecated)]
|
||||
UIScreen::screens(mtm)
|
||||
.iter()
|
||||
.position(|rhs| rhs == *self.ui_screen(mtm))
|
||||
.map(|idx| idx.to_string().into())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
let bounds = self.ui_screen.get_on_main(|ui_screen| ui_screen.nativeBounds());
|
||||
Some((bounds.origin.x as f64, bounds.origin.y as f64).into())
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f64 {
|
||||
self.ui_screen.get_on_main(|ui_screen| ui_screen.nativeScale()) as f64
|
||||
}
|
||||
|
||||
fn current_video_mode(&self) -> Option<VideoMode> {
|
||||
Some(run_on_main(|mtm| {
|
||||
VideoModeHandle::new(
|
||||
self.ui_screen(mtm).clone(),
|
||||
self.ui_screen(mtm).currentMode().unwrap(),
|
||||
mtm,
|
||||
)
|
||||
.mode
|
||||
}))
|
||||
}
|
||||
|
||||
fn video_modes(&self) -> Box<dyn Iterator<Item = VideoMode>> {
|
||||
Box::new(self.video_modes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for MonitorHandle {
|
||||
fn clone(&self) -> Self {
|
||||
run_on_main(|mtm| Self {
|
||||
|
|
@ -137,44 +191,6 @@ impl MonitorHandle {
|
|||
Self { ui_screen: MainThreadBound::new(ui_screen, mtm) }
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Option<String> {
|
||||
run_on_main(|mtm| {
|
||||
#[allow(deprecated)]
|
||||
let main = UIScreen::mainScreen(mtm);
|
||||
if *self.ui_screen(mtm) == main {
|
||||
Some("Primary".to_string())
|
||||
} else if Some(self.ui_screen(mtm)) == main.mirroredScreen().as_ref() {
|
||||
Some("Mirrored".to_string())
|
||||
} else {
|
||||
#[allow(deprecated)]
|
||||
UIScreen::screens(mtm)
|
||||
.iter()
|
||||
.position(|rhs| rhs == *self.ui_screen(mtm))
|
||||
.map(|idx| idx.to_string())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
||||
let bounds = self.ui_screen.get_on_main(|ui_screen| ui_screen.nativeBounds());
|
||||
Some((bounds.origin.x as f64, bounds.origin.y as f64).into())
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
self.ui_screen.get_on_main(|ui_screen| ui_screen.nativeScale()) as f64
|
||||
}
|
||||
|
||||
pub fn current_video_mode(&self) -> Option<VideoMode> {
|
||||
Some(run_on_main(|mtm| {
|
||||
VideoModeHandle::new(
|
||||
self.ui_screen(mtm).clone(),
|
||||
self.ui_screen(mtm).currentMode().unwrap(),
|
||||
mtm,
|
||||
)
|
||||
.mode
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn video_modes_handles(&self) -> impl Iterator<Item = VideoModeHandle> {
|
||||
run_on_main(|mtm| {
|
||||
let ui_screen = self.ui_screen(mtm);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue