Switching keyboard layouts on macOS

Those §°±¤ keyboard layouts

I imagine this frustration is shared by programmers who don't speak English as their native language: to fluently type text in your language, you need easy access to some funny characters (åäö in my case) which are best found on your native keyboard layout. But that layout was designed by people who value characters like §°±¤ over the characters you need for programming, such as []{}\|.

So you switch between layouts. This used to work fine on MacOS X, but in some recent versions of macOS it has become unreliable. It feels like the layout switch sometimes fails (perhaps a third of the time), or happens after a delay, and sometimes it even switches the layout indicator but not the actual layout. I thought it was just me, but a colleague asked about this recently, so I guess it could be more widespread.

It could be this bug but that was supposed to be solved in 11.2? Also I never liked using the fn key for this, it gives some extra slow graphical feedback. (I used to map ctrl-shift-space to the layout switch instead of the default ctrl-space, because the latter is needed in Emacs.)

Solution

So here's what I do: run Karabiner Elements with this configuration:

{
  "title": "Select_input_source fi/us",
  "rules": [
    {
      "description": "Tap left shift for FI layout, right shift for US",
      "manipulators": [{
        "type": "basic",
        "from": {
          "key_code": "left_shift",
          "modifiers": { "optional": ["any"] }
        },
        "to": [{ "key_code": "left_shift" }],
        "to_if_alone": [{
          "select_input_source": {
            "input_source_id": "^com\\.apple\\.keylayout\\.Finnish$"
          }
        }]
      }, {
        "type": "basic",
        "from": {
          "key_code": "right_shift",
          "modifiers": { "optional": ["any"] }
        },
        "to": [{ "key_code": "right_shift" }],
        "to_if_alone": [{
          "select_input_source": {
            "input_source_id": "^com\\.apple\\.keylayout\\.ABC$"
          }
        }]
      }]
    }
  ]
}

With this configuration, tapping either shift key switches the layout. It doesn't seem to be affected by the bug mentioned above, but if that starts to happen, it's easier to get to a known state by tapping the relevant key twice or more than by using a state-toggle shortcut.

To use this, put the json file in ~/.config/karabiner/assets/complex_modifications/ and enable it in the settings. You'll want to modify the input source IDs to match your own keyboard layouts, which you can find by running

defaults read ~/Library/Preferences/com.apple.HIToolbox.plist \
  AppleCurrentKeyboardLayoutInputSourceID

with each layout active in turn, or using the Karabiner Elements event viewer.