Qwerty-Dvorak Layout for ErgoDox EZ

Inspired by the “Dvorak-Qwerty ⌘” keyboard layout from Mac OSX, I created a layout for ErgoDox EZ called qdvorak. In short, it is a Dvorak layout when typing normally, but the layout is switched to Qwerty when certain modifier keys are held (CTRL and CMD).

You can find the keymap.c and accompanying files in this GitHub repo.

Why use a hybrid layout like this?

As a developer, I use the Dvorak keyboard layout as part of my ergonomic working setup. However, Qwerty is still the most common keyboard layout, and using a non-standard layout tends to cause some friction. For example, the most common shortcuts for copy/paste, CTRL-C, X and V, are laid out to be within easy reach of one hand in Qwerty. In Dvorak, these shortcuts are spread out across both sides of the keyboard.

To make keyboard shortcuts easier, I had experimented with using the Dvorak-Qwerty ⌘ layout from Mac OSX, which temporarily switches to a Qwerty layout when CMD is held. In around 90% of cases, things worked great, but because this was a software layout, there were occasional programs that wouldn’t work. In particular, I recall having some trouble with IntelliJ. IntelliJ got very confused by the Qwerty mode, either reverting back to Dvorak for the shortcuts, or becoming so confused that some shortcuts were simply impossible to execute with either the Qwerty or Dvorak key placements.

Along with these compatibility issues, there were two other limitations that I wanted to improve:

  • The layout was only available on OSX, not Windows or Linux.
  • The software layout only switched to Qwerty when CMD was held, but I also wanted this to happen with CTRL, to work with common shortcuts on Windows and Linux programs.

I really liked the idea of the Dvorak-Qwerty layout, so I wanted to extend on the basic idea of this layout, this time in hardware rather than software. Having the keyboard hardware perform the Qwerty/Dvorak conversion would remove the software incompatibility issues, provide the same experience on any operating system, and would not require any setup or customization in the OS.

To do this project, I needed a programmable keyboard, and I chose the ErgoDox EZ. As a long-time fan of ergonomic keyboards, I really liked the adjustable split design and ortholinear layout. I was also drawn to the similarity to the Kinesis Advantage layout, with some commonly-used keys (like backspace) in the thumb areas.

qdvorak implementation in QMK

The qdvorak layout is implemented as a keymap in QMK. On top of a standard dvorak base layer, the keymap adds a new QWRT layer, which rearranges the core keys in a Qwerty layout. In a previous version of this keymap, I had problems with the QWRT layer getting stuck in a bad interaction with the symbols layer, which I think was due to suboptimal layer ordering. For this iteration of the keymap, I made sure to give the QWRT layer a lower layer number (1) than the SYMB layer (2):

#define BASE 0 // base layer == dvorak
#define QWRT 1 // qwerty
#define SYMB 2 // symbols

The keymap replaces the standard CTRL and CMD keycodes with custom keycodes (CTRL_Q and CMD_Q in the code). process_record_user implements the behavior of the custom keycodes:

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    case CTRL_Q:
      if (record->event.pressed) {
      else {
      return false;

    case CMD_Q:
      if (record->event.pressed) {
      else {
      return false;

  return true;

In addition to the standard behavior of sending the ctrl/cmd keycode, these custom keycodes also turn on/off the QWRT layer. As a result, the QWRT layer is temporarily enabled while ctrl or cmd is being held.

The layout also adds a key (the upper-left vertical button) that toggles the QWRT layer manually. Having a temporary all-Qwerty mode is convenient for programs that treat the keyboard keys geometrically, rather than using the letters to mean something. For example, video games use WASD, and editors like vim use HJKL for movement. Having the ability to easily switch back and forth from Dvorak to Qwerty can be very convenient in these cases.

Layer state LEDs

The keymap uses the blue and green LEDs on the ErgoDox EZ to indicate when the QWRT and SYMB layers are enabled. This is done in the layer_state_set_user function, which is called by QMK whenever the layer state changes:

layer_state_t layer_state_set_user(layer_state_t layer_state) {

  if (layer_state & (1<<QWRT)) {

  if (layer_state & (1<<SYMB)) {

  return layer_state;

You might be wondering why the keymap doesn’t use any RGB illumination, and the simple reason is that I got my ErgoDox EZ in 2016, before RGB lighting was added to the board.

Caps lock

Unlike the standard ErgoDox EZ layout, I chose to add a caps lock key, which I use when typing all-caps names in code (e.g. QMK_KEYBOARD_H). The keymap uses the red LED to indicate the caps lock state. led_set_user is the function that QMK will call to indicate a change to the “keyboard LEDs” (i.e. num lock, caps lock, scroll lock) state:

void led_set_user(uint8_t usb_led) {
    if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
    } else {

Custom configuration

Custom configuration parameters can be set in a config.h file in the same directory as the keymap. The keymap only changes one parameter, TAPPING_TOGGLE, which sets the behavior of TT() keys:



I’ve been using and refining this custom qdvorak layout for a few years, and hopefully seeing it will inspire others to create their own custom layouts. This layout barely scratches the surface of the possibilies offered by the QMK firmware on the ErgoDox EZ. If you’re interested in learning more, you can read about all of the other features of QMK at the official QMK Firmware documentation.