Add throttled breadcrumbs for drag-handle hit-test anomalies (#527)
This commit is contained in:
parent
fdca658c80
commit
6f459918c5
1 changed files with 70 additions and 0 deletions
|
|
@ -6,6 +6,55 @@ private func windowDragHandleFormatPoint(_ point: NSPoint) -> String {
|
|||
String(format: "(%.1f,%.1f)", point.x, point.y)
|
||||
}
|
||||
|
||||
private func windowDragHandleEventTypeDescription(_ eventType: NSEvent.EventType?) -> String {
|
||||
eventType.map { String(describing: $0) } ?? "nil"
|
||||
}
|
||||
|
||||
private enum WindowDragHandleBreadcrumbLimiter {
|
||||
private static var lastEmissionByKey: [String: CFAbsoluteTime] = [:]
|
||||
|
||||
static func shouldEmit(key: String, minInterval: CFTimeInterval) -> Bool {
|
||||
let now = CFAbsoluteTimeGetCurrent()
|
||||
if let previous = lastEmissionByKey[key], (now - previous) < minInterval {
|
||||
return false
|
||||
}
|
||||
lastEmissionByKey[key] = now
|
||||
if lastEmissionByKey.count > 128 {
|
||||
let staleThreshold = now - max(minInterval * 4, 60)
|
||||
lastEmissionByKey = lastEmissionByKey.filter { _, timestamp in
|
||||
timestamp >= staleThreshold
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private func windowDragHandleEmitBreadcrumb(
|
||||
_ message: String,
|
||||
window: NSWindow?,
|
||||
eventType: NSEvent.EventType?,
|
||||
point: NSPoint,
|
||||
minInterval: CFTimeInterval = 10,
|
||||
extraData: [String: Any] = [:]
|
||||
) {
|
||||
let windowNumber = window?.windowNumber ?? -1
|
||||
let key = "\(message):\(windowNumber)"
|
||||
guard WindowDragHandleBreadcrumbLimiter.shouldEmit(key: key, minInterval: minInterval) else {
|
||||
return
|
||||
}
|
||||
|
||||
var data: [String: Any] = [
|
||||
"event_type": windowDragHandleEventTypeDescription(eventType),
|
||||
"point": windowDragHandleFormatPoint(point),
|
||||
"window_number": windowNumber,
|
||||
"window_present": window != nil
|
||||
]
|
||||
for (name, value) in extraData {
|
||||
data[name] = value
|
||||
}
|
||||
sentryBreadcrumb(message, category: "titlebar.drag", data: data)
|
||||
}
|
||||
|
||||
private func windowDragHandleShouldDeferHitCapture(for eventType: NSEvent.EventType?) -> Bool {
|
||||
switch eventType {
|
||||
case .leftMouseDown?:
|
||||
|
|
@ -171,6 +220,16 @@ func windowDragHandleShouldCaptureHit(
|
|||
// We only keep suppression active while the left mouse button is down.
|
||||
if (NSEvent.pressedMouseButtons & 0x1) == 0 {
|
||||
let clearedDepth = clearWindowDragSuppression(window: dragHandleView.window)
|
||||
windowDragHandleEmitBreadcrumb(
|
||||
"titlebar.dragHandle.suppression.recovered",
|
||||
window: dragHandleView.window,
|
||||
eventType: eventType,
|
||||
point: point,
|
||||
minInterval: 20,
|
||||
extraData: [
|
||||
"cleared_depth": clearedDepth
|
||||
]
|
||||
)
|
||||
#if DEBUG
|
||||
dlog(
|
||||
"titlebar.dragHandle.hitTest suppressionRecovered clearedDepth=\(clearedDepth) point=\(windowDragHandleFormatPoint(point))"
|
||||
|
|
@ -239,6 +298,17 @@ func windowDragHandleShouldCaptureHit(
|
|||
"titlebar.dragHandle.hitTest capture=false point=\(windowDragHandleFormatPoint(point)) siblingCount=\(siblingCount) sibling=\(type(of: sibling)) hit=\(type(of: hitView)) passiveHost=false"
|
||||
)
|
||||
#endif
|
||||
windowDragHandleEmitBreadcrumb(
|
||||
"titlebar.dragHandle.hitTest.blockedBySiblingHit",
|
||||
window: dragHandleView.window,
|
||||
eventType: eventType,
|
||||
point: point,
|
||||
minInterval: 8,
|
||||
extraData: [
|
||||
"sibling_type": String(describing: type(of: sibling)),
|
||||
"hit_type": String(describing: type(of: hitView))
|
||||
]
|
||||
)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue