Commit Graph
38 Commits
Author SHA1 Message Date
me0nline 81f190b936 feat(assets): add multi-resolution Windows application icon catser.ico 2026-09-09 00:21:01 +02:00
me0nline 6f678ec0a4 feat(assets): support PyInstaller sys._MEIPASS frozen asset bundle path 2026-09-09 00:19:35 +02:00
me0nline c8f12b26c1 docs: document dynamic monitor hotplug and resolution detection 2026-09-08 23:47:57 +02:00
me0nline 449c6bac9a feat(app): connect overlay on_display_change to controller.refresh_display_bounds 2026-09-08 23:47:32 +02:00
me0nline 8aeb5360f6 feat(controller): add refresh_display_bounds and dynamic resolution and monitor change detection 2026-09-08 23:47:22 +02:00
me0nline 3afd197027 feat(overlay): handle WM_DISPLAYCHANGE and WM_SETTINGCHANGE for dynamic display updates 2026-09-08 23:46:55 +02:00
me0nline 0033fbce9b feat(window_manager): add get_display_topology_signature for dynamic monitor and resolution change detection 2026-09-08 23:46:30 +02:00
me0nline 59ba4b988f docs: document window ledge platforming, jumping kinematics, and multi-monitor roaming 2026-09-08 23:45:00 +02:00
me0nline dc2d6ee9eb feat(controller): add jump state, window platform walking, and multi-monitor physics navigation 2026-09-08 23:44:43 +02:00
me0nline 5d152db057 feat(window_manager): add multi-monitor awareness, floor calculation, and window ledge platform extraction 2026-09-08 23:41:25 +02:00
me0nline 71fe013c80 feat(config): add physics and window platforming parameters 2026-09-08 23:40:33 +02:00
me0nline a969c91c28 feat(aw): scan both active foreground and visible desktop windows for distractions
Previously, fallback window detection only checked user32.GetForegroundWindow().
If the user had YouTube Shorts open in Chrome on a second monitor or behind the terminal,
it was ignored.

Now check_for_distraction():
1. Checks the active foreground window first.
2. If not a distraction, scans all visible top-level desktop windows via find_window_by_match().
3. Immediately wakes the cat from sleeping or sitting if any distraction window is discovered.
2026-09-08 23:38:00 +02:00
me0nline 6204a88792 feat(window_manager): use OpenInputDesktop in find_window_by_match and exclude Catser overlay
Ensures desktop window enumeration accesses the user's interactive desktop station
across multiple monitors and ignores Catser's own overlay window.
2026-09-08 23:37:54 +02:00
me0nline ff8cc01dd8 feat(config): increase sleep duration to 1-4 minutes and expand default distraction keywords
1. Increased SLEEP_MIN_MS to 60s and SLEEP_MAX_MS to 240s so the cat takes real
   naps (1-4 min) instead of waking up after only a few seconds.
2. Increased SIT_MIN_MS to 15s and SIT_MAX_MS to 45s.
3. Added 'youtube', 'youtube.com/shorts', 'instagram', and 'twitch' to default
   distraction keywords. Browser tabs playing YouTube Shorts have titles like
   '<Video Title> - YouTube - Google Chrome' where 'shorts' does not appear.
2026-09-08 23:37:49 +02:00
me0nline e439e638da fix(app): initialize overlay with canvas dimensions and offset draw_frame by padding 2026-09-08 23:33:20 +02:00
me0nline 3b202c8e68 fix(controller): update particle positioning and compositing for padded canvas 2026-09-08 23:33:16 +02:00
me0nline 78b3f949c3 fix(assets): unified padded canvas eliminates tail clipping and fixes animation scaling
Workcat's tail flick (-15% left), paw reach (+9% right), and stretch motions
extend beyond the nominal cat bounding box. Previously, frames were drawn
onto a compact 144x110 canvas without padding, causing negative offsets
(e.g. ox=-22px on tail) to truncate the tail tip and create mismatched scales.

Fixes:
- Added padding (pad_x=20%, pad_y=20%) to the render canvas so all extended
  poses (tail swings to x=16, paw strikes to x=185) fit completely without clipping.
- Unified the coordinate system: walk, tail, stretch, paw, and scruff now share
  the exact same body scale (height ~93-94px) and feet baseline (y=128).
2026-09-08 23:33:12 +02:00
me0nline 0d52a5451b feat(config): add canvas dimensions and padding properties for extended animation motions 2026-09-08 23:33:08 +02:00
me0nline 07b4fbd401 fix(app): signal background ActivityWatch worker to stop on shutdown 2026-09-08 23:26:31 +02:00
me0nline bbc6768b78 perf(overlay): pre-allocate persistent DIB section and handle WM_SETCURSOR
1. Handled WM_SETCURSOR explicitly in the window procedure, setting IDC_HAND
   when dragging/hovering and returning 1 to prevent Windows from displaying
   an hourglass/wait cursor.
2. Pre-allocated persistent memory DC, DIB section, and buffer pointer in
   _init_gdi_resources() instead of allocating and freeing them 60 times/sec
   in draw_frame(), eliminating GDI handle churn.
3. Added cleanup of DIB/DC handles and class unregistration in destroy().
2026-09-08 23:26:26 +02:00
me0nline 4d1d7cc655 perf(aw): run ActivityWatch polling in background thread to eliminate UI freezes
Synchronous urllib calls in the 60 FPS main loop caused a 3-second network
connect timeout every 5 seconds whenever ActivityWatch was offline (due to
Windows IPv6/IPv4 localhost resolution). This completely froze the main thread,
stalled the Windows message pump, and triggered Windows Hung-App detection
(hourglass / wait cursor).

ActivityWatchClient now polls in a dedicated daemon worker thread:
- All socket connections and HTTP timeouts occur in the background thread.
- get_current_window_event() reads cached state in 0ms without blocking.
- Fallback to native Win32 window APIs is immediate with zero latency.
2026-09-08 23:26:21 +02:00
me0nline 145971f6ab fix(assets): correct walk frame scaling -- remove 1.25 overcorrection and wrong GAIT_SHIFT
The walk polygon was rendered 25% too large due to an erroneous * 1.25
factor on scale_x / scale_y. On top of this, GAIT_SHIFT_X=-6.383 and
GAIT_SHIFT_Y=3.76 (internal cat.js group transforms) were incorrectly
ported as canvas offsets, pushing the polygon partially above the top
edge of the overlay window (visible clipping).

Root cause: the SVG viewBox is 0 0 150 120. Walk polygon coordinates
span 4-145 in X and 8-112 in Y -- already fitting the viewBox with no
additional scaling or translation needed.

Fix: use scale_x = (cat_width / 150) * SS and scale_y = (cat_height / 120) * SS
with zero offset. Walk frame now renders at the same visual size as paw/
scruff/tail/stretch frames (all on a cat_width x cat_height canvas).

Result: cat body is no longer clipped at the top and matches size of all
other animation states.
2026-09-08 23:20:57 +02:00
me0nline 4e57a9c596 fix(cat_controller): use virtual desktop bounds for drag, work area for walk
Split screen boundary usage into two sources:

1. walk / roam / run-to-target (unchanged):
   - self.screen_* = WindowManager.get_work_area() (primary monitor, taskbar-aware)
   - Cat autonomously roams the primary desktop floor only

2. drag clamping (new):
   - self.vd_* = WindowManager.get_virtual_desktop_bounds() (all monitors)
   - on_mouse_move() clamps to vd_left/right/top/bottom instead of
     screen_left/right/top/bottom
   - User can now pick up the cat and drag it to any connected monitor

Previously on_mouse_move() clamped to the primary work area rectangle
(0, 0, 1920, 1032), so moving the cursor past x=1776 would immediately
snap the cat back, making the second monitor unreachable.
2026-09-08 23:17:18 +02:00
me0nline f20a6129f6 perf(overlay): replace O(N) Python pixel loop with numpy vectorised premultiply
_premultiply_bgra() was iterating over every RGBA pixel in a pure-Python
for-loop at 60 FPS (144x110 sprite = ~950k iterations/sec).  This was the
primary cause of UI hangs.

New implementation uses numpy:
  - np.frombuffer + reshape to view raw bytes as (H*W, 4) uint8 array
  - Fancy-index column reorder [2,1,0,3] for R,G,B,A -> B,G,R,A in one op
  - float32 alpha / 255 premultiplication via broadcasting
  - tobytes() to emit the final DIB data

Roughly 100x faster than the previous loop, freeing the main thread to
sustain 60 FPS without freezing.
2026-09-08 23:17:10 +02:00
me0nline ff6158e7a0 feat(window_manager): add get_virtual_desktop_bounds() for multi-monitor support 2026-09-08 23:17:01 +02:00
me0nline e2e66c1938 docs: add comprehensive README with setup, ActivityWatch integration, and usage 2026-09-08 23:07:15 +02:00
me0nline ad440a49b3 feat(cli): add top-level launcher and CLI options 2026-09-08 23:06:45 +02:00
me0nline 28a8f8597f feat(app): add main application loop, distraction detection, and window closing logic 2026-09-08 23:06:34 +02:00
me0nline dedae31a66 feat(controller): add cat AI state machine, kinematics, and paw targeting logic 2026-09-08 23:06:14 +02:00
me0nline 4eeb96d5b6 fix(overlay): declare complete 64-bit ctypes prototypes for GDI/User32 2026-09-08 23:05:49 +02:00
me0nline 9bade210f5 feat(overlay): add Win32 32-bit ARGB layered window overlay 2026-09-08 23:05:04 +02:00
me0nline ddf99b8664 feat(activitywatch): add ActivityWatch client with native fallback 2026-09-08 23:04:44 +02:00
me0nline 3dfec1896e feat(windows): add Win32 window manager for HWND search, coords, and closing 2026-09-08 23:04:23 +02:00
me0nline 880e772668 feat(assets): add bundled Workcat sprite frames (walk, paw, tail, stretch, scruff) 2026-09-08 23:04:06 +02:00
me0nline eaae0b96aa feat(assets): add asset manager for Workcat sprites, animations, and coats 2026-09-08 23:02:50 +02:00
me0nline 44d6f3b1c5 feat(config): add configuration parameters, kinematics, and distraction targets 2026-09-08 23:02:22 +02:00
me0nline fe1c3c4b73 feat: initialize catser package 2026-09-08 23:02:10 +02:00
me0nline 7a0d397fb1 build: initialize git repository and gitignore 2026-09-08 23:02:00 +02:00