2010-09-15 Martin Robinson <mrobinson@igalia.com>
authormrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Sep 2010 01:34:00 +0000 (01:34 +0000)
committermrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Sep 2010 01:34:00 +0000 (01:34 +0000)
        Reviewed by Eric Seidel.

        [Gtk] Use GOwnPtr for code that needs it
        https://bugs.webkit.org/show_bug.cgi?id=21594

        Convert as reference counted private members of WebKitWebView to
        smart pointers as possible. This removes a lot of unecessary manual
        memory management. Also convert some pointer members away from pointer
        types, now that we are sure their destructors are called.

        * WebCoreSupport/ContextMenuClientGtk.cpp:
        (WebKit::inputMethodsMenuItem): Updated to reflect PlatformRefPtr changes.
        * WebCoreSupport/DragClientGtk.cpp:
        (WebKit::DragClient::startDrag): Ditto.
        * WebCoreSupport/EditorClientGtk.cpp:
        (WebKit::EditorClient::setInputMethodState): Ditto.
        (WebKit::EditorClient::respondToChangedSelection): Ditto.
        (WebKit::EditorClient::handleInputMethodKeydown): Ditto.
        (WebKit::EditorClient::handleInputMethodMousePress): Ditto.
        (WebKit::EditorClient::EditorClient): Ditto.
        (WebKit::EditorClient::~EditorClient): Ditto.
        * WebCoreSupport/FrameLoaderClientGtk.cpp:
        (WebKit::postCommitFrameViewSetup): Ditto.
        * webkit/webkitprivate.h: Ditto.
        * webkit/webkitwebview.cpp: Ditto.
        (destroy_menu_cb): Ditto.
        (webkit_web_view_forward_context_menu_event): Ditto.
        (webkit_web_view_key_release_event): Ditto.
        (webkit_web_view_button_press_event): Ditto.
        (webkit_web_view_button_release_event): Ditto.
        (webkit_web_view_focus_in_event): Ditto.
        (webkit_web_view_focus_out_event): Ditto.
        (webkit_web_view_realize): Ditto.
        (webkit_web_view_set_scroll_adjustments): Ditto.
        (webkit_web_view_dispose): Changed all g_object_unref calls to
        PlatformRefPtr.clear(). Although this will also be done by the manual
        call to the WebKitWebViewPrivate destructor, the order that these
        fields are zero'd in is still very sensitive.
        (webkit_web_view_finalize): Updated to reflect PlatformRefPtr changes.
        (webViewGetDPI): Ditto.
        (webkit_web_view_screen_changed): Ditto.
        (webkit_web_view_drag_end): Ditto.
        (webkit_web_view_drag_data_get): Ditto.
        (doDragLeaveLater): Ditto.
        (webkit_web_view_drag_leave): Ditto.
        (webkit_web_view_drag_motion): Ditto.
        (webkit_web_view_drag_data_received): Ditto.
        (webkit_web_view_drag_drop): Ditto.
        (webkit_web_view_get_im_context): Ditto.
        (webkit_web_view_update_settings): Ditto.
        (webkit_web_view_init): Ditto.
        (webkit_web_view_set_settings): Ditto.
        (webkit_web_view_get_settings): Ditto.
        (webkit_web_view_get_inspector): Ditto.
        (webkit_web_view_set_window_features): Ditto.
        (webkit_web_view_get_window_features): Ditto.
        (webkit_web_view_get_back_forward_list): Ditto.
        (webkit_web_view_zoom_in): Ditto.
        (webkit_web_view_zoom_out): Ditto.
        (webkit_web_view_add_resource): Ditto.
        (webkit_web_view_get_resource): Ditto.
        (webkit_web_view_get_main_resource): Ditto.
        (webkit_web_view_clear_resources): Ditto.
        (webkit_web_view_get_subresources): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@67591 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/gtk/ChangeLog
WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp
WebKit/gtk/WebCoreSupport/DragClientGtk.cpp
WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
WebKit/gtk/webkit/webkitprivate.h
WebKit/gtk/webkit/webkitwebview.cpp

index 7747f27..9cbbff2 100644 (file)
@@ -1,3 +1,70 @@
+2010-09-15  Martin Robinson  <mrobinson@igalia.com>
+
+        Reviewed by Eric Seidel.
+
+        [Gtk] Use GOwnPtr for code that needs it
+        https://bugs.webkit.org/show_bug.cgi?id=21594
+
+        Convert as reference counted private members of WebKitWebView to
+        smart pointers as possible. This removes a lot of unecessary manual
+        memory management. Also convert some pointer members away from pointer
+        types, now that we are sure their destructors are called.
+
+        * WebCoreSupport/ContextMenuClientGtk.cpp:
+        (WebKit::inputMethodsMenuItem): Updated to reflect PlatformRefPtr changes.
+        * WebCoreSupport/DragClientGtk.cpp:
+        (WebKit::DragClient::startDrag): Ditto.
+        * WebCoreSupport/EditorClientGtk.cpp:
+        (WebKit::EditorClient::setInputMethodState): Ditto.
+        (WebKit::EditorClient::respondToChangedSelection): Ditto.
+        (WebKit::EditorClient::handleInputMethodKeydown): Ditto.
+        (WebKit::EditorClient::handleInputMethodMousePress): Ditto.
+        (WebKit::EditorClient::EditorClient): Ditto.
+        (WebKit::EditorClient::~EditorClient): Ditto.
+        * WebCoreSupport/FrameLoaderClientGtk.cpp:
+        (WebKit::postCommitFrameViewSetup): Ditto.
+        * webkit/webkitprivate.h: Ditto.
+        * webkit/webkitwebview.cpp: Ditto.
+        (destroy_menu_cb): Ditto.
+        (webkit_web_view_forward_context_menu_event): Ditto.
+        (webkit_web_view_key_release_event): Ditto.
+        (webkit_web_view_button_press_event): Ditto.
+        (webkit_web_view_button_release_event): Ditto.
+        (webkit_web_view_focus_in_event): Ditto.
+        (webkit_web_view_focus_out_event): Ditto.
+        (webkit_web_view_realize): Ditto.
+        (webkit_web_view_set_scroll_adjustments): Ditto.
+        (webkit_web_view_dispose): Changed all g_object_unref calls to
+        PlatformRefPtr.clear(). Although this will also be done by the manual
+        call to the WebKitWebViewPrivate destructor, the order that these
+        fields are zero'd in is still very sensitive.
+        (webkit_web_view_finalize): Updated to reflect PlatformRefPtr changes.
+        (webViewGetDPI): Ditto.
+        (webkit_web_view_screen_changed): Ditto.
+        (webkit_web_view_drag_end): Ditto.
+        (webkit_web_view_drag_data_get): Ditto.
+        (doDragLeaveLater): Ditto.
+        (webkit_web_view_drag_leave): Ditto.
+        (webkit_web_view_drag_motion): Ditto.
+        (webkit_web_view_drag_data_received): Ditto.
+        (webkit_web_view_drag_drop): Ditto.
+        (webkit_web_view_get_im_context): Ditto.
+        (webkit_web_view_update_settings): Ditto.
+        (webkit_web_view_init): Ditto.
+        (webkit_web_view_set_settings): Ditto.
+        (webkit_web_view_get_settings): Ditto.
+        (webkit_web_view_get_inspector): Ditto.
+        (webkit_web_view_set_window_features): Ditto.
+        (webkit_web_view_get_window_features): Ditto.
+        (webkit_web_view_get_back_forward_list): Ditto.
+        (webkit_web_view_zoom_in): Ditto.
+        (webkit_web_view_zoom_out): Ditto.
+        (webkit_web_view_add_resource): Ditto.
+        (webkit_web_view_get_resource): Ditto.
+        (webkit_web_view_get_main_resource): Ditto.
+        (webkit_web_view_clear_resources): Ditto.
+        (webkit_web_view_get_subresources): Ditto.
+
 2010-09-14  Martin Robinson  <mrobinson@igalia.com>
 
         Reviewed by Xan Lopez.
index 5c1bc0b..069fb19 100644 (file)
@@ -62,7 +62,7 @@ static GtkWidget* inputMethodsMenuItem (WebKitWebView* webView)
 
     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
     GtkWidget* imContextMenu = gtk_menu_new();
-    gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(priv->imContext), GTK_MENU_SHELL(imContextMenu));
+    gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(priv->imContext.get()), GTK_MENU_SHELL(imContextMenu));
 
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), imContextMenu);
 
index b6075b6..5720099 100644 (file)
@@ -77,7 +77,7 @@ void DragClient::startDrag(DragImageRef image, const IntPoint& dragImageOrigin,
     GOwnPtr<GdkEvent> currentEvent(gtk_get_current_event());
 
     GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView), targetList.get(), dragOperationToGdkDragActions(clipboard->sourceOperation()), 1, currentEvent.get());
-    webView->priv->draggingDataObjects->set(context, dataObject);
+    webView->priv->draggingDataObjects.set(context, dataObject);
 
     // A drag starting should prevent a double-click from happening. This might
     // happen if a drag is followed very quickly by another click (like in the DRT).
index a9c9b00..d4e70b6 100644 (file)
@@ -236,15 +236,15 @@ void EditorClient::setInputMethodState(bool active)
     WebKitWebViewPrivate* priv = m_webView->priv;
 
     if (active)
-        gtk_im_context_focus_in(priv->imContext);
+        gtk_im_context_focus_in(priv->imContext.get());
     else
-        gtk_im_context_focus_out(priv->imContext);
+        gtk_im_context_focus_out(priv->imContext.get());
 
 #ifdef MAEMO_CHANGES
     if (active)
-        hildon_gtk_im_context_show(priv->imContext);
+        hildon_gtk_im_context_show(priv->imContext.get());
     else
-        hildon_gtk_im_context_hide(priv->imContext);
+        hildon_gtk_im_context_hide(priv->imContext.get());
 #endif
 }
 
@@ -396,7 +396,7 @@ void EditorClient::respondToChangedSelection()
     unsigned end;
     if (!targetFrame->editor()->getCompositionSelection(start, end)) {
         // gtk_im_context_reset() clears the composition for us.
-        gtk_im_context_reset(priv->imContext);
+        gtk_im_context_reset(priv->imContext.get());
         targetFrame->editor()->confirmCompositionWithoutDisturbingSelection();
     }
 }
@@ -730,7 +730,7 @@ void EditorClient::handleInputMethodKeydown(KeyboardEvent* event)
     m_treatContextCommitAsKeyEvent = (!targetFrame->editor()->hasComposition())
          && event->keyEvent()->gdkEventKey()->keyval;
     clearPendingComposition();
-    if ((gtk_im_context_filter_keypress(priv->imContext, event->keyEvent()->gdkEventKey()) && !m_pendingComposition)
+    if ((gtk_im_context_filter_keypress(priv->imContext.get(), event->keyEvent()->gdkEventKey()) && !m_pendingComposition)
         || (!m_treatContextCommitAsKeyEvent && !targetFrame->editor()->hasComposition()))
         event->preventDefault();
 
@@ -750,12 +750,12 @@ void EditorClient::handleInputMethodMousePress()
     // In this case, if the focused node is changed, the commit signal happens in a diffrent node.
     // Therefore, we need to confirm the current compositon and ignore the next commit signal. 
     GOwnPtr<gchar> newPreedit(0);
-    gtk_im_context_get_preedit_string(priv->imContext, &newPreedit.outPtr(), 0, 0);
+    gtk_im_context_get_preedit_string(priv->imContext.get(), &newPreedit.outPtr(), 0, 0);
     
     if (g_utf8_strlen(newPreedit.get(), -1)) {
         targetFrame->editor()->confirmComposition();
         m_preventNextCompositionCommit = true;
-        gtk_im_context_reset(priv->imContext);
+        gtk_im_context_reset(priv->imContext.get());
     } 
 }
 
@@ -767,8 +767,8 @@ EditorClient::EditorClient(WebKitWebView* webView)
     , m_nativeWidget(gtk_text_view_new())
 {
     WebKitWebViewPrivate* priv = m_webView->priv;
-    g_signal_connect(priv->imContext, "commit", G_CALLBACK(imContextCommitted), this);
-    g_signal_connect(priv->imContext, "preedit-changed", G_CALLBACK(imContextPreeditChanged), this);
+    g_signal_connect(priv->imContext.get(), "commit", G_CALLBACK(imContextCommitted), this);
+    g_signal_connect(priv->imContext.get(), "preedit-changed", G_CALLBACK(imContextPreeditChanged), this);
 
     g_signal_connect(m_nativeWidget.get(), "backspace", G_CALLBACK(backspaceCallback), this);
     g_signal_connect(m_nativeWidget.get(), "cut-clipboard", G_CALLBACK(cutClipboardCallback), this);
@@ -783,8 +783,8 @@ EditorClient::EditorClient(WebKitWebView* webView)
 EditorClient::~EditorClient()
 {
     WebKitWebViewPrivate* priv = m_webView->priv;
-    g_signal_handlers_disconnect_by_func(priv->imContext, (gpointer)imContextCommitted, this);
-    g_signal_handlers_disconnect_by_func(priv->imContext, (gpointer)imContextPreeditChanged, this);
+    g_signal_handlers_disconnect_by_func(priv->imContext.get(), (gpointer)imContextCommitted, this);
+    g_signal_handlers_disconnect_by_func(priv->imContext.get(), (gpointer)imContextPreeditChanged, this);
 }
 
 void EditorClient::textFieldDidBeginEditing(Element*)
index 54762ca..93b4cc2 100644 (file)
@@ -1247,14 +1247,12 @@ static void postCommitFrameViewSetup(WebKitWebFrame *frame, FrameView *view, boo
 {
     WebKitWebView* containingWindow = getViewFromFrame(frame);
     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(containingWindow);
-    view->setGtkAdjustments(priv->horizontalAdjustment, priv->verticalAdjustment, resetValues);
+    view->setGtkAdjustments(priv->horizontalAdjustment.get(), priv->verticalAdjustment.get(), resetValues);
 
     if (priv->currentMenu) {
-        GtkMenu* menu = priv->currentMenu;
-        priv->currentMenu = 0;
-
-        gtk_menu_popdown(menu);
-        g_object_unref(menu);
+        PlatformRefPtr<GtkMenu> menu(priv->currentMenu);
+        priv->currentMenu.clear();
+        gtk_menu_popdown(menu.get());
     }
 
     // Do not allow click counting between main frame loads.
index aba3eba..5c6d151 100644 (file)
@@ -134,25 +134,25 @@ extern "C" {
     typedef struct _WebKitWebViewPrivate WebKitWebViewPrivate;
     struct _WebKitWebViewPrivate {
         WebCore::Page* corePage;
-        WebKitWebSettings* webSettings;
-        WebKitWebInspector* webInspector;
-        WebKitWebWindowFeatures* webWindowFeatures;
+        PlatformRefPtr<WebKitWebSettings> webSettings;
+        PlatformRefPtr<WebKitWebInspector> webInspector;
+        PlatformRefPtr<WebKitWebWindowFeatures> webWindowFeatures;
 
         WebKitWebFrame* mainFrame;
-        WebKitWebBackForwardList* backForwardList;
+        PlatformRefPtr<WebKitWebBackForwardList> backForwardList;
 
-        GtkMenu* currentMenu;
+        PlatformRefPtr<GtkMenu> currentMenu;
         gint lastPopupXPosition;
         gint lastPopupYPosition;
 
         HashSet<GtkWidget*> children;
         bool editable;
-        GtkIMContext* imContext;
+        PlatformRefPtr<GtkIMContext> imContext;
 
         gboolean transparent;
 
-        GtkAdjustment* horizontalAdjustment;
-        GtkAdjustment* verticalAdjustment;
+        PlatformRefPtr<GtkAdjustment> horizontalAdjustment;
+        PlatformRefPtr<GtkAdjustment> verticalAdjustment;
 
         gboolean zoomFullContent;
         WebKitLoadStatus loadStatus;
@@ -170,18 +170,17 @@ extern "C" {
 
         // These are hosted here because the DataSource object is
         // created too late in the frame loading process.
-        WebKitWebResource* mainResource;
+        PlatformRefPtr<WebKitWebResource> mainResource;
         CString mainResourceIdentifier;
-        GHashTable* subResources;
+        PlatformRefPtr<GHashTable> subResources;
         CString tooltipText;
 
         int currentClickCount;
-        WebCore::IntPoint* previousClickPoint;
+        WebCore::IntPoint previousClickPoint;
         guint previousClickButton;
         guint32 previousClickTime;
-
-        HashMap<GdkDragContext*, RefPtr<WebCore::DataObjectGtk> >* draggingDataObjects;
-        HashMap<GdkDragContext*, WebKit::DroppingContext*>* droppingContexts;
+        HashMap<GdkDragContext*, RefPtr<WebCore::DataObjectGtk> > draggingDataObjects;
+        HashMap<GdkDragContext*, WebKit::DroppingContext*> droppingContexts;
     };
 
     #define WEBKIT_WEB_FRAME_GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_FRAME, WebKitWebFramePrivate))
index 9020064..1446675 100644 (file)
@@ -210,11 +210,7 @@ static GtkIMContext* webkit_web_view_get_im_context(WebKitWebView*);
 
 static void destroy_menu_cb(GtkObject* object, gpointer data)
 {
-    WebKitWebView* webView = WEBKIT_WEB_VIEW(data);
-    WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
-
-    g_object_unref(priv->currentMenu);
-    priv->currentMenu = NULL;
+    WEBKIT_WEB_VIEW(data)->priv->currentMenu = 0;
 }
 
 static void PopupMenuPositionFunc(GtkMenu* menu, gint *x, gint *y, gboolean *pushIn, gpointer userData)
@@ -304,7 +300,7 @@ static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webVie
         return FALSE;
 
     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
-    priv->currentMenu = GTK_MENU(g_object_ref(menu));
+    priv->currentMenu = menu;
     priv->lastPopupXPosition = event.globalX();
     priv->lastPopupYPosition = event.globalY();
 
@@ -592,7 +588,7 @@ static gboolean webkit_web_view_key_release_event(GtkWidget* widget, GdkEventKey
     // the event if we don't have a pending composition, because that means we
     // are using a context like 'simple' which marks every keystroke as filtered.
     WebKit::EditorClient* client = static_cast<WebKit::EditorClient*>(core(webView)->editorClient());
-    if (gtk_im_context_filter_keypress(webView->priv->imContext, event) && !client->hasPendingComposition())
+    if (gtk_im_context_filter_keypress(webView->priv->imContext.get(), event) && !client->hasPendingComposition())
         return TRUE;
 
     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
@@ -651,8 +647,8 @@ static gboolean webkit_web_view_button_press_event(GtkWidget* widget, GdkEventBu
     // GDK logic for counting clicks.
     guint32 eventTime = getEventTime(reinterpret_cast<GdkEvent*>(event));
     if ((event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
-        || ((abs(event->x - priv->previousClickPoint->x()) < doubleClickDistance)
-            && (abs(event->y - priv->previousClickPoint->y()) < doubleClickDistance)
+        || ((abs(event->x - priv->previousClickPoint.x()) < doubleClickDistance)
+            && (abs(event->y - priv->previousClickPoint.y()) < doubleClickDistance)
             && (eventTime - priv->previousClickTime < static_cast<guint>(doubleClickTime))
             && (event->button == priv->previousClickButton)))
         priv->currentClickCount++;
@@ -661,7 +657,7 @@ static gboolean webkit_web_view_button_press_event(GtkWidget* widget, GdkEventBu
 
     PlatformMouseEvent platformEvent(event);
     platformEvent.setClickCount(priv->currentClickCount);
-    *priv->previousClickPoint = platformEvent.pos();
+    priv->previousClickPoint = platformEvent.pos();
     priv->previousClickButton = event->button;
     priv->previousClickTime = eventTime;
 
@@ -702,7 +698,7 @@ static gboolean webkit_web_view_button_release_event(GtkWidget* widget, GdkEvent
     if (focusedFrame && focusedFrame->editor()->canEdit()) {
 #ifdef MAEMO_CHANGES
         WebKitWebViewPrivate* priv = webView->priv;
-        hildon_gtk_im_context_filter_event(priv->imContext, (GdkEvent*)event);
+        hildon_gtk_im_context_filter_event(priv->imContext.get(), (GdkEvent*)event);
 #endif
     }
 
@@ -806,7 +802,7 @@ static gboolean webkit_web_view_focus_in_event(GtkWidget* widget, GdkEventFocus*
             focusController->setFocusedFrame(core(webView)->mainFrame());
 
         if (focusController->focusedFrame()->editor()->canEdit())
-            gtk_im_context_focus_in(webView->priv->imContext);
+            gtk_im_context_focus_in(webView->priv->imContext.get());
     }
     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_in_event(widget, event);
 }
@@ -824,7 +820,7 @@ static gboolean webkit_web_view_focus_out_event(GtkWidget* widget, GdkEventFocus
     }
 
     if (webView->priv->imContext)
-        gtk_im_context_focus_out(webView->priv->imContext);
+        gtk_im_context_focus_out(webView->priv->imContext.get());
 
     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_out_event(widget, event);
 }
@@ -875,7 +871,7 @@ static void webkit_web_view_realize(GtkWidget* widget)
 
     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
     WebKitWebViewPrivate* priv = webView->priv;
-    gtk_im_context_set_client_window(priv->imContext, window);
+    gtk_im_context_set_client_window(priv->imContext.get(), window);
 }
 
 static void webkit_web_view_set_scroll_adjustments(WebKitWebView* webView, GtkAdjustment* hadj, GtkAdjustment* vadj)
@@ -883,26 +879,12 @@ static void webkit_web_view_set_scroll_adjustments(WebKitWebView* webView, GtkAd
     if (!core(webView))
         return;
 
-    FrameView* view = core(webkit_web_view_get_main_frame(webView))->view();
-
-    if (hadj)
-        g_object_ref(hadj);
-    if (vadj)
-        g_object_ref(vadj);
-
-    WebKitWebViewPrivate* priv = webView->priv;
-
-    if (priv->horizontalAdjustment)
-        g_object_unref(priv->horizontalAdjustment);
-    if (priv->verticalAdjustment)
-        g_object_unref(priv->verticalAdjustment);
-
-    priv->horizontalAdjustment = hadj;
-    priv->verticalAdjustment = vadj;
+    webView->priv->horizontalAdjustment = hadj;
+    webView->priv->verticalAdjustment = vadj;
 
+    FrameView* view = core(webkit_web_view_get_main_frame(webView))->view();
     if (!view)
         return;
-
     view->setGtkAdjustments(hadj, vadj);
 }
 
@@ -1158,75 +1140,42 @@ static void webkit_web_view_dispose(GObject* object)
 
     priv->disposing = TRUE;
 
-    if (priv->horizontalAdjustment) {
-        g_object_unref(priv->horizontalAdjustment);
-        priv->horizontalAdjustment = NULL;
-    }
-
-    if (priv->verticalAdjustment) {
-        g_object_unref(priv->verticalAdjustment);
-        priv->verticalAdjustment = NULL;
-    }
-
-    if (priv->backForwardList) {
-        g_object_unref(priv->backForwardList);
-        priv->backForwardList = NULL;
-    }
+    // These smart pointers are cleared manually, because some cleanup operations are
+    // very sensitive to their value. We may crash if these are done in the wrong order.
+    priv->horizontalAdjustment.clear();
+    priv->verticalAdjustment.clear();
+    priv->backForwardList.clear();
 
     if (priv->corePage) {
         webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(object));
-
         core(priv->mainFrame)->loader()->detachFromParent();
         delete priv->corePage;
-        priv->corePage = NULL;
+        priv->corePage = 0;
     }
 
     if (priv->webSettings) {
-        g_signal_handlers_disconnect_by_func(priv->webSettings, (gpointer)webkit_web_view_settings_notify, webView);
-        g_object_unref(priv->webSettings);
-        priv->webSettings = NULL;
-
-        g_object_unref(priv->webInspector);
-        priv->webInspector = NULL;
-
-        g_object_unref(priv->webWindowFeatures);
-        priv->webWindowFeatures = NULL;
-
-        g_object_unref(priv->imContext);
-        priv->imContext = NULL;
-    }
-
-    if (priv->mainResource) {
-        g_object_unref(priv->mainResource);
-        priv->mainResource = NULL;
+        g_signal_handlers_disconnect_by_func(priv->webSettings.get(), (gpointer)webkit_web_view_settings_notify, webView);
+        priv->webSettings.clear();
     }
 
-    if (priv->subResources) {
-        g_hash_table_unref(priv->subResources);
-        priv->subResources = NULL;
-    }
+    priv->webInspector.clear();
+    priv->webWindowFeatures.clear();
+    priv->mainResource.clear();
+    priv->subResources.clear();
 
-    priv->draggingDataObjects->clear();
-    HashMap<GdkDragContext*, DroppingContext*>::iterator endDroppingContexts = priv->droppingContexts->end();
-    for (HashMap<GdkDragContext*, DroppingContext*>::iterator iter = priv->droppingContexts->begin(); iter != endDroppingContexts; ++iter)
+    HashMap<GdkDragContext*, DroppingContext*>::iterator endDroppingContexts = priv->droppingContexts.end();
+    for (HashMap<GdkDragContext*, DroppingContext*>::iterator iter = priv->droppingContexts.begin(); iter != endDroppingContexts; ++iter)
         delete (iter->second);
-    priv->droppingContexts->clear();
+    priv->droppingContexts.clear();
 
     G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object);
 }
 
 static void webkit_web_view_finalize(GObject* object)
 {
-    WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
-    WebKitWebViewPrivate* priv = webView->priv;
-
-    delete priv->previousClickPoint;
-    delete priv->draggingDataObjects;
-    delete priv->droppingContexts;
-
     // We need to manually call the destructor here, since this object's memory is managed
     // by GLib. This calls all C++ members' destructors and prevents memory leaks.
-    priv->~WebKitWebViewPrivate();
+    WEBKIT_WEB_VIEW(object)->priv->~WebKitWebViewPrivate();
     G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
 }
 
@@ -1276,7 +1225,7 @@ static AtkObject* webkit_web_view_get_accessible(GtkWidget* widget)
 static gdouble webViewGetDPI(WebKitWebView* webView)
 {
     WebKitWebViewPrivate* priv = webView->priv;
-    WebKitWebSettings* webSettings = priv->webSettings;
+    WebKitWebSettings* webSettings = priv->webSettings.get();
     gboolean enforce96DPI;
     g_object_get(webSettings, "enforce-96-dpi", &enforce96DPI, NULL);
     if (enforce96DPI)
@@ -1302,7 +1251,7 @@ static void webkit_web_view_screen_changed(GtkWidget* widget, GdkScreen* previou
     if (priv->disposing)
         return;
 
-    WebKitWebSettings* webSettings = priv->webSettings;
+    WebKitWebSettings* webSettings = priv->webSettings.get();
     Settings* settings = core(webView)->settings();
     gdouble DPI = webViewGetDPI(webView);
 
@@ -1336,10 +1285,10 @@ static void webkit_web_view_drag_end(GtkWidget* widget, GdkDragContext* context)
 
     // This might happen if a drag is still in progress after a WebKitWebView
     // is disposed and before it is finalized.
-    if (!priv->draggingDataObjects->contains(context))
+    if (!priv->draggingDataObjects.contains(context))
         return;
 
-    priv->draggingDataObjects->remove(context);
+    priv->draggingDataObjects.remove(context);
 
     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
     if (!frame)
@@ -1374,10 +1323,10 @@ static void webkit_web_view_drag_data_get(GtkWidget* widget, GdkDragContext* con
 
     // This might happen if a drag is still in progress after a WebKitWebView
     // is diposed and before it is finalized.
-    if (!priv->draggingDataObjects->contains(context))
+    if (!priv->draggingDataObjects.contains(context))
         return;
 
-    pasteboardHelperInstance()->fillSelectionData(selectionData, info, priv->draggingDataObjects->get(context).get());
+    pasteboardHelperInstance()->fillSelectionData(selectionData, info, priv->draggingDataObjects.get(context).get());
 }
 
 static gboolean doDragLeaveLater(DroppingContext* context)
@@ -1385,7 +1334,7 @@ static gboolean doDragLeaveLater(DroppingContext* context)
     WebKitWebView* webView = context->webView;
     WebKitWebViewPrivate* priv = webView->priv;
 
-    if (!priv->droppingContexts->contains(context->gdkContext))
+    if (!priv->droppingContexts.contains(context->gdkContext))
         return FALSE;
 
     // If the view doesn't know about the drag yet (there are still pending data)
@@ -1402,7 +1351,7 @@ static gboolean doDragLeaveLater(DroppingContext* context)
     }
 
     core(webView)->dragController()->dragEnded();
-    priv->droppingContexts->remove(context->gdkContext);
+    priv->droppingContexts.remove(context->gdkContext);
     delete context;
     return FALSE;
 }
@@ -1412,13 +1361,13 @@ static void webkit_web_view_drag_leave(GtkWidget* widget, GdkDragContext* contex
     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
     WebKitWebViewPrivate* priv = webView->priv;
 
-    if (!priv->droppingContexts->contains(context))
+    if (!priv->droppingContexts.contains(context))
         return;
 
     // During a drop GTK+ will fire a drag-leave signal right before firing
     // the drag-drop signal. We want the actions for drag-leave to happen after
     // those for drag-drop, so schedule them to happen asynchronously here.
-    g_timeout_add(0, reinterpret_cast<GSourceFunc>(doDragLeaveLater), priv->droppingContexts->get(context));
+    g_timeout_add(0, reinterpret_cast<GSourceFunc>(doDragLeaveLater), priv->droppingContexts.get(context));
 }
 
 static gboolean webkit_web_view_drag_motion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
@@ -1428,21 +1377,21 @@ static gboolean webkit_web_view_drag_motion(GtkWidget* widget, GdkDragContext* c
 
     DroppingContext* droppingContext = 0;
     IntPoint position = IntPoint(x, y);
-    if (!priv->droppingContexts->contains(context)) {
+    if (!priv->droppingContexts.contains(context)) {
         droppingContext = new DroppingContext;
         droppingContext->webView = webView;
         droppingContext->gdkContext = context;
         droppingContext->dataObject = WebCore::DataObjectGtk::create();
         droppingContext->dropHappened = false;
         droppingContext->lastMotionPosition = position;
-        priv->droppingContexts->set(context, droppingContext);
+        priv->droppingContexts.set(context, droppingContext);
 
         Vector<GdkAtom> acceptableTargets(pasteboardHelperInstance()->dropAtomsForContext(widget, context));
         droppingContext->pendingDataRequests = acceptableTargets.size();
         for (size_t i = 0; i < acceptableTargets.size(); i++)
             gtk_drag_get_data(widget, context, acceptableTargets.at(i), time);
     } else {
-        droppingContext = priv->droppingContexts->get(context);
+        droppingContext = priv->droppingContexts.get(context);
         droppingContext->lastMotionPosition = position;
     }
 
@@ -1465,10 +1414,10 @@ static void webkit_web_view_drag_data_received(GtkWidget* widget, GdkDragContext
     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
     WebKitWebViewPrivate* priv = webView->priv;
 
-    if (!priv->droppingContexts->contains(context))
+    if (!priv->droppingContexts.contains(context))
         return;
 
-    DroppingContext* droppingContext = priv->droppingContexts->get(context);
+    DroppingContext* droppingContext = priv->droppingContexts.get(context);
     droppingContext->pendingDataRequests--;
     pasteboardHelperInstance()->fillDataObjectFromDropData(selectionData, info, droppingContext->dataObject.get());
 
@@ -1490,10 +1439,10 @@ static gboolean webkit_web_view_drag_drop(GtkWidget* widget, GdkDragContext* con
     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
     WebKitWebViewPrivate* priv = webView->priv;
 
-    if (!priv->droppingContexts->contains(context))
+    if (!priv->droppingContexts.contains(context))
         return FALSE;
 
-    DroppingContext* droppingContext = priv->droppingContexts->get(context);
+    DroppingContext* droppingContext = priv->droppingContexts.get(context);
     droppingContext->dropHappened = true;
 
     IntPoint position(x, y);
@@ -1521,7 +1470,7 @@ static gboolean webkit_web_view_query_tooltip(GtkWidget *widget, gint x, gint y,
 static GtkIMContext* webkit_web_view_get_im_context(WebKitWebView* webView)
 {
     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
-    return GTK_IM_CONTEXT(webView->priv->imContext);
+    return GTK_IM_CONTEXT(webView->priv->imContext.get());
 }
 
 static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
@@ -2889,7 +2838,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
 static void webkit_web_view_update_settings(WebKitWebView* webView)
 {
     WebKitWebViewPrivate* priv = webView->priv;
-    WebKitWebSettings* webSettings = priv->webSettings;
+    WebKitWebSettings* webSettings = priv->webSettings.get();
     Settings* settings = core(webView)->settings();
 
     gchar* defaultEncoding, *cursiveFontFamily, *defaultFontFamily, *fantasyFontFamily, *monospaceFontFamily, *sansSerifFontFamily, *serifFontFamily, *userStylesheetUri;
@@ -3099,7 +3048,7 @@ static void webkit_web_view_init(WebKitWebView* webView)
     // members, which ensures they are initialized properly.
     new (priv) WebKitWebViewPrivate();
 
-    priv->imContext = gtk_im_multicontext_new();
+    priv->imContext = adoptPlatformRef(gtk_im_multicontext_new());
 
     Page::PageClients pageClients;
     pageClients.chromeClient = new WebKit::ChromeClient(webView);
@@ -3111,15 +3060,13 @@ static void webkit_web_view_init(WebKitWebView* webView)
 
     // We also add a simple wrapper class to provide the public
     // interface for the Web Inspector.
-    priv->webInspector = WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL));
-    webkit_web_inspector_set_inspector_client(priv->webInspector, priv->corePage);
+    priv->webInspector = adoptPlatformRef(WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL)));
+    webkit_web_inspector_set_inspector_client(priv->webInspector.get(), priv->corePage);
 
+    // The smart pointer will call g_object_ref_sink on these adjustments.
     priv->horizontalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
     priv->verticalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
 
-    g_object_ref_sink(priv->horizontalAdjustment);
-    g_object_ref_sink(priv->verticalAdjustment);
-
     gtk_widget_set_can_focus(GTK_WIDGET(webView), TRUE);
     priv->mainFrame = WEBKIT_WEB_FRAME(webkit_web_frame_new(webView));
     priv->lastPopupXPosition = priv->lastPopupYPosition = -1;
@@ -3129,21 +3076,17 @@ static void webkit_web_view_init(WebKitWebView* webView)
 
     priv->zoomFullContent = FALSE;
 
-    priv->webSettings = webkit_web_settings_new();
+    priv->webSettings = adoptPlatformRef(webkit_web_settings_new());
     webkit_web_view_update_settings(webView);
-    g_signal_connect(priv->webSettings, "notify", G_CALLBACK(webkit_web_view_settings_notify), webView);
+    g_signal_connect(priv->webSettings.get(), "notify", G_CALLBACK(webkit_web_view_settings_notify), webView);
 
-    priv->webWindowFeatures = webkit_web_window_features_new();
+    priv->webWindowFeatures = adoptPlatformRef(webkit_web_window_features_new());
 
-    priv->subResources = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
+    priv->subResources = adoptPlatformRef(g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref));
 
     priv->currentClickCount = 0;
-    priv->previousClickPoint = new IntPoint(0, 0);
     priv->previousClickButton = 0;
     priv->previousClickTime = 0;
-
-    priv->draggingDataObjects = new HashMap<GdkDragContext*, RefPtr<WebCore::DataObjectGtk> >();
-    priv->droppingContexts = new HashMap<GdkDragContext*, DroppingContext*>();
     gtk_drag_dest_set(GTK_WIDGET(webView), static_cast<GtkDestDefaults>(0), 0, 0, static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE));
     gtk_drag_dest_set_target_list(GTK_WIDGET(webView), pasteboardHelperInstance()->targetList());
 }
@@ -3213,9 +3156,7 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitWebSettings* web
     g_return_if_fail(WEBKIT_IS_WEB_SETTINGS(webSettings));
 
     WebKitWebViewPrivate* priv = webView->priv;
-    g_signal_handlers_disconnect_by_func(priv->webSettings, (gpointer)webkit_web_view_settings_notify, webView);
-    g_object_unref(priv->webSettings);
-    g_object_ref(webSettings);
+    g_signal_handlers_disconnect_by_func(priv->webSettings.get(), (gpointer)webkit_web_view_settings_notify, webView);
     priv->webSettings = webSettings;
     webkit_web_view_update_settings(webView);
     g_signal_connect(webSettings, "notify", G_CALLBACK(webkit_web_view_settings_notify), webView);
@@ -3237,10 +3178,8 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitWebSettings* web
  */
 WebKitWebSettings* webkit_web_view_get_settings(WebKitWebView* webView)
 {
-    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
-
-    WebKitWebViewPrivate* priv = webView->priv;
-    return priv->webSettings;
+    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+    return webView->priv->webSettings.get();
 }
 
 /**
@@ -3259,26 +3198,18 @@ WebKitWebSettings* webkit_web_view_get_settings(WebKitWebView* webView)
  */
 WebKitWebInspector* webkit_web_view_get_inspector(WebKitWebView* webView)
 {
-    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
-
-    WebKitWebViewPrivate* priv = webView->priv;
-    return priv->webInspector;
+    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+    return webView->priv->webInspector.get();
 }
 
 // internal
 static void webkit_web_view_set_window_features(WebKitWebView* webView, WebKitWebWindowFeatures* webWindowFeatures)
 {
-    WebKitWebViewPrivate* priv = webView->priv;
-    
     if (!webWindowFeatures)
       return;
-
-    if (webkit_web_window_features_equal(priv->webWindowFeatures, webWindowFeatures))
+    if (webkit_web_window_features_equal(webView->priv->webWindowFeatures.get(), webWindowFeatures))
       return;
-
-    g_object_unref(priv->webWindowFeatures);
-    g_object_ref(webWindowFeatures);
-    priv->webWindowFeatures = webWindowFeatures;
+    webView->priv->webWindowFeatures = webWindowFeatures;
 }
 
 /**
@@ -3294,10 +3225,8 @@ static void webkit_web_view_set_window_features(WebKitWebView* webView, WebKitWe
  */
 WebKitWebWindowFeatures* webkit_web_view_get_window_features(WebKitWebView* webView)
 {
-    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
-
-    WebKitWebViewPrivate* priv = webView->priv;
-    return priv->webWindowFeatures;
+    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+    return webView->priv->webWindowFeatures.get();
 }
 
 /**
@@ -3361,14 +3290,10 @@ void webkit_web_view_set_maintains_back_forward_list(WebKitWebView* webView, gbo
  */
 WebKitWebBackForwardList* webkit_web_view_get_back_forward_list(WebKitWebView* webView)
 {
-    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
-
-    WebKitWebViewPrivate* priv = webView->priv;
-
+    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
     if (!core(webView) || !core(webView)->backForwardList()->enabled())
-        return NULL;
-
-    return priv->backForwardList;
+        return 0;
+    return webView->priv->backForwardList.get();
 }
 
 /**
@@ -4139,7 +4064,7 @@ void webkit_web_view_zoom_in(WebKitWebView* webView)
 
     WebKitWebViewPrivate* priv = webView->priv;
     gfloat zoomMultiplierRatio;
-    g_object_get(priv->webSettings, "zoom-step", &zoomMultiplierRatio, NULL);
+    g_object_get(priv->webSettings.get(), "zoom-step", &zoomMultiplierRatio, NULL);
 
     webkit_web_view_set_zoom_level(webView, webkit_web_view_get_zoom_level(webView) + zoomMultiplierRatio);
 }
@@ -4160,7 +4085,7 @@ void webkit_web_view_zoom_out(WebKitWebView* webView)
 
     WebKitWebViewPrivate* priv = webView->priv;
     gfloat zoomMultiplierRatio;
-    g_object_get(priv->webSettings, "zoom-step", &zoomMultiplierRatio, NULL);
+    g_object_get(priv->webSettings.get(), "zoom-step", &zoomMultiplierRatio, NULL);
 
     webkit_web_view_set_zoom_level(webView, webkit_web_view_get_zoom_level(webView) - zoomMultiplierRatio);
 }
@@ -4529,19 +4454,19 @@ void webkit_web_view_add_resource(WebKitWebView* webView, const char* identifier
     WebKitWebViewPrivate* priv = webView->priv;
 
     if (!priv->mainResource) {
-        priv->mainResource = webResource;
+        priv->mainResource = adoptPlatformRef(webResource);
         priv->mainResourceIdentifier = identifier;
         return;
     }
 
-    g_hash_table_insert(priv->subResources, g_strdup(identifier), webResource);
+    g_hash_table_insert(priv->subResources.get(), g_strdup(identifier), webResource);
 }
 
 WebKitWebResource* webkit_web_view_get_resource(WebKitWebView* webView, char* identifier)
 {
     WebKitWebViewPrivate* priv = webView->priv;
     gpointer webResource = 0;
-    gboolean resourceFound = g_hash_table_lookup_extended(priv->subResources, identifier, NULL, &webResource);
+    gboolean resourceFound = g_hash_table_lookup_extended(priv->subResources.get(), identifier, NULL, &webResource);
 
     // The only resource we do not store in this hash table is the
     // main!  If we did not find a request, it probably means the load
@@ -4558,29 +4483,24 @@ WebKitWebResource* webkit_web_view_get_resource(WebKitWebView* webView, char* id
 
 WebKitWebResource* webkit_web_view_get_main_resource(WebKitWebView* webView)
 {
-    return webView->priv->mainResource;
+    return webView->priv->mainResource.get();
 }
 
 void webkit_web_view_clear_resources(WebKitWebView* webView)
 {
     WebKitWebViewPrivate* priv = webView->priv;
-
     priv->mainResourceIdentifier = "";
-
-    if (priv->mainResource) {
-        g_object_unref(priv->mainResource);
-        priv->mainResource = NULL;
-    }
+    priv->mainResource = 0;
 
     if (priv->subResources)
-        g_hash_table_remove_all(priv->subResources);
+        g_hash_table_remove_all(priv->subResources.get());
 }
 
 GList* webkit_web_view_get_subresources(WebKitWebView* webView)
 {
     WebKitWebViewPrivate* priv = webView->priv;
-    GList* subResources = g_hash_table_get_values(priv->subResources);
-    return g_list_remove(subResources, priv->mainResource);
+    GList* subResources = g_hash_table_get_values(priv->subResources.get());
+    return g_list_remove(subResources, priv->mainResource.get());
 }
 
 /* From EventHandler.cpp */