Mac : Get Rid of Keyboard Foreign Layout Troubles with Microsoft Remote Desktop

Mac : Get Rid of Keyboard Foreign Layout Troubles with Microsoft Remote Desktop

Microsoft Remote Desktop IconFor over a year now, Microsoft provides a free application called Microsoft Remote Desktop to access a computer (usually running Windows) through RDP from a Mac or iOS or Android device. This version should replace another free application provided by Microsoft: Remote Desktop Connection Client for Mac. If I remember well, the latter had taken his time to fully manage Mac keyboards in a foreign language. It looks the same for this new App: this problem does not seem a priority. Indeed, for now this app assumes you are using a PC keyboard on your Mac.

As Microsoft Remote Deskto is a promising product (in particular, it supports RemoteApp from a Mac, xfreerdp being a little disappointing on this point), I thought it deserved a little search. I finally found two different methods to overcome the problem, one looking more usable than the other.

About keyboard management by operating systems

Schematically, we can say that a keyboard is managed by the operating system (OS) at 2 levels. A level we could call “hard” and another “soft”. At the “hard” one, electrical signal corresponding to the movements of the keys on the keyboard are sent to the OS, it calls the keyboard driver that interprets these signals and translated them into push key or release key events. Those will be used downstream by the OS. For example, if you push the first key next to the tabulation one, the “hard” part will say the OS: the key “0x0” was pressed. Here come the “soft” level that defines what should be done with this information: the concept of keyboard layout come into action. One can decide, if the keyboard is QWERTY that key “0x0” displays an “A” and if the keyboard is QWERTY, it displays a “Q”.

On the Mac, there is an open-source tool for working at the “hard” level: Karabiner and another to work at the “soft” one: Ukelele. The second is slightly simpler approach, so I started there, especially because I had already used it for VNC connections to Windows computers from a Mac. Unfortunately, soon I came to the conclusion that Microsoft Remote Desktop is working at the “hard” level and therefore it was useless to try to redefine a new layout on the client-side.

With this conclusion, there are only two ways:

  • Working at the “hard” level with Karabiner on the client
  • Working at the “soft” level on the RDP server

An easy workaround if you are connecting to Windows Server 2012 or Windows 8

On Windows 2012, it appears that the management of keyboard layouts has been greatly improved. Also, if you define a keyboard layout for your Mac client, you can:

  • Propose this layout from the login screen that allows your users to type passwords despite key mismatches between Mac and PC keyboard (the user must be active and trained to do this)
  • Request that all previously open applications change to the new keyboard layout if ever you were using an other one before

Now, I do not have computers running Windows Server 2012, so I can’t confirm that. That’s my readings, but if it’s indeed the case, you just have to define (or find on the Internet) a layout for your Mac keyboard and just ask to change to this keyboard layout when you connect from your Mac. If you can’t find one of those layouts, you can define one with the intuitive tool to create a layout (at the “soft” level) under Windows: Microsoft Keyboard Layout Creator (MSKLC).

The solution for connections to Windows 2008 R2 or Windows 2007: Karabiner on the client

Karabiner is an open-source solution used to be called KeyRemap4MacBook and which gradually replaced DoubleCommand. This application is no longer maintained. Historically, it was use to switch the Cmd and Ctrl keys on your Mac keyboard (often useful while going to Mac from the PC world). Karabiner seems a very good and very configurable tool, but not particularly user-friendly. It is easy to use, but the creation of a specific mapping remains difficult. Moreover, in our case it’s enough to drive you up the wall.

The remapping is done in 2 steps:

  • First, I identify the key that is typed on the keyboard (quite easy with the tool provided by Karabiner: EventViewer)
  • Then, I define the key that should be pressed instead. There, it gets complicated: we must assume that if you were using a PC keyboard on your Mac, it would work. So you need a picture of a French PC keyboard and that of a US keyboard.
    • Example for the “=” key on Mac French keyboard that corresponds to the “! ” on PC. I want an “=”: Imagine that I have a PC keyboard, to have a “=”, one must press the key to the left of the backspace key. On a standard Mac keyboard (i.e. American) this key is the same and is called EQUAL key.
    • Example for the “§” key on the French Mac keyboard that corresponds to the “-” key on PC. I want a “§”: Imagine that I have a PC keyboard, to have a “§”, one must press the key to the left of the right shift key. On a standard Mac keyboard (i.e. American) this key is called SLASH key.
French Mac Keyboard
French Mac Keyboard
Mac US Standard Keyboard
Mac US Standard Keyboard
French PC Keyboard
French PC Keyboard

Finally, we can tell karabiner to apply this remapping for a particular application: Microsoft Remote Desktop.

This leads to this private.xml file:

<appdef>
  <appname>Microsoft Remote Desktop</appname>
  <equal>com.microsoft.rdc.mac</equal>
</appdef>
<item>
  <name>French Mac keyboard A1314 using the Microsoft Remote Desktop App</name>
  <appendix>Assure all keys writen on the keyboard to be the same on the remote server.</appendix>
  <appendix>Done for Version 8.0.12 (Build 25282)</appendix>
  <identifier>remap.mac_french_keyboard_MRD_layout</identifier>
  <only>Microsoft Remote Desktop</only>
  <!-- KEY_6 to '§' -->
  <autogen>__KeyToKey__ KeyCode::KEY_6, ModifierFlag::NONE, KeyCode::SLASH, ModifierFlag::SHIFT_R</autogen>
  <!-- KEY_8 to '!' -->
  <autogen>__KeyToKey__ KeyCode::KEY_8, ModifierFlag::NONE, KeyCode::SLASH, ModifierFlag::NONE</autogen>
  <!-- FRENCH_MINUS to '-' -->
  <autogen>__KeyToKey__ KeyCode::FRENCH_MINUS, ModifierFlag::NONE, KeyCode::KEY_6, ModifierFlag::NONE</autogen>
  <!-- FRENCH_MINUS + Shift to '_' -->
  <autogen>__KeyToKey__ KeyCode::FRENCH_MINUS, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_SHIFT | ModifierFlag::NONE, KeyCode::KEY_8, ModifierFlag::NONE</autogen>
  <!-- FRENCH_@ to '@' -->
  <autogen>__KeyToKey__ KeyCode::RawValue::0xa, ModifierFlag::NONE, KeyCode::KEY_0, ModifierFlag::OPTION_R</autogen>
  <!-- FRENCH_@ + Shift to '#' -->
  <autogen>__KeyToKey__ KeyCode::RawValue::0xa, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_SHIFT | ModifierFlag::NONE, KeyCode::KEY_3, ModifierFlag::OPTION_R</autogen>
  <!-- FRENCH_DOLLAR + Shift to '*' -->
  <autogen>__KeyToKey__ KeyCode::FRENCH_DOLLAR, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_SHIFT | ModifierFlag::NONE, KeyCode::KEYPAD_MULTIPLY, ModifierFlag::NONE</autogen>
  <!-- FRENCH_DOLLAR + AltGr to '€' -->
  <autogen>__KeyToKey__ KeyCode::FRENCH_DOLLAR, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_OPTION | ModifierFlag::NONE, KeyCode::E, ModifierFlag::OPTION_R</autogen>
  <!-- BACKSLASH to '`' -->
  <autogen>__KeyToKey__ KeyCode::BACKSLASH, ModifierFlag::NONE, KeyCode::KEY_7, ModifierFlag::OPTION_R</autogen>
  <!-- BACKSLASH + Shift to '£' -->
  <autogen>__KeyToKey__ KeyCode::BACKSLASH, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_SHIFT | ModifierFlag::NONE, KeyCode::FRENCH_DOLLAR, ModifierFlag::SHIFT_R</autogen>
  <!-- FRENCH_EQUAL to '=' -->
  <autogen>__KeyToKey__ KeyCode::FRENCH_EQUAL, ModifierFlag::NONE, KeyCode::EQUAL, ModifierFlag::NONE</autogen>
  <!-- FRENCH_EQUAL + Shift to '+' -->
  <autogen>__KeyToKey__ KeyCode::FRENCH_EQUAL, MODIFIERFLAG_EITHER_LEFT_OR_RIGHT_SHIFT | ModifierFlag::NONE, KeyCode::EQUAL, ModifierFlag::SHIFT_R</autogen>
</item>

Another solution to connect to Windows 2008 R2 or Windows 2007 but on the server-side

In fact, we will fill the gaps in these versions of Windows versus Windows 8 or Server 2012, i.e.:

  • allow the choice of a compatible keyboard layout from the Windows login screen
  • automatically update the keyboard layout on connection using the task scheduler, Cassia and kbswitch2

Make available new keyboard layouts on the login screen of Windows 7 or Windows 2008 R2

On Windows, the login screen is started by a service that runs with Local System ID (UID S-1-5-18). If you want other languages ​​or keyboard layouts available at login, simply assign them to Local System. Unfortunately, I don’t know any graphical way to achieve this. The only one I know is to go through the registry by copying all or part of the key “Keyboard Layout” of an account that has been configured with languages ​​and keyboard layouts you whish. Little howto:

  1. Connect with your credentials and set the languages ​​and keyboard layouts as you would like them to be available on the login screen.
  2. Open the registry and export the key “Keyboard Layout” of HKEY_CURRENT_USER.
  3. Replace in the file the string “HKEY_CURRENT_USER” by “HKEY_USERS\S-1-5-18”.
  4. Double-click on the file with the appropriate privileges to add the new key to Local System.

Run a script at session startup or when reconnecting to an already open session

Run a script on login is really easy, but executing one on reconnection to an already open session is far less documented. A way that works is to go through the task scheduler which allows the execution of a script when reconnecting. As it also allows a script execution on a new session, it’s really the right tool to use.

Create a script that identifies the RDP client application and selects accordingly the right keyboard layout

Our script is based on two tools:

  • Cassia, a library that aggregates various information about the RDP connection. It comes with a SessionInfo.exe that do the job if you use the latest version of the library which binaries are not distributed at present. So just recompile from source with .Net 3.5.
  • kbswitch2 a small open source application that switches all previously open applications to a given keyboard layout and launch every new application to that new chosen layout. In other words, it does what Windows 8 or Windows Server 2012 do that lacks on Windows 7 or Windows 2008 R2.

The script is easy:

REM Go to the directory where are kbswitchv2 and SessionInfo.exe of Cassia.
cd c:\kbswitch2v2
REM Set layout to french by default and depending on SessionInfo.exe results, switch to a specific one or not
kbswitch2.exe "Français" & SessionInfo.exe |findstr /C:"Client Build Number: 25282" && kbswitch2.exe "Français - Custom"

Of course the layout “French – Custom” is this French Mac keyboard for Windows.

One thought on “Mac : Get Rid of Keyboard Foreign Layout Troubles with Microsoft Remote Desktop

  1. I’ve just changes the post for the star (*) key. As I didn’t manage to find this key on a American keyboard, I use the one of the numeric pad. It works as good with wired or wireless Mac french keyboard now.

Leave a Reply

Your email address will not be published. Required fields are marked *