You are not logged in.

#1 2007-03-10 09:40:54

Master One
Member
From: Austria
Registered: 2007-01-21
Posts: 242

How to map a key-combination to a keyboard-button?

My ThinkPad has two extra buttons, which I have set up in .Xmodmap as follows:

keycode 234 = XF86Back
keycode 233 = XF86Forward

This works as forward and back in Konqueror, but not in Firefox (and most likely in a lot of other apps).

Is there a way, to assign "Alt_L|Left" and "Alt_L|Right" to these buttons, in addition to XF86Back & XF86Forward?

Offline

#2 2007-03-10 12:08:10

espo
Member
From: Stuttgart - Germany
Registered: 2006-08-11
Posts: 74

Re: How to map a key-combination to a keyboard-button?

Maybe its possible to do this with xbindkeys. You can take a look at it.

Greetings
eSpo

Offline

#3 2007-03-10 14:59:18

ralvez
Member
From: Canada
Registered: 2005-12-06
Posts: 1,629
Website

Re: How to map a key-combination to a keyboard-button?

I use xbindkeys but I have been unable to do that so far.
The way xbindkeys works is to enter a command and a key or key combination but ... since you are required to enter a specific command (and I cannot find what specific command would make FF go back and forth) I've been unable to do it.
I'm considering to write a small program that I could invoke with xbindkeys but have not had time for that so far.

Offline

#4 2007-03-21 17:00:55

SiD
Member
From: Germany
Registered: 2006-09-21
Posts: 729

Re: How to map a key-combination to a keyboard-button?

there is a firefox-extension called "keyconfig", maybe that's what you're looking for...
http://extensionroom.mozdev.org/more-info/keyconfig

Last edited by SiD (2007-03-21 17:19:33)

Offline

#5 2007-03-21 17:11:38

Master One
Member
From: Austria
Registered: 2007-01-21
Posts: 242

Re: How to map a key-combination to a keyboard-button?

I am more thinking of using new Epiphany 2.18 instead of Firefox in the future (if I should go for Gnome 2.18, when Arch packages are available), so a solution based on a Firefox extension is not the way to go. Epiphany also uses "Alt_L|Left" and "Alt_L|Right" for back & forward, so the issue still remains.

Offline

#6 2007-03-21 17:24:14

SiD
Member
From: Germany
Registered: 2006-09-21
Posts: 729

Re: How to map a key-combination to a keyboard-button?

I just found this,
you are not interested in a solution for FF but If someone else has this problem and read this thread...
https://addons.mozilla.org/firefox/2282/

If there is an Epiphany-Command for navigate forwards/backwards you could do it with xbindkeys.
You have to bind the keycodes to that command (if one exists) in the config-file of xbindkeys...

edit:
does it work if you press
Alt-L  + right
Alt_L + left
?

Last edited by SiD (2007-03-21 17:45:19)

Offline

#7 2007-03-21 18:16:58

Master One
Member
From: Austria
Registered: 2007-01-21
Posts: 242

Re: How to map a key-combination to a keyboard-button?

Epiphany uses ALT+LEFT & ALT+RIGHT for going one page back/forward (sorry if this wasn't clear from my last posting, it's the same as "Alt_L|Left" and "Alt_L|Right" which I use in my .imwheelrc for mapping these key-combination to the thumb-buttons of my Intellimouse Explorer).

I don't know, how this should work using xbindkeys and a command, because how should it be possible to navigate backwards/forward in Epiphany (or any other browser) by letting xbinkeys execute a command?

This is not about generating a keyboard shortcut for executing a command or program using a keycombination, but using the mentioned extra-keyboard-buttons of my ThinkPad (which have keycodes 233 & 234) for navigating backwards/forward in browsers like Firefox of Epiphany, which just act on ALT+LEFT and ALT+RIGHT for this functionality.

imwheel does that job just fine for mapping mouse-buttons to keys or key-combinations, but xmodmap or xbindkeys does not seem to be suited for generating a fake-key-event based on another keypress-event. Still no idea, what to do, and how to get that kind of funktionality from these two extra-keyboard-buttons.

Offline

#8 2007-03-21 18:51:51

SiD
Member
From: Germany
Registered: 2006-09-21
Posts: 729

Re: How to map a key-combination to a keyboard-button?

Master One wrote:

I don't know, how this should work using xbindkeys and a command, because how should it be possible to navigate backwards/forward in Epiphany (or any other browser) by letting xbinkeys execute a command?

It would work if the browser can be controled from the console by a command; like "audacious -f" to play next song in audacious playlist for example...

I have never used xmodmap, but is it not possible to bind two keys to one keycode?
maybe something like this: keycode 233 = Alt_L + Left

Last edited by SiD (2007-03-21 19:01:27)

Offline

#9 2007-03-21 19:10:50

Master One
Member
From: Austria
Registered: 2007-01-21
Posts: 242

Re: How to map a key-combination to a keyboard-button?

It does not look like Epiphany or Firefox can be controlled from the commandline (how should this even work, if you have more than one instance of these programs open?).

I am not an expert concerning xmodmap, but the manpage didn't tell me anything that would hint to a possible use of a key-combination.

Offline

#10 2007-03-22 09:15:34

Master One
Member
From: Austria
Registered: 2007-01-21
Posts: 242

Re: How to map a key-combination to a keyboard-button?

Ok, I found How to inject fake keystrokes in the ThinkWiki. As it looks to me, only FVWM can produce fake button events out of the box, for any other WM you need to program that functionality by yourself.

I am not a programmer. Can somebody with the knowledge please have a look, and adapt the little program shown at the above mentioned link, to fake ALT+LEFT instead of ESC?

Offline

#11 2007-03-22 13:45:34

SiD
Member
From: Germany
Registered: 2006-09-21
Posts: 729

Re: How to map a key-combination to a keyboard-button?

i am not a programmer too, but i think you have to figure out the keycode for ALT+LEFT  and use it as value for the KEYCODE_ALT_LEFT constant. But I don't know if there are keycodes for key-combinations.
(I tested it with the keycode for Fn+Pos1 as value for  KEYCODE_ALT_LEFT on my laptop, and it works..)

#include <X11/extensions/XTest.h>

#define KEY_DOWN True
#define KEY_UP   False

#define KEYCODE_ALT_LEFT <keycode for Alt + Left>

int main() {
  Display *dpy = XOpenDisplay(NULL);
  if (!dpy) return 1;
  XTestFakeKeyEvent(dpy, KEYCODE_ALT_LEFT, KEY_DOWN, CurrentTime);
  XTestFakeKeyEvent(dpy, KEYCODE_ALT_LEFT, KEY_UP, CurrentTime);
  XCloseDisplay(dpy);
  return 0;
}

the output of xev shows this on my laptop

Alt_L + Left pressed

  state 0x8, keycode 100 (keysym 0xff51, Left)

only Left pressed

 state 0x0, keycode 100 (keysym 0xff51, Left)

so the difference is in the state,
but I don't know how to use this information for the programm or Xmodmap.... sad

Offline

#12 2007-03-22 14:03:29

Master One
Member
From: Austria
Registered: 2007-01-21
Posts: 242

Re: How to map a key-combination to a keyboard-button?

ALT_LEFT has its own keycode (64), and yes, the only way to differ between LEFT and ALT+LEFT is the change of state. Someone with programming skills may come up with a solution. Anyone?

Offline

#13 2007-03-23 06:53:58

veek
Member
Registered: 2006-03-10
Posts: 167

Re: How to map a key-combination to a keyboard-button?

Hey Master One,

I was kind of interested in your problem, and I figured it wouldn't be too hard to do what you wanted so I investigated some.
Actually it turned out to be more difficult than I thought due to X security considerations.
There's no way to map a keycode and have it generate multiple keysyms, so the only way is to write a program to generate the desired
sequence of keypresses.

I found some code that generated keypress events using a couple standard Xlib functions (Here's a link to the original code: http://www.doctort.org/adam/nerd-notes/ … event.html.)
Although very useful, unfortunately, it didn't work. The problem was the fake key events were marked "synthetic," so that the target program would know they were fake.
Most programs ignore synthetic keypresses as a security measure to prevent the app from being controlled by a malicious program.

So I spent quite a while hunting, and eventually I found a way to send keypresses that are not marked synthetic by using an X extension called XTest.
I modified the program and tested it, and it works perfectly. 

I use Ion as my window manager so I was able to just map one of my extra keys (I have an internet keyboard with unused keys) to
the fake key program. Several other window managers including beryl have a facility for mapping commands to keys, but if yours doesn't
you can just use xbindkeys which you mentioned before.

So here's the source code:

// Send a fake keystroke event to an X window.
// by Adam Pierce - http://www.doctort.org/adam/
// modified by veek in order to generate keystrokes that aren't marked "synthetic," 
// so the receiving application thinks it's receiving genuine keyboard input.

#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <string.h>

// The key code to be sent.
// A full list of available codes can be found in /usr/include/X11/keysymdef.h
#define KEYCODE XK_F7
#define KEYCODE1 XK_Alt_L
#define KEYCODE2 XK_Left
#define KEYPRESS 1
#define KEYRELEASE 0

main()
{
// Obtain the X11 display.
    Display *display = XOpenDisplay(0);
    if(display == NULL) {
        printf("Display not found\n");
        return -1;
    }

// Get the root window for the current display.
    Window winRoot = XDefaultRootWindow(display);

// Find the window which has the current keyboard focus.
    Window winFocus;
    int    revert;
    XGetInputFocus(display, &winFocus, &revert);

// Send ALT + LEFT key sequence to currently targeted window 
        XTestFakeKeyEvent(display, XKeysymToKeycode(display, KEYCODE1), KEYPRESS, 0);
        XTestFakeKeyEvent(display, XKeysymToKeycode(display, KEYCODE2), KEYPRESS, 0);
        XTestFakeKeyEvent(display, XKeysymToKeycode(display, KEYCODE2), KEYRELEASE, 0);
        XTestFakeKeyEvent(display, XKeysymToKeycode(display, KEYCODE1), KEYRELEASE, 0);

// Done.
    XCloseDisplay(display);
    return 0;
}

Compile command:

g++ -o XFakeKey XFakeKey.cpp `pkg-config --libs --cflags x11 xtst`

You can copy the source code and save it to a file called XFakeKey.cpp.
Then use the compile command above, and it will generate an executable called XFakeKey.
Map the executable to whatever key you want, and you're good to go. You'll be able to
use your extra button to go back on any browser that uses that ALT + Left key combo.

Hope this is what you were after.

Offline

#14 2007-03-23 07:05:03

veek
Member
Registered: 2006-03-10
Posts: 167

Re: How to map a key-combination to a keyboard-button?

I guess you might want to be able to go forward too, huh? I could add it in a jiffy if necessary.

Right now the program is really just a simple hack, but it gets the job done.

Offline

#15 2007-03-23 08:15:33

Master One
Member
From: Austria
Registered: 2007-01-21
Posts: 242

Re: How to map a key-combination to a keyboard-button?

Cool, thanks for taking your time smile

Looks like you have overlooked the provided link to the codesnippet on ThinkWiki, which already revealed the way to go (your solution looks better though), but I just wasn't sure how to adapt it for a key-combination instead of a single key (this must have been a really long line in my brain, because it's so obvious now). Adapting your code for other keys and key-combinations should not be a problem. This is really nice, and surely is of interest for others as well.

Offline

#16 2007-03-23 10:44:23

SiD
Member
From: Germany
Registered: 2006-09-21
Posts: 729

Re: How to map a key-combination to a keyboard-button?

does it work for you MasterOne?

I've tested it in combination with xbindkeys and it does not work correctly. sad
FF goes only back sometimes, but mostly I press the key binded to XFakeKey in xbindkeysrc nothing happens.

@veek
Just an idea:
Maybe you could make KEYCODE1 and KEYCODE2 parameters. So one could run the Programm like this

XFakeKey <keysym1> <keysym2>

Last edited by SiD (2007-03-23 10:47:46)

Offline

#17 2007-03-23 11:22:28

Master One
Member
From: Austria
Registered: 2007-01-21
Posts: 242

Re: How to map a key-combination to a keyboard-button?

SiD wrote:

does it work for you MasterOne? I've tested it in combination with xbindkeys and it does not work correctly. sad
FF goes only back sometimes, but mostly I press the key binded to XFakeKey in xbindkeysrc nothing happens.

Couldn't test it yet. Maybe veek knows, what could be the issue.

SiD wrote:

@veek
Just an idea:
Maybe you could make KEYCODE1 and KEYCODE2 parameters. So one could run the Programm like this

XFakeKey <keysym1> <keysym2>

Yes, that would be the best approach, because then only one version of that app is needed (would be pretty redundant to leave the keys hardcoded in that program). That way 3 keycodes should be handled as parameters, with the possibility, to use just one, two or all three simultaneously.

Offline

#18 2007-03-23 12:48:51

stb
Member
Registered: 2007-03-13
Posts: 40

Re: How to map a key-combination to a keyboard-button?

How about Xmacro?

For usage of key BAR you have to do the following:

1) Enable record extension in Xorg.
2) Create macro foo: xmacrorec2 > foo
3) Edit .xbindkeys:

"xmacroplay :0.0 < ~/foo"
  release+BAR

Works for me.

EDIT

Removed wrong pointing link. Correct one is: http://xmacro.sourceforge.net/

Last edited by stb (2007-03-23 14:15:45)

Offline

#19 2007-03-23 20:13:56

veek
Member
Registered: 2006-03-10
Posts: 167

Re: How to map a key-combination to a keyboard-button?

Master One, you're right I did overlook that code! (Slaps forehead)

stb, I searched quite a bit for a keyboard macro program, and I couldn't find one, good find.
Now I searched again in reference to XTest, and I actually found a couple similar ones.

Given stb's find, the bit of code I posted is probably useless.

That said, I've modified the program so that it takes a pair of keystrokes on the commandline, and fixes the error SiD was experiencing.

Now you can invoke the program with:

XFakeKey Alt_L Left

Or whatever other combination you have in mind.

SiD, I didn't encounter the error you were experiencing in ION, but  I tested it in beryl, and I started experiencing the problem
of the keypresses being ignored randomly. It turns out it's a timing issue, and I added a delay and a few other things that fixes the problem.

// Send a fake keystroke event to an X window.
// by Adam Pierce - http://www.doctort.org/adam/
// modified by veek in order to generate keystrokes that aren't marked "synthetic."

#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

// The key code to be sent.
// A full list of available codes can be found in /usr/include/X11/keysymdef.h
#define KEYPRESS 1
#define KEYRELEASE 0

main(int argc, char **argv)
{       
        int keycode;

// Obtain the X11 display.
        Display *display = XOpenDisplay(0);


        XTestGrabControl(display, 1);
// Send sequence of keysyms to currently targeted window 
        usleep(100000);
        for ( int i = 1; i < argc; i++) {
                
                keycode = XKeysymToKeycode(display, XStringToKeysym(argv[i]));
                XTestFakeKeyEvent(display, keycode, KEYPRESS, CurrentTime);
        }
        XFlush(display);

        XTestGrabControl(display, 1);
        for ( int i = 1; i < argc; i++) {
                keycode = XKeysymToKeycode(display, XStringToKeysym(argv[i]));
                XTestFakeKeyEvent(display, keycode, KEYRELEASE, CurrentTime);
        }
        XFlush(display);

// Done.
        XCloseDisplay(display);
        return 0;
}

You can compile with the same command as before.
One note, the sequence of buttons aren't pressed and released immediately.
Each key is pressed and held until all the key events have been sent and then they're all released,
so it's not very good for an arbitrarily long sequence of commands. It becomes complicated when
you have a sequence where you sometimes want a combination of keys pressed  and sometimes only a single key.

One thing that would work is to use parentheses to group keys that should be held together.
For example to navigate a menu or something: XFakeKeys (Alt_L F1) Right Down Down.
This is something that could be implemented but...

Again it's probably not worth it given the prog stb found, unless someone can think of a reason.

Last edited by veek (2007-03-23 20:24:57)

Offline

#20 2007-03-23 20:43:50

SiD
Member
From: Germany
Registered: 2006-09-21
Posts: 729

Re: How to map a key-combination to a keyboard-button?

veek wrote:

SiD, I didn't encounter the error you were experiencing in ION, but  I tested it in beryl, and I started experiencing the problem
of the keypresses being ignored randomly. It turns out it's a timing issue, and I added a delay and a few other things that fixes the problem.

the modified version works fine.

stb wrote:

1) Enable record extension in Xorg.

How can I do this?

Offline

#21 2007-03-23 21:53:21

stb
Member
Registered: 2007-03-13
Posts: 40

Re: How to map a key-combination to a keyboard-button?

How can I do this?

Put this under the section "Module" in your xorg.conf:

    Load    "record"

librecord.so should be in /usr/lib/xorg/modules/extensions.

Offline

#22 2010-01-17 17:38:27

cprice404
Member
Registered: 2010-01-17
Posts: 1

Re: How to map a key-combination to a keyboard-button?

Almost three years later... just wanted to say "THANKS" to you guys (and especially veek) for this thread.  Solved a problem that I've been battling for the better part of a day, and works like an absolute charm.  awesome!!

Offline

#23 2010-01-17 17:43:27

Inxsible
Forum Fellow
From: Chicago
Registered: 2008-06-09
Posts: 9,148

Re: How to map a key-combination to a keyboard-button?

cprice404 wrote:

Almost three years later... just wanted to say "THANKS" to you guys (and especially veek) for this thread.  Solved a problem that I've been battling for the better part of a day, and works like an absolute charm.  awesome!!

glad it helped you, but as a rule its better not to bump very old threads because they will be closed by the mods. And in most cases 3 year old info may not be applicable to the current Arch release causing more confusion among other, especially newer users.


Forum Rules

There's no such thing as a stupid question, but there sure are a lot of inquisitive idiots !

Offline

Board footer

Powered by FluxBB