3

I speak both French and English, and I very often switch from one keyboard (French Canadian) to another (English US). When I write French emails, the French keyboard becomes necessary for accents (e.g. é, è, à, ç, etc.), while using Vim/writing code is much more practical with the US layout.

The problem is that very often, I start typing, realize I'm using the wrong keyboard layout, and then I have to go delete and re-type what I was doing. This is especially true for Vim, where I can quickly destroy a document in a few keystrokes.

Is there a way to make the current keyboard layout much more obvious than the small bottom-right corner indicator? Are there existing settings in Windows, or software I could install, that could help?

Examples of what I mean when I'm using a specific keyboard layout:

  • A colored screen border
  • A permanent overlay (modal, popup)
  • Changing the taskbar color
  • Etc.

Other suggestions that would help reduce lost time using the wrong keyboard layout are appreciated.

  • Thanks @JosefZ, this is what I was aiming for, but I ended up writing a similar script myself in the meantime :) I'll post it here. – Christian Rondeau Dec 27 '16 at 22:27
  • I agree it is very annoying. There should be more OS features addressing that. BTW in DOS (operating system from 80s) there appeared a thick green frame around the screen when switching the layout. I think another good solution would be changing mouse cursor image or caret image for different layouts - probably also possible with Autohotkey? – Mikhail V Nov 8 '17 at 14:20
  • Mmh, that's an interesting idea, you can get the information using the Windows API (msdn.microsoft.com/en-us/library/windows/desktop/…) but I'm not sure you can get notifications though. You might have to poll. – Christian Rondeau Nov 14 '17 at 16:47
2

This is an alternative that works for me up to now; Using AutoHotkey, I dynamically switch to a preferred language for specific software (E.g. Vim uses en-CA, and Slack uses fr-CA).

This is not an answer to my specific question, but if it worked for me, it might work for other people too:

https://gist.github.com/christianrondeau/00d7cd5848f33e029f00ce2b6b935ab9

; How to use:
; 1. Install AuthotKey: https://www.autohotkey.com
; 2. Save this script in `My Documents`
; 3. Create a shortcut in the Startup folder (`Win`+`R`, `shell:startup`)
; 4. Change the configurations below
; 5. Start and test the script!

; Configuration

    ; Cultures can be fetched from here: https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693(v=vs.85).aspx
    ; They must be set twice in the language ID;
    ;   en-US: 0x04090409
    ;   fr-CA: 0x0C0C0C0C

global DefaultLanguage := "fr-CA"
global DefaultLanguageIndentifier := "0x0C0C0C0C"
global SecondaryLanguage := "en-US"
global SecondaryLanguageIndentifier := "0x04090409"
global SecondaryLanguageWindowTitles := "VIM,Visual Studio"

; And the code itself (you should not have to change this)

Gui +LastFound 
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,Hwnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return

ShellMessage( wParam,lParam )
{
 WinGetTitle, title, ahk_id %lParam%
; 4 is HSHELL_WINDOWACTIVATED, 32772 is HSHELL_RUDEAPPACTIVATED
 If (wParam=4 || wParam=32772) {
    If title contains %SecondaryLanguageWindowTitles%
        SetKeyboard( title, SecondaryLanguage )
    Else
        SetKeyboard( title, DefaultLanguage )
 }
}

SetKeyboard( title, culture )
{
    ; 0x50 is WM_INPUTLANGCHANGEREQUEST.
    Try
    {
        If (culture = SecondaryLanguage)
        {
            PostMessage, 0x50, 0, %SecondaryLanguageIndentifier%,, A
            ; To debug:
            ; ToolTip, Using secondary language %SecondaryLanguage%
            ; Sleep 1000
            ; ToolTip
        }
        Else If (culture = DefaultLanguage)
        {
            PostMessage, 0x50, 0, %DefaultLanguageIndentifier%,, A
            ; To debug:
            ; ToolTip, Using default language %DefaultLanguage%
            ; Sleep 1000
            ; ToolTip
        }
        Else
        {
            ; To debug:
            ; ToolTip, Unknown culture: %culture%
            ; Sleep 1000
            ; ToolTip
        }
    }
    Catch e
    {
        ToolTip, Could not switch to %culture%`n%e%
        Sleep 1000
        ToolTip
    }
}
1

Here is my simple AHK solution to the problem. This is hard-coded to EN and RU layout codes (RU - 1049 (hex: 419) and EN - 1033 (hex: 409)).

The algorithm is simple: if active window has RU layout, then a red square appears on top. If it is EN layout, then it dissapears. In such way, I always see if the layout is not EN, so I can avoid the mis-typing.

The script scans for active window each 600 milliseconds (see sleep parameter inside the loop to adjust it) so it works system-wide and correctly shows it if separate apps have different layout set. Tested on Windows 7 and 10.
To adjust size and positions see the line Gui, Show, W100 H100 x980 y500

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.

SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
; SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

; get Layout of active window
getactiveKL() {
    active_hwnd := WinExist("A")
    threadID := dllCall("GetWindowThreadProcessId", "uint", active_hwnd, "uint", 0)
    code := dllCall("GetKeyboardLayout", "uint", threadID, "uint") & 0xFFFF
    return code
}
; 1049 - RU (hex: 419)
; 1033 - EN (hex: 409)

OSD_bg = AA0000
Gui, +AlwaysOnTop +Disabled -SysMenu -Caption +Owner
; Gui, Add, Text, , HELLO 
Gui, Color, %OSD_bg%
KL := getactiveKL()     ; scan KL once

Gui, Show, W100 H100 x980 y500, NoActivate
; if US then hide
if (KL = 1033) {
    Gui, Cancel
}

loop {
    KL_prev := KL
    sleep, 600
    KL := getactiveKL()
    if (KL = KL_prev) {
        continue
    }
    if (KL = 1049) {
        Gui, Show, NoActivate
    }
    if (KL = 1033) {
        Gui, Cancel
    }
}

+esc::exitapp ;press Shift-Escape to close script

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.