Skip to content

fix(task): prepare foreground interaction before one-time capture - #95

Open
sinxy-sai wants to merge 1 commit into
ok-oldking:masterfrom
sinxy-sai:codex/fix-onetime-task-foreground
Open

sinxy-sai wants to merge 1 commit into
ok-oldking:masterfrom
sinxy-sai:codex/fix-onetime-task-foreground

Conversation

@sinxy-sai

@sinxy-sai sinxy-sai commented Sep 8, 2026

Copy link
Copy Markdown

Summary

  • Prepare foreground interaction backends before the first frame of a one-time task.
  • Prevent one-time tasks from waiting in the pre-run capture path when the target window is in the background.
  • Add regression tests for one-time and trigger-task preparation, including the execution order.

Related to #94

Context

This was found while developing and repeatedly debugging FishingOnceTask in ok-how-to-fish, an application created from the ok-script application template. The task uses the normal BaseTask API, and the GUI Run action uses the framework's normal StartController.start(task) entry point.

Root cause

TaskExecutor.execute() requested the first frame before calling a one-time task's run(). With foreground interaction backends such as Pynput or PyDirect, should_capture() returns false while the target window is not foreground. A task-level ensure_in_front() inside run() therefore cannot prepare the window before that first capture request.

The result is that a one-time task can be queued and taken by the executor but remain in the pre-run capture path for an avoidable and potentially long delay before entering run(). The exact delay depends on the capture backend, window focus, and related frame checks; this is not a deliberate task-level wait and can look like the task is stuck.

The GUI task start path eventually uses StartController._mark_task_enabled(), which directly marks the task enabled and queues it instead of calling BaseTask.enable(). This means the existing interaction.on_run() call in BaseTask.enable() does not cover this framework entry path. The same controller path is also used by command-line/headless and Web/API starts.

This is a framework lifecycle/order issue, not an incorrect ok-how-to-fish task API call or an incorrect GUI debug action.

Fix

Call interaction.on_run() before requesting the first frame for one-time tasks. This lets foreground-dependent interaction backends prepare the target window before capture begins.

Trigger tasks retain their existing behavior and are not forcibly foregrounded by this change.

Validation

  • python -m unittest discover -s tests -p "test_task_executor_queue.py" -v
  • Result: 9 tests passed in the contributor environment
  • py_compile passed for the changed Python files

One-time tasks could block in next_frame when a foreground interaction backend reported that the target window was not active. Prepare the interaction backend before requesting the first frame so task.run() can execute normally.

Add regression coverage for one-time and trigger-task preparation, including the execution order.
@sonarqubecloud

sonarqubecloud Bot commented Sep 8, 2026

Copy link
Copy Markdown

@ok-oldking

Copy link
Copy Markdown
Owner

哪里会用到

@sinxy-sai

Copy link
Copy Markdown
Author

@ok-oldking 这个修改用于一次性任务的启动流程。任务被执行器取出后,会在第一次调用 next_frame() 之前执行 interaction.on_run()

对于 PynputPyDirect 等要求目标窗口处于前台的交互方式,这可以避免一次性任务在首次取帧阶段长时间等待,使任务能够正常进入 task.run()

原因是标准的 StartController.start(task) 流程会直接标记任务并入队,没有经过 BaseTask.enable() 中已有的 interaction.on_run() 调用,因此需要在执行器这里补上。

持续执行的 TriggerTask 不会走这段新逻辑,原有行为不受影响。

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