From: Mike Hommey <mh@glandium.org>
Date: Thu, 25 Feb 2010 10:58:45 +0100
Subject: Reuse the GdkWindow in MozContainers

https://bugzilla.mozilla.org/show_bug.cgi?id=506433
---
 widget/src/gtk2/mozcontainer.c |   11 +++++++-
 widget/src/gtk2/mozcontainer.h |    5 ++++
 widget/src/gtk2/nsWindow.cpp   |   53 +++++++++++++++++----------------------
 3 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/widget/src/gtk2/mozcontainer.c b/widget/src/gtk2/mozcontainer.c
index 71b425f..89731a3 100644
--- a/widget/src/gtk2/mozcontainer.c
+++ b/widget/src/gtk2/mozcontainer.c
@@ -294,8 +294,15 @@ moz_container_realize (GtkWidget *widget)
 
     /* create the shell window */
 
-    attributes.event_mask = gtk_widget_get_events (widget);
-    attributes.event_mask |=  (GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK);
+    attributes.event_mask = (gtk_widget_get_events (widget) |
+                             GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK |
+                             GDK_VISIBILITY_NOTIFY_MASK |
+                             GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+                             GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+#ifdef HAVE_GTK_MOTION_HINTS
+                             GDK_POINTER_MOTION_HINT_MASK |
+#endif
+                             GDK_POINTER_MOTION_MASK);
     attributes.x = widget->allocation.x;
     attributes.y = widget->allocation.y;
     attributes.width = widget->allocation.width;
diff --git a/widget/src/gtk2/mozcontainer.h b/widget/src/gtk2/mozcontainer.h
index 8f1d2f0..7135873 100644
--- a/widget/src/gtk2/mozcontainer.h
+++ b/widget/src/gtk2/mozcontainer.h
@@ -83,6 +83,11 @@ extern "C" {
 #define IS_MOZ_CONTAINER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), MOZ_CONTAINER_TYPE))
 #define MOZ_CONAINTER_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), MOZ_CONTAINER_TYPE, MozContainerClass))
 
+#if (GTK_CHECK_VERSION(2, 12, 0) || \
+    (GTK_CHECK_VERSION(2, 10, 0) && defined(MOZ_PLATFORM_HILDON)))
+#define HAVE_GTK_MOTION_HINTS
+#endif
+
 typedef struct _MozContainer      MozContainer;
 typedef struct _MozContainerClass MozContainerClass;
 
diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp
index 234ccc5..e497d8e 100644
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -142,11 +142,6 @@ D_DEBUG_DOMAIN( ns_Window, "nsWindow", "nsWindow" );
 #define D_DEBUG_AT(x,y...)    do {} while (0)
 #endif
 
-#if (GTK_CHECK_VERSION(2, 12, 0) || \
-    (GTK_CHECK_VERSION(2, 10, 0) && defined(MOZ_PLATFORM_HILDON)))
-#define HAVE_GTK_MOTION_HINTS
-#endif
-
 // Don't put more than this many rects in the dirty region, just fluff
 // out to the bounding-box if there are more
 #define MAX_RECTS_IN_REGION 100
@@ -803,25 +798,27 @@ nsWindow::Destroy(void)
         gtk_widget_destroy(mShell);
         mShell = nsnull;
         mContainer = nsnull;
+        NS_ABORT_IF_FALSE(!mGdkWindow,
+                          "mGdkWindow should be NULL when mContainer is destroyed");
     }
     else if (mContainer) {
         gtk_widget_destroy(GTK_WIDGET(mContainer));
         mContainer = nsnull;
+        NS_ABORT_IF_FALSE(!mGdkWindow,
+                          "mGdkWindow should be NULL when mContainer is destroyed");
     }
-    else if (owningWidget) {
+    else if (mGdkWindow) {
         // Remove references from GdkWindows back to their container
         // widget while the GdkWindow hierarchy is still available.
         // (OnContainerUnrealize does this when the MozContainer widget is
         // destroyed.)
-        SetWidgetForHierarchy(mGdkWindow, owningWidget, NULL);
-    }
-
-    if (mGdkWindow) {
-        g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", NULL);
-
+        if (owningWidget) {
+            SetWidgetForHierarchy(mGdkWindow, owningWidget, NULL);
+        }
         NS_ASSERTION(!get_gtk_widget_for_gdk_window(mGdkWindow),
                      "widget reference not removed");
 
+        g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", NULL);
         gdk_window_destroy(mGdkWindow);
         mGdkWindow = nsnull;
     }
@@ -2569,6 +2566,9 @@ nsWindow::OnContainerUnrealize(GtkWidget *aWidget)
 
     if (mGdkWindow) {
         SetWidgetForHierarchy(mGdkWindow, aWidget, NULL);
+
+        g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", NULL);
+        mGdkWindow = NULL;
     }
 }
 
@@ -2590,8 +2590,6 @@ nsWindow::OnSizeAllocate(GtkWidget *aWidget, GtkAllocation *aAllocation)
     if (!mGdkWindow)
         return;
 
-    gdk_window_resize (mGdkWindow, rect.width, rect.height);
-
     if (mTransparencyBitmap) {
       ApplyTransparencyBitmap();
     }
@@ -4023,7 +4021,7 @@ nsWindow::NativeCreate(nsIWidget        *aParent,
         gtk_window_set_focus(GTK_WINDOW(mShell), container);
 
         // and the drawing area
-        mGdkWindow = CreateGdkWindow(container->window, container);
+        mGdkWindow = container->window;
 
         if (mWindowType == eWindowType_popup) {
             // gdk does not automatically set the cursor for "temporary"
@@ -4047,7 +4045,7 @@ nsWindow::NativeCreate(nsIWidget        *aParent,
             gtk_container_add(parentGtkContainer, container);
             gtk_widget_realize(container);
 
-            mGdkWindow = CreateGdkWindow(container->window, container);
+            mGdkWindow = container->window;
         }
         else {
             NS_WARNING("Warning: tried to create a new child widget with no parent!");
@@ -4159,8 +4157,7 @@ nsWindow::NativeCreate(nsIWidget        *aParent,
              (void *)GTK_WIDGET(mContainer)->window,
              GDK_WINDOW_XWINDOW(GTK_WIDGET(mContainer)->window)));
     }
-
-    if (mGdkWindow) {
+    else if (mGdkWindow) {
         LOG(("\tmGdkWindow %p %lx\n", (void *)mGdkWindow,
              GDK_WINDOW_XWINDOW(mGdkWindow)));
     }
@@ -4320,15 +4317,15 @@ nsWindow::NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool  aRepaint)
         gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight);
     }
     else if (mContainer) {
+        GtkWidget *widget = GTK_WIDGET(mContainer);
         GtkAllocation allocation;
-        allocation.x = 0;
-        allocation.y = 0;
+        allocation.x = widget->allocation.x;
+        allocation.y = widget->allocation.y;
         allocation.width = aWidth;
         allocation.height = aHeight;
-        gtk_widget_size_allocate(GTK_WIDGET(mContainer), &allocation);
+        gtk_widget_size_allocate(widget, &allocation);
     }
-
-    if (mGdkWindow) {
+    else if (mGdkWindow) {
         gdk_window_resize(mGdkWindow, aWidth, aHeight);
     }
 }
@@ -4359,12 +4356,11 @@ nsWindow::NativeResize(PRInt32 aX, PRInt32 aY,
     }
     else if (mContainer) {
         GtkAllocation allocation;
-        allocation.x = 0;
-        allocation.y = 0;
+        allocation.x = aX;
+        allocation.y = aY;
         allocation.width = aWidth;
         allocation.height = aHeight;
         gtk_widget_size_allocate(GTK_WIDGET(mContainer), &allocation);
-        gdk_window_move_resize(mGdkWindow, aX, aY, aWidth, aHeight);
     }
     else if (mGdkWindow) {
         gdk_window_move_resize(mGdkWindow, aX, aY, aWidth, aHeight);
@@ -4396,12 +4392,10 @@ nsWindow::NativeShow (PRBool  aAction)
                 SetUserTimeAndStartupIDForActivatedWindow(mShell);
             }
 
-            gdk_window_show_unraised(mGdkWindow);
             gtk_widget_show(GTK_WIDGET(mContainer));
             gtk_widget_show(mShell);
         }
         else if (mContainer) {
-            gdk_window_show_unraised(mGdkWindow);
             gtk_widget_show(GTK_WIDGET(mContainer));
         }
         else if (mGdkWindow) {
@@ -4415,9 +4409,8 @@ nsWindow::NativeShow (PRBool  aAction)
         }
         else if (mContainer) {
             gtk_widget_hide(GTK_WIDGET(mContainer));
-            gdk_window_hide(mGdkWindow);
         }
-        if (mGdkWindow) {
+        else if (mGdkWindow) {
             gdk_window_hide(mGdkWindow);
         }
     }
