From 4e57a9c596a0b5b49431d96f00e70fb5c229bb67 Mon Sep 17 00:00:00 2001 From: max Date: Tue, 8 Sep 2026 23:17:18 +0200 Subject: [PATCH] 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. --- catser/cat_controller.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/catser/cat_controller.py b/catser/cat_controller.py index ae496a2..742d455 100644 --- a/catser/cat_controller.py +++ b/catser/cat_controller.py @@ -83,13 +83,21 @@ class CatController: self.config = config self.assets = assets - # Screen boundaries + # Primary monitor work area (excludes taskbar) – used for walk/roam floor clamping work_area = WindowManager.get_work_area() - self.screen_left = work_area[0] - self.screen_top = work_area[1] - self.screen_right = work_area[2] + self.screen_left = work_area[0] + self.screen_top = work_area[1] + self.screen_right = work_area[2] self.screen_bottom = work_area[3] + # Full virtual desktop spanning ALL monitors – used for drag clamping so + # the user can pick up the cat and carry it to a second monitor. + vd = WindowManager.get_virtual_desktop_bounds() + self.vd_left = vd[0] + self.vd_top = vd[1] + self.vd_right = vd[2] + self.vd_bottom = vd[3] + # Floor position: Cat walks on top of the taskbar / bottom of work area self.floor_y = float(self.screen_bottom - self.config.cat_height) @@ -246,9 +254,10 @@ class CatController: if self.state == CatState.DRAG: new_x = self.drag_start_pos[0] + dx new_y = self.drag_start_pos[1] + dy - # Keep on screen - self.x = max(float(self.screen_left), min(float(self.screen_right - self.config.cat_width), new_x)) - self.y = max(float(self.screen_top), min(float(self.screen_bottom - self.config.cat_height), new_y)) + # Clamp to FULL virtual desktop so the cat can be dragged to any monitor. + # self.vd_* covers the combined bounds of all connected displays. + self.x = max(float(self.vd_left), min(float(self.vd_right - self.config.cat_width), new_x)) + self.y = max(float(self.vd_top), min(float(self.vd_bottom - self.config.cat_height), new_y)) self.lift = max(0.0, self.floor_y - self.y) def on_mouse_up(self, cursor_x: int, cursor_y: int) -> None: