diff --git a/CLAUDE.md b/CLAUDE.md index f726ca6..27fb3f7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,6 +42,7 @@ wechat_clicker/ - 滚动使用 **kCGEventMouseMoved + ScrollWheel**(不触发点击),避免误点 UI 元素 - "..."按钮搜索限制在预览区域(独立窗口或主窗口 x>200),排除侧边栏 - 可见性检查基于元素**中心点**是否在消息列表可见区域内(30px margin) +- **QuickTime Player 清理**:直接发送的视频(非文件方式)被点击后通过 QuickTime Player 打开,处理完毕后通过 bundle ID 检测 + activate + Cmd+W 关闭 - 状态检测基于窗口计数 + **AXMinimized 属性**:区分窗口存在但最小化 vs 真正可见 - **窗口恢复策略(4 层)**:NSRunningApplication.unhide(隐藏)→ 检测 0 窗口时 `open -b` 重新打开(窗口被关闭,带 polling 验证)→ AX API 设置 AXMinimized=False(最小化)→ activate(前台) - **UNKNOWN/ABNORMAL 状态恢复**:先关闭所有非主窗口(含空标题遗留预览、小尺寸浮窗),再 Escape + activate + 点击侧边栏 diff --git a/wechat_clicker/automator.py b/wechat_clicker/automator.py index b79e906..67bea17 100644 --- a/wechat_clicker/automator.py +++ b/wechat_clicker/automator.py @@ -733,6 +733,10 @@ class WeChatAutomator: logger.debug(" 关闭 Preview.app") self.state.close_preview_app() + if self.state.is_quicktime_player_running(): + logger.debug(" 关闭 QuickTime Player") + self.state.close_quicktime_player() + conv_wins = self.ui.get_conversation_windows() for win in conv_wins: title = self.ax.get_title(win) diff --git a/wechat_clicker/state_machine.py b/wechat_clicker/state_machine.py index a3e31de..7f80c59 100644 --- a/wechat_clicker/state_machine.py +++ b/wechat_clicker/state_machine.py @@ -302,3 +302,36 @@ class StateMachine: if not apps or len(apps) == 0: return False return not apps[0].isTerminated() + + # ---------------------------------------------------------------- + # QuickTime Player 处理 + # ---------------------------------------------------------------- + + def close_quicktime_player(self) -> bool: + """关闭 QuickTime Player 窗口(直接发送的视频会用它打开)。""" + qt_bundle = "com.apple.QuickTimePlayerX" + apps = NSRunningApplication.runningApplicationsWithBundleIdentifier_(qt_bundle) + if not apps or len(apps) == 0: + return True + + app = apps[0] + if app.isTerminated(): + return True + + logger.debug("检测到 QuickTime Player 正在运行,发送 Cmd+W 关闭窗口") + app.activateWithOptions_(0) + time.sleep(0.5) + self.ax.send_cmd_w() + time.sleep(0.5) + + self.ui.ensure_wechat_frontmost() + time.sleep(0.3) + return True + + def is_quicktime_player_running(self) -> bool: + """检查 QuickTime Player 是否在运行。""" + qt_bundle = "com.apple.QuickTimePlayerX" + apps = NSRunningApplication.runningApplicationsWithBundleIdentifier_(qt_bundle) + if not apps or len(apps) == 0: + return False + return not apps[0].isTerminated()