Bug 1809430 - Clean up ClientToWindowRect. r=cmartin,mstange

Make it return a margin from client area to window area, and add an
explicit function to get the size difference.

No behavior change.

Depends on D166428

Differential Revision: https://phabricator.services.mozilla.com/D166431
This commit is contained in:
Emilio Cobos Álvarez 2023-01-16 23:35:34 +00:00
Родитель 58fca810d3
Коммит 5077bb750f
9 изменённых файлов: 59 добавлений и 49 удалений

Просмотреть файл

@ -869,16 +869,19 @@ void nsContainerFrame::SetSizeConstraints(nsPresContext* aPresContext,
// The sizes are in inner window sizes, so convert them into outer window
// sizes. Use a size of (200, 200) as only the difference between the inner
// and outer size is needed.
LayoutDeviceIntSize windowSize =
aWidget->ClientToWindowSize(LayoutDeviceIntSize(200, 200));
if (constraints.mMinSize.width)
constraints.mMinSize.width += windowSize.width - 200;
if (constraints.mMinSize.height)
constraints.mMinSize.height += windowSize.height - 200;
if (constraints.mMaxSize.width != NS_MAXSIZE)
constraints.mMaxSize.width += windowSize.width - 200;
if (constraints.mMaxSize.height != NS_MAXSIZE)
constraints.mMaxSize.height += windowSize.height - 200;
const LayoutDeviceIntSize sizeDiff = aWidget->ClientToWindowSizeDifference();
if (constraints.mMinSize.width) {
constraints.mMinSize.width += sizeDiff.width;
}
if (constraints.mMinSize.height) {
constraints.mMinSize.height += sizeDiff.height;
}
if (constraints.mMaxSize.width != NS_MAXSIZE) {
constraints.mMaxSize.width += sizeDiff.width;
}
if (constraints.mMaxSize.height != NS_MAXSIZE) {
constraints.mMaxSize.height += sizeDiff.height;
}
aWidget->SetSizeConstraints(constraints);
}

Просмотреть файл

@ -249,7 +249,7 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
virtual void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
virtual LayoutDeviceIntPoint WidgetToScreenOffset() override;
virtual LayoutDeviceIntPoint GetClientOffset() override;
virtual LayoutDeviceIntSize ClientToWindowSize(const LayoutDeviceIntSize& aClientSize) override;
virtual LayoutDeviceIntMargin ClientToWindowMargin() override;
virtual void* GetNativeData(uint32_t aDataType) override;

Просмотреть файл

@ -2224,22 +2224,23 @@ LayoutDeviceIntPoint nsCocoaWindow::GetClientOffset() {
NS_OBJC_END_TRY_BLOCK_RETURN(LayoutDeviceIntPoint(0, 0));
}
LayoutDeviceIntSize nsCocoaWindow::ClientToWindowSize(const LayoutDeviceIntSize& aClientSize) {
LayoutDeviceIntMargin nsCocoaWindow::ClientToWindowMargin() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (!mWindow) {
return LayoutDeviceIntSize(0, 0);
return {};
}
NSRect clientNSRect = [mWindow contentLayoutRect];
NSRect frameNSRect = [mWindow frameRectForContentRect:clientNSRect];
CGFloat backingScale = BackingScaleFactor();
LayoutDeviceIntRect r(0, 0, aClientSize.width, aClientSize.height);
NSRect rect = nsCocoaUtils::DevPixelsToCocoaPoints(r, backingScale);
const auto clientRect = nsCocoaUtils::CocoaRectToGeckoRectDevPix(clientNSRect, backingScale);
const auto frameRect = nsCocoaUtils::CocoaRectToGeckoRectDevPix(frameNSRect, backingScale);
NSRect maybeInflatedRect = [mWindow frameRectForContentRect:rect];
r = nsCocoaUtils::CocoaRectToGeckoRectDevPix(maybeInflatedRect, backingScale);
return r.Size();
return frameRect - clientRect;
NS_OBJC_END_TRY_BLOCK_RETURN(LayoutDeviceIntSize(0, 0));
NS_OBJC_END_TRY_BLOCK_RETURN({});
}
nsMenuBarX* nsCocoaWindow::GetMenuBar() { return mMenuBar; }

Просмотреть файл

@ -567,6 +567,15 @@ nsIntSize nsIWidget::CustomCursorSize(const Cursor& aCursor) {
return {width, height};
}
LayoutDeviceIntSize nsIWidget::ClientToWindowSizeDifference() {
auto margin = ClientToWindowMargin();
MOZ_ASSERT(margin.top >= 0, "Window should be bigger than client area");
MOZ_ASSERT(margin.left >= 0, "Window should be bigger than client area");
MOZ_ASSERT(margin.right >= 0, "Window should be bigger than client area");
MOZ_ASSERT(margin.bottom >= 0, "Window should be bigger than client area");
return {margin.LeftRight(), margin.TopBottom()};
}
RefPtr<mozilla::VsyncDispatcher> nsIWidget::GetVsyncDispatcher() {
return nullptr;
}

Просмотреть файл

@ -365,11 +365,6 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
nsPopupLevel PopupLevel() { return mPopupLevel; }
LayoutDeviceIntSize ClientToWindowSize(
const LayoutDeviceIntSize& aClientSize) override {
return aClientSize;
}
// return true if this is a popup widget with a native titlebar
bool IsPopupWithTitleBar() const {
return (mWindowType == eWindowType_popup &&

Просмотреть файл

@ -1329,12 +1329,13 @@ class nsIWidget : public nsISupports {
}
/**
* Given the specified client size, return the corresponding window size,
* which includes the area for the borders and titlebar. This method
* should work even when the window is not yet visible.
* Returns the margins that are applied to go from client sizes to window
* sizes (which includes window borders and titlebar).
* This method should work even when the window is not yet visible.
*/
virtual LayoutDeviceIntSize ClientToWindowSize(
const LayoutDeviceIntSize& aClientSize) = 0;
virtual LayoutDeviceIntMargin ClientToWindowMargin() { return {}; }
LayoutDeviceIntSize ClientToWindowSizeDifference();
/**
* Dispatches an event to the widget

Просмотреть файл

@ -3871,27 +3871,31 @@ LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() {
return LayoutDeviceIntPoint(point.x, point.y);
}
LayoutDeviceIntSize nsWindow::ClientToWindowSize(
const LayoutDeviceIntSize& aClientSize) {
LayoutDeviceIntMargin nsWindow::ClientToWindowMargin() {
if (mWindowType == eWindowType_popup && !IsPopupWithTitleBar()) {
return aClientSize;
return {};
}
// Just use (200, 200) as the position
const LayoutDeviceIntPoint point(200, 200);
if (mCustomNonClient) {
auto winRect = LayoutDeviceIntRect(point, aClientSize);
winRect.Inflate(NonClientSizeMargin(NormalWindowNonClientOffset()));
return winRect.Size();
return NonClientSizeMargin(NormalWindowNonClientOffset());
}
RECT r;
r.left = point.x;
r.top = point.y;
r.right = point.x + aClientSize.width;
r.bottom = point.y + aClientSize.height;
::AdjustWindowRectEx(&r, WindowStyle(), false, WindowExStyle());
return LayoutDeviceIntSize(r.right - r.left, r.bottom - r.top);
// Just use a dummy 200x200 at (200, 200) client rect as the rect.
RECT clientRect;
clientRect.left = 200;
clientRect.top = 200;
clientRect.right = 400;
clientRect.bottom = 400;
auto ToRect = [](const RECT& aRect) -> LayoutDeviceIntRect {
return {aRect.left, aRect.top, aRect.right - aRect.left,
aRect.bottom - aRect.top};
};
RECT windowRect = clientRect;
::AdjustWindowRectEx(&windowRect, WindowStyle(), false, WindowExStyle());
return ToRect(windowRect) - ToRect(clientRect);
}
/**************************************************************

Просмотреть файл

@ -223,8 +223,7 @@ class nsWindow final : public nsBaseWidget {
nsresult SetTitle(const nsAString& aTitle) override;
void SetIcon(const nsAString& aIconSpec) override;
LayoutDeviceIntPoint WidgetToScreenOffset() override;
LayoutDeviceIntSize ClientToWindowSize(
const LayoutDeviceIntSize& aClientSize) override;
LayoutDeviceIntMargin ClientToWindowMargin() override;
nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
nsEventStatus& aStatus) override;
void EnableDragDrop(bool aEnable) override;

Просмотреть файл

@ -437,9 +437,7 @@ static LayoutDeviceIntSize GetOuterToInnerSizeDifference(nsIWidget* aWindow) {
if (!aWindow) {
return LayoutDeviceIntSize();
}
LayoutDeviceIntSize baseSize(200, 200);
LayoutDeviceIntSize windowSize = aWindow->ClientToWindowSize(baseSize);
return windowSize - baseSize;
return aWindow->ClientToWindowSizeDifference();
}
static CSSIntSize GetOuterToInnerSizeDifferenceInCSSPixels(