Module: Mouse

Extended by:
Mouse
Included in:
Mouse
Defined in:
lib/mouse.rb

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.

Reference.

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.

Returns:

  • (Number)
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.

Returns:

  • (Number)
Rational(1, FPS)
UNIT =

Available constants for the type of units to use when scrolling.

Returns:

  • (Hash{Symbol=>Fixnum})
{
  line:  KCGScrollEventUnitLine,
  pixel: KCGScrollEventUnitPixel
}

Instance Method Summary collapse

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.

Parameters:



160
161
162
163
164
165
166
# File 'lib/mouse.rb', line 160

def arbitrary_click point = current_position, button = KCGMouseButtonCenter, duration = 12
  event = new_event KCGEventOtherMouseDown, point, button
  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.

Parameters:



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.

Parameters:



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_positionCGPoint

The coordinates of the mouse using the flipped coordinate system (origin in top left).

Returns:



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.

Parameters:



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.

Parameters:

  • (CGPoint)
  • duration (Float) (defaults to: 0.2)

    animation duration, in seconds



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.

Parameters:

  • (CGPoint)
  • duration (Float) (defaults to: 0.2)

    animation duration, in seconds



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

TODO:

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.

Parameters:

  • amount (Fixnum)

    number of units to scroll; positive to scroll up or negative to scroll down

  • duration (Float) (defaults to: 0.2)

    animation duration, in seconds

  • units (Symbol) (defaults to: :line)

    :line scrolls by line, :pixel scrolls by pixel



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.

Parameters:



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