Bug 703260, part 1, remove view from eventstatemanager and presshell event handling, r=smaug,sr=roc
authorNeil Deakin <neil@mozilla.com>
Mon, 21 Nov 2011 12:53:20 -0500
changeset 80579 9298bebc43bf6d96bf3bf773931ca59ef1a815f5
parent 80578 2873fd69475001beda6d4fbcff5b23a043460572
child 80580 e4a32b4ffd93f7594ff7496d44f51e6eb7bb4ae8
push id21511
push userbmo@edmorley.co.uk
push dateTue, 22 Nov 2011 02:38:00 +0000
treeherdermozilla-central@b8955ff00aae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, roc
bugs703260
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 703260, part 1, remove view from eventstatemanager and presshell event handling, r=smaug,sr=roc
content/events/src/nsEventStateManager.cpp
content/events/src/nsEventStateManager.h
dom/base/nsDOMWindowUtils.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresContext.cpp
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/generic/nsContainerFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsSubDocumentFrame.cpp
layout/xul/base/src/nsXULPopupManager.cpp
view/public/nsIView.h
view/public/nsIViewObserver.h
view/src/nsView.cpp
view/src/nsViewManager.cpp
view/src/nsViewManager.h
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -63,18 +63,16 @@
 #include "nsIEditorDocShell.h"
 #include "nsIFormControl.h"
 #include "nsIComboboxControlFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMXULControlElement.h"
 #include "nsINameSpaceManager.h"
 #include "nsIBaseWindow.h"
-#include "nsIView.h"
-#include "nsIViewManager.h"
 #include "nsISelection.h"
 #include "nsFrameSelection.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsIEnumerator.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeNode.h"
@@ -1025,18 +1023,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument);
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mAccessKeys);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 nsresult
 nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
                                     nsEvent *aEvent,
                                     nsIFrame* aTargetFrame,
-                                    nsEventStatus* aStatus,
-                                    nsIView* aView)
+                                    nsEventStatus* aStatus)
 {
   NS_ENSURE_ARG_POINTER(aStatus);
   NS_ENSURE_ARG(aPresContext);
   if (!aEvent) {
     NS_ERROR("aEvent is null.  This should never happen.");
     return NS_ERROR_NULL_POINTER;
   }
 
@@ -3024,18 +3021,17 @@ NodeAllowsClickThrough(nsINode* aNode)
   return true;
 }
 #endif
 
 nsresult
 nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
                                      nsEvent *aEvent,
                                      nsIFrame* aTargetFrame,
-                                     nsEventStatus* aStatus,
-                                     nsIView* aView)
+                                     nsEventStatus* aStatus)
 {
   NS_ENSURE_ARG(aPresContext);
   NS_ENSURE_ARG_POINTER(aStatus);
 
   HandleCrossProcessEvent(aEvent, aTargetFrame, aStatus);
 
   mCurrentTarget = aTargetFrame;
   mCurrentTargetContent = nsnull;
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -101,29 +101,27 @@ public:
    * cancelled should occur here.  Any processing which is intended to
    * be conditional based on either DOM or frame processing should occur in
    * PostHandleEvent.  Any centralized event processing which must occur before
    * DOM or frame event handling should occur here as well.
    */
   nsresult PreHandleEvent(nsPresContext* aPresContext,
                           nsEvent *aEvent,
                           nsIFrame* aTargetFrame,
-                          nsEventStatus* aStatus,
-                          nsIView* aView);
+                          nsEventStatus* aStatus);
 
   /* The PostHandleEvent method should contain all system processing which
    * should occur conditionally based on DOM or frame processing.  It should
    * also contain any centralized event processing which must occur after
    * DOM and frame processing.
    */
   nsresult PostHandleEvent(nsPresContext* aPresContext,
                            nsEvent *aEvent,
                            nsIFrame* aTargetFrame,
-                           nsEventStatus* aStatus,
-                           nsIView* aView);
+                           nsEventStatus* aStatus);
 
   void NotifyDestroyPresContext(nsPresContext* aPresContext);
   void SetPresContext(nsPresContext* aPresContext);
   void ClearFrameRefs(nsIFrame* aFrame);
 
   nsIFrame* GetEventTarget();
   already_AddRefed<nsIContent> GetEventTargetContent(nsEvent* aEvent);
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -484,17 +484,17 @@ nsDOMWindowUtils::SendMouseEventCommon(c
     nsIViewManager* viewManager = presShell->GetViewManager();
     if (!viewManager)
       return NS_ERROR_FAILURE;
     nsIView* view = viewManager->GetRootView();
     if (!view)
       return NS_ERROR_FAILURE;
 
     status = nsEventStatus_eIgnore;
-    return vo->HandleEvent(view, &event, false, &status);
+    return vo->HandleEvent(view->GetFrame(), &event, false, &status);
   }
   return widget->DispatchEvent(&event, status);
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendMouseScrollEvent(const nsAString& aType,
                                        float aX,
                                        float aY,
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -505,19 +505,17 @@ nsLayoutUtils::GetCrossDocParentFrame(co
     return nsnull;
   v = v->GetParent(); // anonymous inner view
   if (!v)
     return nsnull;
   if (aExtraOffset) {
     *aExtraOffset += v->GetPosition();
   }
   v = v->GetParent(); // subdocumentframe's view
-  if (!v)
-    return nsnull;
-  return static_cast<nsIFrame*>(v->GetClientData());
+  return v ? v->GetFrame() : nsnull;
 }
 
 // static
 bool
 nsLayoutUtils::IsProperAncestorFrameCrossDoc(nsIFrame* aAncestorFrame, nsIFrame* aFrame,
                                              nsIFrame* aCommonAncestor)
 {
   if (aFrame == aCommonAncestor)
@@ -748,26 +746,26 @@ nsIFrame* nsLayoutUtils::GetLastSibling(
     aFrame = next;
   }
   return aFrame;
 }
 
 // static
 nsIView*
 nsLayoutUtils::FindSiblingViewFor(nsIView* aParentView, nsIFrame* aFrame) {
-  nsIFrame* parentViewFrame = static_cast<nsIFrame*>(aParentView->GetClientData());
+  nsIFrame* parentViewFrame = aParentView->GetFrame();
   nsIContent* parentViewContent = parentViewFrame ? parentViewFrame->GetContent() : nsnull;
   for (nsIView* insertBefore = aParentView->GetFirstChild(); insertBefore;
        insertBefore = insertBefore->GetNextSibling()) {
-    nsIFrame* f = static_cast<nsIFrame*>(insertBefore->GetClientData());
+    nsIFrame* f = insertBefore->GetFrame();
     if (!f) {
       // this view could be some anonymous view attached to a meaningful parent
       for (nsIView* searchView = insertBefore->GetParent(); searchView;
            searchView = searchView->GetParent()) {
-        f = static_cast<nsIFrame*>(searchView->GetClientData());
+        f = searchView->GetFrame();
         if (f) {
           break;
         }
       }
       NS_ASSERTION(f, "Can't find a frame anywhere!");
     }
     if (!f || !aFrame->GetContent() || !f->GetContent() ||
         CompareTreePosition(aFrame->GetContent(), f->GetContent(), parentViewContent) > 0) {
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -337,18 +337,17 @@ public:
   static bool ScrolledByViewportScrolling(nsIFrame* aActiveScrolledRoot,
                                             nsDisplayListBuilder* aBuilder);
 
   /**
     * GetFrameFor returns the root frame for a view
     * @param aView is the view to return the root frame for
     * @return the root frame for the view
     */
-  static nsIFrame* GetFrameFor(nsIView *aView)
-  { return static_cast<nsIFrame*>(aView->GetClientData()); }
+  static nsIFrame* GetFrameFor(nsIView *aView) { return aView->GetFrame(); }
 
   /**
     * GetScrollableFrameFor returns the scrollable frame for a scrolled frame
     */
   static nsIScrollableFrame* GetScrollableFrameFor(nsIFrame *aScrolledFrame);
 
   /**
    * GetNearestScrollableFrameForDirection locates the first ancestor of
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2296,17 +2296,17 @@ nsPresContext::IsRootContentDocument()
   if (!view) {
     return true;
   }
   view = view->GetParent(); // subdocumentframe's view
   if (!view) {
     return true;
   }
 
-  nsIFrame* f = static_cast<nsIFrame*>(view->GetClientData());
+  nsIFrame* f = view->GetFrame();
   return (f && f->PresContext()->IsChrome());
 }
 
 nsRootPresContext::nsRootPresContext(nsIDocument* aDocument,
                                      nsPresContextType aType)
   : nsPresContext(aDocument, aType),
     mUpdatePluginGeometryForFrame(nsnull),
     mDOMGeneration(0),
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -67,17 +67,18 @@
 #include "nsIDocument.h"
 #include "nsIDOMXULDocument.h"
 #include "nsCSSStyleSheet.h" // XXX for UA sheet loading hack, can this go away please?
 #include "nsIDOMCSSStyleSheet.h"  // for Pref-related rule management (bugs 22963,20760,31816)
 #include "nsAnimationManager.h"
 #include "nsINameSpaceManager.h"  // for Pref-related rule management (bugs 22963,20760,31816)
 #include "nsIServiceManager.h"
 #include "nsFrame.h"
-#include "nsIViewManager.h"
+#include "nsViewManager.h"
+#include "nsView.h"
 #include "nsCRTGlue.h"
 #include "prlog.h"
 #include "prmem.h"
 #include "prprf.h"
 #include "prinrval.h"
 #include "nsTArray.h"
 #include "nsCOMArray.h"
 #include "nsHashtable.h"
@@ -5257,17 +5258,17 @@ void PresShell::SynthesizeMouseMove(bool
  * traverse the entire view hierarchy --- use carefully.
  */
 static nsIView* FindFloatingViewContaining(nsIView* aView, nsPoint aPt)
 {
   if (aView->GetVisibility() == nsViewVisibility_kHide)
     // No need to look into descendants.
     return nsnull;
 
-  nsIFrame* frame = static_cast<nsIFrame*>(aView->GetClientData());
+  nsIFrame* frame = aView->GetFrame();
   if (frame) {
     if (!frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY) ||
         !frame->PresContext()->PresShell()->IsActive()) {
       return nsnull;
     }
   }
 
   for (nsIView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
@@ -5294,17 +5295,17 @@ static nsIView* FindFloatingViewContaini
  */
 static nsIView* FindViewContaining(nsIView* aView, nsPoint aPt)
 {
   if (!aView->GetDimensions().Contains(aPt) ||
       aView->GetVisibility() == nsViewVisibility_kHide) {
     return nsnull;
   }
 
-  nsIFrame* frame = static_cast<nsIFrame*>(aView->GetClientData());
+  nsIFrame* frame = aView->GetFrame();
   if (frame) {
     if (!frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY) ||
         !frame->PresContext()->PresShell()->IsActive()) {
       return nsnull;
     }
   }
 
   for (nsIView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
@@ -5369,17 +5370,17 @@ PresShell::ProcessSynthMouseMoveEvent(bo
     view = rootView;
     nsIView *pointView = FindViewContaining(rootView, mMouseLocation);
     // pointView can be null in situations related to mouse capture
     pointVM = (pointView ? pointView : view)->GetViewManager();
     refpoint = mMouseLocation + rootView->ViewToWidgetOffset();
     viewAPD = APD;
   } else {
     pointVM = view->GetViewManager();
-    nsIFrame* frame = static_cast<nsIFrame*>(view->GetClientData());
+    nsIFrame* frame = view->GetFrame();
     NS_ASSERTION(frame, "floating views can't be anonymous");
     viewAPD = frame->PresContext()->AppUnitsPerDevPixel();
     refpoint = mMouseLocation.ConvertAppUnits(APD, viewAPD);
     refpoint -= view->GetOffsetTo(rootView);
     refpoint += view->ViewToWidgetOffset();
   }
   NS_ASSERTION(view->GetWidget(), "view should have a widget here");
   nsMouseEvent event(true, NS_MOUSE_MOVE, view->GetWidget(),
@@ -5419,18 +5420,17 @@ PresShell::Paint(nsIView*           aVie
 
   NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
   NS_ASSERTION(aViewToPaint, "null view");
   NS_ASSERTION(aWidgetToPaint, "Can't paint without a widget");
 
   nsPresContext* presContext = GetPresContext();
   AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
 
-  nsIFrame* frame = aPaintDefaultBackground
-      ? nsnull : static_cast<nsIFrame*>(aViewToPaint->GetClientData());
+  nsIFrame* frame = aPaintDefaultBackground ? nsnull : aViewToPaint->GetFrame();
 
   bool isRetainingManager;
   LayerManager* layerManager =
     aWidgetToPaint->GetLayerManager(&isRetainingManager);
   NS_ASSERTION(layerManager, "Must be in paint event");
   layerManager->BeginTransaction();
 
   if (frame && isRetainingManager) {
@@ -5646,20 +5646,18 @@ PresShell::RetargetEventToParent(nsGUIEv
   nsCOMPtr<nsIPresShell> parentPresShell = GetParentPresShell();
   NS_ENSURE_TRUE(parentPresShell, NS_ERROR_FAILURE);
   nsCOMPtr<nsIViewObserver> parentViewObserver = 
     do_QueryInterface(parentPresShell);
   if (!parentViewObserver) {
     return NS_ERROR_FAILURE;
   }
 
-  // Fake the event as though it'ss from the parent pres shell's root view.
-  nsIView *parentRootView = parentPresShell->GetViewManager()->GetRootView();
-  
-  return parentViewObserver->HandleEvent(parentRootView, aEvent, true, aEventStatus);
+  // Fake the event as though it's from the parent pres shell's root frame.
+  return parentViewObserver->HandleEvent(parentPresShell->GetRootFrame(), aEvent, true, aEventStatus);
 }
 
 void
 PresShell::DisableNonTestMouseEvents(bool aDisable)
 {
   sDisableNonTestMouseEvents = aDisable;
 }
 
@@ -5722,38 +5720,38 @@ PresShell::RecordMouseLocation(nsGUIEven
            this, aEvent->widget);
     printf("[ps=%p]clearing mouse location\n",
            this);
 #endif
   }
 }
 
 NS_IMETHODIMP
-PresShell::HandleEvent(nsIView         *aView,
+PresShell::HandleEvent(nsIFrame        *aFrame,
                        nsGUIEvent*     aEvent,
                        bool            aDontRetargetEvents,
                        nsEventStatus*  aEventStatus)
 {
-  NS_ASSERTION(aView, "null view");
+  NS_ASSERTION(aFrame, "null frame");
 
   if (mIsDestroying ||
       (sDisableNonTestMouseEvents && NS_IS_MOUSE_EVENT(aEvent) &&
        !(aEvent->flags & NS_EVENT_FLAG_SYNTHETIC_TEST_EVENT))) {
     return NS_OK;
   }
 
   RecordMouseLocation(aEvent);
 
 #ifdef ACCESSIBILITY
   if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT) {
     NS_TIME_FUNCTION_MIN(1.0);
 
     // Accessibility events come through OS requests and not from scripts,
     // so it is safe to handle here
-    return HandleEventInternal(aEvent, aView, aEventStatus);
+    return HandleEventInternal(aEvent, aEventStatus);
   }
 #endif
 
   if (!nsContentUtils::IsSafeToRunScript())
     return NS_OK;
 
   NS_TIME_FUNCTION_MIN(1.0);
 
@@ -5793,18 +5791,17 @@ PresShell::HandleEvent(nsIView         *
       if (!presShell)
         return NS_OK;
 
       if (presShell != this) {
         nsCOMPtr<nsIViewObserver> viewObserver = do_QueryInterface(presShell);
         if (!viewObserver)
           return NS_ERROR_FAILURE;
 
-        nsIView* view = presShell->GetViewManager()->GetRootView();
-        return viewObserver->HandleEvent(view, aEvent, true, aEventStatus);
+        return viewObserver->HandleEvent(presShell->GetRootFrame(), aEvent, true, aEventStatus);
       }
     }
   }
 
   // Check for a theme change up front, since the frame type is irrelevant
   if (aEvent->message == NS_THEMECHANGED && mPresContext) {
     mPresContext->ThemeChanged();
     return NS_OK;
@@ -5816,30 +5813,20 @@ PresShell::HandleEvent(nsIView         *
       nsUIStateChangeEvent* event = (nsUIStateChangeEvent*)aEvent;
       win->SetKeyboardIndicators(event->showAccelerators, event->showFocusRings);
     }
     return NS_OK;
   }
 
   // Check for a system color change up front, since the frame type is
   // irrelevant
-  if ((aEvent->message == NS_SYSCOLORCHANGED) && mPresContext) {
-    nsIViewManager* vm = GetViewManager();
-    if (vm) {
-      // Only dispatch system color change when the message originates from
-      // from the root views widget. This is necessary to prevent us from 
-      // dispatching the SysColorChanged notification for each child window 
-      // which may be redundant.
-      nsIView* view = vm->GetRootView();
-      if (view == aView) {
-        *aEventStatus = nsEventStatus_eConsumeDoDefault;
-        mPresContext->SysColorChanged();
-        return NS_OK;
-      }
-    }
+  if ((aEvent->message == NS_SYSCOLORCHANGED) && mPresContext &&
+      aFrame == FrameManager()->GetRootFrame()) {
+    *aEventStatus = nsEventStatus_eConsumeDoDefault;
+    mPresContext->SysColorChanged();
     return NS_OK;
   }
 
   if (aEvent->eventStructType == NS_KEY_EVENT &&
       mDocument && mDocument->EventHandlingSuppressed()) {
     if (aEvent->message == NS_KEY_DOWN) {
       mNoDelayedKeyEvents = true;
     } else if (!mNoDelayedKeyEvents) {
@@ -5847,38 +5834,18 @@ PresShell::HandleEvent(nsIView         *
         new nsDelayedKeyEvent(static_cast<nsKeyEvent*>(aEvent));
       if (!mDelayedEvents.AppendElement(event)) {
         delete event;
       }
     }
     return NS_OK;
   }
 
-  nsIFrame* frame = static_cast<nsIFrame*>(aView->GetClientData());
+  nsIFrame* frame = aFrame;
   bool dispatchUsingCoordinates = NS_IsEventUsingCoordinates(aEvent);
-
-  // if this event has no frame, we need to retarget it at a parent
-  // view that has a frame.
-  if (!frame &&
-      (dispatchUsingCoordinates || NS_IS_KEY_EVENT(aEvent) ||
-       NS_IS_IME_RELATED_EVENT(aEvent) ||
-       NS_IS_NON_RETARGETED_PLUGIN_EVENT(aEvent) ||
-       aEvent->message == NS_PLUGIN_ACTIVATE ||
-       aEvent->message == NS_PLUGIN_FOCUS)) {
-    nsIView* targetView = aView;
-    while (targetView && !targetView->GetClientData()) {
-      targetView = targetView->GetParent();
-    }
-    
-    if (targetView) {
-      aView = targetView;
-      frame = static_cast<nsIFrame*>(aView->GetClientData());
-    }
-  }
-
   if (dispatchUsingCoordinates) {
     NS_WARN_IF_FALSE(frame, "Nothing to handle this event!");
     if (!frame)
       return NS_OK;
 
     nsPresContext* framePresContext = frame->PresContext();
     nsPresContext* rootPresContext = framePresContext->GetRootPresContext();
     NS_ASSERTION(rootPresContext == mPresContext->GetRootPresContext(),
@@ -5977,17 +5944,16 @@ PresShell::HandleEvent(nsIView         *
                                                         capturingContent))) {
       // A check was already done above to ensure that capturingContent is
       // in this presshell.
       NS_ASSERTION(capturingContent->GetCurrentDoc() == GetDocument(),
                    "Unexpected document");
       nsIFrame* capturingFrame = capturingContent->GetPrimaryFrame();
       if (capturingFrame) {
         frame = capturingFrame;
-        aView = frame->GetClosestView();
       }
     }
 
     // Suppress mouse event if it's being targeted at an element inside
     // a document which needs events suppressed
     if (aEvent->eventStructType == NS_MOUSE_EVENT &&
         frame->PresContext()->Document()->EventHandlingSuppressed()) {
       if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
@@ -6021,35 +5987,32 @@ PresShell::HandleEvent(nsIView         *
         activeESM != shell->GetPresContext()->EventStateManager() &&
         static_cast<nsEventStateManager*>(activeESM)->GetPresContext()) {
       nsIPresShell* activeShell =
         static_cast<nsEventStateManager*>(activeESM)->GetPresContext()->GetPresShell();
       if (activeShell &&
           nsContentUtils::ContentIsCrossDocDescendantOf(activeShell->GetDocument(),
                                                         shell->GetDocument())) {
         shell = static_cast<PresShell*>(activeShell);
-        nsIView* activeShellRootView = shell->GetViewManager()->GetRootView();
-        frame = static_cast<nsIFrame*>(activeShellRootView->GetClientData());
+        frame = shell->GetRootFrame();
       }
     }
 
     if (shell != this) {
       // Handle the event in the correct shell.
       // Prevent deletion until we're done with event handling (bug 336582).
       nsCOMPtr<nsIPresShell> kungFuDeathGrip(shell);
-      nsIView* subshellRootView = shell->GetViewManager()->GetRootView();
-      // We pass the subshell's root view as the view to start from. This is
+      // We pass the subshell's root frame as the frame to start from. This is
       // the only correct alternative; if the event was captured then it
       // must have been captured by us or some ancestor shell and we
       // now ask the subshell to dispatch it normally.
-      return shell->HandlePositionedEvent(subshellRootView, frame,
-                                          aEvent, aEventStatus);
-    }
-
-    return HandlePositionedEvent(aView, frame, aEvent, aEventStatus);
+      return shell->HandlePositionedEvent(frame, aEvent, aEventStatus);
+    }
+
+    return HandlePositionedEvent(frame, aEvent, aEventStatus);
   }
   
   nsresult rv = NS_OK;
   
   if (frame) {
     PushCurrentEventInfo(nsnull, nsnull);
 
     // key and IME related events go to the focused frame in this DOM window.
@@ -6106,19 +6069,17 @@ PresShell::HandleEvent(nsIView         *
 
       mCurrentEventFrame = nsnull;
       nsIDocument* targetDoc = eventTarget ? eventTarget->OwnerDoc() : nsnull;
       if (targetDoc && targetDoc != mDocument) {
         PopCurrentEventInfo();
         nsIPresShell* shell = targetDoc->GetShell();
         nsCOMPtr<nsIViewObserver> vo = do_QueryInterface(shell);
         if (vo) {
-          nsIView* root = shell->GetViewManager()->GetRootView();
           rv = static_cast<PresShell*>(shell)->HandleRetargetedEvent(aEvent,
-                                                                     root,
                                                                      aEventStatus,
                                                                      eventTarget);
         }
         return rv;
       } else {
         mCurrentEventContent = eventTarget;
       }
         
@@ -6127,30 +6088,30 @@ PresShell::HandleEvent(nsIView         *
         rv = RetargetEventToParent(aEvent, aEventStatus);
         PopCurrentEventInfo();
         return rv;
       }
     } else {
       mCurrentEventFrame = frame;
     }
     if (GetCurrentEventFrame()) {
-      rv = HandleEventInternal(aEvent, aView, aEventStatus);
+      rv = HandleEventInternal(aEvent, aEventStatus);
     }
   
 #ifdef NS_DEBUG
     ShowEventTargetDebug();
 #endif
     PopCurrentEventInfo();
   } else {
     // Activation events need to be dispatched even if no frame was found, since
     // we don't want the focus to be out of sync.
 
     if (!NS_EVENT_NEEDS_FRAME(aEvent)) {
       mCurrentEventFrame = nsnull;
-      return HandleEventInternal(aEvent, aView, aEventStatus);
+      return HandleEventInternal(aEvent, aEventStatus);
     }
     else if (NS_IS_KEY_EVENT(aEvent)) {
       // Keypress events in new blank tabs should not be completely thrown away.
       // Retarget them -- the parent chrome shell might make use of them.
       return RetargetEventToParent(aEvent, aEventStatus);
     }
   }
 
@@ -6171,18 +6132,17 @@ PresShell::ShowEventTargetDebug()
     mDrawEventTargetFrame = mCurrentEventFrame;
     mDrawEventTargetFrame->Invalidate(
         nsRect(nsPoint(0, 0), mDrawEventTargetFrame->GetSize()));
   }
 }
 #endif
 
 nsresult
-PresShell::HandlePositionedEvent(nsIView*       aView,
-                                 nsIFrame*      aTargetFrame,
+PresShell::HandlePositionedEvent(nsIFrame*      aTargetFrame,
                                  nsGUIEvent*    aEvent,
                                  nsEventStatus* aEventStatus)
 {
   nsresult rv = NS_OK;
   
   PushCurrentEventInfo(nsnull, nsnull);
   
   mCurrentEventFrame = aTargetFrame;
@@ -6214,32 +6174,32 @@ PresShell::HandlePositionedEvent(nsIView
         mCurrentEventFrame = nsnull;
       } else if (targetElement != mCurrentEventContent) {
         mCurrentEventContent = targetElement;
       }
     }
   }
 
   if (GetCurrentEventFrame()) {
-    rv = HandleEventInternal(aEvent, aView, aEventStatus);
+    rv = HandleEventInternal(aEvent, aEventStatus);
   }
 
 #ifdef NS_DEBUG
   ShowEventTargetDebug();
 #endif
   PopCurrentEventInfo();
   return rv;
 }
 
 nsresult
 PresShell::HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame,
                                  nsIContent* aContent, nsEventStatus* aStatus)
 {
   PushCurrentEventInfo(aFrame, aContent);
-  nsresult rv = HandleEventInternal(aEvent, nsnull, aStatus);
+  nsresult rv = HandleEventInternal(aEvent, aStatus);
   PopCurrentEventInfo();
   return rv;
 }
 
 static inline bool
 IsSynthesizedMouseEvent(nsEvent* aEvent)
 {
   return aEvent->eventStructType == NS_MOUSE_EVENT &&
@@ -6318,18 +6278,17 @@ IsFullScreenAndRestrictedKeyEvent(nsICon
     default:
       // Otherwise, fullscreen is enabled, key input is restricted, and the key
       // code is not an allowed key code.
       return true;
   }
 }
 
 nsresult
-PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
-                               nsEventStatus* aStatus)
+PresShell::HandleEventInternal(nsEvent* aEvent, nsEventStatus* aStatus)
 {
   NS_TIME_FUNCTION_MIN(1.0);
 
 #ifdef ACCESSIBILITY
   if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT)
   {
     nsAccessibleEvent *accEvent = static_cast<nsAccessibleEvent*>(aEvent);
     accEvent->mAccessible = nsnull;
@@ -6438,21 +6397,19 @@ PresShell::HandleEventInternal(nsEvent* 
     }
 
     nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent));
 
     // FIXME. If the event was reused, we need to clear the old target,
     // bug 329430
     aEvent->target = nsnull;
 
-    nsWeakView weakView(aView);
     // 1. Give event to event manager for pre event state changes and
     //    generation of synthetic events.
-    rv = manager->PreHandleEvent(mPresContext, aEvent, mCurrentEventFrame,
-                                 aStatus, aView);
+    rv = manager->PreHandleEvent(mPresContext, aEvent, mCurrentEventFrame, aStatus);
 
     // 2. Give event to the DOM for third party and JS use.
     if (GetCurrentEventFrame() && NS_SUCCEEDED(rv)) {
       bool wasHandlingKeyBoardEvent =
         nsContentUtils::IsHandlingKeyBoardEvent();
       if (aEvent->eventStructType == NS_KEY_EVENT) {
         nsContentUtils::SetIsHandlingKeyBoardEvent(true);
       }
@@ -6481,18 +6438,17 @@ PresShell::HandleEventInternal(nsEvent* 
       }
 
       nsContentUtils::SetIsHandlingKeyBoardEvent(wasHandlingKeyBoardEvent);
 
       // 3. Give event to event manager for post event state changes and
       //    generation of synthetic events.
       if (!mIsDestroying && NS_SUCCEEDED(rv)) {
         rv = manager->PostHandleEvent(mPresContext, aEvent,
-                                      GetCurrentEventFrame(), aStatus,
-                                      weakView.GetView());
+                                      GetCurrentEventFrame(), aStatus);
       }
     }
 
     if (aEvent->message == NS_MOUSE_BUTTON_UP) {
       // reset the capturing content now that the mouse button is up
       SetCapturingContent(nsnull, 0);
     } else if (aEvent->message == NS_MOUSE_MOVE) {
       nsIPresShell::AllowMouseCapture(false);
@@ -6967,17 +6923,17 @@ PresShell::IsVisible()
   if (!view)
     return true;
   
   // subdoc view
   view = view->GetParent();
   if (!view)
     return true;
 
-  nsIFrame* frame = static_cast<nsIFrame*>(view->GetClientData());
+  nsIFrame* frame = view->GetFrame();
   if (!frame)
     return true;
 
   return frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY);
 }
 
 nsresult
 PresShell::GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets)
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -315,17 +315,17 @@ public:
   //nsIViewObserver interface
 
   NS_IMETHOD Paint(nsIView* aViewToPaint,
                    nsIWidget* aWidget,
                    const nsRegion& aDirtyRegion,
                    const nsIntRegion& aIntDirtyRegion,
                    bool aPaintDefaultBackground,
                    bool aWillSendDidPaint);
-  NS_IMETHOD HandleEvent(nsIView*        aView,
+  NS_IMETHOD HandleEvent(nsIFrame*       aFrame,
                          nsGUIEvent*     aEvent,
                          bool            aDontRetargetEvents,
                          nsEventStatus*  aEventStatus);
   virtual NS_HIDDEN_(nsresult) HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                         nsEvent* aEvent,
                                                         nsEventStatus* aStatus);
   virtual NS_HIDDEN_(nsresult) HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                         nsIDOMEvent* aEvent,
@@ -600,24 +600,23 @@ protected:
       frameSelection->SetMouseDownState(false);
     }
     if (gCaptureInfo.mContent &&
         gCaptureInfo.mContent->OwnerDoc() == mDocument) {
       SetCapturingContent(nsnull, 0);
     }
   }
 
-  nsresult HandleRetargetedEvent(nsEvent* aEvent, nsIView* aView,
-                                 nsEventStatus* aStatus, nsIContent* aTarget)
+  nsresult HandleRetargetedEvent(nsEvent* aEvent, nsEventStatus* aStatus, nsIContent* aTarget)
   {
     PushCurrentEventInfo(nsnull, nsnull);
     mCurrentEventContent = aTarget;
     nsresult rv = NS_OK;
     if (GetCurrentEventFrame()) {
-      rv = HandleEventInternal(aEvent, aView, aStatus);
+      rv = HandleEventInternal(aEvent, aStatus);
     }
     PopCurrentEventInfo();
     return rv;
   }
 
   nsRefPtr<nsCSSStyleSheet> mPrefStyleSheet; // mStyleSet owns it but we
                                              // maintain a ref, may be null
 #ifdef DEBUG
@@ -796,20 +795,18 @@ private:
 
   //helper funcs for event handling
 protected:
   //protected because nsPresShellEventCB needs this.
   nsIFrame* GetCurrentEventFrame();
 private:
   void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
   void PopCurrentEventInfo();
-  nsresult HandleEventInternal(nsEvent* aEvent, nsIView* aView,
-                               nsEventStatus *aStatus);
-  nsresult HandlePositionedEvent(nsIView*       aView,
-                                 nsIFrame*      aTargetFrame,
+  nsresult HandleEventInternal(nsEvent* aEvent, nsEventStatus *aStatus);
+  nsresult HandlePositionedEvent(nsIFrame*      aTargetFrame,
                                  nsGUIEvent*    aEvent,
                                  nsEventStatus* aEventStatus);
   // This returns the focused DOM window under our top level window.
   //  I.e., when we are deactive, this returns the *last* focused DOM window.
   already_AddRefed<nsPIDOMWindow> GetFocusedDOMWindowInOurWindow();
 
   /*
    * This and the next two helper methods are used to target and position the
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -240,17 +240,17 @@ nsContainerFrame::RemoveFrame(ChildListI
   return NS_OK;
 }
 
 void
 nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   // Prevent event dispatch during destruction
   if (HasView()) {
-    GetView()->SetClientData(nsnull);
+    GetView()->SetFrame(nsnull);
   }
 
   // Delete the primary child list
   mFrames.DestroyFramesFrom(aDestructRoot);
 
   // Destroy auxiliary frame lists
   nsPresContext* prescontext = PresContext();
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -570,17 +570,17 @@ nsFrame::DestroyFrom(nsIFrame* aDestruct
 
   if ((mState & NS_FRAME_EXTERNAL_REFERENCE) ||
       (mState & NS_FRAME_SELECTED_CONTENT)) {
     shell->ClearFrameRefs(this);
   }
 
   if (view) {
     // Break association between view and frame
-    view->SetClientData(nsnull);
+    view->SetFrame(nsnull);
 
     // Destroy the view
     view->Destroy();
   }
 
   // Make sure that our deleted frame can't be returned from GetPrimaryFrame()
   if (mContent && mContent->GetPrimaryFrame() == this) {
     mContent->SetPrimaryFrame(nsnull);
@@ -4044,17 +4044,17 @@ nsIFrame::GetViewExternal() const
 {
   return GetView();
 }
 
 nsresult
 nsIFrame::SetView(nsIView* aView)
 {
   if (aView) {
-    aView->SetClientData(this);
+    aView->SetFrame(this);
 
     // Set a property on the frame
     Properties().Set(ViewProperty(), aView);
 
     // Set the frame state bit that says the frame has a view
     AddStateBits(NS_FRAME_HAS_VIEW);
 
     // Let all of the ancestors know they have a descendant with a view.
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -102,17 +102,17 @@
 using namespace mozilla;
 using mozilla::layout::RenderFrameParent;
 
 static nsIDocument*
 GetDocumentFromView(nsIView* aView)
 {
   NS_PRECONDITION(aView, "");
 
-  nsIFrame* f = static_cast<nsIFrame*>(aView->GetClientData());
+  nsIFrame* f = aView->GetFrame();
   nsIPresShell* ps =  f ? f->PresContext()->PresShell() : nsnull;
   return ps ? ps->GetDocument() : nsnull;
 }
 
 class AsyncFrameInit;
 
 nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext)
   : nsLeafFrame(aContext)
@@ -245,19 +245,17 @@ nsSubDocumentFrame::GetSkipSides() const
 }
 
 nsIFrame*
 nsSubDocumentFrame::GetSubdocumentRootFrame()
 {
   if (!mInnerView)
     return nsnull;
   nsIView* subdocView = mInnerView->GetFirstChild();
-  if (!subdocView)
-    return nsnull;
-  return static_cast<nsIFrame*>(subdocView->GetClientData());
+  return subdocView ? subdocView->GetFrame() : nsnull;
 }
 
 NS_IMETHODIMP
 nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                      const nsRect&           aDirtyRect,
                                      const nsDisplayListSet& aLists)
 {
   if (!IsVisibleForPainting(aBuilder))
@@ -282,33 +280,31 @@ nsSubDocumentFrame::BuildDisplayList(nsD
   }
 
   nsIView* subdocView = mInnerView->GetFirstChild();
   if (!subdocView)
     return NS_OK;
 
   nsCOMPtr<nsIPresShell> presShell = nsnull;
 
-  nsIFrame* subdocRootFrame =
-    static_cast<nsIFrame*>(subdocView->GetClientData());
-
+  nsIFrame* subdocRootFrame = subdocView->GetFrame();
   if (subdocRootFrame) {
     presShell = subdocRootFrame->PresContext()->PresShell();
   }
   // If painting is suppressed in the presshell, we try to look for a better
   // presshell to use.
   if (!presShell || (presShell->IsPaintingSuppressed() &&
                      !aBuilder->IsIgnoringPaintSuppression())) {
     // During page transition mInnerView will sometimes have two children, the
     // first being the new page that may not have any frame, and the second
     // being the old page that will probably have a frame.
     nsIView* nextView = subdocView->GetNextSibling();
     nsIFrame* frame = nsnull;
     if (nextView) {
-      frame = static_cast<nsIFrame*>(nextView->GetClientData());
+      frame = nextView->GetFrame();
     }
     if (frame) {
       nsIPresShell* ps = frame->PresContext()->PresShell();
       if (!presShell || (ps && !ps->IsPaintingSuppressed())) {
         subdocView = nextView;
         subdocRootFrame = frame;
         presShell = ps;
       }
--- a/layout/xul/base/src/nsXULPopupManager.cpp
+++ b/layout/xul/base/src/nsXULPopupManager.cpp
@@ -333,17 +333,17 @@ nsXULPopupManager::AdjustPopupsOnWindowC
 
     item = item->GetParent();
   }
 }
 
 static
 nsMenuPopupFrame* GetPopupToMoveOrResize(nsIView* aView)
 {
-  nsIFrame *frame = static_cast<nsIFrame *>(aView->GetClientData());
+  nsIFrame *frame = aView->GetFrame();
   if (!frame || frame->GetType() != nsGkAtoms::menuPopupFrame)
     return nsnull;
 
   // no point moving or resizing hidden popups
   nsMenuPopupFrame* menuPopupFrame = static_cast<nsMenuPopupFrame *>(frame);
   if (menuPopupFrame->PopupState() != ePopupOpenAndVisible)
     return nsnull;
 
@@ -995,17 +995,17 @@ nsXULPopupManager::HidePopupCallback(nsI
                            foundMenu->PopupType(), aDeselectMenu);
     }
   }
 }
 
 void
 nsXULPopupManager::HidePopup(nsIView* aView)
 {
-  nsIFrame *frame = static_cast<nsIFrame *>(aView->GetClientData());
+  nsIFrame *frame = aView->GetFrame();
   if (!frame || frame->GetType() != nsGkAtoms::menuPopupFrame)
     return;
 
   HidePopup(frame->GetContent(), false, true, false);
 }
 
 void
 nsXULPopupManager::HidePopupAfterDelay(nsMenuPopupFrame* aPopup)
--- a/view/public/nsIView.h
+++ b/view/public/nsIView.h
@@ -40,16 +40,17 @@
 
 #include "nsISupports.h"
 #include "nsCoord.h"
 #include "nsRect.h"
 #include "nsPoint.h"
 #include "nsNativeWidget.h"
 #include "nsIWidget.h"
 #include "nsWidgetInitData.h"
+#include "nsIFrame.h"
 
 class nsIViewManager;
 class nsViewManager;
 class nsView;
 class nsWeakView;
 class nsIWidget;
 
 // Enumerated type to indicate the visibility of a layer.
@@ -57,18 +58,18 @@ class nsIWidget;
 // show - the layer is shown irrespective of the visibility of 
 //        the layer's parent.
 enum nsViewVisibility {
   nsViewVisibility_kHide = 0,
   nsViewVisibility_kShow = 1
 };
 
 #define NS_IVIEW_IID    \
-  { 0x7caf32d2, 0xd82a, 0x4b9f, \
-    { 0x84, 0xc1, 0xbd, 0x20, 0xeb, 0x5c, 0x78, 0x55 } }
+  { 0xda62efbf, 0x0711, 0x4b79, \
+    { 0x87, 0x85, 0x9e, 0xec, 0xed, 0xf5, 0xb0, 0x32 } }
 
 // Public view flags
 
 // Indicates that the view is using auto z-indexing
 #define NS_VIEW_FLAG_AUTO_ZINDEX          0x0004
 
 // Indicates that the view is a floating view.
 #define NS_VIEW_FLAG_FLOATING             0x0008
@@ -246,26 +247,24 @@ public:
    * @result view's next sibling
    */
   nsIView* GetNextSibling() const { return reinterpret_cast<nsIView*>(mNextSibling); }
   void SetNextSibling(nsIView *aSibling) {
     mNextSibling = reinterpret_cast<nsView*>(aSibling);
   }
 
   /**
-   * Set the view's link to client owned data.
-   * @param aData - data to associate with view. nsnull to disassociate
+   * Set the view's frame.
    */
-  void SetClientData(void *aData) { mClientData = aData; }
+  void SetFrame(nsIFrame* aRootFrame) { mFrame = aRootFrame; }
 
   /**
-   * Query the view for it's link to client owned data.
-   * @result data associated with view or nsnull if there is none.
+   * Retrieve the view's frame.
    */
-  void* GetClientData() const { return mClientData; }
+  nsIFrame* GetFrame() const { return mFrame; }
 
   /**
    * Get the nearest widget in this view or a parent of this view and
    * the offset from the widget's origin to this view's origin
    * @param aOffset - if non-null the offset from this view's origin to the
    * widget's origin (usually positive) expressed in appunits of this will be
    * returned in aOffset.
    * @return the widget closest to this view; can be null because some view trees
@@ -394,17 +393,17 @@ public:
 
 protected:
   friend class nsWeakView;
   nsViewManager     *mViewManager;
   nsView            *mParent;
   nsIWidget         *mWindow;
   nsView            *mNextSibling;
   nsView            *mFirstChild;
-  void              *mClientData;
+  nsIFrame          *mFrame;
   PRInt32           mZIndex;
   nsViewVisibility  mVis;
   // position relative our parent view origin but in our appunits
   nscoord           mPosX, mPosY;
   // relative to parent, but in our appunits
   nsRect            mDimBounds;
   // in our appunits
   nsPoint           mViewToWidgetOffset;
--- a/view/public/nsIViewObserver.h
+++ b/view/public/nsIViewObserver.h
@@ -45,18 +45,18 @@
 
 class nsRenderingContext;
 class nsGUIEvent;
 class nsIWidget;
 class nsRegion;
 class nsIntRegion;
 
 #define NS_IVIEWOBSERVER_IID  \
-  { 0xac6eec35, 0x65d2, 0x4fe8, \
-    { 0xa1, 0x37, 0x1a, 0xc3, 0xf6, 0x51, 0x52, 0x56 } }
+  { 0x0d7ea18f, 0xc154, 0x4e25, \
+    { 0x81, 0x0c, 0x5d, 0x60, 0x31, 0xd0, 0xac, 0xc3 } }
 
 class nsIViewObserver : public nsISupports
 {
 public:
   
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IVIEWOBSERVER_IID)
 
   /* called when the observer needs to paint. This paints the entire
@@ -82,27 +82,26 @@ public:
   NS_IMETHOD Paint(nsIView*           aViewToPaint,
                    nsIWidget*         aWidgetToPaint,
                    const nsRegion&    aDirtyRegion,
                    const nsIntRegion& aIntDirtyRegion,
                    bool               aPaintDefaultBackground,
                    bool               aWillSendDidPaint) = 0;
 
   /* called when the observer needs to handle an event
-   * @param aView  - where to start processing the event; the root view,
-   * or the view that's currently capturing this sort of event; must be a view
-   * for this presshell
+   * @param aFrame  - the frame of where to start processing the event;
+   * must be a frame for this presshell
    * @param aEvent - event notification
    * @param aEventStatus - out parameter for event handling
    *                       status
    * @param aHandled - whether the correct frame was found to
    *                   handle the event
    * @return error status
    */
-  NS_IMETHOD HandleEvent(nsIView*       aView,
+  NS_IMETHOD HandleEvent(nsIFrame*      aFrame,
                          nsGUIEvent*    aEvent,
                          bool           aDontRetargetEvents,
                          nsEventStatus* aEventStatus) = 0;
 
   /* called when the view has been resized and the
    * content within the view needs to be reflowed.
    * @param aWidth - new width of view
    * @param aHeight - new height of view
--- a/view/src/nsView.cpp
+++ b/view/src/nsView.cpp
@@ -978,18 +978,18 @@ void nsIView::List(FILE* out, PRInt32 aI
     fprintf(out, "(widget=%p[%d] z=%d pos={%d,%d,%d,%d}) ",
             (void*)mWindow, widgetRefCnt, Z,
             nonclientBounds.x, nonclientBounds.y,
             windowBounds.width, windowBounds.height);
   }
   nsRect brect = GetBounds();
   fprintf(out, "{%d,%d,%d,%d}",
           brect.x, brect.y, brect.width, brect.height);
-  fprintf(out, " z=%d vis=%d clientData=%p <\n",
-          mZIndex, mVis, mClientData);
+  fprintf(out, " z=%d vis=%d frame=%p <\n",
+          mZIndex, mVis, mFrame);
   for (nsView* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
     NS_ASSERTION(kid->GetParent() == this, "incorrect parent");
     kid->List(out, aIndent + 1);
   }
   for (i = aIndent; --i >= 0; ) fputs("  ", out);
   fputs(">\n", out);
 }
 #endif // DEBUG
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -950,17 +950,17 @@ NS_IMETHODIMP nsViewManager::DispatchEve
 
     case NS_SYSCOLORCHANGED:
       {
         // Hold a refcount to the observer. The continued existence of the observer will
         // delay deletion of this view hierarchy should the event want to cause its
         // destruction in, say, some JavaScript event handler.
         nsCOMPtr<nsIViewObserver> obs = GetViewObserver();
         if (obs) {
-          obs->HandleEvent(aView, aEvent, false, aStatus);
+          obs->HandleEvent(aView->GetFrame(), aEvent, false, aStatus);
         }
       }
       break; 
 
     default:
       {
         if ((NS_IS_MOUSE_EVENT(aEvent) &&
              // Ignore mouse events that we synthesize.
@@ -981,55 +981,59 @@ NS_IMETHODIMP nsViewManager::DispatchEve
           // if a window is deactivated, clear the mouse capture regardless
           // of what is capturing
           nsIViewObserver* viewObserver = GetViewObserver();
           if (viewObserver) {
             viewObserver->ClearMouseCapture(nsnull);
           }
         }
 
-        //Find the view whose coordinates system we're in.
-        nsView* baseView = static_cast<nsView*>(aView);
-        nsView* view = baseView;
+        // Find the view whose coordinates system we're in.
+        nsIView* view = aView;
+        bool dispatchUsingCoordinates = NS_IsEventUsingCoordinates(aEvent);
+        if (dispatchUsingCoordinates) {
+          // Will dispatch using coordinates. Pretty bogus but it's consistent
+          // with what presshell does.
+          view = GetDisplayRootFor(view);
+        }
+  
+        // If the view has no frame, look for a view that does.
+        nsIFrame* frame = view->GetFrame();
+        if (!frame &&
+            (dispatchUsingCoordinates || NS_IS_KEY_EVENT(aEvent) ||
+             NS_IS_IME_RELATED_EVENT(aEvent) ||
+             NS_IS_NON_RETARGETED_PLUGIN_EVENT(aEvent) ||
+             aEvent->message == NS_PLUGIN_ACTIVATE ||
+             aEvent->message == NS_PLUGIN_FOCUS)) {
+          while (view && !view->GetFrame()) {
+            view = view->GetParent();
+          }
 
-        if (NS_IsEventUsingCoordinates(aEvent)) {
-          // will dispatch using coordinates. Pretty bogus but it's consistent
-          // with what presshell does.
-          view = static_cast<nsView*>(GetDisplayRootFor(baseView));
+          if (view) {
+            frame = view->GetFrame();
+          }
         }
 
-        if (nsnull != view) {
-          *aStatus = HandleEvent(view, aEvent);
+        if (nsnull != frame) {
+          // Hold a refcount to the presshell. The continued existence of the
+          // presshell will delay deletion of this view hierarchy should the event
+          // want to cause its destruction in, say, some JavaScript event handler.
+          nsCOMPtr<nsIViewObserver> obs = view->GetViewManager()->GetViewObserver();
+          if (obs) {
+            obs->HandleEvent(frame, aEvent, false, aStatus);
+          }
         }
     
         break;
       }
     }
 
   return NS_OK;
 }
 
-nsEventStatus nsViewManager::HandleEvent(nsView* aView, nsGUIEvent* aEvent)
-{
-#if 0
-  printf(" %d %d %d %d (%d,%d) \n", this, event->widget, event->widgetSupports, 
-         event->message, event->point.x, event->point.y);
-#endif
-  // Hold a refcount to the observer. The continued existence of the observer will
-  // delay deletion of this view hierarchy should the event want to cause its
-  // destruction in, say, some JavaScript event handler.
-  nsCOMPtr<nsIViewObserver> obs = aView->GetViewManager()->GetViewObserver();
-  nsEventStatus status = nsEventStatus_eIgnore;
-  if (obs) {
-     obs->HandleEvent(aView, aEvent, false, &status);
-  }
-
-  return status;
-}
-
 // Recursively reparent widgets if necessary 
 
 void nsViewManager::ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget)
 {
   NS_PRECONDITION(aNewWidget, "");
 
   if (aView->HasWidget()) {
     // Check to see if the parent widget is the
--- a/view/src/nsViewManager.h
+++ b/view/src/nsViewManager.h
@@ -239,18 +239,16 @@ private:
 
   nsresult UpdateView(nsIView *aView, const nsRect &aRect, PRUint32 aUpdateFlags);
 
 public: // NOT in nsIViewManager, so private to the view module
   nsView* GetRootViewImpl() const { return mRootView; }
   nsViewManager* RootViewManager() const { return mRootViewManager; }
   bool IsRootVM() const { return this == RootViewManager(); }
 
-  nsEventStatus HandleEvent(nsView* aView, nsGUIEvent* aEvent);
-
   bool IsRefreshEnabled() { return RootViewManager()->mUpdateBatchCnt == 0; }
 
   // Call this when you need to let the viewmanager know that it now has
   // pending updates.
   void PostPendingUpdate() { RootViewManager()->mHasPendingUpdates = true; }
 
   PRUint32 AppUnitsPerDevPixel() const
   {