xremap icon indicating copy to clipboard operation
xremap copied to clipboard

Mouse wheel doesn't flush timeout keys

Open Frederick888 opened this issue 2 years ago • 5 comments

I currently have the configuration below:

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

When I hold left ctrl, I expect to be able to scroll my mouse wheel to zoom in/out in Firefox, GIMP, and etc.

However since EventType::RELATIVE is not captured by the main loop, I have to wait until the remap times out for Ctrl modifier to kick in.

As mouse wheel events look quite different from key presses (EventType::RELATIVE, KEY::KEY_0, values are integers like 16 -16 etc), I was able to hack the code for my particular case:

diff --git a/src/event_handler.rs b/src/event_handler.rs
index f1d2267..72787ad 100644
--- a/src/event_handler.rs
+++ b/src/event_handler.rs
@@ -100,9 +100,13 @@ impl EventHandler {
                     self.dispatch_actions(&actions, &key)?;
                     continue;
                 }
             }
-            self.send_key(&key, value)?;
+            if value == PRESS || value == REPEAT || value == RELEASE {
+                self.send_key(&key, value)?;
+            } else {
+                self.send_event(InputEvent::new(event.event_type(), key.code(), value))?;
+            }
         }
         Ok(())
     }
 
@@ -214,10 +218,10 @@ impl EventHandler {
     }
 
     fn flush_timeout_keys(&mut self, key_values: Vec<(Key, i32)>) -> Vec<(Key, i32)> {
         let mut flush = false;
-        for (_, value) in key_values.iter() {
-            if *value == PRESS {
+        for (key, value) in key_values.iter() {
+            if *value == PRESS || *key == Key::KEY_0 {
                 flush = true;
                 break;
             }
         }
diff --git a/src/main.rs b/src/main.rs
index cf9d457..510068e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,9 +5,9 @@ use anyhow::{anyhow, bail, Context};
 use clap::{AppSettings, ArgEnum, IntoApp, Parser};
 use clap_complete::Shell;
 use config::{config_watcher, load_config};
 use device::InputDevice;
-use evdev::EventType;
+use evdev::{EventType, Key};
 use nix::libc::ENODEV;
 use nix::sys::inotify::{AddWatchFlags, Inotify, InotifyEvent};
 use nix::sys::select::select;
 use nix::sys::select::FdSet;
@@ -206,9 +206,11 @@ fn handle_input_events(
         Err((Some(ENODEV), _)) => Ok(false),
         Err((_, error)) => Err(error).context("Error fetching input events"),
         Ok(events) => {
             for event in events {
-                if event.event_type() == EventType::KEY {
+                if event.event_type() == EventType::KEY
+                    || (event.event_type() == EventType::RELATIVE && event.code() == Key::KEY_0.0)
+                {
                     handler
                         .on_event(event, config)
                         .map_err(|e| anyhow!("Failed handling {event:?}:\n  {e:?}"))?;
                 } else {

However this certainly doesn't look good. Perhaps we should refactor a few (Key, i32) tuples out in the main loop and use InputEvent directly?

PS: Good luck with your conference! No hurries for this.

Frederick888 avatar Sep 08 '22 15:09 Frederick888

Looks like there are a couple of people who are working on relative events. Let me see how https://github.com/k0kubun/xremap/pull/181 and https://github.com/k0kubun/xremap/pull/187 go and revisit this after it's settled.

k0kubun avatar Oct 20 '22 04:10 k0kubun

#187 has been merged, is this solved now? I have the same issue with the mouse wheel

threddast avatar Oct 20 '23 09:10 threddast

Hmm yeah, hopefully? Let's close this for now and see if anybody wants to reopen it. Thanks.

k0kubun avatar Oct 20 '23 16:10 k0kubun

@k0kubun Sorry if I wasn't clear.

What I meant is that I'm on xremap 0.8.11 on Arch Linux, this is my config

virtual_modifiers:
  - hiragana
modmap:
  - name: emacs
    remap:
      # RALT SUPER CTRL SPC ALT
      leftalt: hiragana
      rightalt: leftalt

      # CTRL -> SUPER/ALT
      rightctrl: rightalt
      leftctrl: rightalt

      capslock:
        held: leftctrl
        alone: esc
keymap:
  - remap:
      hiragana-j: left
      hiragana-l: right
      hiragana-i: up
      hiragana-k: down
      hiragana-semicolon: shift-p # capslock-o -> :
      hiragana-z: C-z # capslock-x -> :
      hiragana-x: C-x # capslock-c -> :
      hiragana-c: C-c # capslock-d -> :
      hiragana-v: C-v # capslock-v -> :

everything works great, e.g. Capslock-C always behaves like CTRL-C. However, Capslock+mouse-wheel behaves like "mouse-wheel" for 2 seconds, then switches to "CTRL-mousewheel". Practically this means that if I want to zoom on a webpage, first the webpage is scrolled for 2 seconds then the zooming starts

threddast avatar Oct 23 '23 10:10 threddast

Ah okay, I was confused when reading the previous reply.

It appears that the two of you understand the problem better than me since I don't remap a mouse wheel. If @threddast's case is also fixed by letting a mouse wheel flush timeout keys, that'd be great. Would either of you be interested in filing a pull request to fix it on the latest version?

k0kubun avatar Oct 27 '23 06:10 k0kubun