Skip to content

Commit

Permalink
feat: add support for mouse move with modifier keys
Browse files Browse the repository at this point in the history
  • Loading branch information
socsieng committed Jan 1, 2021
1 parent 1654fd7 commit 7f4c891
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 15 deletions.
8 changes: 5 additions & 3 deletions Sources/SendKeysLib/Commands/CommandExecutor.swift
Expand Up @@ -47,23 +47,25 @@ public class CommandExecutor: CommandExecutorProtocol {
let x2 = Double(command.arguments[2]!)!
let y2 = Double(command.arguments[3]!)!
let duration: TimeInterval = Double(command.arguments[4]!)!
let modifiers = command.arguments[5]

mouseController.move(
start: CGPoint(x: x1, y: y1),
end: CGPoint(x: x2, y: y2),
duration: duration
duration: duration,
flags: modifiers != nil ? try! KeyPresser.getModifierFlags(modifiers!.components(separatedBy: ",")) : []
)
}

private func executeMouseClick(_ command: Command) {
let button = command.arguments[0]!
let modifiers = command.arguments[1] ?? ""
let modifiers = command.arguments[1]
let clicks = Int(command.arguments[2]!)!

try! mouseController.click(
CGPoint(x: -1, y: -1),
button: getMouseButton(button: button),
flags: KeyPresser.getModifierFlags(modifiers.components(separatedBy: ",")),
flags: modifiers != nil ? try! KeyPresser.getModifierFlags(modifiers!.components(separatedBy: ",")) : [],
clickCount: clicks
)
}
Expand Down
8 changes: 5 additions & 3 deletions Sources/SendKeysLib/Commands/MouseMoveCommandMatcher.swift
Expand Up @@ -2,7 +2,7 @@ import Foundation

public class MouseMoveCommandMatcher: CommandMatcher {
public init() {
super.init(try! NSRegularExpression(pattern: "\\<m:((\\d+),(\\d+),)?(\\d+),(\\d+)(:([\\d.]+))?\\>"))
super.init(try! NSRegularExpression(pattern: "\\<m:((\\d+),(\\d+),)?(\\d+),(\\d+)(:([\\d.]+))?(:([a-z,]+))?\\>"))
}

override public func createCommand(_ arguments: [String?]) -> Command {
Expand All @@ -11,13 +11,15 @@ public class MouseMoveCommandMatcher: CommandMatcher {
let x2 = arguments[4]
let y2 = arguments[5]
let duration = arguments[7]

let modifiers = arguments[9]

return Command(.mouseMove, [
x1 ?? "-1",
y1 ?? "-1",
x2!,
y2!,
duration ?? "0"
duration ?? "0",
modifiers
])
}
}
7 changes: 4 additions & 3 deletions Sources/SendKeysLib/MouseController.swift
Expand Up @@ -8,15 +8,15 @@ class MouseController {

let animationRefreshInterval: TimeInterval = 0.01

func move(start: CGPoint, end: CGPoint, duration: TimeInterval) {
func move(start: CGPoint, end: CGPoint, duration: TimeInterval, flags: CGEventFlags) {
let resolvedStart = resolveLocation(start)

let animator = Animator(duration, animationRefreshInterval, { progress in
let location = CGPoint(
x: (Double(end.x - resolvedStart.x) * progress) + Double(resolvedStart.x),
y: (Double(end.y - resolvedStart.y) * progress) + Double(resolvedStart.y)
)
self.setLocation(location)
self.setLocation(location, flags: flags)
})

animator.animate()
Expand Down Expand Up @@ -107,8 +107,9 @@ class MouseController {
return event?.location
}

private func setLocation(_ location: CGPoint, moveType: CGEventType = CGEventType.mouseMoved, button: CGMouseButton = CGMouseButton.left) {
private func setLocation(_ location: CGPoint, moveType: CGEventType = CGEventType.mouseMoved, button: CGMouseButton = CGMouseButton.left, flags: CGEventFlags = []) {
let moveEvent = CGEvent(mouseEventSource: nil, mouseType: moveType, mouseCursorPosition: location, mouseButton: button)
moveEvent?.flags = flags
moveEvent?.post(tap: CGEventTapLocation.cghidEventTap)
}

Expand Down
26 changes: 22 additions & 4 deletions Tests/SendKeysTests/CommandIteratorTests.swift
Expand Up @@ -105,7 +105,16 @@ final class CommandIteratorTests: XCTestCase {
XCTAssertEqual(
commands,
[
Command(CommandType.mouseMove, ["1", "2", "3", "4", "0"])
Command(CommandType.mouseMove, ["1", "2", "3", "4", "0", nil])
])
}

func testParsesMouseMoveWithModifier() throws {
let commands = getCommands(CommandsIterator("<m:1,2,3,4:command>"))
XCTAssertEqual(
commands,
[
Command(CommandType.mouseMove, ["1", "2", "3", "4", "0", "command"])
])
}

Expand All @@ -114,7 +123,16 @@ final class CommandIteratorTests: XCTestCase {
XCTAssertEqual(
commands,
[
Command(CommandType.mouseMove, ["1", "2", "3", "4", "0.1"])
Command(CommandType.mouseMove, ["1", "2", "3", "4", "0.1", nil])
])
}

func testParsesMouseMoveWithDurationAndModifiers() throws {
let commands = getCommands(CommandsIterator("<m:1,2,3,4:0.1:shift,command>"))
XCTAssertEqual(
commands,
[
Command(CommandType.mouseMove, ["1", "2", "3", "4", "0.1", "shift,command"])
])
}

Expand All @@ -123,7 +141,7 @@ final class CommandIteratorTests: XCTestCase {
XCTAssertEqual(
commands,
[
Command(CommandType.mouseMove, ["-1", "-1", "3", "4", "0"])
Command(CommandType.mouseMove, ["-1", "-1", "3", "4", "0", nil])
])
}

Expand All @@ -132,7 +150,7 @@ final class CommandIteratorTests: XCTestCase {
XCTAssertEqual(
commands,
[
Command(CommandType.mouseMove, ["-1", "-1", "3", "4", "2"])
Command(CommandType.mouseMove, ["-1", "-1", "3", "4", "2", nil])
])
}

Expand Down
4 changes: 2 additions & 2 deletions Tests/SendKeysTests/CommandsProcessorTests.swift
Expand Up @@ -126,9 +126,9 @@ final class CommandProcessorTests: XCTestCase {
let commands = commandExecutor!.commands

XCTAssertEqual(commands, [
Command(.mouseMove, ["-1", "-1", "20", "20", "1"]),
Command(.mouseMove, ["-1", "-1", "20", "20", "1", nil]),
Command(.pause, ["0.1"]),
Command(.mouseMove, ["-1", "-1", "200", "200", "1"]),
Command(.mouseMove, ["-1", "-1", "200", "200", "1", nil]),
Command(.pause, ["0.1"]),
Command(.mouseClick, ["left", nil, "1"]),
])
Expand Down

0 comments on commit 7f4c891

Please sign in to comment.