commit
2f404f3646
@ -0,0 +1 @@ |
||||
/target |
@ -0,0 +1,283 @@ |
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
version = 3 |
||||
|
||||
[[package]] |
||||
name = "bumpalo" |
||||
version = "3.7.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" |
||||
|
||||
[[package]] |
||||
name = "cfg-if" |
||||
version = "1.0.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" |
||||
|
||||
[[package]] |
||||
name = "flume" |
||||
version = "0.10.9" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "24c3fd473b3a903a62609e413ed7538f99e10b665ecb502b5e481a95283f8ab4" |
||||
dependencies = [ |
||||
"futures-core", |
||||
"futures-sink", |
||||
"nanorand", |
||||
"pin-project", |
||||
"spin", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "futures-core" |
||||
version = "0.3.16" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" |
||||
|
||||
[[package]] |
||||
name = "futures-sink" |
||||
version = "0.3.16" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" |
||||
|
||||
[[package]] |
||||
name = "getrandom" |
||||
version = "0.2.3" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" |
||||
dependencies = [ |
||||
"cfg-if", |
||||
"js-sys", |
||||
"libc", |
||||
"wasi", |
||||
"wasm-bindgen", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "i3status-simple" |
||||
version = "0.1.0" |
||||
dependencies = [ |
||||
"flume", |
||||
"serde", |
||||
"serde_json", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "itoa" |
||||
version = "0.4.8" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" |
||||
|
||||
[[package]] |
||||
name = "js-sys" |
||||
version = "0.3.53" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" |
||||
dependencies = [ |
||||
"wasm-bindgen", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "lazy_static" |
||||
version = "1.4.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" |
||||
|
||||
[[package]] |
||||
name = "libc" |
||||
version = "0.2.101" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" |
||||
|
||||
[[package]] |
||||
name = "lock_api" |
||||
version = "0.4.4" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" |
||||
dependencies = [ |
||||
"scopeguard", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "log" |
||||
version = "0.4.14" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" |
||||
dependencies = [ |
||||
"cfg-if", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "nanorand" |
||||
version = "0.6.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "729eb334247daa1803e0a094d0a5c55711b85571179f5ec6e53eccfdf7008958" |
||||
dependencies = [ |
||||
"getrandom", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "pin-project" |
||||
version = "1.0.8" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" |
||||
dependencies = [ |
||||
"pin-project-internal", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "pin-project-internal" |
||||
version = "1.0.8" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "proc-macro2" |
||||
version = "1.0.28" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" |
||||
dependencies = [ |
||||
"unicode-xid", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "quote" |
||||
version = "1.0.9" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "ryu" |
||||
version = "1.0.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" |
||||
|
||||
[[package]] |
||||
name = "scopeguard" |
||||
version = "1.1.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" |
||||
|
||||
[[package]] |
||||
name = "serde" |
||||
version = "1.0.129" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1" |
||||
dependencies = [ |
||||
"serde_derive", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "serde_derive" |
||||
version = "1.0.129" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "serde_json" |
||||
version = "1.0.66" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" |
||||
dependencies = [ |
||||
"itoa", |
||||
"ryu", |
||||
"serde", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "spin" |
||||
version = "0.9.2" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" |
||||
dependencies = [ |
||||
"lock_api", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "syn" |
||||
version = "1.0.75" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"unicode-xid", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "unicode-xid" |
||||
version = "0.2.2" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" |
||||
|
||||
[[package]] |
||||
name = "wasi" |
||||
version = "0.10.2+wasi-snapshot-preview1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen" |
||||
version = "0.2.76" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" |
||||
dependencies = [ |
||||
"cfg-if", |
||||
"wasm-bindgen-macro", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen-backend" |
||||
version = "0.2.76" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" |
||||
dependencies = [ |
||||
"bumpalo", |
||||
"lazy_static", |
||||
"log", |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
"wasm-bindgen-shared", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen-macro" |
||||
version = "0.2.76" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" |
||||
dependencies = [ |
||||
"quote", |
||||
"wasm-bindgen-macro-support", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen-macro-support" |
||||
version = "0.2.76" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
"wasm-bindgen-backend", |
||||
"wasm-bindgen-shared", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen-shared" |
||||
version = "0.2.76" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" |
@ -0,0 +1,11 @@ |
||||
[package] |
||||
name = "i3status-simple" |
||||
version = "0.1.0" |
||||
edition = "2018" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
flume = "0.10" |
||||
serde = { version = "1.0", features = ["derive"] } |
||||
serde_json = "1.0" |
@ -0,0 +1,124 @@ |
||||
use std::sync::mpsc; |
||||
use std::{collections::HashMap, io::Write}; |
||||
|
||||
use protocol::i3bar_event::I3BarEvent; |
||||
|
||||
use crate::protocol::{ |
||||
i3bar_block::{write_blocks, I3BarBlock}, |
||||
i3bar_event::read_event, |
||||
}; |
||||
|
||||
mod protocol; |
||||
|
||||
fn main() { |
||||
protocol::init(); |
||||
|
||||
let (event_s, event_r) = flume::unbounded(); |
||||
std::thread::spawn(move || loop { |
||||
let event = read_event().unwrap(); |
||||
event_s.send(event).unwrap(); |
||||
}); |
||||
|
||||
let blocks = vec![ |
||||
TestBlock { id: 0, n: 0 }, |
||||
TestBlock { id: 1, n: 1 }, |
||||
TestBlock { id: 2, n: 2 }, |
||||
TestBlock { id: 3, n: 3 }, |
||||
]; |
||||
let (update_s, update_r) = flume::unbounded(); |
||||
let block_ids: Vec<_> = blocks.iter().map(|b| b.id()).collect(); |
||||
|
||||
for block in blocks { |
||||
let event_r = event_r.clone(); |
||||
let update_s = update_s.clone(); |
||||
std::thread::spawn(move || { |
||||
block.run(event_r, update_s); |
||||
}); |
||||
} |
||||
|
||||
let mut cache = HashMap::new(); |
||||
loop { |
||||
let (id, content) = update_r.recv().unwrap(); |
||||
cache.insert(id, content); |
||||
let rendered_blocks = block_ids |
||||
.iter() |
||||
.filter_map(|id| cache.get(id).map(|content| content.clone())) |
||||
.map(|content| I3BarBlock { |
||||
full_text: content, |
||||
color: Some(String::from("#ff0000")), |
||||
background: Some(String::from("#00ff00")), |
||||
border: Some(String::from("#0000ff")), |
||||
border_right: Some(16), |
||||
border_left: Some(16), |
||||
..Default::default() |
||||
}) |
||||
.collect(); |
||||
write_blocks(rendered_blocks); |
||||
} |
||||
} |
||||
|
||||
pub trait Block { |
||||
fn id(&self) -> usize; |
||||
|
||||
fn name(&self) -> &str; |
||||
|
||||
fn run(self, event_r: flume::Receiver<I3BarEvent>, update_s: flume::Sender<(usize, String)>); |
||||
} |
||||
|
||||
pub enum Event { |
||||
I3Bar(I3BarEvent), |
||||
Poll, |
||||
} |
||||
|
||||
struct TestBlock { |
||||
id: usize, |
||||
n: i32, |
||||
} |
||||
|
||||
impl Block for TestBlock { |
||||
fn id(&self) -> usize { |
||||
self.id |
||||
} |
||||
|
||||
fn name(&self) -> &str { |
||||
"test" |
||||
} |
||||
|
||||
fn run( |
||||
mut self, |
||||
event_r: flume::Receiver<I3BarEvent>, |
||||
update_s: flume::Sender<(usize, String)>, |
||||
) { |
||||
let (poll_s, poll_r) = flume::unbounded(); |
||||
std::thread::spawn(move || loop { |
||||
std::thread::sleep(std::time::Duration::from_millis(333)); |
||||
poll_s.send(()).unwrap(); |
||||
}); |
||||
|
||||
loop { |
||||
flume::Selector::new() |
||||
.recv(&event_r, |msg| msg.map(|msg| Event::I3Bar(msg))) |
||||
.recv(&poll_r, |_| Ok(Event::Poll)) |
||||
.wait() |
||||
.unwrap(); |
||||
self.n += 1; |
||||
update_s |
||||
.send((self.id(), format!(" hello {} ", self.n))) |
||||
.unwrap(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub fn debug<'s, S1, S2>(loc: S1, content: S2) |
||||
where |
||||
S1: AsRef<str>, |
||||
S2: AsRef<str>, |
||||
{ |
||||
let mut file = std::fs::OpenOptions::new() |
||||
.append(true) |
||||
.create(true) |
||||
.open("/home/rosen/dev/i3status-simple/debug.log") |
||||
.unwrap(); |
||||
file.write_all(format!("[{:?}]: {:?}\n", loc.as_ref(), content.as_ref()).as_bytes()) |
||||
.unwrap(); |
||||
} |
@ -0,0 +1,38 @@ |
||||
use serde::Serialize; |
||||
|
||||
#[derive(Clone, Debug, Default, Serialize)] |
||||
pub struct I3BarBlock { |
||||
pub full_text: String, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub short_text: Option<String>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub color: Option<String>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub background: Option<String>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub border: Option<String>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub border_top: Option<i32>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub border_right: Option<i32>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub border_bottom: Option<i32>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub border_left: Option<i32>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub min_width: Option<i32>, |
||||
pub name: String, |
||||
pub instance: String, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub urgent: Option<bool>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub separator: Option<bool>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub separator_block_width: Option<i32>, |
||||
#[serde(skip_serializing_if = "Option::is_none")] |
||||
pub markup: Option<String>, |
||||
} |
||||
|
||||
pub fn write_blocks(blocks: Vec<I3BarBlock>) { |
||||
println!("{},", serde_json::to_string(&blocks).unwrap()); |
||||
} |
@ -0,0 +1,90 @@ |
||||
use serde::{de, Deserialize, Deserializer}; |
||||
|
||||
#[derive(Clone, Debug, Deserialize)] |
||||
pub struct I3BarEvent { |
||||
pub name: String, |
||||
pub instance: String, |
||||
pub x: i32, |
||||
pub y: i32, |
||||
#[serde(deserialize_with = "deserialize_mousebutton")] |
||||
pub button: I3BarEventButton, |
||||
pub relative_x: i32, |
||||
pub relative_y: i32, |
||||
pub output_x: i32, |
||||
pub output_y: i32, |
||||
pub width: i32, |
||||
pub height: i32, |
||||
pub modifiers: Vec<I3BarEventModifier>, |
||||
} |
||||
|
||||
pub fn read_event() -> std::io::Result<I3BarEvent> { |
||||
let mut line = String::new(); |
||||
std::io::stdin().read_line(&mut line)?; |
||||
|
||||
let slice = line.trim_start_matches(|c| c != '{'); |
||||
let slice = slice.trim_end_matches(|c| c != '}'); |
||||
|
||||
// If empty line, read another line
|
||||
if slice == "" { |
||||
return read_event(); |
||||
} |
||||
|
||||
Ok(serde_json::from_str(slice).unwrap()) |
||||
} |
||||
|
||||
#[derive(Clone, Debug)] |
||||
pub enum I3BarEventButton { |
||||
LeftMouse, |
||||
MiddleMouse, |
||||
RightMouse, |
||||
ScrollUp, |
||||
ScrollDown, |
||||
ScrollRight, |
||||
ScrollLeft, |
||||
} |
||||
|
||||
fn deserialize_mousebutton<'de, D>(deserializer: D) -> Result<I3BarEventButton, D::Error> |
||||
where |
||||
D: Deserializer<'de>, |
||||
{ |
||||
struct I3BarEventButtonVisitor; |
||||
|
||||
impl<'de> de::Visitor<'de> for I3BarEventButtonVisitor { |
||||
type Value = I3BarEventButton; |
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { |
||||
formatter.write_str("u64") |
||||
} |
||||
|
||||
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
||||
where |
||||
E: de::Error, |
||||
{ |
||||
Ok(match v { |
||||
1 => I3BarEventButton::LeftMouse, |
||||
2 => I3BarEventButton::MiddleMouse, |
||||
3 => I3BarEventButton::RightMouse, |
||||
4 => I3BarEventButton::ScrollUp, |
||||
5 => I3BarEventButton::ScrollDown, |
||||
6 => I3BarEventButton::ScrollRight, |
||||
7 => I3BarEventButton::ScrollLeft, |
||||
_ => { |
||||
return Err(de::Error::invalid_value( |
||||
de::Unexpected::Unsigned(v), |
||||
&"1-7", |
||||
)) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
deserializer.deserialize_any(I3BarEventButtonVisitor) |
||||
} |
||||
|
||||
#[derive(Clone, Debug, Deserialize)] |
||||
pub enum I3BarEventModifier { |
||||
Mod1, |
||||
Mod4, |
||||
Control, |
||||
Shift, |
||||
} |
@ -0,0 +1,6 @@ |
||||
pub mod i3bar_block; |
||||
pub mod i3bar_event; |
||||
|
||||
pub fn init() { |
||||
println!(r#"{{ "version": 1, "click_events": true }}["#) |
||||
} |
Loading…
Reference in new issue