Subject: Re: bug#63312: 29.0.90; set-frame-parameter sometimes called with dead frame when quitting ediff

From: Tobias Bading <[email-masked]>
Date: Sat, 6 May 2023 12:10:33 +0200

> Does the patch below give good results?
>
> diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el
> index 9286a18..acfbbed 100644
> --- a/lisp/x-dnd.el
> +++ b/lisp/x-dnd.el
> @@ -609,8 +609,9 @@ x-dnd-init-xdnd-for-frame
>  (defun x-dnd-after-move-frame (frame)
>    "Handle FRAME moving to a different position.
>  Clear any cached root window position."
> -  (set-frame-parameter frame 'dnd-root-window-position
> -                       nil))
> +  (and (frame-live-p frame)
> +       (set-frame-parameter frame 'dnd-root-window-position
> +                            nil)))
>
>  (add-hook 'move-frame-functions #'x-dnd-after-move-frame)

It probably would, because for testing purposes I already patched
handle-move-frame like this:

diff --git a/lisp/frame.el b/lisp/frame.el
index bf984da0d6..d6ca63ce53 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -237,11 +237,16 @@ handle-focus-out
 (defun handle-move-frame (event)
   "Handle a move-frame event.
 This function runs the abnormal hook `move-frame-functions'."
   (interactive "e")
   (let ((frame (posn-window (event-start event))))
-    (run-hook-with-args 'move-frame-functions frame)))
+    ;; make sure the frame is still alive (TODO)
+    (if (frame-live-p frame)
+        (run-hook-with-args 'move-frame-functions frame)
+      (let ((inhibit-message t))
+        (message "FRAME IS ALREADY DEAD: %s" frame))
+      )))

Basically the same change, just one function higher and with a silent log
message. This successfully suppresses the error and logs when the strange
situation occurred.

This looks like some race between Emacs and Compiz or something. Sometimes
it occurs, sometimes it doesn’t. handle-move-frame should probably not get
triggered at all if the frame is already dead. So far I didn’t find the C
function doing this, but I didn’t look that hard because I have a few other
minor problems that might be related:
I need (ediff-control-frame-upward-shift -20) to properly align the ediff
control frame with the main frame. Also, starting Emacs with -geometry and
fiddling with left/top/width/height in default-frame-alist and
initial-frame-alist doesn’t give the same results as with Emacs 26.3.
Something fishy is going on and probably related to the fact that I’m using
a 4K monitor and thus HiDPI scaling is in play. Might be another case of a
missing conversion between GTK application pixels and device pixels
somewhere. Such a misinterpretation (or rounding error) of pixel positions
and/or sizes may trigger the handle-move-frame, which in itself doesn’t make
much sense when a frame is being destroyed.