# Catser 🐾 A Windows desktop cat companion inspired by [Workcat](https://workcat.app/en/#how) and [Desktop Goose](https://github.com/arkangel-dev/desktop-goose-source). **Catser** wanders across your Windows desktop, interacts with you, and automatically monitors your active windows using [ActivityWatch](https://activitywatch.net/) (with a native Windows API fallback). When it spots drift content like **YouTube Shorts**, **Instagram Reels**, or **TikTok**, the cat perks up in alert, sprints and leaps to the target window's close button `[X]`, and **closes the window with a swift paw strike!** --- ## Features - 🐱 **Authentic Workcat Animations**: - **Walk Cycle**: 30 smooth SVG silhouette frames with antialiased vector rasterization and natural cadence. - **Paw Strike**: 17 WebP animation frames at 24 FPS with contact triggered on **Frame 14** (`PAW_CONTACT_FRAME`). - **Scruff Dragging**: Pick up the cat by its neck scruff (`scruff.webp`) and move it anywhere on your screen. - **Gravity Physics**: When released in mid-air, the cat falls back down to the desktop floor with quadratic acceleration (`t²`). - **Interactive Petting**: Click the cat without dragging to see happy eyes (`FACE_HAPPY`) and a rising floating heart particle (`♥`). - **Autonomous Life Actions**: Sits, sleeps (with floating `z` snoring particle), stretches (37 frames), and flicks its tail (37 frames). - **6 Coat Colors**: Ivory, Charcoal, Grey, Apricot, Sage, and Plum. - ⏱️ **ActivityWatch Backend**: - Connects to `http://localhost:5600/api/0` and discovers active `aw-watcher-window_*` buckets. - Monitors active application executables and window titles in real-time. - **Zero-Config Fallback**: If ActivityWatch is offline or not installed, Catser automatically falls back to native Windows OS APIs (`GetForegroundWindow`, `GetWindowTextW`), ensuring it works right out of the box. - 🎯 **Pinpoint Targeting & Window Closing**: - Catser calculates the exact screen coordinates of the target window's `[X]` close button. - Applies Workcat's contact offset formula: $$\text{offset}_x = \text{width} \times 1.0858$$ $$\text{offset}_y = \text{height} \times 0.3874$$ - Sprints diagonally across your screen to reach the close button, strikes it with its paw, and dispatches native `WM_CLOSE` to close the distracting app. - 🪟 **Window Platforming & Ledge Walking**: - Treats the top frames of visible open application windows (browsers, editors, terminals) as physical platforms. - Cat autonomously performs parabolic leaps onto window ledges, walks along them, sits, naps, and hops back down. - Dynamic surface tracking: If an underlying window moves or closes while the cat is resting on it, the cat wakes up and falls under gravity to the next surface or floor. - 🖥️ **Dynamic Multi-Monitor & Resolution Detection**: - Full virtual desktop support spanning all connected displays with arbitrary resolutions, positions, and DPI scaling. - **Live Hotplug Detection**: Listens to Win32 `WM_DISPLAYCHANGE` and `WM_SETTINGCHANGE` system events (with a 1.5s background check) to dynamically detect when monitors are connected, disconnected, rearranged, or when display resolution/scaling changes. - Automatically recalculates screen bounds and taskbar floors in real-time, clamping the cat into valid active displays so it never gets stranded off-screen. - Seamlessly navigates elevation differences between monitors (e.g. stepping off higher floors into gravity falls, or leaping up steep monitor steps). - 🪟 **High-Performance Transparent Overlay**: - Built with Win32 Layered Windows (`WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE`). - Uses `UpdateLayeredWindow` with 32-bit ARGB premultiplied alpha (vectorized with numpy) for clean anti-aliased fur edges, soft contact shadows, and tear-free 60 FPS rendering. - Pixel-perfect hit-testing allows mouse clicks on transparent regions to pass through to your apps, while clicking the cat itself allows dragging and petting. --- ## Quickstart ### Prerequisites - Windows 10 or Windows 11 - Python 3.10+ (Python 3.14 fully supported) - [ActivityWatch](https://activitywatch.net/) *(optional, runs with native fallback if not active)* ### Installation Clone the repository and install required dependencies: ```bash git clone https://github.com/yourusername/Catser.git cd Catser py -m pip install pillow ``` ### Running Catser Run Catser with default settings (Ivory coat, closes Shorts/Reels/TikTok): ```bash py run_catser.py ``` Run in **Test Mode** (demonstrates an attack sprint and paw strike in 5 seconds): ```bash py run_catser.py --test ``` --- ## CLI Options & Customization | Flag | Options | Default | Description | |------|---------|---------|-------------| | `--coat` | `ivory`, `charcoal`, `grey`, `apricot`, `sage`, `plum` | `ivory` | Choose the cat's fur coat color. | | `--action` | `close`, `minimize`, `notify` | `close` | Action to take when the paw strikes the window. | | `--aw-url` | URL string | `http://localhost:5600` | ActivityWatch server endpoint. | | `--add-keyword` | keyword string | *None* | Add custom window title keyword to close. | | `--width` | integer | `144` | Rendered width of the cat in pixels. | | `--test` | *flag* | *False* | Launch in test demonstration mode. | | `--verbose`, `-v` | *flag* | *False* | Enable debug logging output. | ### Examples **Select a Charcoal cat that minimizes windows instead of closing them:** ```bash py run_catser.py --coat charcoal --action minimize ``` **Add custom distraction targets (e.g. Steam, Reddit, Netflix):** ```bash py run_catser.py --add-keyword "steam" --add-keyword "netflix" --add-keyword "reddit" ``` --- ## User Interaction & Controls - **Drag the Cat**: Click and drag the cat anywhere on your desktop. It switches to the scruff sprite (`scruff.webp`). When released, it falls back down to your taskbar. - **Pet the Cat**: Click the cat once without moving your mouse. It will purr, show smiling eyes (`^^`), emit a floating heart particle, and flick its tail. - **Exit**: Press `Ctrl+C` in the terminal to close Catser cleanly. --- ## Architecture & Codebase Overview ``` Catser/ ├── run_catser.py # CLI launcher and entry point ├── README.md # Project documentation ├── .gitignore # Git ignore rules └── catser/ ├── __init__.py # Package version and metadata ├── config.py # Constants, kinematics, coats, and distraction rules ├── assets_manager.py # Workcat sprite pipeline (vector rasterization & WebP frames) ├── window_manager.py # Win32 window handles, geometry, and WM_CLOSE dispatcher ├── activitywatch.py # ActivityWatch REST client with native Win32 fallback ├── overlay.py # Win32 32-bit ARGB layered window overlay ├── cat_controller.py # State machine, trajectory kinematics, and paw attack ├── app.py # 60 FPS animation loop and coordinator └── assets/ # Bundled sprite animations (walk, paw, tail, stretch, scruff) ``` --- ## Technical Details ### Kinematic & Physics Constants Sourced directly from Workcat's engine (`apps/desktop/src/features/pet-mode/petModeData.ts` and `cat.js`) and desktop physics kinematics: - `WALK_SPEED = 20.8` (stride = `26.0`, cadence = `0.9`) - `RUN_SPEED = 300.0` (stride = `72.0`) - `PAW_FPS = 24` (17 total frames, contact at index `14`) - `CONTACT_RATIO_X = (143.0 - 11.4) / 121.2 ≈ 1.0858` - `CONTACT_RATIO_Y = (40.0 - 4.2) / 92.4 ≈ 0.3874` - `ALERT_HOLD_MS = 620ms` - `GRAVITY = 1600.0 px/s²` (smooth parabolic acceleration during falls and jumps) - `JUMP_VELOCITY = 650.0 px/s` (dynamic trajectory calculation solving launch velocity $(v_x, v_y)$ for any elevation difference) ### Window Platforming & Multi-Monitor Support - Uses Win32 `OpenInputDesktop` and `EnumDesktopWindows` to extract visible top frames of non-minimized desktop windows as physical ledges. - Tracks multi-display monitor geometries via `EnumDisplayMonitors` / `GetMonitorInfoW` to support arbitrary screen resolutions and vertical offsets. ### Win32 Window Closing On contact frame 14, Catser issues both `WM_CLOSE` (`0x0010`) and `WM_SYSCOMMAND / SC_CLOSE` (`0x0112 / 0xF060`) to the target window's handle (`HWND`), ensuring smooth closing across standard Win32 apps and Chromium browsers. --- ## License MIT License. Sprite assets courtesy of [Workcat](https://workcat.app).