Skip to content

Commit

Permalink
fix star hotkeys matching shift modifier too
Browse files Browse the repository at this point in the history
example: `*a::` wasn't triggered by <kbd>shift</kbd>+<kbd>a</kbd> but now is
Internals slightly changed with a small breaking change: Hotkey with shift keys need to be declared explicitly because the uppercase version is transformed to lowercase. So it isn't enough anymore to do e.g. `A::` - you'll have to do `+A::` or `+a::` now.
  • Loading branch information
phil294 committed Jul 11, 2023
1 parent 134303c commit fc88e1b
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/run/display/hotkey.cr
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ module Run
end

def init(escape_char)
key_combos = Util::AhkString.parse_key_combinations(@key_str.gsub("*","").gsub("~",""), escape_char, implicit_braces: true)
key_combos = Util::AhkString.parse_key_combinations(@key_str.downcase.gsub("*","").gsub("~",""), escape_char, implicit_braces: true)
raise Run::RuntimeException.new "Multiple keys aren't allowed for Hotkey definitions" if key_combos.size != 1 # TODO: probably impossible?
@key_name = key_combos[0].key_name
@keysym = key_combos[0].keysym
Expand Down
6 changes: 4 additions & 2 deletions src/run/display/hotkeys.cr
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ module Run
end
if hotkey
if ! hotkey.up && ! hotkey.no_grab
# Fixing https://github.com/jordansissel/xdotool/issues/210: (also see Send/SendRaw)
# Fixing https://github.com/jordansissel/xdotool/issues/210:
# Doing a `hotkey.keycode` UP event works great but breaks key remaps.
# Instead, the following magic seems to work reliably.
# Instead, the following magic seems to work reliably, as long as the hotkey key
# isn't sent itself (see Send for that other fix).
# Note that both grab and ungrab may fail / not work as expected but that's fine.
# This would better be placed at the *first* `Send`/`SendRaw` command on a per-hotkey
# basis, but since the performance penalty is negligible and it has no negative
Expand Down Expand Up @@ -113,6 +114,7 @@ module Run
end
end
end
# todo doesnt belong here
def block_input
@runner.display.adapter.grab_keyboard
end
Expand Down
11 changes: 10 additions & 1 deletion src/run/display/x11.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ at_exit { GC.collect }
module X11::C
# Infer a long list of key names from lib/x11/src/x11/c/keysymdef.cr, stripped from XK_ and underscores.
# Seems to be necessary because XStringToKeysym is always case sensitive (?)
# In our X11 key handling, we only deal with lowercase chars.
def self.ahk_key_name_to_keysym_generic
{{
@type.constants # TODO: possible to declare this outside of the module?
Expand Down Expand Up @@ -317,7 +318,15 @@ module Run
lookup = key_event.lookup_string
char = lookup[:string][0]?
keysym = lookup[:keysym]
@key_handler.not_nil!.call(key_event, keysym, char)
# We may have e.g. grabbed *a (so including Shift + lowercase a) but the reported
# event here will return Shift + uppercase A. We'll deal with lowercase only.
if char && char.downcase != char
char = char.downcase
keysym = Run::X11.ahk_key_name_to_keysym(char.to_s)
# TODO: like ahk-string.cr
raise Run::RuntimeException.new "Unexpected keysym #{keysym} is uppercase but can't be mapped to lowercase" if ! keysym || ! keysym.is_a?(Int32)
end
@key_handler.not_nil!.call(key_event, keysym.to_u64, char)
end

# It's easier to just grab on the root window once, but by repeatedly reattaching to the respectively currently
Expand Down
8 changes: 2 additions & 6 deletions src/util/ahk-string.cr
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,8 @@ class Util::AhkString
end
escape = false
if key_name
if key_name.size == 1 && key_name.upcase != key_name.downcase
if modifiers & ::X11::ShiftMask == ::X11::ShiftMask
key_name = key_name.upcase
elsif key_name.upcase == key_name
modifiers |= ::X11::ShiftMask
end
if key_name.size == 1 && key_name.upcase != key_name.downcase && key_name.upcase == key_name
modifiers |= ::X11::ShiftMask
end
keysym = Run::X11.ahk_key_name_to_keysym(key_name)
# TODO: why the typecheck / why not in x11.cr?
Expand Down
6 changes: 5 additions & 1 deletion tests.ahk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
; Right now, only commands that can be easily tested in 1-2 lines are tested.
;;;;;;;;;;;;;;;;;;;;;;

N_TESTS = 53
N_TESTS = 55

GoSub, run_tests
if tests_run != %N_TESTS%
Expand Down Expand Up @@ -656,6 +656,10 @@ key = +S
xdotool_run = key shift+s
gosub test_hotkey_success

key = *s
xdotool_run = key shift+s
gosub test_hotkey_success

; esc and xbutton2 share the same keycode:
key = esc
xdotool_run = key Escape
Expand Down

0 comments on commit fc88e1b

Please sign in to comment.