diff --git a/chrome/browser/gtk/hover_controller_gtk.cc b/chrome/browser/gtk/hover_controller_gtk.cc
index 50a8f1ae1fb65befd441b89069b1e2ff4606d8c7..0737a97bb9c0b442522ef8f8d1a3b5b51b971b4e 100644
--- a/chrome/browser/gtk/hover_controller_gtk.cc
+++ b/chrome/browser/gtk/hover_controller_gtk.cc
@@ -16,12 +16,12 @@ HoverControllerGtk::HoverControllerGtk(GtkWidget* button)
   g_object_ref(button_);
   gtk_chrome_button_set_hover_state(GTK_CHROME_BUTTON(button_), 0);
 
-  g_signal_connect(button_, "enter-notify-event",
+  signals_.Connect(button_, "enter-notify-event",
                    G_CALLBACK(OnEnterThunk), this);
-  g_signal_connect(button_, "leave-notify-event",
+  signals_.Connect(button_, "leave-notify-event",
                    G_CALLBACK(OnLeaveThunk), this);
-  g_signal_connect(button_, "destroy",
-                   G_CALLBACK(OnButtonDestroyThunk), this);
+  signals_.Connect(button_, "destroy",
+                   G_CALLBACK(OnDestroyThunk), this);
 
 #ifndef NDEBUG
   if (g_object_get_data(G_OBJECT(button_), kHoverControllerGtkKey))
@@ -54,10 +54,7 @@ HoverControllerGtk* HoverControllerGtk::GetHoverControllerGtk(
 
 void HoverControllerGtk::Destroy() {
   gtk_chrome_button_set_hover_state(GTK_CHROME_BUTTON(button_), -1.0);
-  g_signal_handlers_disconnect_by_func(
-      button_,
-      reinterpret_cast<gpointer>(OnButtonDestroyThunk),
-      this);
+
   g_object_set_data(G_OBJECT(button_), kHoverControllerGtkKey, NULL);
   g_object_unref(button_);
   button_ = NULL;
@@ -111,6 +108,6 @@ gboolean HoverControllerGtk::OnLeave(GtkWidget* widget,
   return FALSE;
 }
 
-void HoverControllerGtk::OnButtonDestroy(GtkWidget* widget) {
+void HoverControllerGtk::OnDestroy(GtkWidget* widget) {
   Destroy();
 }
diff --git a/chrome/browser/gtk/hover_controller_gtk.h b/chrome/browser/gtk/hover_controller_gtk.h
index 6867503f4b16cd21cddf4431fcee99b8787b83a5..10196ad12e58f4ea4af12db9bee525a631ad6685 100644
--- a/chrome/browser/gtk/hover_controller_gtk.h
+++ b/chrome/browser/gtk/hover_controller_gtk.h
@@ -7,6 +7,7 @@
 
 #include <gtk/gtk.h>
 
+#include "app/gtk_signal.h"
 #include "app/slide_animation.h"
 #include "app/throb_animation.h"
 #include "base/scoped_ptr.h"
@@ -44,30 +45,18 @@ class HoverControllerGtk : public AnimationDelegate {
   virtual void AnimationEnded(const Animation* animation);
   virtual void AnimationCanceled(const Animation* animation);
 
-  static gboolean OnEnterThunk(GtkWidget* widget,
-                               GdkEventCrossing* event,
-                               HoverControllerGtk* hover_controller) {
-    return hover_controller->OnEnter(widget, event);
-  }
-  gboolean OnEnter(GtkWidget* widget, GdkEventCrossing* event);
-
-  static gboolean OnLeaveThunk(GtkWidget* widget,
-                               GdkEventCrossing* event,
-                               HoverControllerGtk* hover_controller) {
-    return hover_controller->OnLeave(widget, event);
-  }
-  gboolean OnLeave(GtkWidget* widget, GdkEventCrossing* event);
-
-  static void OnButtonDestroyThunk(GtkWidget* widget,
-                                   HoverControllerGtk* hover_controller) {
-    hover_controller->OnButtonDestroy(widget);
-  }
-  void OnButtonDestroy(GtkWidget* widget);
+  CHROMEGTK_CALLBACK_1(HoverControllerGtk, gboolean, OnEnter,
+                       GdkEventCrossing*);
+  CHROMEGTK_CALLBACK_1(HoverControllerGtk, gboolean, OnLeave,
+                       GdkEventCrossing*);
+  CHROMEGTK_CALLBACK_0(HoverControllerGtk, void, OnDestroy);
 
   ThrobAnimation throb_animation_;
   SlideAnimation hover_animation_;
   GtkWidget* button_;
 
+  GtkSignalRegistrar signals_;
+
   DISALLOW_COPY_AND_ASSIGN(HoverControllerGtk);
 };
 
diff --git a/chrome/browser/gtk/tab_contents_drag_source.cc b/chrome/browser/gtk/tab_contents_drag_source.cc
index c3d94c0ee029fc825e9b8311581beb1cfdabff4b..ffd914e8806f72e936bf945358cda9025f06bdfb 100644
--- a/chrome/browser/gtk/tab_contents_drag_source.cc
+++ b/chrome/browser/gtk/tab_contents_drag_source.cc
@@ -32,29 +32,25 @@ TabContentsDragSource::TabContentsDragSource(
     : tab_contents_view_(tab_contents_view),
       drag_pixbuf_(NULL),
       drag_failed_(false),
-      drag_widget_(NULL),
-      drag_icon_(NULL) {
-  drag_widget_ = gtk_invisible_new();
-  g_signal_connect(drag_widget_, "drag-failed",
+      drag_widget_(gtk_invisible_new()),
+      drag_icon_(gtk_window_new(GTK_WINDOW_POPUP)) {
+  g_object_ref(drag_widget_);
+  signals_.Connect(drag_widget_, "drag-failed",
                    G_CALLBACK(OnDragFailedThunk), this);
-  g_signal_connect(drag_widget_, "drag-begin", G_CALLBACK(OnDragBeginThunk),
+  signals_.Connect(drag_widget_, "drag-begin",
+                   G_CALLBACK(OnDragBeginThunk),
                    this);
-  g_signal_connect(drag_widget_, "drag-end", G_CALLBACK(OnDragEndThunk), this);
-  g_signal_connect(drag_widget_, "drag-data-get",
+  signals_.Connect(drag_widget_, "drag-end",
+                   G_CALLBACK(OnDragEndThunk), this);
+  signals_.Connect(drag_widget_, "drag-data-get",
                    G_CALLBACK(OnDragDataGetThunk), this);
-  g_object_ref_sink(drag_widget_);
+
+  g_object_ref(drag_icon_);
+  signals_.Connect(drag_icon_, "expose-event",
+                   G_CALLBACK(OnDragIconExposeThunk), this);
 }
 
 TabContentsDragSource::~TabContentsDragSource() {
-  g_signal_handlers_disconnect_by_func(drag_widget_,
-      reinterpret_cast<gpointer>(OnDragFailedThunk), this);
-  g_signal_handlers_disconnect_by_func(drag_widget_,
-      reinterpret_cast<gpointer>(OnDragBeginThunk), this);
-  g_signal_handlers_disconnect_by_func(drag_widget_,
-      reinterpret_cast<gpointer>(OnDragEndThunk), this);
-  g_signal_handlers_disconnect_by_func(drag_widget_,
-      reinterpret_cast<gpointer>(OnDragDataGetThunk), this);
-
   // Break the current drag, if any.
   if (drop_data_.get()) {
     gtk_grab_add(drag_widget_);
@@ -63,9 +59,8 @@ TabContentsDragSource::~TabContentsDragSource() {
     drop_data_.reset();
   }
 
-  gtk_widget_destroy(drag_widget_);
   g_object_unref(drag_widget_);
-  drag_widget_ = NULL;
+  g_object_unref(drag_icon_);
 }
 
 TabContents* TabContentsDragSource::tab_contents() const {
@@ -319,18 +314,14 @@ void TabContentsDragSource::OnDragBegin(GtkWidget* sender,
   }
 
   if (drag_pixbuf_) {
-    drag_icon_ = gtk_window_new(GTK_WINDOW_POPUP);
-    g_object_ref_sink(drag_icon_);
-    g_signal_connect(drag_icon_, "expose-event",
-                     G_CALLBACK(OnDragIconExposeThunk), this);
     gtk_widget_set_size_request(drag_icon_,
                                 gdk_pixbuf_get_width(drag_pixbuf_),
                                 gdk_pixbuf_get_height(drag_pixbuf_));
 
-    GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET(drag_icon_));
+    GdkScreen* screen = gtk_widget_get_screen(drag_icon_);
     GdkColormap* rgba = gdk_screen_get_rgba_colormap(screen);
     if (rgba)
-      gtk_widget_set_colormap(GTK_WIDGET(drag_icon_), rgba);
+      gtk_widget_set_colormap(drag_icon_, rgba);
 
     gtk_drag_set_icon_widget(drag_context, drag_icon_,
                              image_offset_.x(), image_offset_.y());
@@ -339,10 +330,6 @@ void TabContentsDragSource::OnDragBegin(GtkWidget* sender,
 
 void TabContentsDragSource::OnDragEnd(GtkWidget* sender,
                                       GdkDragContext* drag_context) {
-  if (drag_icon_) {
-    g_object_unref(drag_icon_);
-    drag_icon_ = NULL;
-  }
   if (drag_pixbuf_) {
     g_object_unref(drag_pixbuf_);
     drag_pixbuf_ = NULL;
diff --git a/chrome/browser/gtk/tab_contents_drag_source.h b/chrome/browser/gtk/tab_contents_drag_source.h
index f43629ffb9fc6ee5f01d5e46585f46fcc5316d36..d11e4e1579be34cb224d7e5790cd2c85c9ffa33c 100644
--- a/chrome/browser/gtk/tab_contents_drag_source.h
+++ b/chrome/browser/gtk/tab_contents_drag_source.h
@@ -90,11 +90,11 @@ class TabContentsDragSource : public MessageLoopForUI::Observer {
   // The URL to download from for a drag-out download.
   GURL download_url_;
 
-  // The widget that provides visual feedback for the drag. We use this instead
-  // of gtk_drag_set_icon_pixbuf() because some window managers will use shadows
-  // or other visual effects on top level windows.
+  // The widget that provides visual feedback for the drag.
   GtkWidget* drag_icon_;
 
+  GtkSignalRegistrar signals_;
+
   DISALLOW_COPY_AND_ASSIGN(TabContentsDragSource);
 };