Code Monkey home page Code Monkey logo

xcape's Introduction

XCAPE

xcape allows you to use a modifier key as another key when pressed and released on its own. Note that it is slightly slower than pressing the original key, because the pressed event does not occur until the key is released. The default behaviour is to generate the Escape key when Left Control is pressed and released on its own. (If you don't understand why anybody would want this, I'm guessing that Vim is not your favourite text editor ;)

Minimal building instructions

First install the development dependencies. On Debian-based systems (including Ubuntu and Linux Mint), run:

$ sudo apt-get install git gcc make pkg-config libx11-dev libxtst-dev libxi-dev

On Fedora-based systems, run:

$ sudo dnf install git gcc make pkgconfig libX11-devel libXtst-devel libXi-devel

Then run:

$ git clone https://github.com/alols/xcape.git
$ cd xcape
$ make
$ sudo make install

Usage

$ xcape [-d] [-f] [-t <timeout ms>] [-e <map-expression>]

-d

Debug mode. Does not fork into the background. Prints debug information.

-f

Foreground mode. Does not fork into the background.

-t <timeout ms>

If you hold a key longer than this timeout, xcape will not generate a key event. Default is 500 ms.

-e <map-expression>

The expression has the grammar 'ModKey=Key[|OtherKey][;NextExpression]'

The list of key names is found in the header file X11/keysymdef.h (remove the XK_ prefix). Note that due to limitations of X11 shifted keys must be specified as a shift key followed by the key to be pressed rather than the actual name of the character. For example to generate "{" the expression 'ModKey=Shift_L|bracketleft' could be used (assuming that you have a key with "{" above "[").

You can also specify keys in decimal (prefix #), octal (#0), or hexadecimal (#0x). They will be interpreted as keycodes unless no corresponding key name is found.

Examples

  • This will make Left Shift generate Escape when pressed and released on its own, and Left Control generate Ctrl-O combination when pressed and released on its own.

    xcape -e 'Shift_L=Escape;Control_L=Control_L|O'
    
  • In conjunction with xmodmap it is possible to make an ordinary key act as an extra modifier. First map the key to the modifier with xmodmap and then the modifier back to the key with xcape. However, this has several limitations: the key will not work as ordinary until it is released, and in particular, it may act as a modifier unintentionally if you type too fast. This is not a bug in xcape, but an unavoidable consequence of using these two tools together in this way. As an example, we can make the space bar work as an additional ctrl key when held (similar to Space2ctrl) with the following sequence of commands.

    # Map an unused modifier's keysym to the spacebar's keycode and make it a
    # control modifier. It needs to be an existing key so that emacs won't
    # spazz out when you press it. Hyper_L is a good candidate.
    spare_modifier="Hyper_L"
    xmodmap -e "keycode 65 = $spare_modifier"
    xmodmap -e "remove mod4 = $spare_modifier" # hyper_l is mod4 by default
    xmodmap -e "add Control = $spare_modifier"
    
    # Map space to an unused keycode (to keep it around for xcape to
    # use).
    xmodmap -e "keycode any = space"
    
    # Finally use xcape to cause the space bar to generate a space when tapped.
    xcape -e "$spare_modifier=space"
    

Note regarding xmodmap

If you are in the habit of remapping keycodes to keysyms (eg, using xmodmap), there are two issues you may encounter.

  1. You will need to restart xcape after every time you modify the mapping from keycodes to keysyms (eg, with xmodmap), or xcape will still use the old mapping.

  2. The key you wish to send must have a defined keycode. So for example, with the default mapping Control_L=Escape, you still need an escape key defined in your xmodmap mapping. (I get around this by using 255, which my keyboard cannot send).

Contact

Find the latest version at https://github.com/alols/xcape

The author can be reached at albin dot olsson at gmail dot com

xcape's People

Contributors

ainola avatar alols avatar atykhonov avatar calmofthestorm avatar davidshepherd7 avatar dexterthedragon avatar exergonic avatar jbernard avatar joetw avatar johnhill avatar mar04 avatar mdom avatar mortal avatar orestisfl avatar otommod avatar paulporfiroff avatar phy1729 avatar polachok avatar thebinarypenguin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xcape's Issues

Incorrect default timeout value specified in README.md

Judging by the code, the correct value in the documentation should be 500 ms. Just missing a 0.

Considering best human reaction times is around 200 ms, I was wondering what kind of super keyboard and/or fingers you have... ;-)

Wishlist : mouse click(wheel) also make capslock to ctrl not esc.

First of all, huge, huge thanks for this application. I've always dreamed about capslock for both ctrl and esc.

Today I've used capslock + mouse wheel combiation(zoom in/out) in evince full screen mode(F11). Evince leaved fullscreen. Looks like xcape trigger esc. But in this situation(capslock + wheel), would be better don't trigger escape.

Again, huge thanks for xcape.
Thanks.

xcape with Ubuntu 14

Installed using the given method but doesn't seem to work for me.
I'm not getting the error here, I'm just not getting anything.

Installed using :

    cd ~
    sudo apt-get install git gcc make pkg-config libx11-dev libxtst-dev libxi-dev
    mkdir xcape
    cd xcape
    git clone https://github.com/alols/xcape.git .
    make

This is the output of the install:

Reading package lists... Done
Building dependency tree
Reading state information... Done
gcc is already the newest version.
libx11-dev is already the newest version.
libxtst-dev is already the newest version.
make is already the newest version.
pkg-config is already the newest version.
libxi-dev is already the newest version.
git is already the newest version.
The following packages were automatically installed and are no longer required:
  fonts-font-awesome fonts-mathjax ipython-notebook-common libjs-highlight
  libjs-jquery-ui libjs-marked libjs-mathjax libpgm-5.1-0 libx265-49 libzmq3
  python-mysqldb python-simplegeneric python-tornado python-zmq
  vlc-plugin-pulse

I have the file xcape in ~/xcape

└─[$]› file xcape
xcape: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=88b6cd9cb4aabc502ba59d897c8b3a4e60a563ab, not st
ripped

If I run this file with ./xcape I see no output, and which doesn't return anything either

[$]› ./xcape 

[$]› which xcape

If I then load a new terminal with the following in bashrc

xmodmap -e "clear lock"
xmodmap -e "remove control = Control_L"
xmodmap -e "keycode 66 = Control_L"
xmodmap -e "add control = Control_L"

xcape -e "Control_L=Escape"

I get the output :

xmodmap:  please release the following keys within 2 seconds:
    Return (keysym 0xff0d, keycode 36)
    Super_L (keysym 0xffeb, keycode 133)
xcape: command not found
xcape: command not found

After restarting the machine I still get the error

xcape: command not found
xcape: command not found

I'm not sure if this is something to do with the distro or what - are there known issues for particular distros?

Cannot map ISO_Level2_Latch to a Shift tap

I'm trying to make left Shift sticky, and running:

$ xcape -e "Shift_L=ISO_Level2_Latch"

It gets me an error message:

WARNING: No keycode found for keysym ISO_Level2_Latch (0xfe02) in mapping Shift_L. Ignoring this mapping.

Seems that this is due to XKBKeycodeToKeysym doesn't know how to translate ISO_Level2_Latch to keycode.
README says that "I get around this by using 255, which my keyboard cannot send", but I couldn't find .xinitrc in your dotfiles, and it's not in .Xmodmap either, so it's not obvious how to do that.

I have tried the following:

$ xmodmap -e "keycode 255 = ISO_Level2_Latch"
$ xcape -d -e "Shift_L=ISO_Level2_Latch"
Assigned mapping from "Shift_L" ( keysym 0xffe1, key code 50)
to "ISO_Level2_Latch" (keysym 0xfe02, key code 255)
sig_handler running...
Intercepted key event 2, key code 50
Key pressed!
Intercepted key event 3, key code 50
Key released!
Generating ISO_Level2_Latch!

Doesn't make first typed symbol to stick.
However same for Caps_Lock works perfectly fine:

$ xmodmap -e "keycode 255 = Caps_Lock"
$ xcape -d -e "Shift_L=Caps_Lock"
Intercepted key event 3, key code 50
Key released!
Generating Caps_Lock!

And all typed keys produce capitals.

I was able to make it sticky once, and later on couldn't reproduce that, no idea what might fail.

Output of xmodmap -pm just for the case:

xmodmap:  up to 4 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0x32),  Shift_R (0x3e)
lock      
control     Control_L (0x25),  Control_L (0x42)
mod1        Alt_L (0x40),  ISO_Next_Group (0x6c),  Meta_L (0xcd)
mod2        Num_Lock (0x4d)
mod3      
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)

My dotfiles's .xinitrc (has some setxkbmap calls): https://github.com/pirj/dotfiles/blob/master/.xinitrc

This is a part of larger goal for me, I intend to map my left Shift key to Mod4(hold) and Sticky Shift (tap). All of the above did not include the following meaning that experiment was clean.

Simple:

xmodmap -e "remove Shift = Shift_L"
xmodmap -e "keysym Shift_L = Hyper_L"
xcape -e "Shift_L=ISO_Level2_Latch"

Complex (don't get any difference):

xmodmap -e "keycode 50 = Hyper_L"
xmodmap -e "remove mod4 = Hyper_L"
xmodmap -e "add mod4 = Hyper_L"
xmodmap -e "keycode any = space"
xmodmap -e "keycode 255 = ISO_Level2_Latch"
xcape -e "Hyper_L=ISO_Level2_Latch"

In both cases I get my left Shift key working as Mod4, but in both cases xcape complains.

spacebar and Thunderbird

Hi!
Thank you for xcape!
I just started to use it to restore space symbol from space bar which I remapped in my xkb layout to shift to level3.
I use Ubuntu 13.10 with default Unity Desktop.
And as far as I can see all works well with xcape started as
xcape -e "ISO_Level3_Shift=space"

I can get space character in Gnome terminal, Firefox, Chrome, Sublime Text, Gedit, LibreOffice etc. but not in Thunderbird.

If I create new email in Thunderbird and try to enter space in Subject or Body I've getting nothing.
Thanks in advance for any ideas or help.

Creates a dummy process with incorrect arguments

If you run xcape with no arguments it creates a process:

$ ./path/to/xcape
$ ps aux | grep xcape
=> username   21310  0.0  0.0  30508   720 ?        Ssl  18:19   0:00 ./xcape

If you run it with an argument that does not have a -:

$ ./path/to/xcape foobar
$ ps aux | grep xcape
=> a     bunch     of     stuff    ./xcape foobar

It'd be great if these threw an error, even if it's clear that options to linux commands always start with -.

I think that this has something to do with the way arguments are being handled with getopt and that optind may hold the answer but I haven't been able to pin down where to put the check for argv[optind] != NULL. Correct me if I'm on the wrong track here.

Release

Please make a proper release tarball! It's a lot easier to use for us, porting/packaging people.

Allowing keycodes in map expressions

Pasted from email:

First of all, thank you very much for xcape.

Are you interested in adding support for map-expressions that allow
keycodes instead of key names?

The reason is this use case: I use xmodmap to set my "s" and "l" keys
both to AltGr. Then I would like xcape to turn them back into "s" and
"l" like this:

xcape -e "ISO_Level3_Shift=s;ISO_Level3_Shift=l"

which obviously doesn't work, because there is no AltGr_L and _R. But

xcape -e "42=s;43=l"

would make sense.

I'm sorry that I can suggest no patch.

detect if running with same parameters

After starting xcape, it detects if it is already running with the same command line parameters as passed to it and does not start again, instead of spawning a new process? (Useful, for example, if xcape autostarts with your window manager that, on a restart, would load it unnecessarily again.)

Alternate keyboard support

xcape works well with standard US keyboard layout. Is there a way to make it work with dvorak latyout?

Feature request, timeout generates 'long key press'

Hi,

I'm not sure if this is possible/easy to add, but it would be an awesome addition to me!

I would like a odified behaviour of the time out. instead of a time out I would like the key to behave as a long press single key press.
ie I run xcape -t 1000 -e 'Control_L=BackSpace|Control_L' and when I hold the key more than one second it behaves like a 'real' backspace and removes multiple characters.

Would this be possible? I'd like to look into it myself but I don't really know where to start.

TTY?

I realise that it's outside of the scope of this program, but I have become addicted to having Ctrl/Escape on the CapsLock key, and I'm wondering if anyone here knows of a way to get this behaviour without X.

:P

reverse operation

is it possible to generate a fake modifier key when a normal key is pressed in combination with another normal key?

on osx, the karabiner tool allows for some magic behaviour of the tab key when it is pressed with the h and l keys: it allows for vim-like window navigation in "alt-tab style" using the tab key as a modifier. when pressed alone, tab just generates a tab.

is this possible to achieve under linux/xorg?

Not working every time with xkb rules?

I've just tried out xcape and it seems really lightweight and functional.

However I have a xkb rule ctrl:nocap that makes the capslock act as the control key, and I was thinking that xcape should work with that and make my capslock key send escape on short press. From my experimentation sometimes this works but sometimes it doesn't. Is there any reason why or any workaround?

Non-modifier Keys Mapped to Modifiers Work as Modifiers Even When not Held Down

Trying example two, all the symbols I have on my altgr layer are inserted when typing normally even if "s" is not held down. Any key that has mappings on the altgr level being typed quickly after s results in a symbol being entered.

It would be nice if there was a setting to specify a time for which the key had to be held down before acting as a modifier to prevent this from happening.

Is it possible to send key sequences on a single key stroke?

Hi,
This perhaps is not appropriate to be called an issure. But it looks like we can only send a combination of keys once. I am using emacs, can I send a key sequence like "ctrl-x" then "alt-o" (which toggles omit mode in dired) for a short hit of the shift key? Sure we can bind the command to a key with modifier, but in emacs a single key with modifier is quite scarce resource.
Thank you very much!

problems while installing - fatal error: <stdlib.h>

I follow the installation guide and everything is fine, until I run make to
finish the process. I get the following error message:

cc -Wall `pkg-config --cflags xtst x11` -o xcape xcape.c `pkg-config --libs xtst x11` -pthread
xcape.c:21:20: fatal error: stdlib.h: file or directory not found
#include <stdlib.h>
                    ^
compilation terminated.
make: *** [xcape] Fehler 1

I am on

Linux x86_64
3.11.0-18-generic
Ubuntu 13.10
GNOME Shell 3.10.4

packages are installed as recommended (pkg-config as well)!

Feature request: Option to listen to mouse click events

In my use case I'm using Super on it's own to start dmenu, and Super in combination with mouse 1 and mouse 3 (left and right click) for window moving/resizing.

The problem occurs when I move windows around fast enough that I release Super before the timeout is up (quite reasonable when doing small tweaks to window size etc.). When this happens, xcape ends up calling the openbox shortcut and running dmenu even though I pressed some mouse buttons while Super was held.

I tried fiddling with the timeout a bit, and it kind of works, but either it still occasionally starts dmenu at undesired times, or I have to stab Super in a really staccato fashion when I actually want dmenu.

Would it be possible to have xcape listen for mouse button press events in addition to the way it currently listens for keypress events?

TL;DR: Would it be possible to make it so that when Super+Left Mouse is pressed within the timeout, the alternate keypresses are not generated?

xcape with XkbOption ctrl:nocaps, escape not generated form capslock press until ctrl is pressed

with XkbOption 'ctrl:nocaps' when I start xcape using i3 config or in my .xinitrc xcape does not generate an escape from the capslocks key until I press the ctrl key atleast once. If I start xcape manually it works as it should.


Here is an example of the behaviour xcape exhibits when started in either i3 config or .xinitrc:

Assigned mapping from "Control_L" ( keysym 0xffe3, key code 37)
to "Escape" (keysym 0xff1b, key code 9)
sig_handler running...
Intercepted key event 2, key code 66
Intercepted key event 3, key code 66
Intercepted key event 2, key code 37
Key pressed!
Intercepted key event 3, key code 37
Key released!
Generating Escape!
Ignoring generated event.
Ignoring generated event.
^[Intercepted key event 2, key code 66
Key pressed!
Intercepted key event 3, key code 66
Key released!
Generating Escape!
Ignoring generated event.
Ignoring generated event.


Versus starting xcape manually on the command line, after i3 has started:

Assigned mapping from "Control_L" ( keysym 0xffe3, key code 37)
to "Escape" (keysym 0xff1b, key code 9)
sig_handler running...
Intercepted key event 3, key code 36
Intercepted key event 2, key code 66
Key pressed!
Intercepted key event 3, key code 66
Key released!
Generating Escape!
Ignoring generated event.
Ignoring generated event.


Here are my xkb settings:

Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /usr/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules:      evdev
model:      thinkpad
layout:     us
options:    ctrl:nocaps
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete
compat:     complete
symbols:    pc+us+inet(evdev)+ctrl(nocaps)
geometry:   thinkpad(us)
xkb_keymap {
        xkb_keycodes  { include "evdev+aliases(qwerty)" };
        xkb_types     { include "complete"      };
        xkb_compat    { include "complete"      };
        xkb_symbols   { include "pc+us+inet(evdev)+ctrl(nocaps)"        };
        xkb_geometry  { include "thinkpad(us)"  };
};

}

Feature Request: Do not send escape event if the mouse is clicked while holding the key.

If I press control, click with the mouse, and then release it the mouse event will work as a control+click AND an escape keypress will be sent. I would like a mouse click to be treated like another keypress, and prevent sending escape.

This is not a huge problem, but in some applications that use control+click it can cause confusion. I noticed this while playing a game. A control+click (which is used heavily in the game) caused the menu to pop up because of the escape key event.

Using xcape sets keymap to US temporarily

Hi,

I normally use a spanish keyboard so the special keys are arranged in a different way.
I have the following setup for the Super key:
xcape -e 'Super_L=Super_L|D'
Super+D is a prefix command in my WM so after it I can press other keys and get different options, the problem is, whenever I hit the "?" key I get a "/", making xcape useless. Is there a way to fix this?

-d flag does two things

...namely turning on debug mode (verbose output) and keeping the process in the foreground. would it be possible to have a separate -f flag (implied by -d) that only keeps the process in the foreground without spitting out verbose debugging info?

Stop space to ctrl

As mentioned in readme I am using space as space and ctrl. How can I stop this behaviour?

Two modifiers as a key.

Is it possible to press one modifier and press and release another one to generate a key event? This is useful to achieve joystick motions. Alt_L + Alt_R = Action1 and Alt_R + Alt_L = Action2.

Crashing

Just giving it a try. Works well when it's working but right now it seems to keep crashing for me.

Control pressed!
Intercepted key event 2, key code 40
Intercepted key event 3, key code 40
Intercepted key event 2, key code 40
Caught signal 28!
sig_handler exiting...
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
xcape: xcb_io.c:178: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
[1]    8051 abort      ./xcape --debug

Cannot bind Caps_Lock to a key

I cannot today bind my left shift to the capslock key.
It used to work, but I now get this error:

WARNING: No keycode found for keysym Caps_Lock (0xffe5) in mapping Shift_L. Ignoring this mapping.

I precise I use the X11 option "caps:backspace".
I don't have any other information and I'm quite unfamiliar with X11 and its configuration (I'm only able to choose which options I prefer…)

Mapping Control_R to underscore

Hi, I'm trying to map my right control key to underscore as follows:

xcape -e 'Control_R=underscore'

However, when I press the right control key I get - instead of _. Am I doing something wrong or is it a bug?

Thanks,
Anton

Block modifier keys until they are used

I have xcape set up to bind alt and super, i.e.

xcape -e 'Alt_L=Return;Super_L=space'

Generally, I can navigate menus with (e.g.) alt+f to open the file menu, then navigate with the arrow keys, pressing Enter to select the menu item. Similarly, I can press the menu button to open a context menu where the text cursor is, and navigate with arrows and enter.

Since binding enter with xcape as above, pressing enter now closes the menu, and sends a newline character to the current cursor position. Note that it still works fine in some other applications, e.g. kate.

Stuck Modifier

I start xcape with:

xcape -e 'Control_R=Return'

My .Xmodmaprc is:

clear Lock
clear Control

keycode 66 = Control_L
keycode 37 = Multi_key Caps_Lock
keycode 36 = Control_R
keycode 255 = Return

add Control = Control_L Control_R

And while xcape was running, the control modifier got stuck (i.e. pressing 'a' was equivalent to pressing 'Ctrl-a').

Killing the xcape process restored the keyboard to its sane state.

wayland support

Not really an issue I guess but currently testing wayland, I find myself cruelly missing xcape !!

Since I have absolutely no idea how the same could be achieved in wayland, I try asking here...

Cheers,

Christophe

xcape + vim + tmux

Hi,

With xcape running in my .zshrc like so:
setxkbmap -option 'caps:ctrl_modifier'
xcape -t 50 -e 'Caps_Lock=Escape'

I seem to be able to get it work on normal behavior such as browsing the internet, copying things from my terminal and copying and pasting all using the Caps Lock key.
I am even able to switch panes in tmux.

However, when I use vim within tmux and I want to switch to normal mode, pressing Caps Lock doesn't work. Anyone know why?

Exits when run by systemd

Because the xmodmap and xcape settings are not kept after suspend and resume, I’ve created a systemd service:

[Unit]
Description=space2ctrl
After=suspend.target

[Service]
User=m
Type=simple
ExecStart=/home/m/space2ctrl

[Install]
WantedBy=suspend.target

This /home/m/space2ctrl is a copy of the script from the README.md with sleep 5 added (even xmodmap wouldn’t work otherwise):

#!/bin/sh
sleep 5
export DISPLAY=":0"

# Kill instances of xcape that might be running.
killall -u m xcape

# Map an unused modifier’s keysym to the spacebar’s keycode and make it a
# control modifier. It needs to be an existing key so that emacs won't
# spazz out when you press it. Hyper_L is a good candidate.
spare_modifier="Hyper_L"
xmodmap -e "keycode 65 = $spare_modifier"
xmodmap -e "remove mod4 = $spare_modifier" # hyper_l is mod4 by default
xmodmap -e "add Control = $spare_modifier"

# Map space to an unused keycode (to keep it around for xcape to
# use).
xmodmap -e "keycode any = space"

# Finally use xcape to cause the space bar to generate a space when tapped.
xcape -e "${spare_modifier}=space"

With this service, after resuming, the xmodmap mods work (Space is Ctrl), but xcape exits immediately and no space can be typed.

When the above script, /home/m/space2ctrl, is run manually in a terminal, everything works as expected.

What could be the case?

With Caps remapped, after emulating escape two times, it stops working

Hello. I'm having some weird issue with xcape and Caps mapped to Control. The thing is, it works only for the first two presses, and then stops. It still works with normal Control key, but not with Caps, until restarted.

Here's how I map Caps to Control:

dmedvinsky at zeus in ~
><((°> cat /etc/X11/xorg.conf.d/20-keyboard.conf 
Section "InputClass"
    Identifier "keyboard defaults"
    MatchIsKeyboard "on"
    Option "XkbLayout" "us,ru,"
    Option "XkbOptions" "grp:alt_space_toggle,compose:menu,ctrl:nocaps"
EndSection

Here's the output of xcape --debug:

dmedvinsky at zeus in ~
><((°> pgrep xcape

dmedvinsky at zeus in ~
[1] ><((ˣ> xcape --debug
sig_handler running...
Intercepted key event 3, key code 36
Intercepted key event 2, key code 66
Control pressed!
Intercepted key event 3, key code 66
Control released!
Generating ESC!
Intercepted key event 2, key code 9
Intercepted key event 3, key code 9
^[Intercepted key event 2, key code 66
Control pressed!
Intercepted key event 3, key code 66
Control released!
Generating ESC!
Intercepted key event 2, key code 9
Intercepted key event 3, key code 9
^[Intercepted key event 2, key code 66
Intercepted key event 3, key code 66

That is me running it and pressing Caps key three times in a row with a couple of seconds in between key presses and no other keys pressed.

Delete bindings

Hi,

I should have been more careful. I ran

./xcape -e 'a=A'

and now everytime I type a it gives me aa. This is driving me nuts. How do I remove this behaviour? (This small message took a looong time to write).

Thanks for the help,
Daniel

xcape stopps working after suspend

I followed instructions to make work at control key if pressed with other key. It's great, but only until the next suspend (closing, opening the laptop under Ubuntu). I suspect there is hook somewhere, where I can put my space-as-ctrl.sh command in to call it after every suspend.
Of course, there are the /etc/pm/sleep.d/ hooks, but they are not userspace (and might not even find the Xorg process). Is there a recommended solution?

Information about shift'ed keys is lost due to conversion to keycodes

I've found a set of commands for which xcape doesn't as expected, at least on arch linux and a few versions of mint using a gb layout keyboard. Here's an example (I've added some additional debugging output to display the assigned mapping):

./xcape -d -e 'Control_R=braceleft'
Assigned mapping from keysym 0xffe4 (which is on key code 105)
to braceleft (keysym 0x7b, key code 34)
sig_handler running...
Intercepted key event 3, key code 36
Intercepted key event 2, key code 105
Key pressed!
Intercepted key event 3, key code 105
Key released!
Generating bracketleft!
Key numer is 34
Ignoring generated event.
Ignoring generated event.
[Intercepted key event 2, key code 37
Intercepted key event 2, key code 54
^CCaught signal 2!
sig_handler exiting...
main exiting

It should output braceleft but instead it outputs bracketleft. On my keyboard these two are on the same key but braceleft is the shifted version of bracketleft. I see the same behaviour for various other symbols (tested with asciitilde, at, question).

I'm pretty sure that the problem is due to the fact that we store key codes rather than keysyms. I guess the reason for using key codes is that XTestFakeKeyEvent only accepts key codes. A possible fix is to store keysyms and use createKeyEvent along with XSendEvent to create the key presses (there's some C code for that here).

I'm going to have a go at doing this now, but I thought I should ask for input first because I have absolutely zero experience programming using X and almost no experience using C (I've done a lot of C++ though, which has helped me understand your code). So, do you think this will work?


An interesting note: this bug does not show up with parenleft/right, for these two cases everything works perfectly even though they are accessed with shift. I think this is because they somehow have their own keycode--xev gives additional information for these two keys (and alt gr, but nothing else): XKeysymToKeycode returns keycode: 187/188. You can examine this behaviour with

xev | grep "XKeysymToKeycode returns keycode:"

and some keyboard mashing. :)

"-t" Flag Not Using Default

Not a big issue, but if you specify the "-t" flag without giving a value, the program chokes. I'm running the following command:

xcape -d -t -e "Mode_switch=Escape"

It says "Mode_switch=Escape" isn't a command line option, so it appears the "-t" is consuming "-e" as the timeout delay, leaving the "Mode_switch..." clause stranded.

doesn't start from .xinitrc

I've tried writing the xcape expression I want to enable in my .xinitrc but it doesn't work. Where should I launch the xcape command ?
Here's my .xinitrc:

#!/bin/sh
#
if [ -d /etc/X11/xinit/xinitrc.d ]; then
  for f in /etc/X11/xinit/xinitrc.d/*; do
    [ -x "$f" ] && . "$f"
  done
  unset f
fi
[ -f ~/.xprofile ] && source ~/.xprofile
[[ -f ~/.dotfiles/Xresources ]] && xrdb -merge ~/.dotfiles/Xresources
[[ -r ~/.config/colors/default.xresources ]] && xrdb -merge ~/.config/colors/default.xresources
xsetroot -cursor_name left_ptr
exec dwm & wmpid=$!
if [ -f $HOME/.dotfiles/xbindkeysrc ]; then
    /usr/bin/xbindkeys --file $HOME/.dotfiles/xbindkeysrc &
fi
if [ -f $HOME/.dotfiles/xmodmaprc ]; then
    /usr/bin/xmodmap $HOME/.dotfiles/xmodmaprc &
fi
feh --bg-fill "Media/Pictures/c&h.jpg"
unclutter -grab &
redshift -l 44.5075:11.3514 &
dropboxd
numlockx &
kupfer --no-splash &
eval $(cat ~/.fehbg)
xcape
wait $wmpid

Control_L='Control_L|Escape' not working in vimperator

Hello,

I'm not able to use xcape within vimperator.
It looks like it's interpreting my keystroke before xcape change it.

Edit :
In insert mode when I press Control_L my cursor is set at the start of the line, I've got the same issue in my terminal. Usually, in my terminal, when I press Escape it displays some proposals.

Edit 2:
Nevermind, I misunderstood the meaning of the "|" ...
'Control_L=Escape' works fine, even tho my cursor is still moving, but it's not a big issue.

Regards

Shift_L=parenleft;Shift_R=parenright generates '9' and '0', not '(' and ')'

I've seen this bug a few times; it seems to be system-specific.

On my laptop, I'm running server 1.17.2-2 and libX11 1.6.3-1 on Arch Linux; this configuration works. On my desktop, I'm running server 1.14.7_5,1 and libX11 1.6.2_3,1 on FreeBSD 10.2-BETA2, and get this.

Here's xcape generating Shift_L => '9':

KeyPress event, serial 29, synthetic NO, window 0x2400001,
    root 0x2bd, subw 0x0, time 77669581, (-449,135), root:(1702,575),
    state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0x2400001,
    root 0x2bd, subw 0x0, time 77669633, (-449,135), root:(1702,575),
    state 0x1, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

MappingNotify event, serial 32, synthetic NO, window 0x0,
    request MappingKeyboard, first_keycode 8, count 248

KeyPress event, serial 32, synthetic NO, window 0x2400001,
    root 0x2bd, subw 0x0, time 77669633, (-449,135), root:(1702,575),
    state 0x0, keycode 18 (keysym 0x39, 9), same_screen YES,
    XLookupString gives 1 bytes: (39) "9"
    XmbLookupString gives 1 bytes: (39) "9"
    XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0x2400001,
    root 0x2bd, subw 0x0, time 77669633, (-449,135), root:(1702,575),
    state 0x0, keycode 18 (keysym 0x39, 9), same_screen YES,
    XLookupString gives 1 bytes: (39) "9"
    XFilterEvent returns: False

and here's Shift + 9 => '(':


KeyPress event, serial 34, synthetic NO, window 0x2400001,
    root 0x2bd, subw 0x0, time 77725149, (-449,135), root:(1702,575),
    state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 34, synthetic NO, window 0x2400001,
    root 0x2bd, subw 0x0, time 77725397, (-449,135), root:(1702,575),
    state 0x1, keycode 18 (keysym 0x28, parenleft), same_screen YES,
    XLookupString gives 1 bytes: (28) "("
    XmbLookupString gives 1 bytes: (28) "("
    XFilterEvent returns: False

KeyRelease event, serial 34, synthetic NO, window 0x2400001,
    root 0x2bd, subw 0x0, time 77725473, (-449,135), root:(1702,575),
    state 0x1, keycode 18 (keysym 0x28, parenleft), same_screen YES,
    XLookupString gives 1 bytes: (28) "("
    XFilterEvent returns: False

KeyRelease event, serial 34, synthetic NO, window 0x2400001,
    root 0x2bd, subw 0x0, time 77725597, (-449,135), root:(1702,575),
    state 0x1, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

If I give the mapping as Shift_L=0x28;Shift_R=0x29, I get the same results.

I'm stumped.

Support other keys

What do you think about adding support for other keys and mappings?
I did some work on this functionality here: https://github.com/polachok/xcape/tree/multikey. It's not the best code ever, but works for me. Do whatever you feel right to it, merge it or not.

I use it like this: xcape -e 'Shift_L=Shift_L|parenleft,Shift_R=Shift_R|parenright;Control_L=Escape'

make enter key act as 'super' key when held

As the title says, I want to make the enter key act as an extra modifier as the 'super' key (i.e. the 'windows' key) when held (as part of a key chord), but act as a normal enter when just pressed by itself.

Following from the example in the README, I tried the following:

spare_modifier='Hyper_L'
xmodmap -e "keycode 36 = $spare_modifier" &
xmodmap -e "remove mod4 = $spare_modifier" &
xmodmap -e "add Super_R = $spare_modifier" &
xmodmap -e 'keycode any = Return' &
xcape -e "$spare_modifier=Return" &

in .xinitrc, but it didn't seem to work. As in, the enter key still works, produces an enter when you tap the enter key. But holding it down and pressing it as part of a chord does not produce a Super_R.

36 is the keycode for 'Return' (enter key), got from xev.

What am I doing wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.