Add an #InputLevel directive for controlling which generated inputs get ignored #7

Merged
merged 15 commits into from Jan 14, 2012

Conversation

Projects
None yet
2 participants
Contributor

russelldavis commented Nov 27, 2011

This supercedes the InputGroup branch.

A single script can now specify multiple InputLevels. Input generated from a higher InputLevel can trigger hotkeys in a lower level. Example:

#InputLevel 1
Numpad0::LButton
#InputLevel 0
~LButton::Msgbox Clicked

The ~LButton hotkey will get triggered for both Numpad0 and LButton presses.

russelldavis added some commits Nov 24, 2011

@russelldavis russelldavis Add a new #InputGroup directive for controlling which generated input…
…s get ignored.

To avoid infinite loops and other side effects, AHK ignores self-generated input events.
It does this by setting a sentinel value in the ExtraInfo field when sending input. In
previous versions, a single sentinel value was used for all scripts, making it impossible
for a script to send input that triggers a hotkey in another script.

The #InputGroup directive provides a way to change the sentinel, so that each script only
ignores input from the other scripts in the same input group.
e02c0df
@russelldavis russelldavis Initial implementation of #InputLevel directive.
Like the experimental #InputGroup directive, this allows control over which
generated inputs get ignored. However, instead of working at the file level,
this applies at the HotkeyVariant level like the #IfWinXXX directives.

All hotkeys declared after the directive are assigned the specified InputLevel.
Input generated at a given level can only trigger hotkeys that belong to a
lower InputLevel. Input generated at level 0 cannot trigger any other hotkey
since it is the lowest level. It is also the default level, which means the
default behavior is exactly as in previous versions.

TODO:
- Rename from InputGroup to InputLevel.
- Change the minimum InputLevel to 0.
- Fix the default InputLevel sent by the hook.
- Add a SendLevel command to change the SendLevel independently from the InputLevel
5ae066c
@russelldavis russelldavis - Rename from InputGroup to InputLevel (for incoming input) and SendL…
…evel (for generating input)

- Change the min & max InputLevels to 0 and 100.
- Change InputLevel & SendLevel to unsigned.
016c6ca
@russelldavis russelldavis Change the approach for sending the KEY_IGNORE sentinel.
Now using the original KEY_IGNORE value (equivalent to KEY_IGNORE_BY_SENDLEVEL
at SendLevel 0) as the default for all generated input, and manually specifying
KEY_IGNORE_BY_SENDLEVEL where appropriate. This works much better because:
(a) KEY_IGNORE_BY_SENDLEVEL doesn't make sense in the context of the hook
    (or anywhere else outside of a running AHK pseudo-thread), and using
    it in such a way would compile fine but cause problems at runtime.
(b) It turns out the vast majority of calls that generate input are doing
    so for side effects that should always be ignored at SendLevel 0 anyway.

TODO: Fix the hook to properly handle KEY_IGNORE_ALL_EXCEPT_MODIFIER_BY_SENDLEVEL
at SendLevels other than 0.
d3409e4
@russelldavis russelldavis Fix the hook to properly handle modifiers for KEY_IGNORE_BY_SENDLEVEL at
SendLevels other than 0. The fix ended up being to not support this mode in
the first place. Based on the use cases this is designed for, any time we're
sending input to be ignored at a given level, it will also make sense to update
the state of the modifiers (i.e., exactly what KEY_IGNORE_ALL_EXCEPT_MODIFIER
does).

As an added bonus, limiting the scope like this allowed for simplification of
some of the supporting code.

This feature should now be functionally complete, with no known major issues.
e3ad76a
@russelldavis russelldavis Add a new action: SendLevel. By default, hotkey threads get a SendLevel
set to the same as their #InputLevel, and other threads get the level
of the last #InputLevel directive. The SendLevel action provides a way
to set a different value during thread execution. This should rarely
be needed for hotkey threads, and can result in infinite hotkey loops
if not used carefully.
3db270d
@russelldavis russelldavis Clean up the SendLevel definitions and types.
Move some of them to more appropriate header files.
d388d46
@russelldavis russelldavis Refactor into a new HotInputLevelAllowsFiring function that can be us…
…ed for

both hotkeys and hotstrings.
c08aa17
@russelldavis russelldavis Respect #InputLevel when triggering hotstrings. 086a1d2
@russelldavis russelldavis Initialize hotstring threads with a SendLevel corresponding to the
hotstring's InputLevel.
b42cdae
@russelldavis russelldavis Set the SendLevel to 0 when auto-replacing hotstrings. 4b0079e
@russelldavis russelldavis Fix KeyHistory character for ignored input. ec7e784
@russelldavis russelldavis Update documentation. 23049fa
Contributor

russelldavis commented Dec 17, 2011

Have you had a chance to look at this? Any thoughts on potentially merging it in?

russelldavis added some commits Jan 8, 2012

@russelldavis russelldavis Ignore by SendLevel when setting the modifier state for generated input.
Fixes this bug: when sending something like ^a from an elevated SendLevel,
the ctrl key would still be ignored at lower levels.
0522a70
@russelldavis russelldavis Force the keyboard hook for hotkeys using a non-zero InputLevel.
(A non-zero InputLevel only works when using the hook.)
8d086e2

Lexikos merged commit 8d086e2 into Lexikos:master Jan 14, 2012

Owner

Lexikos commented Jan 14, 2012

Good work. Would you mind writing user documentation for the new features?

As I mentioned via e-mail previously, commit 23049fa caused the merge to fail. I've since figured out that it had inconsistent line endings - I'm guessing you had the core.autocrlf option turned off (better turn it on, if you haven't already). Rather than causing a merge conflict (which could easily be resolved), it caused the merge to fail entirely. Fortunately I found that writing the hash of your head commit into .git/MERGE_HEAD and then committing was sufficient to complete the merge.

Contributor

russelldavis commented Jan 23, 2012

Ah, yeah, damn line endings, sorry. Setting core.autocrlf to true has caused its own set of problems, which is why I had it disabled. I'm gonna try setting it to input and see if that's the sweet spot.

I'll take a stab at writing user documentation, just need to find some time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment