@lattices/cli 0.4.12 → 0.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/mac/Lattices.app/Contents/Info.plist +4 -4
- package/apps/mac/Lattices.app/Contents/MacOS/Lattices +0 -0
- package/apps/mac/Sources/Core/Input/KeyboardRemapController.swift +17 -6
- package/apps/mac/Sources/Core/Overlays/ScreenOverlayCanvasController.swift +9 -56
- package/docs/reference/dewey.config.ts +1 -1
- package/package.json +1 -1
|
@@ -26,17 +26,17 @@
|
|
|
26
26
|
</dict>
|
|
27
27
|
</array>
|
|
28
28
|
<key>CFBundleVersion</key>
|
|
29
|
-
<string>0.4.
|
|
29
|
+
<string>0.4.13</string>
|
|
30
30
|
<key>CFBundleShortVersionString</key>
|
|
31
|
-
<string>0.4.
|
|
31
|
+
<string>0.4.13</string>
|
|
32
32
|
<key>LatticesBuildChannel</key>
|
|
33
33
|
<string>dev</string>
|
|
34
34
|
<key>LatticesBuildTrack</key>
|
|
35
35
|
<string>latest</string>
|
|
36
36
|
<key>LatticesBuildRevision</key>
|
|
37
|
-
<string>
|
|
37
|
+
<string>42928c7</string>
|
|
38
38
|
<key>LatticesBuildTimestamp</key>
|
|
39
|
-
<string>2026-05-
|
|
39
|
+
<string>2026-05-04T17:39:23Z</string>
|
|
40
40
|
<key>LSMinimumSystemVersion</key>
|
|
41
41
|
<string>13.0</string>
|
|
42
42
|
<key>LSUIElement</key>
|
|
Binary file
|
|
@@ -21,11 +21,12 @@ final class KeyboardRemapController: ObservableObject {
|
|
|
21
21
|
private var capsLayerLastEventAt: CFAbsoluteTime?
|
|
22
22
|
private var bypassUntil: CFAbsoluteTime = 0
|
|
23
23
|
private var lastCapsLayerStaleLogAt: CFAbsoluteTime = 0
|
|
24
|
-
private var pressedKeyCodes =
|
|
24
|
+
private var pressedKeyCodes: [Int64: CFAbsoluteTime] = [:]
|
|
25
25
|
private let breaker = EventTapBreaker(label: "KeyboardRemap")
|
|
26
26
|
private let budgetMeter = TapBudgetMeter(label: "KeyboardRemap")
|
|
27
27
|
private let maxCapsLayerIdleDuration: TimeInterval = 2.0
|
|
28
28
|
private let maxCapsLayerHeldDuration: TimeInterval = 20.0
|
|
29
|
+
private let maxTrackedKeyDownDuration: TimeInterval = 120.0
|
|
29
30
|
private let emergencyBypassDuration: TimeInterval = 3.0
|
|
30
31
|
|
|
31
32
|
private init() {
|
|
@@ -182,7 +183,8 @@ final class KeyboardRemapController: ObservableObject {
|
|
|
182
183
|
return Unmanaged.passUnretained(event)
|
|
183
184
|
}
|
|
184
185
|
|
|
185
|
-
|
|
186
|
+
expireStalePressedKeys(now: started)
|
|
187
|
+
updatePressedKeys(type: type, keyCode: event.getIntegerValueField(.keyboardEventKeycode), now: started)
|
|
186
188
|
if shouldTriggerEmergencyReset(type: type, event: event) {
|
|
187
189
|
emergencyClear(now: started)
|
|
188
190
|
InputCaptureResetCenter.reset(reason: "keyboard emergency chord")
|
|
@@ -295,23 +297,32 @@ final class KeyboardRemapController: ObservableObject {
|
|
|
295
297
|
DiagnosticLog.shared.warn("KeyboardRemap: emergency bypass via Escape")
|
|
296
298
|
}
|
|
297
299
|
|
|
298
|
-
private func updatePressedKeys(type: CGEventType, keyCode: Int64) {
|
|
300
|
+
private func updatePressedKeys(type: CGEventType, keyCode: Int64, now: CFAbsoluteTime) {
|
|
299
301
|
switch type {
|
|
300
302
|
case .keyDown:
|
|
301
|
-
pressedKeyCodes
|
|
303
|
+
pressedKeyCodes[keyCode] = now
|
|
302
304
|
case .keyUp:
|
|
303
|
-
pressedKeyCodes.
|
|
305
|
+
pressedKeyCodes.removeValue(forKey: keyCode)
|
|
304
306
|
default:
|
|
305
307
|
break
|
|
306
308
|
}
|
|
307
309
|
}
|
|
308
310
|
|
|
311
|
+
private func expireStalePressedKeys(now: CFAbsoluteTime) {
|
|
312
|
+
let staleKeys = pressedKeyCodes.filter { now - $0.value > maxTrackedKeyDownDuration }.map(\.key)
|
|
313
|
+
guard !staleKeys.isEmpty else { return }
|
|
314
|
+
for keyCode in staleKeys {
|
|
315
|
+
pressedKeyCodes.removeValue(forKey: keyCode)
|
|
316
|
+
}
|
|
317
|
+
DiagnosticLog.shared.warn("KeyboardRemap: cleared stale key-down state for \(staleKeys.count) key(s)")
|
|
318
|
+
}
|
|
319
|
+
|
|
309
320
|
private func shouldTriggerEmergencyReset(type: CGEventType, event: CGEvent) -> Bool {
|
|
310
321
|
guard type == .keyDown else { return false }
|
|
311
322
|
let keyCode = event.getIntegerValueField(.keyboardEventKeycode)
|
|
312
323
|
let flags = event.flags
|
|
313
324
|
return keyCode == 40
|
|
314
|
-
&& pressedKeyCodes
|
|
325
|
+
&& pressedKeyCodes[53] != nil
|
|
315
326
|
&& flags.contains(.maskShift)
|
|
316
327
|
}
|
|
317
328
|
|
|
@@ -371,30 +371,19 @@ final class ScreenOverlayCanvasController {
|
|
|
371
371
|
let hasAgentLayer = layersByID.values.contains { $0.owner == .agentApi }
|
|
372
372
|
if hasAgentLayer, globalDismissMonitor == nil {
|
|
373
373
|
let mask: NSEvent.EventTypeMask = [
|
|
374
|
-
.mouseMoved,
|
|
375
374
|
.leftMouseDown,
|
|
376
|
-
.leftMouseUp,
|
|
377
375
|
.rightMouseDown,
|
|
378
376
|
.otherMouseDown,
|
|
379
|
-
.leftMouseDragged,
|
|
380
|
-
.rightMouseDragged,
|
|
381
|
-
.otherMouseDragged,
|
|
382
377
|
]
|
|
383
378
|
globalDismissMonitor = NSEvent.addGlobalMonitorForEvents(matching: mask) { [weak self] event in
|
|
384
379
|
DispatchQueue.main.async {
|
|
385
380
|
_ = self?.handlePointerEvent(event)
|
|
386
381
|
}
|
|
387
382
|
}
|
|
388
|
-
localDismissMonitor = NSEvent.addLocalMonitorForEvents(matching:
|
|
389
|
-
if event.
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
return nil
|
|
393
|
-
}
|
|
394
|
-
} else {
|
|
395
|
-
if self?.handlePointerEvent(event) == true {
|
|
396
|
-
return nil
|
|
397
|
-
}
|
|
383
|
+
localDismissMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in
|
|
384
|
+
if event.keyCode == 53 {
|
|
385
|
+
self?.dismissAgentOverlays()
|
|
386
|
+
return nil
|
|
398
387
|
}
|
|
399
388
|
return event
|
|
400
389
|
}
|
|
@@ -416,35 +405,7 @@ final class ScreenOverlayCanvasController {
|
|
|
416
405
|
@discardableResult
|
|
417
406
|
private func handlePointerEvent(_ event: NSEvent) -> Bool {
|
|
418
407
|
switch event.type {
|
|
419
|
-
case .
|
|
420
|
-
updatePointerCapture(at: NSEvent.mouseLocation)
|
|
421
|
-
return false
|
|
422
|
-
case .leftMouseDown:
|
|
423
|
-
updatePointerCapture(at: NSEvent.mouseLocation)
|
|
424
|
-
if beginActorDrag(at: NSEvent.mouseLocation) {
|
|
425
|
-
return true
|
|
426
|
-
}
|
|
427
|
-
dismissAgentOverlays()
|
|
428
|
-
return false
|
|
429
|
-
case .leftMouseDragged:
|
|
430
|
-
if dragActor(to: NSEvent.mouseLocation) {
|
|
431
|
-
return true
|
|
432
|
-
}
|
|
433
|
-
dismissAgentOverlays()
|
|
434
|
-
return false
|
|
435
|
-
case .leftMouseUp:
|
|
436
|
-
let wasDragging = dragState != nil
|
|
437
|
-
endActorDrag()
|
|
438
|
-
updatePointerCapture(at: NSEvent.mouseLocation)
|
|
439
|
-
return wasDragging
|
|
440
|
-
case .rightMouseDown:
|
|
441
|
-
updatePointerCapture(at: NSEvent.mouseLocation)
|
|
442
|
-
if closeActor(at: NSEvent.mouseLocation) {
|
|
443
|
-
return true
|
|
444
|
-
}
|
|
445
|
-
dismissAgentOverlays()
|
|
446
|
-
return false
|
|
447
|
-
case .otherMouseDown, .rightMouseDragged, .otherMouseDragged:
|
|
408
|
+
case .leftMouseDown, .rightMouseDown, .otherMouseDown:
|
|
448
409
|
dismissAgentOverlays()
|
|
449
410
|
return false
|
|
450
411
|
default:
|
|
@@ -453,16 +414,7 @@ final class ScreenOverlayCanvasController {
|
|
|
453
414
|
}
|
|
454
415
|
|
|
455
416
|
private func updatePointerCapture(at globalPoint: CGPoint) {
|
|
456
|
-
|
|
457
|
-
let captureWindow: ScreenOverlayWindow?
|
|
458
|
-
if let dragState {
|
|
459
|
-
captureWindow = windowsByScreenID[dragState.screenID]
|
|
460
|
-
} else {
|
|
461
|
-
captureWindow = hitActor(at: globalPoint)?.window
|
|
462
|
-
}
|
|
463
|
-
for window in windowsByScreenID.values {
|
|
464
|
-
window.ignoresMouseEvents = window !== captureWindow
|
|
465
|
-
}
|
|
417
|
+
resetPointerCapture()
|
|
466
418
|
}
|
|
467
419
|
|
|
468
420
|
private func beginActorDrag(at globalPoint: CGPoint) -> Bool {
|
|
@@ -512,6 +464,7 @@ final class ScreenOverlayCanvasController {
|
|
|
512
464
|
let layer = layersByID[dragState.id],
|
|
513
465
|
case .pet(let payload) = layer.payload else {
|
|
514
466
|
self.dragState = nil
|
|
467
|
+
cancelActorDragTimeout()
|
|
515
468
|
resetPointerCapture()
|
|
516
469
|
return
|
|
517
470
|
}
|
|
@@ -520,7 +473,7 @@ final class ScreenOverlayCanvasController {
|
|
|
520
473
|
cancelActorDragTimeout()
|
|
521
474
|
render()
|
|
522
475
|
updateLifecycleMonitors()
|
|
523
|
-
|
|
476
|
+
resetPointerCapture()
|
|
524
477
|
}
|
|
525
478
|
|
|
526
479
|
private func clearStaleActorDragIfNeeded() {
|
|
@@ -562,7 +515,7 @@ final class ScreenOverlayCanvasController {
|
|
|
562
515
|
}
|
|
563
516
|
render()
|
|
564
517
|
updateLifecycleMonitors()
|
|
565
|
-
|
|
518
|
+
resetPointerCapture()
|
|
566
519
|
return true
|
|
567
520
|
}
|
|
568
521
|
|