diff --git a/src/generalagents/macos/computer.py b/src/generalagents/macos/computer.py index cdd6e82..7eebed0 100644 --- a/src/generalagents/macos/computer.py +++ b/src/generalagents/macos/computer.py @@ -5,6 +5,7 @@ import pyautogui from PIL import Image +from pytweening import easeInOutQuad from generalagents.action import ( Action, @@ -23,6 +24,8 @@ ) pyautogui.FAILSAFE = True # Move mouse to corner to abort +pyautogui.PAUSE = 0.001 # We are waiting manually in the code +MOUSE_SETTINGS = {"duration": 0.101, "tween": easeInOutQuad} # duration <= 0.1 is treated as 0 by pyautogui class Computer: @@ -52,25 +55,28 @@ def _scaled(self, coord: Coordinate) -> tuple[int, int]: def _execute_action(self, action: Action) -> None: match action: case ActionKeyPress(kind="key_press", keys=keys) if keys: - pyautogui.hotkey(*keys) + for key in keys: + pyautogui.keyDown(key) + for key in reversed(keys): + pyautogui.keyUp(key) case ActionType(kind="type", text=text) if text: pyautogui.write(text) case ActionLeftClick(kind="left_click", coordinate=coord): - pyautogui.click(*self._scaled(coord), button="left") + pyautogui.click(*self._scaled(coord), button="left", **MOUSE_SETTINGS) case ActionRightClick(kind="right_click", coordinate=coord): - pyautogui.click(*self._scaled(coord), button="right") + pyautogui.click(*self._scaled(coord), button="right", **MOUSE_SETTINGS) case ActionDoubleClick(kind="double_click", coordinate=coord): - pyautogui.doubleClick(*self._scaled(coord)) + pyautogui.doubleClick(*self._scaled(coord), **MOUSE_SETTINGS) case ActionTripleClick(kind="triple_click", coordinate=coord): - pyautogui.tripleClick(*self._scaled(coord)) + pyautogui.tripleClick(*self._scaled(coord), **MOUSE_SETTINGS) case ActionMouseMove(kind="mouse_move", coordinate=coord): - pyautogui.moveTo(*self._scaled(coord)) + pyautogui.moveTo(*self._scaled(coord), **MOUSE_SETTINGS) case ActionDrag(kind="drag", drag_start=start, drag_end=end): pyautogui.moveTo(*self._scaled(start))