Subject: Re: bug#53276: The blink-cursor-mode not work after startup on macOS

From: Po Lu <[email-masked]>
Date: Sat, 15 Jan 2022 21:05:38 +0800

Alan Third <[email-masked]> writes:

> On Sat, Jan 15, 2022 at 03:04:35PM +0800, Po Lu wrote:
>> Eason Huang <[email-masked]> writes:
>> 
>> > When Emacs is started at the first time, the blink-cursor-mode does
>> > not work, and the focus needs to be switched to another
>> > application, and then switching back again, it will work properly.
>> 
>> blink-cursor-mode will only start the idle timer that actually blinks
>> the cursor if at least one frame is focused, but no FOCUS_IN_EVENT is
>> sent until windowDidBecomeKey is called a second time, as emacs_event is
>> NULL when windowDidBecomeKey is first called.  This is both on GNUstep
>> and macOS.  (Perhaps storing the FOCUS_IN_EVENT into the keyboard buffer
>> would be an option.)
>> 
>> Alan, do you have any idea as to why this is?  I'm afraid I don't really
>> understand the NS event loop code.
>
> No, I don't know why it's done this way. There are a number of other
> bugs that have the same root cause, where emacs_event is null because
> the code is being called outside the run loop and therefore the event
> never reaches Emacs.

I think the right solution is to store events directly into the keyboard
buffer instead of using emacs_event, but I don't know if there's a
reason the NS port was not developed that way.

> My assumption is that there is a reason why it's done this way, but I
> can't work it out.

Basically, it fits well into the pselect-read-XPending-XNextEvent model
that most X-Windows applications are designed around.  The other ports
are then designed around this X model.

> I had a look at some of the other terms and they *kind of* work in a
> similar fashion, in that there's one function that scoops up all the
> events and passes them to Emacs (like ns_read_socket does) but they
> differ in that the events are queued up by the system before they're
> read in.

Does NS not queue unread events until they're read?  That seems like odd
design to me.

> So given that I wonder if the NS port is just copying that style from
> other terms, but it doesn't actually work right.

That style is reasonable (think of it like `read', except it reads
events from a display server connection into the keyboard buffer), but
what I don't understand here is why callback methods like
windowDidBecomeKey can't just call kbd_buffer_store_event, instead going
through all the trouble to allocate a temporary buffer and using that to
hold the events.

Thanks in advance.

> (I sometimes think it would be nice if we had git history for the NS
> port from before it was merged in, because a lot of these design
> decisions are ancient and it's unclear why they were made.)

I agree.