Subject: Re: bug#32864: 26.1; menus don't work correctly in Mac OS Mojave

From: Alan Third <[email-masked]>
Date: Tue, 4 Jun 2019 17:44:46 +0100

On Mon, Jun 03, 2019 at 07:25:27PM +0200, Mattias Engdegård wrote:
> 
> So why does Emacs do this to begin with? Because the menu contents
> are generated dynamically from elisp code each time. The standard
> way to do this in Cocoa is to implement menuNeedsUpdate:, but this
> requires running arbitrary elisp code inside the event loop, which
> is undesirable for some reason.
> 
> The workarounds mentioned involved adding Emacs to some sort of
> whitelist for legacy applications, but this cannot be a solution.
> The synthetic mouse click hack must go away.
> 
> Could someone explain why, exactly, elisp code cannot be run inside
> the event loop? An alternative would be to run elisp code in a
> different thread, and let menuNeedsUpdate: block until the menu has
> been updated. I'm not sure what the difference would be.

Elisp code doesn’t guarantee it will return, it can longjmp when you
hit C-g, for example. This means you can end up with the application
attempting to run the event loop while it is still INSIDE the previous
event loop, and the toolkit really doesn’t like that. It will, in
fact, kill Emacs on the spot.

It may also be the case that Emacs can try to run the event loop from
within elisp code as a matter of course.

Quite simply we’re, as you said, not able to handle running elisp from
within the NS event loop.

I’m not sure why it was written this way originally, I believe the NS
port is some twenty five years old now and I’ve only been working on
Emacs for three.

The best solution is, as you said, to separate the lisp and toolkit
calls into separate threads, but unfortunately it’s not a straight
forward job. I want to do it anyway as there are other benefits, but
it won’t be happening soon unless someone else wants to pick it up.

The other solution I found is to rebuild the menu completely whenever
lisp updates it. This is simple enough to do but rebuilding the menus
takes something like 40‐70ms every time, as opposed to 1‐2ms to just
rebuild the top level, and it can do it up to three times per
keypress. I think it may also do it sometimes while scrolling. It
didn’t seem like a good idea to me. On the other hand I don’t remember
actually having much trouble with it.

If anyone has any other ideas I’d be happy to hear them.
-- 
Alan Third