mirror of
https://codeberg.org/icewind/shortcutd.git
synced 2026-06-03 09:14:07 +02:00
client: zbus/tokio
This commit is contained in:
parent
cea82db46b
commit
dfebec7c24
5 changed files with 68 additions and 120 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
|
@ -244,16 +244,6 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dbus"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5cd9e78c210146a1860f897db03412fd5091fd73100778e43ee255cca252cf32"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"libdbus-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derivative"
|
name = "derivative"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
|
@ -568,15 +558,6 @@ version = "0.2.146"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
|
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libdbus-sys"
|
|
||||||
version = "0.2.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72"
|
|
||||||
dependencies = [
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
|
@ -763,12 +744,6 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "polling"
|
name = "polling"
|
||||||
version = "2.8.0"
|
version = "2.8.0"
|
||||||
|
|
@ -982,9 +957,11 @@ dependencies = [
|
||||||
name = "shortcutd"
|
name = "shortcutd"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dbus",
|
|
||||||
"evdev-shortcut",
|
"evdev-shortcut",
|
||||||
|
"futures",
|
||||||
"test-case",
|
"test-case",
|
||||||
|
"tokio",
|
||||||
|
"zbus",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,10 @@ name = "shortcutd"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dbus = { version = "0.8.4" }
|
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.1", default_features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
test-case = "3.1.0"
|
test-case = "3.1.0"
|
||||||
|
tokio = { version = "1.28.2", features = ["macros", "rt-multi-thread"] }
|
||||||
|
|
@ -1,23 +1,24 @@
|
||||||
use shortcutd::{Shortcut, ShortcutClient};
|
use shortcutd::{ShortcutClient};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::time::Duration;
|
use futures::pin_mut;
|
||||||
|
use futures::stream::iter;
|
||||||
|
use futures::StreamExt;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
#[tokio::main]
|
||||||
let mut client = ShortcutClient::new()?;
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let client = ShortcutClient::new().await?;
|
||||||
|
|
||||||
let shortcut: Shortcut = "<Ctrl><Alt>-KeyP".parse()?;
|
let streams = [
|
||||||
|
Box::pin(client.register("<Ctrl>-KeyM".parse()?).await?),
|
||||||
|
Box::pin(client.register("<Ctrl><Alt>-KeyO".parse()?).await?),
|
||||||
|
];
|
||||||
|
|
||||||
client.register(shortcut, |s| {
|
let stream = iter(streams).flatten_unordered(None);
|
||||||
eprintln!("shortcut1 {}", s);
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let shortcut: Shortcut = "<Ctrl><Alt>-KeyO".parse()?;
|
pin_mut!(stream);
|
||||||
|
|
||||||
client.register(shortcut, |s| {
|
while let Some(event) = stream.next().await {
|
||||||
eprintln!("shortcut2 {}", s);
|
println!("{} {}", event.shortcut, event.state.as_str());
|
||||||
})?;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
client.process(Duration::from_millis(1000))?;
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,97 +1,63 @@
|
||||||
use dbus::arg;
|
|
||||||
use dbus::blocking;
|
|
||||||
pub use evdev_shortcut::Shortcut;
|
pub use evdev_shortcut::Shortcut;
|
||||||
|
use evdev_shortcut::{ShortcutEvent, ShortcutState};
|
||||||
|
use futures::Stream;
|
||||||
|
use zbus::{Connection, fdo};
|
||||||
|
use zbus::dbus_proxy;
|
||||||
|
use futures::StreamExt;
|
||||||
|
|
||||||
const INTERFACE: &'static str = "nl.icewind.shortcutd";
|
#[dbus_proxy(
|
||||||
|
interface = "nl.icewind.shortcutd",
|
||||||
pub trait NlIcewindShortcutd {
|
default_service = "nl.icewind.shortcutd",
|
||||||
fn register(&self, shortcut: &str) -> Result<String, dbus::Error>;
|
default_path = "/register"
|
||||||
|
)]
|
||||||
|
trait Register {
|
||||||
|
async fn register(&self, shortcut: &str) -> fdo::Result<String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C: ::std::ops::Deref<Target = blocking::Connection>> NlIcewindShortcutd
|
|
||||||
for blocking::Proxy<'a, C>
|
#[dbus_proxy(
|
||||||
{
|
interface = "nl.icewind.shortcutd",
|
||||||
fn register(&self, shortcut: &str) -> Result<String, dbus::Error> {
|
default_service = "nl.icewind.shortcutd"
|
||||||
self.method_call(INTERFACE, "Register", (shortcut,))
|
)]
|
||||||
.and_then(|r: (String,)| Ok(r.0))
|
trait ShortcutSignal {
|
||||||
}
|
#[dbus_proxy(signal)]
|
||||||
|
async fn triggered(&self, pressed: bool) -> fdo::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct NlIcewindShortcutdTriggered {}
|
|
||||||
|
|
||||||
impl arg::AppendAll for NlIcewindShortcutdTriggered {
|
|
||||||
fn append(&self, _: &mut arg::IterAppend) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl arg::ReadAll for NlIcewindShortcutdTriggered {
|
|
||||||
fn read(_: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
|
|
||||||
Ok(NlIcewindShortcutdTriggered {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl dbus::message::SignalArgs for NlIcewindShortcutdTriggered {
|
|
||||||
const NAME: &'static str = "Triggered";
|
|
||||||
const INTERFACE: &'static str = INTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait OrgFreedesktopDBusIntrospectable {
|
|
||||||
fn introspect(&self) -> Result<String, dbus::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, C: ::std::ops::Deref<Target = blocking::Connection>> OrgFreedesktopDBusIntrospectable
|
|
||||||
for blocking::Proxy<'a, C>
|
|
||||||
{
|
|
||||||
fn introspect(&self) -> Result<String, dbus::Error> {
|
|
||||||
self.method_call("org.freedesktop.DBus.Introspectable", "Introspect", ())
|
|
||||||
.and_then(|r: (String,)| Ok(r.0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Autogenerated code ends here.
|
|
||||||
|
|
||||||
use dbus::blocking::Connection;
|
|
||||||
use dbus::Message;
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
pub struct ShortcutClient {
|
pub struct ShortcutClient {
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShortcutClient {
|
impl ShortcutClient {
|
||||||
pub fn new() -> Result<Self, dbus::Error> {
|
pub async fn new() -> Result<Self, zbus::Error> {
|
||||||
Ok(ShortcutClient {
|
Ok(ShortcutClient {
|
||||||
connection: Connection::new_system()?,
|
connection: Connection::system().await?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register(
|
pub fn from_zbus(connection: Connection) -> Self {
|
||||||
&mut self,
|
ShortcutClient { connection }
|
||||||
shortcut: Shortcut,
|
|
||||||
handler: impl Fn(Shortcut) + Send + 'static,
|
|
||||||
) -> Result<(), dbus::Error> {
|
|
||||||
let path = self
|
|
||||||
.connection
|
|
||||||
.with_proxy(INTERFACE, "/register", Duration::from_millis(5000))
|
|
||||||
.register(&format!("{}", shortcut))?;
|
|
||||||
|
|
||||||
let proxy = self
|
|
||||||
.connection
|
|
||||||
.with_proxy(INTERFACE, &path, Duration::from_millis(5000));
|
|
||||||
|
|
||||||
// Let's start listening to signals.
|
|
||||||
let _id = proxy.match_signal(
|
|
||||||
move |_: NlIcewindShortcutdTriggered, _: &Connection, _: &Message| {
|
|
||||||
handler(shortcut.clone());
|
|
||||||
true
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process(&mut self, timeout: Duration) -> Result<(), dbus::Error> {
|
pub async fn register(
|
||||||
self.connection.process(timeout)?;
|
&self,
|
||||||
Ok(())
|
shortcut: Shortcut,
|
||||||
|
) -> 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 signals = p.receive_triggered().await?;
|
||||||
|
|
||||||
|
Ok(signals.filter_map(move |signal| {
|
||||||
|
let shortcut = shortcut.clone();
|
||||||
|
async move {
|
||||||
|
let pressed = signal.args().ok()?.pressed;
|
||||||
|
Some(ShortcutEvent {
|
||||||
|
shortcut,
|
||||||
|
state: if pressed { ShortcutState::Pressed } else { ShortcutState::Released },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use evdev_shortcut::{Shortcut, ShortcutEvent, ShortcutListener, ShortcutState};
|
||||||
use glob::GlobError;
|
use glob::GlobError;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
|
use tracing::info;
|
||||||
use zbus::{ConnectionBuilder, dbus_interface, fdo, SignalContext, ObjectServer};
|
use zbus::{ConnectionBuilder, dbus_interface, fdo, SignalContext, ObjectServer};
|
||||||
use zbus::export::futures_util::pin_mut;
|
use zbus::export::futures_util::pin_mut;
|
||||||
|
|
||||||
|
|
@ -15,6 +16,7 @@ impl Register {
|
||||||
async fn register(&mut self, shortcut: &str, #[zbus(object_server)] server: &ObjectServer) -> Result<String, fdo::Error> {
|
async fn register(&mut self, shortcut: &str, #[zbus(object_server)] server: &ObjectServer) -> Result<String, fdo::Error> {
|
||||||
match shortcut.parse::<Shortcut>() {
|
match shortcut.parse::<Shortcut>() {
|
||||||
Ok(shortcut) => {
|
Ok(shortcut) => {
|
||||||
|
info!(%shortcut, "registering shortcut");
|
||||||
self.listener.add(shortcut.clone());
|
self.listener.add(shortcut.clone());
|
||||||
let path = format!("/{}", shortcut.identifier());
|
let path = format!("/{}", shortcut.identifier());
|
||||||
if let Err(e) = server.at(path.as_str(), ShortcutSignal).await {
|
if let Err(e) = server.at(path.as_str(), ShortcutSignal).await {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue