|
| 1 | +Held Modifiers Across an Action Group |
| 2 | +===================================== |
| 3 | + |
| 4 | +``hotkey`` presses a set of keys and releases them immediately — fine for a |
| 5 | +one-shot chord, but there was no way to hold ``ctrl`` (or ``shift``) *down across |
| 6 | +several independent actions* (range-select with shift-clicks, ctrl-clicks to |
| 7 | +multi-select) and be sure the modifiers are released even if one of those actions |
| 8 | +raises. |
| 9 | + |
| 10 | +:func:`plan_with_modifiers` wraps an op-step list with press / release steps and |
| 11 | +is pure / unit-testable; :func:`hold_modifiers` is a context manager that presses |
| 12 | +on enter and releases (in reverse) on exit — including on exception — |
| 13 | +dispatching through an injectable ``sink``. Imports no ``PySide6``. |
| 14 | + |
| 15 | +Headless API |
| 16 | +------------ |
| 17 | + |
| 18 | +.. code-block:: python |
| 19 | +
|
| 20 | + from je_auto_control import hold_modifiers, plan_with_modifiers |
| 21 | + from je_auto_control import click_mouse |
| 22 | +
|
| 23 | + # shift-held range select: every click happens with shift down |
| 24 | + with hold_modifiers(["shift"]): |
| 25 | + click_mouse("mouse_left", 100, 100) |
| 26 | + click_mouse("mouse_left", 100, 300) |
| 27 | + # shift is released here — even if a click raised |
| 28 | +
|
| 29 | + plan_with_modifiers([{"op": "click"}], ["ctrl", "shift"]) |
| 30 | + # press ctrl, press shift, click, release shift, release ctrl |
| 31 | +
|
| 32 | +Modifiers are pressed in order on entry and released in *reverse* order on exit, |
| 33 | +in a ``finally`` block, so a stuck modifier can never leak. ``plan_with_modifiers`` |
| 34 | +is the pure plan for any op-step list. |
| 35 | + |
| 36 | +Executor commands |
| 37 | +----------------- |
| 38 | + |
| 39 | +``AC_with_modifiers`` runs a nested JSON action list while ``modifiers`` (e.g. |
| 40 | +``["ctrl"]`` or ``"ctrl+shift"``) are held, releasing them even if an action |
| 41 | +fails. It is exposed as the MCP tool ``ac_with_modifiers`` and as a Script |
| 42 | +Builder command under **Keyboard**. |
0 commit comments