xremap / xremap

Key remapper for X11 and Wayland
MIT License
1.51k stars 85 forks source link

Infinite loop if a key is pressed down or mouse is moving when `xremap` starts #192

Open Frederick888 opened 2 years ago

Frederick888 commented 2 years ago

xremap version: 0.7.6

Command line: xremap --ignore='Yubico YubiKey OTP+FIDO+CCID' --mouse --watch=device "$HOME/.config/xremap/config.yml"

Config:

modmap:
  - name: Left Ctrl (Hard Mapped From Caps Lock) as Esc
    application:
      not: 
        - /^Minecraft/
    remap:
      Ctrl_L:
        held: Ctrl_L
        alone: Esc

I added below logs:

diff --git a/src/device.rs b/src/device.rs
index b2c5ad6..c281561 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -128,11 +128,11 @@ pub fn get_input_devices(
 }

 #[derive_where(PartialEq, PartialOrd, Ord)]
 pub struct InputDevice {
-    path: PathBuf,
+    pub path: PathBuf,
     #[derive_where(skip)]
-    device: Device,
+    pub device: Device,
 }

 impl Eq for InputDevice {}

diff --git a/src/main.rs b/src/main.rs
index 897df59..1119f9c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,8 +6,9 @@ use clap::{AppSettings, ArgEnum, IntoApp, Parser};
 use clap_complete::Shell;
 use config::{config_watcher, load_config};
 use device::InputDevice;
 use evdev::EventType;
+use log::debug;
 use nix::libc::ENODEV;
 use nix::sys::inotify::{AddWatchFlags, Inotify, InotifyEvent};
 use nix::sys::select::select;
 use nix::sys::select::FdSet;
@@ -203,13 +204,19 @@ fn handle_input_events(
     input_device: &mut InputDevice,
     handler: &mut EventHandler,
     config: &mut Config,
 ) -> anyhow::Result<bool> {
+    let device_name = input_device
+        .device
+        .name()
+        .map_or_else(|| "unknown".to_owned(), |n| n.to_owned());
     match input_device.fetch_events().map_err(|e| (e.raw_os_error(), e)) {
         Err((Some(ENODEV), _)) => Ok(false),
         Err((_, error)) => Err(error).context("Error fetching input events"),
         Ok(events) => {
+            debug!("Entering loop for device {}", device_name);
             for event in events {
+                debug!("Looping here! Event: {}, code: {}", event.event_type().0, event.code());
                 if event.event_type() == EventType::KEY {
                     handler
                         .on_event(event, config)
                         .map_err(|e| anyhow!("Failed handling {event:?}:\n  {e:?}"))?;

Regular startup (if I start typing or moving mouse after xremap starts):

/dev/input/event11: Logitech MX Master 3
/dev/input/event3 : AT Translated Set 2 keyboard
/dev/input/event9 : LEOPOLD LEO 98Keyboard
------------------------------------------------------------------------------
[2022-10-18T12:29:05Z DEBUG xremap] Entering loop for device Logitech MX Master 3
[2022-10-18T12:29:05Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:29:05Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:29:05Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:29:05Z DEBUG xremap] Entering loop for device AT Translated Set 2 keyboard
[2022-10-18T12:29:05Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:29:05Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:29:05Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:29:05Z DEBUG xremap] Entering loop for device LEOPOLD LEO 98Keyboard
[2022-10-18T12:29:05Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:29:05Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:29:08Z DEBUG xremap] Entering loop for device Logitech MX Master 3
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 2, code: 0
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:29:08Z DEBUG xremap] Entering loop for device Logitech MX Master 3
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 2, code: 0
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 2, code: 1
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:29:08Z DEBUG xremap] Entering loop for device Logitech MX Master 3
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 2, code: 0
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 2, code: 1
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:29:08Z DEBUG xremap] Entering loop for device Logitech MX Master 3
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 2, code: 0
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 2, code: 1
[2022-10-18T12:29:08Z DEBUG xremap] Looping here! Event: 0, code: 0

Log if I keep a key pressed down when xremap starts (and I can see the key keeps repeating later even after I've released the key):

/dev/input/event11: Logitech MX Master 3
/dev/input/event3 : AT Translated Set 2 keyboard
/dev/input/event9 : LEOPOLD LEO 98Keyboard
------------------------------------------------------------------------------
[2022-10-18T12:33:47Z DEBUG xremap] Entering loop for device LEOPOLD LEO 98Keyboard
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 1, code: 36
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] => 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 1, code: 36
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] => 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 1, code: 36
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] => 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 1, code: 36
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] => 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 1, code: 36
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] => 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:33:47Z DEBUG xremap] Looping here! Event: 1, code: 36
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] => 2: KEY_J
[2022-10-18T12:33:47Z DEBUG xremap::event_handler] 2: KEY_J

Log if I keep moving my mouse when xremap starts (the event is a 'force feedback status', which isn't even supported by my mouse an LED event. and CPU usage of xremap immediately shoots up to 100% in this case, freezing all my keyboards and mouse. I have to re-connect devices to regain control.):

/dev/input/event11: Logitech MX Master 3
/dev/input/event3 : AT Translated Set 2 keyboard
/dev/input/event9 : LEOPOLD LEO 98Keyboard
------------------------------------------------------------------------------
[2022-10-18T12:25:45Z DEBUG xremap] Entering loop for device Logitech MX Master 3
[2022-10-18T12:25:45Z DEBUG xremap] Entering loop for device AT Translated Set 2 keyboard
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Entering loop for device LEOPOLD LEO 98Keyboard
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 0, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Entering loop for device Logitech MX Master 3
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
[2022-10-18T12:25:45Z DEBUG xremap] Looping here! Event: 17, code: 0
k0kubun commented 2 years ago
Frederick888 commented 2 years ago

Sorry forgot to provide those info

I'm using X11/KDE on latest Arch Linux (regular kernel).

k0kubun commented 2 years ago

I can't reproduce the problem in my environment. I applied your patch, tried starting xremap with a mouse enabled while moving it, and tried starting xremap while pressing Enter forever. But none of them kept printing the logs you added.

Looking at https://bugs.freedesktop.org/show_bug.cgi?id=101796, it feels like this kind of thing is a problem that needs to be fixed on the driver's side, not xremap's, especially when you're using the bleeding-edge version on Arch Linux.

Because I cannot reproduce this issue on my end, there's no way to fix it for me. Could you provide a virtual machine (e.g. VirtualBox) and the minimum steps to reproduce the problem on it? If it's too hard or even it doesn't reproduce the issue in my environment, I need you to file a pull request yourself.

U1s2e3r4n5a6m7e commented 2 years ago

Same bug here. xremap 0.7.8 X11 Linux 6.0.1-arch2-1 #1 SMP PREEMPT_DYNAMIC Thu, 13 Oct 2022 18:58:49 +0000 x86_64 GNU/Linux

Part 1/2

Steps to reproduce

  1. Start xremap with Ctrl key on terminal: Ctrl+Enter

  2. Release Ctrl key

  3. Now you have Ctrl on every key press:

    • k -> Ctrl + k
  4. Press again Ctrl to release the Ctrl. Everything is fine now:

    • k -> k

Same bug for the Shift key. Probably Alt key too and other keys etc.

Part 2/2

Steps to reproduce

  1. xremap path/to/config
  2. suspend with Ctrl+z
    • Now you have:
      ------------------------------------------------------------------------------
      Selected keyboards automatically since --device options weren't specified:
      ------------------------------------------------------------------------------
      /dev/input/event2 : <Insert the keyboard here>
      ------------------------------------------------------------------------------
      ^Z
      zsh: suspended  xremap Documents/xremap.yml
      [USER@HOSTNAME ~]$ ^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z
      ^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z
      ^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z^Z  <IT DOESN'T STOP>
  3. physically Unplug and Plug the keyboard
  4. Stop the ^Z by pressing the Ctrl+c
distbit0 commented 11 months ago

Can also confirm this issue exists. I experienced it once when accidentally pressing the windows key while starting xremap, and another time when accidentally pressing the up arrow key.

This causes xremap to be unusable for me until it is fixed, as I run xremap periodically via a cronjob and hence can not guarantee that I am not holding down a key while it starts (I probably am).

k0kubun commented 11 months ago

Thanks for all the reports.

Now, I've learned from a friend that xremap could check which keys are currently pressed when xremap starts if you check the output of ioctl with that device and EVIOCGKEY. We need to integrate that evdev interface to fix the problem. At the moment I don't have the bandwidth to immediately write a patch myself, especially when I don't have this issue (I just automatically start xremap on boot, and I don't need to restart it), but I would merge a pull request to fix it if filed.