Fix window staggering and positioning to make sure new windows are never partly positioned offscreen and don't seeminly arbitrarily get larger by the size of the title bar. b=218214 r=mano r=cbarrett sr=roc a=roc

git-svn-id: svn://10.0.0.236/trunk@236037 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
joshmoz%gmail.com 2007-09-15 17:01:36 +00:00
parent 6511484952
commit b3669eefe2
4 changed files with 29 additions and 41 deletions

View File

@ -816,20 +816,13 @@ function BrowserStartup()
else {
// Create a narrower window for large or wide-aspect displays, to suggest
// side-by-side page view.
if ((screen.availWidth / 2) >= 800)
if (screen.availWidth >= 1600)
defaultWidth = (screen.availWidth / 2) - 20;
defaultHeight = screen.availHeight - 10;
#ifdef MOZ_WIDGET_GTK2
#define USE_HEIGHT_ADJUST
#endif
#ifdef USE_HEIGHT_ADJUST
// On X, we're not currently able to account for the size of the window
// border. Use 28px as a guess (titlebar + bottom window border)
defaultHeight -= 28;
#endif
#ifdef XP_MACOSX
// account for the Mac OS X title bar
defaultHeight -= 22;
#endif
}
document.documentElement.setAttribute("width", defaultWidth);

View File

@ -558,7 +558,8 @@ class nsIWidget : public nsISupports {
* Get this widget's outside dimensions in global coordinates. (One might think this
* could be accomplished by stringing together other methods in this interface, but
* then one would bloody one's nose on different coordinate system handling by different
* platforms.)
* platforms.) This includes any title bar on the window.
*
*
* @param aRect on return it holds the x, y, width and height of this widget
*

View File

@ -65,6 +65,12 @@ extern BOOL gSomeMenuBarPainted;
NS_IMPL_ISUPPORTS_INHERITED1(nsCocoaWindow, Inherited, nsPIWidgetCocoa)
// A note on testing to see if your object is a sheet...
// |mWindowType == eWindowType_sheet| is true if your gecko nsIWidget is a sheet
// widget - whether or not the sheet is showing. |[mWindow isSheet]| will return
// true *only when the sheet is actually showing*. Choose your test wisely.
// returns the height of the title bar for a given cocoa NSWindow
static float TitleBarHeightForWindow(NSWindow* aWindow)
{
@ -752,21 +758,10 @@ NS_IMETHODIMP nsCocoaWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRep
// width is easy, no adjusting necessary
newFrame.size.width = aWidth;
// Adjusting the height is harder.
// Note that [mWindow isSheet] is not the same as checking for
// |mWindowType == eWindowType_sheet|. If this is a sheet object, the latter
// will always be true. The former is true only when the sheet is being shown.
// Here we need to know if the sheet is actually being shown because if it is,
// the content view and the window's frame are equal, despite the fact that
// the native window object has the title bar flag set. If the window is not
// being shown as a sheet the content area and window frame differ.
float newHeight = (float)aHeight;
if (mWindowType != eWindowType_popup && ![mWindow isSheet])
newHeight += TitleBarHeightForWindow(mWindow); // add height of title bar
// Now we need to adjust for the fact that gecko wants the top of the window
// We need to adjust for the fact that gecko wants the top of the window
// to remain in the same place.
newFrame.origin.y += newFrame.size.height - newHeight;
newFrame.size.height = newHeight;
newFrame.origin.y += newFrame.size.height - aHeight;
newFrame.size.height = aHeight;
StartResizing();
[mWindow setFrame:newFrame display:NO];
@ -785,16 +780,13 @@ NS_IMETHODIMP nsCocoaWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRep
}
// We return the origin for the entire window (title bar and all) but
// the size of the content area. I have no idea why it was originally done
// this way, but it matches Carbon and makes things work nicely.
NS_IMETHODIMP nsCocoaWindow::GetScreenBounds(nsRect &aRect)
{
nsRect windowFrame = cocoaRectToGeckoRect([mWindow frame]);
aRect.x = windowFrame.x;
aRect.y = windowFrame.y;
aRect.width = mBounds.width;
aRect.height = mBounds.height;
aRect.width = windowFrame.width;
aRect.height = windowFrame.height;
// printf("GetScreenBounds: output: %d,%d,%d,%d\n", aRect.x, aRect.y, aRect.width, aRect.height);
return NS_OK;
}

View File

@ -1062,8 +1062,10 @@ PRBool nsXULWindow::LoadPositionFromXUL()
specX += parentX;
specY += parentY;
}
} else
}
else {
StaggerPosition(specX, specY, currWidth, currHeight);
}
}
mWindow->ConstrainPosition(PR_FALSE, &specX, &specY);
if (specX != currX || specY != currY)
@ -1256,8 +1258,7 @@ void nsXULWindow::StaggerPosition(PRInt32 &aRequestedX, PRInt32 &aRequestedY,
}
}
// one full pass through all windows of this type. repeat until
// no collisions.
// One full pass through all windows of this type, repeat until no collisions.
do {
keepTrying = PR_FALSE;
nsCOMPtr<nsISimpleEnumerator> windowList;
@ -1266,11 +1267,9 @@ void nsXULWindow::StaggerPosition(PRInt32 &aRequestedX, PRInt32 &aRequestedY,
if (!windowList)
break;
// one full pass through all windows of this type. offset and stop
// on collision.
// One full pass through all windows of this type, offset and stop on collision.
do {
PRBool more;
PRInt32 listX, listY;
windowList->HasMoreElements(&more);
if (!more)
break;
@ -1279,13 +1278,13 @@ void nsXULWindow::StaggerPosition(PRInt32 &aRequestedX, PRInt32 &aRequestedY,
windowList->GetNext(getter_AddRefs(supportsWindow));
nsCOMPtr<nsIXULWindow> listXULWindow(do_QueryInterface(supportsWindow));
nsCOMPtr<nsIBaseWindow> listBaseWindow(do_QueryInterface(supportsWindow));
if (listXULWindow != ourXULWindow) {
PRInt32 listX, listY;
nsCOMPtr<nsIBaseWindow> listBaseWindow(do_QueryInterface(supportsWindow));
listBaseWindow->GetPosition(&listX, &listY);
if (PR_ABS(listX-aRequestedX) <= kSlop &&
PR_ABS(listY-aRequestedY) <= kSlop) {
if (PR_ABS(listX - aRequestedX) <= kSlop &&
PR_ABS(listY - aRequestedY) <= kSlop) {
// collision! offset and start over
if (bouncedX & 0x1)
aRequestedX -= kOffset;
@ -1294,16 +1293,19 @@ void nsXULWindow::StaggerPosition(PRInt32 &aRequestedX, PRInt32 &aRequestedY,
aRequestedY += kOffset;
if (gotScreen) {
// bounce off left and right edges
if (!(bouncedX & 0x1) && aRequestedX + aSpecWidth > screenRight) {
// if we're moving to the right and we need to bounce...
if (!(bouncedX & 0x1) && ((aRequestedX + aSpecWidth) > screenRight)) {
aRequestedX = screenRight - aSpecWidth;
++bouncedX;
}
// if we're moving to the left and we need to bounce...
if ((bouncedX & 0x1) && aRequestedX < screenLeft) {
aRequestedX = screenLeft;
++bouncedX;
}
// hit the bottom and start again at the top
// if we hit the bottom then bounce to the top
if (aRequestedY + aSpecHeight > screenBottom) {
aRequestedY = screenTop;
++bouncedY;