Keyboards over Terminal Server

by Michael S. Kaplan, published on 2006/01/05 10:01 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2006/01/05/509539.aspx


Ilya Constantinov asked in the Suggestion Box:

Remote Desktop seems to have an undocumented behavior of passing on your current keyboard layout (at time of connection) to be installed on the server you're connecting to. This sort-of makes sense, especially cause it's installed only for the duration of the session, but why don't all my local keyboard layouts get installed on the server side? Was there special reasoning for that?

And not too long ago a related question came up from an email from Holger Luebsen:

When I connect to a US English Terminal Server and my local default language is say French, then the logon prompt on the Terminal Server shows FR and I can toggle to EN. So far so good. 

The problem comes, when my local default language is English and I select a temporary French keyboard/language locally and connect to the Terminal Server. The logon prompt will show EN, but type FR. I can then toggle the language. It still displays EN, but now types English. Toggle back and it is French again.

Now when I cancel the logon, but do not close the rdp client, switch the keyboard to German and connect again, the language indicator correctly shows DE. If I now cancel again without closing the rdp client and switch back to French and connect it correctly displays FR.

If I cancel and close the rdp client, open a new client and connect I will see EN again instead of FR.

That looks like a bug to me. Is this known and has someone a fix for this? Anybody else experienced this?

Hmmm.... lots of information in there, isn't there? Let's try combining it all with the feature in the Updating the keyboard list in the logon dialog post.

I have a Windows Vista machine that has the English and Greek keyboard layouts installed using the logon dialog trick above, and on my machine I have installed English, Russian, Greek, and Thai keyboards. From the very beginning in the Login dialog you can see the language list is available:

Now note that in this case the English keyboard is my process default. Let's try changing the latter, using the same thing but with a Greek process default.

Ok, so now we know that the Terminal Services is smart enough to negotiate when the same keyboard you are trying to use before the login is available on both client and server.

Unfortunately, it does go downhill from here....

Let's try switching to one of those other keyboard layouts on the client (either by setting the process default or switching to the keyboard prior to hitting the Connect button). What do we get in the dialog?

Wow, it picked up the Russian! And if you Left Alt+Shift toggle through layouts it does not hit that other keyboard (the Thai one). And as I move between the layouts (so I can type in my password!) the language bar icon updates:

Once I have logged in, that Russian layout is the one that is selected in the Language List and it is the process default....

But the weird part is that it is not on the Text Services and Input Language dialog as being the process default or even on the list at all!

This is definitely a temporary keyboard, isn't it? :-)

I ran several experiments (inspied by Holger's posting) and found that I was able to confuse it sometimes (though not as often as the bug report I mentioned earlier!), but it seemed remarkably robust in light of all the odd changes being thrown at it. And when I was done playing aroundresearching, all traces of the extra 'temporary' keyboards were gone.

So when I consider the real world scenarios involving users who explicitly change their keyboard layouts, I think they are most likely to get what they expect (if they switch to a keyboard layout, that keyboard is used). It seems fragile enough for a tester to find oodles of minor inconsistencies, but robust enough that it recovers gracefully.

And it does seem to be getting better in Vista (this very post might cause it to be a little better if any bug reports are inspired by it!).

I definitely don't envy the folks who had to do the work to build the logic for the huge matrix of possibilities between all of the possible server and client settings. It might be the hour I am typing this but I honestly get a headache just thinking about it....

 

This post brought to you by "Ψ" (U+03a8, a.k.a. GREEK CAPITAL LETTER PSI)


# Marc Brooks on 5 Jan 2006 12:30 PM:

First, I know I should just try it, but I'm busy...

Would this automatic installation of keyboard handling open the door to extending system-level deviousness into the RDP server? Could my carefully constructed custom keyboard be infected, injected, and then applied to the RDP server to do my bidding?

Should I worry?

# Michael S. Kaplan on 5 Jan 2006 2:14 PM:

Hi Marc,

Good question, but you don't have to worry. TS does not copy the keyboard layouts -- it is using layouts that exist on both machines.

# Ilya Konstantinov on 5 Jan 2006 6:39 PM:

Michael, thanks for the answer. "It's by design" is pretty much what I expected to hear, but still wanted to get that issue to your attention.

Simply enough, the RDP protocol seems to have a single place for an LCID so you've gotta pick one. Why do I know this? I've been working on this very thing in rdesktop, the open source RDP client.

# Michael S. Kaplan on 5 Jan 2006 6:51 PM:

Ah, but the thing that will really bake a person's noodle is wondering what SystemParametersInfo with the SPI_GETDEFAULTINPUTLANG would do in this case of the "temp default keyboard" (and then whether that is the right thing!). :-)

# Ben Cooke on 6 Jan 2006 8:12 PM:

I've often paused to wonder why the remote desktop protocol doesn't just send over the Unicode characters generated by my local keymap, rather than sending over the scancodes (presumably) and interpreting it remotely.

This way I'd be able to change my keyboard layout using the language bar *on the client* just as I do for any other application. Even aside from that particular benefit, it seems obvious to use the client keyboard layout since it's the client that's got the user's keyboard plugged into it!

# Michael S. Kaplan on 6 Jan 2006 10:55 PM:

Hi Ben,

It is actually a slippery slope to start moving more and more functionality down to the client, but in this case it is not possible -- the keyboard sends keyboard messages to the app and if processed appropriately with the thread's input language then a keyboard msg is sent. There is no way to move all of that processing down to the client....

# Ilya Konstantinov on 1 Mar 2006 11:09 AM:

Of course we still need to send AT scancodes so things like WM_KEYDOWN will keep behaving as usual, but couldn't TranslateMessage be hacked so that (just in the case of RDP session) it'll emit a WM_UNICHAR message with a value received from network rather than attempt to translate the WM_KEYDOWN?

Furthermore, switching windows will have to message the client, asking it to change its keyboard language to the remote thread's language.

Oh, and when a remote thread will query for installed keyboard languages, it'll get the client's list.

Yup, lots of hacks needed here, some can potentially make input flaky over high-latency connections. For example, what if you switch a window and start typing ahead of time, before the message telling your RDP client to switch its language to the active window's language has arrived?

The "AT scancodes" requirement complicates things quite a bit on platforms where its hard to get the underlying AT scancode (and pray your keyboard is even an AT one!) but don't let this trouble your Wintel head :/

referenced by

2007/11/29 The UK Extended keyboard -- over-extended? Or weirdly extended?

go to newer or older post, or back to index or month or day