зеркало из https://github.com/mozilla/gecko-dev.git
fix for mexican-jumping menus when menus were too large and needed to be repositioned to fit on screen. fixes bug 21477. r=hyatt.
This commit is contained in:
Родитель
8e7fc7d323
Коммит
be979f653a
|
@ -218,7 +218,10 @@ nsMenuPopupFrame::SyncViewWithFrame(nsIPresContext* aPresContext,
|
||||||
nsPoint parentPos;
|
nsPoint parentPos;
|
||||||
nsCOMPtr<nsIViewManager> viewManager;
|
nsCOMPtr<nsIViewManager> viewManager;
|
||||||
|
|
||||||
//Get the nearest enclosing parent view to aFrame.
|
//
|
||||||
|
// Collect info about our parent view and the frame we're sync'ing to
|
||||||
|
//
|
||||||
|
|
||||||
nsIView* parentView = nsnull;
|
nsIView* parentView = nsnull;
|
||||||
GetNearestEnclosingView(aPresContext, aFrame, &parentView);
|
GetNearestEnclosingView(aPresContext, aFrame, &parentView);
|
||||||
if (!parentView)
|
if (!parentView)
|
||||||
|
@ -254,11 +257,11 @@ nsMenuPopupFrame::SyncViewWithFrame(nsIPresContext* aPresContext,
|
||||||
viewManager->GetDeviceContext(*getter_AddRefs(dx));
|
viewManager->GetDeviceContext(*getter_AddRefs(dx));
|
||||||
dx->GetAppUnitsToDevUnits(t2p);
|
dx->GetAppUnitsToDevUnits(t2p);
|
||||||
|
|
||||||
PRInt32 xpos;
|
// |xpos| and |ypos| hold the x and y positions of where the popup will be moved to,
|
||||||
PRInt32 ypos;
|
// in _twips_, in the coordinate system of the _parent view_.
|
||||||
viewManager->ResizeView(view, mRect.width, mRect.height);
|
PRInt32 xpos = 0, ypos = 0;
|
||||||
|
|
||||||
if (aXPos != -1 || aYPos != -1) {
|
if (aXPos != -1 || aYPos != -1) {
|
||||||
// Convert the screen coords to twips
|
|
||||||
xpos = NSIntPixelsToTwips(aXPos, p2t);
|
xpos = NSIntPixelsToTwips(aXPos, p2t);
|
||||||
ypos = NSIntPixelsToTwips(aYPos, p2t);
|
ypos = NSIntPixelsToTwips(aYPos, p2t);
|
||||||
xpos += offset.x;
|
xpos += offset.x;
|
||||||
|
@ -298,15 +301,15 @@ nsMenuPopupFrame::SyncViewWithFrame(nsIPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewManager->MoveViewTo(view, xpos, ypos);
|
//
|
||||||
|
// At this point, we should be positioned where we're told. Ensure that we fit
|
||||||
|
// on the screen.
|
||||||
|
//
|
||||||
|
|
||||||
// Check if we fit on the screen, if not, resize and/or move so we do
|
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> document;
|
nsCOMPtr<nsIDocument> document;
|
||||||
presShell->GetDocument(getter_AddRefs(document));
|
presShell->GetDocument(getter_AddRefs(document));
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject;
|
nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject;
|
||||||
document->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject));
|
document->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject));
|
||||||
|
|
||||||
|
@ -318,73 +321,63 @@ nsMenuPopupFrame::SyncViewWithFrame(nsIPresContext* aPresContext,
|
||||||
screen->GetAvailWidth(&screenWidth);
|
screen->GetAvailWidth(&screenWidth);
|
||||||
screen->GetAvailHeight(&screenHeight);
|
screen->GetAvailHeight(&screenHeight);
|
||||||
|
|
||||||
PRInt32 screenLeft; // May be negative on MacOS!
|
// Compute info about the screen dimensions. Because of multiple monitor systems,
|
||||||
PRInt32 screenTop; // May be negative on MacOS!
|
// the left or top sides of the screen may be in negative space (main monitor is on the
|
||||||
|
// right, etc). We need to be sure to do the right thing.
|
||||||
|
PRInt32 screenLeft;
|
||||||
|
PRInt32 screenTop;
|
||||||
screen->GetAvailLeft(&screenLeft);
|
screen->GetAvailLeft(&screenLeft);
|
||||||
screen->GetAvailTop(&screenTop);
|
screen->GetAvailTop(&screenTop);
|
||||||
|
|
||||||
PRInt32 screenRight;
|
PRInt32 screenRight;
|
||||||
if(screenLeft<0)
|
if(screenLeft<0)
|
||||||
screenRight = screenWidth + screenLeft;
|
screenRight = screenWidth + screenLeft;
|
||||||
else
|
else
|
||||||
screenRight = screenWidth - screenLeft;
|
screenRight = screenWidth - screenLeft;
|
||||||
|
|
||||||
PRInt32 screenBottom;
|
PRInt32 screenBottom;
|
||||||
if(screenTop<0)
|
if(screenTop<0)
|
||||||
screenBottom = screenHeight + screenTop;
|
screenBottom = screenHeight + screenTop;
|
||||||
else
|
else
|
||||||
screenBottom = screenHeight - screenTop;
|
screenBottom = screenHeight - screenTop;
|
||||||
|
PRInt32 screenWidthTwips = NSIntPixelsToTwips(screenWidth, p2t);
|
||||||
|
PRInt32 screenHeightTwips = NSIntPixelsToTwips(screenHeight, p2t);
|
||||||
|
PRInt32 screenRightTwips = NSIntPixelsToTwips(screenRight, p2t);
|
||||||
|
PRInt32 screenBottomTwips = NSIntPixelsToTwips(screenBottom, p2t);
|
||||||
|
|
||||||
screenWidth = NSIntPixelsToTwips(screenWidth, p2t);
|
// shrink to fit onto the screen, vertically and horizontally
|
||||||
screenHeight = NSIntPixelsToTwips(screenHeight, p2t);
|
if(mRect.width > screenWidthTwips)
|
||||||
screenRight = NSIntPixelsToTwips(screenRight, p2t);
|
mRect.width = screenWidthTwips;
|
||||||
screenBottom = NSIntPixelsToTwips(screenBottom, p2t);
|
if(mRect.height > screenHeightTwips)
|
||||||
|
mRect.height = screenHeightTwips;
|
||||||
|
|
||||||
if(mRect.width > screenWidth || mRect.height > screenHeight) {
|
// Recall that |xpos| and |ypos| are in the coordinate system of the parent view. In
|
||||||
if(mRect.width > screenWidth) mRect.width = screenWidth;
|
// order to determine the screen coordinates of where our view will end up, we
|
||||||
|
// need to find the x/y position of the parent view in screen coords. That is done
|
||||||
|
// by getting the widget associated with the parent view and determining the offset
|
||||||
|
// based on converting (0,0) in its coordinate space to screen coords. We then
|
||||||
|
// offset that point by (|xpos|,|ypos|) to get the true screen coorindates of
|
||||||
|
// the view. *whew*
|
||||||
|
nsCOMPtr<nsIWidget> parentViewWidget;
|
||||||
|
parentView->GetWidget ( *getter_AddRefs(parentViewWidget) );
|
||||||
|
nsRect localParentRect(0,0,0,0), screenParentRect;
|
||||||
|
parentViewWidget->WidgetToScreen ( localParentRect, screenParentRect );
|
||||||
|
PRInt32 screenViewLocX = screenParentRect.x + NSTwipsToIntPixels(xpos - parentPos.x, t2p);
|
||||||
|
PRInt32 screenViewLocY = screenParentRect.y + NSTwipsToIntPixels(ypos - parentPos.y, t2p);
|
||||||
|
|
||||||
if(mRect.height > screenHeight) mRect.height = screenHeight;
|
// we now know where the view is...check that it's still onscreen at all!
|
||||||
|
if ( screenViewLocX < screenLeft )
|
||||||
|
xpos += NSIntPixelsToTwips(screenLeft - screenViewLocX,p2t);
|
||||||
|
if ( screenViewLocY < screenTop )
|
||||||
|
ypos += NSIntPixelsToTwips(screenTop - screenViewLocY,p2t);
|
||||||
|
|
||||||
|
// ensure it is not even partially offscreen.
|
||||||
|
if ((NSIntPixelsToTwips(screenViewLocX,p2t) + mRect.width) > screenRightTwips)
|
||||||
|
xpos -= (NSIntPixelsToTwips(screenViewLocX,p2t) + mRect.width) - screenRightTwips;
|
||||||
|
if ((NSIntPixelsToTwips(screenViewLocY,p2t) + mRect.height) > screenBottomTwips)
|
||||||
|
ypos -= (NSIntPixelsToTwips(screenViewLocY,p2t) + mRect.height) - screenBottomTwips;
|
||||||
|
|
||||||
|
// finally move and resize it
|
||||||
|
viewManager->MoveViewTo(view, xpos, ypos);
|
||||||
viewManager->ResizeView(view, mRect.width, mRect.height);
|
viewManager->ResizeView(view, mRect.width, mRect.height);
|
||||||
}
|
|
||||||
|
|
||||||
// Get pixel distance from popup widget 0,0 to screen 0,0
|
|
||||||
nsCOMPtr<nsIWidget> widget;
|
|
||||||
view->GetWidget(*getter_AddRefs(widget));
|
|
||||||
|
|
||||||
nsRect inRect, outRect;
|
|
||||||
inRect.x = 0;
|
|
||||||
inRect.y = 0;
|
|
||||||
widget->WidgetToScreen(inRect, outRect);
|
|
||||||
|
|
||||||
if(outRect.x < screenLeft || outRect.y < screenTop) {
|
|
||||||
if(outRect.x < screenLeft) {
|
|
||||||
PRInt32 diff = NSIntPixelsToTwips(screenLeft - outRect.x,p2t);
|
|
||||||
if(diff>0)
|
|
||||||
xpos += diff;
|
|
||||||
else
|
|
||||||
xpos -= diff;
|
|
||||||
}
|
|
||||||
if(outRect.y < screenTop) {
|
|
||||||
PRInt32 diff = NSIntPixelsToTwips(screenTop - outRect.y,p2t);
|
|
||||||
if(diff>0)
|
|
||||||
ypos += diff;
|
|
||||||
else
|
|
||||||
ypos -= diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
viewManager->MoveViewTo(view, xpos, ypos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((NSIntPixelsToTwips(outRect.x,p2t) + mRect.width) > screenRight) {
|
|
||||||
xpos -= (NSIntPixelsToTwips(outRect.x,p2t) + mRect.width) - screenRight;
|
|
||||||
viewManager->MoveViewTo(view, xpos, ypos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((NSIntPixelsToTwips(outRect.y,p2t) + mRect.height) > screenBottom) {
|
|
||||||
ypos -= (NSIntPixelsToTwips(outRect.y,p2t) + mRect.height) - screenBottom;
|
|
||||||
viewManager->MoveViewTo(view, xpos, ypos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((! viewWasVisible) && viewIsVisible) {
|
if ((! viewWasVisible) && viewIsVisible) {
|
||||||
view->SetVisibility(nsViewVisibility_kShow);
|
view->SetVisibility(nsViewVisibility_kShow);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче