From 25860caa84368165ab5ba0542325368f73a508ca Mon Sep 17 00:00:00 2001 From: mnussbaum Date: Thu, 5 Sep 2019 17:28:50 -0700 Subject: [PATCH 1/5] Apply suggested formatting from rustfmt --- src/main.rs | 147 +++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 77 deletions(-) diff --git a/src/main.rs b/src/main.rs index 23fd6cc..a07e689 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ -extern crate glob; extern crate clap; -use clap::{Arg, App}; +extern crate glob; +use clap::{App, Arg}; +use glob::glob; use std::fs; +use std::process::Command; use std::thread; use std::time::Duration; -use std::process::Command; -use glob::glob; fn main() { let mut mode = ""; @@ -13,68 +13,67 @@ fn main() { let mut new_state: &str; let mut path_x: String = "".to_string(); let mut path_y: String = "".to_string(); - let mut matrix: [&str;9]; + let mut matrix: [&str; 9]; let mut x_state: &str; - let sway_pid = String::from_utf8(Command::new("pidof") - .arg("sway") - .output() - .unwrap() - .stdout).unwrap(); + let sway_pid = + String::from_utf8(Command::new("pidof").arg("sway").output().unwrap().stdout).unwrap(); - let x_pid = String::from_utf8(Command::new("pidof") - .arg("x") - .output() - .unwrap() - .stdout).unwrap(); + let x_pid = String::from_utf8(Command::new("pidof").arg("x").output().unwrap().stdout).unwrap(); - if sway_pid.len() >= 1 { + if sway_pid.len() >= 1 { mode = "sway"; } - if x_pid.len() >= 1 { + if x_pid.len() >= 1 { mode = "x"; } let matches = App::new("rot8") - .version("0.1.1") - .arg(Arg::with_name("sleep") - .default_value("500") - .long("sleep") - .value_name("SLEEP") - .help("Set sleep millis") - .takes_value(true)) - .arg(Arg::with_name("display") - .default_value("eDP-1") - .long("display") - .value_name("DISPLAY") - .help("Set Display Device") - .takes_value(true)) - .arg(Arg::with_name("touchscreen") - .default_value("ELAN0732:00 04F3:22E1") - .long("touchscreen") - .value_name("TOUCHSCREEN") - .help("Set Touchscreen Device (X11)") - .takes_value(true)) - .get_matches(); + .version("0.1.1") + .arg( + Arg::with_name("sleep") + .default_value("500") + .long("sleep") + .value_name("SLEEP") + .help("Set sleep millis") + .takes_value(true), + ) + .arg( + Arg::with_name("display") + .default_value("eDP-1") + .long("display") + .value_name("DISPLAY") + .help("Set Display Device") + .takes_value(true), + ) + .arg( + Arg::with_name("touchscreen") + .default_value("ELAN0732:00 04F3:22E1") + .long("touchscreen") + .value_name("TOUCHSCREEN") + .help("Set Touchscreen Device (X11)") + .takes_value(true), + ) + .get_matches(); let sleep = matches.value_of("sleep").unwrap_or("default.conf"); let display = matches.value_of("display").unwrap_or("default.conf"); - let touchscreen = matches.value_of("touchscreen").unwrap_or("default.conf"); + let touchscreen = matches.value_of("touchscreen").unwrap_or("default.conf"); - for entry in glob("/sys/bus/iio/devices/iio:device*/in_accel_*_raw").unwrap(){ - match entry { + for entry in glob("/sys/bus/iio/devices/iio:device*/in_accel_*_raw").unwrap() { + match entry { Ok(path) => { - if path.to_str().unwrap().contains("x_raw"){ + if path.to_str().unwrap().contains("x_raw") { path_x = path.to_str().unwrap().to_owned(); - } else if path.to_str().unwrap().contains("y_raw"){ + } else if path.to_str().unwrap().contains("y_raw") { path_y = path.to_str().unwrap().to_owned(); - } else if path.to_str().unwrap().contains("z_raw"){ + } else if path.to_str().unwrap().contains("z_raw") { continue; } else { println!("{:?}", path); panic!(); } - }, - Err(e) => println!("{:?}",e) + } + Err(e) => println!("{:?}", e), } } @@ -89,20 +88,17 @@ fn main() { new_state = "180"; x_state = "normal"; matrix = ["-1", "0", "1", "0", "-1", "1", "0", "0", "1"]; - } - else { - - new_state = "90"; - x_state = "left"; - matrix = ["0", "-1", "1", "1", "0", "0", "0", "0", "1"]; + } else { + new_state = "90"; + x_state = "left"; + matrix = ["0", "-1", "1", "1", "0", "0", "0", "0", "1"]; } } else if x > 500000 { if y > 500000 { new_state = "180"; x_state = "inverted"; matrix = ["-1", "0", "1", "0", "-1", "1", "0", "0", "1"]; - } - else { + } else { new_state = "270"; x_state = "right"; matrix = ["0", "1", "0", "-1", "0", "1", "0", "0", "1"]; @@ -112,8 +108,7 @@ fn main() { new_state = "180"; x_state = "inverted"; matrix = ["-1", "0", "1", "0", "-1", "1", "0", "0", "1"]; - } - else { + } else { new_state = "normal"; x_state = "normal"; matrix = ["1", "0", "0", "0", "1", "0", "0", "0", "1"]; @@ -121,33 +116,33 @@ fn main() { } if new_state != old_state { - if mode == "sway" { + if mode == "sway" { Command::new("swaymsg") - .arg("output") - .arg(display) - .arg("transform") - .arg(new_state) - .spawn() - .expect("rotate command failed to start"); + .arg("output") + .arg(display) + .arg("transform") + .arg(new_state) + .spawn() + .expect("rotate command failed to start"); old_state = new_state; } - if mode == "x" { + if mode == "x" { Command::new("xrandr") - .arg("-o") - .arg(x_state) - .spawn() - .expect("rotate command failed to start"); + .arg("-o") + .arg(x_state) + .spawn() + .expect("rotate command failed to start"); Command::new("xinput") - .arg("set-prop") - .arg(touchscreen) - .arg("Coordinate") - .arg("Transformation") - .arg("Matrix") - .args(&matrix) - .spawn() - .expect("rotate command failed to start"); + .arg("set-prop") + .arg(touchscreen) + .arg("Coordinate") + .arg("Transformation") + .arg("Matrix") + .args(&matrix) + .spawn() + .expect("rotate command failed to start"); old_state = new_state; } @@ -155,5 +150,3 @@ fn main() { thread::sleep(Duration::from_millis(sleep.parse::().unwrap_or(0))); } } - - From 1e0cc3ed57391948b96a90dae4aea66c6418c42f Mon Sep 17 00:00:00 2001 From: mnussbaum Date: Thu, 5 Sep 2019 17:28:26 -0700 Subject: [PATCH 2/5] Use Xorg process to determine if on X backend I believe the old process name "x" was incorrect. This also moves the list of backends to an enum instead of a string. --- src/main.rs | 89 +++++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/src/main.rs b/src/main.rs index a07e689..ad2a09e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,8 +7,12 @@ use std::process::Command; use std::thread; use std::time::Duration; -fn main() { - let mut mode = ""; +enum BackendMode { + Sway, + Xorg, +} + +fn main() -> Result<(), String> { let mut old_state = "normal"; let mut new_state: &str; let mut path_x: String = "".to_string(); @@ -16,17 +20,21 @@ fn main() { let mut matrix: [&str; 9]; let mut x_state: &str; - let sway_pid = - String::from_utf8(Command::new("pidof").arg("sway").output().unwrap().stdout).unwrap(); - - let x_pid = String::from_utf8(Command::new("pidof").arg("x").output().unwrap().stdout).unwrap(); - - if sway_pid.len() >= 1 { - mode = "sway"; - } - if x_pid.len() >= 1 { - mode = "x"; - } + let mode = if String::from_utf8(Command::new("pidof").arg("sway").output().unwrap().stdout) + .unwrap() + .len() + >= 1 + { + BackendMode::Sway + } else if String::from_utf8(Command::new("pidof").arg("Xorg").output().unwrap().stdout) + .unwrap() + .len() + >= 1 + { + BackendMode::Xorg + } else { + return Err("Unable to find Sway or Xorg procceses".to_owned()); + }; let matches = App::new("rot8") .version("0.1.1") @@ -116,36 +124,35 @@ fn main() { } if new_state != old_state { - if mode == "sway" { - Command::new("swaymsg") - .arg("output") - .arg(display) - .arg("transform") - .arg(new_state) - .spawn() - .expect("rotate command failed to start"); + match mode { + BackendMode::Sway => { + Command::new("swaymsg") + .arg("output") + .arg(display) + .arg("transform") + .arg(new_state) + .spawn() + .expect("rotate command failed to start"); + } + BackendMode::Xorg => { + Command::new("xrandr") + .arg("-o") + .arg(x_state) + .spawn() + .expect("rotate command failed to start"); - old_state = new_state; - } - if mode == "x" { - Command::new("xrandr") - .arg("-o") - .arg(x_state) - .spawn() - .expect("rotate command failed to start"); - - Command::new("xinput") - .arg("set-prop") - .arg(touchscreen) - .arg("Coordinate") - .arg("Transformation") - .arg("Matrix") - .args(&matrix) - .spawn() - .expect("rotate command failed to start"); - - old_state = new_state; + Command::new("xinput") + .arg("set-prop") + .arg(touchscreen) + .arg("Coordinate") + .arg("Transformation") + .arg("Matrix") + .args(&matrix) + .spawn() + .expect("rotate command failed to start"); + } } + old_state = new_state; } thread::sleep(Duration::from_millis(sleep.parse::().unwrap_or(0))); } From 5ca46c50f8d6c675f1e6ef380335a4664ee8a600 Mon Sep 17 00:00:00 2001 From: mnussbaum Date: Thu, 5 Sep 2019 07:08:19 -0700 Subject: [PATCH 3/5] Fix detection of initial rotation state This ensures that if rot8 starts while the window server output is rotated, but the physical device is in a "normal" position, rot8 will detect the initial misalignment and rotate the window server's output to reflect the device's physical state. This scenario occurs if you frequently toggle rot8 on and off as form of rotation lock, and you: 1. Use rot8 to rotate the output sideways 2. Turn rot8 off 3. Move the physical device back into a "normal" position 4. Turn rot8 back on --- Cargo.lock | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 +- src/main.rs | 97 +++++++++++++++++++++++++++++++++------ 3 files changed, 217 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ebdd46c..380c73c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,13 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -42,16 +50,47 @@ name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "itoa" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libc" version = "0.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "memchr" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "numtoa" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "proc-macro2" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.54" @@ -65,12 +104,64 @@ dependencies = [ "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rot8" version = "0.1.1" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ryu" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -78,6 +169,16 @@ name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "syn" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termion" version = "1.5.2" @@ -97,11 +198,24 @@ dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicode-width" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "vec_map" version = "0.8.1" @@ -127,19 +241,34 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "42914d39aad277d9e176efbdad68acb1d5443ab65afe0e0e4f0d49352a950880" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" +"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" +"checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f" +"checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425" +"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/Cargo.toml b/Cargo.toml index ccad21c..ac8a890 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,8 @@ keywords = ["sway", "x11", "display", "rotation"] edition = "2018" [dependencies] -glob = "0.3" clap = "2.33" +glob = "0.3" +regex = "1" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/src/main.rs b/src/main.rs index ad2a09e..3f4c0ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,37 +1,107 @@ extern crate clap; extern crate glob; +extern crate regex; + use clap::{App, Arg}; use glob::glob; +use serde::Deserialize; use std::fs; use std::process::Command; use std::thread; use std::time::Duration; -enum BackendMode { +enum Backend { Sway, Xorg, } +#[derive(Deserialize)] +struct SwayOutput { + name: String, + transform: String, +} + +fn get_window_server_rotation_state(display: &str, backend: &Backend) -> Result { + match backend { + Backend::Sway => { + let raw_rotation_state = String::from_utf8( + Command::new("swaymsg") + .arg("-t") + .arg("get_outputs") + .arg("--raw") + .output() + .expect("Swaymsg get outputs command failed to start") + .stdout, + ) + .unwrap(); + let deserialized: Vec = serde_json::from_str(&raw_rotation_state) + .expect("Unable to deserialize swaymsg JSON output"); + for output in deserialized { + if output.name == display { + return Ok(output.transform); + } + } + + return Err(format!( + "Unable to determine rotation state: display {} not found in 'swaymsg -t get_outputs'", + display + ) + .to_owned()); + } + Backend::Xorg => { + let raw_rotation_state = String::from_utf8( + Command::new("xrandr") + .output() + .expect("Xrandr get outputs command failed to start") + .stdout, + ) + .unwrap(); + let xrandr_output_pattern = regex::Regex::new(format!( + r"^{} connected .+? .+? (normal |inverted |left |right )?\(normal left inverted right x axis y axis\) .+$", + regex::escape(display), + ).as_str()).unwrap(); + for xrandr_output_line in raw_rotation_state.split("\n") { + if !xrandr_output_pattern.is_match(xrandr_output_line) { + continue; + } + + let xrandr_output_captures = + xrandr_output_pattern.captures(xrandr_output_line).unwrap(); + if let Some(transform) = xrandr_output_captures.get(1) { + return Ok(transform.as_str().to_owned()); + } else { + return Ok("normal".to_owned()); + } + } + + return Err(format!( + "Unable to determine rotation state: display {} not found in xrandr output", + display + ) + .to_owned()); + } + } +} + fn main() -> Result<(), String> { - let mut old_state = "normal"; let mut new_state: &str; let mut path_x: String = "".to_string(); let mut path_y: String = "".to_string(); let mut matrix: [&str; 9]; let mut x_state: &str; - let mode = if String::from_utf8(Command::new("pidof").arg("sway").output().unwrap().stdout) + let backend = if String::from_utf8(Command::new("pidof").arg("sway").output().unwrap().stdout) .unwrap() .len() >= 1 { - BackendMode::Sway + Backend::Sway } else if String::from_utf8(Command::new("pidof").arg("Xorg").output().unwrap().stdout) .unwrap() .len() >= 1 { - BackendMode::Xorg + Backend::Xorg } else { return Err("Unable to find Sway or Xorg procceses".to_owned()); }; @@ -66,6 +136,8 @@ fn main() -> Result<(), String> { let sleep = matches.value_of("sleep").unwrap_or("default.conf"); let display = matches.value_of("display").unwrap_or("default.conf"); let touchscreen = matches.value_of("touchscreen").unwrap_or("default.conf"); + let old_state_owned = get_window_server_rotation_state(display, &backend)?; + let mut old_state = old_state_owned.as_str(); for entry in glob("/sys/bus/iio/devices/iio:device*/in_accel_*_raw").unwrap() { match entry { @@ -77,8 +149,7 @@ fn main() -> Result<(), String> { } else if path.to_str().unwrap().contains("z_raw") { continue; } else { - println!("{:?}", path); - panic!(); + panic!("Unknown accelerometer device path {:?}", path); } } Err(e) => println!("{:?}", e), @@ -124,22 +195,22 @@ fn main() -> Result<(), String> { } if new_state != old_state { - match mode { - BackendMode::Sway => { + match backend { + Backend::Sway => { Command::new("swaymsg") .arg("output") .arg(display) .arg("transform") .arg(new_state) .spawn() - .expect("rotate command failed to start"); + .expect("Swaymsg rotate command failed to start"); } - BackendMode::Xorg => { + Backend::Xorg => { Command::new("xrandr") .arg("-o") .arg(x_state) .spawn() - .expect("rotate command failed to start"); + .expect("Xrandr rotate command failed to start"); Command::new("xinput") .arg("set-prop") @@ -149,7 +220,7 @@ fn main() -> Result<(), String> { .arg("Matrix") .args(&matrix) .spawn() - .expect("rotate command failed to start"); + .expect("Xinput rotate command failed to start"); } } old_state = new_state; From 2a548252d1f873999a86229e16df772781f68673 Mon Sep 17 00:00:00 2001 From: mnussbaum Date: Fri, 6 Sep 2019 00:00:27 -0700 Subject: [PATCH 4/5] Fix inverted left/right rotation with Xorg backend The accelerometer to Xorg orientation mapping had left and right inverted, causing the output to flip opposite the desired direction when used sideways. --- src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3f4c0ee..89f5c71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -169,7 +169,7 @@ fn main() -> Result<(), String> { matrix = ["-1", "0", "1", "0", "-1", "1", "0", "0", "1"]; } else { new_state = "90"; - x_state = "left"; + x_state = "right"; matrix = ["0", "-1", "1", "1", "0", "0", "0", "0", "1"]; } } else if x > 500000 { @@ -179,7 +179,7 @@ fn main() -> Result<(), String> { matrix = ["-1", "0", "1", "0", "-1", "1", "0", "0", "1"]; } else { new_state = "270"; - x_state = "right"; + x_state = "left"; matrix = ["0", "1", "0", "-1", "0", "1", "0", "0", "1"]; } } else { From 7832d2be2c7f443ecfc29d965ac4cabe65a8ed9d Mon Sep 17 00:00:00 2001 From: mnussbaum Date: Fri, 6 Sep 2019 00:22:08 -0700 Subject: [PATCH 5/5] Ensure no zombie processes are left behind Dead subprocesses need an explicit wait before they're reaped --- src/main.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 89f5c71..5c69dba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -203,14 +203,18 @@ fn main() -> Result<(), String> { .arg("transform") .arg(new_state) .spawn() - .expect("Swaymsg rotate command failed to start"); + .expect("Swaymsg rotate command failed to start") + .wait() + .expect("Swaymsg rotate command wait failed"); } Backend::Xorg => { Command::new("xrandr") .arg("-o") .arg(x_state) .spawn() - .expect("Xrandr rotate command failed to start"); + .expect("Xrandr rotate command failed to start") + .wait() + .expect("Xrandr rotate command wait failed"); Command::new("xinput") .arg("set-prop") @@ -220,7 +224,9 @@ fn main() -> Result<(), String> { .arg("Matrix") .args(&matrix) .spawn() - .expect("Xinput rotate command failed to start"); + .expect("Xinput rotate command failed to start") + .wait() + .expect("Xinput rotate command wait failed"); } } old_state = new_state;