Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/ipykernel/_eventloop_macos.py: 0%

60 statements  

« prev     ^ index     » next       coverage.py v7.3.3, created at 2023-12-15 06:13 +0000

1"""Eventloop hook for OS X 

2 

3Calls NSApp / CoreFoundation APIs via ctypes. 

4""" 

5 

6# cribbed heavily from IPython.terminal.pt_inputhooks.osx 

7# obj-c boilerplate from appnope, used under BSD 2-clause 

8 

9import ctypes 

10import ctypes.util 

11from threading import Event 

12 

13objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("objc")) # type:ignore[arg-type] 

14 

15void_p = ctypes.c_void_p 

16 

17objc.objc_getClass.restype = void_p 

18objc.sel_registerName.restype = void_p 

19objc.objc_msgSend.restype = void_p 

20objc.objc_msgSend.argtypes = [void_p, void_p] 

21 

22msg = objc.objc_msgSend 

23 

24 

25def _utf8(s): 

26 """ensure utf8 bytes""" 

27 if not isinstance(s, bytes): 

28 s = s.encode("utf8") 

29 return s 

30 

31 

32def n(name): 

33 """create a selector name (for ObjC methods)""" 

34 return objc.sel_registerName(_utf8(name)) 

35 

36 

37def C(classname): 

38 """get an ObjC Class by name""" 

39 return objc.objc_getClass(_utf8(classname)) 

40 

41 

42# end obj-c boilerplate from appnope 

43 

44# CoreFoundation C-API calls we will use: 

45CoreFoundation = ctypes.cdll.LoadLibrary( 

46 ctypes.util.find_library("CoreFoundation") # type:ignore[arg-type] 

47) 

48 

49CFAbsoluteTimeGetCurrent = CoreFoundation.CFAbsoluteTimeGetCurrent 

50CFAbsoluteTimeGetCurrent.restype = ctypes.c_double 

51 

52CFRunLoopGetCurrent = CoreFoundation.CFRunLoopGetCurrent 

53CFRunLoopGetCurrent.restype = void_p 

54 

55CFRunLoopGetMain = CoreFoundation.CFRunLoopGetMain 

56CFRunLoopGetMain.restype = void_p 

57 

58CFRunLoopStop = CoreFoundation.CFRunLoopStop 

59CFRunLoopStop.restype = None 

60CFRunLoopStop.argtypes = [void_p] 

61 

62CFRunLoopTimerCreate = CoreFoundation.CFRunLoopTimerCreate 

63CFRunLoopTimerCreate.restype = void_p 

64CFRunLoopTimerCreate.argtypes = [ 

65 void_p, # allocator (NULL) 

66 ctypes.c_double, # fireDate 

67 ctypes.c_double, # interval 

68 ctypes.c_int, # flags (0) 

69 ctypes.c_int, # order (0) 

70 void_p, # callout 

71 void_p, # context 

72] 

73 

74CFRunLoopAddTimer = CoreFoundation.CFRunLoopAddTimer 

75CFRunLoopAddTimer.restype = None 

76CFRunLoopAddTimer.argtypes = [void_p, void_p, void_p] 

77 

78kCFRunLoopCommonModes = void_p.in_dll(CoreFoundation, "kCFRunLoopCommonModes") 

79 

80 

81def _NSApp(): 

82 """Return the global NSApplication instance (NSApp)""" 

83 return msg(C("NSApplication"), n("sharedApplication")) 

84 

85 

86def _wake(NSApp): 

87 """Wake the Application""" 

88 event = msg( 

89 C("NSEvent"), 

90 n( 

91 "otherEventWithType:location:modifierFlags:" 

92 "timestamp:windowNumber:context:subtype:data1:data2:" 

93 ), 

94 15, # Type 

95 0, # location 

96 0, # flags 

97 0, # timestamp 

98 0, # window 

99 None, # context 

100 0, # subtype 

101 0, # data1 

102 0, # data2 

103 ) 

104 msg(NSApp, n("postEvent:atStart:"), void_p(event), True) 

105 

106 

107_triggered = Event() 

108 

109 

110def stop(timer=None, loop=None): 

111 """Callback to fire when there's input to be read""" 

112 _triggered.set() 

113 NSApp = _NSApp() 

114 # if NSApp is not running, stop CFRunLoop directly, 

115 # otherwise stop and wake NSApp 

116 if msg(NSApp, n("isRunning")): 

117 msg(NSApp, n("stop:"), NSApp) 

118 _wake(NSApp) 

119 else: 

120 CFRunLoopStop(CFRunLoopGetCurrent()) 

121 

122 

123_c_callback_func_type = ctypes.CFUNCTYPE(None, void_p, void_p) 

124_c_stop_callback = _c_callback_func_type(stop) 

125 

126 

127def _stop_after(delay): 

128 """Register callback to stop eventloop after a delay""" 

129 timer = CFRunLoopTimerCreate( 

130 None, # allocator 

131 CFAbsoluteTimeGetCurrent() + delay, # fireDate 

132 0, # interval 

133 0, # flags 

134 0, # order 

135 _c_stop_callback, 

136 None, 

137 ) 

138 CFRunLoopAddTimer( 

139 CFRunLoopGetMain(), 

140 timer, 

141 kCFRunLoopCommonModes, 

142 ) 

143 

144 

145def mainloop(duration=1): 

146 """run the Cocoa eventloop for the specified duration (seconds)""" 

147 

148 _triggered.clear() 

149 NSApp = _NSApp() 

150 _stop_after(duration) 

151 msg(NSApp, n("run")) 

152 if not _triggered.is_set(): 

153 # app closed without firing callback, 

154 # probably due to last window being closed. 

155 # Run the loop manually in this case, 

156 # since there may be events still to process (ipython/ipython#9734) 

157 CoreFoundation.CFRunLoopRun()