b=793501 attach DocumentViewer to top GTK widget r=roc
authorKarl Tomlinson <karlt+@karlt.net>
Tue, 23 Oct 2012 11:46:45 +1300
changeset 111238 a0158d3707850441cbbd3156395390380d90ef36
parent 111237 8da9c24417d07c87a8006a170efc2bfae0825512
child 111239 9ae8f8f7028fbd5793247806c7ffcaaf3ed79a67
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersroc
bugs793501
milestone19.0a1
b=793501 attach DocumentViewer to top GTK widget r=roc
layout/base/nsDocumentViewer.cpp
widget/gtk2/nsWindow.cpp
widget/gtk2/nsWindow.h
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -4058,17 +4058,17 @@ DocumentViewerImpl::ShouldAttachToTopLev
   nsCOMPtr<nsIDocShellTreeItem> containerItem = do_QueryReferent(mContainer);
   if (!containerItem)
     return false;
 
   // We always attach when using puppet widgets
   if (nsIWidget::UsePuppetWidgets())
     return true;
 
-#ifdef XP_WIN
+#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
   // On windows, in the parent process we also attach, but just to
   // chrome items
   int32_t docType;
   nsWindowType winType;
   containerItem->GetItemType(&docType);
   mParentWidget->GetWindowType(winType);
   if ((winType == eWindowType_toplevel ||
        winType == eWindowType_dialog ||
--- a/widget/gtk2/nsWindow.cpp
+++ b/widget/gtk2/nsWindow.cpp
@@ -447,29 +447,42 @@ nsWindow::DispatchDeactivateEvent(void)
     if (mWidgetListener)
       mWidgetListener->WindowDeactivated();
 
 #ifdef ACCESSIBILITY
     DispatchDeactivateEventAccessible();
 #endif //ACCESSIBILITY
 }
 
-
+void
+nsWindow::DispatchResized(int32_t aWidth, int32_t aHeight)
+{
+    nsIWidgetListener *listeners[] =
+        { mWidgetListener, mAttachedWidgetListener };
+    for (size_t i = 0; i < ArrayLength(listeners); ++i) {
+        if (listeners[i]) {
+            listeners[i]->WindowResized(this, aWidth, aHeight);
+        }
+    }
+}
 
 nsresult
 nsWindow::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus)
 {
 #ifdef DEBUG
     debug_DumpEvent(stdout, aEvent->widget, aEvent,
                     nsAutoCString("something"), 0);
 #endif
 
     aStatus = nsEventStatus_eIgnore;
-    if (mWidgetListener)
-      aStatus = mWidgetListener->HandleEvent(aEvent, mUseAttachedEvents);
+    nsIWidgetListener* listener =
+        mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
+    if (listener) {
+      aStatus = listener->HandleEvent(aEvent, mUseAttachedEvents);
+    }
 
     return NS_OK;
 }
 
 void
 nsWindow::OnDestroy(void)
 {
     if (mOnDestroyCalled)
@@ -1068,18 +1081,17 @@ nsWindow::Resize(int32_t aWidth, int32_t
             mNeedsResize = true;
         }
     }
 
     NotifyRollupGeometryChange(gRollupListener);
 
     // send a resize notification if this is a toplevel
     if (mIsTopLevel || mListenForResizes) {
-        if (mWidgetListener)
-            mWidgetListener->WindowResized(this, aWidth, aHeight);
+        DispatchResized(aWidth, aHeight);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::Resize(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight,
                        bool aRepaint)
@@ -1134,18 +1146,17 @@ nsWindow::Resize(int32_t aX, int32_t aY,
         else {
             mNeedsResize = true;
         }
     }
 
     NotifyRollupGeometryChange(gRollupListener);
 
     if (mIsTopLevel || mListenForResizes) {
-        if (mWidgetListener)
-            mWidgetListener->WindowResized(this, aWidth, aHeight);
+        DispatchResized(aWidth, aHeight);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::Enable(bool aState)
 {
@@ -2005,21 +2016,25 @@ nsWindow::OnExposeEvent(cairo_t *cr)
     if (mIsDestroyed) {
         return FALSE;
     }
 
     // Windows that are not visible will be painted after they become visible.
     if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel)
         return FALSE;
 
+    nsIWidgetListener *listener =
+        mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
+    if (!listener)
+        return FALSE;
+
     // Dispatch WillPaintWindow notification to allow scripts etc. to run
     // before we paint
     {
-        if (mWidgetListener)
-          mWidgetListener->WillPaintWindow(this, true);
+        listener->WillPaintWindow(this, true);
 
         // If the window has been destroyed during the will paint notification,
         // there is nothing left to do.
         if (!mGdkWindow)
             return TRUE;
     }
 
 #if defined(MOZ_WIDGET_GTK2)
@@ -2121,38 +2136,30 @@ nsWindow::OnExposeEvent(cairo_t *cr)
 #if defined(MOZ_WIDGET_GTK2)
         nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface());
 #else
         nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface(cr));
 #endif
         nsBaseWidget::AutoLayerManagerSetup
           setupLayerManager(this, ctx, mozilla::layers::BUFFER_NONE);
 
-        if (mWidgetListener)
-            mWidgetListener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
+        listener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
+        listener->DidPaintWindow();
 
         g_free(rects);
-
-        if (mWidgetListener)
-            mWidgetListener->DidPaintWindow();
-
         return TRUE;
 
     } else if (GetLayerManager()->GetBackendType() == mozilla::layers::LAYERS_OPENGL) {
         LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(GetLayerManager());
         manager->SetClippingRegion(region);
 
-        if (mWidgetListener)
-            mWidgetListener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
+        listener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
+        listener->DidPaintWindow();
 
         g_free(rects);
-
-        if (mWidgetListener)
-            mWidgetListener->DidPaintWindow();
-
         return TRUE;
     }
 
 #if defined(MOZ_WIDGET_GTK2)
     nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface());
 #else
     nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface(cr));
 #endif
@@ -2202,19 +2209,17 @@ nsWindow::OnExposeEvent(cairo_t *cr)
 #endif
 #endif
 
 #endif // MOZ_X11
 
     bool painted = false;
     {
       AutoLayerManagerSetup setupLayerManager(this, ctx, layerBuffering);
-
-      if (mWidgetListener)
-        painted = mWidgetListener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
+      painted = listener->PaintWindow(this, region, nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
     }
 
 #ifdef MOZ_X11
     // PaintWindow can Destroy us (bug 378273), avoid doing any paint
     // operations below if that happened - it will lead to XError and exit().
     if (shaped) {
         if (NS_LIKELY(!mIsDestroyed)) {
             if (painted) {
@@ -2256,18 +2261,17 @@ nsWindow::OnExposeEvent(cairo_t *cr)
 #endif // MOZ_X11
 
 #if defined(MOZ_WIDGET_GTK2)
     g_free(rects);
 #else
     cairo_rectangle_list_destroy(rects);
 #endif
 
-    if (mWidgetListener)
-      mWidgetListener->DidPaintWindow();
+    listener->DidPaintWindow();
 
     // Synchronously flush any new dirty areas
 #if defined(MOZ_WIDGET_GTK2)
     GdkRegion* dirtyArea = gdk_window_get_update_area(mGdkWindow);
 #else
     cairo_region_t* dirtyArea = gdk_window_get_update_area(mGdkWindow);
 #endif
 
@@ -2395,18 +2399,17 @@ nsWindow::OnSizeAllocate(GtkAllocation *
         gdk_window_invalidate_rect(mGdkWindow, &rect, FALSE);
     }
 
     mBounds.SizeTo(size);
 
     if (!mGdkWindow)
         return;
 
-    if (mWidgetListener)
-        mWidgetListener->WindowResized(this, size.width, size.height);
+    DispatchResized(size.width, size.height);
 }
 
 void
 nsWindow::OnDeleteEvent()
 {
     if (mWidgetListener)
         mWidgetListener->RequestWindowClose(this);
 }
--- a/widget/gtk2/nsWindow.h
+++ b/widget/gtk2/nsWindow.h
@@ -77,20 +77,16 @@ public:
     virtual ~nsWindow();
 
     static void ReleaseGlobals();
 
     NS_DECL_ISUPPORTS_INHERITED
     
     void CommonCreate(nsIWidget *aParent, bool aListenForResizes);
     
-    // event handling code
-    void DispatchActivateEvent(void);
-    void DispatchDeactivateEvent(void);
-
     virtual nsresult DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus);
     
     // called when we are destroyed
     void OnDestroy(void);
 
     // called to check and see if a widget's dimensions are sane
     bool AreBoundsSane(void);
 
@@ -292,16 +288,21 @@ public:
     virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint,
                                                 uint32_t aNativeMessage,
                                                 uint32_t aModifierFlags);
 
     virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint)
     { return SynthesizeNativeMouseEvent(aPoint, GDK_MOTION_NOTIFY, 0); }
 
 protected:
+    // event handling code
+    void DispatchActivateEvent(void);
+    void DispatchDeactivateEvent(void);
+    void DispatchResized(int32_t aWidth, int32_t aHeight);
+
     // Helper for SetParent and ReparentNativeWidget.
     void ReparentNativeWidgetInternal(nsIWidget* aNewParent,
                                       GtkWidget* aNewContainer,
                                       GdkWindow* aNewParentWindow,
                                       GtkWidget* aOldContainer);
     nsCOMPtr<nsIWidget> mParent;
     // Is this a toplevel window?
     bool                mIsTopLevel;