Subject: Re: bug#31920: 26.1; frame appears in wrong part of desktop after restoring frameset from fullscreen

From: Spenser Truex <[email-masked]>
Date: Sun, 30 Jun 2019 23:08:40 -0700

Robert Pluim <[email-masked]> writes:

> diff --git i/lisp/frame.el w/lisp/frame.el
> index 29c31f41cb..a58fad6481 100644
> --- i/lisp/frame.el
> +++ w/lisp/frame.el
> @@ -2413,7 +2413,7 @@ toggle-frame-maximized
>       (t
>        (set-frame-parameter nil 'fullscreen 'maximized)))))
>
> -(defun toggle-frame-fullscreen ()
> +(defun toggle-frame-fullscreen (&optional frame)
>    "Toggle fullscreen state of selected frame.
>  Make selected frame fullscreen or restore its previous size if it
>  is already fullscreen.
> @@ -2431,14 +2431,14 @@ toggle-frame-fullscreen
>
>  See also `toggle-frame-maximized'."
>    (interactive)
> -  (let ((fullscreen (frame-parameter nil 'fullscreen)))
> +  (let ((fullscreen (frame-parameter frame 'fullscreen)))
>      (if (memq fullscreen '(fullscreen fullboth))
> -	(let ((fullscreen-restore (frame-parameter nil 'fullscreen-restore)))
> +	(let ((fullscreen-restore (frame-parameter frame 'fullscreen-restore)))
>  	  (if (memq fullscreen-restore '(maximized fullheight fullwidth))
> -	      (set-frame-parameter nil 'fullscreen fullscreen-restore)
> -	    (set-frame-parameter nil 'fullscreen nil)))
> +	      (set-frame-parameter frame 'fullscreen fullscreen-restore)
> +	    (set-frame-parameter frame 'fullscreen nil)))
>        (modify-frame-parameters
> -       nil `((fullscreen . fullboth) (fullscreen-restore . ,fullscreen))))
> +       frame `((fullscreen . fullboth) (fullscreen-restore . ,fullscreen))))
>      ;; Manipulating a frame without waiting for the fullscreen
>      ;; animation to complete can cause a crash, or other unexpected
>      ;; behavior, on macOS (bug#28496).
> diff --git i/lisp/frameset.el w/lisp/frameset.el
> index 0e3363d7ae..ffbf6722a7 100644
> --- i/lisp/frameset.el
> +++ w/lisp/frameset.el
> @@ -1085,6 +1085,11 @@ frameset--restore-frame
>        (when (frame-live-p parent-frame)
>          (set-frame-parameter frame 'parent-frame parent-frame)))
>
> +    (let ((old-fullscreen (frame-parameter frame 'fullscreen)))
> +      (and (not (eq old-fullscreen fullscreen))
> +           (memq old-fullscreen '(fullscreen fullboth))
> +           (not fullscreen)
> +           (toggle-frame-fullscreen frame)))
>      (modify-frame-parameters frame
>  			     (if (eq (frame-parameter frame 'fullscreen) fullscreen)
>  				 ;; Workaround for bug#14949
>
>
>
>

I've just discovered this bug for myself, without any register
manipulation. Here is the recipe (almost the same as the original):

1) Make a window and use the WM to make it 1/2 the screen size. I
usually grab the window with the mouse and hit it against the right side
of the screen.
2) F11 to toggle fullscreen.
3) do #2 again.

Now the window isn't perfectly 1/2 the window.

Checking the value of (frame-parameter nil 'fullscreen) produces the
symbol fullheight, which indicates the problem: the emacs restore
procedure (fullscreen-restore) only stores *some* information about the
previous window configuration. The following diff shows the workaround I
was using so I could happily use f11 with my emacs:
--- lisp/frame.el	2019-06-30 21:42:29.257939995 -0700
+++ lisp/frame.el	2019-06-30 21:41:34.239940756 -0700
@@ -2621,21 +2621,21 @@
 `frame-resize-pixelwise' to non-nil in order to make a frame
 appear truly fullscreen.  In addition, you may have to set
 `x-frame-normalize-before-maximize' in order to enable
 transitions from one fullscreen state to another.

 See also `toggle-frame-maximized'."
   (interactive)
   (let ((fullscreen (frame-parameter frame 'fullscreen)))
     (if (memq fullscreen '(fullscreen fullboth))
 	(let ((fullscreen-restore (frame-parameter frame 'fullscreen-restore)))
-	  (if (memq fullscreen-restore '(maximized fullheight fullwidth))
+	  (if (memq fullscreen-restore '(maximized))
 	      (set-frame-parameter frame 'fullscreen fullscreen-restore)
 	    (set-frame-parameter frame 'fullscreen nil)))
       (modify-frame-parameters
        frame `((fullscreen . fullboth) (fullscreen-restore . ,fullscreen))))
     ;; Manipulating a frame without waiting for the fullscreen
     ;; animation to complete can cause a crash, or other unexpected
     ;; behavior, on macOS (bug#28496).
     (when (featurep 'cocoa) (sleep-for 0.5))))

 

So I just threw out all width and height information. To do a proper
fix, I think Emacs needs to keep track of sufficient information about
the window. Window height, width, and location must be stored. The
current one only stores height or width.

This way the window manager seems to be able to make all the decisions
about window size, though I actually have no idea what is going on.

For toggle-frame-maximized the problem still exists though, and I have
not found any workaround.

--
Spenser Truex