[OS X Emacs] Re: one-buffer-one-frame-mode strangeness with Spaces

Ted Middleton middleton.ted at gmail.com
Tue Oct 26 18:15:33 EDT 2010

Ok - after a bit of digging, a bit of debugging, and a bit of dtrace,
I've found the chunk of code that calls [NSWindow
:makeKeyAndOrderFront:] when a NSWindow is dismissed. Here's the stack

              AppKit`-[NSWindow makeKeyWindow]
              AppKit`-[NSWindow _makeKeyRegardlessOfVisibility]+0x6f
              AppKit`-[NSWindow makeKeyAndOrderFront:]+0x18


In src/frame.c, at line 1456, we have

	/* Under NS, there is no system mechanism for choosing a new
	   window to get focus -- it is left to application code.
	   So the portion of THIS application interfacing with NS
	   needs to know about it.  We call Fraise_frame, but the
	   purpose is really to transfer focus.  */
	Fraise_frame (frame1);
      do_switch_frame (frame1, 0, 1, Qnil);
      sf = SELECTED_FRAME ();

  /* Don't allow minibuf_window to remain on a deleted frame.  */

This is a bit deeper inside emacs base source code I think. Commenting
out the call to Fraise_frame() fixes the Space switching problem with
an Aquamacs NSWindow is closed.

The problem is that the comment above is essentially correct - I'm not
clear on how exactly to fix this. If you don't explicitly call
:makeKeyWindow then remaining NSWindows don't automatically get made
'key' - they just remain in the background.

Ideally I'd like Aquamacs to behave like Terminal. When I open up two
NSWindows of Terminal in the same Space and then close one of them,
the other NSWindow is automatically made 'key'. When I open up two
NSWindows of Terminal and they're in different Spaces and then close
one of them, then the other Terminal NSWindow in the other Space
doesn't raise above other application NSWindows in that Space.

I'm wondering if the real issue here is whether Spaces is taking cues
from 'key' switches or rather from NSWindow order changes?
Fraise_frame() doesn't just call makeKeyWindow: - it calls
makeKeyAndOrderFront: which then calls makeKeyWindow:. I'm going to
try just calling makeKeyWindow rather than makeKeyAndOrderFront: in

I think I'm going to take this into the dev mailing list. Is it
possible to get access to the repo on github? Does the Aquamacs team
take but fix  commits from non-maintainers?

On Tue, Oct 26, 2010 at 12:22 PM, Ted Middleton <middleton.ted at gmail.com> wrote:
> Incidentally, for anyone else who wants to fix this problem locally,
> what I've done here is really an awful and kind of blind hack. Someone
> who actually knows what he or she is doing needs to look at this code
> more carefully than I have. In the meantime, I'll keep looking for the
> code that transfers focus to other NSWindows/frames when an
> NSWindow/frame is dismissed.
> On Tue, Oct 26, 2010 at 12:14 PM, Ted Middleton <middleton.ted at gmail.com> wrote:
>> Well, I've had a look at it, and at least I know where it's going
>> wrong. In Resources/lisp/aquamacs/one-buffer-one-frame.el at line 578
>> we have:
>>                (unless (eq display-buffer-reuse-frames 'select)
>>                  ;; we can't use select-frame-set-input-focus because
>>                  ;; that would raise the (main) frame over the newly
>>                  ;; opened one, and we don't want that.
>>                  (select-frame sframe)
>>                  (cond ((memq window-system '(x mac ns))
>>                         (x-focus-frame sframe))
>>                        ((eq window-system 'w32)
>>                         (w32-focus-frame sframe)))
>>                  (select-window swin))
>>                ret))
>> If I turn the "(x-focus-frame sframe)" into "()", this problem goes
>> away and aquamacs doesn't try to return me to another NSWindow. I
>> don't know what knock-ons this introduces (probably lots?) but I've
>> made this change locally and it's working quite nicely for me.
>> The next problem is that when I dismiss the NSWindow, aquamacs tries
>> to change the focus to another NSWindow, again, in another Space. I'll
>> try to hunt down where this is happening.
>> On Tue, Oct 26, 2010 at 9:41 AM, Ted Middleton <middleton.ted at gmail.com> wrote:
>>> Odd - I still don't seem to be getting digests or emails from this
>>> list - and there's nothing in my gmail spam box? Oh well - I'll have
>>> to keep replying to messages in the archive
>>>>> The other problem is that when I close an aquamacs frame the space switches automatically to another space where there is an open aquamacs frame.
>>>>This is indeed independent of one-buffer-one-frame-mode.  (In fact, Emacs Lisp-level modes do not know anything about spaces.)
>>>>I haven't seen it as a problem, but changing this behavior shouldn't be too difficult provided it is indeed non-standard on OS X.
>>> I'm guessing what's happening here is when emacs/aquamacs creates a
>>> new NSWindow/frame, it's keeping track of which aquamacs
>>> NSWindow/frame was most recently the key window, and then
>>> re-designates that the key window by calling NSWindow -makeKeyWindow
>>> or -makeKeyAndFrontOrder - I suspect that this is what triggers Spaces
>>> to switch to a different Space.
>>> Going back to my example, in Space 4 aquamacs has a NSWindow with the
>>> somefile.txt buffer, and being the only NSWindow it's designated as
>>> the key NSWindow. We switch to Space 7 and type 'aquamacs
>>> otherfile.txt' and that tells aquamacs to open a new NSWindow/frame
>>> with a buffer for otherfile.txt. If it all stopped there I think we
>>> would be just fine, but I suspect that, for some reason, aquamacs is
>>> then calling -makeKeyWindow: or -makeKeyAndOrderFront: on the first
>>> NSWindow (the one in Space 4 with the somefile.txt buffer). I believe
>>> (I'll test this later today myself) that this would trigger Spaces to
>>> switch back to Space 4.

More information about the MacOSX-Emacs mailing list