Modal-aware invoke + display keep-awake - #1
Merged
Conversation
UIA pattern calls (Invoke/Toggle/Select) are synchronous cross-process calls. In WinForms/DevExpress apps a click handler that opens a modal dialog (ShowDialog) does not return until the dialog closes, so the pattern call - and with it the target app's entire UIA provider - stays blocked, causing every tool to hit the 30s timeout. windows_click now runs the pattern call on a background thread while watching the target process's top-level windows via non-blocking Win32 APIs. When a modal is detected (new top-level window, or owner window disabled) it returns immediately with the dialog title instead of hanging. While a provider is blocked by a pending call, ref-based tools (snapshot, get_text, click, type, fill, send_keys) and batch actions fail fast with guidance instead of timing out. windows_list_windows/focus/close now use Win32 (never blocked), and windows_screenshot falls back to a Win32 window-bounds capture. Tools that do not need UIA - screenshot, ref-less send_keys/type - keep working throughout, so a modal can be seen and dismissed. Adds ModalAwareInvoker, PendingInvokeTracker, Win32Desktop, unit tests, and a desktop integration test exercising the WinForms test app's modal dialog.
Long automation runs generate no keyboard or mouse input, so Windows turns off the display and shows the lock screen mid-run, breaking screenshots and interaction. The server now holds a Windows power availability request (PowerCreateRequest/PowerSetRequest with DisplayRequired + SystemRequired) - the same signal video players and conferencing apps send - while tool calls are arriving, visible in `powercfg /requests` with a diagnostic reason. The request uses a sliding hold: the first tool call acquires it, every call extends it, and it is released after 5 minutes without activity so an idle server does not keep the screen on. Configure the idle period (or disable with 0) via FLAUI_MCP_KEEP_AWAKE_SECONDS. Note: a group-policy machine inactivity limit locks on raw input idle time and cannot be suppressed by availability requests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Modal-aware invoke + display keep-awake
Two features that make long, unattended automation runs against WinForms/DevExpress apps (e.g. Tabular Editor 3) actually survive: clicks that open modal dialogs no longer hang the server, and Windows no longer locks the screen mid-run.
Modal dialog detection (
e943ed7)UIA pattern calls (Invoke/Toggle/Select) are synchronous cross-process calls. In WinForms/DevExpress apps, a click handler that opens a modal dialog (
ShowDialog()) does not return until the dialog closes — so the pattern call, and with it the target app's entire UIA provider, stays blocked, and every subsequent tool call hits the 30s timeout.What changed:
windows_clicknow runs the pattern call on a background thread while watching the target process's top-level windows via non-blocking Win32 APIs. When a modal is detected (new top-level window, or owner window disabled), the tool returns immediately with the dialog's title and interaction guidance instead of hanging.windows_snapshot,windows_get_text,windows_click,windows_type,windows_fill, ref-basedwindows_send_keys) andwindows_batchactions targeting that app fail fast with guidance instead of timing out.windows_list_windows,windows_focusandwindows_closenow use Win32 (EnumWindows/SetForegroundWindow/WM_CLOSE), so they are never blocked. Window handles are also stable acrosswindows_list_windowscalls now.windows_screenshotfalls back to a Win32 window-bounds capture while the provider is blocked.send_keys/type).Typical flow: click a button → "modal dialog opened" → screenshot to see it → send keys to dismiss it → snapshot works again.
New components:
ModalAwareInvoker,PendingInvokeTracker,Win32Desktop.Display keep-awake (
c218870)Long automation runs generate no keyboard or mouse input, so Windows turns off the display and shows the lock screen mid-run — breaking screenshots and interaction.
What changed:
PowerCreateRequest/PowerSetRequestwithDisplayRequired+SystemRequired) — the same signal video players and conferencing apps send. Visible inpowercfg /requests(elevated) as "FlaUI-MCP is driving Windows UI automation".FLAUI_MCP_KEEP_AWAKE_SECONDSenvironment variable (positive value = idle period,0= disabled).Limitation (documented in README): a domain group policy enforcing a hard machine inactivity limit ("Interactive logon: Machine inactivity limit") locks on raw input idle time and cannot be suppressed by availability requests.
New components:
KeepAwake(sliding-hold controller),PowerAvailabilityRequest(Win32 wrapper);ToolRegistrygained anonToolActivitycallback.Housekeeping
release.ymlnow points at this fork instead of upstreamshanselman/FlaUI-MCP(837201f).publish/output is now gitignored (9153469).Testing
ModalAwareInvokerTests,PendingInvokeTrackerTests,KeepAwakeTests(sliding-hold semantics, dispose behavior, and a live round-trip through the realPowerCreateRequestAPI), plus aToolRegistryactivity-callback test — 32 tests passing.ModalDialogTests) exercises the WinForms test app's modal dialog end-to-end (requires an interactive Windows session).🤖 Generated with Claude Code