allow some bare shortcuts, example work

This commit is contained in:
Robin Appelman 2023-06-17 20:55:25 +02:00
commit 42237bc965
9 changed files with 232 additions and 63 deletions

View file

@ -11,8 +11,9 @@ path = "src/lib.rs"
[dependencies]
futures = "0.3.28"
zbus = { version = "3.13.1", features = ["tokio"], default-features = false }
evdev-shortcut = { version = "0.1.1", default_features = false }
evdev-shortcut = { version = "0.1.2", default_features = false }
[dev-dependencies]
test-case = "3.1.0"
tokio = { version = "1.28.2", features = ["macros", "rt-multi-thread"] }
tokio = { version = "1.28.2", features = ["macros", "rt-multi-thread"] }
clap = { version = "4.3.4", features = ["derive"] }

View file

@ -1,19 +1,26 @@
use shortcutd::{ShortcutClient};
use std::error::Error;
use clap::Parser;
use evdev_shortcut::Shortcut;
use futures::pin_mut;
use futures::stream::iter;
use futures::StreamExt;
use shortcutd::ShortcutClient;
use std::error::Error;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Shortcut to listen to
shortcuts: Vec<Shortcut>,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let args = Args::parse();
let client = ShortcutClient::new().await?;
let streams = [
Box::pin(client.register("<Ctrl>-KeyM".parse()?).await?),
Box::pin(client.register("<Ctrl><Alt>-KeyO".parse()?).await?),
];
let stream = iter(streams).flatten_unordered(None);
let stream = iter(args.shortcuts)
.then(|shortcut| async { Box::pin(client.listen(shortcut).await.unwrap()) })
.flatten_unordered(None);
pin_mut!(stream);

19
client/examples/simple.rs Normal file
View file

@ -0,0 +1,19 @@
use futures::{pin_mut, StreamExt};
use shortcutd::{Shortcut, ShortcutClient};
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let client = ShortcutClient::new().await?;
let shortcut: Shortcut = "<Ctrl><Alt>-KeyO".parse()?;
let stream = client.listen(shortcut).await?;
pin_mut!(stream);
while let Some(event) = stream.next().await {
println!("{} {}", event.shortcut, event.state.as_str());
}
Ok(())
}

View file

@ -1,23 +1,22 @@
pub use evdev_shortcut::Shortcut;
use evdev_shortcut::{ShortcutEvent, ShortcutState};
use futures::Stream;
use zbus::{Connection, fdo};
use zbus::dbus_proxy;
use futures::StreamExt;
use zbus::dbus_proxy;
use zbus::{fdo, Connection};
#[dbus_proxy(
interface = "nl.icewind.shortcutd",
default_service = "nl.icewind.shortcutd",
default_path = "/register"
interface = "nl.icewind.shortcutd",
default_service = "nl.icewind.shortcutd",
default_path = "/register"
)]
trait Register {
async fn register(&self, shortcut: &str) -> fdo::Result<String>;
}
#[dbus_proxy(
interface = "nl.icewind.shortcutd",
default_service = "nl.icewind.shortcutd"
interface = "nl.icewind.shortcutd",
default_service = "nl.icewind.shortcutd"
)]
trait ShortcutSignal {
#[dbus_proxy(signal)]
@ -39,14 +38,17 @@ impl ShortcutClient {
ShortcutClient { connection }
}
pub async fn register(
pub async fn listen(
&self,
shortcut: Shortcut,
) -> Result<impl Stream<Item=ShortcutEvent> + '_, zbus::Error> {
) -> Result<impl Stream<Item = ShortcutEvent> + '_, zbus::Error> {
let register = RegisterProxy::new(&self.connection).await?;
let path = register.register(&format!("{}", shortcut)).await?;
let p = ShortcutSignalProxy::builder(&self.connection).path(path.as_str())?.build().await?;
let p = ShortcutSignalProxy::builder(&self.connection)
.path(path.as_str())?
.build()
.await?;
let signals = p.receive_triggered().await?;
Ok(signals.filter_map(move |signal| {
@ -55,7 +57,11 @@ impl ShortcutClient {
let pressed = signal.args().ok()?.pressed;
Some(ShortcutEvent {
shortcut,
state: if pressed { ShortcutState::Pressed } else { ShortcutState::Released },
state: if pressed {
ShortcutState::Pressed
} else {
ShortcutState::Released
},
})
}
}))