зеркало из https://github.com/mozilla/pjs.git
Bug 264245. Make all popups have no nsIWidget parent to avoid the hassles of various widget implementations not keeping their position consistent with their parent. Also, aggressively invalidate cached screen coordinates in GTK1 to avoid bugs. r=bzbarsky,sr=blizzard
This commit is contained in:
Родитель
7e0e605b99
Коммит
d3706fffdc
|
@ -343,14 +343,18 @@ static void AdjustChildWidgets(nsView *aView,
|
|||
nsPoint aWidgetToParentViewOrigin, float aScale, PRBool aInvalidate)
|
||||
{
|
||||
if (aView->HasWidget()) {
|
||||
nsRect bounds = aView->GetBounds();
|
||||
nsPoint widgetOrigin = aWidgetToParentViewOrigin
|
||||
+ nsPoint(bounds.x, bounds.y);
|
||||
nsIWidget* widget = aView->GetWidget();
|
||||
widget->Move(NSTwipsToIntPixels(widgetOrigin.x, aScale),
|
||||
NSTwipsToIntPixels(widgetOrigin.y, aScale));
|
||||
if (aInvalidate) {
|
||||
widget->Invalidate(PR_FALSE);
|
||||
nsWindowType type;
|
||||
widget->GetWindowType(type);
|
||||
if (type != eWindowType_popup) {
|
||||
nsRect bounds = aView->GetBounds();
|
||||
nsPoint widgetOrigin = aWidgetToParentViewOrigin
|
||||
+ nsPoint(bounds.x, bounds.y);
|
||||
widget->Move(NSTwipsToIntPixels(widgetOrigin.x, aScale),
|
||||
NSTwipsToIntPixels(widgetOrigin.y, aScale));
|
||||
if (aInvalidate) {
|
||||
widget->Invalidate(PR_FALSE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Don't recurse if the view has a widget, because we adjusted the view's
|
||||
|
|
|
@ -396,15 +396,26 @@ void nsView::ResetWidgetBounds(PRBool aRecurse, PRBool aMoveOnly,
|
|||
}
|
||||
|
||||
nsIDeviceContext *dx;
|
||||
float t2p;
|
||||
float t2p, p2t;
|
||||
|
||||
mViewManager->GetDeviceContext(dx);
|
||||
t2p = dx->AppUnitsToDevUnits();
|
||||
p2t = dx->DevUnitsToAppUnits();
|
||||
NS_RELEASE(dx);
|
||||
|
||||
nsPoint offset(0, 0);
|
||||
if (GetParent()) {
|
||||
GetParent()->GetNearestWidget(&offset);
|
||||
nsIWidget* parentWidget = GetParent()->GetNearestWidget(&offset);
|
||||
|
||||
nsWindowType type;
|
||||
mWindow->GetWindowType(type);
|
||||
if (type == eWindowType_popup) {
|
||||
// put offset into screen coordinates
|
||||
nsRect screenRect(0,0,1,1);
|
||||
parentWidget->WidgetToScreen(screenRect, screenRect);
|
||||
offset += nsPoint(NSIntPixelsToTwips(screenRect.x, p2t),
|
||||
NSIntPixelsToTwips(screenRect.y, p2t));
|
||||
}
|
||||
}
|
||||
|
||||
nsRect newBounds(NSTwipsToIntPixels((mDimBounds.x + offset.x), t2p),
|
||||
|
@ -568,11 +579,11 @@ NS_IMETHODIMP nsView::SetContentTransparency(PRBool aTransparent)
|
|||
}
|
||||
|
||||
nsresult nsIView::CreateWidget(const nsIID &aWindowIID,
|
||||
nsWidgetInitData *aWidgetInitData,
|
||||
nsNativeWidget aNative,
|
||||
PRBool aEnableDragDrop,
|
||||
PRBool aResetVisibility,
|
||||
nsContentType aContentType)
|
||||
nsWidgetInitData *aWidgetInitData,
|
||||
nsNativeWidget aNative,
|
||||
PRBool aEnableDragDrop,
|
||||
PRBool aResetVisibility,
|
||||
nsContentType aContentType)
|
||||
{
|
||||
nsIDeviceContext *dx;
|
||||
nsRect trect = mDimBounds;
|
||||
|
@ -615,8 +626,13 @@ nsresult nsIView::CreateWidget(const nsIID &aWindowIID,
|
|||
|
||||
nsIWidget* parentWidget = GetParent() ? GetParent()->GetNearestWidget(nsnull)
|
||||
: nsnull;
|
||||
mWindow->Create(parentWidget, trect,
|
||||
::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
|
||||
if (aWidgetInitData->mWindowType == eWindowType_popup) {
|
||||
mWindow->Create(parentWidget->GetNativeData(NS_NATIVE_WINDOW), trect,
|
||||
::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
|
||||
} else {
|
||||
mWindow->Create(parentWidget, trect,
|
||||
::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
|
||||
}
|
||||
}
|
||||
if (aEnableDragDrop) {
|
||||
mWindow->EnableDragDrop(PR_TRUE);
|
||||
|
|
|
@ -1248,6 +1248,9 @@ nsresult nsWidget::CreateWidget(nsIWidget *aParent,
|
|||
aInitData->mWindowType == eWindowType_invisible) ?
|
||||
nsnull : aParent;
|
||||
|
||||
NS_ASSERTION(aInitData->mWindowType != eWindowType_popup ||
|
||||
!aParent, "Popups should not be hooked into nsIWidget hierarchy");
|
||||
|
||||
BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
|
||||
aAppShell, aToolkit, aInitData);
|
||||
|
||||
|
|
|
@ -415,6 +415,13 @@ NS_IMETHODIMP nsWindow::Destroy(void)
|
|||
void nsWindow::InvalidateWindowPos(void)
|
||||
{
|
||||
mCachedX = mCachedY = -1;
|
||||
|
||||
for (nsIWidget* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
|
||||
// Force kid to invalidate its window position if necessary.
|
||||
nsRect kidBounds;
|
||||
kid->GetBounds(kidBounds);
|
||||
kid->Move(kidBounds.x, kidBounds.y);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -428,7 +435,17 @@ PRBool nsWindow::GetWindowPos(nscoord &x, nscoord &y)
|
|||
{
|
||||
if ((mCachedX==-1) && (mCachedY==-1)) { /* Not cached */
|
||||
gint xpos, ypos;
|
||||
if (mMozArea)
|
||||
|
||||
if (mParent)
|
||||
{
|
||||
// Just ask our parent; it might have its position cached, so
|
||||
// we can save a bunch of work.
|
||||
nsRect newRect;
|
||||
mParent->WidgetToScreen(mBounds, newRect);
|
||||
xpos = newRect.x;
|
||||
ypos = newRect.y;
|
||||
}
|
||||
else if (mMozArea)
|
||||
{
|
||||
if (mMozArea->window)
|
||||
{
|
||||
|
@ -448,8 +465,11 @@ PRBool nsWindow::GetWindowPos(nscoord &x, nscoord &y)
|
|||
gdk_window_get_origin(mSuperWin->bin_window, &xpos, &ypos);
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
else
|
||||
return PR_FALSE;
|
||||
|
||||
mCachedX = xpos;
|
||||
mCachedY = ypos;
|
||||
}
|
||||
|
@ -2617,7 +2637,7 @@ NS_IMETHODIMP nsWindow::ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt3
|
|||
|
||||
NS_IMETHODIMP nsWindow::Move(PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
InvalidateWindowPos();
|
||||
InvalidateWindowPos();
|
||||
// check if we are at right place already
|
||||
if((aX == mBounds.x) && (aY == mBounds.y) && !mIsToplevel) {
|
||||
return NS_OK;
|
||||
|
|
|
@ -2032,6 +2032,9 @@ nsWindow::NativeCreate(nsIWidget *aParent,
|
|||
aInitData->mWindowType == eWindowType_invisible) ?
|
||||
nsnull : aParent;
|
||||
|
||||
NS_ASSERTION(aInitData->mWindowType != eWindowType_popup ||
|
||||
!aParent, "Popups should not be hooked into nsIWidget hierarchy");
|
||||
|
||||
// initialize all the common bits of this class
|
||||
BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
|
||||
aAppShell, aToolkit, aInitData);
|
||||
|
|
|
@ -1460,6 +1460,7 @@ nsWindow::StandardWindowCreate(nsIWidget *aParent,
|
|||
DWORD extendedStyle = WindowExStyle();
|
||||
|
||||
if (mWindowType == eWindowType_popup) {
|
||||
NS_ASSERTION(!aParent, "Popups should not be hooked into the nsIWidget hierarchy");
|
||||
mBorderlessParent = parent;
|
||||
// Don't set the parent of a popup window.
|
||||
parent = NULL;
|
||||
|
@ -2001,22 +2002,6 @@ NS_METHOD nsWindow::Move(PRInt32 aX, PRInt32 aY)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// When moving a borderless top-level window the window
|
||||
// must be placed relative to its parent. WIN32 wants to
|
||||
// place it relative to the screen, so we used the cached parent
|
||||
// to calculate the parent's location then add the x,y passed to
|
||||
// the move to get the screen coordinate for the borderless top-level
|
||||
// window.
|
||||
if (mWindowType == eWindowType_popup) {
|
||||
HWND parent = mBorderlessParent;
|
||||
if (parent) {
|
||||
RECT pr;
|
||||
VERIFY(::GetWindowRect(parent, &pr));
|
||||
aX += pr.left;
|
||||
aY += pr.top;
|
||||
}
|
||||
}
|
||||
|
||||
mBounds.x = aX;
|
||||
mBounds.y = aY;
|
||||
|
||||
|
@ -2127,22 +2112,6 @@ NS_METHOD nsWindow::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeig
|
|||
ResizeTranslucentWindow(aWidth, aHeight);
|
||||
#endif
|
||||
|
||||
// When resizing a borderless top-level window the window
|
||||
// must be placed relative to its parent. WIN32 wants to
|
||||
// place it relative to the screen, so we used the cached parent
|
||||
// to calculate the parent's location then add the x,y passed to
|
||||
// the resize to get the screen coordinate for the borderless top-level
|
||||
// window.
|
||||
if (mWindowType == eWindowType_popup) {
|
||||
HWND parent = mBorderlessParent;
|
||||
if (parent) {
|
||||
RECT pr;
|
||||
VERIFY(::GetWindowRect(parent, &pr));
|
||||
aX += pr.left;
|
||||
aY += pr.top;
|
||||
}
|
||||
}
|
||||
|
||||
// Set cached value for lightweight and printing
|
||||
mBounds.x = aX;
|
||||
mBounds.y = aY;
|
||||
|
|
Загрузка…
Ссылка в новой задаче