зеркало из https://github.com/mozilla/pjs.git
Don't do resize reflows for view managers that aren't visible. (Improve window resizing and find toolbar performance when multiple tabs are open.) b=227361 r+sr=roc
This commit is contained in:
Родитель
279d8c6aef
Коммит
0bfc91bf4e
|
@ -126,6 +126,7 @@
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsIDocShell.h" // for reflow observation
|
#include "nsIDocShell.h" // for reflow observation
|
||||||
|
#include "nsIBaseWindow.h"
|
||||||
#include "nsLayoutErrors.h"
|
#include "nsLayoutErrors.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsCSSRendering.h"
|
#include "nsCSSRendering.h"
|
||||||
|
@ -1221,6 +1222,7 @@ public:
|
||||||
nsEvent* aEvent,
|
nsEvent* aEvent,
|
||||||
nsEventStatus* aStatus);
|
nsEventStatus* aStatus);
|
||||||
NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
|
NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
|
||||||
|
NS_IMETHOD_(PRBool) IsVisible();
|
||||||
|
|
||||||
// caret handling
|
// caret handling
|
||||||
NS_IMETHOD GetCaret(nsICaret **aOutCaret);
|
NS_IMETHOD GetCaret(nsICaret **aOutCaret);
|
||||||
|
@ -6034,6 +6036,18 @@ PresShell::ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight)
|
||||||
return ResizeReflow(aWidth, aHeight);
|
return ResizeReflow(aWidth, aHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP_(PRBool)
|
||||||
|
PresShell::IsVisible()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
|
||||||
|
nsCOMPtr<nsIBaseWindow> bw = do_QueryInterface(container);
|
||||||
|
if (!bw)
|
||||||
|
return PR_FALSE;
|
||||||
|
PRBool res = PR_TRUE;
|
||||||
|
bw->GetVisibility(&res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
PresShell::GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets)
|
PresShell::GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets)
|
||||||
{
|
{
|
||||||
|
|
|
@ -126,6 +126,7 @@
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsIDocShell.h" // for reflow observation
|
#include "nsIDocShell.h" // for reflow observation
|
||||||
|
#include "nsIBaseWindow.h"
|
||||||
#include "nsLayoutErrors.h"
|
#include "nsLayoutErrors.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsCSSRendering.h"
|
#include "nsCSSRendering.h"
|
||||||
|
@ -1221,6 +1222,7 @@ public:
|
||||||
nsEvent* aEvent,
|
nsEvent* aEvent,
|
||||||
nsEventStatus* aStatus);
|
nsEventStatus* aStatus);
|
||||||
NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
|
NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
|
||||||
|
NS_IMETHOD_(PRBool) IsVisible();
|
||||||
|
|
||||||
// caret handling
|
// caret handling
|
||||||
NS_IMETHOD GetCaret(nsICaret **aOutCaret);
|
NS_IMETHOD GetCaret(nsICaret **aOutCaret);
|
||||||
|
@ -6034,6 +6036,18 @@ PresShell::ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight)
|
||||||
return ResizeReflow(aWidth, aHeight);
|
return ResizeReflow(aWidth, aHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP_(PRBool)
|
||||||
|
PresShell::IsVisible()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
|
||||||
|
nsCOMPtr<nsIBaseWindow> bw = do_QueryInterface(container);
|
||||||
|
if (!bw)
|
||||||
|
return PR_FALSE;
|
||||||
|
PRBool res = PR_TRUE;
|
||||||
|
bw->GetVisibility(&res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
PresShell::GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets)
|
PresShell::GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,8 +46,8 @@ struct nsRect;
|
||||||
struct nsGUIEvent;
|
struct nsGUIEvent;
|
||||||
|
|
||||||
#define NS_IVIEWOBSERVER_IID \
|
#define NS_IVIEWOBSERVER_IID \
|
||||||
{ 0x6a1529e0, 0x3d2c, 0x11d2, \
|
{ 0x0f4bc34a, 0xc93b, 0x4699, \
|
||||||
{ 0xa8, 0x32, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
|
{ 0xb6, 0xc2, 0xb3, 0xca, 0x9e, 0xe4, 0x6c, 0x95 } }
|
||||||
|
|
||||||
class nsIViewObserver : public nsISupports
|
class nsIViewObserver : public nsISupports
|
||||||
{
|
{
|
||||||
|
@ -85,6 +85,12 @@ public:
|
||||||
* @return error status
|
* @return error status
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD ResizeReflow(nsIView * aView, nscoord aWidth, nscoord aHeight) = 0;
|
NS_IMETHOD ResizeReflow(nsIView * aView, nscoord aWidth, nscoord aHeight) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack to find out if the view observer is itself visible, in lieu
|
||||||
|
* of having the view trees linked.
|
||||||
|
*/
|
||||||
|
NS_IMETHOD_(PRBool) IsVisible();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -412,6 +412,24 @@ static PRInt32 CompareZIndex(PRInt32 aZIndex1, PRBool aTopMost1, PRBool aIsAuto1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool IsViewVisible(nsView *aView)
|
||||||
|
{
|
||||||
|
for (nsIView *view = aView; view; view = view->GetParent()) {
|
||||||
|
// We don't check widget visibility here because in the future (with
|
||||||
|
// the better approach to this that's in attachment 160801 on bug
|
||||||
|
// 227361), callers of the equivalent to this function should be able
|
||||||
|
// to rely on being notified when the result of this function changes.
|
||||||
|
if (view->GetVisibility() == nsViewVisibility_kHide)
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
// Find out if the root view is visible by asking the view observer
|
||||||
|
// (this won't be needed anymore if we link view trees across chrome /
|
||||||
|
// content boundaries in DocumentViewerImpl::MakeWindow).
|
||||||
|
nsCOMPtr<nsIViewObserver> vo;
|
||||||
|
aView->GetViewManager()->GetViewObserver(*getter_AddRefs(vo));
|
||||||
|
return vo->IsVisible();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsViewManager::PostInvalidateEvent()
|
nsViewManager::PostInvalidateEvent()
|
||||||
{
|
{
|
||||||
|
@ -438,6 +456,7 @@ PRUint32 nsViewManager::gLastUserEventTime = 0;
|
||||||
|
|
||||||
nsViewManager::nsViewManager()
|
nsViewManager::nsViewManager()
|
||||||
: mMouseLocation(NSCOORD_NONE, NSCOORD_NONE)
|
: mMouseLocation(NSCOORD_NONE, NSCOORD_NONE)
|
||||||
|
, mDelayedResize(NSCOORD_NONE, NSCOORD_NONE)
|
||||||
{
|
{
|
||||||
if (gViewManagers == nsnull) {
|
if (gViewManagers == nsnull) {
|
||||||
NS_ASSERTION(mVMCount == 0, "View Manager count is incorrect");
|
NS_ASSERTION(mVMCount == 0, "View Manager count is incorrect");
|
||||||
|
@ -607,10 +626,15 @@ NS_IMETHODIMP nsViewManager::SetRootView(nsIView *aView)
|
||||||
NS_IMETHODIMP nsViewManager::GetWindowDimensions(nscoord *aWidth, nscoord *aHeight)
|
NS_IMETHODIMP nsViewManager::GetWindowDimensions(nscoord *aWidth, nscoord *aHeight)
|
||||||
{
|
{
|
||||||
if (nsnull != mRootView) {
|
if (nsnull != mRootView) {
|
||||||
|
if (mDelayedResize == nsSize(NSCOORD_NONE, NSCOORD_NONE)) {
|
||||||
nsRect dim;
|
nsRect dim;
|
||||||
mRootView->GetDimensions(dim);
|
mRootView->GetDimensions(dim);
|
||||||
*aWidth = dim.width;
|
*aWidth = dim.width;
|
||||||
*aHeight = dim.height;
|
*aHeight = dim.height;
|
||||||
|
} else {
|
||||||
|
*aWidth = mDelayedResize.width;
|
||||||
|
*aHeight = mDelayedResize.height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -622,18 +646,14 @@ NS_IMETHODIMP nsViewManager::GetWindowDimensions(nscoord *aWidth, nscoord *aHeig
|
||||||
|
|
||||||
NS_IMETHODIMP nsViewManager::SetWindowDimensions(nscoord aWidth, nscoord aHeight)
|
NS_IMETHODIMP nsViewManager::SetWindowDimensions(nscoord aWidth, nscoord aHeight)
|
||||||
{
|
{
|
||||||
// Resize the root view
|
if (mRootView) {
|
||||||
if (nsnull != mRootView) {
|
if (IsViewVisible(mRootView)) {
|
||||||
nsRect dim(0, 0, aWidth, aHeight);
|
mDelayedResize.SizeTo(NSCOORD_NONE, NSCOORD_NONE);
|
||||||
// Don't resize the widget. It is already being set elsewhere.
|
DoSetWindowDimensions(aWidth, aHeight);
|
||||||
mRootView->SetDimensions(dim, PR_TRUE, PR_FALSE);
|
} else {
|
||||||
|
mDelayedResize.SizeTo(aWidth, aHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("new dims: %d %d\n", aWidth, aHeight);
|
|
||||||
// Inform the presentation shell that we've been resized
|
|
||||||
if (nsnull != mObserver)
|
|
||||||
mObserver->ResizeReflow(mRootView, aWidth, aHeight);
|
|
||||||
//printf("reflow done\n");
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1811,6 +1831,7 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
|
||||||
|
|
||||||
case NS_PAINT:
|
case NS_PAINT:
|
||||||
{
|
{
|
||||||
|
nsPaintEvent *event = NS_STATIC_CAST(nsPaintEvent*, aEvent);
|
||||||
nsView *view = nsView::GetViewFor(aEvent->widget);
|
nsView *view = nsView::GetViewFor(aEvent->widget);
|
||||||
|
|
||||||
if (!view || !mContext)
|
if (!view || !mContext)
|
||||||
|
@ -1820,12 +1841,12 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
|
||||||
|
|
||||||
// The rect is in device units, and it's in the coordinate space of its
|
// The rect is in device units, and it's in the coordinate space of its
|
||||||
// associated window.
|
// associated window.
|
||||||
nsCOMPtr<nsIRegion> region = ((nsPaintEvent*)aEvent)->region;
|
nsCOMPtr<nsIRegion> region = event->region;
|
||||||
if (!region) {
|
if (!region) {
|
||||||
if (NS_FAILED(CreateRegion(getter_AddRefs(region))))
|
if (NS_FAILED(CreateRegion(getter_AddRefs(region))))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const nsRect& damrect = *((nsPaintEvent*)aEvent)->rect;
|
const nsRect& damrect = *event->rect;
|
||||||
region->SetTo(damrect.x, damrect.y, damrect.width, damrect.height);
|
region->SetTo(damrect.x, damrect.y, damrect.width, damrect.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1834,8 +1855,21 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
|
||||||
|
|
||||||
// Refresh the view
|
// Refresh the view
|
||||||
if (mRefreshEnabled) {
|
if (mRefreshEnabled) {
|
||||||
Refresh(view, ((nsPaintEvent*)aEvent)->renderingContext, region,
|
// If an ancestor widget was hidden and then shown, we could
|
||||||
|
// have a delayed resize to handle.
|
||||||
|
if (view == mRootView &&
|
||||||
|
mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
|
||||||
|
IsViewVisible(view)) {
|
||||||
|
DoSetWindowDimensions(mDelayedResize.width, mDelayedResize.height);
|
||||||
|
mDelayedResize.SizeTo(NSCOORD_NONE, NSCOORD_NONE);
|
||||||
|
|
||||||
|
// Paint later.
|
||||||
|
UpdateView(view, NS_VMREFRESH_NO_SYNC);
|
||||||
|
} else {
|
||||||
|
NS_ASSERTION(IsViewVisible(view), "painting an invisible view");
|
||||||
|
Refresh(view, event->renderingContext, region,
|
||||||
NS_VMREFRESH_DOUBLE_BUFFER);
|
NS_VMREFRESH_DOUBLE_BUFFER);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// since we got an NS_PAINT event, we need to
|
// since we got an NS_PAINT event, we need to
|
||||||
// draw something so we don't get blank areas.
|
// draw something so we don't get blank areas.
|
||||||
|
|
|
@ -351,6 +351,19 @@ private:
|
||||||
*/
|
*/
|
||||||
void GetMaxWidgetBounds(nsRect& aMaxWidgetBounds) const;
|
void GetMaxWidgetBounds(nsRect& aMaxWidgetBounds) const;
|
||||||
|
|
||||||
|
void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight)
|
||||||
|
{
|
||||||
|
nsRect oldDim;
|
||||||
|
nsRect newDim(0, 0, aWidth, aHeight);
|
||||||
|
mRootView->GetDimensions(oldDim);
|
||||||
|
if (oldDim != newDim) {
|
||||||
|
// Don't resize the widget. It is already being set elsewhere.
|
||||||
|
mRootView->SetDimensions(newDim, PR_TRUE, PR_FALSE);
|
||||||
|
if (mObserver)
|
||||||
|
mObserver->ResizeReflow(mRootView, aWidth, aHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public: // NOT in nsIViewManager, so private to the view module
|
public: // NOT in nsIViewManager, so private to the view module
|
||||||
nsView* GetRootView() const { return mRootView; }
|
nsView* GetRootView() const { return mRootView; }
|
||||||
nsView* GetMouseEventGrabber() const;
|
nsView* GetMouseEventGrabber() const;
|
||||||
|
@ -391,6 +404,11 @@ private:
|
||||||
nsIScrollableView *mRootScrollable;
|
nsIScrollableView *mRootScrollable;
|
||||||
nscolor mDefaultBackgroundColor;
|
nscolor mDefaultBackgroundColor;
|
||||||
nsPoint mMouseLocation; // device units, relative to mRootView
|
nsPoint mMouseLocation; // device units, relative to mRootView
|
||||||
|
|
||||||
|
// The size for a resize that we delayed until the root view becomes
|
||||||
|
// visible again.
|
||||||
|
nsSize mDelayedResize;
|
||||||
|
|
||||||
nsCOMPtr<nsIBlender> mBlender;
|
nsCOMPtr<nsIBlender> mBlender;
|
||||||
nsISupportsArray *mCompositeListeners;
|
nsISupportsArray *mCompositeListeners;
|
||||||
nsCOMPtr<nsIFactory> mRegionFactory;
|
nsCOMPtr<nsIFactory> mRegionFactory;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче