houmain / keymapper

A cross-platform context-aware key remapper.
GNU General Public License v3.0
257 stars 21 forks source link

Title or class context awareness breaks after toggling a virtual modifier (Ubuntu 20.04, i3wm) #99

Closed ristomatti closed 5 months ago

ristomatti commented 5 months ago

The class or title context mappings start to leak if a virtual modifier is toggled back and forth on the targeted window. At least with the configuration I have. I got it reproduced in a "minimal" example:

# Immediately forward common modifiers
MetaLeft      >> MetaLeft
MetaRight     >> MetaRight
Control       >> Control
AltRight      >> AltRight

notify = notify-send -t 1000 keymapper

auto_shift_status_on       = $(notify "AutoShift ON")
auto_shift_status_off      = $(notify "AutoShift OFF")

direct_umlauts_status_on  = $(notify "DirectUmlauts ON")
direct_umlauts_status_off = $(notify "DirectUmlauts OFF")

caps_word_status_on        = $(notify "CapsWord ON")
caps_word_status_off       = $(notify "CapsWord OFF")

# Intl. layout modifiers
AltGr           = AltRight

# Key groups
NonShiftMod     = Meta | MetaRight | AltLeft | Control | ControlRight
Number          = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Letter          = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

# Input modes
CapsWord        = Virtual1
AutoShift       = Virtual2
DirectUmlauts   = Virtual3

F5 >> F5 ^ AutoShift
F6 >> F6 ^ DirectUmlauts

# CapsWord emulation (https://docs.qmk.fm/#/feature_caps_word)
[default]
  CapsWordKey = Letter | Number | Minus | Backspace

  Shift{200ms}          >> Shift
  ShiftLeft{ShiftRight} >> CapsWord CapsLock ^

  CapsWord >> caps_word_status_on ^ caps_word_status_off

[modifier="CapsWord"]
  Minus                 >> Shift{Minus} # '_'
  CapsWordKey           >> CapsWordKey
  !CapsWordKey Any      >> CapsWord CapsLock Any ^

# AutoShift emulation (https://docs.qmk.fm/#/feature_auto_shift)
[default]
  AutoShift = Virtual2
  AutoShifted = BracketLeft | BracketRight | Number | Minus | Equal | Comma | Period

  AutoShift >> auto_shift_status_on ^ auto_shift_status_off

[modifier="!NonShiftMod AutoShift"]
  Shift{AutoShifted}                >> (Shift AutoShifted)
  AutoShifted{120ms} !AutoShifted   >> (Shift AutoShifted)
  AutoShifted{Any}                  >> AutoShifted Any ^
  AutoShifted                       >> AutoShifted

# Direct umlaut input
[default]
  DirectUmlauts  = Virtual3
  DirectUmlauts >> direct_umlauts_status_on ^ direct_umlauts_status_off

# Use direct umlauts only in Xed
[modifier="DirectUmlauts" class="xed"]
  Shift{Comma}          >> (Shift Semicolon)
  ShiftRight{2}         >> (Shift Quote)

  Quote{120ms}          >> Quote ^
  Semicolon{120ms}      >> Semicolon ^
  AltGr{Quote}          >> !AltGr Quote
  AltGr{Semicolon}      >> !AltGr Semicolon
  Quote                 >> AltGr{Q}
  Semicolon             >> AltGr{P}

Prerequirements:

Steps to reproduce:

  1. Focus the terminal
  2. Toggle "AutoShift" and "DirectUmlaus" on/off from F5 and F6 respectively to verify they work as defined
  3. Toggle both off
  4. Focus the window in which the context should apply
  5. Toggle DirectUmlauts on from F6. This should work as expected, typing ä from a, ö from o.
  6. Toggle AutoShift on (F5), this likely breaks DirectUmlauts
  7. Toggle DirectUmlauts (F6) off and back on which should result in it working again
  8. Focus the terminal and type ao, it incorrectly results in äö

Occasionally this also breaks keymapperd in some way and it needs to be restarted for keymapper to connect to it.

I've recorded a screen capture which attemps to demonstrate the bug. I'm not a streamer or a YouTuber, so few potentially confusing screw ups ended on it. On the recording, the reproduction steps aren't exactly as above but the order of execution doesn't make a difference, as long as DirectUmlauts mode is toggled back end forth.

https://github.com/houmain/keymapper/assets/9029939/c854617b-695a-44a0-812f-c7c7208ebeb5

ristomatti commented 5 months ago

The "CapsWord" input mode (triggered from ShifftLeft{ShiftRight}) is unrelated but included as I had it there while recording. It's not used during the screen capture.

houmain commented 5 months ago

Thanks for reporting! I could reproduce it with this simple configuration:

F5 >> Virtual1
Virtual1 >> $(echo) ^

[title="GPUpad"]
A >> B

After hitting F5 once the contexts are no longer updated. Up to now the contexts were only updated when no key was hold. The Virtual1 was also wrongly considered in the case when its pressing triggers something.

Now the contexts and configurations are updated even when a key is still hold. The updates were initially disabled to prevent hanging keys when one hits e.g. Control-S to save a configuration, which immediately reset the state without releasing the keys.

ristomatti commented 5 months ago

I am happy to report the issue is gone. It's also somewhat of a relief to know it was an actual bug and not just my ability to understand documentation.

Now with the context issue gone, I also got all input modes working consistently by moving "DirectUmlauts" before "AutoShift". Now regardlesss of the focused window, the behavior affects every window (if the context allows).

You are a legend. Thank you!