Browse Source

fix: DCHECK entering fullscreen while loading url (#35111)

* fix: DCHECK entering fullscreen while loading url

* spec: fixup test
Shelley Vohr 2 years ago
parent
commit
7588bb7425

+ 10 - 5
shell/browser/api/electron_api_web_contents.cc

@@ -1327,6 +1327,8 @@ void WebContents::OnEnterFullscreenModeForTab(
     return;
   }
 
+  owner_window()->set_fullscreen_transition_type(
+      NativeWindow::FullScreenTransitionType::HTML);
   exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
       requesting_frame, options.display_id);
 
@@ -3537,12 +3539,15 @@ void WebContents::EnumerateDirectory(
 
 bool WebContents::IsFullscreenForTabOrPending(
     const content::WebContents* source) {
-  bool transition_fs = owner_window()
-                           ? owner_window()->fullscreen_transition_state() !=
-                                 NativeWindow::FullScreenTransitionState::NONE
-                           : false;
+  if (!owner_window())
+    return html_fullscreen_;
+
+  bool in_transition = owner_window()->fullscreen_transition_state() !=
+                       NativeWindow::FullScreenTransitionState::NONE;
+  bool is_html_transition = owner_window()->fullscreen_transition_type() ==
+                            NativeWindow::FullScreenTransitionType::HTML;
 
-  return html_fullscreen_ || transition_fs;
+  return html_fullscreen_ || (in_transition && is_html_transition);
 }
 
 bool WebContents::TakeFocus(content::WebContents* source, bool reverse) {

+ 3 - 1
shell/browser/native_window.cc

@@ -718,8 +718,10 @@ std::string NativeWindow::GetAccessibleTitle() {
 }
 
 void NativeWindow::HandlePendingFullscreenTransitions() {
-  if (pending_transitions_.empty())
+  if (pending_transitions_.empty()) {
+    set_fullscreen_transition_type(FullScreenTransitionType::NONE);
     return;
+  }
 
   bool next_transition = pending_transitions_.front();
   pending_transitions_.pop();

+ 14 - 2
shell/browser/native_window.h

@@ -318,10 +318,11 @@ class NativeWindow : public base::SupportsUserData,
     observers_.RemoveObserver(obs);
   }
 
-  enum class FullScreenTransitionState { ENTERING, EXITING, NONE };
-
   // Handle fullscreen transitions.
   void HandlePendingFullscreenTransitions();
+
+  enum class FullScreenTransitionState { ENTERING, EXITING, NONE };
+
   void set_fullscreen_transition_state(FullScreenTransitionState state) {
     fullscreen_transition_state_ = state;
   }
@@ -329,6 +330,15 @@ class NativeWindow : public base::SupportsUserData,
     return fullscreen_transition_state_;
   }
 
+  enum class FullScreenTransitionType { HTML, NATIVE, NONE };
+
+  void set_fullscreen_transition_type(FullScreenTransitionType type) {
+    fullscreen_transition_type_ = type;
+  }
+  FullScreenTransitionType fullscreen_transition_type() const {
+    return fullscreen_transition_type_;
+  }
+
   views::Widget* widget() const { return widget_.get(); }
   views::View* content_view() const { return content_view_; }
 
@@ -390,6 +400,8 @@ class NativeWindow : public base::SupportsUserData,
   std::queue<bool> pending_transitions_;
   FullScreenTransitionState fullscreen_transition_state_ =
       FullScreenTransitionState::NONE;
+  FullScreenTransitionType fullscreen_transition_type_ =
+      FullScreenTransitionType::NONE;
 
  private:
   std::unique_ptr<views::Widget> widget_;

+ 1 - 1
shell/browser/ui/cocoa/electron_ns_window_delegate.mm

@@ -19,7 +19,7 @@
 
 using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
 using FullScreenTransitionState =
-    electron::NativeWindowMac::FullScreenTransitionState;
+    electron::NativeWindow::FullScreenTransitionState;
 
 @implementation ElectronNSWindowDelegate
 

+ 17 - 0
spec-main/api-browser-window-spec.ts

@@ -4954,6 +4954,23 @@ describe('BrowserWindow module', () => {
         await leaveFullScreen;
       });
 
+      it('should be able to load a URL while transitioning to fullscreen', async () => {
+        const w = new BrowserWindow({ fullscreen: true });
+        w.loadFile(path.join(fixtures, 'pages', 'c.html'));
+
+        const load = emittedOnce(w.webContents, 'did-finish-load');
+        const enterFS = emittedOnce(w, 'enter-full-screen');
+
+        await Promise.all([enterFS, load]);
+        expect(w.fullScreen).to.be.true();
+
+        await delay();
+
+        const leaveFullScreen = emittedOnce(w, 'leave-full-screen');
+        w.setFullScreen(false);
+        await leaveFullScreen;
+      });
+
       it('can be changed with setFullScreen method', async () => {
         const w = new BrowserWindow();
         const enterFullScreen = emittedOnce(w, 'enter-full-screen');