use std::env;
use winit::window::Window;
use crate::cli;
pub struct DisplayInfo {
#[allow(dead_code)]
pub count: i8,
#[allow(dead_code)]
pub resolutions: Vec<String>,
pub total_resolution: String,
pub max_single_resolution: String,
}
pub fn get_info(window: Window) -> DisplayInfo {
let resolutions = get_display_resolutions(&window);
let max_single_resolution = get_max_single_display_resolution(&window);
let total_resolution = get_total_resolution();
DisplayInfo {
count: resolutions.len() as i8,
resolutions,
total_resolution,
max_single_resolution,
}
}
fn is_wayland() -> bool {
env::var("XDG_SESSION_TYPE")
.expect("Can't identify XDG_SESSION_TYPE")
.eq("wayland")
}
fn get_max_single_display_resolution(window: &Window) -> String {
let resolutions = get_display_resolutions(window);
let mut max_resolution = 0;
let mut resolution_string = String::from("");
for resolution in resolutions {
let current_resolution = multiply_resolution(&resolution);
if current_resolution > max_resolution {
max_resolution = current_resolution;
resolution_string = resolution;
}
}
resolution_string
}
fn multiply_resolution(resolution: &str) -> i32 {
let mut multiply = 1;
resolution
.split('x')
.map(|s| s.parse::<i32>().unwrap())
.for_each(|n| multiply *= n);
multiply
}
pub fn get_total_resolution() -> String {
execute_display_command(r#"xprop -notype -len 16 -root _NET_DESKTOP_GEOMETRY | cut -c 25-"#)
.replace(", ", "x")
.trim()
.to_string()
}
pub fn get_display_resolutions(window: &Window) -> Vec<String> {
window
.available_monitors()
.map(|monitor| format!("{}x{}", monitor.size().width, monitor.size().height))
.collect()
}
fn execute_display_command(cmd: &str) -> String {
if is_display_var_set() {
cli::execute_command(cmd)
} else if is_wayland() {
cli::execute_command(format!("WAYLAND_DISPLAY=:wayland-0 {cmd}").as_str())
} else {
cli::execute_command(format!("DISPLAY=:0 {cmd}").as_str())
}
}
fn is_display_var_set() -> bool {
if is_wayland() {
env::var("WAYLAND_DISPLAY").is_ok()
} else {
env::var("DISPLAY").is_ok()
}
}
pub fn get_width(resolution_string: &str) -> String {
resolution_string
.split('x')
.next()
.expect("wrong display resolution format")
.to_string()
}
pub fn get_height(resolution_string: &str) -> String {
resolution_string
.split('x')
.nth(1)
.expect("wrong display resolution format")
.to_string()
}