Skip to content

Commit

Permalink
feat: add support for mouse scroll with modifier keys
Browse files Browse the repository at this point in the history
  • Loading branch information
socsieng committed Jan 1, 2021
1 parent d870e10 commit 27afc5b
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 11 deletions.
4 changes: 3 additions & 1 deletion Sources/SendKeysLib/Commands/CommandExecutor.swift
Expand Up @@ -74,10 +74,12 @@ public class CommandExecutor: CommandExecutorProtocol {
let x = Int(command.arguments[0]!) ?? 0
let y = Int(command.arguments[1]!) ?? 0
let duration = Double(command.arguments[2] ?? "0") ?? 0
let modifiers = command.arguments[3]

mouseController.scroll(
CGPoint(x: x, y: y),
duration
duration,
flags: modifiers != nil ? try! KeyPresser.getModifierFlags(modifiers!.components(separatedBy: ",")) : []
)
}

Expand Down
6 changes: 4 additions & 2 deletions Sources/SendKeysLib/Commands/MouseScrollCommandMatcher.swift
Expand Up @@ -2,18 +2,20 @@ import Foundation

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

override public func createCommand(_ arguments: [String?]) -> Command {
let x = arguments[1]
let y = arguments[2]
let duration = arguments[4]
let modifiers = arguments[6]

return Command(.mouseScroll, [
x,
y,
duration
duration,
modifiers
])
}
}
10 changes: 6 additions & 4 deletions Sources/SendKeysLib/MouseController.swift
Expand Up @@ -85,7 +85,7 @@ class MouseController {
upEvent?.post(tap: CGEventTapLocation.cghidEventTap)
}

func scroll(_ delta: CGPoint, _ duration: TimeInterval) {
func scroll(_ delta: CGPoint, _ duration: TimeInterval, flags: CGEventFlags) {
var scrolledX: Int = 0;
var scrolledY: Int = 0;
let eventSource = CGEventSource(event: nil)
Expand All @@ -95,25 +95,27 @@ class MouseController {
let amount = Int((Double(delta.x) * progress) - Double(scrolledX))
scrolledX += amount

self.scrollBy(amount, .horizontal, eventSource: eventSource)
self.scrollBy(amount, .horizontal, eventSource: eventSource, flags: flags)
}
if delta.y != 0 {
let amount = Int((Double(delta.y) * progress) - Double(scrolledY))
scrolledY += amount

self.scrollBy(amount, .vertical, eventSource: eventSource)
self.scrollBy(amount, .vertical, eventSource: eventSource, flags: flags)
}
})

animator.animate()
}

func scrollBy(_ amount: Int, _ axis: ScrollAxis, eventSource: CGEventSource?) {
func scrollBy(_ amount: Int, _ axis: ScrollAxis, eventSource: CGEventSource?, flags: CGEventFlags) {
if #available(OSX 10.13, *) {
let event = CGEvent(scrollWheelEvent2Source: eventSource, units: .pixel, wheelCount: 1, wheel1: 0, wheel2: 0, wheel3: 0)
let field = axis == .vertical ? CGEventField.scrollWheelEventPointDeltaAxis1 : CGEventField.scrollWheelEventPointDeltaAxis2

event?.setIntegerValueField(field, value: Int64(amount * -1))
event?.flags = flags

event?.post(tap: CGEventTapLocation.cghidEventTap)
} else {
fatalError("Scrolling is only available on 10.13 or later\n")
Expand Down
17 changes: 13 additions & 4 deletions Tests/SendKeysTests/CommandIteratorTests.swift
Expand Up @@ -276,7 +276,7 @@ final class CommandIteratorTests: XCTestCase {
XCTAssertEqual(
commands,
[
Command(CommandType.mouseScroll, ["0", "10", nil])
Command(CommandType.mouseScroll, ["0", "10", nil, nil])
])
}

Expand All @@ -285,7 +285,7 @@ final class CommandIteratorTests: XCTestCase {
XCTAssertEqual(
commands,
[
Command(CommandType.mouseScroll, ["-100", "10", nil])
Command(CommandType.mouseScroll, ["-100", "10", nil, nil])
])
}

Expand All @@ -294,7 +294,16 @@ final class CommandIteratorTests: XCTestCase {
XCTAssertEqual(
commands,
[
Command(CommandType.mouseScroll, ["0", "10", "0.5"])
Command(CommandType.mouseScroll, ["0", "10", "0.5", nil])
])
}

func testParsesMouseScrollWithDurationAndModifiers() throws {
let commands = getCommands(CommandsIterator("<s:0,10:0.5:shift>"))
XCTAssertEqual(
commands,
[
Command(CommandType.mouseScroll, ["0", "10", "0.5", "shift"])
])
}

Expand All @@ -303,7 +312,7 @@ final class CommandIteratorTests: XCTestCase {
XCTAssertEqual(
commands,
[
Command(CommandType.mouseScroll, ["0", "-10", "0.5"])
Command(CommandType.mouseScroll, ["0", "-10", "0.5", nil])
])
}

Expand Down

0 comments on commit 27afc5b

Please sign in to comment.