зеркало из https://github.com/mozilla/pjs.git
Bug 598482 part 18 - Separate NS_WILL_PAINT and NS_PAINT handling; only flush again if no NS_WILL_PAINT event has been sent by the platform. r=roc
This commit is contained in:
Родитель
2eef95f959
Коммит
7e9c8ecff4
|
@ -753,34 +753,20 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NS_WILL_PAINT:
|
case NS_WILL_PAINT:
|
||||||
case NS_PAINT:
|
|
||||||
{
|
{
|
||||||
nsPaintEvent *event = static_cast<nsPaintEvent*>(aEvent);
|
|
||||||
|
|
||||||
if (!aView || !mContext)
|
if (!aView || !mContext)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
*aStatus = nsEventStatus_eConsumeNoDefault;
|
*aStatus = nsEventStatus_eConsumeNoDefault;
|
||||||
|
|
||||||
if (aEvent->message == NS_PAINT && event->region.IsEmpty())
|
nsPaintEvent *event = static_cast<nsPaintEvent*>(aEvent);
|
||||||
break;
|
|
||||||
|
|
||||||
NS_ASSERTION(static_cast<nsView*>(aView) ==
|
NS_ASSERTION(static_cast<nsView*>(aView) ==
|
||||||
nsView::GetViewFor(event->widget),
|
nsView::GetViewFor(event->widget),
|
||||||
"view/widget mismatch");
|
"view/widget mismatch");
|
||||||
|
|
||||||
// The region is in device units, and it's in the coordinate space of
|
|
||||||
// its associated widget.
|
|
||||||
|
|
||||||
// Refresh the view
|
|
||||||
NS_ASSERTION(IsPaintingAllowed(),
|
|
||||||
"shouldn't be receiving paint events while painting is "
|
|
||||||
"disallowed!");
|
|
||||||
nsRefPtr<nsViewManager> rootVM = RootViewManager();
|
|
||||||
|
|
||||||
// If an ancestor widget was hidden and then shown, we could
|
// If an ancestor widget was hidden and then shown, we could
|
||||||
// have a delayed resize to handle.
|
// have a delayed resize to handle.
|
||||||
bool didResize = false;
|
|
||||||
for (nsViewManager *vm = this; vm;
|
for (nsViewManager *vm = this; vm;
|
||||||
vm = vm->mRootView->GetParent()
|
vm = vm->mRootView->GetParent()
|
||||||
? vm->mRootView->GetParent()->GetViewManager()
|
? vm->mRootView->GetParent()->GetViewManager()
|
||||||
|
@ -789,47 +775,51 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
|
||||||
vm->mRootView->IsEffectivelyVisible() &&
|
vm->mRootView->IsEffectivelyVisible() &&
|
||||||
mPresShell && mPresShell->IsVisible()) {
|
mPresShell && mPresShell->IsVisible()) {
|
||||||
vm->FlushDelayedResize(true);
|
vm->FlushDelayedResize(true);
|
||||||
|
|
||||||
// Paint later.
|
|
||||||
vm->UpdateView(vm->mRootView);
|
vm->UpdateView(vm->mRootView);
|
||||||
didResize = true;
|
|
||||||
|
|
||||||
// not sure if it's valid for us to claim that we
|
|
||||||
// ignored this, but we're going to do so anyway, since
|
|
||||||
// we didn't actually paint anything
|
|
||||||
*aStatus = nsEventStatus_eIgnore;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!didResize) {
|
// Flush things like reflows and plugin widget geometry updates by
|
||||||
// Notify view observers that we're about to paint.
|
// calling WillPaint on observer presShells.
|
||||||
// Make sure to not send WillPaint notifications while scrolling.
|
nsRefPtr<nsViewManager> rootVM = RootViewManager();
|
||||||
|
if (mPresShell) {
|
||||||
nsCOMPtr<nsIWidget> widget;
|
rootVM->CallWillPaintOnObservers(event->willSendDidPaint);
|
||||||
rootVM->GetRootWidget(getter_AddRefs(widget));
|
|
||||||
bool transparentWindow = false;
|
|
||||||
if (widget)
|
|
||||||
transparentWindow = widget->GetTransparencyMode() == eTransparencyTransparent;
|
|
||||||
|
|
||||||
nsView* view = static_cast<nsView*>(aView);
|
|
||||||
if (!transparentWindow) {
|
|
||||||
if (mPresShell) {
|
|
||||||
rootVM->CallWillPaintOnObservers(event->willSendDidPaint);
|
|
||||||
// Get the view pointer again since the code above might have
|
|
||||||
// destroyed it (bug 378273).
|
|
||||||
view = nsView::GetViewFor(aEvent->widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Make sure to sync up any widget geometry changes we
|
|
||||||
// have pending before we paint.
|
|
||||||
if (rootVM->mHasPendingUpdates) {
|
|
||||||
rootVM->ProcessPendingUpdatesForView(mRootView);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (view && aEvent->message == NS_PAINT) {
|
|
||||||
Refresh(view, event->widget, event->region);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// Flush view widget geometry updates and invalidations.
|
||||||
|
rootVM->ProcessPendingUpdates();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NS_PAINT:
|
||||||
|
{
|
||||||
|
if (!aView || !mContext)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*aStatus = nsEventStatus_eConsumeNoDefault;
|
||||||
|
nsPaintEvent *event = static_cast<nsPaintEvent*>(aEvent);
|
||||||
|
nsView* view = static_cast<nsView*>(aView);
|
||||||
|
NS_ASSERTION(view == nsView::GetViewFor(event->widget),
|
||||||
|
"view/widget mismatch");
|
||||||
|
NS_ASSERTION(IsPaintingAllowed(),
|
||||||
|
"shouldn't be receiving paint events while painting is "
|
||||||
|
"disallowed!");
|
||||||
|
|
||||||
|
if (!event->didSendWillPaint) {
|
||||||
|
// Send NS_WILL_PAINT event ourselves.
|
||||||
|
nsPaintEvent willPaintEvent(true, NS_WILL_PAINT, event->widget);
|
||||||
|
willPaintEvent.willSendDidPaint = event->willSendDidPaint;
|
||||||
|
DispatchEvent(&willPaintEvent, view, aStatus);
|
||||||
|
|
||||||
|
// Get the view pointer again since NS_WILL_PAINT might have
|
||||||
|
// destroyed it during CallWillPaintOnObservers (bug 378273).
|
||||||
|
view = nsView::GetViewFor(event->widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!view || event->region.IsEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Paint.
|
||||||
|
Refresh(view, event->widget, event->region);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2508,6 +2508,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||||
#endif
|
#endif
|
||||||
// Create the event so we can fill in its region
|
// Create the event so we can fill in its region
|
||||||
nsPaintEvent paintEvent(true, NS_PAINT, mGeckoChild);
|
nsPaintEvent paintEvent(true, NS_PAINT, mGeckoChild);
|
||||||
|
paintEvent.didSendWillPaint = true;
|
||||||
|
|
||||||
nsIntRect boundingRect =
|
nsIntRect boundingRect =
|
||||||
nsIntRect(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height);
|
nsIntRect(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height);
|
||||||
|
|
|
@ -737,13 +737,15 @@ class nsPaintEvent : public nsGUIEvent
|
||||||
public:
|
public:
|
||||||
nsPaintEvent(bool isTrusted, PRUint32 msg, nsIWidget *w)
|
nsPaintEvent(bool isTrusted, PRUint32 msg, nsIWidget *w)
|
||||||
: nsGUIEvent(isTrusted, msg, w, NS_PAINT_EVENT),
|
: nsGUIEvent(isTrusted, msg, w, NS_PAINT_EVENT),
|
||||||
willSendDidPaint(false)
|
willSendDidPaint(false),
|
||||||
|
didSendWillPaint(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// area that needs repainting
|
// area that needs repainting
|
||||||
nsIntRegion region;
|
nsIntRegion region;
|
||||||
bool willSendDidPaint;
|
bool willSendDidPaint;
|
||||||
|
bool didSendWillPaint;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -312,6 +312,7 @@ bool nsWindow::OnPaint(HDC aDC, PRUint32 aNestingLevel)
|
||||||
#endif
|
#endif
|
||||||
event.region = GetRegionToPaint(forceRepaint, ps, hDC);
|
event.region = GetRegionToPaint(forceRepaint, ps, hDC);
|
||||||
event.willSendDidPaint = true;
|
event.willSendDidPaint = true;
|
||||||
|
event.didSendWillPaint = true;
|
||||||
|
|
||||||
if (!event.region.IsEmpty() && mEventCallback)
|
if (!event.region.IsEmpty() && mEventCallback)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче