Subject: bug#25542: 25.1; Restoring the frame from fullscreen to maximized

From: Ken Brown <[email-masked]>
Date: Wed, 9 Sep 2020 16:24:31 -0400

On 9/9/2020 2:19 PM, Ken Brown wrote:
> On 9/9/2020 4:44 AM, martin rudalics wrote:
>>  > I've just downloaded a native w32 build [1] and I've run it on my
>>  > system (MS Windows 10 Enterprise). I see the same problem with this
>>  > native build.
>>
>> Can you please run under gdb with a breakpoint in w32fullscreen_hook of
>> w32term.c suitably in here
>>
>>        else if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
>>      {
>>        if (prev_fsmode == FULLSCREEN_BOTH || prev_fsmode == FULLSCREEN_WIDTH
>>            || prev_fsmode == FULLSCREEN_HEIGHT)
>>          /* Make window normal since otherwise the subsequent
>>             maximization might fail in some cases.  */
>>          ShowWindow (hwnd, SW_SHOWNORMAL);
>>        ShowWindow (hwnd, SW_MAXIMIZE);
>>      }
>>
>> and tell us how the frame appears immediately after the ShowWindow
>> calls.  Here the first call makes the frame appear with its "normal"
>> size, the second one makes it appear maximized.
> 
> I just tried this on a Cygwin-w32 build from the master branch.  I put the 
> taskbar on the left, started emacs, maximized it, attached gdb, put breakpoints 
> at each of the ShowWindow lines, and ran through Dani's recipe for producing the 
> bug.  The breakpoints were never hit.

I just tried again, but this time with a breakpoint at w32fullscreen_hook so 
that I could follow the flow.  Here are the relevant excerpts from the gdb session:

$ gdb ./emacs
GNU gdb (GDB) (Cygwin 9.2-1) 9.2

[...]

(gdb) b w32fullscreen_hook
Breakpoint 2 at 0x10069507a: file ../../master/src/w32term.c, line 6441.
(gdb) r -Q
Starting program: /home/kbrown/src/emacs/x86_64-w32/src/emacs -Q

[...]

[Press F11]

Thread 1 "emacs" hit Breakpoint 2, w32fullscreen_hook (f=0x8001f7c88)
     at ../../master/src/w32term.c:6441
6441      if (FRAME_VISIBLE_P (f))
(gdb) n
6443          HWND hwnd = FRAME_W32_WINDOW(f);
(gdb)
6444          DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
(gdb)
6446          enum fullscreen_type prev_fsmode = FRAME_PREV_FSMODE (f);
(gdb)
6448          block_input();
(gdb)
6449          f->want_fullscreen &= ~FULLSCREEN_WAIT;
(gdb)
6451          if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE)
(gdb)
6452            GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
(gdb)
6454          if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH)
(gdb)
6460          else if (FRAME_PREV_FSMODE (f) == FULLSCREEN_HEIGHT
(gdb)
6461                   || FRAME_PREV_FSMODE (f) == FULLSCREEN_WIDTH)
(gdb)
6464          FRAME_PREV_FSMODE (f) = f->want_fullscreen;
(gdb) p f->want_fullscreen
$1 = FULLSCREEN_BOTH
(gdb) n
6466          if (f->want_fullscreen == FULLSCREEN_NONE)
(gdb)
6468          else if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
(gdb)
6477          else if (f->want_fullscreen == FULLSCREEN_BOTH)
(gdb)
6479              int menu_bar_height = GetSystemMetrics (SM_CYMENU);
(gdb)
6482                                   FRAME_NORMAL_PLACEMENT 
(f).rcNormalPosition, &rect);
(gdb)
6481              w32_fullscreen_rect (hwnd, f->want_fullscreen,
(gdb)
6483              if (!FRAME_UNDECORATED (f))
(gdb)
6484                SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
(gdb)
6486                            rect.right - rect.left, rect.bottom - rect.top,
(gdb)
6485              SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
(gdb)
6486                            rect.right - rect.left, rect.bottom - rect.top,
(gdb)
6485              SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
(gdb)
6490                 FRAME_PIXEL_TO_TEXT_HEIGHT (f, (rect.bottom - rect.top
(gdb)
6488              change_frame_size
(gdb)
6489                (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, rect.right - rect.left),
(gdb)
6488              change_frame_size
(gdb)
6526          f->want_fullscreen = FULLSCREEN_NONE;
(gdb)
6527          unblock_input ();
(gdb)
6529          if (f->want_fullscreen == FULLSCREEN_BOTH
(gdb)
6530              || f->want_fullscreen == FULLSCREEN_WIDTH
(gdb)
6531              || f->want_fullscreen == FULLSCREEN_HEIGHT)
(gdb)
6537    }

[...]

(gdb) c
Continuing.

[Press F11 again]

Thread 1 "emacs" hit Breakpoint 2, w32fullscreen_hook (f=0x8001f7c88)
     at ../../master/src/w32term.c:6441
6441      if (FRAME_VISIBLE_P (f))
(gdb) n
6443          HWND hwnd = FRAME_W32_WINDOW(f);
(gdb)
6444          DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
(gdb)
6446          enum fullscreen_type prev_fsmode = FRAME_PREV_FSMODE (f);
(gdb)
6448          block_input();
(gdb)
6449          f->want_fullscreen &= ~FULLSCREEN_WAIT;
(gdb)
6451          if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE)
(gdb) p f->want_fullscreen
$2 = FULLSCREEN_NONE
(gdb) n
6454          if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH)
(gdb)
6456              if (!FRAME_UNDECORATED (f))
(gdb)
6457                SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW);
(gdb)
6458              SetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
(gdb)
6464          FRAME_PREV_FSMODE (f) = f->want_fullscreen;
(gdb)
6466          if (f->want_fullscreen == FULLSCREEN_NONE)
(gdb)
6467            ShowWindow (hwnd, SW_SHOWNORMAL);

[Now the frame reverts to an unmaximized state, exhibiting the bug.]

Ken