Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add state conditions #104

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add state conditions #104

wants to merge 1 commit into from

Conversation

c-max
Copy link

@c-max c-max commented May 2, 2018

Hello Albin,

searching for a way to make Space act as Shift, if pressed with another key,
I found xcape. Very nice! Big thanx from me and my relaxed small fingers for
providing the code.

Using a custom multi level keyboard layout (xkb) with
key {[Hyper_R,Hyper_R,space,0,space]}; // Hyper_R >> Shift-Mod
I had to prevent xcape from generating space at levels 3..5 (set by combinations of Mod1&2).
Therefore I added condidions to xcape (see below) and simply call:

xcape -e 'Hyper_R=#255?,0x30

It works very well in my normal use, but nearly simultaneous keystrokes
might fool the modifier state detection (see below).

Problem:
XRecordInterceptData does not seem to reference any modifier state data.
Nearly simultaneous keystrokes might cause XRecord to record a second key before the XkbGetState() call is done.

If you like to adopt this mod feel free to do so.
Suggestions for improvements are very welcome.

Regards,

max


Description:

ModKey=GenKey[Condidions][|OtherGenKey[Condidions]...]

The Condidions syntax is ´?[[Filter],[Mask]]...´ (see examples).

Conditions can be used to control the key generation based on the
keyboard/pointer state before ModKey was pressed.
This is especially usefull if the ModKey has variable keysyms or actions
using a multi level/group keyboard layouts with xkb.
(The Key should be referenced by its key code in this case.)

State bits:

0 .. 7: Shift, Lock, Control, Mod1..Mod5
8 .. 10: Pointer buttons
11 .. 12: n/a (always 0 in xcape)
13 .. 15: index of layout group (0..3)

The debug mode (-d) can be used to show current states.

A GenKey with one or more condidions will be generated if at least one condidion matches the state. That is all masked bits of Filter are equal to those of the state.

Filter and Mask may be specified decimal (no prefix), octal (0) or hexadecimal (0x) within the valid range 0x0..0x7fff. Both are optional. Filter defaults to 0x0, Mask to Filter.
So Mask (Filter) can be omitted if a condition checks set (unset) state bits only.

Examples:

Press both Shift keys to toogle Caps Lock:

xcape -e 'Shift_L=Caps_Lock?1;Shift_R=Caps_Lock?1'

Press both Shift keys to set Caps Lock - one to unset:

xcape -e 'Shift_L=Caps_Lock?1?2;Shift_R=Caps_Lock?1?2'

Press both Shift keys to set Caps Lock - one to unset if Control is unset:

xcape -e 'Shift_L=Caps_Lock?1?2,6;Shift_R=Caps_Lock?1?2,6'

Known problem:

Nearly simultaneous keystrokes might fool the modifier state detection since
xcape gets key events and the current modifier state from two different
sources.

In the examples above simultaneous Shift + Control might lead to unintended Caps Lock.

condition handling added
@c-max c-max changed the title Update xcape.c add state conditions May 4, 2018
@c-max c-max changed the title add state conditions Add state conditions May 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant