mirror of
https://codeberg.org/icewind/evdev-shortcut.git
synced 2026-06-04 02:24:11 +02:00
flake + ci rework
This commit is contained in:
parent
025ee6a620
commit
6e13b8e412
10 changed files with 178 additions and 165 deletions
44
src/lib.rs
44
src/lib.rs
|
|
@ -11,9 +11,12 @@
|
|||
//! ```rust,no_run
|
||||
//! # use std::path::PathBuf;
|
||||
//! # use glob::GlobError;
|
||||
//! # use evdev_shortcut::{ShortcutListener, Shortcut, Modifier, Key};
|
||||
//! # #[cfg(feature = "listener")]
|
||||
//! # use evdev_shortcut::{ShortcutListener};
|
||||
//! # use evdev_shortcut::{Shortcut, Modifier, Key};
|
||||
//! # use tokio::pin;
|
||||
//! # use futures::stream::StreamExt;
|
||||
//! # use tokio_stream::StreamExt;
|
||||
//! # #[cfg(feature = "listener")]
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! let listener = ShortcutListener::new();
|
||||
|
|
@ -30,6 +33,10 @@
|
|||
//! }
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! # #[cfg(not(feature = "listener"))]
|
||||
//! # fn main() {
|
||||
//! # // placeholder so we can build the doc example without default features
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
pub use keycodes::Key;
|
||||
|
|
@ -134,21 +141,26 @@ pub struct ModifierList(u8);
|
|||
|
||||
impl ModifierList {
|
||||
pub fn new(modifiers: &[Modifier]) -> Self {
|
||||
ModifierList(modifiers
|
||||
.iter()
|
||||
.fold(0, |mask, modifier| mask | modifier.mask()))
|
||||
ModifierList(
|
||||
modifiers
|
||||
.iter()
|
||||
.fold(0, |mask, modifier| mask | modifier.mask()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn mask(&self) -> u8 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn modifiers(&self) -> impl Iterator<Item=Modifier> {
|
||||
pub fn modifiers(&self) -> impl Iterator<Item = Modifier> {
|
||||
let mask = self.mask();
|
||||
ALL_MODIFIERS.iter().copied().filter(move |modifier| {
|
||||
for combined in COMBINED_MODIFIERS {
|
||||
// if <Ctrl> is enabled, don't emit <LeftCtrl> and <RightCtrl>
|
||||
if combined != modifier && combined.mask() & modifier.mask() == modifier.mask() && combined.mask() & mask == combined.mask() {
|
||||
if combined != modifier
|
||||
&& combined.mask() & modifier.mask() == modifier.mask()
|
||||
&& combined.mask() & mask == combined.mask()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -178,7 +190,8 @@ impl FromStr for ModifierList {
|
|||
type Err = ParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let modifiers = s.split('>')
|
||||
let modifiers = s
|
||||
.split('>')
|
||||
.filter(|part| !part.is_empty())
|
||||
.map(|part| {
|
||||
if !part.starts_with('<') {
|
||||
|
|
@ -251,8 +264,8 @@ impl Display for Shortcut {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test_case::test_case;
|
||||
use crate::{Key, Modifier, ModifierList, Shortcut};
|
||||
use test_case::test_case;
|
||||
|
||||
#[test_case("KeyP", Shortcut::new(& [], Key::KeyP))]
|
||||
#[test_case("<Ctrl>-KeyP", Shortcut::new(& [Modifier::Ctrl], Key::KeyP))]
|
||||
|
|
@ -267,7 +280,10 @@ mod tests {
|
|||
#[test_case(& [Modifier::LeftAlt, Modifier::LeftCtrl])]
|
||||
#[test_case(& [Modifier::Shift, Modifier::Meta])]
|
||||
fn test_modifier_list(modifiers: &[Modifier]) {
|
||||
assert_eq!(modifiers.to_vec(), ModifierList::new(modifiers).modifiers().collect::<Vec<_>>())
|
||||
assert_eq!(
|
||||
modifiers.to_vec(),
|
||||
ModifierList::new(modifiers).modifiers().collect::<Vec<_>>()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -280,9 +296,7 @@ impl Shortcut {
|
|||
}
|
||||
|
||||
pub fn identifier(&self) -> String {
|
||||
self.to_string()
|
||||
.replace(['<', '>'], "")
|
||||
.replace('-', "_")
|
||||
self.to_string().replace(['<', '>'], "").replace('-', "_")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +336,7 @@ mod triggered_tests {
|
|||
#[test_case("<Ctrl><Alt>-KeyLeft", & [Key::KeyLeftCtrl, Key::KeyRightAlt, Key::KeyLeft] => true)]
|
||||
fn shortcut_triggered(s: &str, keys: &[Key]) -> bool {
|
||||
let shortcut: Shortcut = s.parse().unwrap();
|
||||
shortcut.is_triggered(&keys.into_iter().copied().collect())
|
||||
shortcut.is_triggered(&keys.iter().copied().collect())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -353,4 +367,4 @@ impl Display for ShortcutState {
|
|||
pub struct ShortcutEvent {
|
||||
pub shortcut: Shortcut,
|
||||
pub state: ShortcutState,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
use crate::{DeviceOpenError, Key, Shortcut, ShortcutEvent, ShortcutState};
|
||||
use async_stream::stream;
|
||||
use evdev::Device;
|
||||
use futures::pin_mut;
|
||||
use futures::stream::iter;
|
||||
use futures::{Stream, StreamExt};
|
||||
use std::collections::HashSet;
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crate::{Shortcut, DeviceOpenError, Key, ShortcutEvent, ShortcutState};
|
||||
use std::path::Path;
|
||||
use async_stream::stream;
|
||||
use futures::pin_mut;
|
||||
use futures::{Stream, StreamExt};
|
||||
use futures::stream::{iter};
|
||||
use tracing::{debug, trace, info};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tracing::{debug, info, trace};
|
||||
|
||||
/// A listener for shortcut events
|
||||
///
|
||||
|
|
@ -42,20 +42,29 @@ impl ShortcutListener {
|
|||
/// Listen for shortcuts on the provided set of input devices.
|
||||
///
|
||||
/// Note that you need to register shortcuts using [add](ShortcutListener::add) to get any events.
|
||||
pub fn listen<P: AsRef<Path>>(&self, devices: &[P]) -> Result<impl Stream<Item=ShortcutEvent>, DeviceOpenError> {
|
||||
pub fn listen<P: AsRef<Path>>(
|
||||
&self,
|
||||
devices: &[P],
|
||||
) -> Result<impl Stream<Item = ShortcutEvent>, DeviceOpenError> {
|
||||
let shortcuts = self.shortcuts.clone();
|
||||
|
||||
let devices = devices
|
||||
.iter()
|
||||
.map(|path| {
|
||||
let path = path.as_ref();
|
||||
let res = Device::open(path).map_err(|_| DeviceOpenError { device: path.into() });
|
||||
let res = Device::open(path).map_err(|_| DeviceOpenError {
|
||||
device: path.into(),
|
||||
});
|
||||
debug!(device = ?path, success = res.is_ok(), "opening input device");
|
||||
res
|
||||
})
|
||||
.collect::<Result<Vec<Device>, DeviceOpenError>>()?;
|
||||
let events = iter(devices.into_iter().flat_map(|device| device.into_event_stream()))
|
||||
.flatten();
|
||||
let events = iter(
|
||||
devices
|
||||
.into_iter()
|
||||
.flat_map(|device| device.into_event_stream()),
|
||||
)
|
||||
.flatten();
|
||||
|
||||
Ok(stream! {
|
||||
let mut active_keys = HashSet::new();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue