Make Apple happy with the new macOS screenshot API
This commit is contained in:
68
owocr/run.py
68
owocr/run.py
@@ -40,11 +40,12 @@ except ImportError:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import objc
|
import objc
|
||||||
|
import platform
|
||||||
from AppKit import NSData, NSImage, NSBitmapImageRep, NSDeviceRGBColorSpace, NSGraphicsContext, NSZeroPoint, NSZeroRect, NSCompositingOperationCopy
|
from AppKit import NSData, NSImage, NSBitmapImageRep, NSDeviceRGBColorSpace, NSGraphicsContext, NSZeroPoint, NSZeroRect, NSCompositingOperationCopy
|
||||||
from Quartz import CGWindowListCreateImageFromArray, kCGWindowImageBoundsIgnoreFraming, CGRectNull, CGWindowListCopyWindowInfo, CGWindowListCreateDescriptionFromArray, \
|
from Quartz import CGWindowListCreateImageFromArray, kCGWindowImageBoundsIgnoreFraming, CGRectNull, CGMainDisplayID, CGWindowListCopyWindowInfo, CGWindowListCreateDescriptionFromArray, \
|
||||||
kCGWindowListOptionOnScreenOnly, kCGWindowListExcludeDesktopElements, kCGWindowName, kCGNullWindowID, \
|
kCGWindowListOptionOnScreenOnly, kCGWindowListExcludeDesktopElements, kCGWindowName, kCGNullWindowID, \
|
||||||
CGImageGetWidth, CGImageGetHeight, CGDataProviderCopyData, CGImageGetDataProvider, CGImageGetBytesPerRow
|
CGImageGetWidth, CGImageGetHeight, CGDataProviderCopyData, CGImageGetDataProvider, CGImageGetBytesPerRow
|
||||||
|
from ScreenCaptureKit import SCContentFilter, SCScreenshotManager, SCShareableContent, SCStreamConfiguration, SCCaptureResolutionBest
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -229,6 +230,51 @@ class WindowsWindowTracker(threading.Thread):
|
|||||||
on_window_closed(False)
|
on_window_closed(False)
|
||||||
|
|
||||||
|
|
||||||
|
def capture_macos_window_screenshot(window_id):
|
||||||
|
def shareable_content_completion_handler(shareable_content, error):
|
||||||
|
if error:
|
||||||
|
screencapturekit_queue.put(None)
|
||||||
|
return
|
||||||
|
|
||||||
|
target_window = None
|
||||||
|
for window in shareable_content.windows():
|
||||||
|
if window.windowID() == window_id:
|
||||||
|
target_window = window
|
||||||
|
break
|
||||||
|
|
||||||
|
if not target_window:
|
||||||
|
screencapturekit_queue.put(None)
|
||||||
|
return
|
||||||
|
|
||||||
|
with objc.autorelease_pool():
|
||||||
|
content_filter = SCContentFilter.alloc().initWithDesktopIndependentWindow_(target_window)
|
||||||
|
|
||||||
|
frame = content_filter.contentRect()
|
||||||
|
scale = content_filter.pointPixelScale()
|
||||||
|
width = frame.size.width * scale
|
||||||
|
height = frame.size.height * scale
|
||||||
|
configuration = SCStreamConfiguration.alloc().init()
|
||||||
|
configuration.setWidth_(width)
|
||||||
|
configuration.setHeight_(height)
|
||||||
|
configuration.setShowsCursor_(False)
|
||||||
|
configuration.setCaptureResolution_(SCCaptureResolutionBest)
|
||||||
|
|
||||||
|
SCScreenshotManager.captureImageWithFilter_configuration_completionHandler_(
|
||||||
|
content_filter, configuration, capture_image_completion_handler
|
||||||
|
)
|
||||||
|
|
||||||
|
def capture_image_completion_handler(image, error):
|
||||||
|
if error:
|
||||||
|
screencapturekit_queue.put(None)
|
||||||
|
return
|
||||||
|
|
||||||
|
screencapturekit_queue.put(image)
|
||||||
|
|
||||||
|
SCShareableContent.getShareableContentWithCompletionHandler_(
|
||||||
|
shareable_content_completion_handler
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_windows_window_handle(window_title):
|
def get_windows_window_handle(window_title):
|
||||||
def callback(hwnd, window_title_part):
|
def callback(hwnd, window_title_part):
|
||||||
if window_title_part in win32gui.GetWindowText(hwnd):
|
if window_title_part in win32gui.GetWindowText(hwnd):
|
||||||
@@ -695,7 +741,7 @@ def run(read_from=None,
|
|||||||
unix_socket_server_thread.start()
|
unix_socket_server_thread.start()
|
||||||
read_from_readable = 'unix socket'
|
read_from_readable = 'unix socket'
|
||||||
elif read_from == 'clipboard':
|
elif read_from == 'clipboard':
|
||||||
mac_clipboard_polling = False
|
macos_clipboard_polling = False
|
||||||
windows_clipboard_polling = False
|
windows_clipboard_polling = False
|
||||||
img = None
|
img = None
|
||||||
|
|
||||||
@@ -703,7 +749,7 @@ def run(read_from=None,
|
|||||||
from AppKit import NSPasteboard, NSPasteboardTypeTIFF, NSPasteboardTypeString
|
from AppKit import NSPasteboard, NSPasteboardTypeTIFF, NSPasteboardTypeString
|
||||||
pasteboard = NSPasteboard.generalPasteboard()
|
pasteboard = NSPasteboard.generalPasteboard()
|
||||||
count = pasteboard.changeCount()
|
count = pasteboard.changeCount()
|
||||||
mac_clipboard_polling = True
|
macos_clipboard_polling = True
|
||||||
elif sys.platform == 'win32':
|
elif sys.platform == 'win32':
|
||||||
global clipboard_event
|
global clipboard_event
|
||||||
clipboard_event = threading.Event()
|
clipboard_event = threading.Event()
|
||||||
@@ -756,6 +802,14 @@ def run(read_from=None,
|
|||||||
sct_params = {'top': coord_top, 'left': coord_left, 'width': coord_width, 'height': coord_height, 'mon': screen_capture_monitor}
|
sct_params = {'top': coord_top, 'left': coord_left, 'width': coord_width, 'height': coord_height, 'mon': screen_capture_monitor}
|
||||||
else:
|
else:
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
|
if int(platform.mac_ver()[0].split('.')[0]) < 12:
|
||||||
|
old_macos_screenshot_api = True
|
||||||
|
else:
|
||||||
|
global screencapturekit_queue
|
||||||
|
screencapturekit_queue = queue.Queue()
|
||||||
|
CGMainDisplayID()
|
||||||
|
old_macos_screenshot_api = False
|
||||||
|
|
||||||
window_list = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID)
|
window_list = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID)
|
||||||
window_titles = []
|
window_titles = []
|
||||||
window_ids = []
|
window_ids = []
|
||||||
@@ -897,7 +951,7 @@ def run(read_from=None,
|
|||||||
img = Image.open(io.BytesIO(win32clipboard.GetClipboardData(win32clipboard.CF_DIB)))
|
img = Image.open(io.BytesIO(win32clipboard.GetClipboardData(win32clipboard.CF_DIB)))
|
||||||
process_clipboard = True
|
process_clipboard = True
|
||||||
win32clipboard.CloseClipboard()
|
win32clipboard.CloseClipboard()
|
||||||
elif mac_clipboard_polling:
|
elif macos_clipboard_polling:
|
||||||
if not paused:
|
if not paused:
|
||||||
with objc.autorelease_pool():
|
with objc.autorelease_pool():
|
||||||
old_count = count
|
old_count = count
|
||||||
@@ -941,7 +995,11 @@ def run(read_from=None,
|
|||||||
if take_screenshot and screencapture_window_visible:
|
if take_screenshot and screencapture_window_visible:
|
||||||
if screencapture_mode == 2 and sys.platform == 'darwin':
|
if screencapture_mode == 2 and sys.platform == 'darwin':
|
||||||
with objc.autorelease_pool():
|
with objc.autorelease_pool():
|
||||||
|
if old_macos_screenshot_api:
|
||||||
cg_image = CGWindowListCreateImageFromArray(CGRectNull, [window_id], kCGWindowImageBoundsIgnoreFraming)
|
cg_image = CGWindowListCreateImageFromArray(CGRectNull, [window_id], kCGWindowImageBoundsIgnoreFraming)
|
||||||
|
else:
|
||||||
|
capture_macos_window_screenshot(window_id)
|
||||||
|
cg_image = screencapturekit_queue.get()
|
||||||
if not cg_image:
|
if not cg_image:
|
||||||
on_window_closed(False)
|
on_window_closed(False)
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user