Bug 352093. Part 1: Add view parameter to nsViewManager::DispatchEvent so we can target view system events to widget-less documents. r=bzbarsky
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 22 Jul 2009 12:44:59 +1200
changeset 30521 dfa7ab1fe97c6a5015cf5ffd73bd21109d4662bf
parent 30520 d54c8b8b2eccd19e07664348dfaaa2452196f3f0
child 30522 6d131711f67fa1e16c33304abd104466a7f17e63
push idunknown
push userunknown
push dateunknown
reviewersbzbarsky
bugs352093
milestone1.9.2a1pre
Bug 352093. Part 1: Add view parameter to nsViewManager::DispatchEvent so we can target view system events to widget-less documents. r=bzbarsky
extensions/widgetutils/src/nsWidgetUtils.cpp
layout/base/nsPresShell.cpp
view/public/nsIViewManager.h
view/src/nsView.cpp
view/src/nsViewManager.cpp
view/src/nsViewManager.h
--- a/extensions/widgetutils/src/nsWidgetUtils.cpp
+++ b/extensions/widgetutils/src/nsWidgetUtils.cpp
@@ -294,28 +294,28 @@ nsWidgetUtils::MouseMove(nsIDOMEvent* aD
   if (!aView)
     if (NS_FAILED(UpdateFromEvent(aDOMEvent)))
       return NS_OK;
 
   nsEventStatus statusX;
   nsMouseScrollEvent scrollEventX(PR_TRUE, NS_MOUSE_SCROLL, mWidget);
   scrollEventX.delta = dx;
   scrollEventX.scrollFlags = nsMouseScrollEvent::kIsHorizontal | nsMouseScrollEvent::kIsPixels;
-  mViewManager->DispatchEvent(&scrollEventX, &statusX);
+  mViewManager->DispatchEvent(&scrollEventX, aView, &statusX);
   if(statusX != nsEventStatus_eIgnore ){
     if (dx > 5)
       g_panning = PR_TRUE;
     g_lastX = x;
   }
 
   nsEventStatus statusY;
   nsMouseScrollEvent scrollEventY(PR_TRUE, NS_MOUSE_SCROLL, mWidget);
   scrollEventY.delta = dy;
   scrollEventY.scrollFlags = nsMouseScrollEvent::kIsVertical | nsMouseScrollEvent::kIsPixels;
-  mViewManager->DispatchEvent(&scrollEventY, &statusY);
+  mViewManager->DispatchEvent(&scrollEventY, aView, &statusY);
   if(statusY != nsEventStatus_eIgnore ){
     if (dy > 5)
       g_panning = PR_TRUE;
     g_lastY = y;
   }
   if (g_panning) {
      aDOMEvent->StopPropagation();
      aDOMEvent->PreventDefault();
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -4471,17 +4471,19 @@ PresShell::InvalidateFrameForView(nsIVie
 }
 
 NS_IMETHODIMP_(void)
 PresShell::DispatchSynthMouseMove(nsGUIEvent *aEvent,
                                   PRBool aFlushOnHoverChange)
 {
   PRUint32 hoverGenerationBefore = mFrameConstructor->GetHoverGeneration();
   nsEventStatus status;
-  mViewManager->DispatchEvent(aEvent, &status);
+  nsIView* rootView;
+  mViewManager->GetRootView(rootView);
+  mViewManager->DispatchEvent(aEvent, rootView, &status);
   if (aFlushOnHoverChange &&
       hoverGenerationBefore != mFrameConstructor->GetHoverGeneration()) {
     // Flush so that the resulting reflow happens now so that our caller
     // can suppress any synthesized mouse moves caused by that reflow.
     FlushPendingNotifications(Flush_Layout);
   }
 }
 
--- a/view/public/nsIViewManager.h
+++ b/view/public/nsIViewManager.h
@@ -54,20 +54,20 @@ enum nsRectVisibility {
   nsRectVisibility_kVisible, 
   nsRectVisibility_kAboveViewport, 
   nsRectVisibility_kBelowViewport, 
   nsRectVisibility_kLeftOfViewport, 
   nsRectVisibility_kRightOfViewport, 
   nsRectVisibility_kZeroAreaRect
 }; 
 
-// fa490965-ebd0-4203-836c-51c42d01fedb
+// 98f676da-eb1a-467d-9c0e-0d64c2c88d85
 #define NS_IVIEWMANAGER_IID   \
-{ 0xfa490965, 0xebd0, 0x4203, \
-  { 0x83, 0x6c, 0x51, 0xc4, 0x2d, 0x01, 0xfe, 0xdb } }
+  { 0x98f676da, 0xeb1a, 0x467d, \
+    { 0x9c, 0x0e, 0x0d, 0x64, 0xc2, 0xc8, 0x8d, 0x85 } }
 
 class nsIViewManager : public nsISupports
 {
 public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IVIEWMANAGER_IID)
   /**
    * Initialize the ViewManager
@@ -176,20 +176,22 @@ public:
    * @param aUpdateFlags see bottom of nsIViewManager.h for description
    */
   NS_IMETHOD  UpdateAllViews(PRUint32 aUpdateFlags) = 0;
 
   /**
    * Called to dispatch an event to the appropriate view. Often called
    * as a result of receiving a mouse or keyboard event from the widget
    * event system.
-   * @param event event to dispatch
-   * @result event handling status
+   * @param aEvent event to dispatch
+   * @param aViewTarget dispatch the event to this view
+   * @param aStatus event handling status
    */
-  NS_IMETHOD  DispatchEvent(nsGUIEvent *aEvent, nsEventStatus* aStatus) = 0;
+  NS_IMETHOD  DispatchEvent(nsGUIEvent *aEvent,
+      nsIView* aViewTarget, nsEventStatus* aStatus) = 0;
 
   /**
    * Used to grab/capture all mouse events for a specific view,
    * irrespective of the cursor position at which the
    * event occurred.
    * @param aView view to capture mouse events
    * @result event handling status
    */
--- a/view/src/nsView.cpp
+++ b/view/src/nsView.cpp
@@ -160,17 +160,17 @@ nsEventStatus HandleEvent(nsGUIEvent *aE
 //printf(" %d %d %d (%d,%d) \n", aEvent->widget, aEvent->widgetSupports, 
 //       aEvent->message, aEvent->point.x, aEvent->point.y);
   nsEventStatus result = nsEventStatus_eIgnore;
   nsView       *view = nsView::GetViewFor(aEvent->widget);
 
   if (view)
   {
     nsCOMPtr<nsIViewManager> vm = view->GetViewManager();
-    vm->DispatchEvent(aEvent, &result);
+    vm->DispatchEvent(aEvent, view, &result);
   }
 
   return result;
 }
 
 nsView::nsView(nsViewManager* aViewManager, nsViewVisibility aVisibility)
 {
   MOZ_COUNT_CTOR(nsView);
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -858,54 +858,52 @@ void nsViewManager::UpdateViews(nsView *
   // update all children as well.
   nsView* childView = aView->GetFirstChild();
   while (nsnull != childView)  {
     UpdateViews(childView, aUpdateFlags);
     childView = childView->GetNextSibling();
   }
 }
 
-NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aStatus)
+NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
+                                           nsIView* aView, nsEventStatus *aStatus)
 {
   *aStatus = nsEventStatus_eIgnore;
 
   switch(aEvent->message)
     {
     case NS_SIZE:
       {
-        nsView* view = nsView::GetViewFor(aEvent->widget);
-
-        if (nsnull != view)
+        if (aView)
           {
             nscoord width = ((nsSizeEvent*)aEvent)->windowSize->width;
             nscoord height = ((nsSizeEvent*)aEvent)->windowSize->height;
             width = ((nsSizeEvent*)aEvent)->mWinWidth;
             height = ((nsSizeEvent*)aEvent)->mWinHeight;
 
             // The root view may not be set if this is the resize associated with
             // window creation
 
-            if (view == mRootView)
+            if (aView == mRootView)
               {
                 PRInt32 p2a = mContext->AppUnitsPerDevPixel();
                 SetWindowDimensions(NSIntPixelsToAppUnits(width, p2a),
                                     NSIntPixelsToAppUnits(height, p2a));
                 *aStatus = nsEventStatus_eConsumeNoDefault;
               }
           }
 
         break;
       }
 
     case NS_PAINT:
       {
         nsPaintEvent *event = static_cast<nsPaintEvent*>(aEvent);
-        nsView *view = nsView::GetViewFor(aEvent->widget);
 
-        if (!view || !mContext)
+        if (!aView || !mContext)
           break;
 
         *aStatus = nsEventStatus_eConsumeNoDefault;
 
         // The rect is in device units, and it's in the coordinate space of its
         // associated window.
         nsCOMPtr<nsIRegion> region = event->region;
         if (!region) {
@@ -952,16 +950,17 @@ NS_IMETHODIMP nsViewManager::DispatchEve
             // Make sure to not send WillPaint notifications while scrolling
             nsRefPtr<nsViewManager> rootVM = RootViewManager();
 
             nsIWidget *widget = mRootView->GetWidget();
             PRBool transparentWindow = PR_FALSE;
             if (widget)
                 transparentWindow = widget->GetTransparencyMode() == eTransparencyTransparent;
 
+            nsView* view = static_cast<nsView*>(aView);
             if (rootVM->mScrollCnt == 0 && !transparentWindow) {
               nsIViewObserver* observer = GetViewObserver();
               if (observer) {
                 // Do an update view batch.  Make sure not to do it DEFERRED,
                 // since that would effectively delay any invalidates that are
                 // triggered by the WillPaint notification (they'd happen when
                 // the invalid event fires, which is later than the reflow
                 // event would fire and could end up being after some timer
@@ -998,20 +997,20 @@ NS_IMETHODIMP nsViewManager::DispatchEve
           nsIntRect damIntRect;
           region->GetBoundingBox(&damIntRect.x, &damIntRect.y,
                                  &damIntRect.width, &damIntRect.height);
           nsRect damRect =
             damIntRect.ToAppUnits(mContext->AppUnitsPerDevPixel());
 
           nsCOMPtr<nsIRenderingContext> context = event->renderingContext;
           if (!context)
-            context = CreateRenderingContext(*view);
+            context = CreateRenderingContext(*static_cast<nsView*>(aView));
 
           if (context)
-            mObserver->PaintDefaultBackground(view, context, damRect);
+            mObserver->PaintDefaultBackground(aView, context, damRect);
           else
             NS_WARNING("nsViewManager: no rc for default refresh");        
 
           // Clients like the editor can trigger multiple
           // reflows during what the user perceives as a single
           // edit operation, so it disables view manager
           // refreshing until the edit operation is complete
           // so that users don't see the intermediate steps.
@@ -1029,17 +1028,17 @@ NS_IMETHODIMP nsViewManager::DispatchEve
           //
           // Note that calling UpdateView() here was deemed
           // to have the least impact on performance, since the
           // other alternative was to make Scroll() post an
           // async paint event for the *entire* ScrollPort or
           // ScrollingView's viewable area. (See bug 97674 for this
           // alternate patch.)
 
-          UpdateView(view, damRect, NS_VMREFRESH_NO_SYNC);
+          UpdateView(aView, damRect, NS_VMREFRESH_NO_SYNC);
         }
 
         break;
       }
 
     case NS_CREATE:
     case NS_DESTROY:
     case NS_SETZLEVEL:
@@ -1059,20 +1058,19 @@ NS_IMETHODIMP nsViewManager::DispatchEve
       *aStatus = nsEventStatus_eConsumeDoDefault;
       break;
 
     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.
-        nsView *view = nsView::GetViewFor(aEvent->widget);
         nsCOMPtr<nsIViewObserver> obs = GetViewObserver();
         if (obs) {
-          obs->HandleEvent(view, aEvent, aStatus);
+          obs->HandleEvent(aView, aEvent, aStatus);
         }
       }
       break; 
 
     default:
       {
         if ((NS_IS_MOUSE_EVENT(aEvent) &&
              // Ignore moves that we synthesize.
@@ -1090,17 +1088,17 @@ NS_IMETHODIMP nsViewManager::DispatchEve
         }
 
         if (aEvent->message == NS_DEACTIVATE) {
           PRBool result;
           GrabMouseEvents(nsnull, result);
         }
 
         //Find the view whose coordinates system we're in.
-        nsView* baseView = nsView::GetViewFor(aEvent->widget);
+        nsView* baseView = static_cast<nsView*>(aView);
         nsView* view = baseView;
         PRBool capturedEvent = PR_FALSE;
         
         if (!NS_IS_KEY_EVENT(aEvent) && !NS_IS_IME_EVENT(aEvent) &&
             !NS_IS_CONTEXT_MENU_KEY(aEvent) && !NS_IS_FOCUS_EVENT(aEvent) &&
             !NS_IS_QUERY_CONTENT_EVENT(aEvent) && !NS_IS_PLUGIN_EVENT(aEvent) &&
             !NS_IS_SELECTION_EVENT(aEvent) &&
              aEvent->eventStructType != NS_ACCESSIBLE_EVENT) {
@@ -1172,17 +1170,17 @@ NS_IMETHODIMP nsViewManager::DispatchEve
 
             //Subtract back offset from root of view
             for (parent = view; parent; parent = parent->GetParent())
               parent->ConvertFromParentCoords(&offset.x, &offset.y);
           }
 
           // Dispatch the event
           nsRect baseViewDimensions;
-          if (baseView != nsnull) {
+          if (baseView) {
             baseView->GetDimensions(baseViewDimensions);
           }
 
           nsPoint pt;
           pt.x = baseViewDimensions.x + 
             NSFloatPixelsToAppUnits(float(aEvent->refPoint.x) + 0.5f, p2a);
           pt.y = baseViewDimensions.y + 
             NSFloatPixelsToAppUnits(float(aEvent->refPoint.y) + 0.5f, p2a);
--- a/view/src/nsViewManager.h
+++ b/view/src/nsViewManager.h
@@ -125,17 +125,18 @@ public:
   NS_IMETHOD  FlushDelayedResize();
 
   NS_IMETHOD  Composite(void);
 
   NS_IMETHOD  UpdateView(nsIView *aView, PRUint32 aUpdateFlags);
   NS_IMETHOD  UpdateView(nsIView *aView, const nsRect &aRect, PRUint32 aUpdateFlags);
   NS_IMETHOD  UpdateAllViews(PRUint32 aUpdateFlags);
 
-  NS_IMETHOD  DispatchEvent(nsGUIEvent *aEvent, nsEventStatus* aStatus);
+  NS_IMETHOD  DispatchEvent(nsGUIEvent *aEvent,
+      nsIView* aTargetView, nsEventStatus* aStatus);
 
   NS_IMETHOD  GrabMouseEvents(nsIView *aView, PRBool &aResult);
 
   NS_IMETHOD  GetMouseEventGrabber(nsIView *&aView);
 
   NS_IMETHOD  InsertChild(nsIView *parent, nsIView *child, nsIView *sibling,
                           PRBool above);