macOS 14中CMD`切换窗口后ScreenCaptureKit帧异常的解决方案求助
macOS 14 ScreenCaptureKit窗口切换帧更新Bug的规避方案求助
已向苹果提交Bug反馈(FB13561921),现寻求无视觉瑕疵、无需辅助功能的规避方案。
Bug现象
使用ScreenCaptureKit捕获全屏帧时,在多窗口应用中按下「切换到下一个窗口」(CMD + `)快捷键后,捕获的帧无法正确更新:实际已前置的窗口在捕获帧中仍显示为后置状态,与真实屏幕显示不符。
复现步骤
- 运行苹果官方ScreenCaptureKit示例应用
注:搭建SCK会话并展示输出的代码量较大,使用官方代码可排除框架误用问题
- 捕获全屏内容(而非单个窗口)
- 在文本编辑(Text Edit)中打开两个部分重叠的窗口,确保示例应用能正确显示
- 按下*CMD + `*切换文本编辑的窗口
- 此时真实屏幕上窗口的Z轴层级已变化,但示例应用中仍显示原前置窗口在顶层
- 拖动窗口或点击窗口间隙后,捕获帧恢复正常更新
该Bug存在于macOS 14.1-14.3,macOS 13.6无此问题。
已尝试的临时方案
- 重启SCStream无效果,重启后的流仍显示原前置窗口
- 通过辅助功能模拟拖动窗口再还原,但会产生视觉瑕疵
问题
是否存在无需辅助功能、无视觉瑕疵的方案,能让ScreenCaptureKit在使用该快捷键后生成正确更新的新前置窗口帧?
附产生视觉瑕疵的辅助功能"hack"代码:
func moveTheWindow(_ point: CGPoint) async { guard let originalCursorPosition = CGEvent(source: nil)?.location else { print("Failed to get the original cursor position.") return } let mouseDownPoint = point let mouseDragRightPoint = CGPoint(x: point.x + 1, y: point.y) let mouseDragLeftPoint = CGPoint(x: point.x, y: point.y) // Mouse down at the starting point if let mouseDown = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: mouseDownPoint, mouseButton: .left) { mouseDown.post(tap: .cghidEventTap) } // Drag the window 1px to the right if let mouseDragRight = CGEvent( mouseEventSource: nil, mouseType: .leftMouseDragged, mouseCursorPosition: mouseDragRightPoint, mouseButton: .left ) { mouseDragRight.post(tap: .cghidEventTap) } // Mouse up to finish the first drag if let mouseUpRight = CGEvent( mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: mouseDragRightPoint, mouseButton: .left ) { mouseUpRight.post(tap: .cghidEventTap) } try? await Task.sleep(nanoseconds: NSEC_PER_SEC / 20) // Mouse down again for the second drag if let mouseDownAgain = CGEvent( mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: mouseDragRightPoint, mouseButton: .left ) { mouseDownAgain.post(tap: .cghidEventTap) } // Drag the window back 1px to the left if let mouseDragLeft = CGEvent( mouseEventSource: nil, mouseType: .leftMouseDragged, mouseCursorPosition: mouseDragLeftPoint, mouseButton: .left ) { mouseDragLeft.post(tap: .cghidEventTap) } // Mouse up to complete the second drag if let mouseUpLeft = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: mouseDragLeftPoint, mouseButton: .left) { mouseUpLeft.post(tap: .cghidEventTap) } try? await Task.sleep(nanoseconds: NSEC_PER_SEC / 20) // Move the cursor back to the original position CGWarpMouseCursorPosition(originalCursorPosition) }
内容的提问来源于stack exchange,提问作者jnpdx
相关产品推荐
相关产品推荐

