Merge branch 'randr'
This commit is contained in:
158
Cargo.lock
generated
158
Cargo.lock
generated
@@ -50,6 +50,15 @@ dependencies = [
|
|||||||
"core_extensions",
|
"core_extensions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@@ -118,6 +127,17 @@ dependencies = [
|
|||||||
"syn 1.0.107",
|
"syn 1.0.107",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.68"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.13",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atk"
|
name = "atk"
|
||||||
version = "0.16.0"
|
version = "0.16.0"
|
||||||
@@ -286,6 +306,12 @@ version = "0.2.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58baae561b85ca19b3122a9ddd35c8ec40c3bcd14fe89921824eae73f7baffbf"
|
checksum = "58baae561b85ca19b3122a9ddd35c8ec40c3bcd14fe89921824eae73f7baffbf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "convert_case"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation-sys"
|
||||||
version = "0.8.3"
|
version = "0.8.3"
|
||||||
@@ -381,6 +407,25 @@ dependencies = [
|
|||||||
"syn 1.0.107",
|
"syn 1.0.107",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_more"
|
||||||
|
version = "0.99.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||||
|
dependencies = [
|
||||||
|
"convert_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustc_version 0.4.0",
|
||||||
|
"syn 1.0.107",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "doc-comment"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "downcast-rs"
|
name = "downcast-rs"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@@ -816,6 +861,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
@@ -887,6 +938,39 @@ dependencies = [
|
|||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyprland"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2166a21b9f0018d522bfd25debccdb16af8d2100aee63f842f9da37256129571"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"derive_more",
|
||||||
|
"doc-comment",
|
||||||
|
"futures",
|
||||||
|
"hex",
|
||||||
|
"hyprland-macros",
|
||||||
|
"lazy_static",
|
||||||
|
"num-traits",
|
||||||
|
"paste",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"strum",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyprland-macros"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2de65550b4ec230167654f367b6ec02795acf2cfd9692f05bedb10ff09e46a6e"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.13",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.53"
|
version = "0.1.53"
|
||||||
@@ -1386,6 +1470,16 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "randr"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"abi_stable",
|
||||||
|
"anyrun-plugin",
|
||||||
|
"fuzzy-matcher",
|
||||||
|
"hyprland",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@@ -1401,6 +1495,8 @@ version = "1.7.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
|
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1557,6 +1653,12 @@ dependencies = [
|
|||||||
"base64 0.21.0",
|
"base64 0.21.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
@@ -1640,6 +1742,17 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_repr"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.13",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -1662,6 +1775,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
@@ -1705,6 +1827,28 @@ version = "0.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.24.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
|
||||||
|
dependencies = [
|
||||||
|
"strum_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.24.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn 1.0.107",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sublime_fuzzy"
|
name = "sublime_fuzzy"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -1847,11 +1991,25 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
"parking_lot",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "1.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.107",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-rustls"
|
name = "tokio-rustls"
|
||||||
version = "0.23.4"
|
version = "0.23.4"
|
||||||
|
@@ -9,4 +9,5 @@ members = [
|
|||||||
"plugins/shell",
|
"plugins/shell",
|
||||||
"plugins/kidex",
|
"plugins/kidex",
|
||||||
"plugins/translate",
|
"plugins/translate",
|
||||||
|
"plugins/randr",
|
||||||
]
|
]
|
@@ -136,6 +136,9 @@ Anyrun requires plugins to function, as they provide the results for input. The
|
|||||||
- Run shell commands
|
- Run shell commands
|
||||||
- [Kidex](plugins/kidex)
|
- [Kidex](plugins/kidex)
|
||||||
- File search provided by [Kidex](https://github.com/Kirottu/kidex)
|
- File search provided by [Kidex](https://github.com/Kirottu/kidex)
|
||||||
|
- [Randr](plugins/randr)
|
||||||
|
- Rotate and resize; quickly change monitor configurations on the fly.
|
||||||
|
- TODO: Only supports Hyprland, needs support for other compositors.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
15
plugins/randr/Cargo.toml
Normal file
15
plugins/randr/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "randr"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
fuzzy-matcher = "0.3.7"
|
||||||
|
anyrun-plugin = { path = "../../anyrun-plugin" }
|
||||||
|
abi_stable = "0.11.1"
|
||||||
|
hyprland = "0.3"
|
163
plugins/randr/src/lib.rs
Normal file
163
plugins/randr/src/lib.rs
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
use abi_stable::std_types::{ROption, RString, RVec};
|
||||||
|
use anyrun_plugin::{anyrun_interface::HandleResult, plugin, Match, PluginInfo};
|
||||||
|
use fuzzy_matcher::FuzzyMatcher;
|
||||||
|
use randr::{dummy::Dummy, hyprland::Hyprland, Configure, Monitor, Randr};
|
||||||
|
|
||||||
|
mod randr;
|
||||||
|
|
||||||
|
enum InnerState {
|
||||||
|
None,
|
||||||
|
Position(Monitor),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct State {
|
||||||
|
randr: Box<dyn Randr + Send + Sync>,
|
||||||
|
inner: InnerState,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(_config_dir: RString) -> State {
|
||||||
|
// Determine which Randr implementation should be used
|
||||||
|
let randr: Box<dyn Randr + Send + Sync> = if env::var("HYPRLAND_INSTANCE_SIGNATURE").is_ok() {
|
||||||
|
Box::new(Hyprland::new())
|
||||||
|
} else {
|
||||||
|
Box::new(Dummy)
|
||||||
|
};
|
||||||
|
|
||||||
|
State {
|
||||||
|
randr,
|
||||||
|
inner: InnerState::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn info() -> PluginInfo {
|
||||||
|
PluginInfo {
|
||||||
|
name: "Randr".into(),
|
||||||
|
icon: "video-display".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handler(_match: Match, state: &mut State) -> HandleResult {
|
||||||
|
match &state.inner {
|
||||||
|
InnerState::None => {
|
||||||
|
state.inner = InnerState::Position(
|
||||||
|
state
|
||||||
|
.randr
|
||||||
|
.get_monitors()
|
||||||
|
.into_iter()
|
||||||
|
.find(|mon| mon.id == _match.id.unwrap())
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
HandleResult::Refresh(true)
|
||||||
|
}
|
||||||
|
InnerState::Position(mon) => {
|
||||||
|
if _match.id.unwrap() == u64::MAX {
|
||||||
|
state.inner = InnerState::None;
|
||||||
|
return HandleResult::Refresh(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rel_id = (_match.id.unwrap() >> 32) as u32;
|
||||||
|
let action = _match.id.unwrap() as u32;
|
||||||
|
|
||||||
|
let rel_mon = state
|
||||||
|
.randr
|
||||||
|
.get_monitors()
|
||||||
|
.into_iter()
|
||||||
|
.find(|mon| mon.id == rel_id as u64)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
state
|
||||||
|
.randr
|
||||||
|
.configure(mon, Configure::from_id(action, &rel_mon));
|
||||||
|
|
||||||
|
HandleResult::Close
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_matches(input: RString, state: &mut State) -> RVec<Match> {
|
||||||
|
let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().smart_case();
|
||||||
|
let mut vec = match &state.inner {
|
||||||
|
InnerState::None => state
|
||||||
|
.randr
|
||||||
|
.get_monitors()
|
||||||
|
.into_iter()
|
||||||
|
.map(|mon| Match {
|
||||||
|
title: format!("Change position of {}", mon.name).into(),
|
||||||
|
description: ROption::RSome(
|
||||||
|
format!("{}x{} at {}x{}", mon.width, mon.height, mon.x, mon.y).into(),
|
||||||
|
),
|
||||||
|
use_pango: false,
|
||||||
|
icon: ROption::RSome("object-flip-horizontal".into()),
|
||||||
|
id: ROption::RSome(mon.id),
|
||||||
|
})
|
||||||
|
.collect::<RVec<_>>(),
|
||||||
|
InnerState::Position(mon) => {
|
||||||
|
let mut vec = state
|
||||||
|
.randr
|
||||||
|
.get_monitors()
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|_mon| {
|
||||||
|
if _mon == *mon {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(
|
||||||
|
[
|
||||||
|
Configure::Mirror(&_mon),
|
||||||
|
Configure::LeftOf(&_mon),
|
||||||
|
Configure::RightOf(&_mon),
|
||||||
|
Configure::Below(&_mon),
|
||||||
|
Configure::Above(&_mon),
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.map(|configure| Match {
|
||||||
|
title: format!("{} {}", configure.to_string(), _mon.name).into(),
|
||||||
|
description: ROption::RNone,
|
||||||
|
use_pango: false,
|
||||||
|
icon: ROption::RSome(configure.icon().into()),
|
||||||
|
// Store 2 32 bit IDs in the single 64 bit integer, a bit of a hack
|
||||||
|
id: ROption::RSome(_mon.id << 32 | Into::<u64>::into(configure)),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.collect::<RVec<_>>();
|
||||||
|
|
||||||
|
vec.push(Match {
|
||||||
|
title: "Reset position".into(),
|
||||||
|
description: ROption::RNone,
|
||||||
|
use_pango: false,
|
||||||
|
icon: ROption::RSome(Configure::Zero.icon().into()),
|
||||||
|
id: ROption::RSome((&Configure::Zero).into()),
|
||||||
|
});
|
||||||
|
|
||||||
|
vec.push(Match {
|
||||||
|
title: "Back".into(),
|
||||||
|
description: ROption::RSome("Return to the previous menu".into()),
|
||||||
|
use_pango: false,
|
||||||
|
icon: ROption::RSome("edit-undo".into()),
|
||||||
|
id: ROption::RSome(u64::MAX),
|
||||||
|
});
|
||||||
|
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|_match| {
|
||||||
|
matcher
|
||||||
|
.fuzzy_match(&_match.title, &input)
|
||||||
|
.map(|score| (_match, score))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
vec.sort_by(|a, b| b.1.cmp(&a.1));
|
||||||
|
|
||||||
|
vec.truncate(5);
|
||||||
|
|
||||||
|
vec.into_iter().map(|(_match, _)| _match).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin!(init, info, get_matches, handler, State);
|
11
plugins/randr/src/randr/dummy.rs
Normal file
11
plugins/randr/src/randr/dummy.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use super::Randr;
|
||||||
|
|
||||||
|
pub struct Dummy;
|
||||||
|
|
||||||
|
impl Randr for Dummy {
|
||||||
|
fn get_monitors(&self) -> Vec<super::Monitor> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn configure(&self, _mon: &super::Monitor, _config: super::Configure) {}
|
||||||
|
}
|
141
plugins/randr/src/randr/hyprland.rs
Normal file
141
plugins/randr/src/randr/hyprland.rs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
use hyprland::{
|
||||||
|
data,
|
||||||
|
keyword::Keyword,
|
||||||
|
shared::{HyprData, HyprDataVec},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{Configure, Monitor, Randr};
|
||||||
|
|
||||||
|
pub struct Hyprland {
|
||||||
|
monitors: Vec<data::Monitor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hyprland {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
monitors: data::Monitors::get().unwrap().to_vec(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Randr for Hyprland {
|
||||||
|
fn get_monitors(&self) -> Vec<Monitor> {
|
||||||
|
self.monitors
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(|mon| Monitor {
|
||||||
|
x: mon.x,
|
||||||
|
y: mon.y,
|
||||||
|
width: mon.width as u32,
|
||||||
|
height: mon.height as u32,
|
||||||
|
refresh_rate: mon.refresh_rate,
|
||||||
|
scale: mon.scale,
|
||||||
|
name: mon.name,
|
||||||
|
id: mon.id as u64,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn configure(&self, mon: &Monitor, config: Configure) {
|
||||||
|
match config {
|
||||||
|
Configure::Mirror(rel) => Keyword::set(
|
||||||
|
"monitor",
|
||||||
|
format!("{},preferred,auto,1,mirror,{}", mon.name, rel.name),
|
||||||
|
)
|
||||||
|
.expect("Failed to configure monitor"),
|
||||||
|
Configure::LeftOf(rel) => {
|
||||||
|
let mut x = rel.x - mon.width as i32;
|
||||||
|
if x < 0 {
|
||||||
|
Keyword::set(
|
||||||
|
"monitor",
|
||||||
|
format!(
|
||||||
|
"{},{}x{}@{},{}x{},{}",
|
||||||
|
rel.name,
|
||||||
|
rel.width,
|
||||||
|
rel.height,
|
||||||
|
rel.refresh_rate,
|
||||||
|
rel.x - x,
|
||||||
|
rel.y,
|
||||||
|
rel.scale
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("Failed to configure monitor");
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyword::set(
|
||||||
|
"monitor",
|
||||||
|
format!(
|
||||||
|
"{},{}x{}@{},{}x{},{}",
|
||||||
|
mon.name, mon.width, mon.height, mon.refresh_rate, x, rel.y, mon.scale
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("Failed to configure monitor");
|
||||||
|
}
|
||||||
|
Configure::RightOf(rel) => Keyword::set(
|
||||||
|
"monitor",
|
||||||
|
format!(
|
||||||
|
"{},{}x{}@{},{}x{},1",
|
||||||
|
mon.name,
|
||||||
|
mon.width,
|
||||||
|
mon.height,
|
||||||
|
mon.refresh_rate,
|
||||||
|
rel.x + rel.width as i32,
|
||||||
|
rel.y
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("Failed to configure monitor"),
|
||||||
|
Configure::Below(rel) => Keyword::set(
|
||||||
|
"monitor",
|
||||||
|
format!(
|
||||||
|
"{},{}x{}@{},{}x{},{}",
|
||||||
|
mon.name,
|
||||||
|
mon.width,
|
||||||
|
mon.height,
|
||||||
|
mon.refresh_rate,
|
||||||
|
rel.x,
|
||||||
|
rel.y + rel.height as i32,
|
||||||
|
mon.scale
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("Failed to configure monitor"),
|
||||||
|
Configure::Above(rel) => {
|
||||||
|
let mut y = rel.y - mon.height as i32;
|
||||||
|
if y < 0 {
|
||||||
|
Keyword::set(
|
||||||
|
"monitor",
|
||||||
|
format!(
|
||||||
|
"{},{}x{}@{},{}x{},{}",
|
||||||
|
rel.name,
|
||||||
|
rel.width,
|
||||||
|
rel.height,
|
||||||
|
rel.refresh_rate,
|
||||||
|
rel.x,
|
||||||
|
rel.y - y,
|
||||||
|
rel.scale
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("Failed to configure monitor");
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyword::set(
|
||||||
|
"monitor",
|
||||||
|
format!(
|
||||||
|
"{},{}x{}@{},{}x{},{}",
|
||||||
|
mon.name, mon.width, mon.height, mon.refresh_rate, rel.x, y, mon.scale
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("Failed to configure monitor");
|
||||||
|
}
|
||||||
|
Configure::Zero => Keyword::set(
|
||||||
|
"monitor",
|
||||||
|
format!(
|
||||||
|
"{},{}x{}@{},0x0,{}",
|
||||||
|
mon.name, mon.width, mon.height, mon.refresh_rate, mon.scale
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("Failed to configure monitor"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
plugins/randr/src/randr/mod.rs
Normal file
79
plugins/randr/src/randr/mod.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
pub mod dummy;
|
||||||
|
pub mod hyprland;
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub struct Monitor {
|
||||||
|
pub x: i32,
|
||||||
|
pub y: i32,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
pub scale: f32,
|
||||||
|
pub refresh_rate: f32,
|
||||||
|
pub name: String,
|
||||||
|
pub id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Configure<'a> {
|
||||||
|
Mirror(&'a Monitor),
|
||||||
|
LeftOf(&'a Monitor),
|
||||||
|
RightOf(&'a Monitor),
|
||||||
|
Below(&'a Monitor),
|
||||||
|
Above(&'a Monitor),
|
||||||
|
Zero,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Configure<'a> {
|
||||||
|
pub fn from_id(id: u32, mon: &'a Monitor) -> Self {
|
||||||
|
match id {
|
||||||
|
0 => Configure::Mirror(mon),
|
||||||
|
1 => Configure::LeftOf(mon),
|
||||||
|
2 => Configure::RightOf(mon),
|
||||||
|
3 => Configure::Below(mon),
|
||||||
|
4 => Configure::Above(mon),
|
||||||
|
5 => Configure::Zero,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Configure::Mirror(_) => "edit-copy",
|
||||||
|
Configure::LeftOf(_) => "go-previous",
|
||||||
|
Configure::RightOf(_) => "go-next",
|
||||||
|
Configure::Below(_) => "go-down",
|
||||||
|
Configure::Above(_) => "go-up",
|
||||||
|
Configure::Zero => "go-home",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToString for Configure<'a> {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Configure::Mirror(_) => "Mirror".to_string(),
|
||||||
|
Configure::LeftOf(_) => "Left of".to_string(),
|
||||||
|
Configure::RightOf(_) => "Right of".to_string(),
|
||||||
|
Configure::Below(_) => "Below".to_string(),
|
||||||
|
Configure::Above(_) => "Above".to_string(),
|
||||||
|
Configure::Zero => "Zero".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&Configure<'a>> for u64 {
|
||||||
|
fn from(configure: &Configure) -> u64 {
|
||||||
|
match configure {
|
||||||
|
Configure::Mirror(_) => 0,
|
||||||
|
Configure::LeftOf(_) => 1,
|
||||||
|
Configure::RightOf(_) => 2,
|
||||||
|
Configure::Below(_) => 3,
|
||||||
|
Configure::Above(_) => 4,
|
||||||
|
Configure::Zero => 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Randr {
|
||||||
|
fn get_monitors(&self) -> Vec<Monitor>;
|
||||||
|
fn configure(&self, mon: &Monitor, config: Configure);
|
||||||
|
}
|
Reference in New Issue
Block a user