from abc import ABC, abstractmethod from ctypes import WINFUNCTYPE, byref, windll from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, LPRECT, POINT, RECT import time user32 = windll.user32 user32.GetCursorPos.argtypes = [LPPOINT] user32.SetCursorPos.argtypes = [INT, INT] user32.GetSystemMetrics.argtypes = [INT] CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) user32.EnumWindows.argtypes = [CB_ENUM_WINDOWS, LPARAM] user32.GetWindowRect.argtypes = [HWND, LPRECT] user32.SetWindowPos.argtypes = [HWND, INT, INT, INT, INT, INT, INT] user32.IsWindowVisible.argtypes = [HWND] def get_resolution_y() -> int: SM_CYSCREEN = 1 return user32.GetSystemMetrics(SM_CYSCREEN) class BouncyObject(ABC): @abstractmethod def get_position(self) -> tuple[int, int]: raise NotImplementedError @abstractmethod def set_position(self, xy: tuple[int, int]) -> None: raise NotImplementedError class Mouse(BouncyObject): def get_position(self) -> tuple[int, int]: point = POINT() user32.GetCursorPos(byref(point)) return point.x, point.y def set_position(self, xy: tuple[int, int]): x, y = xy user32.SetCursorPos(x, y) class Window(BouncyObject): def __init__(self, handle: int): self._handle = handle def get_position(self) -> tuple[int, int]: rect = RECT() user32.GetWindowRect(self._handle, byref(rect)) return (rect.left, rect.bottom) def set_position(self, xy: tuple[int, int]) -> None: rect = RECT() user32.GetWindowRect(self._handle, byref(rect)) height = rect.bottom - rect.top x, y = xy user32.SetWindowPos( self._handle, 0, x, y - height, -1, -1, 0x0010 | # SWP_NOACTIVATE 0x0001 | # SWP_NOSIZE 0x0004 | # SWP_NOZORDER 0x4000 # SWP_ASYNCWINDOWPOS ) class Body(object): def __init__(self, controlled_object: BouncyObject): self._last_offset: tuple[float, float] = (0.5, 0.5) self._velocity = 0.0 self._controlled_object = controlled_object def update(self, res_y: int) -> None: x, y = self._controlled_object.get_position() ox, oy = self._last_offset x += ox y += oy for _ in range(100): self._velocity += 0.0002 y += self._velocity if y > res_y and self._velocity > 0: self._velocity = -self._velocity * 0.75 if abs(self._velocity) < 0.05: self._velocity = 0 x_int, y_int = int(x), min(int(y), res_y) self._controlled_object.set_position((x_int, y_int)) self._last_offset = x - x_int, y - y_int def enumerate_windows() -> list[int]: windows: list[int] = [] @CB_ENUM_WINDOWS def _handle_window(hwnd: int, _lparam: int): if user32.IsWindowVisible(hwnd): windows.append(hwnd) return True user32.EnumWindows(_handle_window, 0) return windows class Bodies(object): def __init__(self): self._mouse = Body(Mouse()) self._windows = {} def enumerate(self): windows_2 = {} for i in enumerate_windows(): if existing := self._windows.get(i): windows_2[i] = existing else: windows_2[i] = Body(Window(i)) self._windows = windows_2 def get(self) -> list[Body]: return [self._mouse, *self._windows.values()] def main(): bodies = Bodies() while True: res_y = get_resolution_y() bodies.enumerate() for b in bodies.get(): b.update(res_y) time.sleep(1.0/120.0) if __name__ == "__main__": main()