54 lines
2.5 KiB
Python
54 lines
2.5 KiB
Python
# gui/selection_monitor.py
|
|
from pynput import mouse
|
|
import pyperclip
|
|
import time
|
|
import win32gui
|
|
from pywinauto.keyboard import send_keys
|
|
|
|
class SelectionMonitor:
|
|
def __init__(self, browser_hwnd, callback, drag_threshold=10):
|
|
"""
|
|
:param browser_hwnd: 임베딩된 브라우저 창의 핸들 (정수)
|
|
:param callback: 드래그 이벤트 후 클립보드에 복사된 텍스트가 있으면 호출할 함수 (인자로 텍스트 전달)
|
|
:param drag_threshold: 드래그로 인식하기 위한 최소 이동 거리(픽셀). 기본값 10픽셀.
|
|
"""
|
|
self.browser_hwnd = browser_hwnd
|
|
self.callback = callback
|
|
self.drag_threshold = drag_threshold
|
|
self.press_pos = None
|
|
self.listener = mouse.Listener(on_click=self.on_click, on_move=self.on_move)
|
|
self.listener.start()
|
|
|
|
def on_click(self, x, y, button, pressed):
|
|
# 왼쪽 버튼에 대해서만 처리
|
|
if button == mouse.Button.left:
|
|
if pressed:
|
|
# 마우스 버튼이 눌렸을 때: 브라우저 영역 안에서 눌렸다면 좌표 저장
|
|
rect = win32gui.GetWindowRect(self.browser_hwnd)
|
|
if rect[0] <= x <= rect[2] and rect[1] <= y <= rect[3]:
|
|
self.press_pos = (x, y)
|
|
else:
|
|
# 마우스 버튼 릴리즈 시: 만약 이전에 누른 좌표가 있다면 드래그 여부 판별
|
|
if self.press_pos:
|
|
release_pos = (x, y)
|
|
dx = release_pos[0] - self.press_pos[0]
|
|
dy = release_pos[1] - self.press_pos[1]
|
|
distance_sq = dx * dx + dy * dy
|
|
if distance_sq >= self.drag_threshold * self.drag_threshold:
|
|
# 일정 픽셀 이상 이동했으므로 드래그로 간주함.
|
|
# 브라우저 창에 "Ctrl+C"를 시뮬레이션하여 현재 선택된 텍스트를 클립보드에 복사.
|
|
send_keys('^c')
|
|
time.sleep(0.3) # 클립보드 업데이트를 위해 잠시 대기
|
|
text = pyperclip.paste()
|
|
if text:
|
|
self.callback(text)
|
|
self.press_pos = None
|
|
return True
|
|
|
|
def on_move(self, x, y):
|
|
# 별도로 이동 이벤트를 처리할 필요는 없으므로 그냥 True 반환
|
|
return True
|
|
|
|
def stop(self):
|
|
self.listener.stop()
|