Search this site


Metadata

Articles

Projects

Presentations

keynav - retire your mouse.

What is keynav?

Another episode in the revolution against mouse-requisite interfaces. It's one more step towards impulse-driven computing.

Enough marketing jargon. keynav is a piece of an on-going experiment to make pointer-driven interfaces easier and faster for users to operate. It lets you move the pointer quickly to most points on the screen with only a few key strokes.

Note that I said pointer, not mouse. The mouse simply drives the pointer. We can drive the pointer with other devices too. keynav turns your keyboard into an fast pointer mover.

What does it do?

You select a piece of the screen. The screen is initially wholely selected. One move will cut that region by half. A move is a direction: up, down, left, and right.

Once you're done moving, you simply indicate (with a key stroke) that you want to move. Boom, cursor moves.

Why it is fast?

keynav is geared towards selecting a piece of the screen very quickly.

Recall from above that you are selecting a region by cutting the previous region by half. This gives us logarithmic scaling. High resolution screens incur about the same number of moves to select an area as smaller screens do.

For example, to select any pixel on a screen with resolution 1920x1200 it would take 21 moves. 21 moves is horrible. There is a bright side!

How often do you really want to click on a single specific pixel on your screen using your mouse? Never, right? Well, maybe almost never. Most of the time you want to:
  • Raise a window and give it focus: 80x80 pixel target (worst: 9 moves)
  • Click on an "OK" button: 60x25 pixels (worst: 11 moves)
  • Click on a text widget to activate it: 80x25 or larger

Watch the demo!

Bored of reading? How about a screencast demonstration? Click here or the image below.
Hopefully the demo gives you a good idea of what keynav does.

Mailing list

The keynav users mailing list is: keynav-users@googlegroups.com

I'll be announcing new versions on this mailing list. Additionally, if you want help or want to contribute patches to keynav, the mailing list is a good place to go.

Supported Platforms

keynav is currently written in C and only works in X11 (Unix graphics environment). I am planning on porting keynav to both Windows and OS X. If you are interested in helping me with this, please contact me! Known working:
  • FreeBSD + Xorg 6.9.0
  • FreeBSD + Xorg 7.2.0
  • Ubuntu Dapper + Xorg 7.0.0
  • Ubuntu Feisty + Xorg 7.2.0
  • Ubuntu Hardy + Xorg 7.2.0
  • Cygwin + Xorg 6.8.x
  • Fedora 9
I've seen strong interest in this software working on other platforms, so I'm doing the best I can. Again, if you're a .NET (or just Windows) or OS X coder, and are willing to help port this, let me know. It's only 200 lines of C in Xlib, so it can't be more than a one-day-long project.

Download it!

keynav-20080614.01.tar.gz

Looking for an older version? Try the keynav releases archive

Build instructions

make keynav

The above should be all you need to do.

How to use it

Run keynav, and activate it by pressing Control+Semicolon. You should see a thin frame on the screen with a cross in it.

The following is the default configuration:
  • h : select the left half of the region
  • j : select the bottom half of the region
  • k : select the top half of the region
  • l : select the right half of the region
  • shift+h : move the region left
  • shift+j : move the region down
  • shift+k : move the region top
  • shift+l : move the region right
  • semicolon : Move the mouse to the center of the selected region
  • spacebar : Move the mouse and left-click
  • escape : Cancel the move

Configuration file

Your config file must live in ~/.keynavrc. Such as /home/jls/.keynavrc

The config file format consists of a keysequence followed by a comma-separated list of commands. For example:
space warp,click 1,end
This would move the mouse, click left mouse button, and finish (close the keynav selector) when you hit spacebar while keynav was active. A sample config file comes with the distribution as 'keynavrc'.

The following is a list of key modifiers: shift, ctrl, alt, or any valid X Keysym, such as Shift_L, etc.

List of commands:
start
Activate keynav
end
Deactivate keynav
cut-left, cut-right, cut-up, and cut-down
Cut half of the selection in a given direction. For example, cut-left will select the left half of keynav selector region. If you attempt to cut the window too small, the operation will abort. Cut can take a percentage value to cut by. The default is ".5"
move-left, move-right, move-up, move-down
Move the selector window a given direction. The movement amount is equal to the width or height of the selector depending on the direction. You cannot move the window outside the bounds of the screen. Move can take percentage value that specifies the distance relative to the size of the window. The default is "1.0"
warp
Move the mouse to the center of the selector
click <button>
Click the given mouse button once. 1 == left, 2 == middle, 3 == right.
doubleclick <button>
Click the mouse button twice, quickly. This can also be achieved by doing "click 1,click 1" in your command sequence.
drag <button> [keyseq]
Toggle dragging mode for the given button. If keyseq is given then that keysequence is held during the initial mouse button down event. This is useful in invocations such as 'drag 1 alt' to do a alt+click-drag on a window to move it.
grid <rows>x<columns> [Added 20080509]
Change the grid layout of the selection. For example, specifying 'grid 3x3' will divde the screen selection into 9 cells, 3 rows and 3 columns. Specifying 'grid 2x3' will divide the screen selection into 6 cells, 2 rows and 3 columns.
cell-select <row>x<column> OR cell-select <cell> [Added 20080509]
Select a specific cell in the grid. The NxM syntax selects the specific row and column. The single number syntax selects the cell numbered counting from the top left to the bottom left. For example, a 3x3 grid would be numbered this way:
1 2 3
4 5 6
7 8 9

47 responses to 'keynav - retire your mouse.'

Showing last 15 comments... (Click here to view all comments)

Dan Fitch wrote at Mon Oct 22 14:58:14 2007...
Finally started trying to use this, and finding that it is a pretty awesome tool. Much better after getting familiar with it than it seems at first.

However, I can't get the keynavrc to use the key combination I want... I would like to use Super_L+apostrophe to start it (capslock being Super_L here, also set to Mod2) but I can't get anything to work.

Neither `Super_L+apostrophe` or `Mod2+apostrophe`  work here. Can anyone clue me in as to why?

Jordan Sissel wrote at Tue Oct 23 03:10:19 2007...
@Dan,

I can confirm your problem. However, I think I have a fix.

1) My code doesn't check for Mod4Mask (typically what Super_L modifies). I've added this now
2) I had trouble getting capslock recognized as Super_L because I already mapped it to Control_L previously. Here is my fix:

% xmodmap - << XMODMAP
remove Lock = Caps_Lock
keycode 66 = Super_L
add Mod4 = Super_L
XMODMAP

I'll put a new release out now. Thanks for the report!

Jeremiah wrote at Thu May 1 04:11:46 2008...
This is awesome - thank you Jordan for making such an inspirational and useful tool!

Dave wrote at Thu May 1 09:14:38 2008...
Nine-grid sounds good - especially if rigged up to handy keybindings (wer, sdf, xcv or 789, 456, 123 in the numpad).

Between Alt-Tab and Gnome Do I only really use the mouse to either reposition windows or to move around inside the active window - I'll have a look at messing with the source to add some extra modes - I'm thinking different start up keys for different modes.

I'll post again if I get anywhere with it.

Mark wrote at Thu May 1 12:04:44 2008...
Made some changes involving parsing the config file, diff here: http://n.ethz.ch/~nevillm/download/keynav.diff
Changes:
* ~/.keynavrc extends defaults rather than replacing them
* "clear" in ~/.keynavrc resets keybindings
* comments can appear anywhere on a line

Feel free to use them if you wish.

Eric wrote at Thu May 1 16:41:48 2008...
I made a slight change to the percent_of function which will interpret an arg >= 1.0 as an absolute value instead of a percentage.

I find this very helpful when targeting a small space that i can get close to in 2 or 3 keystrokes and can then move in 10 px intervals until I'm on target.

Otherwise, after the first 2 or 3 it usually takes several more cuts, or when using the percentage move, it moves too far if the blocks are still large.

|*** 334,339 ****
|--- 334,342 ----
|  if (sscanf(args, "%f", &pct) <= 0)
|  pct = default_val;
|
|+  if (pct >= 1.0)
|+  return pct;
|+
|  value = (int)((num * (pct * precision)) / precision);
|  return value;
|  }

Gwern wrote at Thu May 1 21:13:54 2008...
This looks pretty neat, but the vi bindings are unusable for me, and quartering strikes me as too slow (maybe it's just me, but at that point, I might as well just reach for the trackball).

While you're considering how to make it more flexible, what I'd like to be able to do is divide the screen up in 6 sections, and then bind the six sections to a block of six keys (the Insert/Delete/Home/End/PgUp/PgDwn slab). I think that'd work well for me.

Jordan Sissel wrote at Fri May 2 13:47:20 2008...
Included Mark and Eric's patches in the latest release.

JimmyT wrote at Fri May 2 16:46:11 2008...
Hi Jordan, I and a friend whipped up a C# version.  Can you email me your email address so I can email it to you (over email)?  We don't want to maintain it.  :)

Enko wrote at Sat May 3 10:00:38 2008...
First I wanted to say that keynav is a realy great app and fills in very wide open gap :D.

I have 2 problems with keynav. The first is a bit strange one, I can activate keynav with C-j, this could be possible because j+second modifier equals to ;. You can obtain my xmodmap from https://neo.eigenheimstrasse.de/svn/linux/xmodmap/neo_de.xmodmap to test this.

The second issue maybe related to the first, is that keynav crashes with the following error message:


$ ./keynav
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  12 (X_ConfigureWindow)
  Resource id in failed request:  0x2400001
  Serial number of failed request:  86
  Current serial number in output stream:  88


Thanks a lot for this great piece of software :).

quazibongo wrote at Sun May 4 00:25:33 2008...
I can't view the demonstration video because it's flash.

Can you maybe direct link to the underlying video so I can play it with mplayer or vlc?

Jordan Sissel wrote at Sun May 4 14:10:55 2008...
The demo was made using Wink, which (iirc) only outputs flash. I don't have the original files anymore anyway.

I can try to make a new one, but your best bet is to just install flash, or find a platform with flash.

Jordan Sissel wrote at Thu May 8 13:04:23 2008...
I found a maintainer for the windows version. It should have a project page soon.

Deech wrote at Thu Jun 12 17:01:08 2008...
The xdotool program fails to compile on my machine because sizeof (int) and sizeof (long) both report 4. The compiler complains about a duplicate case in the following method of xdotool.c:

void window_print(Window wid) {
  switch (sizeof(Window)) {
  case sizeof(int):
  printf("%d\n", (int)wid);
  break;
  case sizeof(long):
  printf("%ld\n", (long)wid);
  break;
  default:
  printf("Unknown window storage size (%ld)\n", sizeof(Window));
  }
}

Commenting out the second case fixed the issue. Perhaps some kind of #ifdef is in order.

Thanks for a great tool and concept.

Louis Turk wrote at Tue Dec 16 12:05:26 2008...
Hi Jordan,

A simplification of your idea:

1. Pressing and holding the windows key brings up a grid of 40 rectangles, each with a large bright orang letter, number, or one of the symbols ;',./ centered in the rectangle.

2. Hit the letter, number, or symbol in the rectangle over the object you need to click or move. If precision is adequate, either, (a) release the windows key to automatically click on that icon window, or link, or (b) press the control key down also, and hit the letter, number or symbol in the rectangle in the grid where you want to drag that object. Now release all keys to move it there instantly.

3. Otherwise, keep pressing the windows key and note that the rectangle you just selected is now divided into more rectangles with letters, numbers, or symbols. Precision should now be very good. So pressing a letter, number, or symbol should place the cursor exactly where it needs to be. Now either, (a) release the windows key to automatically click on that icon window, or link, or (b) press the control key down also, and hit the letter, number or symbol in the rectangle in the first grid where you want to drag that object. Now release all keys to move it there instantly.

4. In the unlikely case that precision is still not good enough, the second rectangle can be divided into still a few more rectangles.

All very simple---virtually no learning curve at all. And blazing fast!

Please make sure it works on Ubuntu, and please provide a dvorak version of the .keynavrc file.

Thanks for considering my idea.


Leave a reply

You need javascript enabled to use this form. Anti-spam efforts ongoing. Also, if the comment doesn't show up, it's because the form expired. Go back and copy your comment, reload the form, and resubmit. Apologies if this is a hassle, I'm just playing with antispam methods right now. If this insists on not working, please email me about it.

Name (required)
E-mail (optional, if you want me to be able to email you back)
URL (also optional)
Comment: