yay
This commit is contained in:
parent
8a5f321f37
commit
4d58c95c73
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
Cargo.lock
|
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "keydisplay"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
toml = "0.8"
|
||||||
|
dirs = "5.0"
|
||||||
|
inputbot = "0.6.0"
|
||||||
|
thiserror = "2.0.11"
|
38
README.md
38
README.md
@ -1,2 +1,40 @@
|
|||||||
# keydisplay
|
# keydisplay
|
||||||
|
note: you will need to add yourself to the input group or run as root if you intend to use wayland
|
||||||
|
|
||||||
|
you can do it like this
|
||||||
|
|
||||||
|
`doas usermod -aG input $USER`
|
||||||
|
|
||||||
|
## config.rs
|
||||||
|
- use serde with a config struct
|
||||||
|
|
||||||
|
- impl with defaults and read function
|
||||||
|
|
||||||
|
### read:
|
||||||
|
- get the current users config folder
|
||||||
|
|
||||||
|
- make a folder if the "keydisplay" folder doesnt exist
|
||||||
|
|
||||||
|
- make a keydisplay/config.toml if it doesnt exist
|
||||||
|
|
||||||
|
- give it 600 permissions
|
||||||
|
|
||||||
|
config:
|
||||||
|
- theme = {catppuccin_mocha, grey, night, day}
|
||||||
|
- [listen]
|
||||||
|
- - keys = "z, x"
|
||||||
|
- - mouse = "m1, m2"
|
||||||
|
- [display]
|
||||||
|
- - mouse = "key"
|
||||||
|
|
||||||
|
## listen.rs
|
||||||
|
- use inputbot to listen for inputs https://github.com/obv-mikhail/InputBot
|
||||||
|
|
||||||
|
- keys you can use are here https://docs.rs/inputbot/latest/src/inputbot/public.rs.html#300-352
|
||||||
|
|
||||||
|
## main.rs
|
||||||
|
- read config
|
||||||
|
|
||||||
|
- start listener on keys from config
|
||||||
|
|
||||||
|
- load gui using theme
|
||||||
|
95
src/config.rs
Normal file
95
src/config.rs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum ConfigError {
|
||||||
|
#[error("Failed to read config file: {0}")]
|
||||||
|
FileRead(#[from] std::io::Error),
|
||||||
|
#[error("Failed to parse config file: {0}")]
|
||||||
|
Parse(#[from] toml::ser::Error),
|
||||||
|
#[error("Failed to parse config file: {0}")]
|
||||||
|
ParseDeserialise(#[from] toml::de::Error),
|
||||||
|
#[error("Failed to write config file: {0}")]
|
||||||
|
FileWrite(std::io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
// theme = grey / night / day / catppuccin_mocha
|
||||||
|
pub theme: String,
|
||||||
|
pub listen: ListenConfig,
|
||||||
|
pub display: DisplayConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
// [listen]
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ListenConfig {
|
||||||
|
// keys = ["KeyZ", "KeyX"]
|
||||||
|
pub keys: Vec<String>,
|
||||||
|
// mouse = ["LeftButton", "RightButton"]
|
||||||
|
pub mouse: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// [display]
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct DisplayConfig {
|
||||||
|
pub mouse: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
// Provide default values
|
||||||
|
pub fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
theme: "grey".to_string(),
|
||||||
|
listen: ListenConfig {
|
||||||
|
keys: vec!["ZKey".to_string(), "XKey".to_string()],
|
||||||
|
mouse: vec!["LeftButton".to_string(), "RightButton".to_string()],
|
||||||
|
},
|
||||||
|
display: DisplayConfig {
|
||||||
|
mouse: "key".to_string(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load config from a file, creating it with defaults if it doesn't exist
|
||||||
|
pub fn load_or_create(path: PathBuf) -> Result<Self, ConfigError> {
|
||||||
|
let full_path = path.join("config.toml");
|
||||||
|
|
||||||
|
if !full_path.exists() {
|
||||||
|
println!("Creating default config");
|
||||||
|
let config = Self::default();
|
||||||
|
|
||||||
|
fs::create_dir_all(&path)?;
|
||||||
|
|
||||||
|
config.save(&full_path)?;
|
||||||
|
return Ok(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Loading default config from {full_path:?}");
|
||||||
|
let content = fs::read_to_string(&full_path)?;
|
||||||
|
let config: Config = toml::from_str(&content)?;
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save config to a file
|
||||||
|
pub fn save(&self, path: &PathBuf) -> Result<(), ConfigError> {
|
||||||
|
let content = toml::to_string_pretty(&self).map_err(|e| ConfigError::Parse(e))?;
|
||||||
|
|
||||||
|
fs::write(path, content).map_err(ConfigError::FileWrite)?;
|
||||||
|
|
||||||
|
// Ensure proper permissions on Unix-like systems
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
let mut perms = fs::metadata(path)
|
||||||
|
.map_err(ConfigError::FileWrite)?
|
||||||
|
.permissions();
|
||||||
|
perms.set_mode(0o600); // Read/write for owner only
|
||||||
|
fs::set_permissions(path, perms).map_err(ConfigError::FileWrite)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
318
src/listen.rs
Normal file
318
src/listen.rs
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use inputbot::{KeybdKey, KeybdKey::*, MouseButton, MouseButton::*};
|
||||||
|
|
||||||
|
pub fn listen(keys: Vec<KeybdKey>, m_buttons: Vec<MouseButton>) {
|
||||||
|
for key in keys {
|
||||||
|
key.bind(move || {
|
||||||
|
recieve_key_press(key);
|
||||||
|
while key.is_pressed() {
|
||||||
|
// theres probably a better way to do this
|
||||||
|
}
|
||||||
|
recieve_key_release(key);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for button in m_buttons {
|
||||||
|
button.bind(move || {
|
||||||
|
recieve_mouse_press(button);
|
||||||
|
while button.is_pressed() {}
|
||||||
|
recieve_mouse_release(button);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
MiddleButton.bind(|| {
|
||||||
|
println!("aaa");
|
||||||
|
});
|
||||||
|
|
||||||
|
inputbot::handle_input_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
// move me into gui.rs later
|
||||||
|
fn recieve_key_press(key: KeybdKey) {
|
||||||
|
println!("pressed {}", string_from_keybdkey(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recieve_key_release(key: KeybdKey) {
|
||||||
|
println!("released {}", string_from_keybdkey(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recieve_mouse_press(button: MouseButton) {
|
||||||
|
println!("pressed {}", string_from_mousebutton(button));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recieve_mouse_release(button: MouseButton) {
|
||||||
|
println!("released {}", string_from_mousebutton(button));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn keybdkey_from_config(key: &str) -> KeybdKey {
|
||||||
|
match key {
|
||||||
|
"BackspaceKey" => BackspaceKey,
|
||||||
|
"TabKey" => TabKey,
|
||||||
|
"EnterKey" => EnterKey,
|
||||||
|
"EscapeKey" => EscapeKey,
|
||||||
|
"SpaceKey" => EscapeKey,
|
||||||
|
"PageUpKey" => PageUpKey,
|
||||||
|
"PageDownKey" => PageDownKey,
|
||||||
|
"EndKey" => EndKey,
|
||||||
|
"HomeKey" => HomeKey,
|
||||||
|
"LeftKey" => LeftKey,
|
||||||
|
"UpKey" => UpKey,
|
||||||
|
"RightKey" => RightKey,
|
||||||
|
"DownKey" => DownKey,
|
||||||
|
"InsertKey" => InsertKey,
|
||||||
|
"DeleteKey" => DeleteKey,
|
||||||
|
"Numrow0Key" => Numrow0Key,
|
||||||
|
"Numrow1Key" => Numrow1Key,
|
||||||
|
"Numrow2Key" => Numrow2Key,
|
||||||
|
"Numrow3Key" => Numrow3Key,
|
||||||
|
"Numrow4Key" => Numrow4Key,
|
||||||
|
"Numrow5Key" => Numrow5Key,
|
||||||
|
"Numrow6Key" => Numrow6Key,
|
||||||
|
"Numrow7Key" => Numrow7Key,
|
||||||
|
"Numrow8Key" => Numrow8Key,
|
||||||
|
"Numrow9Key" => Numrow9Key,
|
||||||
|
"AKey" => AKey,
|
||||||
|
"BKey" => BKey,
|
||||||
|
"CKey" => CKey,
|
||||||
|
"DKey" => DKey,
|
||||||
|
"EKey" => EKey,
|
||||||
|
"FKey" => FKey,
|
||||||
|
"GKey" => GKey,
|
||||||
|
"HKey" => HKey,
|
||||||
|
"IKey" => IKey,
|
||||||
|
"JKey" => JKey,
|
||||||
|
"KKey" => KKey,
|
||||||
|
"LKey" => LKey,
|
||||||
|
"MKey" => MKey,
|
||||||
|
"NKey" => NKey,
|
||||||
|
"OKey" => OKey,
|
||||||
|
"PKey" => PKey,
|
||||||
|
"QKey" => QKey,
|
||||||
|
"RKey" => RKey,
|
||||||
|
"SKey" => SKey,
|
||||||
|
"TKey" => TKey,
|
||||||
|
"UKey" => UKey,
|
||||||
|
"VKey" => VKey,
|
||||||
|
"WKey" => WKey,
|
||||||
|
"XKey" => XKey,
|
||||||
|
"YKey" => YKey,
|
||||||
|
"ZKey" => ZKey,
|
||||||
|
"LSuper" => LSuper,
|
||||||
|
"RSuper" => RSuper,
|
||||||
|
"Numpad0Key" => Numpad0Key,
|
||||||
|
"Numpad1Key" => Numpad1Key,
|
||||||
|
"Numpad2Key" => Numpad2Key,
|
||||||
|
"Numpad3Key" => Numpad3Key,
|
||||||
|
"Numpad4Key" => Numpad4Key,
|
||||||
|
"Numpad5Key" => Numpad5Key,
|
||||||
|
"Numpad6Key" => Numpad6Key,
|
||||||
|
"Numpad7Key" => Numpad7Key,
|
||||||
|
"Numpad8Key" => Numpad8Key,
|
||||||
|
"Numpad9Key" => Numpad9Key,
|
||||||
|
"F1Key" => F1Key,
|
||||||
|
"F2Key" => F2Key,
|
||||||
|
"F3Key" => F3Key,
|
||||||
|
"F4Key" => F4Key,
|
||||||
|
"F5Key" => F5Key,
|
||||||
|
"F6Key" => F6Key,
|
||||||
|
"F7Key" => F7Key,
|
||||||
|
"F8Key" => F8Key,
|
||||||
|
"F9Key" => F9Key,
|
||||||
|
"F10Key" => F10Key,
|
||||||
|
"F11Key" => F11Key,
|
||||||
|
"F12Key" => F12Key,
|
||||||
|
"F13Key" => F13Key,
|
||||||
|
"F14Key" => F14Key,
|
||||||
|
"F15Key" => F15Key,
|
||||||
|
"F16Key" => F16Key,
|
||||||
|
"F17Key" => F17Key,
|
||||||
|
"F18Key" => F18Key,
|
||||||
|
"F19Key" => F19Key,
|
||||||
|
"F20Key" => F20Key,
|
||||||
|
"F21Key" => F21Key,
|
||||||
|
"F22Key" => F22Key,
|
||||||
|
"F23Key" => F23Key,
|
||||||
|
"F24Key" => F24Key,
|
||||||
|
"NumLockKey" => NumLockKey,
|
||||||
|
"ScrollLockKey" => ScrollLockKey,
|
||||||
|
"CapsLockKey" => CapsLockKey,
|
||||||
|
"LShiftKey" => LShiftKey,
|
||||||
|
"RShiftKey" => RShiftKey,
|
||||||
|
"LControlKey" => LControlKey,
|
||||||
|
"RControlKey" => RControlKey,
|
||||||
|
"LAltKey" => LAltKey,
|
||||||
|
"RAltKey" => RAltKey,
|
||||||
|
|
||||||
|
"BrowserBackKey" => BrowserBackKey,
|
||||||
|
"BrowserForwardKey" => BrowserForwardKey,
|
||||||
|
"BrowserRefreshKey" => BrowserRefreshKey,
|
||||||
|
|
||||||
|
"VolumeMuteKey" => VolumeMuteKey,
|
||||||
|
"VolumeDownKey" => VolumeDownKey,
|
||||||
|
"VolumeUpKey" => VolumeUpKey,
|
||||||
|
|
||||||
|
"MediaNextTrackKey" => MediaNextTrackKey,
|
||||||
|
"MediaPrevTrackKey" => MediaPrevTrackKey,
|
||||||
|
"MediaStopKey" => MediaStopKey,
|
||||||
|
"MediaPlayPauseKey" => MediaPlayPauseKey,
|
||||||
|
|
||||||
|
"BackquoteKey" => BackquoteKey,
|
||||||
|
"SlashKey" => SlashKey,
|
||||||
|
"BackslashKey" => BackslashKey,
|
||||||
|
"CommaKey" => CommaKey,
|
||||||
|
"PeriodKey" => PeriodKey,
|
||||||
|
"MinusKey" => MinusKey,
|
||||||
|
"QuoteKey" => QuoteKey,
|
||||||
|
"SemicolonKey" => SemicolonKey,
|
||||||
|
"LBracketKey" => LBracketKey,
|
||||||
|
"RBracketKey" => RBracketKey,
|
||||||
|
"EqualKey" => EqualKey,
|
||||||
|
_ => panic!("invalid keycode!"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn string_from_keybdkey(key: KeybdKey) -> String {
|
||||||
|
match key {
|
||||||
|
BackspaceKey => String::from("🡐"),
|
||||||
|
TabKey => String::from("⇌"),
|
||||||
|
EnterKey => String::from("⮠"),
|
||||||
|
EscapeKey => String::from("ESC"),
|
||||||
|
SpaceKey => String::from(""),
|
||||||
|
PageUpKey => String::from("PGUP"),
|
||||||
|
PageDownKey => String::from("PGDN"),
|
||||||
|
EndKey => String::from("END"),
|
||||||
|
HomeKey => String::from("HOME"),
|
||||||
|
LeftKey => String::from("⯇"),
|
||||||
|
UpKey => String::from("⯅"),
|
||||||
|
RightKey => String::from("⯈"),
|
||||||
|
DownKey => String::from("⯆"),
|
||||||
|
InsertKey => String::from("INS"),
|
||||||
|
DeleteKey => String::from("DEL"),
|
||||||
|
Numrow0Key => String::from("0"),
|
||||||
|
Numrow1Key => String::from("1"),
|
||||||
|
Numrow2Key => String::from("2"),
|
||||||
|
Numrow3Key => String::from("3"),
|
||||||
|
Numrow4Key => String::from("4"),
|
||||||
|
Numrow5Key => String::from("5"),
|
||||||
|
Numrow6Key => String::from("6"),
|
||||||
|
Numrow7Key => String::from("7"),
|
||||||
|
Numrow8Key => String::from("8"),
|
||||||
|
Numrow9Key => String::from("9"),
|
||||||
|
AKey => String::from("A"),
|
||||||
|
BKey => String::from("B"),
|
||||||
|
CKey => String::from("C"),
|
||||||
|
DKey => String::from("D"),
|
||||||
|
EKey => String::from("E"),
|
||||||
|
FKey => String::from("F"),
|
||||||
|
GKey => String::from("G"),
|
||||||
|
HKey => String::from("H"),
|
||||||
|
IKey => String::from("I"),
|
||||||
|
JKey => String::from("J"),
|
||||||
|
KKey => String::from("K"),
|
||||||
|
LKey => String::from("L"),
|
||||||
|
MKey => String::from("M"),
|
||||||
|
NKey => String::from("N"),
|
||||||
|
OKey => String::from("O"),
|
||||||
|
PKey => String::from("P"),
|
||||||
|
QKey => String::from("Q"),
|
||||||
|
RKey => String::from("R"),
|
||||||
|
SKey => String::from("S"),
|
||||||
|
TKey => String::from("T"),
|
||||||
|
UKey => String::from("U"),
|
||||||
|
VKey => String::from("V"),
|
||||||
|
WKey => String::from("W"),
|
||||||
|
XKey => String::from("X"),
|
||||||
|
YKey => String::from("Y"),
|
||||||
|
ZKey => String::from("Z"),
|
||||||
|
LSuper => String::from("SUPER"),
|
||||||
|
RSuper => String::from("SUPER"),
|
||||||
|
Numpad0Key => String::from("0"),
|
||||||
|
Numpad1Key => String::from("1"),
|
||||||
|
Numpad2Key => String::from("2"),
|
||||||
|
Numpad3Key => String::from("3"),
|
||||||
|
Numpad4Key => String::from("4"),
|
||||||
|
Numpad5Key => String::from("5"),
|
||||||
|
Numpad6Key => String::from("6"),
|
||||||
|
Numpad7Key => String::from("7"),
|
||||||
|
Numpad8Key => String::from("8"),
|
||||||
|
Numpad9Key => String::from("9"),
|
||||||
|
F1Key => String::from("F1"),
|
||||||
|
F2Key => String::from("F2"),
|
||||||
|
F3Key => String::from("F3"),
|
||||||
|
F4Key => String::from("F4"),
|
||||||
|
F5Key => String::from("F5"),
|
||||||
|
F6Key => String::from("F6"),
|
||||||
|
F7Key => String::from("F7"),
|
||||||
|
F8Key => String::from("F8"),
|
||||||
|
F9Key => String::from("F9"),
|
||||||
|
F10Key => String::from("F10"),
|
||||||
|
F11Key => String::from("F11"),
|
||||||
|
F12Key => String::from("F12"),
|
||||||
|
F13Key => String::from("F13"),
|
||||||
|
F14Key => String::from("F14"),
|
||||||
|
F15Key => String::from("F15"),
|
||||||
|
F16Key => String::from("F16"),
|
||||||
|
F17Key => String::from("F17"),
|
||||||
|
F18Key => String::from("F18"),
|
||||||
|
F19Key => String::from("F19"),
|
||||||
|
F20Key => String::from("F20"),
|
||||||
|
F21Key => String::from("F21"),
|
||||||
|
F22Key => String::from("F22"),
|
||||||
|
F23Key => String::from("F23"),
|
||||||
|
F24Key => String::from("F24"),
|
||||||
|
NumLockKey => String::from("Num\nLock"),
|
||||||
|
ScrollLockKey => String::from("Scroll\nLock"),
|
||||||
|
CapsLockKey => String::from("CAPS"),
|
||||||
|
LShiftKey => String::from("SHIFT"),
|
||||||
|
RShiftKey => String::from("SHIFT"),
|
||||||
|
LControlKey => String::from("CTRL"),
|
||||||
|
RControlKey => String::from("CTRL"),
|
||||||
|
LAltKey => String::from("ALT"),
|
||||||
|
RAltKey => String::from("ALT"),
|
||||||
|
BrowserBackKey => String::from("🡨"),
|
||||||
|
BrowserForwardKey => String::from("🡪"),
|
||||||
|
BrowserRefreshKey => String::from("⟳"),
|
||||||
|
VolumeMuteKey => String::from("🔊"),
|
||||||
|
VolumeDownKey => String::from("🔉"),
|
||||||
|
VolumeUpKey => String::from("🔈+"),
|
||||||
|
MediaNextTrackKey => String::from("⏭"),
|
||||||
|
MediaPrevTrackKey => String::from("⏮"),
|
||||||
|
MediaStopKey => String::from("⏹ "),
|
||||||
|
MediaPlayPauseKey => String::from("⏵"),
|
||||||
|
BackquoteKey => String::from("`"),
|
||||||
|
SlashKey => String::from("/"),
|
||||||
|
BackslashKey => String::from("\\"),
|
||||||
|
CommaKey => String::from(","),
|
||||||
|
PeriodKey => String::from("."),
|
||||||
|
MinusKey => String::from("-"),
|
||||||
|
QuoteKey => String::from("\""),
|
||||||
|
SemicolonKey => String::from(";"),
|
||||||
|
LBracketKey => String::from("("),
|
||||||
|
RBracketKey => String::from("),"),
|
||||||
|
EqualKey => String::from("="),
|
||||||
|
_ => panic!("invalid keycode!"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mousebutton_from_config(button: &str) -> MouseButton {
|
||||||
|
match button {
|
||||||
|
"LeftButton" => LeftButton,
|
||||||
|
"MiddleButton" => MiddleButton,
|
||||||
|
"RightButton" => RightButton,
|
||||||
|
_ => {
|
||||||
|
panic!("invalid mouse button! (InputBot hasn't implemented it or your config is wrong)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn string_from_mousebutton(button: MouseButton) -> String {
|
||||||
|
match button {
|
||||||
|
LeftButton => String::from("M1"),
|
||||||
|
MiddleButton => String::from("M3"),
|
||||||
|
RightButton => String::from("M2"),
|
||||||
|
_ => {
|
||||||
|
panic!("invalid mouse button! (InputBot hasn't implemented it or your config is wrong)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
src/main.rs
Normal file
27
src/main.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use inputbot::{get_keybd_key, KeybdKey, KeybdKeyIter, MouseButton};
|
||||||
|
|
||||||
|
mod config;
|
||||||
|
mod listen;
|
||||||
|
|
||||||
|
fn main() -> Result<(), config::ConfigError> {
|
||||||
|
println!("Hello, world!");
|
||||||
|
let config_dir = dirs::config_dir().expect("Config directory not found");
|
||||||
|
let keydisplay_dir = config_dir.join("keydisplay");
|
||||||
|
|
||||||
|
let config = config::Config::load_or_create(keydisplay_dir)?;
|
||||||
|
|
||||||
|
let mut config_to_keys: Vec<KeybdKey> = Vec::new();
|
||||||
|
for key in config.listen.keys {
|
||||||
|
// rust is magic 😍 🦀
|
||||||
|
config_to_keys.push(listen::keybdkey_from_config(&key));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut config_to_mouse: Vec<MouseButton> = Vec::new();
|
||||||
|
for button in config.listen.mouse {
|
||||||
|
config_to_mouse.push(listen::mousebutton_from_config(&button));
|
||||||
|
}
|
||||||
|
|
||||||
|
listen::listen(config_to_keys, config_to_mouse);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user