view/src/nsView.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/view/src/nsView.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1101 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nsView.h"
    1.10 +
    1.11 +#include "mozilla/Attributes.h"
    1.12 +#include "mozilla/BasicEvents.h"
    1.13 +#include "mozilla/DebugOnly.h"
    1.14 +#include "mozilla/IntegerPrintfMacros.h"
    1.15 +#include "mozilla/Likely.h"
    1.16 +#include "mozilla/Poison.h"
    1.17 +#include "nsIWidget.h"
    1.18 +#include "nsViewManager.h"
    1.19 +#include "nsIFrame.h"
    1.20 +#include "nsPresArena.h"
    1.21 +#include "nsXULPopupManager.h"
    1.22 +#include "nsIWidgetListener.h"
    1.23 +#include "nsContentUtils.h" // for nsAutoScriptBlocker
    1.24 +
    1.25 +using namespace mozilla;
    1.26 +
    1.27 +nsView::nsView(nsViewManager* aViewManager, nsViewVisibility aVisibility)
    1.28 +{
    1.29 +  MOZ_COUNT_CTOR(nsView);
    1.30 +
    1.31 +  mVis = aVisibility;
    1.32 +  // Views should be transparent by default. Not being transparent is
    1.33 +  // a promise that the view will paint all its pixels opaquely. Views
    1.34 +  // should make this promise explicitly by calling
    1.35 +  // SetViewContentTransparency.
    1.36 +  mVFlags = 0;
    1.37 +  mViewManager = aViewManager;
    1.38 +  mDirtyRegion = nullptr;
    1.39 +  mWidgetIsTopLevel = false;
    1.40 +}
    1.41 +
    1.42 +void nsView::DropMouseGrabbing()
    1.43 +{
    1.44 +  nsIPresShell* presShell = mViewManager->GetPresShell();
    1.45 +  if (presShell)
    1.46 +    presShell->ClearMouseCaptureOnView(this);
    1.47 +}
    1.48 +
    1.49 +nsView::~nsView()
    1.50 +{
    1.51 +  MOZ_COUNT_DTOR(nsView);
    1.52 +
    1.53 +  while (GetFirstChild())
    1.54 +  {
    1.55 +    nsView* child = GetFirstChild();
    1.56 +    if (child->GetViewManager() == mViewManager) {
    1.57 +      child->Destroy();
    1.58 +    } else {
    1.59 +      // just unhook it. Someone else will want to destroy this.
    1.60 +      RemoveChild(child);
    1.61 +    }
    1.62 +  }
    1.63 +
    1.64 +  if (mViewManager)
    1.65 +  {
    1.66 +    DropMouseGrabbing();
    1.67 +  
    1.68 +    nsView *rootView = mViewManager->GetRootView();
    1.69 +    
    1.70 +    if (rootView)
    1.71 +    {
    1.72 +      // Root views can have parents!
    1.73 +      if (mParent)
    1.74 +      {
    1.75 +        mViewManager->RemoveChild(this);
    1.76 +      }
    1.77 +
    1.78 +      if (rootView == this)
    1.79 +      {
    1.80 +        // Inform the view manager that the root view has gone away...
    1.81 +        mViewManager->SetRootView(nullptr);
    1.82 +      }
    1.83 +    }
    1.84 +    else if (mParent)
    1.85 +    {
    1.86 +      mParent->RemoveChild(this);
    1.87 +    }
    1.88 +    
    1.89 +    mViewManager = nullptr;
    1.90 +  }
    1.91 +  else if (mParent)
    1.92 +  {
    1.93 +    mParent->RemoveChild(this);
    1.94 +  }
    1.95 +
    1.96 +  // Destroy and release the widget
    1.97 +  DestroyWidget();
    1.98 +
    1.99 +  delete mDirtyRegion;
   1.100 +}
   1.101 +
   1.102 +class DestroyWidgetRunnable : public nsRunnable {
   1.103 +public:
   1.104 +  NS_DECL_NSIRUNNABLE
   1.105 +
   1.106 +  explicit DestroyWidgetRunnable(nsIWidget* aWidget) : mWidget(aWidget) {}
   1.107 +
   1.108 +private:
   1.109 +  nsCOMPtr<nsIWidget> mWidget;
   1.110 +};
   1.111 +
   1.112 +NS_IMETHODIMP DestroyWidgetRunnable::Run()
   1.113 +{
   1.114 +  mWidget->Destroy();
   1.115 +  mWidget = nullptr;
   1.116 +  return NS_OK;
   1.117 +}
   1.118 +
   1.119 +
   1.120 +void nsView::DestroyWidget()
   1.121 +{
   1.122 +  if (mWindow)
   1.123 +  {
   1.124 +    // If we are not attached to a base window, we're going to tear down our
   1.125 +    // widget here. However, if we're attached to somebody elses widget, we
   1.126 +    // want to leave the widget alone: don't reset the client data or call
   1.127 +    // Destroy. Just clear our event view ptr and free our reference to it. 
   1.128 +    if (mWidgetIsTopLevel) {
   1.129 +      mWindow->SetAttachedWidgetListener(nullptr);
   1.130 +    }
   1.131 +    else {
   1.132 +      mWindow->SetWidgetListener(nullptr);
   1.133 +
   1.134 +      nsCOMPtr<nsIRunnable> widgetDestroyer =
   1.135 +        new DestroyWidgetRunnable(mWindow);
   1.136 +
   1.137 +      NS_DispatchToMainThread(widgetDestroyer);
   1.138 +    }
   1.139 +
   1.140 +    NS_RELEASE(mWindow);
   1.141 +  }
   1.142 +}
   1.143 +
   1.144 +nsView* nsView::GetViewFor(nsIWidget* aWidget)
   1.145 +{
   1.146 +  NS_PRECONDITION(nullptr != aWidget, "null widget ptr");
   1.147 +
   1.148 +  nsIWidgetListener* listener = aWidget->GetWidgetListener();
   1.149 +  if (listener) {
   1.150 +    nsView* view = listener->GetView();
   1.151 +    if (view)
   1.152 +      return view;
   1.153 +  }
   1.154 +
   1.155 +  listener = aWidget->GetAttachedWidgetListener();
   1.156 +  return listener ? listener->GetView() : nullptr;
   1.157 +}
   1.158 +
   1.159 +void nsView::Destroy()
   1.160 +{
   1.161 +  this->~nsView();
   1.162 +  mozWritePoison(this, sizeof(*this));
   1.163 +  nsView::operator delete(this);
   1.164 +}
   1.165 +
   1.166 +void nsView::SetPosition(nscoord aX, nscoord aY)
   1.167 +{
   1.168 +  mDimBounds.x += aX - mPosX;
   1.169 +  mDimBounds.y += aY - mPosY;
   1.170 +  mPosX = aX;
   1.171 +  mPosY = aY;
   1.172 +
   1.173 +  NS_ASSERTION(GetParent() || (aX == 0 && aY == 0),
   1.174 +               "Don't try to move the root widget to something non-zero");
   1.175 +
   1.176 +  ResetWidgetBounds(true, false);
   1.177 +}
   1.178 +
   1.179 +void nsView::ResetWidgetBounds(bool aRecurse, bool aForceSync)
   1.180 +{
   1.181 +  if (mWindow) {
   1.182 +    if (!aForceSync) {
   1.183 +      // Don't change widget geometry synchronously, since that can
   1.184 +      // cause synchronous painting.
   1.185 +      mViewManager->PostPendingUpdate();
   1.186 +    } else {
   1.187 +      DoResetWidgetBounds(false, true);
   1.188 +    }
   1.189 +    return;
   1.190 +  }
   1.191 +
   1.192 +  if (aRecurse) {
   1.193 +    // reposition any widgets under this view
   1.194 +    for (nsView* v = GetFirstChild(); v; v = v->GetNextSibling()) {
   1.195 +      v->ResetWidgetBounds(true, aForceSync);
   1.196 +    }
   1.197 +  }
   1.198 +}
   1.199 +
   1.200 +bool nsView::IsEffectivelyVisible()
   1.201 +{
   1.202 +  for (nsView* v = this; v; v = v->mParent) {
   1.203 +    if (v->GetVisibility() == nsViewVisibility_kHide)
   1.204 +      return false;
   1.205 +  }
   1.206 +  return true;
   1.207 +}
   1.208 +
   1.209 +nsIntRect nsView::CalcWidgetBounds(nsWindowType aType)
   1.210 +{
   1.211 +  int32_t p2a = mViewManager->AppUnitsPerDevPixel();
   1.212 +
   1.213 +  nsRect viewBounds(mDimBounds);
   1.214 +
   1.215 +  nsView* parent = GetParent();
   1.216 +  nsIWidget* parentWidget = nullptr;
   1.217 +  if (parent) {
   1.218 +    nsPoint offset;
   1.219 +    parentWidget = parent->GetNearestWidget(&offset, p2a);
   1.220 +    // make viewBounds be relative to the parent widget, in appunits
   1.221 +    viewBounds += offset;
   1.222 +
   1.223 +    if (parentWidget && aType == eWindowType_popup &&
   1.224 +        IsEffectivelyVisible()) {
   1.225 +      // put offset into screen coordinates. (based on client area origin)
   1.226 +      nsIntPoint screenPoint = parentWidget->WidgetToScreenOffset();
   1.227 +      viewBounds += nsPoint(NSIntPixelsToAppUnits(screenPoint.x, p2a),
   1.228 +                            NSIntPixelsToAppUnits(screenPoint.y, p2a));
   1.229 +    }
   1.230 +  }
   1.231 +
   1.232 +  // Compute widget bounds in device pixels
   1.233 +  nsIntRect newBounds = viewBounds.ToNearestPixels(p2a);
   1.234 +
   1.235 +#ifdef XP_MACOSX
   1.236 +  // cocoa rounds widget coordinates to the nearest global "display pixel"
   1.237 +  // integer value. So we avoid fractional display pixel values by rounding
   1.238 +  // to the nearest value that won't yield a fractional display pixel.
   1.239 +  nsIWidget* widget = parentWidget ? parentWidget : mWindow;
   1.240 +  uint32_t round;
   1.241 +  if (aType == eWindowType_popup && widget &&
   1.242 +      ((round = widget->RoundsWidgetCoordinatesTo()) > 1)) {
   1.243 +    nsIntSize pixelRoundedSize = newBounds.Size();
   1.244 +    // round the top left and bottom right to the nearest round pixel
   1.245 +    newBounds.x = NSToIntRoundUp(NSAppUnitsToDoublePixels(viewBounds.x, p2a) / round) * round;
   1.246 +    newBounds.y = NSToIntRoundUp(NSAppUnitsToDoublePixels(viewBounds.y, p2a) / round) * round;
   1.247 +    newBounds.width =
   1.248 +      NSToIntRoundUp(NSAppUnitsToDoublePixels(viewBounds.XMost(), p2a) / round) * round - newBounds.x;
   1.249 +    newBounds.height =
   1.250 +      NSToIntRoundUp(NSAppUnitsToDoublePixels(viewBounds.YMost(), p2a) / round) * round - newBounds.y;
   1.251 +    // but if that makes the widget larger then our frame may not paint the
   1.252 +    // extra pixels, so reduce the size to the nearest round value
   1.253 +    if (newBounds.width > pixelRoundedSize.width) {
   1.254 +      newBounds.width -= round;
   1.255 +    }
   1.256 +    if (newBounds.height > pixelRoundedSize.height) {
   1.257 +      newBounds.height -= round;
   1.258 +    }
   1.259 +  }
   1.260 +#endif
   1.261 +
   1.262 +  // Compute where the top-left of our widget ended up relative to the parent
   1.263 +  // widget, in appunits.
   1.264 +  nsPoint roundedOffset(NSIntPixelsToAppUnits(newBounds.x, p2a),
   1.265 +                        NSIntPixelsToAppUnits(newBounds.y, p2a));
   1.266 +
   1.267 +  // mViewToWidgetOffset is added to coordinates relative to the view origin
   1.268 +  // to get coordinates relative to the widget.
   1.269 +  // The view origin, relative to the parent widget, is at
   1.270 +  // (mPosX,mPosY) - mDimBounds.TopLeft() + viewBounds.TopLeft().
   1.271 +  // Our widget, relative to the parent widget, is roundedOffset.
   1.272 +  mViewToWidgetOffset = nsPoint(mPosX, mPosY)
   1.273 +    - mDimBounds.TopLeft() + viewBounds.TopLeft() - roundedOffset;
   1.274 +
   1.275 +  return newBounds;
   1.276 +}
   1.277 +
   1.278 +void nsView::DoResetWidgetBounds(bool aMoveOnly,
   1.279 +                                 bool aInvalidateChangedSize) {
   1.280 +  // The geometry of a root view's widget is controlled externally,
   1.281 +  // NOT by sizing or positioning the view
   1.282 +  if (mViewManager->GetRootView() == this) {
   1.283 +    return;
   1.284 +  }
   1.285 +
   1.286 +  NS_PRECONDITION(mWindow, "Why was this called??");
   1.287 +
   1.288 +  // Hold this ref to make sure it stays alive.
   1.289 +  nsCOMPtr<nsIWidget> widget = mWindow;
   1.290 +
   1.291 +  // Stash a copy of these and use them so we can handle this being deleted (say
   1.292 +  // from sync painting/flushing from Show/Move/Resize on the widget).
   1.293 +  nsIntRect newBounds;
   1.294 +  nsRefPtr<nsDeviceContext> dx = mViewManager->GetDeviceContext();
   1.295 +
   1.296 +  nsWindowType type = widget->WindowType();
   1.297 +
   1.298 +  nsIntRect curBounds;
   1.299 +  widget->GetClientBounds(curBounds);
   1.300 +  bool invisiblePopup = type == eWindowType_popup &&
   1.301 +                        ((curBounds.IsEmpty() && mDimBounds.IsEmpty()) ||
   1.302 +                         mVis == nsViewVisibility_kHide);
   1.303 +
   1.304 +  if (invisiblePopup) {
   1.305 +    // We're going to hit the early exit below, avoid calling CalcWidgetBounds.
   1.306 +  } else {
   1.307 +    newBounds = CalcWidgetBounds(type);
   1.308 +  }
   1.309 +
   1.310 +  bool curVisibility = widget->IsVisible();
   1.311 +  bool newVisibility = IsEffectivelyVisible();
   1.312 +  if (curVisibility && !newVisibility) {
   1.313 +    widget->Show(false);
   1.314 +  }
   1.315 +
   1.316 +  if (invisiblePopup) {
   1.317 +    // Don't manipulate empty or hidden popup widgets. For example there's no
   1.318 +    // point moving hidden comboboxes around, or doing X server roundtrips
   1.319 +    // to compute their true screen position. This could mean that WidgetToScreen
   1.320 +    // operations on these widgets don't return up-to-date values, but popup
   1.321 +    // positions aren't reliable anyway because of correction to be on or off-screen.
   1.322 +    return;
   1.323 +  }
   1.324 +
   1.325 +  bool changedPos = curBounds.TopLeft() != newBounds.TopLeft();
   1.326 +  bool changedSize = curBounds.Size() != newBounds.Size();
   1.327 +
   1.328 +  // Child views are never attached to top level widgets, this is safe.
   1.329 +
   1.330 +  // Coordinates are converted to display pixels for window Move/Resize APIs,
   1.331 +  // because of the potential for device-pixel coordinate spaces for mixed
   1.332 +  // hidpi/lodpi screens to overlap each other and result in bad placement
   1.333 +  // (bug 814434).
   1.334 +  double invScale;
   1.335 +
   1.336 +  // Bug 861270: for correct widget manipulation at arbitrary scale factors,
   1.337 +  // prefer to base scaling on widget->GetDefaultScale(). But only do this if
   1.338 +  // it matches the view manager's device context scale after allowing for the
   1.339 +  // quantization to app units, because of OS X multiscreen issues (where the
   1.340 +  // only two scales are 1.0 or 2.0, and so the quantization doesn't actually
   1.341 +  // cause problems anyhow).
   1.342 +  // In the case of a mismatch, fall back to scaling based on the dev context's
   1.343 +  // unscaledAppUnitsPerDevPixel value. On platforms where the device-pixel
   1.344 +  // scale is uniform across all displays (currently all except OS X), we'll
   1.345 +  // always use the precise value from mWindow->GetDefaultScale here.
   1.346 +  CSSToLayoutDeviceScale scale = widget->GetDefaultScale();
   1.347 +  if (NSToIntRound(60.0 / scale.scale) == dx->UnscaledAppUnitsPerDevPixel()) {
   1.348 +    invScale = 1.0 / scale.scale;
   1.349 +  } else {
   1.350 +    invScale = dx->UnscaledAppUnitsPerDevPixel() / 60.0;
   1.351 +  }
   1.352 +
   1.353 +  if (changedPos) {
   1.354 +    if (changedSize && !aMoveOnly) {
   1.355 +      widget->ResizeClient(newBounds.x * invScale,
   1.356 +                           newBounds.y * invScale,
   1.357 +                           newBounds.width * invScale,
   1.358 +                           newBounds.height * invScale,
   1.359 +                           aInvalidateChangedSize);
   1.360 +    } else {
   1.361 +      widget->MoveClient(newBounds.x * invScale,
   1.362 +                         newBounds.y * invScale);
   1.363 +    }
   1.364 +  } else {
   1.365 +    if (changedSize && !aMoveOnly) {
   1.366 +      widget->ResizeClient(newBounds.width * invScale,
   1.367 +                           newBounds.height * invScale,
   1.368 +                           aInvalidateChangedSize);
   1.369 +    } // else do nothing!
   1.370 +  }
   1.371 +
   1.372 +  if (!curVisibility && newVisibility) {
   1.373 +    widget->Show(true);
   1.374 +  }
   1.375 +}
   1.376 +
   1.377 +void nsView::SetDimensions(const nsRect& aRect, bool aPaint, bool aResizeWidget)
   1.378 +{
   1.379 +  nsRect dims = aRect;
   1.380 +  dims.MoveBy(mPosX, mPosY);
   1.381 +
   1.382 +  // Don't use nsRect's operator== here, since it returns true when
   1.383 +  // both rects are empty even if they have different widths and we
   1.384 +  // have cases where that sort of thing matters to us.
   1.385 +  if (mDimBounds.TopLeft() == dims.TopLeft() &&
   1.386 +      mDimBounds.Size() == dims.Size()) {
   1.387 +    return;
   1.388 +  }
   1.389 +
   1.390 +  mDimBounds = dims;
   1.391 +
   1.392 +  if (aResizeWidget) {
   1.393 +    ResetWidgetBounds(false, false);
   1.394 +  }
   1.395 +}
   1.396 +
   1.397 +void nsView::NotifyEffectiveVisibilityChanged(bool aEffectivelyVisible)
   1.398 +{
   1.399 +  if (!aEffectivelyVisible)
   1.400 +  {
   1.401 +    DropMouseGrabbing();
   1.402 +  }
   1.403 +
   1.404 +  SetForcedRepaint(true);
   1.405 +
   1.406 +  if (nullptr != mWindow)
   1.407 +  {
   1.408 +    ResetWidgetBounds(false, false);
   1.409 +  }
   1.410 +
   1.411 +  for (nsView* child = mFirstChild; child; child = child->mNextSibling) {
   1.412 +    if (child->mVis == nsViewVisibility_kHide) {
   1.413 +      // It was effectively hidden and still is
   1.414 +      continue;
   1.415 +    }
   1.416 +    // Our child is visible if we are
   1.417 +    child->NotifyEffectiveVisibilityChanged(aEffectivelyVisible);
   1.418 +  }
   1.419 +}
   1.420 +
   1.421 +void nsView::SetVisibility(nsViewVisibility aVisibility)
   1.422 +{
   1.423 +  mVis = aVisibility;
   1.424 +  NotifyEffectiveVisibilityChanged(IsEffectivelyVisible());
   1.425 +}
   1.426 +
   1.427 +void nsView::SetFloating(bool aFloatingView)
   1.428 +{
   1.429 +	if (aFloatingView)
   1.430 +		mVFlags |= NS_VIEW_FLAG_FLOATING;
   1.431 +	else
   1.432 +		mVFlags &= ~NS_VIEW_FLAG_FLOATING;
   1.433 +}
   1.434 +
   1.435 +void nsView::InvalidateHierarchy(nsViewManager *aViewManagerParent)
   1.436 +{
   1.437 +  if (mViewManager->GetRootView() == this)
   1.438 +    mViewManager->InvalidateHierarchy();
   1.439 +
   1.440 +  for (nsView *child = mFirstChild; child; child = child->GetNextSibling())
   1.441 +    child->InvalidateHierarchy(aViewManagerParent);
   1.442 +}
   1.443 +
   1.444 +void nsView::InsertChild(nsView *aChild, nsView *aSibling)
   1.445 +{
   1.446 +  NS_PRECONDITION(nullptr != aChild, "null ptr");
   1.447 +
   1.448 +  if (nullptr != aChild)
   1.449 +  {
   1.450 +    if (nullptr != aSibling)
   1.451 +    {
   1.452 +#ifdef DEBUG
   1.453 +      NS_ASSERTION(aSibling->GetParent() == this, "tried to insert view with invalid sibling");
   1.454 +#endif
   1.455 +      //insert after sibling
   1.456 +      aChild->SetNextSibling(aSibling->GetNextSibling());
   1.457 +      aSibling->SetNextSibling(aChild);
   1.458 +    }
   1.459 +    else
   1.460 +    {
   1.461 +      aChild->SetNextSibling(mFirstChild);
   1.462 +      mFirstChild = aChild;
   1.463 +    }
   1.464 +    aChild->SetParent(this);
   1.465 +
   1.466 +    // If we just inserted a root view, then update the RootViewManager
   1.467 +    // on all view managers in the new subtree.
   1.468 +
   1.469 +    nsViewManager *vm = aChild->GetViewManager();
   1.470 +    if (vm->GetRootView() == aChild)
   1.471 +    {
   1.472 +      aChild->InvalidateHierarchy(nullptr); // don't care about releasing grabs
   1.473 +    }
   1.474 +  }
   1.475 +}
   1.476 +
   1.477 +void nsView::RemoveChild(nsView *child)
   1.478 +{
   1.479 +  NS_PRECONDITION(nullptr != child, "null ptr");
   1.480 +
   1.481 +  if (nullptr != child)
   1.482 +  {
   1.483 +    nsView* prevKid = nullptr;
   1.484 +    nsView* kid = mFirstChild;
   1.485 +    DebugOnly<bool> found = false;
   1.486 +    while (nullptr != kid) {
   1.487 +      if (kid == child) {
   1.488 +        if (nullptr != prevKid) {
   1.489 +          prevKid->SetNextSibling(kid->GetNextSibling());
   1.490 +        } else {
   1.491 +          mFirstChild = kid->GetNextSibling();
   1.492 +        }
   1.493 +        child->SetParent(nullptr);
   1.494 +        found = true;
   1.495 +        break;
   1.496 +      }
   1.497 +      prevKid = kid;
   1.498 +	    kid = kid->GetNextSibling();
   1.499 +    }
   1.500 +    NS_ASSERTION(found, "tried to remove non child");
   1.501 +
   1.502 +    // If we just removed a root view, then update the RootViewManager
   1.503 +    // on all view managers in the removed subtree.
   1.504 +
   1.505 +    nsViewManager *vm = child->GetViewManager();
   1.506 +    if (vm->GetRootView() == child)
   1.507 +    {
   1.508 +      child->InvalidateHierarchy(GetViewManager());
   1.509 +    }
   1.510 +  }
   1.511 +}
   1.512 +
   1.513 +// Native widgets ultimately just can't deal with the awesome power of
   1.514 +// CSS2 z-index. However, we set the z-index on the widget anyway
   1.515 +// because in many simple common cases the widgets do end up in the
   1.516 +// right order. We set each widget's z-index to the z-index of the
   1.517 +// nearest ancestor that has non-auto z-index.
   1.518 +static void UpdateNativeWidgetZIndexes(nsView* aView, int32_t aZIndex)
   1.519 +{
   1.520 +  if (aView->HasWidget()) {
   1.521 +    nsIWidget* widget = aView->GetWidget();
   1.522 +    if (widget->GetZIndex() != aZIndex) {
   1.523 +      widget->SetZIndex(aZIndex);
   1.524 +    }
   1.525 +  } else {
   1.526 +    for (nsView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
   1.527 +      if (v->GetZIndexIsAuto()) {
   1.528 +        UpdateNativeWidgetZIndexes(v, aZIndex);
   1.529 +      }
   1.530 +    }
   1.531 +  }
   1.532 +}
   1.533 +
   1.534 +static int32_t FindNonAutoZIndex(nsView* aView)
   1.535 +{
   1.536 +  while (aView) {
   1.537 +    if (!aView->GetZIndexIsAuto()) {
   1.538 +      return aView->GetZIndex();
   1.539 +    }
   1.540 +    aView = aView->GetParent();
   1.541 +  }
   1.542 +  return 0;
   1.543 +}
   1.544 +
   1.545 +struct DefaultWidgetInitData : public nsWidgetInitData {
   1.546 +  DefaultWidgetInitData() : nsWidgetInitData()
   1.547 +  {
   1.548 +    mWindowType = eWindowType_child;
   1.549 +    clipChildren = true;
   1.550 +    clipSiblings = true;
   1.551 +  }
   1.552 +};
   1.553 +
   1.554 +nsresult nsView::CreateWidget(nsWidgetInitData *aWidgetInitData,
   1.555 +                               bool aEnableDragDrop,
   1.556 +                               bool aResetVisibility)
   1.557 +{
   1.558 +  AssertNoWindow();
   1.559 +  NS_ABORT_IF_FALSE(!aWidgetInitData ||
   1.560 +                    aWidgetInitData->mWindowType != eWindowType_popup,
   1.561 +                    "Use CreateWidgetForPopup");
   1.562 +
   1.563 +  DefaultWidgetInitData defaultInitData;
   1.564 +  bool initDataPassedIn = !!aWidgetInitData;
   1.565 +  aWidgetInitData = aWidgetInitData ? aWidgetInitData : &defaultInitData;
   1.566 +  defaultInitData.mListenForResizes =
   1.567 +    (!initDataPassedIn && GetParent() &&
   1.568 +     GetParent()->GetViewManager() != mViewManager);
   1.569 +
   1.570 +  nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
   1.571 +
   1.572 +  nsRefPtr<nsDeviceContext> dx = mViewManager->GetDeviceContext();
   1.573 +
   1.574 +  nsIWidget* parentWidget =
   1.575 +    GetParent() ? GetParent()->GetNearestWidget(nullptr) : nullptr;
   1.576 +  if (!parentWidget) {
   1.577 +    NS_ERROR("nsView::CreateWidget without suitable parent widget??");
   1.578 +    return NS_ERROR_FAILURE;
   1.579 +  }
   1.580 +
   1.581 +  // XXX: using aForceUseIWidgetParent=true to preserve previous
   1.582 +  // semantics.  It's not clear that it's actually needed.
   1.583 +  mWindow = parentWidget->CreateChild(trect, dx, aWidgetInitData,
   1.584 +                                      true).take();
   1.585 +  if (!mWindow) {
   1.586 +    return NS_ERROR_FAILURE;
   1.587 +  }
   1.588 + 
   1.589 +  InitializeWindow(aEnableDragDrop, aResetVisibility);
   1.590 +
   1.591 +  return NS_OK;
   1.592 +}
   1.593 +
   1.594 +nsresult nsView::CreateWidgetForParent(nsIWidget* aParentWidget,
   1.595 +                                        nsWidgetInitData *aWidgetInitData,
   1.596 +                                        bool aEnableDragDrop,
   1.597 +                                        bool aResetVisibility)
   1.598 +{
   1.599 +  AssertNoWindow();
   1.600 +  NS_ABORT_IF_FALSE(!aWidgetInitData ||
   1.601 +                    aWidgetInitData->mWindowType != eWindowType_popup,
   1.602 +                    "Use CreateWidgetForPopup");
   1.603 +  NS_ABORT_IF_FALSE(aParentWidget, "Parent widget required");
   1.604 +
   1.605 +  DefaultWidgetInitData defaultInitData;
   1.606 +  aWidgetInitData = aWidgetInitData ? aWidgetInitData : &defaultInitData;
   1.607 +
   1.608 +  nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
   1.609 +
   1.610 +  nsRefPtr<nsDeviceContext> dx = mViewManager->GetDeviceContext();
   1.611 +
   1.612 +  mWindow =
   1.613 +    aParentWidget->CreateChild(trect, dx, aWidgetInitData).take();
   1.614 +  if (!mWindow) {
   1.615 +    return NS_ERROR_FAILURE;
   1.616 +  }
   1.617 +
   1.618 +  InitializeWindow(aEnableDragDrop, aResetVisibility);
   1.619 +
   1.620 +  return NS_OK;
   1.621 +}
   1.622 +
   1.623 +nsresult nsView::CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
   1.624 +                                       nsIWidget* aParentWidget,
   1.625 +                                       bool aEnableDragDrop,
   1.626 +                                       bool aResetVisibility)
   1.627 +{
   1.628 +  AssertNoWindow();
   1.629 +  NS_ABORT_IF_FALSE(aWidgetInitData, "Widget init data required");
   1.630 +  NS_ABORT_IF_FALSE(aWidgetInitData->mWindowType == eWindowType_popup,
   1.631 +                    "Use one of the other CreateWidget methods");
   1.632 +
   1.633 +  nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
   1.634 +
   1.635 +  nsRefPtr<nsDeviceContext> dx = mViewManager->GetDeviceContext();
   1.636 +
   1.637 +  // XXX/cjones: having these two separate creation cases seems ... um
   1.638 +  // ... unnecessary, but it's the way the old code did it.  Please
   1.639 +  // unify them by first finding a suitable parent nsIWidget, then
   1.640 +  // getting rid of aForceUseIWidgetParent.
   1.641 +  if (aParentWidget) {
   1.642 +    // XXX: using aForceUseIWidgetParent=true to preserve previous
   1.643 +    // semantics.  It's not clear that it's actually needed.
   1.644 +    mWindow = aParentWidget->CreateChild(trect, dx, aWidgetInitData,
   1.645 +                                         true).take();
   1.646 +  }
   1.647 +  else {
   1.648 +    nsIWidget* nearestParent = GetParent() ? GetParent()->GetNearestWidget(nullptr)
   1.649 +                                           : nullptr;
   1.650 +    if (!nearestParent) {
   1.651 +      // Without a parent, we can't make a popup.  This can happen
   1.652 +      // when printing
   1.653 +      return NS_ERROR_FAILURE;
   1.654 +    }
   1.655 +
   1.656 +    mWindow =
   1.657 +      nearestParent->CreateChild(trect, dx, aWidgetInitData).take();
   1.658 +  }
   1.659 +  if (!mWindow) {
   1.660 +    return NS_ERROR_FAILURE;
   1.661 +  }
   1.662 +
   1.663 +  InitializeWindow(aEnableDragDrop, aResetVisibility);
   1.664 +
   1.665 +  return NS_OK;
   1.666 +}
   1.667 +
   1.668 +void
   1.669 +nsView::InitializeWindow(bool aEnableDragDrop, bool aResetVisibility)
   1.670 +{
   1.671 +  NS_ABORT_IF_FALSE(mWindow, "Must have a window to initialize");
   1.672 +
   1.673 +  mWindow->SetWidgetListener(this);
   1.674 +
   1.675 +  if (aEnableDragDrop) {
   1.676 +    mWindow->EnableDragDrop(true);
   1.677 +  }
   1.678 +      
   1.679 +  // propagate the z-index to the widget.
   1.680 +  UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
   1.681 +
   1.682 +  //make sure visibility state is accurate
   1.683 +
   1.684 +  if (aResetVisibility) {
   1.685 +    SetVisibility(GetVisibility());
   1.686 +  }
   1.687 +}
   1.688 +
   1.689 +// Attach to a top level widget and start receiving mirrored events.
   1.690 +nsresult nsView::AttachToTopLevelWidget(nsIWidget* aWidget)
   1.691 +{
   1.692 +  NS_PRECONDITION(nullptr != aWidget, "null widget ptr");
   1.693 +  /// XXXjimm This is a temporary workaround to an issue w/document
   1.694 +  // viewer (bug 513162).
   1.695 +  nsIWidgetListener* listener = aWidget->GetAttachedWidgetListener();
   1.696 +  if (listener) {
   1.697 +    nsView *oldView = listener->GetView();
   1.698 +    if (oldView) {
   1.699 +      oldView->DetachFromTopLevelWidget();
   1.700 +    }
   1.701 +  }
   1.702 +
   1.703 +  nsRefPtr<nsDeviceContext> dx = mViewManager->GetDeviceContext();
   1.704 +
   1.705 +  // Note, the previous device context will be released. Detaching
   1.706 +  // will not restore the old one.
   1.707 +  nsresult rv = aWidget->AttachViewToTopLevel(!nsIWidget::UsePuppetWidgets(), dx);
   1.708 +  if (NS_FAILED(rv))
   1.709 +    return rv;
   1.710 +
   1.711 +  mWindow = aWidget;
   1.712 +  NS_ADDREF(mWindow);
   1.713 +
   1.714 +  mWindow->SetAttachedWidgetListener(this);
   1.715 +  mWindow->EnableDragDrop(true);
   1.716 +  mWidgetIsTopLevel = true;
   1.717 +
   1.718 +  // Refresh the view bounds
   1.719 +  CalcWidgetBounds(mWindow->WindowType());
   1.720 +
   1.721 +  return NS_OK;
   1.722 +}
   1.723 +
   1.724 +// Detach this view from an attached widget. 
   1.725 +nsresult nsView::DetachFromTopLevelWidget()
   1.726 +{
   1.727 +  NS_PRECONDITION(mWidgetIsTopLevel, "Not attached currently!");
   1.728 +  NS_PRECONDITION(mWindow, "null mWindow for DetachFromTopLevelWidget!");
   1.729 +
   1.730 +  mWindow->SetAttachedWidgetListener(nullptr);
   1.731 +  NS_RELEASE(mWindow);
   1.732 +
   1.733 +  mWidgetIsTopLevel = false;
   1.734 +  
   1.735 +  return NS_OK;
   1.736 +}
   1.737 +
   1.738 +void nsView::SetZIndex(bool aAuto, int32_t aZIndex)
   1.739 +{
   1.740 +  bool oldIsAuto = GetZIndexIsAuto();
   1.741 +  mVFlags = (mVFlags & ~NS_VIEW_FLAG_AUTO_ZINDEX) | (aAuto ? NS_VIEW_FLAG_AUTO_ZINDEX : 0);
   1.742 +  mZIndex = aZIndex;
   1.743 +  
   1.744 +  if (HasWidget() || !oldIsAuto || !aAuto) {
   1.745 +    UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
   1.746 +  }
   1.747 +}
   1.748 +
   1.749 +void nsView::AssertNoWindow()
   1.750 +{
   1.751 +  // XXX: it would be nice to make this a strong assert
   1.752 +  if (MOZ_UNLIKELY(mWindow)) {
   1.753 +    NS_ERROR("We already have a window for this view? BAD");
   1.754 +    mWindow->SetWidgetListener(nullptr);
   1.755 +    mWindow->Destroy();
   1.756 +    NS_RELEASE(mWindow);
   1.757 +  }
   1.758 +}
   1.759 +
   1.760 +//
   1.761 +// internal window creation functions
   1.762 +//
   1.763 +void nsView::AttachWidgetEventHandler(nsIWidget* aWidget)
   1.764 +{
   1.765 +#ifdef DEBUG
   1.766 +  NS_ASSERTION(!aWidget->GetWidgetListener(), "Already have a widget listener");
   1.767 +#endif
   1.768 +
   1.769 +  aWidget->SetWidgetListener(this);
   1.770 +}
   1.771 +
   1.772 +void nsView::DetachWidgetEventHandler(nsIWidget* aWidget)
   1.773 +{
   1.774 +  NS_ASSERTION(!aWidget->GetWidgetListener() ||
   1.775 +               aWidget->GetWidgetListener()->GetView() == this, "Wrong view");
   1.776 +  aWidget->SetWidgetListener(nullptr);
   1.777 +}
   1.778 +
   1.779 +#ifdef DEBUG
   1.780 +void nsView::List(FILE* out, int32_t aIndent) const
   1.781 +{
   1.782 +  int32_t i;
   1.783 +  for (i = aIndent; --i >= 0; ) fputs("  ", out);
   1.784 +  fprintf(out, "%p ", (void*)this);
   1.785 +  if (nullptr != mWindow) {
   1.786 +    nscoord p2a = mViewManager->AppUnitsPerDevPixel();
   1.787 +    nsIntRect rect;
   1.788 +    mWindow->GetClientBounds(rect);
   1.789 +    nsRect windowBounds = rect.ToAppUnits(p2a);
   1.790 +    mWindow->GetBounds(rect);
   1.791 +    nsRect nonclientBounds = rect.ToAppUnits(p2a);
   1.792 +    nsrefcnt widgetRefCnt = mWindow->AddRef() - 1;
   1.793 +    mWindow->Release();
   1.794 +    int32_t Z = mWindow->GetZIndex();
   1.795 +    fprintf(out, "(widget=%p[%" PRIuPTR "] z=%d pos={%d,%d,%d,%d}) ",
   1.796 +            (void*)mWindow, widgetRefCnt, Z,
   1.797 +            nonclientBounds.x, nonclientBounds.y,
   1.798 +            windowBounds.width, windowBounds.height);
   1.799 +  }
   1.800 +  nsRect brect = GetBounds();
   1.801 +  fprintf(out, "{%d,%d,%d,%d}",
   1.802 +          brect.x, brect.y, brect.width, brect.height);
   1.803 +  fprintf(out, " z=%d vis=%d frame=%p <\n",
   1.804 +          mZIndex, mVis, static_cast<void*>(mFrame));
   1.805 +  for (nsView* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
   1.806 +    NS_ASSERTION(kid->GetParent() == this, "incorrect parent");
   1.807 +    kid->List(out, aIndent + 1);
   1.808 +  }
   1.809 +  for (i = aIndent; --i >= 0; ) fputs("  ", out);
   1.810 +  fputs(">\n", out);
   1.811 +}
   1.812 +#endif // DEBUG
   1.813 +
   1.814 +nsPoint nsView::GetOffsetTo(const nsView* aOther) const
   1.815 +{
   1.816 +  return GetOffsetTo(aOther, GetViewManager()->AppUnitsPerDevPixel());
   1.817 +}
   1.818 +
   1.819 +nsPoint nsView::GetOffsetTo(const nsView* aOther, const int32_t aAPD) const
   1.820 +{
   1.821 +  NS_ABORT_IF_FALSE(GetParent() || !aOther || aOther->GetParent() ||
   1.822 +                    this == aOther, "caller of (outer) GetOffsetTo must not "
   1.823 +                    "pass unrelated views");
   1.824 +  // We accumulate the final result in offset
   1.825 +  nsPoint offset(0, 0);
   1.826 +  // The offset currently accumulated at the current APD
   1.827 +  nsPoint docOffset(0, 0);
   1.828 +  const nsView* v = this;
   1.829 +  nsViewManager* currVM = v->GetViewManager();
   1.830 +  int32_t currAPD = currVM->AppUnitsPerDevPixel();
   1.831 +  const nsView* root = nullptr;
   1.832 +  for ( ; v != aOther && v; root = v, v = v->GetParent()) {
   1.833 +    nsViewManager* newVM = v->GetViewManager();
   1.834 +    if (newVM != currVM) {
   1.835 +      int32_t newAPD = newVM->AppUnitsPerDevPixel();
   1.836 +      if (newAPD != currAPD) {
   1.837 +        offset += docOffset.ConvertAppUnits(currAPD, aAPD);
   1.838 +        docOffset.x = docOffset.y = 0;
   1.839 +        currAPD = newAPD;
   1.840 +      }
   1.841 +      currVM = newVM;
   1.842 +    }
   1.843 +    docOffset += v->GetPosition();
   1.844 +  }
   1.845 +  offset += docOffset.ConvertAppUnits(currAPD, aAPD);
   1.846 +
   1.847 +  if (v != aOther) {
   1.848 +    // Looks like aOther wasn't an ancestor of |this|.  So now we have
   1.849 +    // the root-VM-relative position of |this| in |offset|.  Get the
   1.850 +    // root-VM-relative position of aOther and subtract it.
   1.851 +    nsPoint negOffset = aOther->GetOffsetTo(root, aAPD);
   1.852 +    offset -= negOffset;
   1.853 +  }
   1.854 +
   1.855 +  return offset;
   1.856 +}
   1.857 +
   1.858 +nsPoint nsView::GetOffsetToWidget(nsIWidget* aWidget) const
   1.859 +{
   1.860 +  nsPoint pt;
   1.861 +  // Get the view for widget
   1.862 +  nsView* widgetView = GetViewFor(aWidget);
   1.863 +  if (!widgetView) {
   1.864 +    return pt;
   1.865 +  }
   1.866 +
   1.867 +  // Get the offset to the widget view in the widget view's APD
   1.868 +  // We get the offset in the widget view's APD first and then convert to our
   1.869 +  // APD afterwards so that we can include the widget view's ViewToWidgetOffset
   1.870 +  // in the sum in its native APD, and then convert the whole thing to our APD
   1.871 +  // so that we don't have to convert the APD of the relatively small
   1.872 +  // ViewToWidgetOffset by itself with a potentially large relative rounding
   1.873 +  // error.
   1.874 +  pt = -widgetView->GetOffsetTo(this);
   1.875 +  // Add in the offset to the widget.
   1.876 +  pt += widgetView->ViewToWidgetOffset();
   1.877 +
   1.878 +  // Convert to our appunits.
   1.879 +  int32_t widgetAPD = widgetView->GetViewManager()->AppUnitsPerDevPixel();
   1.880 +  int32_t ourAPD = GetViewManager()->AppUnitsPerDevPixel();
   1.881 +  pt = pt.ConvertAppUnits(widgetAPD, ourAPD);
   1.882 +  return pt;
   1.883 +}
   1.884 +
   1.885 +nsIWidget* nsView::GetNearestWidget(nsPoint* aOffset) const
   1.886 +{
   1.887 +  return GetNearestWidget(aOffset, GetViewManager()->AppUnitsPerDevPixel());
   1.888 +}
   1.889 +
   1.890 +nsIWidget* nsView::GetNearestWidget(nsPoint* aOffset, const int32_t aAPD) const
   1.891 +{
   1.892 +  // aOffset is based on the view's position, which ignores any chrome on
   1.893 +  // attached parent widgets.
   1.894 +
   1.895 +  // We accumulate the final result in pt
   1.896 +  nsPoint pt(0, 0);
   1.897 +  // The offset currently accumulated at the current APD
   1.898 +  nsPoint docPt(0,0);
   1.899 +  const nsView* v = this;
   1.900 +  nsViewManager* currVM = v->GetViewManager();
   1.901 +  int32_t currAPD = currVM->AppUnitsPerDevPixel();
   1.902 +  for ( ; v && !v->HasWidget(); v = v->GetParent()) {
   1.903 +    nsViewManager* newVM = v->GetViewManager();
   1.904 +    if (newVM != currVM) {
   1.905 +      int32_t newAPD = newVM->AppUnitsPerDevPixel();
   1.906 +      if (newAPD != currAPD) {
   1.907 +        pt += docPt.ConvertAppUnits(currAPD, aAPD);
   1.908 +        docPt.x = docPt.y = 0;
   1.909 +        currAPD = newAPD;
   1.910 +      }
   1.911 +      currVM = newVM;
   1.912 +    }
   1.913 +    docPt += v->GetPosition();
   1.914 +  }
   1.915 +  if (!v) {
   1.916 +    if (aOffset) {
   1.917 +      pt += docPt.ConvertAppUnits(currAPD, aAPD);
   1.918 +      *aOffset = pt;
   1.919 +    }
   1.920 +    return nullptr;
   1.921 +  }
   1.922 +
   1.923 +  // pt is now the offset from v's origin to this view's origin.
   1.924 +  // We add the ViewToWidgetOffset to get the offset to the widget.
   1.925 +  if (aOffset) {
   1.926 +    docPt += v->ViewToWidgetOffset();
   1.927 +    pt += docPt.ConvertAppUnits(currAPD, aAPD);
   1.928 +    *aOffset = pt;
   1.929 +  }
   1.930 +  return v->GetWidget();
   1.931 +}
   1.932 +
   1.933 +bool nsView::IsRoot() const
   1.934 +{
   1.935 +  NS_ASSERTION(mViewManager != nullptr," View manager is null in nsView::IsRoot()");
   1.936 +  return mViewManager->GetRootView() == this;
   1.937 +}
   1.938 +
   1.939 +nsRect
   1.940 +nsView::GetBoundsInParentUnits() const
   1.941 +{
   1.942 +  nsView* parent = GetParent();
   1.943 +  nsViewManager* VM = GetViewManager();
   1.944 +  if (this != VM->GetRootView() || !parent) {
   1.945 +    return mDimBounds;
   1.946 +  }
   1.947 +  int32_t ourAPD = VM->AppUnitsPerDevPixel();
   1.948 +  int32_t parentAPD = parent->GetViewManager()->AppUnitsPerDevPixel();
   1.949 +  return mDimBounds.ConvertAppUnitsRoundOut(ourAPD, parentAPD);
   1.950 +}
   1.951 +
   1.952 +nsPoint
   1.953 +nsView::ConvertFromParentCoords(nsPoint aPt) const
   1.954 +{
   1.955 +  const nsView* parent = GetParent();
   1.956 +  if (parent) {
   1.957 +    aPt = aPt.ConvertAppUnits(parent->GetViewManager()->AppUnitsPerDevPixel(),
   1.958 +                              GetViewManager()->AppUnitsPerDevPixel());
   1.959 +  }
   1.960 +  aPt -= GetPosition();
   1.961 +  return aPt;
   1.962 +}
   1.963 +
   1.964 +static bool
   1.965 +IsPopupWidget(nsIWidget* aWidget)
   1.966 +{
   1.967 +  return (aWidget->WindowType() == eWindowType_popup);
   1.968 +}
   1.969 +
   1.970 +nsIPresShell*
   1.971 +nsView::GetPresShell()
   1.972 +{
   1.973 +  return GetViewManager()->GetPresShell();
   1.974 +}
   1.975 +
   1.976 +bool
   1.977 +nsView::WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y)
   1.978 +{
   1.979 +  nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   1.980 +  if (pm && IsPopupWidget(aWidget)) {
   1.981 +    pm->PopupMoved(mFrame, nsIntPoint(x, y));
   1.982 +    return true;
   1.983 +  }
   1.984 +
   1.985 +  return false;
   1.986 +}
   1.987 +
   1.988 +bool
   1.989 +nsView::WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight)
   1.990 +{
   1.991 +  // The root view may not be set if this is the resize associated with
   1.992 +  // window creation
   1.993 +  SetForcedRepaint(true);
   1.994 +  if (this == mViewManager->GetRootView()) {
   1.995 +    nsRefPtr<nsDeviceContext> devContext = mViewManager->GetDeviceContext();
   1.996 +    // ensure DPI is up-to-date, in case of window being opened and sized
   1.997 +    // on a non-default-dpi display (bug 829963)
   1.998 +    devContext->CheckDPIChange();
   1.999 +    int32_t p2a = devContext->AppUnitsPerDevPixel();
  1.1000 +    mViewManager->SetWindowDimensions(NSIntPixelsToAppUnits(aWidth, p2a),
  1.1001 +                                      NSIntPixelsToAppUnits(aHeight, p2a));
  1.1002 +
  1.1003 +    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
  1.1004 +    if (pm) {
  1.1005 +      nsIPresShell* presShell = mViewManager->GetPresShell();
  1.1006 +      if (presShell && presShell->GetDocument()) {
  1.1007 +        pm->AdjustPopupsOnWindowChange(presShell);
  1.1008 +      }
  1.1009 +    }
  1.1010 +
  1.1011 +    return true;
  1.1012 +  }
  1.1013 +  else if (IsPopupWidget(aWidget)) {
  1.1014 +    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
  1.1015 +    if (pm) {
  1.1016 +      pm->PopupResized(mFrame, nsIntSize(aWidth, aHeight));
  1.1017 +      return true;
  1.1018 +    }
  1.1019 +  }
  1.1020 +
  1.1021 +  return false;
  1.1022 +}
  1.1023 +
  1.1024 +bool
  1.1025 +nsView::RequestWindowClose(nsIWidget* aWidget)
  1.1026 +{
  1.1027 +  if (mFrame && IsPopupWidget(aWidget) &&
  1.1028 +      mFrame->GetType() == nsGkAtoms::menuPopupFrame) {
  1.1029 +    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
  1.1030 +    if (pm) {
  1.1031 +      pm->HidePopup(mFrame->GetContent(), false, true, false, false);
  1.1032 +      return true;
  1.1033 +    }
  1.1034 +  }
  1.1035 +
  1.1036 +  return false;
  1.1037 +}
  1.1038 +
  1.1039 +void
  1.1040 +nsView::WillPaintWindow(nsIWidget* aWidget)
  1.1041 +{
  1.1042 +  nsRefPtr<nsViewManager> vm = mViewManager;
  1.1043 +  vm->WillPaintWindow(aWidget);
  1.1044 +}
  1.1045 +
  1.1046 +bool
  1.1047 +nsView::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion)
  1.1048 +{
  1.1049 +  NS_ASSERTION(this == nsView::GetViewFor(aWidget), "wrong view for widget?");
  1.1050 +
  1.1051 +  nsRefPtr<nsViewManager> vm = mViewManager;
  1.1052 +  bool result = vm->PaintWindow(aWidget, aRegion);
  1.1053 +  return result;
  1.1054 +}
  1.1055 +
  1.1056 +void
  1.1057 +nsView::DidPaintWindow()
  1.1058 +{
  1.1059 +  nsRefPtr<nsViewManager> vm = mViewManager;
  1.1060 +  vm->DidPaintWindow();
  1.1061 +}
  1.1062 +
  1.1063 +void
  1.1064 +nsView::DidCompositeWindow()
  1.1065 +{
  1.1066 +  nsIPresShell* presShell = mViewManager->GetPresShell();
  1.1067 +  if (presShell) {
  1.1068 +    nsAutoScriptBlocker scriptBlocker;
  1.1069 +    presShell->GetPresContext()->GetDisplayRootPresContext()->GetRootPresContext()->NotifyDidPaintForSubtree(nsIPresShell::PAINT_COMPOSITE);
  1.1070 +  }
  1.1071 +}
  1.1072 +
  1.1073 +void
  1.1074 +nsView::RequestRepaint()
  1.1075 +{
  1.1076 +  nsIPresShell* presShell = mViewManager->GetPresShell();
  1.1077 +  if (presShell) {
  1.1078 +    presShell->ScheduleViewManagerFlush();
  1.1079 +  }
  1.1080 +}
  1.1081 +
  1.1082 +nsEventStatus
  1.1083 +nsView::HandleEvent(WidgetGUIEvent* aEvent,
  1.1084 +                    bool aUseAttachedEvents)
  1.1085 +{
  1.1086 +  NS_PRECONDITION(nullptr != aEvent->widget, "null widget ptr");
  1.1087 +
  1.1088 +  nsEventStatus result = nsEventStatus_eIgnore;
  1.1089 +  nsView* view;
  1.1090 +  if (aUseAttachedEvents) {
  1.1091 +    nsIWidgetListener* listener = aEvent->widget->GetAttachedWidgetListener();
  1.1092 +    view = listener ? listener->GetView() : nullptr;
  1.1093 +  }
  1.1094 +  else {
  1.1095 +    view = GetViewFor(aEvent->widget);
  1.1096 +  }
  1.1097 +
  1.1098 +  if (view) {
  1.1099 +    nsRefPtr<nsViewManager> vm = view->GetViewManager();
  1.1100 +    vm->DispatchEvent(aEvent, view, &result);
  1.1101 +  }
  1.1102 +
  1.1103 +  return result;
  1.1104 +}

mercurial