Browse Source

feat: add 'resized' event to BrowserWindow (#26454)

Also adds 'moved' event to BrowserWindow on Windows.

Co-authored-by: samuelmaddock <[email protected]>
trop[bot] 4 years ago
parent
commit
01fa45fc50

+ 9 - 3
docs/api/browser-window.md

@@ -541,6 +541,12 @@ Note that this is only emitted when the window is being resized manually. Resizi
 
 Emitted after the window has been resized.
 
+#### Event: 'resized' _macOS_ _Windows_
+
+Emitted once when the window has finished being resized.
+
+This is usually emitted when the window has been resized manually. On macOS, resizing the window with `setBounds`/`setSize` and setting the `animate` parameter to `true` will also emit this event once resizing has finished.
+
 #### Event: 'will-move' _macOS_ _Windows_
 
 Returns:
@@ -556,12 +562,12 @@ Note that this is only emitted when the window is being resized manually. Resizi
 
 Emitted when the window is being moved to a new position.
 
-__Note__: On macOS this event is an alias of `moved`.
-
-#### Event: 'moved' _macOS_
+#### Event: 'moved' _macOS_ _Windows_
 
 Emitted once when the window is moved to a new position.
 
+__Note__: On macOS this event is an alias of `move`.
+
 #### Event: 'enter-full-screen'
 
 Emitted when the window enters a full-screen state.

+ 4 - 0
shell/browser/api/electron_api_base_window.cc

@@ -222,6 +222,10 @@ void BaseWindow::OnWindowResize() {
   Emit("resize");
 }
 
+void BaseWindow::OnWindowResized() {
+  Emit("resized");
+}
+
 void BaseWindow::OnWindowWillMove(const gfx::Rect& new_bounds,
                                   bool* prevent_default) {
   if (Emit("will-move", new_bounds)) {

+ 1 - 0
shell/browser/api/electron_api_base_window.h

@@ -63,6 +63,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
   void OnWindowWillResize(const gfx::Rect& new_bounds,
                           bool* prevent_default) override;
   void OnWindowResize() override;
+  void OnWindowResized() override;
   void OnWindowWillMove(const gfx::Rect& new_bounds,
                         bool* prevent_default) override;
   void OnWindowMove() override;

+ 5 - 0
shell/browser/native_window.cc

@@ -493,6 +493,11 @@ void NativeWindow::NotifyWindowResize() {
     observer.OnWindowResize();
 }
 
+void NativeWindow::NotifyWindowResized() {
+  for (NativeWindowObserver& observer : observers_)
+    observer.OnWindowResized();
+}
+
 void NativeWindow::NotifyWindowMove() {
   for (NativeWindowObserver& observer : observers_)
     observer.OnWindowMove();

+ 1 - 0
shell/browser/native_window.h

@@ -270,6 +270,7 @@ class NativeWindow : public base::SupportsUserData,
   void NotifyWindowWillResize(const gfx::Rect& new_bounds,
                               bool* prevent_default);
   void NotifyWindowResize();
+  void NotifyWindowResized();
   void NotifyWindowWillMove(const gfx::Rect& new_bounds, bool* prevent_default);
   void NotifyWindowMoved();
   void NotifyWindowScrollTouchBegin();

+ 1 - 0
shell/browser/native_window_observer.h

@@ -74,6 +74,7 @@ class NativeWindowObserver : public base::CheckedObserver {
   virtual void OnWindowWillResize(const gfx::Rect& new_bounds,
                                   bool* prevent_default) {}
   virtual void OnWindowResize() {}
+  virtual void OnWindowResized() {}
   virtual void OnWindowWillMove(const gfx::Rect& new_bounds,
                                 bool* prevent_default) {}
   virtual void OnWindowMove() {}

+ 6 - 0
shell/browser/native_window_views.h

@@ -282,6 +282,12 @@ class NativeWindowViews : public NativeWindow,
 
   // Whether we want to set window placement without side effect.
   bool is_setting_window_placement_ = false;
+
+  // Whether the window is currently being resized.
+  bool is_resizing_ = false;
+
+  // Whether the window is currently being moved.
+  bool is_moving_ = false;
 #endif
 
   // Handles unhandled keyboard messages coming back from the renderer process.

+ 13 - 0
shell/browser/native_window_views_win.cc

@@ -259,6 +259,7 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
         return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param));
       return false;
     case WM_SIZING: {
+      is_resizing_ = true;
       bool prevent_default = false;
       NotifyWindowWillResize(gfx::Rect(*reinterpret_cast<RECT*>(l_param)),
                              &prevent_default);
@@ -274,7 +275,19 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
       HandleSizeEvent(w_param, l_param);
       return false;
     }
+    case WM_EXITSIZEMOVE: {
+      if (is_resizing_) {
+        NotifyWindowResized();
+        is_resizing_ = false;
+      }
+      if (is_moving_) {
+        NotifyWindowMoved();
+        is_moving_ = false;
+      }
+      return false;
+    }
     case WM_MOVING: {
+      is_moving_ = true;
       bool prevent_default = false;
       NotifyWindowWillMove(gfx::Rect(*reinterpret_cast<RECT*>(l_param)),
                            &prevent_default);

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

@@ -201,6 +201,7 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
 }
 
 - (void)windowDidEndLiveResize:(NSNotification*)notification {
+  shell_->NotifyWindowResized();
   if (is_zooming_) {
     if (shell_->IsMaximized())
       shell_->NotifyWindowMaximize();

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

@@ -855,6 +855,15 @@ describe('BrowserWindow module', () => {
         const expectedBounds = Object.assign(fullBounds, boundsUpdate);
         expectBoundsEqual(w.getBounds(), expectedBounds);
       });
+
+      ifit(process.platform === 'darwin')('on macOS', () => {
+        it('emits \'resized\' event after animating', async () => {
+          const fullBounds = { x: 440, y: 225, width: 500, height: 400 };
+          w.setBounds(fullBounds, true);
+
+          await expect(emittedOnce(w, 'resized')).to.eventually.be.fulfilled();
+        });
+      });
     });
 
     describe('BrowserWindow.setSize(width, height)', () => {
@@ -867,6 +876,15 @@ describe('BrowserWindow module', () => {
 
         expectBoundsEqual(w.getSize(), size);
       });
+
+      ifit(process.platform === 'darwin')('on macOS', () => {
+        it('emits \'resized\' event after animating', async () => {
+          const size = [300, 400];
+          w.setSize(size[0], size[1], true);
+
+          await expect(emittedOnce(w, 'resized')).to.eventually.be.fulfilled();
+        });
+      });
     });
 
     describe('BrowserWindow.setMinimum/MaximumSize(width, height)', () => {