From 4c9471c16ba43fb40017e9f5fae8231799e86ccb Mon Sep 17 00:00:00 2001
From: "ben@chromium.org"
 <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Wed, 17 Jun 2009 04:23:00 +0000
Subject: Fix build bustage by removing another dependency on browser/gtk by
 creating a new TabContentsViewGtk specifically for views. This subclasses
 WidgetGtk similar to how TabContentsViewWin subclasses WidgetWin.

There was a bug in NativeViewHostGtk - reparenting needs to be done atomically using gtk_widget_reparent since GtkWidgets are refcounted and when removed from a container are released, causing a crash when a TabContents is reparented.

The code now compiles thanks to a stubbed BlockedPopupContainer, however there is one remaining issue - the browser window no longer paints and the app instantly hangs. However this is better than the current state so I figured I'd send the code review.
Review URL: http://codereview.chromium.org/126107

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18588 0039d316-1c4b-4281-b951-d872f2087c98
---
 views/controls/button/native_button_gtk.cc    |  8 ++--
 views/controls/button/native_button_gtk.h     |  2 +-
 views/controls/native/native_view_host_gtk.cc | 66 ++++++++-------------------
 views/controls/native/native_view_host_gtk.h  | 14 +++---
 4 files changed, 30 insertions(+), 60 deletions(-)

(limited to 'views/controls')

diff --git a/views/controls/button/native_button_gtk.cc b/views/controls/button/native_button_gtk.cc
index c97d1e0..1680019 100644
--- a/views/controls/button/native_button_gtk.cc
+++ b/views/controls/button/native_button_gtk.cc
@@ -83,7 +83,7 @@ gfx::Size NativeButtonGtk::GetPreferredSize() {
 void NativeButtonGtk::CreateNativeControl() {
   GtkWidget* widget = gtk_button_new();
   g_signal_connect(G_OBJECT(widget), "clicked",
-                   G_CALLBACK(CallClicked), NULL);
+                   G_CALLBACK(CallClicked), this);
   NativeControlCreated(widget);
 }
 
@@ -96,10 +96,8 @@ void NativeButtonGtk::NativeControlCreated(GtkWidget* widget) {
 }
 
 // static
-void NativeButtonGtk::CallClicked(GtkButton* widget) {
-  View* view = NativeViewHostGtk::GetViewForNative(GTK_WIDGET(widget));
-  if (view)
-    static_cast<NativeButtonGtk*>(view)->OnClicked();
+void NativeButtonGtk::CallClicked(GtkButton* widget, NativeButtonGtk* button) {
+  button->OnClicked();
 }
 
 void NativeButtonGtk::OnClicked() {
diff --git a/views/controls/button/native_button_gtk.h b/views/controls/button/native_button_gtk.h
index e719202..6c3f600 100644
--- a/views/controls/button/native_button_gtk.h
+++ b/views/controls/button/native_button_gtk.h
@@ -36,7 +36,7 @@ class NativeButtonGtk : public NativeControlGtk, public NativeButtonWrapper {
   virtual bool IsCheckbox() const { return false; }
 
  private:
-  static void CallClicked(GtkButton* widget);
+  static void CallClicked(GtkButton* widget, NativeButtonGtk* button);
 
   // Invoked when the user clicks on the button.
   void OnClicked();
diff --git a/views/controls/native/native_view_host_gtk.cc b/views/controls/native/native_view_host_gtk.cc
index 7f59144..6fa7325 100644
--- a/views/controls/native/native_view_host_gtk.cc
+++ b/views/controls/native/native_view_host_gtk.cc
@@ -24,47 +24,21 @@ NativeViewHostGtk::NativeViewHostGtk(NativeViewHost* host)
 NativeViewHostGtk::~NativeViewHostGtk() {
 }
 
-// static
-View* NativeViewHostGtk::GetViewForNative(GtkWidget* widget) {
-  gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-view");
-  return static_cast<View*>(user_data);
-}
-
-// static
-void NativeViewHostGtk::SetViewForNative(GtkWidget* widget, View* view) {
-  g_object_set_data(G_OBJECT(widget), "chrome-view", view);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // NativeViewHostGtk, NativeViewHostWrapper implementation:
 
 void NativeViewHostGtk::NativeViewAttached() {
   DCHECK(host_->native_view());
 
-  GtkWidget* current_parent = gtk_widget_get_parent(host_->native_view());
-  GtkWidget* new_parent = host_->GetWidget()->GetNativeView();
-  // Only adjust the parent if the parent actually changed.
-  if (current_parent != new_parent) {
-    // First hide the new window. We don't want anything to draw (like sub-hwnd
-    // borders), when we change the parent below.
-    gtk_widget_hide(host_->native_view());
-
-    if (current_parent) {
-      gtk_container_remove(GTK_CONTAINER(current_parent),
-                           host_->native_view());
-    }
-
-    // Adds a mapping between the GtkWidget and us.
-    SetViewForNative(host_->native_view(), host_);
-
-    if (!destroy_signal_id_) {
-      destroy_signal_id_ = g_signal_connect(G_OBJECT(host_->native_view()),
-                                            "destroy", G_CALLBACK(CallDestroy),
-                                            NULL);
-    }
+  if (gtk_widget_get_parent(host_->native_view()))
+    GetHostWidget()->ReparentChild(host_->native_view());
+  else
+    GetHostWidget()->AddChild(host_->native_view());
 
-    // Set the parent.
-    static_cast<WidgetGtk*>(host_->GetWidget())->AddChild(host_->native_view());
+  if (!destroy_signal_id_) {
+    destroy_signal_id_ = g_signal_connect(G_OBJECT(host_->native_view()),
+                                          "destroy", G_CALLBACK(CallDestroy),
+                                          this);
   }
 
   // Always layout though.
@@ -88,9 +62,9 @@ void NativeViewHostGtk::NativeViewDetaching() {
 void NativeViewHostGtk::AddedToWidget() {
   if (!host_->native_view())
     return;
-  WidgetGtk* parent_widget = static_cast<WidgetGtk*>(host_->GetWidget());
+  WidgetGtk* parent_widget = GetHostWidget();
   GtkWidget* widget_parent = gtk_widget_get_parent(host_->native_view());
-  GtkWidget* parent_widget_widget = parent_widget->child_widget_parent();
+  GtkWidget* parent_widget_widget = parent_widget->window_contents();
   if (widget_parent != parent_widget_widget) {
     g_object_ref(host_->native_view());
     if (widget_parent)
@@ -110,10 +84,10 @@ void NativeViewHostGtk::RemovedFromWidget() {
   if (!host_->native_view())
     return;
 
-  WidgetGtk* parent_widget = static_cast<WidgetGtk*>(host_->GetWidget());
+  WidgetGtk* parent_widget = GetHostWidget();
   gtk_widget_hide(host_->native_view());
   if (parent_widget) {
-    gtk_container_remove(GTK_CONTAINER(parent_widget->child_widget_parent()),
+    gtk_container_remove(GTK_CONTAINER(parent_widget->window_contents()),
                          host_->native_view());
   }
 }
@@ -157,8 +131,7 @@ void NativeViewHostGtk::UninstallClip() {
 }
 
 void NativeViewHostGtk::ShowWidget(int x, int y, int w, int h) {
-  WidgetGtk* parent = static_cast<WidgetGtk*>(host_->GetWidget());
-  parent->PositionChild(host_->native_view(), x, y, w, h);
+  GetHostWidget()->PositionChild(host_->native_view(), x, y, w, h);
   gtk_widget_show(host_->native_view());
 }
 
@@ -173,13 +146,14 @@ void NativeViewHostGtk::SetFocus() {
 ////////////////////////////////////////////////////////////////////////////////
 // NativeViewHostGtk, private:
 
-// static
-void NativeViewHostGtk::CallDestroy(GtkObject* object) {
-  View* view = GetViewForNative(GTK_WIDGET(object));
-  if (!view)
-    return;
+WidgetGtk* NativeViewHostGtk::GetHostWidget() const {
+  return static_cast<WidgetGtk*>(host_->GetWidget());
+}
 
-  return static_cast<NativeViewHost*>(view)->NativeViewDestroyed();
+// static
+void NativeViewHostGtk::CallDestroy(GtkObject* object,
+                                    NativeViewHostGtk* host) {
+  return host->host_->NativeViewDestroyed();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/views/controls/native/native_view_host_gtk.h b/views/controls/native/native_view_host_gtk.h
index 40a6a65..154da70 100644
--- a/views/controls/native/native_view_host_gtk.h
+++ b/views/controls/native/native_view_host_gtk.h
@@ -14,17 +14,13 @@
 namespace views {
 
 class View;
+class WidgetGtk;
 
 class NativeViewHostGtk : public NativeViewHostWrapper {
  public:
   explicit NativeViewHostGtk(NativeViewHost* host);
   virtual ~NativeViewHostGtk();
 
-  // Sets and retrieves the View associated with a particular widget.
-  // TODO(beng): move to NativeViewHost, and have take gfx::NativeViews.
-  static View* GetViewForNative(GtkWidget* widget);
-  static void SetViewForNative(GtkWidget* widget, View* view);
-
   // Overridden from NativeViewHostWrapper:
   virtual void NativeViewAttached();
   virtual void NativeViewDetaching();
@@ -38,6 +34,11 @@ class NativeViewHostGtk : public NativeViewHostWrapper {
   virtual void SetFocus();
 
  private:
+  WidgetGtk* GetHostWidget() const;
+
+  // Invoked from the 'destroy' signal.
+  static void CallDestroy(GtkObject* object, NativeViewHostGtk* host);
+
   // Our associated NativeViewHost.
   NativeViewHost* host_;
 
@@ -48,9 +49,6 @@ class NativeViewHostGtk : public NativeViewHostWrapper {
   // Signal handle id for 'destroy' signal.
   gulong destroy_signal_id_;
 
-  // Invoked from the 'destroy' signal.
-  static void CallDestroy(GtkObject* object);
-
   DISALLOW_COPY_AND_ASSIGN(NativeViewHostGtk);
 };
 
-- 
cgit v1.1