@@ -1045,6 +1045,52 @@ def shutdown_handler(event):
10451045 pass
10461046 return shutdown_handler .unregister_mpv_events
10471047
1048+ def _wait_for_future (self , result , timeout ):
1049+ """Wait for a future to complete. On macOS main thread, this actively pumps the CoreFoundation event loop."""
1050+ self .check_core_alive ()
1051+
1052+ if sys .platform == 'darwin' and threading .current_thread () is threading .main_thread ():
1053+ import time
1054+ import ctypes
1055+ import ctypes .util
1056+
1057+ global _core_foundation
1058+ global _cf_runloop_default_mode
1059+ try :
1060+ if _core_foundation is None or _cf_runloop_default_mode is None :
1061+ _core_foundation = ctypes .cdll .LoadLibrary (ctypes .util .find_library ('CoreFoundation' ))
1062+
1063+ # CFRunLoopRunInMode(CFStringRef mode, CFTimeInterval seconds, Boolean returnAfterSourceHandled)
1064+ _core_foundation .CFRunLoopRunInMode .argtypes = [ctypes .c_void_p , ctypes .c_double , ctypes .c_bool ]
1065+ _core_foundation .CFRunLoopRunInMode .restype = ctypes .c_int32
1066+
1067+ _cf_runloop_default_mode = ctypes .c_void_p .in_dll (_core_foundation , 'kCFRunLoopDefaultMode' )
1068+
1069+ start_time = time .monotonic ()
1070+ while not result .done ():
1071+ remaining = 0
1072+ if timeout is not None :
1073+ remaining = timeout - (time .monotonic () - start_time )
1074+ if remaining <= 0 :
1075+ break
1076+
1077+ # Pump events for up to 0.05 seconds, or remaining timeout if smaller
1078+ sleep_time = min (0.05 , remaining )
1079+ else :
1080+ sleep_time = 0.05
1081+
1082+ _core_foundation .CFRunLoopRunInMode (_cf_runloop_default_mode , sleep_time , False )
1083+ self .check_core_alive ()
1084+ except ShutdownError :
1085+ raise
1086+ except Exception as e :
1087+ # Fallback if CoreFoundation loading fails
1088+ warn (f"Failed to load CoreFoundation for mpv macOS event loop: { e } " , RuntimeWarning )
1089+
1090+ return result .result (0 if timeout is not None else None )
1091+ else :
1092+ return result .result (timeout )
1093+
10481094 @contextmanager
10491095 def prepare_and_wait_for_property (self , name , cond = lambda val : val , level_sensitive = True , timeout = None , catch_errors = True ):
10501096 """Context manager that waits until ``cond`` evaluates to a truthy value on the named property. See
@@ -1084,8 +1130,7 @@ def observer(name, val):
10841130 result .set_result (rv )
10851131 return
10861132
1087- self .check_core_alive ()
1088- result .result (timeout )
1133+ self ._wait_for_future (result , timeout )
10891134
10901135 except InvalidStateError :
10911136 pass
@@ -1144,44 +1189,7 @@ def target_handler(evt):
11441189
11451190 yield result
11461191
1147- self .check_core_alive ()
1148-
1149- self .check_core_alive ()
1150-
1151- if sys .platform == 'darwin' and threading .current_thread () is threading .main_thread ():
1152- import time
1153- import ctypes
1154- import ctypes .util
1155-
1156- global _core_foundation
1157- global _cf_runloop_default_mode
1158- try :
1159- if _core_foundation is None :
1160- _core_foundation = ctypes .cdll .LoadLibrary (ctypes .util .find_library ('CoreFoundation' ))
1161-
1162- # CFRunLoopRunInMode(CFStringRef mode, CFTimeInterval seconds, Boolean returnAfterSourceHandled)
1163- _core_foundation .CFRunLoopRunInMode .argtypes = [ctypes .c_void_p , ctypes .c_double , ctypes .c_bool ]
1164- _core_foundation .CFRunLoopRunInMode .restype = ctypes .c_int32
1165-
1166- _cf_runloop_default_mode = ctypes .c_void_p .in_dll (_core_foundation , 'kCFRunLoopDefaultMode' )
1167-
1168- start_time = time .monotonic ()
1169- while not result .done ():
1170- remaining = 0
1171- if timeout is not None :
1172- remaining = timeout - (time .monotonic () - start_time )
1173- if remaining <= 0 :
1174- break
1175-
1176- # Pump events for up to 0.05 seconds, or remaining timeout if smaller
1177- sleep_time = min (0.05 , remaining ) if timeout is not None else 0.05
1178- _core_foundation .CFRunLoopRunInMode (_cf_runloop_default_mode , sleep_time , False )
1179- self .check_core_alive ()
1180- except Exception as e :
1181- # Fallback if CoreFoundation loading fails
1182- warn (f"Failed to load CoreFoundation for mpv macOS event loop: { e } " , RuntimeWarning )
1183-
1184- result .result (timeout )
1192+ self ._wait_for_future (result , timeout )
11851193
11861194 finally :
11871195 err_unregister ()
0 commit comments