Disable screen
This commit is contained in:
parent
11c399841f
commit
55f46bcc50
89
src/lib.rs
89
src/lib.rs
|
@ -1,4 +1,5 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
@ -65,8 +66,38 @@ impl Screen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Finds the best common resolution between two screens.
|
||||||
|
fn best_common_resolution(&self, other: &Screen) -> Option<(u32, u32)> {
|
||||||
|
|
||||||
|
let self_res: HashSet<(u32, u32)> = self.resolutions.clone().into_iter().collect();
|
||||||
|
let other_res: HashSet<(u32, u32)> = other.resolutions.clone().into_iter().collect();
|
||||||
|
let intersection = self_res.intersection(&other_res);
|
||||||
|
|
||||||
|
let mut output = None;
|
||||||
|
|
||||||
|
for element in intersection {
|
||||||
|
if let Some(res) = output {
|
||||||
|
if element > &res {
|
||||||
|
output = Some(*element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A struct that contains all the screens and allows to manage them.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MultiScreen {
|
||||||
|
/// All the contained screens.
|
||||||
|
pub(crate) screens: Vec<Screen>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MultiScreen {
|
||||||
|
|
||||||
/// Finds all the screens by spawning and parsing the output of xrandr.
|
/// Finds all the screens by spawning and parsing the output of xrandr.
|
||||||
pub fn find_screens() -> Result<Vec<Screen>, Error> {
|
pub fn detect() -> Result<MultiScreen, Error> {
|
||||||
let mut screens = vec![];
|
let mut screens = vec![];
|
||||||
|
|
||||||
let xrandr = Command::new("xrandr")
|
let xrandr = Command::new("xrandr")
|
||||||
|
@ -108,6 +139,60 @@ impl Screen {
|
||||||
screen.resolutions.sort();
|
screen.resolutions.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(screens)
|
Ok(MultiScreen { screens: screens })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the arguments of xrandr that disable all screens except the primary.
|
||||||
|
pub fn only_primary_args(&self) -> Vec<&str> {
|
||||||
|
|
||||||
|
let mut primary_found = false;
|
||||||
|
let mut args = vec![];
|
||||||
|
|
||||||
|
for screen in &self.screens {
|
||||||
|
|
||||||
|
if ! screen.primary || primary_found {
|
||||||
|
args.push("--output");
|
||||||
|
args.push(&screen.name);
|
||||||
|
args.push("--off");
|
||||||
|
} else {
|
||||||
|
args.push("--output");
|
||||||
|
args.push(&screen.name);
|
||||||
|
args.push("--auto");
|
||||||
|
primary_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
args
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the arguments to duplicate the screens.
|
||||||
|
pub fn duplicate_args(&self) -> Vec<&str> {
|
||||||
|
panic!("Not implemented yet");
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calls the xrandr program to disable all screens except the primary.
|
||||||
|
pub fn only_primary(&self) -> Result<(), Error> {
|
||||||
|
self.run_command(self.only_primary_args())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calls the xrandr program to duplicate the screens.
|
||||||
|
pub fn duplicate(&self) -> Result<(), Error> {
|
||||||
|
self.run_command(self.duplicate_args())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run an xrandr command with its args.
|
||||||
|
pub fn run_command(&self, args: Vec<&str>) -> Result<(), Error> {
|
||||||
|
|
||||||
|
Command::new("xrandr")
|
||||||
|
.args(args)
|
||||||
|
.spawn()?
|
||||||
|
.wait()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
34
src/tv.rs
34
src/tv.rs
|
@ -1,11 +1,39 @@
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate tvrs;
|
extern crate tvrs;
|
||||||
|
|
||||||
use tvrs::Screen;
|
use clap::{Arg, App, SubCommand};
|
||||||
|
use tvrs::MultiScreen;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let screens = Screen::find_screens()
|
|
||||||
|
let matches = App::new("tvrs")
|
||||||
|
.author("Thomas Forgione <thomas@forgione.fr>")
|
||||||
|
.version("0.1.0")
|
||||||
|
.arg(Arg::with_name("disable")
|
||||||
|
.help("Disable all screens except the primary")
|
||||||
|
.conflicts_with_all(&["enable", "duplicate"]))
|
||||||
|
.arg(Arg::with_name("duplicate")
|
||||||
|
.help("Duplicate the primary screen on the second one")
|
||||||
|
.conflicts_with_all(&["enable", "disable"]))
|
||||||
|
.arg(Arg::with_name("enable")
|
||||||
|
.help("Enable the second screen")
|
||||||
|
.requires("enable")
|
||||||
|
.conflicts_with_all(&["disable", "duplicate"]))
|
||||||
|
.arg(Arg::with_name("position")
|
||||||
|
.help("Specify the position of the second screen")
|
||||||
|
.possible_values(&["left", "right", "top", "bottom"]))
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
let screens = MultiScreen::detect()
|
||||||
.expect("An error happened while finding screens");
|
.expect("An error happened while finding screens");
|
||||||
|
|
||||||
println!("{:?}", screens);
|
|
||||||
|
if matches.is_present("disable") {
|
||||||
|
screens.only_primary()
|
||||||
|
.expect("An error happenned while executing the command");
|
||||||
|
} else if matches.is_present("duplicate") {
|
||||||
|
panic!("Not implemented yet");
|
||||||
|
} else if matches.is_present("enable") {
|
||||||
|
panic!("Not implemented yet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue