зеркало из https://github.com/mozilla/gecko-dev.git
reparent the view's descendant widgets when a view is re-inserted into a new view hierarchy position by paginated reflow. b=129034 r=roc+moz sr=kin
This commit is contained in:
Родитель
b61e862689
Коммит
d6f51b19b1
|
@ -2164,6 +2164,64 @@ NS_IMETHODIMP nsViewManager::GetKeyEventGrabber(nsIView *&aView)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Recursively reparent widgets if necessary
|
||||||
|
|
||||||
|
void nsViewManager::ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget)
|
||||||
|
{
|
||||||
|
PRBool hasWidget;
|
||||||
|
aView->HasWidget(&hasWidget);
|
||||||
|
if (hasWidget) {
|
||||||
|
// Check to see if the parent widget is the
|
||||||
|
// same as the new parent. If not then reparent
|
||||||
|
// the widget, otherwise there is nothing more
|
||||||
|
// to do for the view and its descendants
|
||||||
|
nsCOMPtr<nsIWidget> widget;
|
||||||
|
aView->GetWidget(*getter_AddRefs(widget));
|
||||||
|
nsCOMPtr<nsIWidget> parentWidget;
|
||||||
|
parentWidget = widget->GetParent();
|
||||||
|
if (parentWidget.get() != aNewWidget) {
|
||||||
|
widget->SetParent(aNewWidget);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to check each of the views children to see
|
||||||
|
// if they have a widget and reparent it.
|
||||||
|
|
||||||
|
nsView* view = NS_STATIC_CAST(nsView*, aView);
|
||||||
|
nsView *kid = view->GetFirstChild();
|
||||||
|
while (kid) {
|
||||||
|
ReparentChildWidgets(kid, aNewWidget);
|
||||||
|
kid = kid->GetNextSibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reparent a view and its descendant views widgets if necessary
|
||||||
|
|
||||||
|
void nsViewManager::ReparentWidgets(nsIView* aView, nsIView *aParent)
|
||||||
|
{
|
||||||
|
// Quickly determine whether the view has pre-existing children or a
|
||||||
|
// widget. In most cases the view will not have any pre-existing
|
||||||
|
// children when this is called. Only in the case
|
||||||
|
// where a view has been reparented by removing it from
|
||||||
|
// a reinserting it into a new location in the view hierarchy do we
|
||||||
|
// have to consider reparenting the existing widgets for the view and
|
||||||
|
// it's descendants.
|
||||||
|
nsView* view = NS_STATIC_CAST(nsView*, aView);
|
||||||
|
PRBool hasWidget;
|
||||||
|
aView->HasWidget(&hasWidget);
|
||||||
|
if (hasWidget || view->GetFirstChild()) {
|
||||||
|
nsCOMPtr<nsIWidget> parentWidget;
|
||||||
|
GetWidgetForView(aParent, getter_AddRefs(parentWidget));
|
||||||
|
if (parentWidget) {
|
||||||
|
ReparentChildWidgets(aView, parentWidget);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NS_WARNING("Can not find a widget for the parent view");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIView *aSibling,
|
NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIView *aSibling,
|
||||||
PRBool aAfter)
|
PRBool aAfter)
|
||||||
{
|
{
|
||||||
|
@ -2188,6 +2246,7 @@ NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIV
|
||||||
// insert at end of document order, i.e., before first view
|
// insert at end of document order, i.e., before first view
|
||||||
// this is the common case, by far
|
// this is the common case, by far
|
||||||
parent->InsertChild(child, nsnull);
|
parent->InsertChild(child, nsnull);
|
||||||
|
ReparentWidgets(child, parent);
|
||||||
} else {
|
} else {
|
||||||
// insert at beginning of document order, i.e., after last view
|
// insert at beginning of document order, i.e., after last view
|
||||||
nsView *kid = parent->GetFirstChild();
|
nsView *kid = parent->GetFirstChild();
|
||||||
|
@ -2198,6 +2257,7 @@ NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIV
|
||||||
}
|
}
|
||||||
// prev is last view or null if there are no children
|
// prev is last view or null if there are no children
|
||||||
parent->InsertChild(child, prev);
|
parent->InsertChild(child, prev);
|
||||||
|
ReparentWidgets(child, parent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nsView *kid = parent->GetFirstChild();
|
nsView *kid = parent->GetFirstChild();
|
||||||
|
@ -2212,9 +2272,11 @@ NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIV
|
||||||
if (aAfter) {
|
if (aAfter) {
|
||||||
// insert after 'kid' in document order, i.e. before in view order
|
// insert after 'kid' in document order, i.e. before in view order
|
||||||
parent->InsertChild(child, prev);
|
parent->InsertChild(child, prev);
|
||||||
|
ReparentWidgets(child, parent);
|
||||||
} else {
|
} else {
|
||||||
// insert before 'kid' in document order, i.e. after in view order
|
// insert before 'kid' in document order, i.e. after in view order
|
||||||
parent->InsertChild(child, kid);
|
parent->InsertChild(child, kid);
|
||||||
|
ReparentWidgets(child, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // don't keep consistent document order, but order things by z-index instead
|
#else // don't keep consistent document order, but order things by z-index instead
|
||||||
|
@ -2233,6 +2295,7 @@ NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIV
|
||||||
}
|
}
|
||||||
|
|
||||||
parent->InsertChild(child, prev);
|
parent->InsertChild(child, prev);
|
||||||
|
ReparentWidgets(child, parent);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UpdateTransCnt(nsnull, child);
|
UpdateTransCnt(nsnull, child);
|
||||||
|
|
|
@ -244,6 +244,8 @@ protected:
|
||||||
void ProcessPendingUpdates(nsView *aView);
|
void ProcessPendingUpdates(nsView *aView);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget);
|
||||||
|
void ReparentWidgets(nsIView* aView, nsIView *aParent);
|
||||||
nsIRenderingContext *CreateRenderingContext(nsView &aView);
|
nsIRenderingContext *CreateRenderingContext(nsView &aView);
|
||||||
void AddRectToDirtyRegion(nsView* aView, const nsRect &aRect) const;
|
void AddRectToDirtyRegion(nsView* aView, const nsRect &aRect) const;
|
||||||
void UpdateTransCnt(nsView *oldview, nsView *newview);
|
void UpdateTransCnt(nsView *oldview, nsView *newview);
|
||||||
|
|
|
@ -320,6 +320,17 @@ class nsIWidget : public nsISupports {
|
||||||
|
|
||||||
NS_IMETHOD Destroy(void) = 0;
|
NS_IMETHOD Destroy(void) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reparent a widget
|
||||||
|
*
|
||||||
|
* Change the widgets parent
|
||||||
|
*
|
||||||
|
* @param aNewParent new parent
|
||||||
|
*/
|
||||||
|
NS_IMETHOD SetParent(nsIWidget* aNewParent) = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the parent Widget of this Widget or nsnull if this is a
|
* Return the parent Widget of this Widget or nsnull if this is a
|
||||||
* top level window
|
* top level window
|
||||||
|
|
|
@ -1622,6 +1622,18 @@ NS_METHOD nsWindow::Destroy()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsWindow::SetParent(nsIWidget *aNewParent)
|
||||||
|
{
|
||||||
|
if (aNewParent) {
|
||||||
|
HWND newParent = (HWND)aNewParent->GetNativeData(NS_NATIVE_WINDOW);
|
||||||
|
NS_ASSERTION(newParent, "Parent widget has a null native window handle");
|
||||||
|
::SetParent(mWnd, newParent);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
NS_WARNING("Null aNewParent passed to SetParent");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
|
@ -295,6 +295,7 @@ public:
|
||||||
nsNativeWidget aNativeParent = nsnull);
|
nsNativeWidget aNativeParent = nsnull);
|
||||||
|
|
||||||
NS_IMETHOD Destroy();
|
NS_IMETHOD Destroy();
|
||||||
|
NS_IMETHOD SetParent(nsIWidget *aNewParent);
|
||||||
virtual nsIWidget* GetParent(void);
|
virtual nsIWidget* GetParent(void);
|
||||||
NS_IMETHOD Show(PRBool bState);
|
NS_IMETHOD Show(PRBool bState);
|
||||||
NS_IMETHOD IsVisible(PRBool & aState);
|
NS_IMETHOD IsVisible(PRBool & aState);
|
||||||
|
|
|
@ -252,6 +252,17 @@ NS_METHOD nsBaseWidget::Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Set this nsBaseWidget's parent
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP nsBaseWidget::SetParent(nsIWidget* aNewParent)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Get this nsBaseWidget parent
|
// Get this nsBaseWidget parent
|
||||||
|
|
|
@ -78,6 +78,7 @@ public:
|
||||||
NS_IMETHOD GetClientData(void*& aClientData);
|
NS_IMETHOD GetClientData(void*& aClientData);
|
||||||
NS_IMETHOD SetClientData(void* aClientData);
|
NS_IMETHOD SetClientData(void* aClientData);
|
||||||
NS_IMETHOD Destroy();
|
NS_IMETHOD Destroy();
|
||||||
|
NS_IMETHOD SetParent(nsIWidget* aNewParent);
|
||||||
virtual nsIWidget* GetParent(void);
|
virtual nsIWidget* GetParent(void);
|
||||||
virtual nsIEnumerator* GetChildren();
|
virtual nsIEnumerator* GetChildren();
|
||||||
virtual void AddChild(nsIWidget* aChild);
|
virtual void AddChild(nsIWidget* aChild);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче