Repository: electron/electron
Pull request: fix: fullscreen restoration on Windows

#### Description of Change

Closes https://github.com/electron/electron/issues/49793.
Refs CL:7112979
Refs CL:7095963

Fixes an issue where making a window fullscreen on Windows, minimizing it, then restoring it broke previous fullscreen state. Chromium's fullscreen handler conflicts with ours and results in incorrect restoration. Fix this by overriding `DesktopWindowTreeHostWin::Restore` to the previous implementation.

#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [x] PR description included
- [ ] `npm test` passes
- [x] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: Fixed an issue where making a window fullscreen on Windows, minimizing it and then restoring it broke previous fullscreen state. 

Changed files:
filename: shell/browser/ui/win/electron_desktop_window_tree_host_win.cc
patch: @@ -197,6 +197,14 @@ void ElectronDesktopWindowTreeHostWin::SetAllowScreenshots(bool allow) {
   UpdateAllowScreenshots();
 }
 
+// Refs https://chromium-review.googlesource.com/c/chromium/src/+/7095963
+// Chromium's fullscreen handler conflicts with ours and results in incorrect
+// restoration.
+void ElectronDesktopWindowTreeHostWin::Restore() {
+  ::SendMessage(GetAcceleratedWidget(), WM_SYSCOMMAND,
+                static_cast<WPARAM>(SC_RESTORE), 0);
+}
+
 void ElectronDesktopWindowTreeHostWin::UpdateAllowScreenshots() {
   bool allowed = views::DesktopWindowTreeHostWin::AreScreenshotsAllowed();
   if (allowed == allow_screenshots_)

filename: shell/browser/ui/win/electron_desktop_window_tree_host_win.h
patch: @@ -50,6 +50,7 @@ class ElectronDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin,
                         LRESULT* result) override;
   void HandleVisibilityChanged(bool visible) override;
   void SetAllowScreenshots(bool allow) override;
+  void Restore() override;
 
   // ui::NativeThemeObserver:
   void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;

filename: spec/api-browser-window-spec.ts
patch: @@ -4882,6 +4882,27 @@ describe('BrowserWindow module', () => {
       await restore;
       expect(w.isMaximized()).to.equal(true);
     });
+
+    ifit(process.platform !== 'linux')('should not break fullscreen state', async () => {
+      const w = new BrowserWindow({ show: false });
+      w.show();
+
+      const enterFS = once(w, 'enter-full-screen');
+      w.setFullScreen(true);
+      await enterFS;
+      expect(w.isFullScreen()).to.be.true('not fullscreen');
+
+      w.restore();
+      await setTimeout(1000);
+
+      expect(w.isFullScreen()).to.be.true('not fullscreen after restore');
+      expect(w.isMinimized()).to.be.false('should not be minimized');
+
+      // Clean up fullscreen state.
+      const leaveFS = once(w, 'leave-full-screen');
+      w.setFullScreen(false);
+      await leaveFS;
+    });
   });
 
   // TODO(dsanders11): Enable once maximize event works on Linux again on CI