Skip to content
This repository was archived by the owner on Feb 13, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions mouse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,18 @@ def drag(start_x, start_y, end_x, end_y, absolute=True, duration=0):
move(end_x, end_y, absolute, duration)
release()

def on_button(callback, args=(), buttons=(LEFT, MIDDLE, RIGHT, X, X2), types=(UP, DOWN, DOUBLE)):
def on_button(callback, args=(), buttons=(LEFT, MIDDLE, RIGHT, X, X2), types=(UP, DOWN, DOUBLE), injected=(True, False)):
""" Invokes `callback` with `args` when the specified event happens. """
if not isinstance(buttons, (tuple, list)):
buttons = (buttons,)
if not isinstance(types, (tuple, list)):
types = (types,)
if not isinstance(injected, (tuple, list)):
injected = (injected,)

def handler(event):
if isinstance(event, ButtonEvent):
if event.event_type in types and event.button in buttons:
if event.event_type in types and event.button in buttons and event.injected in injected:
callback(*args)
_listener.add_handler(handler)
return handler
Expand Down
2 changes: 1 addition & 1 deletion mouse/_mouse_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
HORIZONTAL = 'horizontal'


ButtonEvent = namedtuple('ButtonEvent', ['event_type', 'button', 'time'])
ButtonEvent = namedtuple('ButtonEvent', ['event_type', 'button', 'time', 'injected'])
WheelEvent = namedtuple('WheelEvent', ['delta', 'time'])
MoveEvent = namedtuple('MoveEvent', ['x', 'y', 'time'])
10 changes: 5 additions & 5 deletions mouse/_winmouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ class MSLLHOOKSTRUCT(Structure):
_fields_ = [("x", c_long),
("y", c_long),
('data', c_int32),
('reserved', c_int32),
("flags", DWORD),
("flags", c_uint32),
("time", c_int),
]

Expand Down Expand Up @@ -139,7 +138,8 @@ def low_level_mouse_handler(nCode, wParam, lParam):
struct = lParam.contents
# Can't use struct.time because it's usually zero.
t = time.time()

injected = struct.flags > 0

if wParam == WM_MOUSEMOVE:
event = MoveEvent(struct.x, struct.y, t)
elif wParam == WM_MOUSEWHEEL:
Expand All @@ -148,12 +148,12 @@ def low_level_mouse_handler(nCode, wParam, lParam):
type, button = buttons_by_wm_code.get(wParam, ('?', '?'))
if wParam >= WM_XBUTTONDOWN:
button = {0x10000: X, 0x20000: X2}[struct.data]
event = ButtonEvent(type, button, t)
event = ButtonEvent(type, button, t, injected)

if (event.event_type == DOWN) and previous_button_event is not None:
# https://msdn.microsoft.com/en-us/library/windows/desktop/gg153548%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
if event.time - previous_button_event.time <= GetDoubleClickTime() / 1000.0:
event = ButtonEvent(DOUBLE, event.button, event.time)
event = ButtonEvent(DOUBLE, event.button, event.time, injected)

previous_button_event = event
else:
Expand Down