WM_INPUTLANGCHANGE not received instantly, and hotkey doesn't work

László Szerémi 35 Reputation points
2023-08-13T10:39:47.58+00:00

I'm currently writing an input and output handling library for the D language, and I'm not getting any kind of input language change messages when the language is being toggled with hotkeys, and only during moving the window from toggling it on the taskbar.

The beginning of the function that can be called for an event loop looks like this under Windows

package int poll_win_LegacyIO(ref InputEvent output) nothrow @nogc {
	tryAgain:
        MSG msg;
        BOOL bret = PeekMessageW(&msg, OSWindow.refCount[winCount].getHandle, 0, 0, PM_REMOVE);
		if (bret) {
            output.timestamp = msg.time * 1000L;
			output.handle = OSWindow.refCount[winCount].getHandle;
            auto message = msg.message & 0xFF_FF;
            DispatchMessageW(&msg);
            [...]
        }
}

Then there's a separate OSWindow class with its own windows callback functions:

static extern (Windows) LRESULT wndprocCallback(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) nothrow @system {
	switch (msg) {
		case WM_CREATE, WM_NCCREATE:
			return DefWindowProcW(hWnd, msg, wParam, lParam);
		default:
			foreach (OSWindow key; refCount) {
				if (key.getHandle() == hWnd)
					return key.wndCallback(msg, wParam, lParam);
				}
			return LRESULT.init;
		}
	}
}
[...]
version (Windows)
protected LRESULT wndCallback(UINT msg, WPARAM wParam, LPARAM lParam) nothrow @system {
	switch (msg) {
		case WM_INPUTLANGCHANGEREQUEST:
			statusFlags = Status.InputLangChReq;
			inputLang = cast(uint)lParam;
			goto default;
		case WM_INPUTLANGCHANGE:
			statusFlags = Status.InputLangCh;
			inputLang = cast(uint)lParam;
			goto default;
[...]
		default:
			return DefWindowProcW(windowHandle, msg, wParam, lParam);
	}
}

Using a debugger, I noticed that the WM_INPUTLANGCHANGE and WM_INPUTLANGCHANGEREQUEST commands are not generated when the input language is being changed by the user, and instead the input language change hotkeys don't work as intended (the selection comes up, but hangs for a while, and no language will be changed, sometimes even hangs the application), and changing the input from the taskbar only get dispatched to my application once the window is being resized or moved. I did various modifications to the code (including removing a part that optionally trapped the Win and Menu key presses, and temporarily moving the DispatchMessageW function before the if statement).

Is there potentially some fundamental problem with handling focus in my window class (there's currently nothing besides the DevWindowProcW), or something else?

Windows development | Windows API - Win32
{count} votes

3 answers

Sort by: Most helpful
  1. Castorix31 90,686 Reputation points
    2023-08-13T12:19:27.9133333+00:00

    On recent OS's, ITfLanguageProfileNotifySink is better

    (I had tested on Windows 10)

    1 person found this answer helpful.
    0 comments No comments

  2. László Szerémi 35 Reputation points
    2023-08-26T14:18:06.65+00:00

    Found the issue, I have to pass null to the PeekMessageW function as window handle, now it works as it should and doesn't hang randomly on input language change attempts.

    1 person found this answer helpful.

  3. Xiaopo Yang - MSFT 12,731 Reputation points Microsoft External Staff
    2023-08-14T03:20:43.7233333+00:00

    I cannot reproduce. There is a ITfLanguageProfileNotifySink related thread which shows a sample and a workaround.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.