Add configurable offline layout correction and latest Windows release
This commit is contained in:
+47
-1
@@ -107,9 +107,55 @@ wchar_t physicalKey(DWORD scan, bool shift)
|
||||
return (shift ? physicalLayout().shifted : physicalLayout().normal)[i];
|
||||
return 0;
|
||||
}
|
||||
static HWND inputWindow(HWND w)
|
||||
{
|
||||
if (!w || !IsWindow(w))
|
||||
return nullptr;
|
||||
GUITHREADINFO info{sizeof(info)};
|
||||
DWORD thread = w == GetForegroundWindow() ? 0 : GetWindowThreadProcessId(w, nullptr);
|
||||
if (GetGUIThreadInfo(thread, &info) && info.hwndFocus &&
|
||||
(info.hwndFocus == w || IsChild(w, info.hwndFocus) || GetAncestor(info.hwndFocus, GA_ROOT) == w))
|
||||
return info.hwndFocus;
|
||||
return w;
|
||||
}
|
||||
HKL windowLayout(HWND w)
|
||||
{
|
||||
return GetKeyboardLayout(GetWindowThreadProcessId(w, nullptr));
|
||||
HWND input = inputWindow(w);
|
||||
return input ? GetKeyboardLayout(GetWindowThreadProcessId(input, nullptr)) : nullptr;
|
||||
}
|
||||
bool switchWindowLayout(HWND target, HKL layout, const std::function<bool()> &valid)
|
||||
{
|
||||
HWND input = inputWindow(target);
|
||||
auto unchanged = [&]
|
||||
{ return input && valid() && GetForegroundWindow() == target && inputWindow(target) == input; };
|
||||
if (!layout || !unchanged())
|
||||
return false;
|
||||
if (windowLayout(target) == layout)
|
||||
return true;
|
||||
// Windows directs layout requests to the focused control, which can belong
|
||||
// to a different UI thread/process than a Teams/WebView top-level window.
|
||||
if (!PostMessageW(input, WM_INPUTLANGCHANGEREQUEST, 0, (LPARAM)layout))
|
||||
return false;
|
||||
for (int i = 0; i < 30; ++i)
|
||||
{
|
||||
if (!unchanged())
|
||||
return false;
|
||||
if (windowLayout(target) == layout)
|
||||
return true;
|
||||
// Some hosts handle this at their top level instead of the focused child.
|
||||
if (i == 14 && input != target)
|
||||
PostMessageW(target, WM_INPUTLANGCHANGEREQUEST, 0, (LPARAM)layout);
|
||||
Sleep(10);
|
||||
}
|
||||
return unchanged() && windowLayout(target) == layout;
|
||||
}
|
||||
void showRequestedWindow(HWND window)
|
||||
{
|
||||
ShowWindow(window, SW_SHOW);
|
||||
// STARTF_USESHOWWINDOW can override the process's first ShowWindow with
|
||||
// SW_HIDE. An explicit user request must still make the window visible.
|
||||
if (!IsWindowVisible(window))
|
||||
ShowWindow(window, SW_SHOW);
|
||||
}
|
||||
bool activateWindow(HWND window)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user