162 lines
8.0 KiB
Markdown
162 lines
8.0 KiB
Markdown
# 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.
|
|
|
|
- 🖥️ **Multi-Monitor Roaming & Elevation Navigation**:
|
|
- Full virtual desktop support spanning all connected displays with arbitrary resolutions, positions, and DPI.
|
|
- Automatically calculates distinct taskbar/work-area floors for each screen.
|
|
- Seamlessly handles elevation differences (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).
|