Files
auto_GUI/wechat_auto/core/window_manager.py
2026-03-04 17:22:39 +08:00

131 lines
4.2 KiB
Python

import subprocess
import time
from dataclasses import dataclass
from typing import Optional, Tuple
from wechat_auto.utils.logger import logger
from wechat_auto.config import settings
@dataclass
class WindowPosition:
x: int
y: int
width: int
height: int
@property
def center(self) -> Tuple[int, int]:
return (self.x + self.width // 2, self.y + self.height // 2)
def relative_to(self, rel_x: int, rel_y: int) -> Tuple[int, int]:
return (self.x + rel_x, self.y + rel_y)
class WindowManager:
def __init__(self, window_name: str = None):
self.window_name = window_name or settings.wechat_window_name
def find_window(self, timeout: float = 10.0) -> Optional[str]:
start_time = time.time()
search_methods = [
['xdotool', 'search', '--name', self.window_name],
['xdotool', 'search', '--class', 'wechat'],
['xdotool', 'search', '--classname', 'wechat'],
]
while time.time() - start_time < timeout:
for cmd in search_methods:
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=5
)
window_id = result.stdout.strip().split('\n')[0]
if window_id:
logger.info(f"找到窗口: {self.window_name}, ID: {window_id}")
return window_id
except Exception as e:
logger.debug(f"搜索方式 {cmd} 失败: {e}")
time.sleep(0.5)
logger.error(f"未找到窗口: {self.window_name}")
return None
def get_window_position(self, window_id: str = None) -> Optional[WindowPosition]:
if not window_id:
window_id = self.find_window()
if not window_id:
return None
try:
result = subprocess.run(
['xdotool', 'getwindowgeometry', window_id],
capture_output=True,
text=True,
timeout=5
)
output = result.stdout
x = y = width = height = 0
for line in output.split('\n'):
line = line.strip()
if line.startswith('Position:'):
parts = line.split(':')[1].strip().split(',')
x = int(parts[0])
y = int(parts[1])
elif line.startswith('Geometry:'):
parts = line.split(':')[1].strip().split('x')
width = int(parts[0])
height = int(parts[1])
if x or y or width or height:
pos = WindowPosition(x=x, y=y, width=width, height=height)
logger.info(f"窗口位置: {pos}")
return pos
except Exception as e:
logger.error(f"获取窗口位置失败: {e}")
return None
def activate_window(self, window_id: str = None) -> bool:
if not window_id:
window_id = self.find_window()
if not window_id:
return False
try:
subprocess.run(
['xdotool', 'windowactivate', window_id],
capture_output=True,
timeout=5
)
time.sleep(0.5)
logger.info(f"窗口已激活: {window_id}")
return True
except Exception as e:
logger.error(f"激活窗口失败: {e}")
return False
def is_window_visible(self, window_id: str = None) -> bool:
if not window_id:
window_id = self.find_window()
if not window_id:
return False
try:
result = subprocess.run(
['xdotool', 'getwindowname', window_id],
capture_output=True,
text=True,
timeout=5
)
return bool(result.stdout.strip())
except Exception:
return False