Subject: Re: bug#78527: 30.1; Mishaving new frame creation in MacOS on new desktop

From: martin rudalics <[email-masked]>
Date: Thu, 5 Jun 2025 11:05:45 +0200

>> I'm still a bit dense in the following sense: You have a fullscreen
 >> frame, do C-x 5 2 and now see the new frame on a new desktop but it
 >> apparently didn't get focus because, as you say, the prompt doesn't
 >> appear there.  However, in your initial posting you say that "Focus
 >> shifts there".  What makes you think that focus shifted there?  The
 >> appearance of the cursor, the mode line, some decoration in the new
 >> frame?  Does C-x 2 split a window in the new or old frame?
 >>
 >
 > C-x 2: New frame, surprisingly.

Not really.  C-x 2 splits the selected window and that's the one on the
new frame.  The C-x 5 2 need _not_ necessarily have made the new frame
the selected one but it apparently does so on your system.  On many
systems, the window manager gives users the choice whether a freshly
created window should automatically become "active", that is, has
keystrokes directed to it.  In your case we apparently have a split
behavior - the new frame becomes selected but focus remains on the old
frame.

 > But subsequent commands are still messed
 > up.  For example, after C-x 2 I now have 2 windows in the new frame, but if
 > I try M-x, the prompt shows up the old frame!

You would have to trace choose_minibuf_frame in minibuf.c to find out
why Emacs shows the prompt in the old frame.  I'm afraid you won't be
able to do that.  Try the following instead: With a fullscreen Emacs
showing *scratch* insert the following text

(setq old-frame (selected-frame))
(setq new-frame (make-frame))

(defun foo ()
   (interactive)
   (insert
    (format "selected: % s old: %s new: %s old-mw: %s new-mw: %s"
	   (selected-frame) old-frame new-frame
	   (window-frame (minibuffer-window old-frame))
	   (window-frame (minibuffer-window new-frame)))))

(global-set-key [(control l)] 'foo)

do M-x RET eval-buffer RET and then type C-l.  The text this adds to
+scratch* might tell us which minibuffer window Emacs wants to use.

 > That's without trying any of
 > the hooks you suggested.
 >
 > Focus: Sorry.  I did not use the right terminology.  I only at the moment
 > work on my laptop with a single physical screen.  So when a "new frame
 > opens on new desktop",  what I see on my physical screen is the old desktop
 > slides off to the left and a new desktop with a new frame appears.  I
 > probably should not have used the word "focus."  I get a new frame with a
 > highlighted cursor in the main window.

This again only indicates that Emacs considers the new frame as the
selected one.  Here on xfce WM windows have decorations showing which
window the WM considers as the one having focus - where it directs
keystrokes to.  Does your bad scenario happen with an initially
"maximized" (not "fullboth") frame too?  Then maybe such decorations
would reveal more information.

 > Just noticed another weirdness, btw:
 > – I see a blinking cursor with emacs -Q.
 > – But after I have two frames in different desktops, immediately after I
 > switch between desktops (in either direction), the cursor is highlighted,
 > but does not blink.
 > – In fact, this cursor thing has nothing to do with full screen or
 > desktops: with two regular frames next to each other on a common desktop,
 > when *I click on a frame to switch focus there*, the cursor gets
 > highlighted, but does not blink until I do something...  *But if I do C-x 5
 > 2 to switch frames, *it blinks as it should.  And when I switch from
 > Firefox (where I am writing this) to Emacs (using Alt-TAB [=command-TAB]),
 > the cursor initially does not blink.

This further indicates a problem with what Emacs thinks about which of
its frames has focus.

 > Another experiment (similar to what I wrote in an earlier email): Do the
 > C-x 5 2 from a full-screen frame.  Do a M-x.  I do *not* see the prompt.
 > Now use MacOS shortcut keys to switch frames (ctrl-right/left).  Then the
 > M-x prompt appears in BOTH frames.

But you can't tell since you can see only one frame at a time.  What is
your value of 'minibuffer-follows-selected-frame'?  Does changing it
change the behavior you see?

 > In one it is selected (cursor is
 > highlighted)

Is "it" the minibuffer window or just the frame?

 > and in the other it is not (highlighted cursor is in the main
 > *scratch* window).  This is w/o any of the hooks you wanted me to try.
 > Just plain Macports Emacs -Q.

Again this hints at a focus problem.  We would have to understand how
focusing works on MacOS.  You could try with

(defun foo-it (&rest rest)
   (with-current-buffer (get-buffer-create "*foo*")
     (goto-char (point-max))
     (when rest
       (insert (format "%s" (car rest)))
       (setq rest (cdr rest))
       (while rest
	(insert (format " .. %s" (car rest)))
	(setq rest (cdr rest)))
       (insert "\n"))))

(defun my-foo-it ()
   (let ((frames (frame-list))
	frame foo)
     (while frames
       (setq frame (car frames))
       (setq foo (cons (cons frame (frame-focus-state frame)) foo))
       (setq frames (cdr frames)))
     (foo-it foo)))

(add-function :after after-focus-change-function #'my-foo-it)

and tell us what the buffer *foo* contains after C-x 5 2.  The focus
handling code has changed in Emacs a couple of years ago and I have no
idea whether 'frame-focus-state' is useful at all.

martin