From de75c09c32935ecb7e3cbc4e75edc67ed3e87ece Mon Sep 17 00:00:00 2001 From: Edwin Svensson Date: Tue, 17 Dec 2019 20:30:46 +0100 Subject: [PATCH 1/2] fix some elementary os issues, added polling option --- CHANGELOG.md | 7 +- Cargo.lock | 196 +++++++++++++++++++++++++++++++++++++- Cargo.toml | 4 +- README.md | 11 ++- cli.yml | 16 ++++ src/actions/elementary.rs | 74 ++++++++++++++ src/actions/mod.rs | 4 + src/actions/rescan.rs | 33 +++++++ src/cerbere.rs | 55 +++++++++++ src/dependencies.rs | 12 ++- src/main.rs | 49 ++++------ src/plank.rs | 16 ++++ src/threads/autoplank.rs | 20 +++- 13 files changed, 456 insertions(+), 41 deletions(-) create mode 100644 src/actions/elementary.rs create mode 100644 src/actions/mod.rs create mode 100644 src/actions/rescan.rs create mode 100644 src/cerbere.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index c358056..3da16c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -# 0.1.2 +# 0.1.3 +* Ability to configure cerbere. +* Kill existing plank process on startup +* Set polling rate with `-p` + +## 0.1.2 * Improved compatibility with docks and disabled monitors. ## 0.1.1 diff --git a/Cargo.lock b/Cargo.lock index 3d04b15..2cb8f84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,12 +32,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "autoplank" -version = "0.1.2" +version = "0.1.3" dependencies = [ "bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.16.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.102 (registry+https://github.com/rust-lang/crates.io-index)", + "sysinfo 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -60,6 +62,16 @@ name = "byteorder" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cc" +version = "1.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "clap" version = "2.33.0" @@ -75,6 +87,64 @@ dependencies = [ "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-deque" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "doc-comment" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hermit-abi" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -90,6 +160,43 @@ name = "memchr" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "memoffset" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nix" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ntapi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_cpus" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "1.0.6" @@ -106,6 +213,28 @@ dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rayon" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "1.3.1" @@ -122,6 +251,32 @@ name = "regex-syntax" version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "serde" version = "1.0.102" @@ -155,6 +310,19 @@ dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sysinfo" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "ntapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -186,6 +354,11 @@ name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.3.8" @@ -218,23 +391,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ab639324e3ee8774d296864fbc0dbbb256cf1a41c490b94cba90c082915f92" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" +"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" +"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" +"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" +"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" +"checksum nix 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19a8300bf427d432716764070ff70d5b2b7801c958b9049686e6cbd8b06fad92" +"checksum ntapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f26e041cd983acbc087e30fcba770380cfa352d0e392e175b2344ebaf7ea0602" +"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd" +"checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791" "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 rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" "checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" +"checksum sysinfo 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "02067c0c215cbc50176ad0c8718183c5e6bfd3d97c6913c26abeae3bfa8ed2ae" "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.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "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 void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index baa707b..0aad914 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "autoplank" -version = "0.1.2" +version = "0.1.3" authors = ["Edwin Svensson "] edition = "2018" @@ -11,3 +11,5 @@ serde = { version = "1.0", features = ["derive"] } bincode = "1.2" clap = { version = "2", features = ["yaml"] } regex = "1.3" +sysinfo = "0.10" +nix = "0.16" diff --git a/README.md b/README.md index a1477ec..599eab0 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,22 @@ Create a autostart file: `~/.config/autostart/autoplank.desktop` [Desktop Entry] Type=Application Name=Autoplank -Description=Move plank to the monitor your mouse is at. +Description=Automatically move plank across monitors Exec=.local/bin/autoplank ``` +optionally set your own polling rate like this (default: 500): +``` +... +Exec=.local/bin/autoplank -p 200 +``` + When adding/removing a monitor make sure to rescan: ```terminal autoplank -r ``` +#### Elementary OS +Elementary has a service called `cerbere` which handles wingpanel and plank. To make autoplank work properly, you might have to run `autoplank --elementary-fix`. You can revert this change with `autoplank --elementary-restore` + Inspired by [abiosoft/autoplank](https://github.com/abiosoft/autoplank). diff --git a/cli.yml b/cli.yml index fb4f1cc..4e3b8ac 100644 --- a/cli.yml +++ b/cli.yml @@ -9,3 +9,19 @@ args: long: rescan takes_value: false multiple: false + - elementary-fix: + help: "Remove plank from cerbere" + long: elementary-fix + takes_value: false + multiple: false + - elementary-restore: + help: "Add plank from cerbere" + long: elementary-restore + takes_value: false + multiple: false + - polling-rate: + help: "Set the mouse position polling rate in milliseconds" + short: p + long: polling-rate + takes_value: true + multiple: false diff --git a/src/actions/elementary.rs b/src/actions/elementary.rs new file mode 100644 index 0000000..f7e699a --- /dev/null +++ b/src/actions/elementary.rs @@ -0,0 +1,74 @@ +use crate::cerbere::Cerbere; +use crate::dependencies; +use std::process::Command; + +const SCHEMA: &str = "io.elementary.desktop.cerbere"; +const KEY: &str = "monitored-processes"; + +fn check_gsettings() { + + if !dependencies::check("gsettings") { + eprintln!("Missing gsettings (libglib2.0-0)"); + std::process::exit(1); + } + +} + +fn util(fix: bool) { + + check_gsettings(); + + let current = match Command::new("gsettings").args(&["get", SCHEMA, KEY]).output() { + Ok(v) => { + match v.status.success() { + true => String::from_utf8_lossy(&v.stdout).trim().to_string(), + false => { + eprintln!("gsettings did not exix successfully"); + std::process::exit(1); + } + } + }, + Err(e) => { + eprintln!("{:#?}", e); + std::process::exit(1); + } + }; + + let mut cerbere = Cerbere::from(current); + + if fix { + cerbere.remove("'plank'"); + } else { + cerbere.add("'plank'"); + } + + match Command::new("gsettings").args(&["set", SCHEMA, KEY, &cerbere.to_string()]).output() { + Ok(v) => { + if !v.status.success() { + eprintln!("gsettings did not exix successfully"); + std::process::exit(1); + } + + }, + Err(e) => { + eprintln!("{:#?}", e); + std::process::exit(1); + } + } + + println!("Success"); + std::process::exit(0); + +} + +pub fn fix() { + + util(true); + +} + +pub fn restore() { + + util(false); + +} diff --git a/src/actions/mod.rs b/src/actions/mod.rs new file mode 100644 index 0000000..b92fdd0 --- /dev/null +++ b/src/actions/mod.rs @@ -0,0 +1,4 @@ +mod rescan; +pub use rescan::rescan; + +pub mod elementary; diff --git a/src/actions/rescan.rs b/src/actions/rescan.rs new file mode 100644 index 0000000..7898fa6 --- /dev/null +++ b/src/actions/rescan.rs @@ -0,0 +1,33 @@ +use bincode; +use std::{ + net::Shutdown, + os::unix::net::UnixStream, + io::Write, +}; +use crate::threads::{ + SocketAction, + SocketMessage, + SOCKET_ADDR +}; + +pub fn rescan() { + + let mut socket = match UnixStream::connect(SOCKET_ADDR) { + Ok(s) => s, + Err(e) => { + eprintln!("{}", e); + return; + } + }; + let msg = SocketMessage { + action: SocketAction::RefreshMonitors + }; + let data = bincode::serialize::(&msg).unwrap(); + socket.write(&data).unwrap(); + socket.shutdown(Shutdown::Both).unwrap(); + + println!("Rescanning started"); + + std::process::exit(0); + +} diff --git a/src/cerbere.rs b/src/cerbere.rs new file mode 100644 index 0000000..789de5c --- /dev/null +++ b/src/cerbere.rs @@ -0,0 +1,55 @@ +pub struct Cerbere { + vec: Vec +} + +impl Cerbere { + + pub fn from>(val: S) -> Self { + + let input = val.into(); + let res = &input[1..][..input.len() - 2]; + let vec: Vec = res.split(", ").map(|v| String::from(v)).collect(); + + Self { + vec: vec + } + + } + + pub fn add>(&mut self, item: S) -> bool { + + let item_str = item.into(); + + if !self.vec.contains(&item_str) { + self.vec.push(item_str); + return true; + } + + false + + } + + pub fn remove>(&mut self, item: S) -> bool { + + let item_str = item.into(); + + // Nightly + // self.vec.remove_item(&item_str).is_some() + + if self.vec.contains(&item_str) { + let index = self.vec.iter().position(|v| v == &item_str).unwrap(); + self.vec.remove(index); + return true; + } + + false + + } + + pub fn to_string(&self) -> String { + + format!("[{}]", self.vec.join(", ")) + + } + +} diff --git a/src/dependencies.rs b/src/dependencies.rs index 6b2d765..aa075d5 100644 --- a/src/dependencies.rs +++ b/src/dependencies.rs @@ -7,13 +7,12 @@ const DEPENDENCIES: &'static [&'static str] = &[ "dconf" ]; -pub fn check() -> (bool, Vec<&'static str>) { +pub fn startup_check() -> (bool, Vec<&'static str>) { let mut missing = Vec::<&'static str>::new(); for dep in DEPENDENCIES { - let output = Command::new("which").arg(dep).output().unwrap(); - if !output.status.success() { + if !check(dep) { missing.push(dep); } } @@ -21,3 +20,10 @@ pub fn check() -> (bool, Vec<&'static str>) { (missing.len() == 0, missing) } + +pub fn check(dep: &str) -> bool { + + let output = Command::new("which").arg(dep).output().unwrap(); + output.status.success() + +} diff --git a/src/main.rs b/src/main.rs index ed46f75..99bfe62 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,24 +3,17 @@ mod monitor; mod plank; mod dependencies; mod threads; +mod cerbere; +mod actions; use monitor::Monitor; -use threads::{ - SOCKET_ADDR, - SocketAction, - SocketMessage -}; use std::{ - net::Shutdown, - os::unix::net::UnixStream, - io::Write, sync::{ Arc, Mutex } }; use clap::{self, load_yaml, crate_version}; -use bincode; fn main() { @@ -28,31 +21,23 @@ fn main() { let matches = clap::App::from(yml).version(crate_version!()).get_matches(); if matches.is_present("rescan") { - - let mut socket = match UnixStream::connect(SOCKET_ADDR) { - Ok(s) => s, - Err(e) => { - eprintln!("{}", e); - return; - } - }; - let msg = SocketMessage { - action: SocketAction::RefreshMonitors - }; - let data = bincode::serialize::(&msg).unwrap(); - socket.write(&data).unwrap(); - socket.shutdown(Shutdown::Both).unwrap(); - - println!("Rescanning started"); - - std::process::exit(0); - + actions::rescan(); + } else if matches.is_present("elementary-fix") { + actions::elementary::fix() + } else if matches.is_present("elementary-restore") { + actions::elementary::restore(); } + let polling_rate = match matches.value_of("polling-rate") { + Some(v) => v.parse::().expect("Error parsing polling rate"), + None => 500 + }; + println!("Autoplank"); + println!("=> Polling rate set to {}ms", polling_rate); // Make sure all dependencies are installed - let deps = dependencies::check(); + let deps = dependencies::startup_check(); if !deps.0 { eprintln!("Missing dependencies:"); for dep in deps.1 { @@ -67,13 +52,13 @@ fn main() { // Autoplank thread, fetches mouse location every 500ms let autoplank_monitors = Arc::clone(&monitors); - thread_handlers.push(std::thread::spawn(|| { - threads::autoplank(autoplank_monitors); + thread_handlers.push(std::thread::spawn(move || { + threads::autoplank(autoplank_monitors, polling_rate); })); // Socket thread let socket_monitors = Arc::clone(&monitors); - thread_handlers.push(std::thread::spawn(|| { + thread_handlers.push(std::thread::spawn(move || { threads::socket(socket_monitors); })); diff --git a/src/plank.rs b/src/plank.rs index 6fcd98a..a114f47 100644 --- a/src/plank.rs +++ b/src/plank.rs @@ -1,4 +1,5 @@ use std::process::{Command, Child, Stdio}; +use sysinfo::{ProcessExt, SystemExt}; const DCONF_KEY: &str = "/net/launchpad/plank/docks/dock1/monitor"; @@ -56,6 +57,21 @@ impl Plank { .unwrap(); } + pub fn get_pid() -> Option { + + let mut system = sysinfo::System::new(); + system.refresh_all(); + + for (pid, process) in system.get_process_list() { + if process.name() == "plank" { + return Some(*pid) + } + } + + None + + } + } impl Drop for Plank { diff --git a/src/threads/autoplank.rs b/src/threads/autoplank.rs index 621b243..e5043d5 100644 --- a/src/threads/autoplank.rs +++ b/src/threads/autoplank.rs @@ -4,15 +4,31 @@ use super::super::{ mouse_location::MouseLocation, monitor::Monitor }; +use nix::{ + sys::signal, + unistd::Pid +}; + +pub fn autoplank(m: Arc>>, rate: u64) { + + let plank_pid = Plank::get_pid(); + if plank_pid.is_some() { -pub fn autoplank(m: Arc>>) { + match signal::kill(Pid::from_raw(plank_pid.unwrap()), signal::Signal::SIGINT) { + Ok(_) => { + println!("Plank killed"); + }, + Err(e) => eprintln!("Error: {:#?}", e) + } + + } let mut p = Plank::new(); loop { // Sleep before locking the mutex to minimize the lock-time. - std::thread::sleep(std::time::Duration::from_millis(500)); + std::thread::sleep(std::time::Duration::from_millis(rate)); let ml = MouseLocation::get(); let monitors = &*m.lock().unwrap(); From f85b7edb9a68e5119ded11b728d0b62f96aee340 Mon Sep 17 00:00:00 2001 From: Edwin Svensson Date: Tue, 17 Dec 2019 20:34:35 +0100 Subject: [PATCH 2/2] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 599eab0..e27d3bd 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,6 @@ autoplank -r ``` #### Elementary OS -Elementary has a service called `cerbere` which handles wingpanel and plank. To make autoplank work properly, you might have to run `autoplank --elementary-fix`. You can revert this change with `autoplank --elementary-restore` +Elementary has a service called `cerbere` which handles wingpanel and plank. To make autoplank work properly, you might have to run `autoplank --elementary-fix`. You can revert this change with `autoplank --elementary-restore`. For these commands to take affect, you have to restart/log out and in. Inspired by [abiosoft/autoplank](https://github.com/abiosoft/autoplank).