Skip to content

Fix gestures losing global input after retrying the hook - #126

Merged
KnifeLemon merged 1 commit into
KnifeLemon:mainfrom
leishifu666:fix/gesture-hook-restart
Oct 19, 2026
Merged

KnifeLemon merged 1 commit into
KnifeLemon:mainfrom
leishifu666:fix/gesture-hook-restart

Conversation

@leishifu666

Copy link
Copy Markdown
Contributor

What does this change?

Retrying gestures can leave Filee reporting a running global input hook while Ctrl+drag no longer opens the radial toolbar and Explorer performs its normal copy operation. Wait for the previous hook's native cleanup to finish before starting its replacement.

RetryHook calls Dispose() followed immediately by Start(). SharpHook requests shutdown asynchronously, and its RunAsync() task completes before the finally block clears the process-wide dispatch callback (SharpHook 8.0.1 source). The old thread can therefore clear the new hook's callback.

This change runs the hook on an owned background thread and joins it after disposal, with a five-second limit. If stopping fails or times out, ownership is retained so a second hook cannot overlap. The existing Linux backend diagnostics are preserved. A failed stop also suppresses SharpHook's finalizer when it has already marked the hook disposed, avoiding a second disposal of its completed event queue.

How was it tested?

  • dotnet format Filee.slnx --verify-no-changes --no-restore
  • dotnet test tests/Filee.App.Tests/Filee.App.Tests.csproj -c Release --filter FullyQualifiedName~TriggerServiceLifecycleTests — 3 passed.
  • dotnet test tests/Filee.App.Tests/Filee.App.Tests.csproj -c Release --no-build --filter "FullyQualifiedName~GestureDetectorTests|FullyQualifiedName~TriggerServiceLifecycleTests|FullyQualifiedName~HookFailureTests" — 13 passed, 0 failed, 0 skipped. This includes the existing gesture state machine and Linux hook-error diagnostics.
  • Full current-main application suite: attempted, then intentionally stopped after about 20 minutes of very slow UI resource updates. Stack samples showed different DonutGroupTests cases executing LocalizationService.SetLanguage, rather than waiting in the hook lifecycle code. There is no completed full-suite result for this PR. Two Explorer-menu packaging tests skipped because the native DLL/MSIX build artifacts were absent locally.
  • The equivalent v1.11.0-based fixed build had previously completed the application suite: 268 passed, 0 failed, 2 skipped. That result is for the earlier baseline, not the current-main PR build.
  • The regression tests use a fake native provider with the real EventLoopGlobalHook: delayed native cleanup, 30 successive restarts that each deliver input, and a failed stop that must not start another hook. No OS input is hooked by these tests.
  • Tried it in the app on Windows, using the equivalent fix on the v1.11.0 installation before adapting this PR to current main: 10 consecutive clicks of Retry gestures retained input; two real Ctrl+drag attempts opened the radial toolbar, confirmed by the user and gesture logs. A radial-toolbar PNG-to-PDF conversion also completed.

Native Linux/macOS gestures and the other test projects were not run locally. The installed-build manual checks above are separate from the automated checks against this PR's current-main build.

Screenshots (UI changes)

No layout or visual changes.

Checklist

  • Localization: no new control labels; the shutdown timeout is a diagnostic error, alongside the existing raw native-hook errors.
  • Third-party notices: no new dependencies, third-party code, or binaries.

@KnifeLemon
KnifeLemon merged commit 76dc187 into KnifeLemon:main Oct 19, 2026
9 checks passed
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.

2 participants