Home > Keyboard Release, Keyboards > Improved Keyboard Layout Program

Improved Keyboard Layout Program

I made some modifications to my keyboard layout program, and it now runs about twice as fast. On my laptop, it can score 12,000 layouts per second — this is six times as fast as Michael Capewell’s program.

You can download it here.

  1. Atle
    July 16, 2010 at 1:55 am


    I finally set up MS Visual C++. Before I study it, will your program work right off?

    • July 16, 2010 at 2:05 am

      You mean, will it work with Visual C++? It should, as far as I know.

  2. Atle
    July 18, 2010 at 4:27 pm

    I have to say thank you. I created the perfect ‘Vere Keyboard’ for me. Keyboard design can be such a game of shifting sands, but with the info from the different experiments you did for me, the discussion also with Feurry, and my own hypothetical keyboard trials, somehow all the pieces fell into place. I was able to intuitively assemble each component of the keyboard – when suddenly I felt a sense of resolution and completion.

  3. dphrei
    December 9, 2010 at 1:25 am

    it so happens that i need a layout like the one described in “have we been mistaken all along?” and i really need some orientation on doing the following with the layout program:

    I want to describe a keyboard with only 24 keys (three rows of eight), eliminating sideways and diagonal reaches from the evaluation.

    I want to exclude vkxjqz and punctuation from the evaluation.
    (i’m old enough to decide where to put those).

    only pinky is treated as weak. all other fingers are equal.
    no penalty on top or bottom row.

    i’m good at concepts but poor at understanding code. any advice greatly appreciated.

    • December 9, 2010 at 1:49 am


      I’m glad you want to use my program to design a keyboard layout, and I think I can help. Do you see how to change the weightings on different attributes (same finger, row changing, etc)?

      If you remove vkxjqz and the punctuation, that only leaves 20 characters, while it leaves 24 spots. How does that work?

      Modifying the program in the way you describe will require pretty thorough knowledge of the program itself. Once I know exactly what you want I’ll make the appropriate modifications to the code and post it here.

  4. dphrei
    December 13, 2010 at 11:25 pm

    apologies. my last post was a bit vague. also i thought of a way that leaves the 30key grid alone. btw, i was unable to compile! all due to my inexperience. i can edit values.h but on deeper matters, i got lost. anyway, i hope this description is clearer…

    here’s MTGAP 3.13.1 after i butchered it.
    #’s are keys that will NOT be evaluated.
    the 20 commonest letters — etaoinshrdlcumpfgwy — are placed on the remaining keys that WILL be evaluated.

    # p u c # # l d b #
    r i e s # # n t a o
    # w f g # # h m y #

    first, i want to lock those ‘#’ keys in place so that only the letters are rearranged. the idea is to optimise only common letters and to keep them on the easiest reaches.

    once that’s done, i want to flip the situation, locking those common letters in place and have the program arrange vkxjqz,.”- in the remaining spaces.
    (but honestly, it would be easier to do this second stage manually.)

    rather than redefining keyboard geometry, i would like the ability to lock specific keys out of the evaluation.

    i guess that means having an exclusion list somewhere, counting the number of keys to be evaluated, and taking an equal number of characters from layoutstore.txt

    how about a matrix representing 30 keys. these keys are either on or off. 0s are evaluated and 1s are not:

    this would give both the number of keys to evaluate and their positions.
    of course you understand this stuff far better; i’m just sharing my thoughts.

    Q. where in the source is the bottom row penalised? i need to remove this bias, giving it the same values as the top row.

    Q. how to lock specific keys out of the evaluation? has this feature yet to be invented? could save a lot of number crunching.

    Q. previously, i built programs using configure-make-install. mtgap sources lack a makefile. i tried ‘gcc -o mtgap ./main.c’ and got a page full of warnings. i feel i need guidance or a link to a howto. sorry to be a pain. (i’m using the debian-based linux mint).

    • December 14, 2010 at 3:06 am

      Modifying the program to ignore certain preset keys would be feasible. Modifying it to ignore any set of keys would be a good deal more difficult, although still possible. I probably won’t be able to look much into this until next week, when I will have some more free time.

      Q1. In values.c there is an array called distanceCosts. Every individual position on the keyboard has a different cost. You can change those numbers to whatever you want. If you don’t know which numbers are which then I can explain further.

      Q2. This is not currently in the program and as I said before it will take a little while to implement. I’ll work on it next week.

      Q3. Sorry, I should probably have a makefile. Until I make one you’ll have to compile by hand. If you’re doing it from the command line it gets rather tedious because you have to compile every single .c file, like this:

      gcc -o mtgap main.c cjalgorithm.c accessories.c algorithm.c fitness.c keyboard.c readfile.c tools.c trikeys.c costs.c values.c


  5. dphrei
    December 14, 2010 at 4:26 am

    > In values.c there is an array called distanceCosts.

    that’s amazing! you’ve already done it. (i feel so foolish).
    please tell me, on this array, which hand+finger are keys 0 and 5?

    i will put vkxjqz+punct on the difficult keys.
    i imagine the high cost will keep them there.
    and thanks for the advice on compiling!


    • December 14, 2010 at 2:37 pm

      The left pinky is 0, ring finger is 1, and it goes across the keyboard like that. Columns 4 and 5 are the middle columns that your index finger stretches to reach.

      If you put vkxjqz.,’; on the difficult keys they may still move around. (Currently the program uses .,’; as the punctuation and if you want to use a different set then you’ll need a new list of digraphs that includes those.)

    • December 25, 2010 at 4:51 am

      Okay, so I’ve started working on the new program. Why exactly do you want to arrange the less common keys and punctuation by hand? It’s easier if the program does it because that way it won’t have to ignore certain parts of the keyboard. Believe it or not, ignoring parts of the keyboard is more difficult than just arranging the whole thing at once.

      The way distanceCosts works right now is that each individual key has a certain cost associated. Fingers and rows don’t cost any more. Pinkies are penalized, but only by penalizing the six keys that pinkies hit. I know that you said you want the top and bottom rows to count the same and for pinkies to be considered weaker than the other keys. Is that all? Are there any positions that you think are more difficult to hit than others?

      Have you been able to do anything with the program? If so, great. If not, I will gladly continue to continue to help.

      What precisely do you want the program to be able to do? I’m not sure I understand. Do you want to be able to disable any set of keys, or do you only care about the ones you specified?

  6. daniel frei
    December 26, 2010 at 9:53 pm

    Merry Christmas.
    After staring endlessly at the code and the resultant layouts, I’ve begun to appreciate what the program does. Therefore, I will adjust distance costs and let the program do its job…when I manage to build it! The array of distance costs simplifies things brilliantly; much better than what I proposed (though someone said that my approach was suited to MATLAB). Dunno why my compile efforts always bail out. I’m in touch with two cs students and, when they return from holidays, I will enlist their help.

    My difficulties are diagonal reaches to the centre and pinky reaches to the corners. My hands quickly become weak and painful if i do these stretches a lot. It’s not RSI; it just hurts. BTW, Human Solutions down in Texas are doing a good price on Kinesis Advantage right now, so I shall splosh the dosh.

    Here’s a thought. I noticed a function KEEP_ZXCV. Maybe this could be modified to fix characters on the four awkward keys of the central columns (or the four corners). JQ;Z for example, could be assigned to these four keys. Can you imagine a function KEEP_CENTRE or KEEP_CORNERS? Maybe you are already going down this road. Actually, I would only expect you to be interested if such a function sped up the program or made it easier to obtain high scoring layouts. At the very least, I hope that sharing my ideas gives you some food for thought.

    Thanks for mentioning the ARENSITO method of putting symbols and numbers on another level. I will implement this. Also, my inadequacy in tech stuff has spurred me to get a grounding in computer science. I am onto the excellent free lectures from google code and MIT (using python). Someday, I hope to make useful contributions to projects.

    • December 27, 2010 at 6:12 pm

      You’ll notice a block of code in keyboard.c that looks like this:

      if (k->layout[i] == 'z') {
      k->layout[i] = k->layout[20];
      k->layout[20] = 'z';
      } else if (k->layout[i] == 'x') {
      k->layout[i] = k->layout[21];
      k->layout[21] = 'x';
      // ...

      Add something similar for each key you want to keep in place. The number in k->layout[XX] is the index on the keyboard.

      This will still score those keys. (It doesn’t change the fitness function in any way.) It just ensures that z is always in one particular spot, x is always in one particular spot, etc.

      To make it separate from KEEP_ZXCV, you could do something like this (assuming you want to keep JQ;Z in the corners):

      if (KEEP_CORNERS)
      for (i = 0; i layout[i] == 'j') {
      k->layout[i] = k->layout[0];
      k->layout[0] = 'j';
      } else if (k->layout[i] == 'q') {
      k->layout[i] = k->layout[9];
      k->layout[9] = 'q';
      } else if (k->layout[i] == ';') {
      k->layout[i] = k->layout[20];
      k->layout[20] = ';';
      } else if (k->layout[i] == 'z') {
      k->layout[i] = k->layout[29];
      k->layout[29] = 'z';

      And then in values.h next to KEEP_ZXCV, put this:

      #define KEEP_CORNERS 1 // 0 = FALSE, 1 = TRUE

      That will put each of JQ;Z in a specific corner, so the keyboard will end up looking like this:

      J . . . . . . . . Q
      . . . . . . . . . .
      ; . . . . . . . . Z

      Where the dots can be any key.

      You can do something similar for KEEP_CENTRE. If you’re going to use this a lot it would be easier to create a macro. In keyboard.h you could do this:

      #define LOCK_KEY(key, index) if (k->layout[i] == key) { k->layout[i] = k->layout[index]; k->layout[index] = key; }

      Then in your KEEP_CORNERS if statement you could put this instead:

      if (KEEP_CORNERS)
      for (i = 0; i < 30; ++i) {
      LOCK_KEY('j', 0);
      LOCK_KEY('q', 9);
      LOCK_KEY(';', 20);
      LOCK_KEY('z', 29);

      That would be shorter and probably easier to read. Every time you type LOCK_KEY, the pre-compiler replaces it with the macro definition. So when it sees LOCK_KEY('j', 0) it replaces that with

      if (k->layout[i] == 'j') { k->layout[i] = k->layout[0]; k->layout[0] = 'j'; }

      This will only work if k and i are already defined, so you have to be careful about where you use a macro.

      Let me know if you get this working or if you need any help with it.

      Edit: Sorry, the indentation is messed up. I’m not sure how to fix that.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: