bug#72496: 31.0.50 macOS: freezes without beach ball
Alan Third <[email protected]> Mon, 3 Aug 2026 16:21:57 +0100
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Aug 03, 2026 at 02:29:37PM +0300, Eli Zaretskii wrote: > Alan and Stéphane, any comments or suggestions? This looks good to me. Any "better" alternative would probably involve getting rid of this appdefined event nonsense completely, which isn't easy. > > From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 > > From: Anton Dergunov <[email protected]> > > Subject: [PATCH] Fix a permanent hang on macOS when no window is main > > > > 'ns_send_appdefined' posted the event that ends [NSApp run] with > > windowNumber: [[NSApp mainWindow] windowNumber]. While the frame is > > miniaturized, or while key/main status is being handed over, [NSApp > > mainWindow] is nil and the window number is 0; AppKit discards such an > > event, so [NSApp run] never returns and Emacs never gets back to its > > command loop. > > > > The hang is permanent rather than intermittent because nothing retries: > > 'send_appdefined' has already been cleared by this same call, so every > > later EV_TRAILER re-post is suppressed, and 'timed_entry' has just been > > invalidated. Unlike 'ns_select_1', 'ns_read_socket_1' never arms a > > 'timed_entry', so no timer can wake the loop either. > > > > Note that [NSApp keyWindow] is nil while miniaturized too, so the scan > > over [NSApp windows] is the fallback that actually applies. > > > > * src/nsterm.m (ns_send_appdefined): Address the app-defined event to a > > window that exists. (Bug#72496) > > --- > > --- a/src/nsterm.m > > +++ b/src/nsterm.m > > @@ -4686,6 +4686,7 @@ > > if (send_appdefined) > > { > > NSEvent *nxev; > > + NSWindow *dest; > > > > /* We only need one NX_APPDEFINED event to stop NXApp from running. */ > > send_appdefined = NO; > > @@ -4697,12 +4698,29 @@ > > [timed_entry release]; > > timed_entry = nil; > > } > > + > > + /* Address the event to a window that actually exists. With no main > > + window -- miniaturized, or mid handover of key/main status -- the > > + window number would be 0 and AppKit would silently discard the > > + event. That is fatal here: send_appdefined has just been cleared > > + and timed_entry invalidated, so nothing would ever end [NSApp run] > > + again, and Emacs would hang forever with its UI unresponsive. */ > > + dest = [NSApp mainWindow]; > > + if (dest == nil) > > + dest = [NSApp keyWindow]; > > + if (dest == nil) > > + for (NSWindow *cand in [NSApp windows]) > > + if ([cand windowNumber] > 0) > > + { > > + dest = cand; > > + break; > > + } > > > > nxev = [NSEvent otherEventWithType: NSEventTypeApplicationDefined > > location: NSMakePoint (0, 0) > > modifierFlags: 0 > > timestamp: 0 > > - windowNumber: [[NSApp mainWindow] windowNumber] > > + windowNumber: [dest windowNumber] > > context: [NSApp context] > > subtype: 0 > > data1: value -- Alan Third