From 9975c878735eb680dd06f6764dba66a40fa8e2d9 Mon Sep 17 00:00:00 2001 From: jtroo Date: Sat, 14 Sep 2024 21:52:01 -0700 Subject: [PATCH 1/4] bus type --- parser/src/cfg/defcfg.rs | 27 +++++++++++++++++++-------- src/kanata/mod.rs | 5 +++++ src/oskbd/linux.rs | 9 +++++++-- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/parser/src/cfg/defcfg.rs b/parser/src/cfg/defcfg.rs index 39d51e7d7..6cef2dbc8 100644 --- a/parser/src/cfg/defcfg.rs +++ b/parser/src/cfg/defcfg.rs @@ -9,22 +9,15 @@ use crate::{anyhow_expr, anyhow_span, bail, bail_expr, bail_span}; #[cfg(any(target_os = "linux", target_os = "unknown"))] #[derive(Debug, Clone)] pub struct CfgLinuxOptions { - #[cfg(any(target_os = "linux", target_os = "unknown"))] pub linux_dev: Vec, - #[cfg(any(target_os = "linux", target_os = "unknown"))] pub linux_dev_names_include: Option>, - #[cfg(any(target_os = "linux", target_os = "unknown"))] pub linux_dev_names_exclude: Option>, - #[cfg(any(target_os = "linux", target_os = "unknown"))] pub linux_continue_if_no_devs_found: bool, - #[cfg(any(target_os = "linux", target_os = "unknown"))] pub linux_unicode_u_code: crate::keys::OsCode, - #[cfg(any(target_os = "linux", target_os = "unknown"))] pub linux_unicode_termination: UnicodeTermination, - #[cfg(any(target_os = "linux", target_os = "unknown"))] pub linux_x11_repeat_delay_rate: Option, - #[cfg(any(target_os = "linux", target_os = "unknown"))] pub linux_use_trackpoint_property: bool, + pub linux_output_bus_type: LinuxCfgOutputBusType, } #[cfg(any(target_os = "linux", target_os = "unknown"))] impl Default for CfgLinuxOptions { @@ -40,9 +33,15 @@ impl Default for CfgLinuxOptions { linux_unicode_termination: UnicodeTermination::Enter, linux_x11_repeat_delay_rate: None, linux_use_trackpoint_property: false, + linux_output_bus_type: BUS_I8042, } } } +#[cfg(any(target_os = "linux", target_os = "unknown"))] +pub enum LinuxCfgOutputBusType { + BUS_USB, + BUS_I8042, +} #[cfg(any( all(feature = "interception_driver", target_os = "windows"), @@ -311,6 +310,18 @@ pub fn parse_defcfg(expr: &[SExpr]) -> Result { parse_defcfg_val_bool(val, label)? } } + "linux-kanata-output-device-bus-type" => { + #[cfg(any(target_os = "linux", target_os = "unknown"))] + { + let bus_type_expr = sexpr_to_str_or_err(val, label)?; + let bus_type = match bus_type { + "USB" => LinuxCfgOutputBusType::BUS_USB, + "I8042" => LinuxCfgOutputBusType::BUS_I8042, + _ => bail_expr!(bus_type_expr, "Invalid value for linux-kanata-output-device-bus-type.\nExpected one of: USB or I8042"), + }; + cfg.linux_opts.linux_output_bus_type = bus_type; + } + } "windows-altgr" => { #[cfg(any(target_os = "windows", target_os = "unknown"))] { diff --git a/src/kanata/mod.rs b/src/kanata/mod.rs index f4a898ad5..22f0a716a 100755 --- a/src/kanata/mod.rs +++ b/src/kanata/mod.rs @@ -286,6 +286,11 @@ impl Kanata { &args.symlink_path, #[cfg(target_os = "linux")] cfg.options.linux_opts.linux_use_trackpoint_property, + #[cfg(target_os = "linux")] + match cfg.options.linux_opts.linux_output_bus_type { + LinuxCfgOutputBusType::BUS_USB => BUS_TYPE::BUS_USB, + LinuxCfgOutputBusType::BUS_I8042 => BUS_TYPE::BUS_I8042, + }, ) { Ok(kbd_out) => kbd_out, Err(err) => { diff --git a/src/oskbd/linux.rs b/src/oskbd/linux.rs index d18e39396..eb4d153cc 100644 --- a/src/oskbd/linux.rs +++ b/src/oskbd/linux.rs @@ -2,6 +2,7 @@ #![cfg_attr(feature = "simulated_output", allow(dead_code, unused_imports))] +pub use evdev::BusType; use evdev::{uinput, Device, EventType, InputEvent, PropType, RelativeAxisType}; use inotify::{Inotify, WatchMask}; use mio::{unix::SourceFd, Events, Interest, Poll, Token}; @@ -324,7 +325,11 @@ pub struct KbdOut { #[cfg(all(not(feature = "simulated_output"), not(feature = "passthru_ahk")))] impl KbdOut { - pub fn new(symlink_path: &Option, trackpoint: bool) -> Result { + pub fn new( + symlink_path: &Option, + trackpoint: bool, + bus_type: BusType, + ) -> Result { // Support pretty much every feature of a Keyboard or a Mouse in a VirtualDevice so that no event from the original input devices gets lost // TODO investigate the rare possibility that a device is e.g. a Joystick and a Keyboard or a Mouse at the same time, which could lead to lost events @@ -349,7 +354,7 @@ impl KbdOut { .name("kanata") // libinput's "disable while typing" feature don't work when bus_type // is set to BUS_USB, but appears to work when it's set to BUS_I8042. - .input_id(evdev::InputId::new(evdev::BusType::BUS_I8042, 1, 1, 1)) + .input_id(evdev::InputId::new(bus_type, 1, 1, 1)) .with_keys(&keys)? .with_relative_axes(&relative_axes)?; let device = if trackpoint { From 974de1025049f0ff112d302d12f42b7057dea8c2 Mon Sep 17 00:00:00 2001 From: jtroo Date: Sat, 14 Sep 2024 22:02:21 -0700 Subject: [PATCH 2/4] fix after dev on linux --- parser/src/cfg/defcfg.rs | 15 ++++++++------- src/kanata/mod.rs | 9 +++++++-- src/oskbd/simulated.rs | 6 +++++- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/parser/src/cfg/defcfg.rs b/parser/src/cfg/defcfg.rs index 6cef2dbc8..f05a1a783 100644 --- a/parser/src/cfg/defcfg.rs +++ b/parser/src/cfg/defcfg.rs @@ -33,14 +33,15 @@ impl Default for CfgLinuxOptions { linux_unicode_termination: UnicodeTermination::Enter, linux_x11_repeat_delay_rate: None, linux_use_trackpoint_property: false, - linux_output_bus_type: BUS_I8042, + linux_output_bus_type: LinuxCfgOutputBusType::BusI8042, } } } #[cfg(any(target_os = "linux", target_os = "unknown"))] +#[derive(Debug, Clone, Copy)] pub enum LinuxCfgOutputBusType { - BUS_USB, - BUS_I8042, + BusUsb, + BusI8042, } #[cfg(any( @@ -313,11 +314,11 @@ pub fn parse_defcfg(expr: &[SExpr]) -> Result { "linux-kanata-output-device-bus-type" => { #[cfg(any(target_os = "linux", target_os = "unknown"))] { - let bus_type_expr = sexpr_to_str_or_err(val, label)?; + let bus_type = sexpr_to_str_or_err(val, label)?; let bus_type = match bus_type { - "USB" => LinuxCfgOutputBusType::BUS_USB, - "I8042" => LinuxCfgOutputBusType::BUS_I8042, - _ => bail_expr!(bus_type_expr, "Invalid value for linux-kanata-output-device-bus-type.\nExpected one of: USB or I8042"), + "USB" => LinuxCfgOutputBusType::BusUsb, + "I8042" => LinuxCfgOutputBusType::BusI8042, + _ => bail_expr!(val, "Invalid value for linux-kanata-output-device-bus-type.\nExpected one of: USB or I8042"), }; cfg.linux_opts.linux_output_bus_type = bus_type; } diff --git a/src/kanata/mod.rs b/src/kanata/mod.rs index 22f0a716a..f9d28c3f9 100755 --- a/src/kanata/mod.rs +++ b/src/kanata/mod.rs @@ -288,8 +288,8 @@ impl Kanata { cfg.options.linux_opts.linux_use_trackpoint_property, #[cfg(target_os = "linux")] match cfg.options.linux_opts.linux_output_bus_type { - LinuxCfgOutputBusType::BUS_USB => BUS_TYPE::BUS_USB, - LinuxCfgOutputBusType::BUS_I8042 => BUS_TYPE::BUS_I8042, + LinuxCfgOutputBusType::BusUsb => evdev::BusType::BUS_USB, + LinuxCfgOutputBusType::BusI8042 => evdev::BusType::BUS_I8042, }, ) { Ok(kbd_out) => kbd_out, @@ -426,6 +426,11 @@ impl Kanata { &None, #[cfg(target_os = "linux")] cfg.options.linux_opts.linux_use_trackpoint_property, + #[cfg(target_os = "linux")] + match cfg.options.linux_opts.linux_output_bus_type { + LinuxCfgOutputBusType::BusUsb => evdev::BusType::BUS_USB, + LinuxCfgOutputBusType::BusI8042 => evdev::BusType::BUS_I8042, + }, ) { Ok(kbd_out) => kbd_out, Err(err) => { diff --git a/src/oskbd/simulated.rs b/src/oskbd/simulated.rs index ac4086607..759c320f0 100644 --- a/src/oskbd/simulated.rs +++ b/src/oskbd/simulated.rs @@ -353,7 +353,11 @@ impl KbdOut { Self::new_actual() } #[cfg(target_os = "linux")] - pub fn new(_s: &Option, _tp: bool) -> Result { + pub fn new( + _s: &Option, + _tp: bool, + _bustype: evdev::BusType, + ) -> Result { Self::new_actual() } #[cfg(target_os = "linux")] From 755b9794e506246e76278f3e147d68207b359687 Mon Sep 17 00:00:00 2001 From: jtroo Date: Sat, 14 Sep 2024 22:17:14 -0700 Subject: [PATCH 3/4] doc, tests --- cfg_samples/kanata.kbd | 14 ++++++++++++-- docs/config.adoc | 18 ++++++++++++++++++ parser/src/cfg/defcfg.rs | 4 ++-- parser/src/cfg/tests.rs | 31 +++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/cfg_samples/kanata.kbd b/cfg_samples/kanata.kbd index 6c4bd4eae..361d76ae9 100644 --- a/cfg_samples/kanata.kbd +++ b/cfg_samples/kanata.kbd @@ -132,6 +132,16 @@ If you need help, please feel welcome to ask in the GitHub discussions. ;; ;; linux-unicode-termination space + ;; Kanata on Linux needs to declare a "bus type" for its evdev output device. + ;; The options are USB and I8042. The default is I8042. + ;; Using USB can break disable-touchpad-while-typing on Wayland. + ;; But using I8042 appears to break some other scenarios. Thus it is configurable. + ;; + ;; Examples: + ;; + ;; linux-output-device-bus-type USB + ;; linux-output-device-bus-type I8042 + ;; There is an optional configuration entry for Windows to help mitigate strange ;; behaviour of AltGr if your layout uses that. Uncomment one of the items below ;; to change what kanata does with the key. @@ -708,7 +718,7 @@ If you need help, please feel welcome to ask in the GitHub discussions. ;; ;; The command takes two extra arguments at the beginning ``, ;; and ``. `` controls where the name - ;; of the command is logged, as well as the success message and command + ;; of the command is logged, as well as the success message and command ;; stdout and stderr. ;; ;; `` is only used if there is a failure executing the initial @@ -729,7 +739,7 @@ If you need help, please feel welcome to ask in the GitHub discussions. ;; of the command and treats it as an S-Expression, similarly to `macro`. ;; However, only delays, keys, chords, and chorded lists are supported. ;; Other actions are not. - ;; + ;; ;; bash: type date-time as YYYY-MM-DD HH:MM ;; cmd-output-keys bash -c "date +'%F %R' | sed 's/./& /g' | sed 's/:/S-;/g' | sed 's/\(.\{20\}\)\(.*\)/\(\1 spc \2\)/'" ) diff --git a/docs/config.adoc b/docs/config.adoc index fab0eab60..4066213b4 100644 --- a/docs/config.adoc +++ b/docs/config.adoc @@ -2488,6 +2488,24 @@ changing their behavior as well. ) ---- +[[linux-only-linux-output-device-bus-type]] +=== Linux only: linux-output-device-bus-type +<> + +Kanata on Linux needs to declare a "bus type" for its evdev output device. +The options are `USB` and `I8042`, with the default as `I8042`. +Using USB can https://github.com/jtroo/kanata/pull/661[break disable-touchpad-while-typing on Wayland]. +But using I8042 appears to break https://github.com/jtroo/kanata/issues/1131[some other scenarios]. +Thus the output bus type is configurable. + +.Example: +[source] +---- +(defcfg + linux-output-device-bus-type USB +) +---- + [[macos-only-macos-dev-names-include]] === macOS only: macos-dev-names-include <> diff --git a/parser/src/cfg/defcfg.rs b/parser/src/cfg/defcfg.rs index f05a1a783..d57559a0d 100644 --- a/parser/src/cfg/defcfg.rs +++ b/parser/src/cfg/defcfg.rs @@ -311,14 +311,14 @@ pub fn parse_defcfg(expr: &[SExpr]) -> Result { parse_defcfg_val_bool(val, label)? } } - "linux-kanata-output-device-bus-type" => { + "linux-output-device-bus-type" => { #[cfg(any(target_os = "linux", target_os = "unknown"))] { let bus_type = sexpr_to_str_or_err(val, label)?; let bus_type = match bus_type { "USB" => LinuxCfgOutputBusType::BusUsb, "I8042" => LinuxCfgOutputBusType::BusI8042, - _ => bail_expr!(val, "Invalid value for linux-kanata-output-device-bus-type.\nExpected one of: USB or I8042"), + _ => bail_expr!(val, "Invalid value for linux-output-device-bus-type.\nExpected one of: USB or I8042"), }; cfg.linux_opts.linux_output_bus_type = bus_type; } diff --git a/parser/src/cfg/tests.rs b/parser/src/cfg/tests.rs index 8df52e2f4..bff39cb0b 100644 --- a/parser/src/cfg/tests.rs +++ b/parser/src/cfg/tests.rs @@ -1366,6 +1366,8 @@ fn parse_all_defcfg() { linux-unicode-u-code v linux-unicode-termination space linux-x11-repeat-delay-rate 400,50 + linux-use-trackpoint-property yes + linux-output-device-bus-type USB tray-icon symbols.ico icon-match-layer-name no tooltip-layer-changes yes @@ -1389,6 +1391,35 @@ fn parse_all_defcfg() { .expect("parses"); } +#[test] +fn parse_defcfg_linux_output_bus() { + let source = r#" +(defcfg linux-output-device-bus-type USB) +(defsrc a) +(deflayer base a) +"#; + parse_cfg(source) + .map_err(|e| eprintln!("{:?}", miette::Error::from(e))) + .expect("parses"); + let source = r#" +(defcfg linux-output-device-bus-type I8042) +(defsrc a) +(deflayer base a) +"#; + parse_cfg(source) + .map_err(|e| eprintln!("{:?}", miette::Error::from(e))) + .expect("parses"); + let source = r#" +(defcfg linux-output-device-bus-type INVALID) +(defsrc a) +(deflayer base a) +"#; + let err = parse_cfg(source).expect_err("should err"); + assert!(err + .msg + .contains("Invalid value for linux-output-device-bus-type")); +} + #[test] fn parse_unmod() { let source = r#" From d4c855f84987e51ae24c9e175bf18bc826a32c4f Mon Sep 17 00:00:00 2001 From: jtroo Date: Sat, 14 Sep 2024 22:23:22 -0700 Subject: [PATCH 4/4] fix tests on non-linux --- parser/src/cfg/defcfg.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/parser/src/cfg/defcfg.rs b/parser/src/cfg/defcfg.rs index d57559a0d..704e87fb7 100644 --- a/parser/src/cfg/defcfg.rs +++ b/parser/src/cfg/defcfg.rs @@ -312,13 +312,17 @@ pub fn parse_defcfg(expr: &[SExpr]) -> Result { } } "linux-output-device-bus-type" => { + let bus_type = sexpr_to_str_or_err(val, label)?; + match bus_type { + "USB" | "I8042" => {}, + _ => bail_expr!(val, "Invalid value for linux-output-device-bus-type.\nExpected one of: USB or I8042"), + }; #[cfg(any(target_os = "linux", target_os = "unknown"))] { - let bus_type = sexpr_to_str_or_err(val, label)?; let bus_type = match bus_type { "USB" => LinuxCfgOutputBusType::BusUsb, "I8042" => LinuxCfgOutputBusType::BusI8042, - _ => bail_expr!(val, "Invalid value for linux-output-device-bus-type.\nExpected one of: USB or I8042"), + _ => unreachable!("validated earlier"), }; cfg.linux_opts.linux_output_bus_type = bus_type; }