Skip to content

Commit

Permalink
Fix errors with the pynput mouse implementation used on macOS
Browse files Browse the repository at this point in the history
Re: #368.

The Mouse action class can now be used to double/triple click, and
scroll the mouse wheel, on macOS.
  • Loading branch information
drmfinlay committed Sep 12, 2022
1 parent 4a914d4 commit 8150445
Showing 1 changed file with 49 additions and 16 deletions.
65 changes: 49 additions & 16 deletions dragonfly/actions/mouse/_pynput.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ def get_button(name):
}

PLATFORM_WHEEL_FLAGS = {
# ((button, event_type), scroll_count)
"wheelup": ((get_button("scroll_up"), 1), 3),
"stepup": ((get_button("scroll_up"), 1), 1),
"wheeldown": ((get_button("scroll_down"), 1), 3),
"stepdown": ((get_button("scroll_down"), 1), 1),
"wheelright": ((get_button("scroll_right"), 1), 3),
"stepright": ((get_button("scroll_right"), 1), 1),
"wheelleft": ((get_button("scroll_left"), 1), 3),
"stepleft": ((get_button("scroll_left"), 1), 1),
# button -> ((button, event_type), step_count)
"wheelup": (("stepup", 1), 3),
"stepup": (("stepup", 1), 1),
"wheeldown": (("stepdown", 1), -3),
"stepdown": (("stepdown", 1), -1),
"wheelright": (("stepright", 1), 3),
"stepright": (("stepright", 1), 1),
"wheelleft": (("stepleft", 1), -3),
"stepleft": (("stepleft", 1), -1),
}


Expand All @@ -118,17 +118,50 @@ def execute(self, window):
# Initialize the pynput mouse controller, if necessary.
_init_controller()

# Process button events.
for ((button, event_type), flag) in self._flags:
# Check if the button is unknown.
# Pre-process event flags.
# - Raise an error if an unsupported event is found.
# - Combine down/up events so that the `click' function may be used
# where appropriate.
events = []
last_event = None
for event in self._flags:
((button, event_type), flag) = event
if button is None:
event_type_s = "button" if event_type == 0 else "scroll"
raise ValueError("Unsupported %s event" % event_type_s)
message = "Unsupported mouse %s event"
if event_type == 0: message = message % "scroll"
else: message = message % "button"
raise ValueError(message)

if last_event is None:
last_event = event
continue

# Is this event compatible with the last one?
# Note: Button events are joined like this because the *pynput*
# `click' controller method must be used for double/triple
# clicking on macOS.
((last_button, last_event_type), last_flag) = last_event
if (last_event_type == event_type == 0 and last_flag and
not flag and last_button == button):
last_event = None
event = ((button, 0), last_flag + 1)
events.append(event)
else:
events.append(last_event)
events.append(event)

# Process button events.
for event in self._flags:
((button, event_type), flag) = event
if event_type == 0: # Button press event
if flag:
if flag == 1:
_controller.press(button)
elif flag > 1:
_controller.click(button, flag)
else:
_controller.release(button)
elif event_type == 1: # Scroll event
_controller.click(button, flag)
if button == "stepup" or button == "stepdown":
_controller.scroll(0, flag)
else:
_controller.scroll(flag, 0)

0 comments on commit 8150445

Please sign in to comment.