LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Desktop
User Name
Password
Linux - Desktop This forum is for the discussion of all Linux Software used in a desktop context.

Notices

Reply
 
Search this Thread
Old 11-25-2009, 09:57 AM   #1
merindol
LQ Newbie
 
Registered: Nov 2009
Posts: 3

Rep: Reputation: 0
Question 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.
 
Old 11-26-2009, 05:08 AM   #2
business_kid
Guru
 
Registered: Jan 2006
Location: Ireland
Distribution: Slackware & Android
Posts: 6,607

Rep: Reputation: 583Reputation: 583Reputation: 583Reputation: 583Reputation: 583Reputation: 583
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
 
Old 11-27-2009, 04:30 AM   #3
merindol
LQ Newbie
 
Registered: Nov 2009
Posts: 3

Original Poster
Rep: Reputation: 0
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.
 
Old 11-28-2009, 04:16 AM   #4
business_kid
Guru
 
Registered: Jan 2006
Location: Ireland
Distribution: Slackware & Android
Posts: 6,607

Rep: Reputation: 583Reputation: 583Reputation: 583Reputation: 583Reputation: 583Reputation: 583
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.
 
Old 01-08-2010, 02:35 PM   #5
mjstone
LQ Newbie
 
Registered: Jan 2010
Posts: 2

Rep: Reputation: 0
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.
 
Old 01-08-2010, 02:46 PM   #6
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714
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.
 
Old 01-09-2010, 05:59 AM   #7
merindol
LQ Newbie
 
Registered: Nov 2009
Posts: 3

Original Poster
Rep: Reputation: 0
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.
 
Old 01-09-2010, 09:08 AM   #8
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714
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);
			}
		}
	}
}
 
Old 01-10-2010, 09:24 AM   #9
mjstone
LQ Newbie
 
Registered: Jan 2010
Posts: 2

Rep: Reputation: 0
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.
 
Old 01-10-2010, 01:39 PM   #10
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714
Quote:
Originally Posted by mjstone View Post
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.
 
Old 01-11-2010, 10:29 PM   #11
bobshaffer2
LQ Newbie
 
Registered: Mar 2005
Location: Ohio
Distribution: Several (Gentoo, Red Hat/Fedora, HP-UX, Helix)
Posts: 25

Rep: Reputation: 17
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.
 
Old 01-11-2010, 11:04 PM   #12
bobshaffer2
LQ Newbie
 
Registered: Mar 2005
Location: Ohio
Distribution: Several (Gentoo, Red Hat/Fedora, HP-UX, Helix)
Posts: 25

Rep: Reputation: 17
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.
 
Old 01-12-2010, 08:11 AM   #13
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714
Quote:
Originally Posted by bobshaffer2 View Post
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)?
 
Old 01-12-2010, 02:10 PM   #14
bobshaffer2
LQ Newbie
 
Registered: Mar 2005
Location: Ohio
Distribution: Several (Gentoo, Red Hat/Fedora, HP-UX, Helix)
Posts: 25

Rep: Reputation: 17
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.
 
Old 01-12-2010, 02:51 PM   #15
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714
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+).

Last edited by MTK358; 01-12-2010 at 02:56 PM.
 
  


Reply

Tags
keyboard, xbindkeys, xmodmap


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Linux Training Tips - Boot Linux from a Linux Installation CD or a Linux Live CD to L beibei Linux - General 1 10-29-2009 05:25 AM


All times are GMT -5. The time now is 01:41 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration