1 from pynput import mouse
2 import time
3 import threading
4
5 __DEBUG = False
6
7 def log(msg,debug=False):
8 if __DEBUG or debug:
9 print(msg)
10
11 class MouseMonitor():
12 __press_time = 0
13 __press_double_state = False
14 __move = (0,0)
15
16 def __init__(self,on_selected=None):
17 if on_selected:
18 self.on_selected = on_selected
19 else:
20 self.on_selected = self.on_selected
21
22 self.listener = mouse.Listener(on_move=self.on_move,on_click=self.on_click)
23 self.listener.start()
24 self.listener.join()
25
26 def on_selected(msg):
27 print('selected "%s" has been copied.' % (msg,))
28
29 def on_move(self,x,y):
30 if self.__press_time == 0:
31 self.__move = (x,y)
32 # log(self.__press_time,time.time())
33 # log('Pointer moved to {0}'.format((x,y)))
34
35 def on_click(self,x,y,button,pressed):
36 if str(button) == 'Button.left':
37 if pressed:
38 self.on_pressed(x,y)
39 else:
40 self.on_released(x,y)
41
42 def on_pressed(self,x,y):
43 if self.__press_double_state:
44 # double click
45 # self.__press_double_state = False
46 if not self.check_not_time_out(self.__press_time, time.time(),0.4): # miss double click
47 log('double1 click timeout and reset then')
48 self.reset()
49 self.__press_time = time.time()
50 else:
51 # single click
52 self.__press_time = time.time()
53 # self.__press_double_state = False
54
55 def on_released(self,x,y):
56 if self.__press_double_state:
57 # double click
58 if self.check_not_time_out(self.__press_time, time.time(),0.8):
59 log('double click: %s' % (self.get_copy()))
60 self.on_selected(self.get_copy())
61 self.__press_double_state = False
62 else:
63 log('double2 click timeout and reset then')
64 self.reset()
65 else:
66 if self.check_not_time_out(self.__press_time, time.time()):
67 log('double click maybe')
68 self.__press_double_state = True
69 threading.Timer(0.5, self.timeout_handler).start() # wait timeout to reset
70 elif not self.check_not_time_out(self.__press_time, time.time(),1):
71 if self.__move != (0,0):
72 self.on_selected(self.get_copy())
73 log('selected: %s' % (self.get_copy(),))
74 self.reset()
75 else:
76 log('reset state')
77 self.reset()
78
79 def get_copy(self):
80 import win32clipboard as wc
81 import win32con
82
83 def trigger_copy():
84 from pynput.keyboard import Key,Controller
85 key = Controller()
86 with key.pressed(Key.ctrl):
87 key.press('c')
88 key.release('c')
89 time.sleep(0.1) # wait for ctrl+c valid
90
91 trigger_copy()
92 msg = ''
93 try:
94 wc.OpenClipboard()
95 msg = wc.GetClipboardData(win32con.CF_UNICODETEXT)
96 wc.CloseClipboard()
97 except TypeError:
98 log('Clipboard Content is TypeError.')
99 return msg
100
101 def reset(self):
102 self.__press_time = 0
103 self.__press_double_state = False
104 self.__move = (0,0)
105
106 def timeout_handler(self):
107 self.reset()
108 log('timeout reset state')
109
110 def check_not_time_out(self,old,new,delta=0.2):
111 if(new - old > delta): # time delta > 0.2s
112 return False
113 else:
114 return True
115
116
117 def printf(msg):
118 log('copy content:'+msg,True)
119 # log('x = {0} , y = {1}'.format(x,y))
120
121
122 if __name__ == '__main__':
123 mm = MouseMonitor(printf)