Browse Source

fix: check for draggable regions outside of main frame (#41377)

Keeley Hammond 1 year ago
parent
commit
136d7e7e6a
2 changed files with 69 additions and 4 deletions
  1. 4 4
      shell/renderer/electron_render_frame_observer.cc
  2. 65 0
      spec/api-browser-window-spec.ts

+ 4 - 4
shell/renderer/electron_render_frame_observer.cc

@@ -66,10 +66,10 @@ ElectronRenderFrameObserver::ElectronRenderFrameObserver(
   // Initialise resource for directory listing.
   net::NetModule::SetResourceProvider(NetResourceProvider);
 
-  // App regions are only supported in the main frame.
-  auto* main_frame = frame->GetMainRenderFrame();
-  if (main_frame && main_frame == frame)
-    render_frame_->GetWebView()->SetSupportsAppRegion(true);
+  // In Chrome, app regions are only supported in the main frame.
+  // However, we need to support draggable regions on other
+  // local frames/windows, so extend support beyond the main frame.
+  render_frame_->GetWebView()->SetSupportsAppRegion(true);
 }
 
 void ElectronRenderFrameObserver::DidClearWindowObject() {

+ 65 - 0
spec/api-browser-window-spec.ts

@@ -6646,5 +6646,70 @@ describe('BrowserWindow module', () => {
 
       expect(startPos).to.not.deep.equal(endPos);
     });
+
+    ifit(hasCapturableScreen())('should allow the window to be dragged when no WCO and --webkit-app-region: drag enabled', async () => {
+      // @ts-ignore: nut-js is an optional dependency so it may not be installed
+      const { mouse, straightTo, centerOf, Region, Button } = require('@nut-tree/nut-js') as typeof import('@nut-tree/nut-js');
+
+      const display = screen.getPrimaryDisplay();
+      const w = new BrowserWindow({
+        x: 0,
+        y: 0,
+        width: display.bounds.width / 2,
+        height: display.bounds.height / 2,
+        frame: false
+      });
+
+      const basePageHTML = path.join(__dirname, 'fixtures', 'pages', 'base-page.html');
+      w.loadFile(basePageHTML);
+      await once(w, 'ready-to-show');
+
+      await w.webContents.executeJavaScript(`
+        const style = document.createElement('style');
+        style.innerHTML = \`
+        #titlebar {
+            
+          background-color: red;
+          height: 30px;
+          width: 100%;
+          -webkit-user-select: none;
+          -webkit-app-region: drag;
+          position: fixed;
+          top: 0;
+          left: 0;
+          z-index: 1000000000000;
+        }
+        \`;
+        
+        const titleBar = document.createElement('title-bar');
+        titleBar.id = 'titlebar';
+        titleBar.textContent = 'test-titlebar';
+        
+        document.body.append(style);
+        document.body.append(titleBar);
+      `);
+      // allow time for titlebar to finish loading
+      await setTimeout(2000);
+
+      const winBounds = w.getBounds();
+      const titleBarHeight = 30;
+      const titleBarRegion = new Region(winBounds.x, winBounds.y, winBounds.width, titleBarHeight);
+      const screenRegion = new Region(display.bounds.x, display.bounds.y, display.bounds.width, display.bounds.height);
+
+      const startPos = w.getPosition();
+      await mouse.setPosition(await centerOf(titleBarRegion));
+      await mouse.pressButton(Button.LEFT);
+      await mouse.drag(straightTo(centerOf(screenRegion)));
+
+      // Wait for move to complete
+      await Promise.race([
+        once(w, 'move'),
+        setTimeout(1000) // fallback for possible race condition
+      ]);
+
+      const endPos = w.getPosition();
+
+      expect(startPos).to.not.deep.equal(endPos);
+    });
   });
 });