use crate::model::profile::{Display, DisplayMode}; use anyhow::Result; use displayz::{query_displays, DisplaySet}; use tauri::{AppHandle, Listener}; #[derive(Clone)] pub struct DisplayInfo { pub primary: String, pub set: Option } impl Default for DisplayInfo { fn default() -> Self { DisplayInfo { primary: "default".to_owned(), set: query_displays().ok() } } } impl Display { pub fn wait_for_exit(app: AppHandle, info: DisplayInfo) { log::debug!("display: waiting"); tauri::async_runtime::spawn(async move { app.listen("launch-end", move |_| { if let Err(e) = Self::clean_up(&info) { log::error!("error cleaning up display: {:?}", e); } }); }); } pub fn line_up(&self) -> Result> { use anyhow::anyhow; use displayz::{query_displays, Orientation, Resolution, Frequency}; if self.target == "default" { log::debug!("prepare display: skip"); return Ok(None); } let display_set = query_displays()?; let primary = display_set .displays() .find(|display| display.is_primary()) .ok_or_else(|| anyhow!("Primary display not found"))?; let target = display_set .displays() .find(|display| display.name() == self.target) .ok_or_else(|| anyhow!("Display {} not found", self.target))?; target.set_primary()?; let settings = target.settings() .as_ref() .ok_or_else(|| anyhow!("Unable to query display settings"))?; let res = DisplayInfo { primary: primary.name().to_owned(), set: Some(display_set.clone()) }; if self.rotation == 90 || self.rotation == 270 { let rez = settings.borrow_mut().resolution; settings.borrow_mut().orientation = if self.rotation == 90 { Orientation::PortraitFlipped } else { Orientation::Portrait }; if rez.height < rez.width { settings.borrow_mut().resolution = Resolution::new(rez.height, rez.width); } } let frequency: u32 = self.frequency .try_into() .map_err(|e| anyhow!("Invalid display frequency: {}", e))?; let width: u32 = self.rez.0 .try_into() .map_err(|e| anyhow!("Invalid display width: {}", e))?; let height: u32 = self.rez.1 .try_into() .map_err(|e| anyhow!("Invalid display height: {}", e))?; settings.borrow_mut().frequency = Frequency::new(frequency); if self.borderless_fullscreen && self.mode == DisplayMode::Borderless { settings.borrow_mut().resolution = Resolution::new(width, height); } display_set.apply()?; displayz::refresh()?; log::debug!("prepare display: done"); Ok(Some(res)) } pub fn clean_up(info: &DisplayInfo) -> Result<()> { use anyhow::anyhow; let display_set = info.set.as_ref() .ok_or_else(|| anyhow!("Unable to clean up displays: no display set"))?; let primary = display_set .displays() .find(|display| display.name() == info.primary) .ok_or_else(|| anyhow!("Display {} not found", info.primary))?; primary.set_primary()?; display_set.apply()?; displayz::refresh()?; log::debug!("undo display: done"); Ok(()) } }