Implemented cursor and scroll movements through keys

This commit is contained in:
cyber-sushi 2024-12-24 18:32:49 +01:00
parent 07d5a8768d
commit 77d8a5d6ad
2 changed files with 305 additions and 2 deletions

View file

@ -60,6 +60,47 @@ impl FromStr for Axis {
} }
} }
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
pub enum Relative {
Cursor(Cursor),
Scroll(Scroll),
}
#[allow(non_camel_case_types)]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
pub enum Cursor {
CURSOR_UP,
CURSOR_DOWN,
CURSOR_LEFT,
CURSOR_RIGHT,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
pub enum Scroll {
SCROLL_UP,
SCROLL_DOWN,
SCROLL_LEFT,
SCROLL_RIGHT,
}
impl FromStr for Relative {
type Err = String;
fn from_str(s: &str) -> Result<Relative, Self::Err> {
match s {
"CURSOR_UP" => Ok(Relative::Cursor(Cursor::CURSOR_UP)),
"CURSOR_DOWN" => Ok(Relative::Cursor(Cursor::CURSOR_DOWN)),
"CURSOR_LEFT" => Ok(Relative::Cursor(Cursor::CURSOR_LEFT)),
"CURSOR_RIGHT" => Ok(Relative::Cursor(Cursor::CURSOR_RIGHT)),
"SCROLL_UP" => Ok(Relative::Scroll(Scroll::SCROLL_UP)),
"SCROLL_DOWN" => Ok(Relative::Scroll(Scroll::SCROLL_DOWN)),
"SCROLL_LEFT" => Ok(Relative::Scroll(Scroll::SCROLL_LEFT)),
"SCROLL_RIGHT" => Ok(Relative::Scroll(Scroll::SCROLL_RIGHT)),
_ => Err(s.to_string()),
}
}
}
#[derive(Debug, PartialEq, Eq, Default, Clone)] #[derive(Debug, PartialEq, Eq, Default, Clone)]
pub struct Associations { pub struct Associations {
pub client: Client, pub client: Client,
@ -70,6 +111,7 @@ pub struct Associations {
pub struct Bindings { pub struct Bindings {
pub remap: HashMap<Event, HashMap<Vec<Event>, Vec<Key>>>, pub remap: HashMap<Event, HashMap<Vec<Event>, Vec<Key>>>,
pub commands: HashMap<Event, HashMap<Vec<Event>, Vec<String>>>, pub commands: HashMap<Event, HashMap<Vec<Event>, Vec<String>>>,
pub movements: HashMap<Event, HashMap<Vec<Event>, Relative>>,
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
@ -86,6 +128,8 @@ pub struct RawConfig {
#[serde(default)] #[serde(default)]
pub commands: HashMap<String, Vec<String>>, pub commands: HashMap<String, Vec<String>>,
#[serde(default)] #[serde(default)]
pub movements: HashMap<String, String>,
#[serde(default)]
pub settings: HashMap<String, String>, pub settings: HashMap<String, String>,
} }
@ -100,10 +144,12 @@ impl RawConfig {
toml::from_str(&file_content).expect("Couldn't parse config file."); toml::from_str(&file_content).expect("Couldn't parse config file.");
let remap = raw_config.remap; let remap = raw_config.remap;
let commands = raw_config.commands; let commands = raw_config.commands;
let movements = raw_config.movements;
let settings = raw_config.settings; let settings = raw_config.settings;
Self { Self {
remap, remap,
commands, commands,
movements,
settings, settings,
} }
} }
@ -147,6 +193,7 @@ impl Config {
fn parse_raw_config(raw_config: RawConfig) -> (Bindings, HashMap<String, String>, MappedModifiers) { fn parse_raw_config(raw_config: RawConfig) -> (Bindings, HashMap<String, String>, MappedModifiers) {
let remap: HashMap<String, Vec<Key>> = raw_config.remap; let remap: HashMap<String, Vec<Key>> = raw_config.remap;
let commands: HashMap<String, Vec<String>> = raw_config.commands; let commands: HashMap<String, Vec<String>> = raw_config.commands;
let movements: HashMap<String, String> = raw_config.movements;
let settings: HashMap<String, String> = raw_config.settings; let settings: HashMap<String, String> = raw_config.settings;
let mut bindings: Bindings = Default::default(); let mut bindings: Bindings = Default::default();
let default_modifiers = vec![ let default_modifiers = vec![
@ -322,6 +369,82 @@ fn parse_raw_config(raw_config: RawConfig) -> (Bindings, HashMap<String, String>
} }
} }
for (input, output) in movements.clone() {
if let Some((mods, event)) = input.rsplit_once("-") {
let str_modifiers = mods.split("-").collect::<Vec<&str>>();
let mut modifiers: Vec<Event> = Vec::new();
for event in str_modifiers.clone() {
if let Ok(axis) = Axis::from_str(event) {
modifiers.push(Event::Axis(axis));
} else if let Ok(key) = Key::from_str(event) {
modifiers.push(Event::Key(key));
}
}
modifiers.sort();
modifiers.dedup();
for modifier in &modifiers {
if !mapped_modifiers.default.contains(&modifier) {
mapped_modifiers.custom.push(modifier.clone());
}
}
if str_modifiers[0] == "" {
modifiers.push(Event::Hold);
}
if let Ok(event) = Axis::from_str(event) {
if !bindings.movements.contains_key(&Event::Axis(event)) {
bindings
.movements
.insert(Event::Axis(event), HashMap::from([(modifiers, Relative::from_str(output.as_str()).expect("Invalid movement in [movements]."))]));
} else {
bindings
.movements
.get_mut(&Event::Axis(event))
.unwrap()
.insert(modifiers, Relative::from_str(output.as_str()).expect("Invalid movement in [movements]."));
}
} else if let Ok(event) = Key::from_str(event) {
if !bindings.movements.contains_key(&Event::Key(event)) {
bindings
.movements
.insert(Event::Key(event), HashMap::from([(modifiers, Relative::from_str(output.as_str()).expect("Invalid movement in [movements]."))]));
} else {
bindings
.movements
.get_mut(&Event::Key(event))
.unwrap()
.insert(modifiers, Relative::from_str(output.as_str()).expect("Invalid movement in [movements]."));
}
}
} else {
let modifiers: Vec<Event> = Vec::new();
if let Ok(event) = Axis::from_str(input.as_str()) {
if !bindings.movements.contains_key(&Event::Axis(event)) {
bindings
.movements
.insert(Event::Axis(event), HashMap::from([(modifiers, Relative::from_str(output.as_str()).expect("Invalid movement in [movements]."))]));
} else {
bindings
.movements
.get_mut(&Event::Axis(event))
.unwrap()
.insert(modifiers, Relative::from_str(output.as_str()).expect("Invalid movement in [movements]."));
}
} else if let Ok(event) = Key::from_str(input.as_str()) {
if !bindings.movements.contains_key(&Event::Key(event)) {
bindings
.movements
.insert(Event::Key(event), HashMap::from([(modifiers, Relative::from_str(output.as_str()).expect("Invalid movement in [movements]."))]));
} else {
bindings
.movements
.get_mut(&Event::Key(event))
.unwrap()
.insert(modifiers, Relative::from_str(output.as_str()).expect("Invalid movement in [movements]."));
}
}
}
}
mapped_modifiers.custom.sort(); mapped_modifiers.custom.sort();
mapped_modifiers.custom.dedup(); mapped_modifiers.custom.dedup();
mapped_modifiers mapped_modifiers

View file

@ -1,5 +1,5 @@
use crate::active_client::*; use crate::active_client::*;
use crate::config::{parse_modifiers, Associations, Axis, Event}; use crate::config::{parse_modifiers, Associations, Axis, Event, Relative, Cursor, Scroll};
use crate::udev_monitor::Environment; use crate::udev_monitor::Environment;
use crate::virtual_devices::VirtualDevices; use crate::virtual_devices::VirtualDevices;
use crate::Config; use crate::Config;
@ -23,6 +23,11 @@ struct Stick {
activation_modifiers: Vec<Event>, activation_modifiers: Vec<Event>,
} }
struct Movement {
speed: i32,
acceleration: f32,
}
struct Settings { struct Settings {
lstick: Stick, lstick: Stick,
rstick: Stick, rstick: Stick,
@ -30,6 +35,8 @@ struct Settings {
invert_scroll_axis: bool, invert_scroll_axis: bool,
axis_16_bit: bool, axis_16_bit: bool,
stadia: bool, stadia: bool,
cursor: Movement,
scroll: Movement,
chain_only: bool, chain_only: bool,
layout_switcher: Key, layout_switcher: Key,
notify_layout_switch: bool, notify_layout_switch: bool,
@ -41,6 +48,8 @@ pub struct EventReader {
virt_dev: Arc<Mutex<VirtualDevices>>, virt_dev: Arc<Mutex<VirtualDevices>>,
lstick_position: Arc<Mutex<Vec<i32>>>, lstick_position: Arc<Mutex<Vec<i32>>>,
rstick_position: Arc<Mutex<Vec<i32>>>, rstick_position: Arc<Mutex<Vec<i32>>>,
cursor_movement: Arc<Mutex<(i32, i32)>>,
scroll_movement: Arc<Mutex<(i32, i32)>>,
modifiers: Arc<Mutex<Vec<Event>>>, modifiers: Arc<Mutex<Vec<Event>>>,
modifier_was_activated: Arc<Mutex<bool>>, modifier_was_activated: Arc<Mutex<bool>>,
device_is_connected: Arc<Mutex<bool>>, device_is_connected: Arc<Mutex<bool>>,
@ -65,6 +74,8 @@ impl EventReader {
} }
let lstick_position = Arc::new(Mutex::new(position_vector.clone())); let lstick_position = Arc::new(Mutex::new(position_vector.clone()));
let rstick_position = Arc::new(Mutex::new(position_vector.clone())); let rstick_position = Arc::new(Mutex::new(position_vector.clone()));
let cursor_movement = Arc::new(Mutex::new((0, 0)));
let scroll_movement = Arc::new(Mutex::new((0, 0)));
let device_is_connected: Arc<Mutex<bool>> = Arc::new(Mutex::new(true)); let device_is_connected: Arc<Mutex<bool>> = Arc::new(Mutex::new(true));
let active_layout: Arc<Mutex<u16>> = Arc::new(Mutex::new(0)); let active_layout: Arc<Mutex<u16>> = Arc::new(Mutex::new(0));
let current_config: Arc<Mutex<Config>> = Arc::new(Mutex::new( let current_config: Arc<Mutex<Config>> = Arc::new(Mutex::new(
@ -206,6 +217,56 @@ impl EventReader {
.parse() .parse()
.expect("INVERT_SCROLL_AXIS can only be true or false."); .expect("INVERT_SCROLL_AXIS can only be true or false.");
let cursor_speed: i32 = config
.iter()
.find(|&x| x.associations == Associations::default())
.unwrap()
.settings
.get("CURSOR_SPEED")
.unwrap_or(&"0".to_string())
.parse()
.expect("Invalid value for CURSOR_SPEED, please use an integer value.");
let cursor_acceleration: f32 = config
.iter()
.find(|&x| x.associations == Associations::default())
.unwrap()
.settings
.get("CURSOR_ACCEL")
.unwrap_or(&"0".to_string())
.parse()
.expect("Invalid value for CURSOR_ACCEL, please use an float value between 0 and 1.");
let scroll_speed: i32 = config
.iter()
.find(|&x| x.associations == Associations::default())
.unwrap()
.settings
.get("SCROLL_SPEED")
.unwrap_or(&"0".to_string())
.parse()
.expect("Invalid value for SCROLL_SPEED, please use an integer value.");
let scroll_acceleration: f32 = config
.iter()
.find(|&x| x.associations == Associations::default())
.unwrap()
.settings
.get("SCROLL_ACCEL")
.unwrap_or(&"0".to_string())
.parse()
.expect("Invalid value for SCROLL_ACCEL, please use a float value between 0 and 1.");
let cursor = Movement {
speed: cursor_speed,
acceleration: cursor_acceleration,
};
let scroll = Movement {
speed: scroll_speed,
acceleration: scroll_acceleration,
};
let layout_switcher: Key = Key::from_str( let layout_switcher: Key = Key::from_str(
config config
.iter() .iter()
@ -234,6 +295,8 @@ impl EventReader {
invert_scroll_axis, invert_scroll_axis,
axis_16_bit, axis_16_bit,
stadia, stadia,
cursor,
scroll,
chain_only, chain_only,
layout_switcher, layout_switcher,
notify_layout_switch, notify_layout_switch,
@ -244,6 +307,8 @@ impl EventReader {
virt_dev, virt_dev,
lstick_position, lstick_position,
rstick_position, rstick_position,
cursor_movement,
scroll_movement,
modifiers, modifiers,
modifier_was_activated, modifier_was_activated,
device_is_connected, device_is_connected,
@ -263,7 +328,7 @@ impl EventReader {
.unwrap() .unwrap()
.name .name
); );
tokio::join!(self.event_loop(), self.cursor_loop(), self.scroll_loop(),); tokio::join!(self.event_loop(), self.cursor_loop(), self.scroll_loop(), self.key_cursor_loop(), self.key_scroll_loop());
} }
pub async fn event_loop(&self) { pub async fn event_loop(&self) {
@ -964,6 +1029,14 @@ impl EventReader {
return; return;
} }
} }
if let Some(map) = config.bindings.movements.get(&event) {
if let Some(movement) = map.get(&modifiers) {
if value <= 1 {
self.emit_movement(movement, value).await;
}
};
return;
}
if let Some(event_list) = map.get(&Vec::new()) { if let Some(event_list) = map.get(&Vec::new()) {
self.emit_event(event_list, value, &modifiers, &config, true, false) self.emit_event(event_list, value, &modifiers, &config, true, false)
.await; .await;
@ -983,6 +1056,14 @@ impl EventReader {
return; return;
} }
} }
if let Some(map) = config.bindings.movements.get(&event) {
if let Some(movement) = map.get(&modifiers) {
if value <= 1 {
self.emit_movement(movement, value).await;
}
};
return;
}
self.emit_nonmapped_event(default_event, event, value, &modifiers, &config) self.emit_nonmapped_event(default_event, event, value, &modifiers, &config)
.await; .await;
} }
@ -1117,6 +1198,21 @@ impl EventReader {
} }
} }
async fn emit_movement(&self, movement: &Relative, value: i32) {
let mut cursor_movement = self.cursor_movement.lock().await;
let mut scroll_movement = self.scroll_movement.lock().await;
match movement {
Relative::Cursor(Cursor::CURSOR_UP) => cursor_movement.1 = -value,
Relative::Cursor(Cursor::CURSOR_DOWN) => cursor_movement.1 = value,
Relative::Cursor(Cursor::CURSOR_LEFT) => cursor_movement.0 = -value,
Relative::Cursor(Cursor::CURSOR_RIGHT) => cursor_movement.0 = value,
Relative::Scroll(Scroll::SCROLL_UP) => scroll_movement.1 = -value,
Relative::Scroll(Scroll::SCROLL_DOWN) => scroll_movement.1 = value,
Relative::Scroll(Scroll::SCROLL_LEFT) => scroll_movement.0 = -value,
Relative::Scroll(Scroll::SCROLL_RIGHT) => scroll_movement.0 = value,
};
}
async fn spawn_subprocess(&self, command_list: &Vec<String>) { async fn spawn_subprocess(&self, command_list: &Vec<String>) {
let mut modifier_was_activated = self.modifier_was_activated.lock().await; let mut modifier_was_activated = self.modifier_was_activated.lock().await;
*modifier_was_activated = true; *modifier_was_activated = true;
@ -1348,4 +1444,88 @@ impl EventReader {
return; return;
} }
} }
pub async fn key_cursor_loop(&self) {
let (speed, acceleration, mut current_speed) = (
if self.settings.cursor.speed == 0 {
return
} else {
self.settings.cursor.speed
},
if self.settings.cursor.acceleration.abs() > 1.0 {
1.0
} else {
self.settings.cursor.acceleration.abs()
},
self.settings.cursor.speed as f32
);
while *self.device_is_connected.lock().await {
{
let cursor_movement = self.cursor_movement.lock().await;
if *cursor_movement == (0, 0) {
current_speed = 0.0
} else {
current_speed += speed as f32 * acceleration / 10.0;
if current_speed > speed as f32 {
current_speed = speed as f32
}
if cursor_movement.0 != 0 {
let mut virt_dev = self.virt_dev.lock().await;
let virtual_event_x: InputEvent =
InputEvent::new_now(EventType::RELATIVE, 0, cursor_movement.0 * current_speed as i32);
virt_dev.axis.emit(&[virtual_event_x]).unwrap();
}
if cursor_movement.1 != 0 {
let mut virt_dev = self.virt_dev.lock().await;
let virtual_event_y: InputEvent =
InputEvent::new_now(EventType::RELATIVE, 1, cursor_movement.1 * current_speed as i32);
virt_dev.axis.emit(&[virtual_event_y]).unwrap();
}
}
}
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
}
}
pub async fn key_scroll_loop(&self) {
let (speed, acceleration, mut current_speed) = (
if self.settings.scroll.speed == 0 {
return
} else {
self.settings.scroll.speed
},
if self.settings.scroll.acceleration.abs() > 1.0 {
1.0
} else {
self.settings.scroll.acceleration.abs()
},
self.settings.scroll.speed as f32
);
while *self.device_is_connected.lock().await {
{
let scroll_movement = self.scroll_movement.lock().await;
if *scroll_movement == (0, 0) {
current_speed = 0.0
} else {
current_speed += speed as f32 * acceleration / 10.0;
if current_speed > speed as f32 {
current_speed = speed as f32
}
if scroll_movement.0 != 0 {
let mut virt_dev = self.virt_dev.lock().await;
let virtual_event_x: InputEvent =
InputEvent::new_now(EventType::RELATIVE, 12, scroll_movement.0 * current_speed as i32);
virt_dev.axis.emit(&[virtual_event_x]).unwrap();
}
if scroll_movement.1 != 0 {
let mut virt_dev = self.virt_dev.lock().await;
let virtual_event_y: InputEvent =
InputEvent::new_now(EventType::RELATIVE, 11, scroll_movement.1 * current_speed as i32);
virt_dev.axis.emit(&[virtual_event_y]).unwrap();
}
}
}
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
}
}
} }