Skip to content

Commit b9d8e37

Browse files
committed
Add support for stopping and starting the mach port event controller
1 parent b142807 commit b9d8e37

1 file changed

Lines changed: 30 additions & 13 deletions

File tree

Sources/MachPort/MachPortEventController.swift

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ public class MachPortEventPublisher {
1313
public final class MachPortEventController: MachPortEventPublisher {
1414
private(set) public var eventSource: CGEventSource!
1515

16-
private var machPort: CFMachPort!
17-
private var runLoopSource: CFRunLoopSource!
16+
private var machPort: CFMachPort?
17+
private var runLoopSource: CFRunLoopSource?
1818
private var lhs: Bool = true
1919

20+
private let eventSourceId: CGEventSourceStateID
2021
private let signature: Int64
2122
private let configuration: MachPortTapConfiguration
2223

@@ -27,30 +28,46 @@ public final class MachPortEventController: MachPortEventPublisher {
2728

2829
required public init(_ eventSourceId: CGEventSourceStateID,
2930
signature: String,
30-
mode: CFRunLoopMode,
31-
configuration: MachPortTapConfiguration = .init()) throws {
31+
configuration: MachPortTapConfiguration = .init(),
32+
autoStartMode: CFRunLoopMode? = .commonModes) throws {
33+
self.eventSourceId = eventSourceId
3234
self.signature = Int64(signature.hashValue)
3335
self.configuration = configuration
34-
3536
try super.init()
37+
if let autoStartMode { try start(mode: autoStartMode) }
38+
}
3639

37-
let machPort = try createMachPort()
3840

41+
required init() throws {
42+
fatalError("init() has not been implemented")
43+
}
44+
45+
// MARK: Public methods
46+
47+
public func start(in runLoop: CFRunLoop = CFRunLoopGetMain(),
48+
mode: CFRunLoopMode) throws {
49+
let machPort = try createMachPort()
3950
self.eventSource = try CGEventSource.create(eventSourceId)
4051
self.machPort = machPort
4152
self.runLoopSource = try CFRunLoopSource.create(with: machPort)
42-
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, mode)
53+
54+
CFRunLoopAddSource(runLoop, runLoopSource, mode)
4355
}
4456

45-
required init() throws {
46-
fatalError("init() has not been implemented")
57+
public func stop(in runLoop: CFRunLoop = CFRunLoopGetMain(), mode: CFRunLoopMode) {
58+
CFRunLoopRemoveSource(runLoop, runLoopSource, mode)
59+
guard let machPort else { return }
60+
CFMachPortInvalidate(machPort)
61+
self.runLoopSource = nil
4762
}
4863

49-
// MARK: Public methods
64+
public func reload(in runLoop: CFRunLoop = CFRunLoopGetMain(),
65+
mode: CFRunLoopMode) throws {
66+
try stop(mode: mode)
67+
try start(mode: mode)
68+
}
5069

51-
public func post(_ key: Int,
52-
type: CGEventType,
53-
flags: CGEventFlags,
70+
public func post(_ key: Int, type: CGEventType, flags: CGEventFlags,
5471
tapLocation: CGEventTapLocation = .cghidEventTap,
5572
configure: (CGEvent) -> Void = { _ in }) throws {
5673
guard let cgKeyCode = CGKeyCode(exactly: key) else {

0 commit comments

Comments
 (0)