feat: include resize edge with will-resize event (#29199)
* feat: emit resize edge with will-resize event fix: wparam type fix: private member usage on mac docs: will-resize event edge option refactor: 'info' -> 'details' for better type gen * Update docs/api/browser-window.md Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com> * Update docs/api/browser-window.md Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
This commit is contained in:
parent
750a762bf0
commit
f9d2a7077e
11 changed files with 104 additions and 4 deletions
|
@ -523,11 +523,20 @@ Returns:
|
||||||
|
|
||||||
* `event` Event
|
* `event` Event
|
||||||
* `newBounds` [Rectangle](structures/rectangle.md) - Size the window is being resized to.
|
* `newBounds` [Rectangle](structures/rectangle.md) - Size the window is being resized to.
|
||||||
|
* `details` Object
|
||||||
|
* `edge` (String) - The edge of the window being dragged for resizing. Can be `bottom`, `left`, `right`, `top-left`, `top-right`, `bottom-left` or `bottom-right`.
|
||||||
|
|
||||||
Emitted before the window is resized. Calling `event.preventDefault()` will prevent the window from being resized.
|
Emitted before the window is resized. Calling `event.preventDefault()` will prevent the window from being resized.
|
||||||
|
|
||||||
Note that this is only emitted when the window is being resized manually. Resizing the window with `setBounds`/`setSize` will not emit this event.
|
Note that this is only emitted when the window is being resized manually. Resizing the window with `setBounds`/`setSize` will not emit this event.
|
||||||
|
|
||||||
|
The possible values and behaviors of the `edge` option are platform dependent. Possible values are:
|
||||||
|
|
||||||
|
* On Windows, possible values are `bottom`, `top`, `left`, `right`, `top-left`, `top-right`, `bottom-left`, `bottom-right`.
|
||||||
|
* On macOS, possible values are `bottom` and `right`.
|
||||||
|
* The value `bottom` is used to denote vertical resizing.
|
||||||
|
* The value `right` is used to denote horizontal resizing.
|
||||||
|
|
||||||
#### Event: 'resize'
|
#### Event: 'resize'
|
||||||
|
|
||||||
Emitted after the window has been resized.
|
Emitted after the window has been resized.
|
||||||
|
|
|
@ -206,8 +206,15 @@ void BaseWindow::OnWindowRestore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseWindow::OnWindowWillResize(const gfx::Rect& new_bounds,
|
void BaseWindow::OnWindowWillResize(const gfx::Rect& new_bounds,
|
||||||
|
const gfx::ResizeEdge& edge,
|
||||||
bool* prevent_default) {
|
bool* prevent_default) {
|
||||||
if (Emit("will-resize", new_bounds)) {
|
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||||
|
v8::Locker locker(isolate);
|
||||||
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
gin_helper::Dictionary info = gin::Dictionary::CreateEmpty(isolate);
|
||||||
|
info.Set("edge", edge);
|
||||||
|
|
||||||
|
if (Emit("will-resize", new_bounds, info)) {
|
||||||
*prevent_default = true;
|
*prevent_default = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
|
||||||
void OnWindowMinimize() override;
|
void OnWindowMinimize() override;
|
||||||
void OnWindowRestore() override;
|
void OnWindowRestore() override;
|
||||||
void OnWindowWillResize(const gfx::Rect& new_bounds,
|
void OnWindowWillResize(const gfx::Rect& new_bounds,
|
||||||
|
const gfx::ResizeEdge& edge,
|
||||||
bool* prevent_default) override;
|
bool* prevent_default) override;
|
||||||
void OnWindowResize() override;
|
void OnWindowResize() override;
|
||||||
void OnWindowResized() override;
|
void OnWindowResized() override;
|
||||||
|
|
|
@ -480,9 +480,10 @@ void NativeWindow::NotifyWindowRestore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::NotifyWindowWillResize(const gfx::Rect& new_bounds,
|
void NativeWindow::NotifyWindowWillResize(const gfx::Rect& new_bounds,
|
||||||
|
const gfx::ResizeEdge& edge,
|
||||||
bool* prevent_default) {
|
bool* prevent_default) {
|
||||||
for (NativeWindowObserver& observer : observers_)
|
for (NativeWindowObserver& observer : observers_)
|
||||||
observer.OnWindowWillResize(new_bounds, prevent_default);
|
observer.OnWindowWillResize(new_bounds, edge, prevent_default);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::NotifyWindowWillMove(const gfx::Rect& new_bounds,
|
void NativeWindow::NotifyWindowWillMove(const gfx::Rect& new_bounds,
|
||||||
|
|
|
@ -32,6 +32,7 @@ class Image;
|
||||||
class Point;
|
class Point;
|
||||||
class Rect;
|
class Rect;
|
||||||
class RectF;
|
class RectF;
|
||||||
|
enum class ResizeEdge;
|
||||||
class Size;
|
class Size;
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
|
||||||
|
@ -275,6 +276,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
void NotifyWindowRestore();
|
void NotifyWindowRestore();
|
||||||
void NotifyWindowMove();
|
void NotifyWindowMove();
|
||||||
void NotifyWindowWillResize(const gfx::Rect& new_bounds,
|
void NotifyWindowWillResize(const gfx::Rect& new_bounds,
|
||||||
|
const gfx::ResizeEdge& edge,
|
||||||
bool* prevent_default);
|
bool* prevent_default);
|
||||||
void NotifyWindowResize();
|
void NotifyWindowResize();
|
||||||
void NotifyWindowResized();
|
void NotifyWindowResized();
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
class Rect;
|
class Rect;
|
||||||
}
|
enum class ResizeEdge;
|
||||||
|
} // namespace gfx
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ class NativeWindowObserver : public base::CheckedObserver {
|
||||||
virtual void OnWindowMinimize() {}
|
virtual void OnWindowMinimize() {}
|
||||||
virtual void OnWindowRestore() {}
|
virtual void OnWindowRestore() {}
|
||||||
virtual void OnWindowWillResize(const gfx::Rect& new_bounds,
|
virtual void OnWindowWillResize(const gfx::Rect& new_bounds,
|
||||||
|
const gfx::ResizeEdge& edge,
|
||||||
bool* prevent_default) {}
|
bool* prevent_default) {}
|
||||||
virtual void OnWindowResize() {}
|
virtual void OnWindowResize() {}
|
||||||
virtual void OnWindowResized() {}
|
virtual void OnWindowResized() {}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "ui/display/display.h"
|
#include "ui/display/display.h"
|
||||||
#include "ui/display/win/screen_win.h"
|
#include "ui/display/win/screen_win.h"
|
||||||
#include "ui/gfx/geometry/insets.h"
|
#include "ui/gfx/geometry/insets.h"
|
||||||
|
#include "ui/gfx/geometry/resize_utils.h"
|
||||||
#include "ui/views/widget/native_widget_private.h"
|
#include "ui/views/widget/native_widget_private.h"
|
||||||
|
|
||||||
// Must be included after other Windows headers.
|
// Must be included after other Windows headers.
|
||||||
|
@ -137,6 +138,31 @@ const char* AppCommandToString(int command_id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copied from ui/views/win/hwnd_message_handler.cc
|
||||||
|
gfx::ResizeEdge GetWindowResizeEdge(WPARAM param) {
|
||||||
|
switch (param) {
|
||||||
|
case WMSZ_BOTTOM:
|
||||||
|
return gfx::ResizeEdge::kBottom;
|
||||||
|
case WMSZ_TOP:
|
||||||
|
return gfx::ResizeEdge::kTop;
|
||||||
|
case WMSZ_LEFT:
|
||||||
|
return gfx::ResizeEdge::kLeft;
|
||||||
|
case WMSZ_RIGHT:
|
||||||
|
return gfx::ResizeEdge::kRight;
|
||||||
|
case WMSZ_TOPLEFT:
|
||||||
|
return gfx::ResizeEdge::kTopLeft;
|
||||||
|
case WMSZ_TOPRIGHT:
|
||||||
|
return gfx::ResizeEdge::kTopRight;
|
||||||
|
case WMSZ_BOTTOMLEFT:
|
||||||
|
return gfx::ResizeEdge::kBottomLeft;
|
||||||
|
case WMSZ_BOTTOMRIGHT:
|
||||||
|
return gfx::ResizeEdge::kBottomRight;
|
||||||
|
default:
|
||||||
|
NOTREACHED();
|
||||||
|
return gfx::ResizeEdge::kBottomRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IsScreenReaderActive() {
|
bool IsScreenReaderActive() {
|
||||||
UINT screenReader = 0;
|
UINT screenReader = 0;
|
||||||
SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenReader, 0);
|
SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenReader, 0);
|
||||||
|
@ -263,7 +289,8 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
|
||||||
gfx::Rect bounds = gfx::Rect(*reinterpret_cast<RECT*>(l_param));
|
gfx::Rect bounds = gfx::Rect(*reinterpret_cast<RECT*>(l_param));
|
||||||
HWND hwnd = GetAcceleratedWidget();
|
HWND hwnd = GetAcceleratedWidget();
|
||||||
gfx::Rect dpi_bounds = ScreenToDIPRect(hwnd, bounds);
|
gfx::Rect dpi_bounds = ScreenToDIPRect(hwnd, bounds);
|
||||||
NotifyWindowWillResize(dpi_bounds, &prevent_default);
|
NotifyWindowWillResize(dpi_bounds, GetWindowResizeEdge(w_param),
|
||||||
|
&prevent_default);
|
||||||
if (prevent_default) {
|
if (prevent_default) {
|
||||||
::GetWindowRect(hwnd, reinterpret_cast<RECT*>(l_param));
|
::GetWindowRect(hwnd, reinterpret_cast<RECT*>(l_param));
|
||||||
return true; // Tells Windows that the Sizing is handled.
|
return true; // Tells Windows that the Sizing is handled.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <Quartz/Quartz.h>
|
#include <Quartz/Quartz.h>
|
||||||
|
|
||||||
#include "components/remote_cocoa/app_shim/views_nswindow_delegate.h"
|
#include "components/remote_cocoa/app_shim/views_nswindow_delegate.h"
|
||||||
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
class NativeWindowMac;
|
class NativeWindowMac;
|
||||||
|
@ -20,6 +21,11 @@ class NativeWindowMac;
|
||||||
bool is_zooming_;
|
bool is_zooming_;
|
||||||
int level_;
|
int level_;
|
||||||
bool is_resizable_;
|
bool is_resizable_;
|
||||||
|
|
||||||
|
// Only valid during a live resize.
|
||||||
|
// Used to keep track of whether a resize is happening horizontally or
|
||||||
|
// vertically, even if physically the user is resizing in both directions.
|
||||||
|
absl::optional<bool> resizingHorizontally_;
|
||||||
}
|
}
|
||||||
- (id)initWithShell:(electron::NativeWindowMac*)shell;
|
- (id)initWithShell:(electron::NativeWindowMac*)shell;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "shell/browser/native_window_mac.h"
|
#include "shell/browser/native_window_mac.h"
|
||||||
#include "shell/browser/ui/cocoa/electron_preview_item.h"
|
#include "shell/browser/ui/cocoa/electron_preview_item.h"
|
||||||
#include "shell/browser/ui/cocoa/electron_touch_bar.h"
|
#include "shell/browser/ui/cocoa/electron_touch_bar.h"
|
||||||
|
#include "ui/gfx/geometry/resize_utils.h"
|
||||||
#include "ui/gfx/mac/coordinate_conversion.h"
|
#include "ui/gfx/mac/coordinate_conversion.h"
|
||||||
#include "ui/views/cocoa/native_widget_mac_ns_window_host.h"
|
#include "ui/views/cocoa/native_widget_mac_ns_window_host.h"
|
||||||
#include "ui/views/widget/native_widget_mac.h"
|
#include "ui/views/widget/native_widget_mac.h"
|
||||||
|
@ -140,11 +141,21 @@ using FullScreenTransitionState =
|
||||||
extraHeightPlusFrame);
|
extraHeightPlusFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!resizingHorizontally_) {
|
||||||
|
NSWindow* window = shell_->GetNativeWindow().GetNativeNSWindow();
|
||||||
|
const auto widthDelta = frameSize.width - [window frame].size.width;
|
||||||
|
const auto heightDelta = frameSize.height - [window frame].size.height;
|
||||||
|
resizingHorizontally_ = std::abs(widthDelta) > std::abs(heightDelta);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
bool prevent_default = false;
|
bool prevent_default = false;
|
||||||
NSRect new_bounds = NSMakeRect(sender.frame.origin.x, sender.frame.origin.y,
|
NSRect new_bounds = NSMakeRect(sender.frame.origin.x, sender.frame.origin.y,
|
||||||
newSize.width, newSize.height);
|
newSize.width, newSize.height);
|
||||||
shell_->NotifyWindowWillResize(gfx::ScreenRectFromNSRect(new_bounds),
|
shell_->NotifyWindowWillResize(gfx::ScreenRectFromNSRect(new_bounds),
|
||||||
|
*resizingHorizontally_
|
||||||
|
? gfx::ResizeEdge::kRight
|
||||||
|
: gfx::ResizeEdge::kBottom,
|
||||||
&prevent_default);
|
&prevent_default);
|
||||||
if (prevent_default) {
|
if (prevent_default) {
|
||||||
return sender.frame.size;
|
return sender.frame.size;
|
||||||
|
@ -204,6 +215,7 @@ using FullScreenTransitionState =
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidEndLiveResize:(NSNotification*)notification {
|
- (void)windowDidEndLiveResize:(NSNotification*)notification {
|
||||||
|
resizingHorizontally_.reset();
|
||||||
shell_->NotifyWindowResized();
|
shell_->NotifyWindowResized();
|
||||||
if (is_zooming_) {
|
if (is_zooming_) {
|
||||||
if (shell_->IsMaximized())
|
if (shell_->IsMaximized())
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "ui/gfx/geometry/point.h"
|
#include "ui/gfx/geometry/point.h"
|
||||||
#include "ui/gfx/geometry/point_f.h"
|
#include "ui/gfx/geometry/point_f.h"
|
||||||
#include "ui/gfx/geometry/rect.h"
|
#include "ui/gfx/geometry/rect.h"
|
||||||
|
#include "ui/gfx/geometry/resize_utils.h"
|
||||||
#include "ui/gfx/geometry/size.h"
|
#include "ui/gfx/geometry/size.h"
|
||||||
|
|
||||||
namespace gin {
|
namespace gin {
|
||||||
|
@ -160,4 +161,29 @@ v8::Local<v8::Value> Converter<display::Display>::ToV8(
|
||||||
return dict.GetHandle();
|
return dict.GetHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::Value> Converter<gfx::ResizeEdge>::ToV8(
|
||||||
|
v8::Isolate* isolate,
|
||||||
|
const gfx::ResizeEdge& val) {
|
||||||
|
switch (val) {
|
||||||
|
case gfx::ResizeEdge::kRight:
|
||||||
|
return StringToV8(isolate, "right");
|
||||||
|
case gfx::ResizeEdge::kBottom:
|
||||||
|
return StringToV8(isolate, "bottom");
|
||||||
|
case gfx::ResizeEdge::kTop:
|
||||||
|
return StringToV8(isolate, "top");
|
||||||
|
case gfx::ResizeEdge::kLeft:
|
||||||
|
return StringToV8(isolate, "left");
|
||||||
|
case gfx::ResizeEdge::kTopLeft:
|
||||||
|
return StringToV8(isolate, "top-left");
|
||||||
|
case gfx::ResizeEdge::kTopRight:
|
||||||
|
return StringToV8(isolate, "top-right");
|
||||||
|
case gfx::ResizeEdge::kBottomLeft:
|
||||||
|
return StringToV8(isolate, "bottom-left");
|
||||||
|
case gfx::ResizeEdge::kBottomRight:
|
||||||
|
return StringToV8(isolate, "bottom-right");
|
||||||
|
default:
|
||||||
|
return StringToV8(isolate, "unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace gin
|
} // namespace gin
|
||||||
|
|
|
@ -16,6 +16,7 @@ class Point;
|
||||||
class PointF;
|
class PointF;
|
||||||
class Size;
|
class Size;
|
||||||
class Rect;
|
class Rect;
|
||||||
|
enum class ResizeEdge;
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
|
||||||
namespace gin {
|
namespace gin {
|
||||||
|
@ -62,6 +63,12 @@ struct Converter<display::Display> {
|
||||||
display::Display* out);
|
display::Display* out);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<gfx::ResizeEdge> {
|
||||||
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const gfx::ResizeEdge& val);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace gin
|
} // namespace gin
|
||||||
|
|
||||||
#endif // SHELL_COMMON_GIN_CONVERTERS_GFX_CONVERTER_H_
|
#endif // SHELL_COMMON_GIN_CONVERTERS_GFX_CONVERTER_H_
|
||||||
|
|
Loading…
Reference in a new issue