mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
fix: accurate window sizing and support for content sizing on Linux/Wayland with CSD (#49209)
* fix window sizing and content sizing on Linux when CSD is in use * fixed size constraints * simplify min/max size calculation * use base window size for min/max * moved windows min/max size overrides * remove unnecessary checks for client frame * cleanup
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "shell/browser/ui/views/frameless_view.h"
|
||||
#include "shell/browser/ui/views/root_view.h"
|
||||
#include "shell/browser/web_contents_preferences.h"
|
||||
#include "shell/browser/web_view_manager.h"
|
||||
@@ -41,14 +42,19 @@
|
||||
#include "ui/base/hit_test.h"
|
||||
#include "ui/compositor/compositor.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/gfx/geometry/outsets.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/native_ui_types.h"
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/controls/webview/webview.h"
|
||||
#include "ui/views/view_utils.h"
|
||||
#include "ui/views/widget/native_widget_private.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/window/client_view.h"
|
||||
#include "ui/views/window/frame_view.h"
|
||||
#include "ui/views/window/non_client_view.h"
|
||||
#include "ui/wm/core/shadow_types.h"
|
||||
#include "ui/wm/core/window_util.h"
|
||||
|
||||
@@ -432,9 +438,12 @@ NativeWindowViews::NativeWindowViews(const int32_t base_window_id,
|
||||
window->AddPreTargetHandler(this);
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
// On linux after the widget is initialized we might have to force set the
|
||||
// bounds if the bounds are smaller than the current display
|
||||
SetBounds(gfx::Rect(GetPosition(), bounds.size()), false);
|
||||
// We need to set bounds again after widget init for two reasons:
|
||||
// 1. For CSD windows, user-specified bounds need to be inflated by frame
|
||||
// insets, but the frame view isn't available at first.
|
||||
// 2. The widget clamps bounds to fit the screen, but we want to allow
|
||||
// windows larger than the display.
|
||||
SetBounds(gfx::Rect(GetPosition(), size), false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -875,16 +884,14 @@ void NativeWindowViews::SetBounds(const gfx::Rect& bounds, bool animate) {
|
||||
}
|
||||
#endif
|
||||
|
||||
widget()->SetBounds(bounds);
|
||||
widget()->SetBounds(LogicalToWidgetBounds(bounds));
|
||||
}
|
||||
|
||||
gfx::Rect NativeWindowViews::GetBounds() const {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
if (IsMinimized())
|
||||
return widget()->GetRestoredBounds();
|
||||
#endif
|
||||
return WidgetToLogicalBounds(widget()->GetRestoredBounds());
|
||||
|
||||
return widget()->GetWindowBoundsInScreen();
|
||||
return WidgetToLogicalBounds(widget()->GetWindowBoundsInScreen());
|
||||
}
|
||||
|
||||
gfx::Rect NativeWindowViews::GetContentBounds() const {
|
||||
@@ -905,7 +912,7 @@ gfx::Rect NativeWindowViews::GetNormalBounds() const {
|
||||
if (IsMaximized() && transparent())
|
||||
return restore_bounds_;
|
||||
#endif
|
||||
return widget()->GetRestoredBounds();
|
||||
return WidgetToLogicalBounds(widget()->GetRestoredBounds());
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetContentSizeConstraints(
|
||||
@@ -1481,6 +1488,22 @@ gfx::NativeWindow NativeWindowViews::GetNativeWindow() const {
|
||||
return widget()->GetNativeWindow();
|
||||
}
|
||||
|
||||
gfx::Insets NativeWindowViews::GetRestoredFrameBorderInsets() const {
|
||||
auto* non_client_view = widget()->non_client_view();
|
||||
if (!non_client_view)
|
||||
return gfx::Insets();
|
||||
|
||||
auto* frame_view = non_client_view->frame_view();
|
||||
if (!frame_view)
|
||||
return gfx::Insets();
|
||||
|
||||
if (auto* frameless = views::AsViewClass<FramelessView>(frame_view)) {
|
||||
return frameless->RestoredFrameBorderInsets();
|
||||
}
|
||||
|
||||
return gfx::Insets();
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetProgressBar(double progress,
|
||||
NativeWindow::ProgressState state) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
@@ -1646,21 +1669,42 @@ NativeWindowHandle NativeWindowViews::GetNativeWindowHandle() const {
|
||||
return GetAcceleratedWidget();
|
||||
}
|
||||
|
||||
gfx::Rect NativeWindowViews::LogicalToWidgetBounds(
|
||||
const gfx::Rect& bounds) const {
|
||||
gfx::Rect widget_bounds(bounds);
|
||||
const gfx::Insets frame_insets = GetRestoredFrameBorderInsets();
|
||||
widget_bounds.Outset(
|
||||
gfx::Outsets::TLBR(frame_insets.top(), frame_insets.left(),
|
||||
frame_insets.bottom(), frame_insets.right()));
|
||||
|
||||
return widget_bounds;
|
||||
}
|
||||
|
||||
gfx::Rect NativeWindowViews::WidgetToLogicalBounds(
|
||||
const gfx::Rect& bounds) const {
|
||||
gfx::Rect logical_bounds(bounds);
|
||||
logical_bounds.Inset(GetRestoredFrameBorderInsets());
|
||||
return logical_bounds;
|
||||
}
|
||||
|
||||
gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
|
||||
const gfx::Rect& bounds) const {
|
||||
if (!has_frame())
|
||||
return bounds;
|
||||
|
||||
gfx::Rect window_bounds(bounds);
|
||||
|
||||
if (auto* ncv = widget()->non_client_view()) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
if (widget()->non_client_view()) {
|
||||
HWND hwnd = GetAcceleratedWidget();
|
||||
gfx::Rect dpi_bounds = DIPToScreenRect(hwnd, bounds);
|
||||
window_bounds = ScreenToDIPRect(
|
||||
hwnd, widget()->non_client_view()->GetWindowBoundsForClientBounds(
|
||||
dpi_bounds));
|
||||
}
|
||||
window_bounds =
|
||||
ScreenToDIPRect(hwnd, ncv->GetWindowBoundsForClientBounds(dpi_bounds));
|
||||
#else
|
||||
window_bounds = WidgetToLogicalBounds(
|
||||
ncv->GetWindowBoundsForClientBounds(window_bounds));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (root_view_.HasMenu() && root_view_.is_menu_bar_visible()) {
|
||||
int menu_bar_height = root_view_.GetMenuBarHeight();
|
||||
@@ -1687,6 +1731,10 @@ gfx::Rect NativeWindowViews::WindowBoundsToContentBounds(
|
||||
content_bounds.set_width(content_bounds.width() - (rect.right - rect.left));
|
||||
content_bounds.set_height(content_bounds.height() - (rect.bottom - rect.top));
|
||||
content_bounds.set_size(ScreenToDIPRect(hwnd, content_bounds).size());
|
||||
#else
|
||||
if (auto* frame_view = widget()->non_client_view()->frame_view()) {
|
||||
content_bounds = frame_view->GetBoundsForClientView();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (root_view_.HasMenu() && root_view_.is_menu_bar_visible()) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "shell/browser/ui/views/root_view.h"
|
||||
#include "third_party/abseil-cpp/absl/container/flat_hash_set.h"
|
||||
#include "ui/base/ozone_buildflags.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
|
||||
@@ -156,6 +157,12 @@ class NativeWindowViews : public NativeWindow,
|
||||
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override;
|
||||
gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override;
|
||||
|
||||
// Translates between logical/opaque window bounds exposed to callers
|
||||
// and the absolute bounds of the underlying widget, which can be larger to
|
||||
// fit CSD, e.g. transparent outer regions for shadows and resize targets.
|
||||
gfx::Rect LogicalToWidgetBounds(const gfx::Rect& bounds) const;
|
||||
gfx::Rect WidgetToLogicalBounds(const gfx::Rect& bounds) const;
|
||||
|
||||
void IncrementChildModals();
|
||||
void DecrementChildModals();
|
||||
|
||||
@@ -205,6 +212,8 @@ class NativeWindowViews : public NativeWindow,
|
||||
overlay_symbol_color_ = color;
|
||||
}
|
||||
|
||||
gfx::Insets GetRestoredFrameBorderInsets() const;
|
||||
|
||||
// views::WidgetObserver:
|
||||
void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
|
||||
void OnWidgetBoundsChanged(views::Widget* widget,
|
||||
|
||||
@@ -53,10 +53,11 @@ void ElectronDesktopWindowTreeHostLinux::OnWidgetInitDone() {
|
||||
UpdateFrameHints();
|
||||
}
|
||||
|
||||
bool ElectronDesktopWindowTreeHostLinux::IsShowingFrame() const {
|
||||
return !native_window_view_->IsFullscreen() &&
|
||||
!native_window_view_->IsMaximized() &&
|
||||
!native_window_view_->IsMinimized();
|
||||
bool ElectronDesktopWindowTreeHostLinux::IsShowingFrame(
|
||||
ui::PlatformWindowState window_state) const {
|
||||
return window_state != ui::PlatformWindowState::kFullScreen &&
|
||||
window_state != ui::PlatformWindowState::kMaximized &&
|
||||
window_state != ui::PlatformWindowState::kMinimized;
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::SetWindowIcons(
|
||||
@@ -80,7 +81,7 @@ void ElectronDesktopWindowTreeHostLinux::Show(
|
||||
gfx::Insets ElectronDesktopWindowTreeHostLinux::CalculateInsetsInDIP(
|
||||
ui::PlatformWindowState window_state) const {
|
||||
// If we are not showing frame, the insets should be zero.
|
||||
if (!IsShowingFrame()) {
|
||||
if (!IsShowingFrame(window_state)) {
|
||||
return gfx::Insets();
|
||||
}
|
||||
|
||||
@@ -88,9 +89,7 @@ gfx::Insets ElectronDesktopWindowTreeHostLinux::CalculateInsetsInDIP(
|
||||
if (!view)
|
||||
return {};
|
||||
|
||||
gfx::Insets insets = view->RestoredMirroredFrameBorderInsets();
|
||||
if (base::i18n::IsRTL())
|
||||
insets.set_left_right(insets.right(), insets.left());
|
||||
gfx::Insets insets = view->RestoredFrameBorderInsets();
|
||||
return insets;
|
||||
}
|
||||
|
||||
@@ -207,7 +206,7 @@ void ElectronDesktopWindowTreeHostLinux::UpdateFrameHints() {
|
||||
if (ui::OzonePlatform::GetInstance()->IsWindowCompositingSupported()) {
|
||||
// Set the opaque region.
|
||||
std::vector<gfx::Rect> opaque_region;
|
||||
if (IsShowingFrame()) {
|
||||
if (IsShowingFrame(window_state)) {
|
||||
// The opaque region is a list of rectangles that contain only fully
|
||||
// opaque pixels of the window. We need to convert the clipping
|
||||
// rounded-rect into this format.
|
||||
|
||||
@@ -74,7 +74,7 @@ class ElectronDesktopWindowTreeHostLinux
|
||||
private:
|
||||
void UpdateWindowState(ui::PlatformWindowState new_state);
|
||||
|
||||
bool IsShowingFrame() const;
|
||||
bool IsShowingFrame(ui::PlatformWindowState window_state) const;
|
||||
|
||||
gfx::ImageSkia saved_window_icon_;
|
||||
|
||||
|
||||
@@ -142,13 +142,6 @@ void ClientFrameViewLinux::Init(NativeWindowViews* window,
|
||||
UpdateThemeValues();
|
||||
}
|
||||
|
||||
gfx::Insets ClientFrameViewLinux::RestoredMirroredFrameBorderInsets() const {
|
||||
auto border = RestoredFrameBorderInsets();
|
||||
return base::i18n::IsRTL() ? gfx::Insets::TLBR(border.top(), border.right(),
|
||||
border.bottom(), border.left())
|
||||
: border;
|
||||
}
|
||||
|
||||
gfx::Insets ClientFrameViewLinux::RestoredFrameBorderInsets() const {
|
||||
gfx::Insets insets = GetFrameProvider()->GetFrameThicknessDip();
|
||||
const gfx::Insets input = GetInputInsets();
|
||||
@@ -163,7 +156,9 @@ gfx::Insets ClientFrameViewLinux::RestoredFrameBorderInsets() const {
|
||||
merged.set_bottom(expand_if_visible(insets.bottom(), input.bottom()));
|
||||
merged.set_right(expand_if_visible(insets.right(), input.right()));
|
||||
|
||||
return merged;
|
||||
return base::i18n::IsRTL() ? gfx::Insets::TLBR(merged.top(), merged.right(),
|
||||
merged.bottom(), merged.left())
|
||||
: merged;
|
||||
}
|
||||
|
||||
gfx::Insets ClientFrameViewLinux::GetInputInsets() const {
|
||||
@@ -174,7 +169,7 @@ gfx::Insets ClientFrameViewLinux::GetInputInsets() const {
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetWindowContentBounds() const {
|
||||
gfx::Rect content_bounds = bounds();
|
||||
content_bounds.Inset(RestoredMirroredFrameBorderInsets());
|
||||
content_bounds.Inset(RestoredFrameBorderInsets());
|
||||
return content_bounds;
|
||||
}
|
||||
|
||||
@@ -208,13 +203,13 @@ void ClientFrameViewLinux::OnWindowButtonOrderingChange() {
|
||||
}
|
||||
|
||||
int ClientFrameViewLinux::ResizingBorderHitTest(const gfx::Point& point) {
|
||||
return ResizingBorderHitTestImpl(point, RestoredMirroredFrameBorderInsets());
|
||||
return ResizingBorderHitTestImpl(point, RestoredFrameBorderInsets());
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetBoundsForClientView() const {
|
||||
gfx::Rect client_bounds = bounds();
|
||||
if (!frame_->IsFullscreen()) {
|
||||
client_bounds.Inset(RestoredMirroredFrameBorderInsets());
|
||||
client_bounds.Inset(RestoredFrameBorderInsets());
|
||||
client_bounds.Inset(
|
||||
gfx::Insets::TLBR(GetTitlebarBounds().height(), 0, 0, 0));
|
||||
}
|
||||
@@ -268,20 +263,6 @@ void ClientFrameViewLinux::SizeConstraintsChanged() {
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
gfx::Size ClientFrameViewLinux::CalculatePreferredSize(
|
||||
const views::SizeBounds& available_size) const {
|
||||
return SizeWithDecorations(
|
||||
FramelessView::CalculatePreferredSize(available_size));
|
||||
}
|
||||
|
||||
gfx::Size ClientFrameViewLinux::GetMinimumSize() const {
|
||||
return SizeWithDecorations(FramelessView::GetMinimumSize());
|
||||
}
|
||||
|
||||
gfx::Size ClientFrameViewLinux::GetMaximumSize() const {
|
||||
return SizeWithDecorations(FramelessView::GetMaximumSize());
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::Layout(PassKey) {
|
||||
LayoutSuperclass<FramelessView>(this);
|
||||
|
||||
@@ -474,7 +455,7 @@ gfx::Rect ClientFrameViewLinux::GetTitlebarBounds() const {
|
||||
std::max(font_height, theme_values_.titlebar_min_height) +
|
||||
GetTitlebarContentInsets().height();
|
||||
|
||||
gfx::Insets decoration_insets = RestoredMirroredFrameBorderInsets();
|
||||
gfx::Insets decoration_insets = RestoredFrameBorderInsets();
|
||||
|
||||
// We add the inset height here, so the .Inset() that follows won't reduce it
|
||||
// to be too small.
|
||||
@@ -493,15 +474,6 @@ gfx::Rect ClientFrameViewLinux::GetTitlebarContentBounds() const {
|
||||
titlebar.Inset(GetTitlebarContentInsets());
|
||||
return titlebar;
|
||||
}
|
||||
|
||||
gfx::Size ClientFrameViewLinux::SizeWithDecorations(gfx::Size size) const {
|
||||
gfx::Insets decoration_insets = RestoredMirroredFrameBorderInsets();
|
||||
|
||||
size.Enlarge(0, GetTitlebarBounds().height());
|
||||
size.Enlarge(decoration_insets.width(), decoration_insets.height());
|
||||
return size;
|
||||
}
|
||||
|
||||
views::View* ClientFrameViewLinux::TargetForRect(views::View* root,
|
||||
const gfx::Rect& rect) {
|
||||
return views::FrameView::TargetForRect(root, rect);
|
||||
|
||||
@@ -42,9 +42,9 @@ class ClientFrameViewLinux : public FramelessView,
|
||||
|
||||
void Init(NativeWindowViews* window, views::Widget* frame) override;
|
||||
|
||||
// These are here for ElectronDesktopWindowTreeHostLinux to use.
|
||||
gfx::Insets RestoredMirroredFrameBorderInsets() const;
|
||||
gfx::Insets RestoredFrameBorderInsets() const;
|
||||
// FramelessView:
|
||||
gfx::Insets RestoredFrameBorderInsets() const override;
|
||||
|
||||
gfx::Insets GetInputInsets() const;
|
||||
gfx::Rect GetWindowContentBounds() const;
|
||||
SkRRect GetRoundedWindowContentBounds() const;
|
||||
@@ -74,10 +74,6 @@ class ClientFrameViewLinux : public FramelessView,
|
||||
void SizeConstraintsChanged() override;
|
||||
|
||||
// Overridden from View:
|
||||
gfx::Size CalculatePreferredSize(
|
||||
const views::SizeBounds& available_size) const override;
|
||||
gfx::Size GetMinimumSize() const override;
|
||||
gfx::Size GetMaximumSize() const override;
|
||||
void Layout(PassKey) override;
|
||||
void OnPaint(gfx::Canvas* canvas) override;
|
||||
|
||||
@@ -127,8 +123,6 @@ class ClientFrameViewLinux : public FramelessView,
|
||||
gfx::Insets GetTitlebarContentInsets() const;
|
||||
gfx::Rect GetTitlebarContentBounds() const;
|
||||
|
||||
gfx::Size SizeWithDecorations(gfx::Size size) const;
|
||||
|
||||
raw_ptr<ui::NativeTheme> theme_;
|
||||
ThemeValues theme_values_;
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@ void FramelessView::Init(NativeWindowViews* window, views::Widget* frame) {
|
||||
frame_ = frame;
|
||||
}
|
||||
|
||||
gfx::Insets FramelessView::RestoredFrameBorderInsets() const {
|
||||
return gfx::Insets();
|
||||
}
|
||||
|
||||
int FramelessView::ResizingBorderHitTest(const gfx::Point& point) {
|
||||
return ResizingBorderHitTestImpl(point, gfx::Insets(kResizeInsideBoundsSize));
|
||||
}
|
||||
@@ -108,16 +112,16 @@ gfx::Size FramelessView::CalculatePreferredSize(
|
||||
}
|
||||
|
||||
gfx::Size FramelessView::GetMinimumSize() const {
|
||||
return window_->GetContentMinimumSize();
|
||||
if (!window_)
|
||||
return gfx::Size();
|
||||
return window_->GetMinimumSize();
|
||||
}
|
||||
|
||||
gfx::Size FramelessView::GetMaximumSize() const {
|
||||
gfx::Size size = window_->GetContentMaximumSize();
|
||||
// Electron public APIs returns (0, 0) when maximum size is not set, but it
|
||||
// would break internal window APIs like HWNDMessageHandler::SetAspectRatio.
|
||||
return size.IsEmpty() ? gfx::Size(INT_MAX, INT_MAX) : size;
|
||||
if (!window_)
|
||||
return gfx::Size();
|
||||
return window_->GetMaximumSize();
|
||||
}
|
||||
|
||||
BEGIN_METADATA(FramelessView)
|
||||
END_METADATA
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "ui/base/metadata/metadata_header_macros.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/views/window/non_client_view.h"
|
||||
|
||||
namespace views {
|
||||
@@ -37,6 +38,10 @@ class FramelessView : public views::FrameView {
|
||||
// and forces a re-layout and re-paint.
|
||||
virtual void InvalidateCaptionButtons() {}
|
||||
|
||||
// Any insets from the (transparent) widget bounds to the logical/opaque
|
||||
// bounds of the view, used for CSD and resize targets on some platforms.
|
||||
virtual gfx::Insets RestoredFrameBorderInsets() const;
|
||||
|
||||
NativeWindowViews* window() const { return window_; }
|
||||
views::Widget* frame() const { return frame_; }
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ class OpaqueFrameView : public FramelessView {
|
||||
void Init(NativeWindowViews* window, views::Widget* frame) override;
|
||||
int ResizingBorderHitTest(const gfx::Point& point) override;
|
||||
void InvalidateCaptionButtons() override;
|
||||
gfx::Insets RestoredFrameBorderInsets() const override;
|
||||
|
||||
// views::FrameView:
|
||||
gfx::Rect GetBoundsForClientView() const override;
|
||||
@@ -99,11 +100,6 @@ class OpaqueFrameView : public FramelessView {
|
||||
// rather than having extra vertical space above the tabs.
|
||||
bool IsFrameCondensed() const;
|
||||
|
||||
// The insets from the native window edge to the client view when the window
|
||||
// is restored. This goes all the way to the web contents on the left, right,
|
||||
// and bottom edges.
|
||||
gfx::Insets RestoredFrameBorderInsets() const;
|
||||
|
||||
// The insets from the native window edge to the flat portion of the
|
||||
// window border. That is, this function returns the "3D portion" of the
|
||||
// border when the window is restored. The returned insets will not be larger
|
||||
|
||||
@@ -274,6 +274,21 @@ bool WinFrameView::GetShouldPaintAsActive() {
|
||||
return ShouldPaintAsActive();
|
||||
}
|
||||
|
||||
gfx::Size WinFrameView::GetMinimumSize() const {
|
||||
// Chromium expects minimum size to be in content dimensions on Windows
|
||||
// because it adds the frame border automatically in OnGetMinMaxInfo.
|
||||
return window_->GetContentMinimumSize();
|
||||
}
|
||||
|
||||
gfx::Size WinFrameView::GetMaximumSize() const {
|
||||
// Chromium expects minimum size to be in content dimensions on Windows
|
||||
// because it adds the frame border automatically in OnGetMinMaxInfo.
|
||||
gfx::Size size = window_->GetContentMaximumSize();
|
||||
// Electron public APIs returns (0, 0) when maximum size is not set, but it
|
||||
// would break internal window APIs like HWNDMessageHandler::SetAspectRatio.
|
||||
return size.IsEmpty() ? gfx::Size(INT_MAX, INT_MAX) : size;
|
||||
}
|
||||
|
||||
BEGIN_METADATA(WinFrameView)
|
||||
END_METADATA
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ class WinFrameView : public FramelessView {
|
||||
gfx::Rect GetWindowBoundsForClientBounds(
|
||||
const gfx::Rect& client_bounds) const override;
|
||||
int NonClientHitTest(const gfx::Point& point) override;
|
||||
gfx::Size GetMinimumSize() const override;
|
||||
gfx::Size GetMaximumSize() const override;
|
||||
|
||||
WinCaptionButtonContainer* caption_button_container() {
|
||||
return caption_button_container_;
|
||||
|
||||
Reference in New Issue
Block a user