Module: Mouse
Overview
This is a first attempt at writing a wrapper around the CoreGraphics event taps API provided by OS X. The module provides a simple Ruby interface to performing mouse interactions such as moving and clicking.
A rewrite is in the works, but in the mean time this code base still works despite its warts.
Constant Summary collapse
- FPS =
Number of animation steps per second.
120
- QUANTUM =
Note:
We keep the number as a rational to try and avoid rounding error introduced by the floats, especially MacRuby floats.
Smallest unit of time allowed for an animation step.
Rational(1, FPS)
- UNIT =
Available constants for the type of units to use when scrolling.
{ line: KCGScrollEventUnitLine, pixel: KCGScrollEventUnitPixel }
Instance Method Summary collapse
-
#arbitrary_click(point = current_position, button = KCGMouseButtonCenter, duration = 12) ⇒ Object
(also: #other_click)
Click with an arbitrary mouse button, using numbers to represent the mouse button.
-
#click_down(point = current_position, duration = 12) ⇒ Object
Perform a down click.
-
#click_up(point = current_position) ⇒ Object
Perform an up click.
-
#current_position ⇒ CGPoint
The coordinates of the mouse using the flipped coordinate system (origin in top left).
-
#double_click(point = current_position) ⇒ Object
A standard double click.
-
#drag_to(point, duration = 0.2) ⇒ Object
Click and drag from the current position to the given point.
-
#move_to(point, duration = 0.2) ⇒ Object
Move the mouse from the current position to the given point.
-
#scroll(amount, duration = 0.2, units = :line) ⇒ Object
Scroll at the current position the given amount of units.
-
#secondary_click(point = current_position, duration = 12) ⇒ Object
(also: #right_click)
Standard secondary click.
Instance Method Details
#arbitrary_click(point = current_position, button = KCGMouseButtonCenter, duration = 12) ⇒ Object Also known as: other_click
Click with an arbitrary mouse button, using numbers to represent the mouse button. At the time of writing, the documented values are:
- KCGMouseButtonLeft = 0
- KCGMouseButtonRight = 1
- KCGMouseButtonCenter = 2
And the rest are not documented! Though they should be easy enough
to figure out. See the CGMouseButton
enum in the reference
documentation for the most up to date list.
160 161 162 163 164 165 166 |
# File 'lib/mouse.rb', line 160 def arbitrary_click point = current_position, = KCGMouseButtonCenter, duration = 12 event = new_event KCGEventOtherMouseDown, point, post event sleep QUANTUM*duration set_type event, KCGEventOtherMouseUp post event end |
#click_down(point = current_position, duration = 12) ⇒ Object
Perform a down click. You should follow this up with a call to #click_up to finish the click.
100 101 102 103 104 |
# File 'lib/mouse.rb', line 100 def click_down point = current_position, duration = 12 event = new_event KCGEventLeftMouseDown, point, KCGMouseButtonLeft post event sleep QUANTUM*duration end |
#click_up(point = current_position) ⇒ Object
Perform an up click. This should only be called after a call to #click_down to finish the click event.
111 112 113 114 |
# File 'lib/mouse.rb', line 111 def click_up point = current_position event = new_event KCGEventLeftMouseUp, point, KCGMouseButtonLeft post event end |
#current_position ⇒ CGPoint
The coordinates of the mouse using the flipped coordinate system (origin in top left).
44 45 46 |
# File 'lib/mouse.rb', line 44 def current_position CGEventGetLocation(CGEventCreate(nil)) end |
#double_click(point = current_position) ⇒ Object
A standard double click. Defaults to clicking at the current position.
133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/mouse.rb', line 133 def double_click point = current_position event = new_event KCGEventLeftMouseDown, point, KCGMouseButtonLeft post event set_type event, KCGEventLeftMouseUp post event CGEventSetIntegerValueField(event, KCGMouseEventClickState, 2) set_type event, KCGEventLeftMouseDown post event set_type event, KCGEventLeftMouseUp post event end |
#drag_to(point, duration = 0.2) ⇒ Object
Click and drag from the current position to the given point.
62 63 64 65 66 67 68 |
# File 'lib/mouse.rb', line 62 def drag_to point, duration = 0.2 post new_event(KCGEventLeftMouseDown, current_position, KCGMouseButtonLeft) animate KCGEventLeftMouseDragged, KCGMouseButtonLeft, current_position, point, duration post new_event(KCGEventLeftMouseUp, current_position, KCGMouseButtonLeft) end |
#move_to(point, duration = 0.2) ⇒ Object
Move the mouse from the current position to the given point.
53 54 55 |
# File 'lib/mouse.rb', line 53 def move_to point, duration = 0.2 animate KCGEventMouseMoved, KCGMouseButtonLeft, current_position, point, duration end |
#scroll(amount, duration = 0.2, units = :line) ⇒ Object
Need to double check to see if I introduce any inaccuracies.
Scroll at the current position the given amount of units.
Scrolling too much or too little in a period of time will cause the animation to look weird, possibly causing the app to mess things up.
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/mouse.rb', line 82 def scroll amount, duration = 0.2, units = :line units = UNIT[units] || raise(ArgumentError, "#{units} is not a valid unit") steps = (FPS * duration).round current = 0.0 steps.times do |step| done = (step+1).to_f / steps scroll = ((done - current)*amount).floor post new_scroll_event(units, 1, scroll) sleep QUANTUM current += scroll.to_f / amount end end |
#secondary_click(point = current_position, duration = 12) ⇒ Object Also known as: right_click
Standard secondary click. Default position is the current position.
120 121 122 123 124 125 126 |
# File 'lib/mouse.rb', line 120 def secondary_click point = current_position, duration = 12 event = new_event KCGEventRightMouseDown, point, KCGMouseButtonRight post event sleep QUANTUM*duration set_type event, KCGEventRightMouseUp post event end |