LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Desktop (https://www.linuxquestions.org/questions/linux-desktop-74/)
-   -   TouchCursor under Linux ; I can't believe there is no way to do that (https://www.linuxquestions.org/questions/linux-desktop-74/touchcursor-under-linux-%3B-i-cant-believe-there-is-no-way-to-do-that-771470/)

merindol 11-25-2009 08:57 AM

TouchCursor under Linux ; I can't believe there is no way to do that
 
Hi there.

I'm trying to do something like TouchCursor does (cf. touchcursor.com, there is a video). It uses the spacebar as a meta-key to give access to the navigation keys (and more) from the main keyboard, like Space+L for Right-key (see the video).

Atm, it almost works. E.g. I can Shift+Ctrl+Space+L to select the word to the right of the cursor.

But my spacebar no longer works as a spacebar. I'm trying to find a way to make it works like with TouchCursor : when I press than release the spacebar, and only if no other keys have pressed, it should spawn a space character.

I tried with Xbindkeys :
Code:

"/usr/bin/xvkbd -xsendevent -text '\[space]'"
Mode_switch+Release

but it prevents the new arrow keys from working. And, even, It wouldn't give us the result we expect (aka. print a space character when only the space bar is pressed and then released, without any other key pressed in the mean time)

Anyone has an idea ? It seams quite tricky.

Btw, here is the ~/.Xmodmap code for the navigation pad feature (keycode 65 is my spacebar ; you can use an other key to test safely) :
Code:

keycode 65 = Mode_switch Mode_switch space space nobreakspace U202F
add mod3 = Mode_switch
keysym i = i I Up NoSymbol icircumflex Icircumflex
keysym k = k K Down NoSymbol idiaeresis Idiaeresis
keysym j = j J Left NoSymbol udiaeresis Udiaeresis
keysym l = l L Right NoSymbol U0140 U013F
keysym h = h H Prior NoSymbol eth ETH
keysym n = n N Next NoSymbol notsign rightarrow
keysym u = u U Home NoSymbol ucircumflex Ucircumflex
keysym o = o O End NoSymbol oe OE
keysym comma = comma question Delete NoSymbol questiondown U2026
keysym p = p P BackSpace NoSymbol ocircumflex Ocircumflex
keysym y = y Y Insert NoSymbol ydiaeresis Ydiaeresis

Maybe should I try Xkbd ? Is it more powerful ?

Regards.

business_kid 11-26-2009 04:08 AM

Welcome to LQ.
If you really want this, use one or more of the standard meta keys (from memory - Ctrl, Alt, Shift, AltGr) and you might be able to map this function into .Xmodmap. I had a go at this in times gone by for the €uro (euro = €)sign

merindol 11-27-2009 03:30 AM

Hi and thanks for the answer.

The xmodmap mapping is not really the problem. Currently I'm using the Menu key but it's not really convenient. Using the spacebar as the modifier would be a lot more comfortable. But then there is the problem to still be able to enter space characters... thus my post.

Regards.

business_kid 11-28-2009 03:16 AM

One function per key, I'm afraid.

The design of the qwerty keyboard is far from ideal. If finding windows utilities in linux is whatyou want, I think your luck is out. You could try

1. Running touchcursor under wine, but it would probably barf or malfunction. You have a copy.
2. If speed is your aim and you're a regular typist, why not go for the dvorak keyboard? I hear much higher speeds are possible once you learn it. Linux accomodates it with keymaps and the like.

mjstone 01-08-2010 01:35 PM

Hi. I'm the author of TouchCursor.

I recently released TouchCursor under the GPL*. Obviously this means you can play around with the TC source and see if it's any help. If you get anywhere I'd be very interested in integrating a Linux version into the project. (I'm currently a total Linux newbie and I can't use Linux in earnest because I'm so dependent on TouchCursor -- so Catch 22 ;-) )

(*This is my first post here so I'm not allowed to post the URL -- It's on SourceForge; I'm sure you'll find it.)

Martin.

MTK358 01-08-2010 01:46 PM

I wonder if it's possible for a program to "steal" all X keyboard events, no matter what window is focused, and is it possible for the same program to "repeat" the events to the focused window?

If so, it might be possible to make a program that filters the keyboard events and can modify them however you like, including modifying the actions of other keys when space is held down.

merindol 01-09-2010 04:59 AM

Hello.

Mjstone, thanks to put TouchCursor under GPL, it's really nice and smart.

I've managed to quite make it work under linux but it's unusable : when writing a text the spacebar lags behind other keys ; it's impossible to write at a decent speed.

I used xbindkeysrc.scm guile configuration file (it's possible to write complex functions).

I do think the only good way to do that is to work on a lower level than those dekstop apps.

Regards.

MTK358 01-09-2010 08:08 AM

I was thinking how to do this, here I made a pseudo-code template of what it might be like:

Code:

int main() {
        bool modPressed = false;
        bool sendSpace;
        Event event;
        while(true) {
                event  = stealXKeyEvent();
                if(event.key == KEY_SPACE) {
                        if(event.type == KEY_PRESSED) {
                                modPressed = true;
                        } else {
                                modPressed = false;
                                if(sendSpace) {
                                        sendXKeyEvent(KEY_SPACE, KEY_PRESSED);
                                        sendXKeyEvent(KEY_SPACE, KEY_RELEASED);
                                }
                        }
                } else {
                        if(modPressed) {
                                sendSpace = false;
                                if(event.key == KEY_I) {
                                        sendXKeyEvent(KEY_UP, event.type);
                                } else if(event.key == KEY_K) {
                                        sendXKeyEvent(KEY_DOWN, event.type);
                                } else if(event.key == KEY_J) {
                                        sendXKeyEvent(KEY_LEFT, event.type);
                                } else if(event.key == KEY_L) {
                                        sendXKeyEvent(KEY_RIGHT, event.type);
                                } else if(event.key == KEY_U) {
                                        sendXKeyEvent(KEY_HOME, event.type);
                                } else if(event.key == KEY_O) {
                                        sendXKeyEvent(KEY_END, event.type);
                                } else if(event.key == KEY_H) {
                                        sendXKeyEvent(KEY_PGUP, event.type);
                                } else if(event.key == KEY_N) {
                                        sendXKeyEvent(KEY_PGDN, event.type);
                                } else if(event.key == KEY_Y) {
                                        sendXKeyEvent(KEY_INSERT, event.type);
                                } else if(event.key == KEY_M) {
                                        sendXKeyEvent(KEY_DELETE, event.type);
                                } else {
                                        sendSpace = true;
                                }
                        } else {
                                sendXKeyEvent(event);
                        }
                }
        }
}


mjstone 01-10-2010 08:24 AM

Well the the TouchCursor code is a bit more complicated -- I needed six states to handle all the cases I cared about, plus some extra state for delaying emitted key-presses.

For example one thing your pseudo-code doesn't handle is overlapping key presses, e.g. [Space-down, L-down, Space-up, L-up], which is the sort of thing that happens a lot when typing fast (for some typists, at least). In this case the program should emit a Space then L, but it doesn't know that until it gets the Space-up.

The interesting bit, for me at least, is what goes in your stealXKeyEvent() and sendXKeyEvent() functions, and how to insert a program into the chain of programs that process the global stream of keyboard events.

MTK358 01-10-2010 12:39 PM

Quote:

Originally Posted by mjstone (Post 3821133)
The interesting bit, for me at least, is what goes in your stealXKeyEvent() and sendXKeyEvent() functions, and how to insert a program into the chain of programs that process the global stream of keyboard events.

I don't know either, and I can't continue until I do.

bobshaffer2 01-11-2010 09:29 PM

You can get a program to grab the keyboard and modify the events and send them to the focused window like what was discussed here, BUT you must realize that some other programs may (and many will) still try to grab the keyboard themselves and/or ignore XEvents for keyboard input. xterm, for instance, has a "Secure Keyboard" mode that wouldn't work if another program had grabbed the keyboard already. Programs run through wine try to grab the keyboard pretty often too. So, while this solution is worth trying, I can be fairly certain you will run into a problem or two with it.

In order to get something completely functional, you might have to actually hack the xorg keyboard driver, and then make a patch for it.

bobshaffer2 01-11-2010 10:04 PM

Looking again at what was posted, I see you were trying to determine a few things...

How to "insert a program into the chain of programs that process the global stream of keyboard events": this is done partly by "grabbing" the keyboard. I'm not sure of the exact code, but the function is XGrabKeyboard(Display*,Window,Bool,int,int,Time). You can send the keys to a program using XSendEvent() and using XKeyEvents. You should realize that you need to send an event for the key being pressed and another for it being released. Determining where to send the event may be the difficult part. It should be possible, but I'm not sure how. One way would be to ask for XFocusChangeEvents I guess and then keep track of who has focus. I don't know if all window managers will agree to give those events, but it seems reasonable enough to try.

Like I said, some programs will try to grab the keyboard themselves and/or ignore XKeyEvents. I would be curious how well this all works if you get it all figured out, though.

MTK358 01-12-2010 07:11 AM

Quote:

Originally Posted by bobshaffer2 (Post 3823217)
Looking again at what was posted, I see you were trying to determine a few things...

How to "insert a program into the chain of programs that process the global stream of keyboard events": this is done partly by "grabbing" the keyboard. I'm not sure of the exact code, but the function is XGrabKeyboard(Display*,Window,Bool,int,int,Time). You can send the keys to a program using XSendEvent() and using XKeyEvents. You should realize that you need to send an event for the key being pressed and another for it being released. Determining where to send the event may be the difficult part. It should be possible, but I'm not sure how. One way would be to ask for XFocusChangeEvents I guess and then keep track of who has focus. I don't know if all window managers will agree to give those events, but it seems reasonable enough to try.

Like I said, some programs will try to grab the keyboard themselves and/or ignore XKeyEvents. I would be curious how well this all works if you get it all figured out, though.

I'll try looking into those later, also I wonder if there is an easy way to do it so that it does not rely on X (that is, would still work in the command line)?

bobshaffer2 01-12-2010 01:10 PM

You could write a kernel module to do it. IDK if there would be any easier way. If you did that, it would completely cover everything. Other than that you would probably be looking at maintaining two projects: one for the console and one for X. The driver would almost certainly need to built into the kernel rather than a module, and it almost seems like the standard keyboard driver would have to NOT be built in, otherwise it would probably claim the device and cause problems. I personally think doing it for just X would be the easy solution, but the other would probably be more flexible.

MTK358 01-12-2010 01:51 PM

Well, I don't know anything whatsoever about the kernel (but I hope that will change), so I guess I should go the X way.

EDIT: using X will also give me the opportunity to integrate a status icon and settings dialog (probably in GTK+).


All times are GMT -5. The time now is 05:50 PM.