fix: use Chromium's way to compute min/max sizes (#38974)

This commit is contained in:
Cheng Zhao 2023-07-06 00:02:05 +09:00 committed by GitHub
parent 52fe76ca28
commit 3fa15ebb7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 397 deletions

View file

@ -78,6 +78,7 @@
#include "ui/display/screen.h"
#include "ui/display/win/screen_win.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/win/msg_util.h"
#endif
namespace electron {
@ -138,6 +139,25 @@ gfx::Rect DIPToScreenRect(HWND hwnd, const gfx::Rect& pixel_bounds) {
return screen_rect;
}
// Chromium uses a buggy implementation that converts content rect to window
// rect when calculating min/max size, we should use the same implementation
// when passing min/max size so we can get correct results.
gfx::Size WindowSizeToContentSizeBuggy(HWND hwnd, const gfx::Size& size) {
// Calculate the size of window frame, using same code with the
// HWNDMessageHandler::OnGetMinMaxInfo method.
// The pitfall is, when window is minimized the calculated window frame size
// will be different from other states.
RECT client_rect, rect;
GetClientRect(hwnd, &client_rect);
GetWindowRect(hwnd, &rect);
CR_DEFLATE_RECT(&rect, &client_rect);
// Convert DIP size to pixel size, do calculation and then return DIP size.
gfx::Rect screen_rect = DIPToScreenRect(hwnd, gfx::Rect(size));
gfx::Size screen_client_size(screen_rect.width() - (rect.right - rect.left),
screen_rect.height() - (rect.bottom - rect.top));
return ScreenToDIPRect(hwnd, gfx::Rect(screen_client_size)).size();
}
#endif
#if defined(USE_OZONE)
@ -812,6 +832,29 @@ void NativeWindowViews::SetContentSizeConstraints(
old_size_constraints_ = size_constraints;
}
#if BUILDFLAG(IS_WIN)
// This override does almost the same with its parent, except that it uses
// the WindowSizeToContentSizeBuggy method to convert window size to content
// size. See the comment of the method for the reason behind this.
extensions::SizeConstraints NativeWindowViews::GetContentSizeConstraints()
const {
if (content_size_constraints_)
return *content_size_constraints_;
if (!size_constraints_)
return extensions::SizeConstraints();
extensions::SizeConstraints constraints;
if (size_constraints_->HasMaximumSize()) {
constraints.set_maximum_size(WindowSizeToContentSizeBuggy(
GetAcceleratedWidget(), size_constraints_->GetMaximumSize()));
}
if (size_constraints_->HasMinimumSize()) {
constraints.set_minimum_size(WindowSizeToContentSizeBuggy(
GetAcceleratedWidget(), size_constraints_->GetMinimumSize()));
}
return constraints;
}
#endif
void NativeWindowViews::SetResizable(bool resizable) {
if (resizable != resizable_) {
// On Linux there is no "resizable" property of a window, we have to set