Skip to content

Commit 948df57

Browse files
fix: Use MTDeviceCreateList to register callbacks on all multitouch devices
MTDeviceCreateDefault() may not return the correct device on some Macs, particularly with macOS 26.1 beta. Using MTDeviceCreateList() to enumerate all available multitouch devices and registering callbacks on each one ensures touch events are properly received.
1 parent 4c972b3 commit 948df57

2 files changed

Lines changed: 64 additions & 7 deletions

File tree

MiddleDrag/Core/MultitouchFramework.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ typealias MTContactCallbackFunction = @convention(c) (
2929
@_silgen_name("MTDeviceCreateDefault")
3030
func MTDeviceCreateDefault() -> MTDeviceRef?
3131

32+
/// Get list of all multitouch devices
33+
@_silgen_name("MTDeviceCreateList")
34+
func MTDeviceCreateList() -> CFArray?
35+
3236
// MARK: - Device Control
3337

3438
/// Start the multitouch device

MiddleDrag/Managers/DeviceMonitor.swift

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
import Foundation
22
import CoreFoundation
33

4+
// MARK: - Debug Logging
5+
6+
private let debugLogPath = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent("middledrag_touch.log")
7+
private var touchCount = 0
8+
9+
private func logToFile(_ message: String) {
10+
let timestamp = ISO8601DateFormatter().string(from: Date())
11+
let line = "[\(timestamp)] \(message)\n"
12+
if let data = line.data(using: .utf8) {
13+
if FileManager.default.fileExists(atPath: debugLogPath.path) {
14+
if let handle = try? FileHandle(forWritingTo: debugLogPath) {
15+
handle.seekToEndOfFile()
16+
handle.write(data)
17+
handle.closeFile()
18+
}
19+
} else {
20+
try? data.write(to: debugLogPath)
21+
}
22+
}
23+
}
24+
425
// MARK: - Global Callback Storage
526

627
// Required because C callbacks cannot capture Swift context
@@ -9,6 +30,11 @@ private var gDeviceMonitor: DeviceMonitor?
930
// MARK: - C Callback Function
1031

1132
private let deviceContactCallback: MTContactCallbackFunction = { device, touches, numTouches, timestamp, frame in
33+
touchCount += 1
34+
if touchCount <= 5 || touchCount % 100 == 0 {
35+
logToFile("Touch callback #\(touchCount): \(numTouches) touches")
36+
}
37+
1238
guard let monitor = gDeviceMonitor,
1339
let touches = touches else { return 0 }
1440

@@ -53,17 +79,44 @@ class DeviceMonitor {
5379
func start() {
5480
guard !isRunning else { return }
5581

56-
guard let defaultDevice = MultitouchFramework.shared.getDefaultDevice() else {
57-
print("⚠️ No multitouch device found")
58-
return
59-
}
82+
logToFile("DeviceMonitor.start() called")
6083

61-
device = defaultDevice
84+
// Try to get all devices
85+
if let deviceList = MTDeviceCreateList() {
86+
let count = CFArrayGetCount(deviceList)
87+
logToFile("Found \(count) multitouch device(s)")
88+
89+
for i in 0..<count {
90+
let devicePtr = CFArrayGetValueAtIndex(deviceList, i)
91+
if let dev = devicePtr {
92+
let deviceRef = UnsafeMutableRawPointer(mutating: dev)
93+
logToFile("Registering callback for device \(i): \(deviceRef)")
94+
MTRegisterContactFrameCallback(deviceRef, deviceContactCallback)
95+
MTDeviceStart(deviceRef, 0)
96+
97+
if device == nil {
98+
device = deviceRef
99+
}
100+
}
101+
}
102+
} else {
103+
logToFile("MTDeviceCreateList returned nil, trying default")
104+
}
62105

63-
MTRegisterContactFrameCallback(defaultDevice, deviceContactCallback)
64-
MTDeviceStart(defaultDevice, 0)
106+
// Also try the default device
107+
if let defaultDevice = MultitouchFramework.shared.getDefaultDevice() {
108+
logToFile("Also registering default device: \(defaultDevice)")
109+
MTRegisterContactFrameCallback(defaultDevice, deviceContactCallback)
110+
MTDeviceStart(defaultDevice, 0)
111+
112+
if device == nil {
113+
device = defaultDevice
114+
}
115+
}
65116

117+
logToFile("Device registration complete")
66118
isRunning = true
119+
logToFile("DeviceMonitor started successfully")
67120
}
68121

69122
/// Stop monitoring

0 commit comments

Comments
 (0)