fix(server): 关闭 Direct2D 设置窗口后悬浮工具栏不再消失 (#1002)
Direct2D 设置窗口是获得键盘焦点的 Win32 窗口,进程里的 TIP 会成为普通输入客户端。 正常退出时 DestroyWindow / CoUninitialize 让 TSF 反激活 TIP,发出终结性反激活, Server 当成用户切走了输入法而隐藏工具栏;回到的窗口不一定重新激活,工具栏要等 点击别的窗口才回来。WebView2 前端的焦点在 WebView 子进程里,宿主线程从不持有路由, 所以没有这个问题。 Direct2D 前端在写入排空后不再销毁窗口、跳过 CoUninitialize,直接结束进程: Server 只看到管道断开(仅挂起路由,不动工具栏),与 WebView2 前端一致。
This commit is contained in:
1 parent
ef28cf690d
commit
81fa7d10c8
1 file changed
+25
-2
@@ -2453,7 +2453,14 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_pa
|
||||
{
|
||||
g_worker->Drain(!g_closing);
|
||||
if (g_closing && g_worker->Stopped())
|
||||
DestroyWindow(hwnd);
|
||||
{
|
||||
// The Direct2D frontend leaves without destroying its window: see the
|
||||
// end of wWinMain for why the process must skip the TSF teardown.
|
||||
if (g_native)
|
||||
PostQuitMessage(0);
|
||||
else
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case WM_CLOSE:
|
||||
@@ -2649,7 +2656,10 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR command_line, int show_
|
||||
DispatchMessageW(&message);
|
||||
}
|
||||
g_worker.reset(); // Drain accepted writes even if the window was destroyed externally.
|
||||
CoUninitialize();
|
||||
// The Direct2D frontend skips CoUninitialize like it skips DestroyWindow: both tear
|
||||
// down this thread's TSF state (see below).
|
||||
if (!use_native)
|
||||
CoUninitialize();
|
||||
if (g_relaunch_after_exit)
|
||||
{
|
||||
// The renderer was switched: reopen in it once this instance no longer holds the
|
||||
@@ -2663,5 +2673,18 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR command_line, int show_
|
||||
ShellExecuteW(nullptr, L"open", module_path.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
if (use_native)
|
||||
{
|
||||
// The Direct2D window is a focused Win32 window, so this thread is an ordinary
|
||||
// input client of the IME. Destroying the window or uninitializing COM lets TSF
|
||||
// deactivate the text service here, which reports a terminal deactivation, and
|
||||
// the Server hides the floating toolbar as if the user had switched input
|
||||
// methods. The window the user returns to may not re-activate, so the toolbar
|
||||
// stayed hidden until they clicked elsewhere. Every write has been drained
|
||||
// above; end the process without that teardown, so the Server only sees the
|
||||
// pipes close (a route suspension, which leaves the toolbar alone), as it does
|
||||
// for the WebView2 frontend.
|
||||
TerminateProcess(GetCurrentProcess(), static_cast<UINT>(message.wParam));
|
||||
}
|
||||
return static_cast<int>(message.wParam);
|
||||
}
|
||||
Reference in new issue
Block a user