Bug 1872997 - Remove "fit to screen" code in cocoa widget. r=mac-reviewers,bradwerth

No other platform does this. This comes from bug 413277, but positioning
windows (in particular popups) partially offscreen is desirable in some
cases (e.g., when drawing non-native shadows).

We have protections in place to prevent content from doing things like
what caused this code to be added.

Remove a cocoa-specific test for this, and tweak another test which has
a dependent window opened from an offscreen window, and the offscreen
window positioning happens right after the load event.

The window ends up on screen even without that tweak.

Differential Revision: https://phabricator.services.mozilla.com/D197903
This commit is contained in:
Emilio Cobos Álvarez 2024-01-08 19:46:13 +00:00
parent b18b3314a5
commit 59b776ccd4
5 changed files with 6 additions and 87 deletions

View File

@ -297,44 +297,6 @@ static NSScreen* FindTargetScreenForRect(const DesktopIntRect& aRect) {
return targetScreen;
}
// fits the rect to the screen that contains the largest area of it,
// or to aScreen if a screen is passed in
// NB: this operates with aRect in desktop pixels
static void FitRectToVisibleAreaForScreen(DesktopIntRect& aRect,
NSScreen* aScreen) {
if (!aScreen) {
aScreen = FindTargetScreenForRect(aRect);
}
DesktopIntRect screenBounds =
nsCocoaUtils::CocoaRectToGeckoRect([aScreen visibleFrame]);
if (aRect.width > screenBounds.width) {
aRect.width = screenBounds.width;
}
if (aRect.height > screenBounds.height) {
aRect.height = screenBounds.height;
}
if (aRect.x - screenBounds.x + aRect.width > screenBounds.width) {
aRect.x += screenBounds.width - (aRect.x - screenBounds.x + aRect.width);
}
if (aRect.y - screenBounds.y + aRect.height > screenBounds.height) {
aRect.y += screenBounds.height - (aRect.y - screenBounds.y + aRect.height);
}
// If the left/top edge of the window is off the screen in either direction,
// then set the window to start at the left/top edge of the screen.
if (aRect.x < screenBounds.x ||
aRect.x > (screenBounds.x + screenBounds.width)) {
aRect.x = screenBounds.x;
}
if (aRect.y < screenBounds.y ||
aRect.y > (screenBounds.y + screenBounds.height)) {
aRect.y = screenBounds.y;
}
}
DesktopToLayoutDeviceScale ParentBackingScaleFactor(nsIWidget* aParent,
NSView* aParentView) {
if (aParent) {
@ -392,9 +354,6 @@ nsresult nsCocoaWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
// we have to provide an autorelease pool (see bug 559075).
nsAutoreleasePool localPool;
DesktopIntRect newBounds = aRect;
FitRectToVisibleAreaForScreen(newBounds, nullptr);
// Set defaults which can be overriden from aInitData in BaseCreate
mWindowType = WindowType::TopLevel;
mBorderStyle = BorderStyle::Default;
@ -431,7 +390,7 @@ nsresult nsCocoaWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
// now we can convert widgetRect to device pixels for the window we created,
// as the child view expects a rect expressed in the dev pix of its parent
LayoutDeviceIntRect devRect =
RoundedToInt(newBounds * GetDesktopToDeviceScale());
RoundedToInt(aRect * GetDesktopToDeviceScale());
return CreatePopupContentView(devRect, aInitData);
}
@ -2166,10 +2125,6 @@ void nsCocoaWindow::DoResize(double aX, double aY, double aWidth,
NSToIntRound(width / scale),
NSToIntRound(height / scale));
// constrain to the screen that contains the largest area of the new rect
FitRectToVisibleAreaForScreen(
newBounds, aConstrainToCurrentScreen ? [mWindow screen] : nullptr);
// convert requested bounds into Cocoa coordinate system
NSRect newFrame = nsCocoaUtils::GeckoRectToCocoaRect(newBounds);

View File

@ -15,9 +15,6 @@ skip-if = ["os == 'win' && bits == 32"]
["test_bug343416.xhtml"]
skip-if = ["debug"]
["test_bug413277.html"]
skip-if = ["toolkit != 'cocoa'"] # Cocoa widget test
["test_bug428405.xhtml"]
skip-if = ["toolkit != 'cocoa'"] # Cocoa widget test

View File

@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=413277
-->
<head>
<title>Test for Bug 413277</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=413277">Mozilla Bug 413277</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="application/javascript">
var atts = "width=100, height=100, top=100, screenY=100";
atts += ", left=100, screenX=100, toolbar=no";
atts += ", location=no, directories=no, status=no";
atts += ", menubar=no, scrollbars=no, resizable=no";
var newWindow = window.open("_blank", "win_name", atts);
newWindow.resizeBy(1000000, 1000000);
SimpleTest.is(newWindow.outerWidth, newWindow.screen.availWidth, true);
SimpleTest.is(newWindow.outerHeight, newWindow.screen.availHeight, true);
SimpleTest.is(newWindow.screenY, newWindow.screen.availTop, true);
SimpleTest.is(newWindow.screenX, newWindow.screen.availLeft, true);
newWindow.close();
</script>
</pre>
</body>

View File

@ -16,8 +16,8 @@
function onload()
{
var SimpleTest = window.opener.SimpleTest;
SimpleTest.ok(window.screenX >= 0, "centerscreen window should not start offscreen (X coordinate)");
SimpleTest.ok(window.screenY >= 0, "centerscreen window should not start offscreen (Y coordinate)");
SimpleTest.ok(window.screenX >= 0, "centerscreen window should not start offscreen (X coordinate): " + window.screenX);
SimpleTest.ok(window.screenY >= 0, "centerscreen window should not start offscreen (Y coordinate): " + window.screenY);
window.opener.finished();
}
]]>

View File

@ -19,7 +19,9 @@ var finish = window.arguments[1];
function onLoad()
{
centerscreen = window.openDialog('window_bug593307_centerscreen.xhtml','', 'chrome,centerscreen,dependent,dialog=no');
setTimeout(() => {
centerscreen = window.openDialog('window_bug593307_centerscreen.xhtml','', 'chrome,centerscreen,dependent,dialog=no');
}, 0);
}
function finished() {