Skip to content

Keep a lone Alt or F10 from freezing the Desktop window on Windows - #1648

Merged
davidmckayv merged 2 commits into
mainfrom
desktop/windows-ipc-lost-wake
Nov 15, 2026
Merged

davidmckayv merged 2 commits into
mainfrom
desktop/windows-ipc-lost-wake

Conversation

@davidmckayv

@davidmckayv davidmckayv commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

What

On Windows, a lone Alt or F10 in the OpenBot window could freeze the link between the window's page and OpenBot until the person clicked somewhere. Setup, start and update looked stuck: the elapsed timer kept ticking but nothing else moved.

Why it happened

A lone Alt or F10 makes DefWindowProc send the top-level window WM_SYSCOMMAND with SC_KEYMENU and an lParam of 0. Handled as it is (tao 0.37.2 passes it straight to DefWindowProc), that starts a modal menu loop on the window's thread, even though OpenBot's windows have no menu bar, so nothing on screen shows it. While the thread is in that loop, WebView2's page and OpenBot stop hearing each other in both directions. An invoke's answer does not reach the page, and the page's next invoke does not reach OpenBot, until a click, Esc or Alt+Tab ends the loop.

On a Windows Server 2022 box, the round-trip logging from #1602 caught it:

  • A lone Alt reached the setup window at 20:54:32, during local update.
  • The page's one-second download poll stopped there. The byte count stayed at 287.8 MB from 1m 21s to 11m 42s, although the downloads finished at 20:55.
  • local update's answer was handed back at 20:56:41 and reached the page 530.2 s later, within a second of a right-click on the tray icon.

Other Tauri apps on WebView2 have measured the same freeze and fixed it the same way.

OpenBot could also cause it itself. tao's set_focus presses and releases Alt when SetForegroundWindow is refused (force_window_active), and eight places still called it on Windows.

The change

  • key_menu.rs: the main and Status windows get a subclass that answers SC_KEYMENU with a zero lParam itself. Everything else still reaches DefWindowProc: Alt+Space (the window menu), Alt with a letter, and a click on the window icon (SC_MOUSEMENU). The page still gets Alt's and F10's keydown and keyup, which arrive before this command and are not touched, so its Alt shortcuts work as before.
  • focus in main.rs: every window now comes forward the way bring_to_front already did on Windows. It uses SetForegroundWindow, and if Windows refuses, the taskbar button flashes. No key is ever pressed on the person's behalf. That covers the shutting-down screen, Status, this computer's settings, setup, the tray's Open, and the three host-access prompts in desktop_host_access.rs.

Tests

  • key_menu::tests::only_a_menu_key_pressed_alone_is_dropped: the rule for which WM_SYSCOMMANDs are dropped.
  • key_menu::tests::a_lone_alt_puts_no_subclassed_window_in_menu_mode (Windows): it posts a real SC_KEYMENU with lParam 0 to two windows on their own message-loop thread.
    • A plain window enters menu mode (GetGUIThreadInfo reports GUI_INMENUMODE). That proves the desktop reproduces the freeze, and it is what OpenBot's window did without the subclass.
    • The subclassed window never enters menu mode, and a message posted to it afterwards (the way wry posts an invoke's answer) is handled at once.
  • coming_forward_with_another_window_in_front_flashes_and_sends_no_input now checks that no set_focus call is left outside focus's non-Windows branch, in main.rs and desktop_host_access.rs.

Proof on a Windows box

Windows Server 2022 with WebView2. A lone Alt and then F10 were pressed on the OpenBot window during a long-running step, and GetGUIThreadInfo was read for OpenBot's UI thread.

  • main (167d7c7), as the control: both keys froze the window. Every probe returned flags 0xC, which includes menu mode. Progress froze, and the "[window ipc]" hops took 32.5 s and 33.8 s. Only a click released it.
  • This PR (5c6b603): the window never entered menu mode. Every probe returned 0x0, progress moved by itself, and all 10 "[window ipc]" hops took 0.0 s.
  • Still working: Alt+Space opens the window menu, a Bot answers, and the window comes forward from the tray, including when it was covered and when it was minimized.

@davidmckayv
davidmckayv force-pushed the desktop/windows-ipc-lost-wake branch 3 times, most recently from 9147f55 to 18ade1d Compare November 15, 2026 16:16
A lone Alt or F10 makes DefWindowProc send the top-level window
WM_SYSCOMMAND/SC_KEYMENU with lParam 0, which starts a modal menu loop on
the window's thread even though the window has no menu bar. While the
thread is in it, WebView2's page and OpenBot stop hearing each other: an
invoke's answer does not reach the page and the page's next invoke does
not reach OpenBot, until a click, Esc or Alt+Tab. On a Windows box a lone
Alt during `local update` held the update's answer back from the page for
530 s, until a right-click on the tray icon.

The main and Status windows now answer that one command themselves.
Alt+Space, Alt with a letter and a click on the window icon still reach
DefWindowProc, and the page still gets Alt's keydown and keyup.

OpenBot also stops pressing Alt itself: tao's set_focus presses and
releases Alt when SetForegroundWindow is refused. Every window now comes
forward through one helper that uses SetForegroundWindow and flashes the
taskbar when Windows refuses, as bring_to_front already did.
@davidmckayv
davidmckayv force-pushed the desktop/windows-ipc-lost-wake branch from 18ade1d to a9af1d5 Compare November 15, 2026 17:10
@davidmckayv
davidmckayv merged commit f4f0ec0 into main Nov 15, 2026
27 checks passed
@davidmckayv
davidmckayv deleted the desktop/windows-ipc-lost-wake branch November 15, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant