Sanitize/optimize Cocoa nsIWidget move and resize implementations. Don't do drawing we don't need to, don't call setFrame: more than once when we don't need to, general cleanup and null checks. b=402176 r=vlad sr=roc

This commit is contained in:
joshmoz@gmail.com 2007-11-06 23:36:10 -08:00
parent 5168792afe
commit 941546e1c9
3 changed files with 93 additions and 85 deletions

View File

@ -239,7 +239,6 @@ public:
NS_IMETHOD ConstrainPosition(PRBool aAllowSlop,
PRInt32 *aX, PRInt32 *aY);
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
NS_IMETHOD MoveWithRepaintOption(PRInt32 aX, PRInt32 aY, PRBool aRepaint);
NS_IMETHOD Resize(PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint);
NS_IMETHOD Resize(PRInt32 aX, PRInt32 aY,PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint);

View File

@ -804,66 +804,74 @@ NS_IMETHODIMP nsChildView::ConstrainPosition(PRBool aAllowSlop,
// Move this component, aX and aY are in the parent widget coordinate system
NS_IMETHODIMP nsChildView::Move(PRInt32 aX, PRInt32 aY)
{
return MoveWithRepaintOption(aX, aY, PR_TRUE);
}
if (!mView || (mBounds.x == aX && mBounds.y == aY))
return NS_OK;
mBounds.x = aX;
mBounds.y = aY;
NS_IMETHODIMP nsChildView::MoveWithRepaintOption(PRInt32 aX, PRInt32 aY, PRBool aRepaint)
{
if ((mBounds.x != aX) || (mBounds.y != aY)) {
// Invalidate the current location
if (mVisible && aRepaint)
[[mView superview] setNeedsDisplayInRect: [mView frame]]; //XXX needed?
// Set the bounds
mBounds.x = aX;
mBounds.y = aY;
NSRect r;
GeckoRectToNSRect(mBounds, r);
[mView setFrame:r];
NSRect r;
GeckoRectToNSRect(mBounds, r);
[mView setFrame:r];
if (mVisible && aRepaint)
[mView setNeedsDisplay:YES];
if (mVisible)
[mView setNeedsDisplay:YES];
ReportMoveEvent();
// Report the event
ReportMoveEvent();
}
return NS_OK;
}
// Resize this component
NS_IMETHODIMP nsChildView::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{
if ((mBounds.width != aWidth) || (mBounds.height != aHeight)) {
// Set the bounds
mBounds.width = aWidth;
mBounds.height = aHeight;
if (!mView || (mBounds.width == aWidth && mBounds.height == aHeight))
return NS_OK;
if (mVisible && aRepaint)
[[mView superview] setNeedsDisplayInRect: [mView frame]]; //XXX needed?
NSRect r;
GeckoRectToNSRect(mBounds, r);
[mView setFrame:r];
mBounds.width = aWidth;
mBounds.height = aHeight;
if (mVisible && aRepaint)
[mView setNeedsDisplay:YES];
NSRect r;
GeckoRectToNSRect(mBounds, r);
[mView setFrame:r];
if (mVisible && aRepaint)
[mView setNeedsDisplay:YES];
ReportSizeEvent();
// Report the event
ReportSizeEvent();
}
return NS_OK;
}
// Resize this component
NS_IMETHODIMP nsChildView::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{
MoveWithRepaintOption(aX, aY, aRepaint);
Resize(aWidth, aHeight, aRepaint);
BOOL isMoving = (mBounds.x != aX || mBounds.y != aY);
BOOL isResizing = (mBounds.width != aWidth || mBounds.height != aHeight);
if (!mView || (!isMoving && !isResizing))
return NS_OK;
if (isMoving) {
mBounds.x = aX;
mBounds.y = aY;
}
if (isResizing) {
mBounds.width = aWidth;
mBounds.height = aHeight;
}
NSRect r;
GeckoRectToNSRect(mBounds, r);
[mView setFrame:r];
if (mVisible && aRepaint)
[mView setNeedsDisplay:YES];
if (isMoving)
ReportMoveEvent();
if (isResizing)
ReportSizeEvent();
return NS_OK;
}

View File

@ -691,39 +691,31 @@ NS_IMETHODIMP nsCocoaWindow::ConstrainPosition(PRBool aAllowSlop,
NS_IMETHODIMP nsCocoaWindow::Move(PRInt32 aX, PRInt32 aY)
{
if (mWindow) {
// if we're a popup, we have to convert from our parent widget's coord
// system to the global coord system first because the (x,y) we're given
// is in its coordinate system.
if (mWindowType == eWindowType_popup) {
nsRect localRect, globalRect;
localRect.x = aX;
localRect.y = aY;
if (mParent) {
mParent->WidgetToScreen(localRect,globalRect);
aX=globalRect.x;
aY=globalRect.y;
}
}
// the point we have is in Gecko coordinates (origin top-left). Convert
// it to Cocoa ones (origin bottom-left).
NSPoint coord = {aX, FlippedScreenY(aY)};
{
if (!mWindow || (mBounds.x == aX && mBounds.y == aY))
return NS_OK;
//printf("final coords %f %f\n", coord.x, coord.y);
//printf("- window coords before %f %f\n", [mWindow frame].origin.x, [mWindow frame].origin.y);
[mWindow setFrameTopLeftPoint:coord];
//printf("- window coords after %f %f\n", [mWindow frame].origin.x, [mWindow frame].origin.y);
// if we're a popup, we have to convert from our parent widget's coord
// system to the global coord system first because the (x,y) we're given
// is in its coordinate system.
if (mParent && mWindowType == eWindowType_popup) {
nsRect globalRect;
nsRect localRect(aX, aY, 0, 0);
mParent->WidgetToScreen(localRect, globalRect);
aX = globalRect.x;
aY = globalRect.y;
}
// The point we have is in Gecko coordinates (origin top-left). Convert
// it to Cocoa ones (origin bottom-left).
NSPoint coord = {aX, FlippedScreenY(aY)};
[mWindow setFrameTopLeftPoint:coord];
return NS_OK;
}
//
// Position the window behind the given window
//
NS_METHOD nsCocoaWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
nsIWidget *aWidget, PRBool aActivate)
{
@ -762,32 +754,41 @@ NS_METHOD nsCocoaWindow::SetSizeMode(PRInt32 aMode)
NS_IMETHODIMP nsCocoaWindow::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{
Resize(aWidth, aHeight, aRepaint);
Move(aX, aY);
BOOL isMoving = (mBounds.x != aX || mBounds.y != aY);
BOOL isResizing = (mBounds.width != aWidth || mBounds.height != aHeight);
if (IsResizing() || !mWindow || (!isMoving && !isResizing))
return NS_OK;
nsRect geckoRect(aX, aY, aWidth, aHeight);
NSRect newFrame = geckoRectToCocoaRect(geckoRect);
StartResizing();
[mWindow setFrame:newFrame display:NO];
StopResizing();
if (isResizing)
ReportSizeEvent();
return NS_OK;
}
NS_IMETHODIMP nsCocoaWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{
if (IsResizing())
if (IsResizing() || !mWindow || (mBounds.width == aWidth && mBounds.height == aHeight))
return NS_OK;
if (mWindow) {
NSRect newFrame = [mWindow frame];
NSRect newFrame = [mWindow frame];
newFrame.size.width = aWidth;
// 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 - aHeight;
newFrame.size.height = aHeight;
// width is easy, no adjusting necessary
newFrame.size.width = aWidth;
// 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 - aHeight;
newFrame.size.height = aHeight;
StartResizing();
[mWindow setFrame:newFrame display:NO];
StopResizing();
}
StartResizing();
[mWindow setFrame:newFrame display:NO];
StopResizing();
ReportSizeEvent();