环境: 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
, 由于没有太多 Cocoa 编程经验, 所以不知道该如何解决. orz
最近两个macOS版本比较常见的问题,火狐窗口多了也很明显。另外全屏了也消失不了
在古法 random programming (指随便乱插代码并反复崩溃) 后, 让窗口不消失的原因可能是窗口关闭了之后仍然被作为 keyWindow 在前台接受事件的输入, 导致不会被 release 掉.
目前看起来能解决这个问题的方法是在 windowWillClose: 前强制加一段把 window 移到后面 orderOut: 以及 setIsVisible:NO (虽然不知道是哪个具体起了作用, 总之它能跑
)
仅供参考的复现代码:
;;; 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