Catser 🐾
A Windows desktop cat companion inspired by Workcat and Desktop Goose.
Catser wanders across your Windows desktop, interacts with you, and automatically monitors your active windows using ActivityWatch (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
zsnoring 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/0and discovers activeaw-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.
- Connects to
-
🎯 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_CLOSEto close the distracting app.
- Catser calculates the exact screen coordinates of the target window's
-
🪟 High-Performance Transparent Overlay:
- Built with Win32 Layered Windows (
WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE). - Uses
UpdateLayeredWindowwith 32-bit ARGB premultiplied alpha 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.
- Built with Win32 Layered Windows (
Quickstart
Prerequisites
- Windows 10 or Windows 11
- Python 3.10+ (Python 3.14 fully supported)
- ActivityWatch (optional, runs with native fallback if not active)
Installation
Clone the repository and install required dependencies:
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):
py run_catser.py
Run in Test Mode (demonstrates an attack sprint and paw strike in 5 seconds):
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:
py run_catser.py --coat charcoal --action minimize
Add custom distraction targets (e.g. Steam, Reddit, Netflix):
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+Cin 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):
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 index14)CONTACT_RATIO_X = (143.0 - 11.4) / 121.2 ≈ 1.0858CONTACT_RATIO_Y = (40.0 - 4.2) / 92.4 ≈ 0.3874ALERT_HOLD_MS = 620ms
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.