macOS 窗口关闭后仍会在 Misson Control 中显示一个透明的 window (Ghost Window)

环境: macOS 26, M2 air, GNU Emacs 31.0.50 (build 1, aarch64-apple-darwin25.3.0, NS appkit-2685.40 Version 26.3 (Build 25D125)) of 2026-03-11 (emacs-plus)

现象: 有时候在关闭窗口后, 仍然会在 Misson Control 中显示一个透明的窗口, 触发的概率比较随机, 但是具体的表现类似于下面这样:

注: 图中并非 Emacs 窗口, 但是 Emacs 有时候也会出现类似的现象. 但是切换到 macOS 15, M1 air 上时并不会发生这样的问题. (因为触发的条件过于诡异所以一时之间没能找到图)

查了一下好像其他程序也有类似的 bug :sweat_droplets:, 由于没有太多 Cocoa 编程经验, 所以不知道该如何解决. orz

最近两个macOS版本比较常见的问题,火狐窗口多了也很明显。另外全屏了也消失不了

在古法 random programming (指随便乱插代码并反复崩溃) 后, 让窗口不消失的原因可能是窗口关闭了之后仍然被作为 keyWindow 在前台接受事件的输入, 导致不会被 release 掉.

目前看起来能解决这个问题的方法是在 windowWillClose: 前强制加一段把 window 移到后面 orderOut: 以及 setIsVisible:NO (虽然不知道是哪个具体起了作用, 总之它能跑 :sweat_droplets:)

仅供参考的复现代码:

;;; Create window:
(let* ((window   (objc:invoke
                      (objc:alloc "McCLIMCocaWindow")
                      "initWithContentRect:styleMask:backing:defer:"
                      :ns-rect       (0 0 100 100)
                      :unsigned-long *ns-window-style*
                      :unsigned-long 2 ; buffered
                      :bool          t ; defer
                      :object))
       (view     (objc:alloc-init "McCLIMCocaView"))
       (delegate (objc:alloc-init "McCLIMCocaWindowDelegate")))
  (objc:invoke window "setTitle:" :ns-string (sheet-pretty-name sheet))
  (objc:invoke window "setReleasedWhenClosed:" :bool t)
  ;; [window delegate]
  (objc:invoke window "setDelegate:" :object delegate))
;;; realize-mirror, https://codeberg.org/li-yiyang/McCLIM/src/commit/538acfe85eef4b4f6197de1452072435896d2b0b/Backends/coca/core/mirror.lisp#L12

;;; Before close: ptr -> NSWindow
(objc:invoke ptr "setIsVisible:" :bool nil)
(objc:invoke ptr "orderOut:" :object (cffi:null-pointer)))
;;; disable-mirror: https://codeberg.org/li-yiyang/McCLIM/src/commit/538acfe85eef4b4f6197de1452072435896d2b0b/Backends/coca/core/mirror.lisp#L103

;;; Clean up
(objc:release window)
;;; destroy-mirror: https://codeberg.org/li-yiyang/McCLIM/src/commit/538acfe85eef4b4f6197de1452072435896d2b0b/Backends/coca/core/mirror.lisp#L113