зеркало из https://github.com/mozilla/pjs.git
Bug 261238. Make widget z-ordering a closer approximation to what CSS2 wants. Also make GTK2 actually implement widget z-ordering. r=bzbarsky,blizzard sr=bzbarsky
This commit is contained in:
Родитель
fe1579f225
Коммит
271af35b03
|
@ -5219,21 +5219,9 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsIPresShell* aPresShell,
|
|||
addedToFrameList = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (nsHTMLAtoms::object == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
||||
}
|
||||
isReplaced = PR_TRUE;
|
||||
rv = NS_NewObjectFrame(aPresShell, &newFrame);
|
||||
}
|
||||
else if (nsHTMLAtoms::applet == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
||||
}
|
||||
isReplaced = PR_TRUE;
|
||||
rv = NS_NewObjectFrame(aPresShell, &newFrame);
|
||||
}
|
||||
else if (nsHTMLAtoms::embed == aTag) {
|
||||
else if (nsHTMLAtoms::object == aTag ||
|
||||
nsHTMLAtoms::applet == aTag ||
|
||||
nsHTMLAtoms::embed == aTag) {
|
||||
if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
||||
}
|
||||
|
|
|
@ -887,6 +887,10 @@ nsContainerFrame::FrameNeedsView(nsIFrame* aFrame)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (aFrame->GetType() == nsLayoutAtoms::objectFrame) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// See if the frame is block-level and has 'overflow' set to 'hidden'. If
|
||||
// so, then we need to give it a view so clipping
|
||||
// of any child views works correctly. Note that if it's floated it is also
|
||||
|
|
|
@ -829,34 +829,16 @@ nsObjectFrame::CreateWidget(nscoord aWidth,
|
|||
nscoord aHeight,
|
||||
PRBool aViewOnly)
|
||||
{
|
||||
// Create our view and widget
|
||||
|
||||
nsRect boundBox(0, 0, aWidth, aHeight);
|
||||
|
||||
nsIView *parView = GetAncestorWithView()->GetView();
|
||||
nsIViewManager* viewMan = parView->GetViewManager();
|
||||
|
||||
// nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted
|
||||
// initialize the view as hidden since we don't know the (x,y) until Paint
|
||||
nsIView *view = viewMan->CreateView(boundBox, parView, nsViewVisibility_kHide);
|
||||
// if (nsnull != initData) {
|
||||
// delete(initData);
|
||||
// }
|
||||
|
||||
nsIView* view = GetView();
|
||||
NS_ASSERTION(view, "Object frames must have views");
|
||||
if (!view) {
|
||||
return NS_OK; //XXX why OK? MMP
|
||||
}
|
||||
|
||||
#if 0
|
||||
// set the content's widget, so it can get content modified by the widget
|
||||
nsIWidget *widget = view->GetWidget();
|
||||
if (widget) {
|
||||
nsInput* content = (nsInput *)mContent; // change this cast to QueryInterface
|
||||
content->SetWidget(widget);
|
||||
} else {
|
||||
NS_ASSERTION(0, "could not get widget");
|
||||
}
|
||||
#endif
|
||||
nsIViewManager* viewMan = view->GetViewManager();
|
||||
// make the view as hidden since we don't know the (x,y) until Paint
|
||||
// XXX is the above comment correct?
|
||||
viewMan->SetViewVisibility(view, nsViewVisibility_kHide);
|
||||
|
||||
// Turn off double buffering on the Mac. This depends on bug 49743 and partially
|
||||
// fixes 32327, 19931 amd 51787
|
||||
|
@ -867,11 +849,7 @@ nsObjectFrame::CreateWidget(nscoord aWidth,
|
|||
viewMan->AllowDoubleBuffering(doubleBuffer);
|
||||
#endif
|
||||
|
||||
// XXX Put this last in document order
|
||||
// XXX Should we be setting the z-index here?
|
||||
viewMan->InsertChild(parView, view, nsnull, PR_TRUE);
|
||||
|
||||
if (aViewOnly != PR_TRUE) {
|
||||
if (!aViewOnly) {
|
||||
// Bug 179822: Create widget and allow non-unicode SubClass
|
||||
nsWidgetInitData initData;
|
||||
initData.mUnicode = PR_FALSE;
|
||||
|
@ -905,10 +883,10 @@ nsObjectFrame::CreateWidget(nscoord aWidth,
|
|||
nsPoint origin;
|
||||
nsRect r(0, 0, mRect.width, mRect.height);
|
||||
|
||||
viewMan->SetViewVisibility(view, nsViewVisibility_kShow);
|
||||
GetOffsetFromView(origin, &parentWithView);
|
||||
viewMan->ResizeView(view, r);
|
||||
viewMan->MoveViewTo(view, origin.x, origin.y);
|
||||
viewMan->SetViewVisibility(view, nsViewVisibility_kShow);
|
||||
}
|
||||
|
||||
SetView(view);
|
||||
|
|
|
@ -559,6 +559,40 @@ NS_IMETHODIMP nsView::SetContentTransparency(PRBool aTransparent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Native widgets ultimately just can't deal with the awesome power of
|
||||
// CSS2 z-index. However, we set the z-index on the widget anyway
|
||||
// because in many simple common cases the widgets do end up in the
|
||||
// right order. We set each widget's z-index to the z-index of the
|
||||
// nearest ancestor that has non-auto z-index.
|
||||
static void UpdateNativeWidgetZIndexes(nsView* aView, PRInt32 aZIndex)
|
||||
{
|
||||
if (aView->HasWidget()) {
|
||||
nsIWidget* widget = aView->GetWidget();
|
||||
PRInt32 curZ;
|
||||
widget->GetZIndex(&curZ);
|
||||
if (curZ != aZIndex) {
|
||||
widget->SetZIndex(aZIndex);
|
||||
}
|
||||
} else {
|
||||
for (nsView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
|
||||
if (v->GetZIndexIsAuto()) {
|
||||
UpdateNativeWidgetZIndexes(v, aZIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PRInt32 FindNonAutoZIndex(nsView* aView)
|
||||
{
|
||||
while (aView) {
|
||||
if (!aView->GetZIndexIsAuto()) {
|
||||
return aView->GetZIndex();
|
||||
}
|
||||
aView = aView->GetParent();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult nsIView::CreateWidget(const nsIID &aWindowIID,
|
||||
nsWidgetInitData *aWidgetInitData,
|
||||
nsNativeWidget aNative,
|
||||
|
@ -620,7 +654,7 @@ nsresult nsIView::CreateWidget(const nsIID &aWindowIID,
|
|||
}
|
||||
|
||||
// propagate the z-index to the widget.
|
||||
mWindow->SetZIndex(mZIndex);
|
||||
UpdateNativeWidgetZIndexes(v, FindNonAutoZIndex(v));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -637,12 +671,13 @@ nsresult nsIView::CreateWidget(const nsIID &aWindowIID,
|
|||
|
||||
void nsView::SetZIndex(PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost)
|
||||
{
|
||||
PRBool oldIsAuto = GetZIndexIsAuto();
|
||||
mVFlags = (mVFlags & ~NS_VIEW_FLAG_AUTO_ZINDEX) | (aAuto ? NS_VIEW_FLAG_AUTO_ZINDEX : 0);
|
||||
mZIndex = aZIndex;
|
||||
SetTopMost(aTopMost);
|
||||
|
||||
if (nsnull != mWindow) {
|
||||
mWindow->SetZIndex(aZIndex);
|
||||
if (HasWidget() || !oldIsAuto || !aAuto) {
|
||||
UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -668,6 +703,8 @@ NS_IMETHODIMP nsView::SetWidget(nsIWidget *aWidget)
|
|||
|
||||
mVFlags &= ~NS_VIEW_FLAG_HAS_POSITIONED_WIDGET;
|
||||
|
||||
UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -691,7 +728,6 @@ nsresult nsView::LoadWidget(const nsCID &aClassIID)
|
|||
}
|
||||
|
||||
mVFlags &= ~NS_VIEW_FLAG_HAS_POSITIONED_WIDGET;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -715,8 +751,10 @@ void nsIView::List(FILE* out, PRInt32 aIndent) const
|
|||
nonclientBounds *= p2t;
|
||||
nsrefcnt widgetRefCnt = mWindow->AddRef() - 1;
|
||||
mWindow->Release();
|
||||
fprintf(out, "(widget=%p[%d] pos={%d,%d,%d,%d}) ",
|
||||
(void*)mWindow, widgetRefCnt,
|
||||
PRInt32 Z;
|
||||
mWindow->GetZIndex(&Z);
|
||||
fprintf(out, "(widget=%p[%d] z=%d pos={%d,%d,%d,%d}) ",
|
||||
(void*)mWindow, widgetRefCnt, Z,
|
||||
nonclientBounds.x, nonclientBounds.y,
|
||||
windowBounds.width, windowBounds.height);
|
||||
}
|
||||
|
|
|
@ -3132,17 +3132,6 @@ NS_IMETHODIMP nsViewManager::SetViewZIndex(nsIView *aView, PRBool aAutoZIndex, P
|
|||
UpdateView(view, NS_VMREFRESH_NO_SYNC);
|
||||
}
|
||||
|
||||
// Native widgets ultimately just can't deal with the awesome power
|
||||
// of CSS2 z-index. However, we set the z-index on the widget anyway
|
||||
// because in many simple common cases the widgets do end up in the
|
||||
// right order. Even if they don't, we'll still render correctly as
|
||||
// long as there are no plugins around (although there may be more
|
||||
// flickering and other perf issues than if the widgets were in a
|
||||
// good order).
|
||||
if (view->HasWidget()) {
|
||||
view->GetWidget()->SetZIndex(aZIndex);
|
||||
}
|
||||
|
||||
nsZPlaceholderView* zParentView = view->GetZParent();
|
||||
if (nsnull != zParentView) {
|
||||
SetViewZIndex(zParentView, aAutoZIndex, aZIndex, aTopMost);
|
||||
|
|
|
@ -202,8 +202,8 @@ moz_drawingarea_set_visibility (MozDrawingarea *drawingarea,
|
|||
gboolean visibility)
|
||||
{
|
||||
if (visibility) {
|
||||
gdk_window_show(drawingarea->inner_window);
|
||||
gdk_window_show(drawingarea->clip_window);
|
||||
gdk_window_show_unraised(drawingarea->inner_window);
|
||||
gdk_window_show_unraised(drawingarea->clip_window);
|
||||
}
|
||||
else {
|
||||
gdk_window_hide(drawingarea->clip_window);
|
||||
|
|
|
@ -528,6 +528,32 @@ nsWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::SetZIndex(PRInt32 aZIndex)
|
||||
{
|
||||
nsIWidget* oldPrev = GetPrevSibling();
|
||||
|
||||
nsBaseWidget::SetZIndex(aZIndex);
|
||||
|
||||
if (GetPrevSibling() == oldPrev) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!mContainer, "Expected Mozilla child widget");
|
||||
|
||||
if (!GetNextSibling()) {
|
||||
// We're to be on top.
|
||||
gdk_window_raise(mDrawingarea->clip_window);
|
||||
} else {
|
||||
// All the siblings before us need to be below our widget.
|
||||
for (nsWindow* w = this; w;
|
||||
w = NS_STATIC_CAST(nsWindow*, w->GetPrevSibling())) {
|
||||
gdk_window_lower(w->mDrawingarea->clip_window);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::SetSizeMode(PRInt32 aMode)
|
||||
{
|
||||
|
|
|
@ -97,6 +97,7 @@ public:
|
|||
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
|
||||
nsIWidget *aWidget,
|
||||
PRBool aActivate);
|
||||
NS_IMETHOD SetZIndex(PRInt32 aZIndex);
|
||||
NS_IMETHOD SetSizeMode(PRInt32 aMode);
|
||||
NS_IMETHOD Enable(PRBool aState);
|
||||
NS_IMETHOD SetFocus(PRBool aRaise = PR_FALSE);
|
||||
|
|
Загрузка…
Ссылка в новой задаче