41
41
static bool keyChangeCapsLock = false ;
42
42
/* Keep track of the current mouse up/down state for open/closed cursor hand */
43
43
static bool leftMouseGrabbing = false ;
44
+ /* Keep track of whether stdin has been received */
45
+ bool stdin_received = false ;
46
+ bool stdin_sigint = false ;
47
+
48
+ // Signal handler for SIGINT
49
+ void handleSigint (int signal) {
50
+ stdin_sigint = true ;
51
+ }
52
+
53
+ int wait_for_stdin () {
54
+ @autoreleasepool {
55
+ stdin_received = false ;
56
+ stdin_sigint = false ;
57
+
58
+ // Set up a SIGINT handler to interrupt the event loop if ctrl+c comes in too
59
+ struct sigaction action = {0 };
60
+ action.sa_handler = handleSigint;
61
+ sigaction (SIGINT, &action, NULL );
62
+
63
+ // Create an NSFileHandle for standard input
64
+ NSFileHandle *stdinHandle = [NSFileHandle fileHandleWithStandardInput ];
65
+
66
+ // Register for data available notifications on standard input
67
+ [[NSNotificationCenter defaultCenter ] addObserverForName: NSFileHandleDataAvailableNotification
68
+ object: stdinHandle
69
+ queue: [NSOperationQueue mainQueue ] // Use the main queue
70
+ usingBlock: ^(NSNotification *notification) {
71
+ // Mark that input has been received
72
+ stdin_received = true ;
73
+ }
74
+ ];
75
+
76
+ // Wait in the background for anything that happens to stdin
77
+ [stdinHandle waitForDataInBackgroundAndNotify ];
78
+
79
+ // continuously run an event loop until the stdin_received flag is set to exit
80
+ while (!stdin_received && !stdin_sigint) {
81
+ while (true ) {
82
+ NSEvent *event = [NSApp nextEventMatchingMask: NSEventMaskAny
83
+ untilDate: [NSDate distantPast ]
84
+ inMode: NSDefaultRunLoopMode
85
+ dequeue: YES ];
86
+ if (!event) { break ; }
87
+ [NSApp sendEvent: event];
88
+ }
89
+ // We need to run the run loop for a short time to allow the
90
+ // events to be processed and keep flushing them while we wait for stdin
91
+ [[NSRunLoop currentRunLoop ] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01 ]];
92
+ }
93
+
94
+ // reset the signal handler to the default behavior
95
+ signal (SIGINT, SIG_DFL);
96
+ if (stdin_sigint) {
97
+ raise (SIGINT);
98
+ }
99
+ // Remove the input handler as an observer
100
+ [[NSNotificationCenter defaultCenter ] removeObserver: stdinHandle];
101
+ return 1 ;
102
+ }
103
+ }
44
104
45
105
/* ---------------------------- Cocoa classes ---------------------------- */
46
106
@@ -139,6 +199,9 @@ static void lazy_init(void) {
139
199
NSApp = [NSApplication sharedApplication ];
140
200
[NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
141
201
202
+ // Run our own event loop while waiting for stdin on the Python side
203
+ // this is needed to keep the application responsive while waiting for input
204
+ PyOS_InputHook = wait_for_stdin;
142
205
}
143
206
144
207
static PyObject*
0 commit comments