changeset 32665:a92f4cb593a4

propagate from branch 'im.pidgin.pidgin' (head c0e633bbd723352b9614b1bfcfab551e416a29dc) to branch 'im.pidgin.cpw.qulogic.gtk3' (head 1887cd5f7ea1e4bc0950747da36d56d618ecd105)
author Marcus Lundblad <ml@update.uu.se>
date Wed, 02 Feb 2011 23:26:42 +0000
parents a7397a3d67ef (diff) 6448e3f3ddd4 (current diff)
children 974722699032
files configure.ac pidgin/gtkutils.c pidgin/plugins/vvconfig.c
diffstat 53 files changed, 2015 insertions(+), 1364 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Wed Feb 02 06:26:19 2011 +0000
+++ b/configure.ac	Wed Feb 02 23:26:42 2011 +0000
@@ -416,11 +416,11 @@
 fi
 
 if test "x$enable_gtkui" = "xyes" ; then
-	PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.10.0], , [
+	PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 2.91.6], , [
 		AC_MSG_RESULT(no)
 		AC_MSG_ERROR([
 
-You must have GTK+ 2.10.0 or newer development headers installed to compile
+You must have GTK+ 2.91.5 or newer development headers installed to compile
 Pidgin.  If you want to build only Finch then specify --disable-gtkui when
 running configure.
 ])])
--- a/pidgin/gtkaccount.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkaccount.c	Wed Feb 02 23:26:42 2011 +0000
@@ -160,6 +160,42 @@
 static void add_protocol_options(AccountPrefsDialog *dialog);
 static void add_proxy_options(AccountPrefsDialog *dialog, GtkWidget *parent);
 
+static const char *
+xmpp_default_domain_hackery(GtkWidget *protocol_combo)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	const char *value = NULL;
+
+	model = gtk_combo_box_get_model(GTK_COMBO_BOX(protocol_combo));
+	if (model != NULL && gtk_combo_box_get_active_iter(GTK_COMBO_BOX(protocol_combo), &iter)) {
+		char *protocol = NULL;
+
+		/* protocol is not stored as G_TYPE_STRING in the model so no g_free necessary */
+		gtk_tree_model_get(model, &iter, 2, &protocol, -1);
+		if (protocol && !strcmp("prpl-jabber", protocol)) {
+			char *item_name = NULL;
+
+			gtk_tree_model_get(model, &iter, 1, &item_name, -1);
+			if (item_name) {
+				if (!strcmp(item_name, _("Google Talk")))
+					value = "gmail.com";
+				g_free(item_name);
+			}
+			if (item_name) {
+				if (!strcmp(item_name, _("Facebook")))
+					value = "chat.facebook.com";
+				g_free(item_name);
+			}
+			/* If it's not GTalk, but still Jabber then the value is not NULL, it's empty */
+			if (NULL == value)
+				value = "";
+		}
+	}
+
+	return value;
+}
+
 static GtkWidget *
 add_pref_box(AccountPrefsDialog *dialog, GtkWidget *parent,
 			 const char *text, GtkWidget *widget)
@@ -214,7 +250,7 @@
 }
 
 static void
-set_account_protocol_cb(GtkWidget *item, const char *id,
+set_account_protocol_cb(GtkWidget *widget, const char *id,
 						AccountPrefsDialog *dialog)
 {
 	PurplePlugin *new_plugin;
@@ -240,8 +276,7 @@
 
 	gtk_widget_grab_focus(dialog->protocol_menu);
 
-	if (!dialog->prpl_info || !dialog->prpl_info->register_user ||
-	    g_object_get_data(G_OBJECT(item), "fake")) {
+	if (!dialog->prpl_info || !dialog->prpl_info->register_user) {
 		gtk_widget_hide(dialog->register_button);
 	} else {
 		if (dialog->prpl_info != NULL &&
@@ -348,9 +383,11 @@
 account_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
 		 GtkSelectionData *sd, guint info, guint t, AccountPrefsDialog *dialog)
 {
-	gchar *name = (gchar *)sd->data;
-
-	if ((sd->length >= 0) && (sd->format == 8)) {
+	const gchar *name = (gchar *) gtk_selection_data_get_data(sd);
+	gint length = gtk_selection_data_get_length(sd);
+	gint format = gtk_selection_data_get_format(sd);
+
+	if (length >= 0 && format == 8) {
 		/* Well, it looks like the drag event was cool.
 		 * Let's do something with it */
 		if (!g_ascii_strncasecmp(name, "file://", 7)) {
@@ -417,8 +454,6 @@
 	GtkWidget *hbox;
 	GtkWidget *vbox;
 	GtkWidget *entry;
-	GtkWidget *menu;
-	GtkWidget *item;
 	GList *user_splits;
 	GList *l, *l2;
 	char *username = NULL;
@@ -557,15 +592,8 @@
 			value = purple_account_user_split_get_default_value(split);
 
 		/* Google Talk default domain hackery! */
-		menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->protocol_menu));
-		item = gtk_menu_get_active(GTK_MENU(menu));
-		if (value == NULL && g_object_get_data(G_OBJECT(item), "fakegoogle") &&
-			!strcmp(purple_account_user_split_get_text(split), _("Domain")))
-			value = "gmail.com";
-
-		if (value == NULL && g_object_get_data(G_OBJECT(item), "fakefacebook") &&
-			!strcmp(purple_account_user_split_get_text(split), _("Domain")))
-			value = "chat.facebook.com";
+		if (!strcmp(_("Domain"), purple_account_user_split_get_text(split)) && !value)
+			value = xmpp_default_domain_hackery(dialog->protocol_menu);
 
 		if (value != NULL)
 			gtk_entry_set_text(GTK_ENTRY(entry), value);
@@ -1036,7 +1064,7 @@
 		dialog->new_proxy_type == PURPLE_PROXY_NONE ||
 		dialog->new_proxy_type == PURPLE_PROXY_USE_ENVVAR) {
 
-		gtk_widget_hide_all(dialog->proxy_vbox);
+		gtk_widget_hide(dialog->proxy_vbox);
 	}
 	else
 		gtk_widget_show_all(dialog->proxy_vbox);
@@ -1131,7 +1159,7 @@
 
 		if (type == PURPLE_PROXY_USE_GLOBAL || type == PURPLE_PROXY_NONE ||
 				type == PURPLE_PROXY_USE_ENVVAR)
-			gtk_widget_hide_all(vbox2);
+			gtk_widget_hide(vbox2);
 
 
 		if ((value = purple_proxy_info_get_host(proxy_info)) != NULL)
@@ -1155,7 +1183,7 @@
 		dialog->new_proxy_type = PURPLE_PROXY_USE_GLOBAL;
 		gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->proxy_dropdown),
 				dialog->new_proxy_type + 1);
-		gtk_widget_hide_all(vbox2);
+		gtk_widget_hide(vbox2);
 	}
 
 	/* Connect signals. */
@@ -1695,7 +1723,9 @@
 				 GtkSelectionData *data, guint info, guint time,
 				 AccountsWindow *dialog)
 {
-	if (data->target == gdk_atom_intern("PURPLE_ACCOUNT", FALSE)) {
+	GdkAtom target = gtk_selection_data_get_target(data);
+
+	if (target == gdk_atom_intern("PURPLE_ACCOUNT", FALSE)) {
 		GtkTreeRowReference *ref;
 		GtkTreePath *source_row;
 		GtkTreeIter iter;
@@ -1766,13 +1796,16 @@
 					  guint x, guint y, GtkSelectionData *sd,
 					  guint info, guint t, AccountsWindow *dialog)
 {
-	if (sd->target == gdk_atom_intern("PURPLE_ACCOUNT", FALSE) && sd->data) {
+	GdkAtom target = gtk_selection_data_get_target(sd);
+	const guchar *data = gtk_selection_data_get_data(sd);
+
+	if (target == gdk_atom_intern("PURPLE_ACCOUNT", FALSE) && data) {
 		gint dest_index;
 		PurpleAccount *a = NULL;
 		GtkTreePath *path = NULL;
 		GtkTreeViewDropPosition position;
 
-		memcpy(&a, sd->data, sizeof(a));
+		memcpy(&a, data, sizeof(a));
 
 		if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y,
 											  &path, &position)) {
@@ -2621,5 +2654,3 @@
 	purple_signals_disconnect_by_handle(pidgin_account_get_handle());
 	purple_signals_unregister_by_instance(pidgin_account_get_handle());
 }
-
-
--- a/pidgin/gtkblist-theme-loader.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkblist-theme-loader.c	Wed Feb 02 23:26:42 2011 +0000
@@ -65,7 +65,8 @@
 	GdkColor color;
 
 	if (temp && gdk_color_parse(temp, &color)) {
-		gdk_colormap_alloc_color(gdk_colormap_get_system(), &color, FALSE, TRUE);
+    /* TODO: fix this for gtk+ 3.0 */
+		/*gdk_colormap_alloc_color(gdk_colormap_get_system(), &color, FALSE, TRUE);*/
 		return gdk_color_copy(&color);
 	} else {
 		return NULL;
--- a/pidgin/gtkblist.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkblist.c	Wed Feb 02 23:26:42 2011 +0000
@@ -123,7 +123,8 @@
 #define PIDGIN_BUDDY_LIST_GET_PRIVATE(list) \
 	((PidginBuddyListPrivate *)((list)->priv))
 
-static GtkWidget *accountmenu = NULL;
+static guint accounts_merge_id;
+static GtkActionGroup *accounts_action_group = NULL;
 
 static guint visibility_manager_count = 0;
 static GdkVisibilityState gtk_blist_visibility = GDK_VISIBILITY_UNOBSCURED;
@@ -137,6 +138,9 @@
 static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
 static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
 static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
+static guint sort_merge_id;
+static GtkActionGroup *sort_action_group = NULL;
+
 static PidginBuddyList *gtkblist = NULL;
 
 static GList *groups_tree(void);
@@ -147,7 +151,6 @@
 static void pidgin_blist_update_group(PurpleBuddyList *list, PurpleBlistNode *node);
 static void pidgin_blist_update_contact(PurpleBuddyList *list, PurpleBlistNode *node);
 static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full);
-static const char *item_factory_translate_func (const char *path, gpointer func_data);
 static gboolean get_iter_from_node(PurpleBlistNode *node, GtkTreeIter *iter);
 static gboolean buddy_is_displayable(PurpleBuddy *buddy);
 static void redo_buddy_list(PurpleBuddyList *list, gboolean remove, gboolean rerender);
@@ -241,7 +244,7 @@
 
 	/* check for visibility because when we aren't visible, this will   *
 	 * give us bogus (0,0) coordinates.                      - xOr      */
-	if (GTK_WIDGET_VISIBLE(w))
+	if (gtk_widget_get_visible(w))
 		gtk_window_get_position(GTK_WINDOW(w), &x, &y);
 	else
 		return FALSE; /* carry on normally */
@@ -981,20 +984,23 @@
 	gtkblist = PIDGIN_BLIST(purple_get_blist());
 	blist_window = gtkblist ? GTK_WINDOW(gtkblist->window) : NULL;
 
+  /* TODO: set no separator in gtk+ 3... */
 	data->window = gtk_dialog_new_with_buttons(title,
-		blist_window, GTK_DIALOG_NO_SEPARATOR,
-		NULL);
+		blist_window, 0, NULL);
 
 	gtk_window_set_transient_for(GTK_WINDOW(data->window), blist_window);
 	gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK);
 	gtk_container_set_border_width(GTK_CONTAINER(data->window), PIDGIN_HIG_BOX_SPACE);
 	gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE);
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BORDER);
-	gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), PIDGIN_HIG_BOX_SPACE);
+	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
+                      PIDGIN_HIG_BORDER);
+	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
+                                 PIDGIN_HIG_BOX_SPACE);
 	gtk_window_set_role(GTK_WINDOW(data->window), window_role);
 
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox);
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
+                    hbox);
 	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
 	gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
 
@@ -1057,7 +1063,7 @@
 
 		if (pce->is_int)
 		{
-			GtkObject *adjust;
+			GtkAdjustment *adjust;
 			adjust = gtk_adjustment_new(pce->min, pce->min, pce->max,
 										1, 10, 10);
 			input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
@@ -1602,11 +1608,11 @@
 			pidgin_retrieve_user_info(buddy->account->gc, buddy->name);
 	} else {
 		switch (event->keyval) {
-			case GDK_F2:
+			case GDK_KEY_F2:
 				gtk_blist_menu_alias_cb(tv, node);
 				break;
 
-			case GDK_Left:
+			case GDK_KEY_Left:
 				path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
 				if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path)) {
 					/* Collapse the Group */
@@ -1628,7 +1634,7 @@
 				gtk_tree_path_free(path);
 				break;
 
-			case GDK_Right:
+			case GDK_KEY_Right:
 				path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
 				if (!gtk_tree_view_row_expanded(GTK_TREE_VIEW(tv), path)) {
 					/* Expand the Group */
@@ -2012,64 +2018,70 @@
 	return handled;
 }
 
-static void pidgin_blist_buddy_details_cb(gpointer data, guint action, GtkWidget *item)
+static void gtk_blist_show_xfer_dialog_cb(GtkAction *item, gpointer data)
+{
+	pidgin_xfer_dialog_show(NULL);
+}
+
+static void pidgin_blist_buddy_details_cb(GtkToggleAction *item, gpointer data)
 {
 	pidgin_set_cursor(gtkblist->window, GDK_WATCH);
 
 	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons",
-			    gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
+			gtk_toggle_action_get_active(item));
 
 	pidgin_clear_cursor(gtkblist->window);
 }
 
-static void pidgin_blist_show_idle_time_cb(gpointer data, guint action, GtkWidget *item)
+static void pidgin_blist_show_idle_time_cb(GtkToggleAction *item, gpointer data)
 {
 	pidgin_set_cursor(gtkblist->window, GDK_WATCH);
 
 	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time",
-			    gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
+			gtk_toggle_action_get_active(item));
 
 	pidgin_clear_cursor(gtkblist->window);
 }
 
-static void pidgin_blist_show_protocol_icons_cb(gpointer data, guint action, GtkWidget *item)
+static void pidgin_blist_show_protocol_icons_cb(GtkToggleAction *item, gpointer data)
 {
 	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
-			      gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
-}
-
-static void pidgin_blist_show_empty_groups_cb(gpointer data, guint action, GtkWidget *item)
+			gtk_toggle_action_get_active(item));
+}
+
+static void pidgin_blist_show_empty_groups_cb(GtkToggleAction *item, gpointer data)
 {
 	pidgin_set_cursor(gtkblist->window, GDK_WATCH);
 
 	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups",
-			gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
+			gtk_toggle_action_get_active(item));
 
 	pidgin_clear_cursor(gtkblist->window);
 }
 
-static void pidgin_blist_edit_mode_cb(gpointer callback_data, guint callback_action,
-		GtkWidget *checkitem)
+static void pidgin_blist_edit_mode_cb(GtkToggleAction *checkitem, gpointer data)
 {
 	pidgin_set_cursor(gtkblist->window, GDK_WATCH);
 
 	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies",
-			gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem)));
+			gtk_toggle_action_get_active(checkitem));
 
 	pidgin_clear_cursor(gtkblist->window);
 }
 
-static void pidgin_blist_mute_sounds_cb(gpointer data, guint action, GtkWidget *item)
-{
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute", GTK_CHECK_MENU_ITEM(item)->active);
-}
+static void pidgin_blist_mute_sounds_cb(GtkToggleAction *item, gpointer data)
+{
+	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute",
+			gtk_toggle_action_get_active(item));
+}
+
 
 static void
 pidgin_blist_mute_pref_cb(const char *name, PurplePrefType type,
 							gconstpointer value, gpointer data)
 {
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(gtkblist->ift,
-						N_("/Tools/Mute Sounds"))),	(gboolean)GPOINTER_TO_INT(value));
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui,
+						"/BList/ToolsMenu/MuteSounds")), (gboolean)GPOINTER_TO_INT(value));
 }
 
 static void
@@ -2081,7 +2093,7 @@
 	if(!strcmp(value, "none"))
 		sensitive = FALSE;
 
-	gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), sensitive);
+	gtk_action_set_sensitive(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds"), sensitive);
 }
 
 static void
@@ -2238,9 +2250,9 @@
 											guint time,
 											gpointer null)
 {
-
-	if (data->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
-	{
+  GdkAtom target = gtk_selection_data_get_target(data);
+
+	if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) {
 		GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row");
 		GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref);
 		GtkTreeIter iter;
@@ -2256,9 +2268,7 @@
 					sizeof (node));
 
 		gtk_tree_path_free(sourcerow);
-	}
-	else if (data->target == gdk_atom_intern("application/x-im-contact", FALSE))
-	{
+	} else if (target == gdk_atom_intern("application/x-im-contact", FALSE)) {
 		GtkTreeRowReference *ref;
 		GtkTreePath *sourcerow;
 		GtkTreeIter iter;
@@ -2336,16 +2346,19 @@
 static void pidgin_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
 			  GtkSelectionData *sd, guint info, guint t)
 {
+  GdkAtom target = gtk_selection_data_get_target(sd);
+  const guchar *data = gtk_selection_data_get_data(sd);
+
 	if (gtkblist->drag_timeout) {
 		g_source_remove(gtkblist->drag_timeout);
 		gtkblist->drag_timeout = 0;
 	}
 
-	if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE) && sd->data) {
+	if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE) && data) {
 		PurpleBlistNode *n = NULL;
 		GtkTreePath *path = NULL;
 		GtkTreeViewDropPosition position;
-		memcpy(&n, sd->data, sizeof(n));
+		memcpy(&n, data, sizeof(n));
 		if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) {
 			/* if we're here, I think it means the drop is ok */
 			GtkTreeIter iter;
@@ -2481,12 +2494,10 @@
 			}
 
 			gtk_tree_path_free(path);
-			gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
-		}
-	}
-	else if (sd->target == gdk_atom_intern("application/x-im-contact",
-										   FALSE) && sd->data)
-	{
+			gtk_drag_finish(dc, TRUE, (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
+		}
+	} else if (target == gdk_atom_intern("application/x-im-contact",
+										   FALSE) && data) {
 		PurpleGroup *group = NULL;
 		GtkTreePath *path = NULL;
 		GtkTreeViewDropPosition position;
@@ -2521,7 +2532,7 @@
 			}
 		}
 
-		if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account,
+		if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
 										&protocol, &username, &alias))
 		{
 			if (account == NULL)
@@ -2545,9 +2556,10 @@
 		if (path != NULL)
 			gtk_tree_path_free(path);
 
-		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
-	}
-	else if (sd->target == gdk_atom_intern("text/x-vcard", FALSE) && sd->data)
+		gtk_drag_finish(dc, TRUE,
+                    (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
+	}
+	else if (target == gdk_atom_intern("text/x-vcard", FALSE) && data)
 	{
 		gboolean result;
 		PurpleGroup *group = NULL;
@@ -2580,10 +2592,11 @@
 			}
 		}
 
-		result = parse_vcard((const gchar *)sd->data, group);
-
-		gtk_drag_finish(dc, result, (dc->action == GDK_ACTION_MOVE), t);
-	} else if (sd->target == gdk_atom_intern("text/uri-list", FALSE) && sd->data) {
+		result = parse_vcard((const gchar *) data, group);
+
+		gtk_drag_finish(dc, result,
+                    (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
+	} else if (target == gdk_atom_intern("text/uri-list", FALSE) && data) {
 		GtkTreePath *path = NULL;
 		GtkTreeViewDropPosition position;
 
@@ -2601,7 +2614,8 @@
 				if (PURPLE_BLIST_NODE_IS_BUDDY(node) || PURPLE_BLIST_NODE_IS_CONTACT(node)) {
 					PurpleBuddy *b = PURPLE_BLIST_NODE_IS_BUDDY(node) ? PURPLE_BUDDY(node) : purple_contact_get_priority_buddy(PURPLE_CONTACT(node));
 					pidgin_dnd_file_manage(sd, b->account, b->name);
-					gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
+					gtk_drag_finish(dc, TRUE,
+                          (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
 				} else {
 					gtk_drag_finish(dc, FALSE, FALSE, t);
 				}
@@ -2939,7 +2953,7 @@
 	if(gtkblist->tooltipdata == NULL)
 		return FALSE;
 
-	style = gtkblist->tipwindow->style;
+	style = gtk_widget_get_style(gtkblist->tipwindow);
 
 	max_text_width = 0;
 	max_avatar_width = 0;
@@ -2965,73 +2979,79 @@
 	for(l = gtkblist->tooltipdata; l; l = l->next)
 	{
 		struct tooltip_data *td = l->data;
+    	cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(gtkblist->tipwindow));
 
 		if (td->avatar && pidgin_gdk_pixbuf_is_opaque(td->avatar))
 		{
 			if (dir == GTK_TEXT_DIR_RTL)
-				gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-						NULL, gtkblist->tipwindow, "tooltip",
-						TOOLTIP_BORDER -1, current_height -1, td->avatar_width +2, td->avatar_height + 2);
+				gtk_paint_flat_box(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+						gtkblist->tipwindow, "tooltip",
+						TOOLTIP_BORDER -1, current_height -1, td->avatar_width +2,
+            			td->avatar_height + 2);
 			else
-				gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-						NULL, gtkblist->tipwindow, "tooltip",
+				gtk_paint_flat_box(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+						gtkblist->tipwindow, "tooltip",
 						max_width - (td->avatar_width+ TOOLTIP_BORDER)-1,
 						current_height-1,td->avatar_width+2, td->avatar_height+2);
 		}
 
 		if (td->status_icon) {
-			if (dir == GTK_TEXT_DIR_RTL)
-				gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon,
-				                0, 0, max_width - TOOLTIP_BORDER - status_size, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
-			else
-				gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon,
-				                0, 0, TOOLTIP_BORDER, current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
-		}
-
-		if(td->avatar) {
-			if (dir == GTK_TEXT_DIR_RTL)
-				gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL,
-						td->avatar, 0, 0, TOOLTIP_BORDER, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
-			else
-				gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL,
-						td->avatar, 0, 0, max_width - (td->avatar_width + TOOLTIP_BORDER),
-						current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
-		}
-
-		if (!td->avatar_is_prpl_icon && td->prpl_icon)
-			gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->prpl_icon,
-					0, 0,
-					prpl_col,
-					current_height + ((td->name_height / 2) - (PRPL_SIZE / 2)),
-					-1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
+			if (dir == GTK_TEXT_DIR_RTL) {
+        		gdk_cairo_set_source_pixbuf(cr, td->status_icon,
+          			max_width - TOOLTIP_BORDER - status_size, current_height);
+        		cairo_paint(cr);
+      		} else {
+        		gdk_cairo_set_source_pixbuf(cr, td->status_icon, TOOLTIP_BORDER, current_height);
+        		cairo_paint(cr);
+      		}
+    	}
+
+		if (td->avatar) {
+			if (dir == GTK_TEXT_DIR_RTL) {
+        		gdk_cairo_set_source_pixbuf(cr, td->avatar, TOOLTIP_BORDER,
+		        	current_height);
+        		cairo_paint(cr);
+      		} else {
+        		gdk_cairo_set_source_pixbuf(cr, td->avatar,
+          			max_width - (td->avatar_width + TOOLTIP_BORDER), current_height);
+        		cairo_paint(cr);
+      		}
+		}
+
+		if (!td->avatar_is_prpl_icon && td->prpl_icon) {
+      		gdk_cairo_set_source_pixbuf(cr, td->prpl_icon, prpl_col,
+        		current_height + ((td->name_height / 2) - (PRPL_SIZE / 2)));
+      		cairo_paint(cr);
+    	}
 
 		if (td->name_layout) {
 			if (dir == GTK_TEXT_DIR_RTL) {
-				gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-						NULL, gtkblist->tipwindow, "tooltip",
+				gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
+						gtkblist->tipwindow, "tooltip",
 						max_width  -(TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
 						current_height, td->name_layout);
 			} else {
-				gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-						NULL, gtkblist->tipwindow, "tooltip",
+				gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
+						gtkblist->tipwindow, "tooltip",
 						TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height, td->name_layout);
 			}
 		}
 
 		if (td->layout) {
 			if (dir != GTK_TEXT_DIR_RTL) {
-				gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-						NULL, gtkblist->tipwindow, "tooltip",
+				gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
+						gtkblist->tipwindow, "tooltip",
 						TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height + td->name_height, td->layout);
 			} else {
-				gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-						NULL, gtkblist->tipwindow, "tooltip",
+				gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
+						gtkblist->tipwindow, "tooltip",
 						max_width - (TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
 						current_height + td->name_height,
 						td->layout);
 			}
 		}
 
+    	cairo_destroy(cr);
 		current_height += MAX(td->name_height + td->height, td->avatar_height) + td->padding;
 	}
 	return FALSE;
@@ -3182,7 +3202,8 @@
 		pidgin_blist_expand_contact_cb(NULL, node);
 
 		gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, &gtkblist->contact_rect);
-		gdk_drawable_get_size(GDK_DRAWABLE(tv->window), &(gtkblist->contact_rect.width), NULL);
+		gtkblist->contact_rect.width =
+		gdk_window_get_width(gtk_widget_get_window(tv));
 		gtkblist->mouseover_contact = node;
 		gtk_tree_path_down (path);
 		while (gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &i, path)) {
@@ -3597,6 +3618,123 @@
 /***************************************************
  *            Crap                                 *
  ***************************************************/
+#if 1
+/* TODO: fill out tooltips... */
+static const GtkActionEntry blist_menu_entries[] = {
+	/* Buddies menu */
+	{ "BuddiesMenu", NULL, N_("_Buddies"), NULL, NULL, NULL },
+	{ "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, pidgin_dialogs_im },
+	{ "JoinAChat", PIDGIN_STOCK_CHAT, N_("Join a _Chat..."), "<control>C", NULL, pidgin_blist_joinchat_show },
+	{ "GetUserInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("Get User _Info..."), "<control>I", NULL, pidgin_dialogs_info },
+	{ "ViewUserLog", NULL, N_("View User _Log..."), "<control>L", NULL, pidgin_dialogs_log },
+	{ "ShowMenu", NULL, N_("Sh_ow"), NULL, NULL, NULL },
+	{ "SortMenu", NULL, N_("_Sort Buddies"), NULL, NULL, NULL },
+	{ "AddBuddy", GTK_STOCK_ADD, N_("_Add Buddy..."), "<control>B", NULL, pidgin_blist_add_buddy_cb },
+	{ "AddChat", GTK_STOCK_ADD, N_("Add C_hat..."), NULL, NULL, pidgin_blist_add_chat_cb },
+	{ "AddGroup", GTK_STOCK_ADD, N_("Add _Group..."), NULL, NULL, purple_blist_request_add_group },
+	{ "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", NULL, purple_core_quit },
+
+	/* Accounts menu */
+	{ "AccountsMenu", NULL, N_("_Accounts"), NULL, NULL, NULL },
+	{ "ManageAccounts", NULL, N_("Manage Accounts"), "<control>A", NULL, pidgin_accounts_window_show },
+	{ "EnableAccountMenu", NULL, N_("Enable Account"), NULL, NULL, NULL },
+
+	/* Tools */
+	{ "ToolsMenu", NULL, N_("_Tools"), NULL, NULL, NULL },
+	{ "BuddyPounces", NULL, N_("Buddy _Pounces"), NULL, NULL, pidgin_pounces_manager_show },
+	{ "Certificates", NULL, N_("_Certificates"), NULL, NULL, pidgin_certmgr_show },
+	{ "CustomSmileys", PIDGIN_STOCK_TOOLBAR_SMILEY, N_("Custom Smile_ys"), "<control>Y", NULL, pidgin_smiley_manager_show },
+	{ "Plugins", PIDGIN_STOCK_TOOLBAR_PLUGINS, N_("Plu_gins"), "<control>U", NULL, pidgin_plugin_dialog_show },
+	{ "Preferences", GTK_STOCK_PREFERENCES, N_("Pr_eferences"), "<control>P", NULL, pidgin_prefs_show },
+	{ "Privacy", NULL, N_("Pr_ivacy"), NULL, NULL, pidgin_privacy_dialog_show },
+	{ "SetMood", NULL, N_("Set _Mood"), "<control>O", NULL, set_mood_show },
+	{ "FileTransfers", PIDGIN_STOCK_TOOLBAR_TRANSFER, N_("_File Transfers"), "<control>T", NULL, G_CALLBACK(gtk_blist_show_xfer_dialog_cb) },
+	{ "RoomList", NULL, N_("R_oom List"), NULL, NULL, pidgin_roomlist_dialog_show },
+	{ "SystemLog", NULL, N_("System _Log"), NULL, NULL, gtk_blist_show_systemlog_cb },
+
+	/* Help */
+	{ "HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL },
+	{ "OnlineHelp", GTK_STOCK_HELP, N_("Online _Help"), "F1", NULL, gtk_blist_show_onlinehelp_cb },
+	{ "BuildInformation", NULL, N_("_Build Information"), NULL, NULL, pidgin_dialogs_buildinfo },
+	{ "DebugWindow", NULL, N_("_Debug Window"), NULL, NULL, toggle_debug },
+	{ "DeveloperInformation", NULL, N_("De_veloper Information"), NULL, NULL, pidgin_dialogs_developers },
+	{ "TranslatorInformation", NULL, N_("_Translator Information"), NULL, NULL, pidgin_dialogs_translators },
+	{ "About", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, pidgin_dialogs_about },
+};
+
+/* Toggle items */
+static const GtkToggleActionEntry blist_menu_toggle_entries[] = {
+	/* Buddies->Show menu */
+	{ "ShowOffline", NULL, N_("_Offline Buddies"), NULL, NULL, G_CALLBACK(pidgin_blist_edit_mode_cb), FALSE },
+	{ "ShowEmptyGroups", NULL, N_("_Empty Groups"), NULL, NULL, G_CALLBACK(pidgin_blist_show_empty_groups_cb), FALSE },
+	{ "ShowBuddyDetails", NULL, N_("Buddy _Details"), NULL, NULL, G_CALLBACK(pidgin_blist_buddy_details_cb), FALSE },
+	{ "ShowIdleTimes", NULL, N_("Idle _Times"), NULL, NULL, G_CALLBACK(pidgin_blist_show_idle_time_cb), FALSE },
+	{ "ShowProtocolIcons", NULL, N_("_Protocol Icons"), NULL, NULL, G_CALLBACK(pidgin_blist_show_protocol_icons_cb), FALSE },
+
+	/* Tools menu */
+	{ "MuteSounds", NULL, N_("Mute _Sounds"), NULL, NULL, G_CALLBACK(pidgin_blist_mute_sounds_cb), FALSE },
+};
+
+static const char *blist_menu =
+"<ui>"
+	"<menubar name='BList'>"
+		"<menu action='BuddiesMenu'>"
+			"<menuitem action='NewInstantMessage'/>"
+			"<menuitem action='JoinAChat'/>"
+			"<menuitem action='GetUserInfo'/>"
+			"<menuitem action='ViewUserLog'/>"
+			"<separator/>"
+			"<menu action='ShowMenu'>"
+				"<menuitem action='ShowOffline'/>"
+				"<menuitem action='ShowEmptyGroups'/>"
+				"<menuitem action='ShowBuddyDetails'/>"
+				"<menuitem action='ShowIdleTimes'/>"
+				"<menuitem action='ShowProtocolIcons'/>"
+			"</menu>"
+			"<menu action='SortMenu'/>"
+			"<separator/>"
+			"<menuitem action='AddBuddy'/>"
+			"<menuitem action='AddChat'/>"
+			"<menuitem action='AddGroup'/>"
+			"<separator/>"
+			"<menuitem action='Quit'/>"
+		"</menu>"
+		"<menu action='AccountsMenu'>"
+			"<menuitem action='ManageAccounts'/>"
+			"<menu action='EnableAccountMenu'/>"
+			"<separator/>"
+			"<placeholder name='Accounts'/>"
+		"</menu>"
+		"<menu action='ToolsMenu'>"
+			"<menuitem action='BuddyPounces'/>"
+			"<menuitem action='Certificates'/>"
+			"<menuitem action='CustomSmileys'/>"
+			"<menuitem action='Plugins'/>"
+			"<menuitem action='Preferences'/>"
+			"<menuitem action='Privacy'/>"
+			"<menuitem action='SetMood'/>"
+			"<separator/>"
+			"<menuitem action='FileTransfers'/>"
+			"<menuitem action='RoomList'/>"
+			"<menuitem action='SystemLog'/>"
+			"<separator/>"
+			"<menuitem action='MuteSounds'/>"
+			"<placeholder name='PluginActions'/>"
+		"</menu>"
+		"<menu action='HelpMenu'>"
+			"<menuitem action='OnlineHelp'/>"
+			"<separator/>"
+			"<menuitem action='BuildInformation'/>"
+			"<menuitem action='DebugWindow'/>"
+			"<menuitem action='DeveloperInformation'/>"
+			"<menuitem action='TranslatorInformation'/>"
+			"<separator/>"
+			"<menuitem action='About'/>"
+		"</menu>"
+	"</menubar>"
+"</ui>";
+
+#else
 static GtkItemFactoryEntry blist_menu[] =
 {
 /* NOTE: Do not set any accelerator to Control+O. It is mapped by
@@ -3653,6 +3791,7 @@
 	{ "/Help/sep2", NULL, NULL, 0, "<Separator>", NULL },
 	{ N_("/Help/_About"), NULL, pidgin_dialogs_about, 4,  "<StockItem>", GTK_STOCK_ABOUT },
 };
+#endif
 
 /*********************************************************
  * Private Utility functions                             *
@@ -4394,7 +4533,7 @@
 	/* if the window exists, is hidden, we're saving positions, and the
 	 * position is sane... */
 	if (gtkblist && gtkblist->window &&
-		!GTK_WIDGET_VISIBLE(gtkblist->window) && blist_width != 0) {
+		!gtk_widget_get_visible(gtkblist->window) && blist_width != 0) {
 
 		blist_x      = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/x");
 		blist_y      = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/y");
@@ -4424,7 +4563,7 @@
 	PurpleBlistNode *gnode, *cnode;
 
 	if (gtk_blist_visibility == GDK_VISIBILITY_FULLY_OBSCURED
-			|| !GTK_WIDGET_VISIBLE(gtkblist->window))
+			|| !gtk_widget_get_visible(gtkblist->window))
 		return TRUE;
 
 	for(gnode = list->root; gnode; gnode = gnode->next) {
@@ -4470,12 +4609,21 @@
 
 static const char *require_connection[] =
 {
+#if 1
+	"/BList/BuddiesMenu/NewInstantMessage",
+	"/BList/BuddiesMenu/JoinAChat",
+	"/BList/BuddiesMenu/GetUserInfo",
+	"/BList/BuddiesMenu/AddBuddy",
+	"/BList/BuddiesMenu/AddChat",
+	"/BList/BuddiesMenu/AddGroup",
+#else
 	N_("/Buddies/New Instant Message..."),
 	N_("/Buddies/Join a Chat..."),
 	N_("/Buddies/Get User Info..."),
 	N_("/Buddies/Add Buddy..."),
 	N_("/Buddies/Add Chat..."),
 	N_("/Buddies/Add Group..."),
+#endif
 };
 
 static const int require_connection_size = sizeof(require_connection)
@@ -4488,7 +4636,7 @@
 static void
 update_menu_bar(PidginBuddyList *gtkblist)
 {
-	GtkWidget *widget;
+	GtkAction *action;
 	gboolean sensitive;
 	int i;
 
@@ -4500,21 +4648,21 @@
 
 	for (i = 0; i < require_connection_size; i++)
 	{
-		widget = gtk_item_factory_get_widget(gtkblist->ift, require_connection[i]);
-		gtk_widget_set_sensitive(widget, sensitive);
-	}
-
-	widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Join a Chat..."));
-	gtk_widget_set_sensitive(widget, pidgin_blist_joinchat_is_showable());
-
-	widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Add Chat..."));
-	gtk_widget_set_sensitive(widget, pidgin_blist_joinchat_is_showable());
-
-	widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Privacy"));
-	gtk_widget_set_sensitive(widget, sensitive);
-
-	widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Room List"));
-	gtk_widget_set_sensitive(widget, pidgin_roomlist_is_showable());
+		action = gtk_ui_manager_get_action(gtkblist->ui, require_connection[i]);
+		gtk_action_set_sensitive(action, sensitive);
+	}
+
+	action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/JoinAChat");
+	gtk_action_set_sensitive(action, pidgin_blist_joinchat_is_showable());
+
+	action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/AddChat");
+	gtk_action_set_sensitive(action, pidgin_blist_joinchat_is_showable());
+
+	action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/Privacy");
+	gtk_action_set_sensitive(action, sensitive);
+
+	action = gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/RoomList");
+	gtk_action_set_sensitive(action, pidgin_roomlist_is_showable());
 }
 
 static void
@@ -4805,12 +4953,6 @@
 	NUM_TARGETS
 };
 
-static const char *
-item_factory_translate_func (const char *path, gpointer func_data)
-{
-	return _((char *)path);
-}
-
 void pidgin_blist_setup_sort_methods()
 {
 	const char *id;
@@ -4933,7 +5075,7 @@
 	widget = gtk_window_get_focus(GTK_WINDOW(gtkblist->window));
 
 	if (GTK_IS_IMHTML(widget) || GTK_IS_ENTRY(widget)) {
-		if (gtk_bindings_activate(GTK_OBJECT(widget), event->keyval, event->state))
+		if (gtk_bindings_activate(G_OBJECT(widget), event->keyval, event->state))
 			return TRUE;
 	}
 	return FALSE;
@@ -4942,14 +5084,14 @@
 static gboolean
 headline_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, PidginBuddyList *gtkblist)
 {
-	gdk_window_set_cursor(widget->window, gtkblist->hand_cursor);
+	gdk_window_set_cursor(gtk_widget_get_window(widget), gtkblist->hand_cursor);
 	return FALSE;
 }
 
 static gboolean
 headline_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, PidginBuddyList *gtkblist)
 {
-	gdk_window_set_cursor(widget->window, gtkblist->arrow_cursor);
+	gdk_window_set_cursor(gtk_widget_get_window(widget), gtkblist->arrow_cursor);
 	return FALSE;
 }
 
@@ -5083,7 +5225,7 @@
 }
 
 static void
-generic_error_destroy_cb(GtkObject *dialog,
+generic_error_destroy_cb(GtkWidget *dialog,
                          PurpleAccount *account)
 {
 	g_hash_table_remove(gtkblist->connection_errors, account);
@@ -5445,17 +5587,22 @@
 		      GdkEventExpose *event,
 		      gpointer user_data)
 {
-	gtk_paint_flat_box (widget->style,
-		      widget->window,
-		      GTK_STATE_NORMAL,
-		      GTK_SHADOW_OUT,
-		      NULL,
-		      widget,
-		      "tooltip",
-		      widget->allocation.x + 1,
-		      widget->allocation.y + 1,
-		      widget->allocation.width - 2,
-		      widget->allocation.height - 2);
+	cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
+	GtkAllocation allocation;
+
+	gtk_widget_get_allocation(widget, &allocation);
+	gtk_paint_flat_box (gtk_widget_get_style(widget),
+		cr,
+		GTK_STATE_NORMAL,
+		GTK_SHADOW_OUT,
+		widget,
+		"tooltip",
+		allocation.x + 1,
+		allocation.y + 1,
+		allocation.width - 2,
+		allocation.height - 2);
+	cairo_destroy(cr);
+
 	return FALSE;
 }
 
@@ -5479,8 +5626,28 @@
 headline_style_set (GtkWidget *widget,
 		    GtkStyle  *prev_style)
 {
+	GtkStyle *style;
+#if GTK_CHECK_VERSION(2,12,0)
+	GtkWidget *window;
+
+	if (gtkblist->changing_style)
+		return;
+
+	/* This is a hack needed to use the tooltip background colour */
+	window = gtk_window_new(GTK_WINDOW_POPUP);
+	gtk_widget_set_name(window, "gtk-tooltip");
+	gtk_widget_ensure_style(window);
+	style = gtk_widget_get_style(window);
+
+	gtkblist->changing_style = TRUE;
+	gtk_widget_set_style(gtkblist->headline_hbox, style);
+	gtkblist->changing_style = FALSE;
+
+	gtk_widget_destroy(window);
+
+	gtk_widget_queue_draw(gtkblist->headline_hbox);
+#else
 	GtkTooltips *tooltips;
-	GtkStyle *style;
 
 	if (gtkblist->changing_style)
 		return;
@@ -5500,6 +5667,7 @@
 	gtkblist->changing_style = FALSE;
 
 	g_object_unref (tooltips);
+#endif
 }
 
 /******************************************/
@@ -5737,6 +5905,8 @@
 	GtkWidget *close;
 	char *pretty, *tmp;
 	const char *theme_name;
+	GtkActionGroup *action_group;
+	GError *error;
 	GtkAccelGroup *accel_group;
 	GtkTreeSelection *selection;
 	GtkTargetEntry dte[] = {{"PURPLE_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW},
@@ -5772,7 +5942,9 @@
 			 G_CALLBACK(blist_focus_cb), gtkblist);
 	g_signal_connect(G_OBJECT(gtkblist->window), "focus-out-event",
 			 G_CALLBACK(blist_focus_cb), gtkblist);
-	GTK_WINDOW(gtkblist->window)->allow_shrink = TRUE;
+
+  /* TODO: how is this done in gtk+ 3.0? */
+	/*GTK_WINDOW(gtkblist->window)->allow_shrink = TRUE;*/
 
 	gtkblist->main_vbox = gtk_vbox_new(FALSE, 0);
 	gtk_widget_show(gtkblist->main_vbox);
@@ -5786,28 +5958,41 @@
 	gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK);
 
 	/******************************* Menu bar *************************************/
-	accel_group = gtk_accel_group_new();
-	gtk_window_add_accel_group(GTK_WINDOW (gtkblist->window), accel_group);
-	g_object_unref(accel_group);
-	gtkblist->ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<PurpleMain>", accel_group);
-	gtk_item_factory_set_translate_func(gtkblist->ift,
-										(GtkTranslateFunc)item_factory_translate_func,
-										NULL, NULL);
-	gtk_item_factory_create_items(gtkblist->ift, sizeof(blist_menu) / sizeof(*blist_menu),
-								  blist_menu, NULL);
-	pidgin_load_accels();
-	g_signal_connect(G_OBJECT(accel_group), "accel-changed", G_CALLBACK(pidgin_save_accels_cb), NULL);
-
-	menu = gtk_item_factory_get_widget(gtkblist->ift, "<PurpleMain>");
+	action_group = gtk_action_group_new("BListActions");
+	gtk_action_group_add_actions(action_group,
+	                             blist_menu_entries,
+	                             G_N_ELEMENTS(blist_menu_entries),
+	                             GTK_WINDOW(gtkblist->window));
+	gtk_action_group_add_toggle_actions(action_group,
+	                                    blist_menu_toggle_entries,
+	                                    G_N_ELEMENTS(blist_menu_toggle_entries),
+	                                    GTK_WINDOW(gtkblist->window));
+#ifdef ENABLE_NLS
+	gtk_action_group_set_translation_domain(action_group,
+	                                        PACKAGE);
+#endif
+
+	gtkblist->ui = gtk_ui_manager_new();
+	gtk_ui_manager_insert_action_group(gtkblist->ui, action_group, 0);
+
+	accel_group = gtk_ui_manager_get_accel_group(gtkblist->ui);
+	gtk_window_add_accel_group(GTK_WINDOW(gtkblist->window), accel_group);
+
+	error = NULL;
+	if (!gtk_ui_manager_add_ui_from_string(gtkblist->ui, blist_menu, -1, &error))
+	{
+		g_message("building menus failed: %s", error->message);
+		g_error_free(error);
+		exit(EXIT_FAILURE);
+	}
+
+	menu = gtk_ui_manager_get_widget(gtkblist->ui, "/BList");
 	gtkblist->menutray = pidgin_menu_tray_new();
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtkblist->menutray);
 	gtk_widget_show(gtkblist->menutray);
 	gtk_widget_show(menu);
 	gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), menu, FALSE, FALSE, 0);
 
-	accountmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts"));
-
-
 	/****************************** Notebook *************************************/
 	gtkblist->notebook = gtk_notebook_new();
 	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gtkblist->notebook), FALSE);
@@ -5828,7 +6013,6 @@
 	pretty = pidgin_make_pretty_arrows(tmp);
 	g_free(tmp);
 	label = gtk_label_new(NULL);
-	gtk_widget_set_size_request(label, purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/width") - 12, -1);
 	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.2);
 	gtk_label_set_markup(GTK_LABEL(label), pretty);
@@ -5858,7 +6042,7 @@
 			 G_CALLBACK(headline_style_set),
 			 NULL);
 	g_signal_connect (gtkblist->headline_hbox,
-			  "expose_event",
+			  "draw",
 			  G_CALLBACK (paint_headline_hbox),
 			  NULL);
 	gtk_widget_set_name(gtkblist->headline_hbox, "gtk-tooltips");
@@ -5998,26 +6182,26 @@
 	/* set the Show Offline Buddies option. must be done
 	 * after the treeview or faceprint gets mad. -Robot101
 	 */
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies"))),
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowOffline")),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Empty Groups"))),
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowEmptyGroups")),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))),
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds")),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/sound/mute"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Buddy Details"))),
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowBuddyDetails")),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Idle Times"))),
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowIdleTimes")),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time"));
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Protocol Icons"))),
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(gtkblist->ui, "/BList/BuddiesMenu/ShowMenu/ShowProtocolIcons")),
 			purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"));
 
 	if(!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
-		gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), FALSE);
+		gtk_action_set_sensitive(gtk_ui_manager_get_action(gtkblist->ui, "/BList/ToolsMenu/MuteSounds"), FALSE);
 
 	/* Update some dynamic things */
 	update_menu_bar(gtkblist);
@@ -6874,7 +7058,7 @@
 	purple_signals_disconnect_by_handle(gtkblist);
 
 	if (gtkblist->headline_close)
-		gdk_pixbuf_unref(gtkblist->headline_close);
+		g_object_unref(G_OBJECT(gtkblist->headline_close));
 
 	gtk_widget_destroy(gtkblist->window);
 
@@ -6894,7 +7078,7 @@
 	gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL;
 	g_object_unref(G_OBJECT(gtkblist->treemodel));
 	gtkblist->treemodel = NULL;
-	g_object_unref(G_OBJECT(gtkblist->ift));
+	g_object_unref(G_OBJECT(gtkblist->ui));
 	g_object_unref(G_OBJECT(gtkblist->empty_avatar));
 
 	gdk_cursor_unref(gtkblist->hand_cursor);
@@ -6908,7 +7092,6 @@
 	g_free(priv);
 
 	g_free(gtkblist);
-	accountmenu = NULL;
 	gtkblist = NULL;
 	purple_prefs_disconnect_by_handle(pidgin_blist_get_handle());
 }
@@ -6919,7 +7102,8 @@
 		return;
 
 	if (show) {
-		if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) && !GTK_WIDGET_VISIBLE(gtkblist->window))
+		if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) &&
+        !gtk_widget_get_visible(gtkblist->window))
 			purple_signal_emit(pidgin_blist_get_handle(), "gtkblist-unhiding", gtkblist);
 		pidgin_blist_restore_position();
 		gtk_window_present(GTK_WINDOW(gtkblist->window));
@@ -6928,7 +7112,7 @@
 			purple_signal_emit(pidgin_blist_get_handle(), "gtkblist-hiding", gtkblist);
 			gtk_widget_hide(gtkblist->window);
 		} else {
-			if (!GTK_WIDGET_VISIBLE(gtkblist->window))
+			if (!gtk_widget_get_visible(gtkblist->window))
 				gtk_widget_show(gtkblist->window);
 			gtk_window_iconify(GTK_WINDOW(gtkblist->window));
 		}
@@ -7304,7 +7488,7 @@
 pidgin_blist_toggle_visibility()
 {
 	if (gtkblist && gtkblist->window) {
-		if (GTK_WIDGET_VISIBLE(gtkblist->window)) {
+		if (gtk_widget_get_visible(gtkblist->window)) {
 			/* make the buddy list visible if it is iconified or if it is
 			 * obscured and not currently focused (the focus part ensures
 			 * that we do something reasonable if the buddy list is obscured
@@ -7369,7 +7553,7 @@
 static void
 set_urgent(void)
 {
-	if (gtkblist->window && !GTK_WIDGET_HAS_FOCUS(gtkblist->window))
+	if (gtkblist->window && !gtk_widget_is_focus(gtkblist->window))
 		pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE);
 }
 
@@ -7899,47 +8083,50 @@
 }
 
 static void
-plugin_act(GtkObject *obj, PurplePluginAction *pam)
+plugin_act(GtkWidget *obj, PurplePluginAction *pam)
 {
 	if (pam && pam->callback)
 		pam->callback(pam);
 }
 
 static void
-build_plugin_actions(GtkWidget *menu, PurplePlugin *plugin,
-		gpointer context)
-{
-	GtkWidget *menuitem;
+build_plugin_actions(GtkActionGroup *action_group, GString *ui, char *parent,
+		PurplePlugin *plugin, gpointer context)
+{
+	GtkAction *menuaction;
 	PurplePluginAction *action = NULL;
 	GList *actions, *l;
+	char *name;
+	int count = 0;
 
 	actions = PURPLE_PLUGIN_ACTIONS(plugin, context);
 
-	for (l = actions; l != NULL; l = l->next)
-	{
-		if (l->data)
-		{
-			action = (PurplePluginAction *) l->data;
+	for (l = actions; l != NULL; l = l->next) {
+		if (l->data) {
+			action = (PurplePluginAction *)l->data;
 			action->plugin = plugin;
 			action->context = context;
 
-			menuitem = gtk_menu_item_new_with_label(action->label);
-			gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-
-			g_signal_connect(G_OBJECT(menuitem), "activate",
+			name = g_strdup_printf("%s-action-%d", parent, count++);
+			menuaction = gtk_action_new(name, action->label, NULL, NULL);
+			gtk_action_group_add_action(action_group, menuaction);
+			g_string_append_printf(ui, "<menuitem action='%s'/>", name);
+
+			g_signal_connect(G_OBJECT(menuaction), "activate",
 					G_CALLBACK(plugin_act), action);
-			g_object_set_data_full(G_OBJECT(menuitem), "plugin_action",
+			g_object_set_data_full(G_OBJECT(menuaction), "plugin_action",
 								   action,
 								   (GDestroyNotify)purple_plugin_action_free);
-			gtk_widget_show(menuitem);
+			g_free(name);
 		}
 		else
-			pidgin_separator(menu);
+			g_string_append(ui, "<separator/>");
 	}
 
 	g_list_free(actions);
 }
 
+
 static void
 modify_account_cb(GtkWidget *widget, gpointer data)
 {
@@ -7971,183 +8158,146 @@
 void
 pidgin_blist_update_accounts_menu(void)
 {
-	GtkWidget *menuitem = NULL, *submenu = NULL;
-	GtkAccelGroup *accel_group = NULL;
-	GList *l = NULL, *accounts = NULL;
-	gboolean disabled_accounts = FALSE;
-	gboolean enabled_accounts = FALSE;
-
-	if (accountmenu == NULL)
+	GList *accounts = NULL;
+
+	GtkAction *action;
+	GString *accounts_ui;
+	GString *enable_ui;
+	gchar *ui_string;
+	int count = 0;
+
+	if ((gtkblist == NULL) || (gtkblist->ui == NULL))
 		return;
 
-	/* Clear the old Accounts menu */
-	for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) {
-		menuitem = l->data;
-
-		if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage Accounts")))
-			gtk_widget_destroy(menuitem);
-	}
-
-	for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
-		char *buf = NULL;
-		GtkWidget *image = NULL;
-		PurpleAccount *account = NULL;
-		GdkPixbuf *pixbuf = NULL;
-
-		account = accounts->data;
-
-		if(!purple_account_get_enabled(account, PIDGIN_UI)) {
-			if (!disabled_accounts) {
-				menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
-				gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
-
-				submenu = gtk_menu_new();
-				gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
-				gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
-				gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-
-				disabled_accounts = TRUE;
-			}
-
-			buf = g_strconcat(purple_account_get_username(account), " (",
-				purple_account_get_protocol_name(account), ")", NULL);
-			menuitem = gtk_image_menu_item_new_with_label(buf);
-			g_free(buf);
-			pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
-			if (pixbuf != NULL)
-			{
-				if (!purple_account_is_connected(account))
-					gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
-				image = gtk_image_new_from_pixbuf(pixbuf);
-				g_object_unref(G_OBJECT(pixbuf));
-				gtk_widget_show(image);
-				gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
-			}
-			g_signal_connect(G_OBJECT(menuitem), "activate",
-				G_CALLBACK(enable_account_cb), account);
-			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-		} else {
-			enabled_accounts = TRUE;
-		}
-	}
-
-	if (!enabled_accounts) {
-		gtk_widget_show_all(accountmenu);
-		return;
-	}
-
-	pidgin_separator(accountmenu);
-	accel_group = gtk_menu_get_accel_group(GTK_MENU(accountmenu));
+	/* Clear the old menu */
+	if (accounts_action_group) {
+		gtk_ui_manager_remove_ui(gtkblist->ui, accounts_merge_id);
+		gtk_ui_manager_remove_action_group(gtkblist->ui, accounts_action_group);
+		g_object_unref(G_OBJECT(accounts_action_group));
+	}
+
+	accounts_action_group = gtk_action_group_new("Accounts");
+#ifdef ENABLE_NLS
+	gtk_action_group_set_translation_domain(accounts_action_group, PACKAGE);
+#endif
+	accounts_ui = g_string_new(NULL);
+	enable_ui = g_string_new(NULL);
+
+	action = gtk_action_new("none-available", N_("No actions available"), NULL, NULL);
+	gtk_action_group_add_action(accounts_action_group, action);
+	gtk_action_set_sensitive(action, FALSE);
 
 	for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
-		char *buf = NULL;
-		char *accel_path_buf = NULL;
-		GtkWidget *image = NULL;
-		PurpleConnection *gc = NULL;
+		char *label;
+		char *base;
+		char *name;
 		PurpleAccount *account = NULL;
-		GdkPixbuf *pixbuf = NULL;
-		PurplePlugin *plugin = NULL;
-		PurplePluginProtocolInfo *prpl_info;
 
 		account = accounts->data;
 
-		if (!purple_account_get_enabled(account, PIDGIN_UI))
-			continue;
-
-		buf = g_strconcat(purple_account_get_username(account), " (",
+		base = name = g_strdup_printf("account%d", count);
+		label = g_strconcat(purple_account_get_username(account), " (",
 				purple_account_get_protocol_name(account), ")", NULL);
-		menuitem = gtk_image_menu_item_new_with_label(buf);
-		accel_path_buf = g_strconcat(N_("<PurpleMain>/Accounts/"), buf, NULL);
-		g_free(buf);
-		pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
-		if (pixbuf != NULL) {
-			if (!purple_account_is_connected(account))
-				gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf,
-						0.0, FALSE);
-			image = gtk_image_new_from_pixbuf(pixbuf);
-			g_object_unref(G_OBJECT(pixbuf));
-			gtk_widget_show(image);
-			gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
-		}
-		gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
-
-		submenu = gtk_menu_new();
-		gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
-		gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path_buf);
-		g_free(accel_path_buf);
-		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-
-
-		menuitem = gtk_menu_item_new_with_mnemonic(_("_Edit Account"));
-		g_signal_connect(G_OBJECT(menuitem), "activate",
-				G_CALLBACK(modify_account_cb), account);
-		gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-
-		pidgin_separator(submenu);
-
-		gc = purple_account_get_connection(account);
-		plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
-		prpl_info = plugin ? PURPLE_PLUGIN_PROTOCOL_INFO(plugin) : NULL;
-
-		if (prpl_info &&
-		    (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) ||
-			 PURPLE_PLUGIN_HAS_ACTIONS(plugin))) {
-			if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) &&
-			    gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
-
-				if (purple_account_get_status(account, "mood")) {
-					menuitem = gtk_menu_item_new_with_mnemonic(_("Set _Mood..."));
-					g_signal_connect(G_OBJECT(menuitem), "activate",
-					         	G_CALLBACK(set_mood_cb), account);
-					gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-				}
+		action = gtk_action_new(name, label, NULL, NULL);
+		g_free(label);
+		gtk_action_group_add_action(accounts_action_group, action);
+
+		if (!purple_account_get_enabled(account, PIDGIN_UI)) {
+			g_string_append_printf(enable_ui, "<menuitem action='%s'/>", name);
+			g_signal_connect(G_OBJECT(action), "activate",
+			                 G_CALLBACK(enable_account_cb), account);
+
+		} else {
+			PurpleConnection *gc = NULL;
+			PurplePlugin *plugin = NULL;
+
+			g_string_append_printf(accounts_ui, "<menu action='%s'>", name);
+
+			name = g_strconcat(base, "-edit", NULL);
+			action = gtk_action_new(name, N_("_Edit Account"), NULL, NULL);
+			gtk_action_group_add_action(accounts_action_group, action);
+			g_signal_connect(G_OBJECT(action), "activate",
+			                 G_CALLBACK(modify_account_cb), account);
+			g_string_append_printf(accounts_ui, "<menuitem action='%s'/>", name);
+			g_free(name);
+
+			g_string_append(accounts_ui, "<separator/>");
+
+			gc = purple_account_get_connection(account);
+			plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
+			if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
+				build_plugin_actions(accounts_action_group, accounts_ui, base, plugin, gc);
+			} else {
+				g_string_append(accounts_ui, "<menuitem action='none-available'/>");
 			}
-			if (PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
-				build_plugin_actions(submenu, plugin, gc);
-			}
-		} else {
-			menuitem = gtk_menu_item_new_with_label(_("No actions available"));
-			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-			gtk_widget_set_sensitive(menuitem, FALSE);
-		}
-
-		pidgin_separator(submenu);
-
-		menuitem = gtk_menu_item_new_with_mnemonic(_("_Disable"));
-		g_signal_connect(G_OBJECT(menuitem), "activate",
-				G_CALLBACK(disable_account_cb), account);
-		gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-	}
-	gtk_widget_show_all(accountmenu);
-}
-
-static GList *plugin_submenus = NULL;
+
+			g_string_append(accounts_ui, "<separator/>");
+
+			name = g_strconcat(base, "-disable", NULL);
+			action = gtk_action_new(name, N_("_Disable"), NULL, NULL);
+			gtk_action_group_add_action(accounts_action_group, action);
+			g_signal_connect(G_OBJECT(action), "activate",
+			                 G_CALLBACK(disable_account_cb), account);
+			g_string_append_printf(accounts_ui, "<menuitem action='%s'/>", name);
+			g_free(name);
+
+			g_string_append(accounts_ui, "</menu>");
+		}
+
+		g_free(base);
+		count++;
+	}
+
+	ui_string = g_strconcat("<ui><menubar action='BList'><menu action='AccountsMenu'><menu action='EnableAccountMenu'>",
+	                        enable_ui->str,
+	                        "</menu><placeholder name='Accounts'>",
+	                        accounts_ui->str,
+	                        "</placeholder></menu></menubar></ui>",
+	                        NULL);
+	gtk_ui_manager_insert_action_group(gtkblist->ui, accounts_action_group, 1);
+	accounts_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string, -1, NULL);
+purple_debug_info("blist", "The account menu is {%s}\n", ui_string);
+
+	g_string_free(enable_ui, TRUE);
+	g_string_free(accounts_ui, TRUE);
+	g_free(ui_string);
+}
+
+static guint plugins_merge_id;
+static GtkActionGroup *plugins_action_group = NULL;
 
 void
 pidgin_blist_update_plugin_actions(void)
 {
-	GtkWidget *menuitem, *submenu;
 	PurplePlugin *plugin = NULL;
 	GList *l;
-	GtkAccelGroup *accel_group;
-
-	GtkWidget *pluginmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools"));
-
-	g_return_if_fail(pluginmenu != NULL);
-
-	/* Remove old plugin action submenus from the Tools menu */
-	for (l = plugin_submenus; l; l = l->next)
-		gtk_widget_destroy(GTK_WIDGET(l->data));
-	g_list_free(plugin_submenus);
-	plugin_submenus = NULL;
-
-	accel_group = gtk_menu_get_accel_group(GTK_MENU(pluginmenu));
+
+	GtkAction *action;
+	GString *plugins_ui;
+	gchar *ui_string;
+	int count = 0;
+
+	if ((gtkblist == NULL) || (gtkblist->ui == NULL))
+		return;
+
+	/* Clear the old menu */
+	if (plugins_action_group) {
+		gtk_ui_manager_remove_ui(gtkblist->ui, plugins_merge_id);
+		gtk_ui_manager_remove_action_group(gtkblist->ui, plugins_action_group);
+		g_object_unref(G_OBJECT(plugins_action_group));
+	}
+
+	plugins_action_group = gtk_action_group_new("PluginActions");
+#ifdef ENABLE_NLS
+	gtk_action_group_set_translation_domain(plugins_action_group, PACKAGE);
+#endif
+	plugins_ui = g_string_new(NULL);
 
 	/* Add a submenu for each plugin with custom actions */
 	for (l = purple_plugins_get_loaded(); l; l = l->next) {
-		char *path;
-
-		plugin = (PurplePlugin *) l->data;
+		char *name;
+
+		plugin = (PurplePlugin *)l->data;
 
 		if (PURPLE_IS_PROTOCOL_PLUGIN(plugin))
 			continue;
@@ -8155,28 +8305,35 @@
 		if (!PURPLE_PLUGIN_HAS_ACTIONS(plugin))
 			continue;
 
-		menuitem = gtk_image_menu_item_new_with_label(_(plugin->info->name));
-		gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem);
-
-		plugin_submenus = g_list_append(plugin_submenus, menuitem);
-
-		submenu = gtk_menu_new();
-		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-
-		gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
-		path = g_strdup_printf("%s/Tools/%s", gtkblist->ift->path, plugin->info->name);
-		gtk_menu_set_accel_path(GTK_MENU(submenu), path);
-		g_free(path);
-
-		build_plugin_actions(submenu, plugin, NULL);
-	}
-	gtk_widget_show_all(pluginmenu);
+		name = g_strdup_printf("plugin%d", count);
+		action = gtk_action_new(name, plugin->info->name, NULL, NULL);
+		gtk_action_group_add_action(plugins_action_group, action);
+		g_string_append_printf(plugins_ui, "<menu action='%s'>", name);
+
+		build_plugin_actions(plugins_action_group, plugins_ui, name, plugin, NULL);
+
+		g_string_append(plugins_ui, "</menu>");
+		count++;
+
+		g_free(name);
+	}
+
+	ui_string = g_strconcat("<ui><menubar action='BList'><menu action='ToolsMenu'><placeholder name='PluginActions'>",
+	                        plugins_ui->str,
+	                        "</placeholder></menu></menubar></ui>",
+	                        NULL);
+	gtk_ui_manager_insert_action_group(gtkblist->ui, plugins_action_group, 1);
+	plugins_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string, -1, NULL);
+purple_debug_info("blist", "The plugins menu is {%s}\n", ui_string);
+
+	g_string_free(plugins_ui, TRUE);
+	g_free(ui_string);
 }
 
 static void
-sortmethod_act(GtkCheckMenuItem *checkmenuitem, char *id)
-{
-	if (gtk_check_menu_item_get_active(checkmenuitem))
+sortmethod_act(GtkRadioAction *action, GtkRadioAction *current, char *id)
+{
+	if (action == current)
 	{
 		pidgin_set_cursor(gtkblist->window, GDK_WATCH);
 		/* This is redundant. I think. */
@@ -8190,40 +8347,57 @@
 void
 pidgin_blist_update_sort_methods(void)
 {
-	GtkWidget *menuitem = NULL, *activeitem = NULL;
 	PidginBlistSortMethod *method = NULL;
 	GList *l;
 	GSList *sl = NULL;
-	GtkWidget *sortmenu;
 	const char *m = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type");
 
-	if ((gtkblist == NULL) || (gtkblist->ift == NULL))
-		return;
-
-	g_return_if_fail(m != NULL);
-
-	sortmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Sort Buddies"));
-
-	if (sortmenu == NULL)
+	GtkRadioAction *action;
+	GString *ui_string;
+
+	if ((gtkblist == NULL) || (gtkblist->ui == NULL))
 		return;
 
 	/* Clear the old menu */
-	for (l = gtk_container_get_children(GTK_CONTAINER(sortmenu)); l; l = g_list_delete_link(l, l)) {
-		menuitem = l->data;
-		gtk_widget_destroy(GTK_WIDGET(menuitem));
-	}
+	if (sort_action_group) {
+		gtk_ui_manager_remove_ui(gtkblist->ui, sort_merge_id);
+		gtk_ui_manager_remove_action_group(gtkblist->ui, sort_action_group);
+		g_object_unref(G_OBJECT(sort_action_group));
+	}
+
+	sort_action_group = gtk_action_group_new("SortMethods");
+#ifdef ENABLE_NLS
+	gtk_action_group_set_translation_domain(sort_action_group, PACKAGE);
+#endif
+	ui_string = g_string_new("<ui><menubar name='BList'>"
+	                         "<menu action='BuddiesMenu'><menu action='SortMenu'>");
 
 	for (l = pidgin_blist_sort_methods; l; l = l->next) {
-		method = (PidginBlistSortMethod *) l->data;
-		menuitem = gtk_radio_menu_item_new_with_label(sl, _(method->name));
-		if (g_str_equal(m, method->id))
-			activeitem = menuitem;
-		sl = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
-		gtk_menu_shell_append(GTK_MENU_SHELL(sortmenu), menuitem);
-		g_signal_connect(G_OBJECT(menuitem), "toggled",
-				 G_CALLBACK(sortmethod_act), method->id);
-		gtk_widget_show(menuitem);
-	}
-	if (activeitem)
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(activeitem), TRUE);
-}
+		method = (PidginBlistSortMethod *)l->data;
+
+		g_string_append_printf(ui_string, "<menuitem action='%s'/>", method->id);
+		action = gtk_radio_action_new(method->id,
+		                              method->name,
+		                              NULL,
+		                              NULL,
+		                              0);
+		gtk_action_group_add_action_with_accel(sort_action_group, GTK_ACTION(action), NULL);
+
+		gtk_radio_action_set_group(action, sl);
+		sl = gtk_radio_action_get_group(action);
+
+		if (!strcmp(m, method->id))
+			gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
+		else
+			gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), FALSE);
+
+		g_signal_connect(G_OBJECT(action), "changed",
+		                 G_CALLBACK(sortmethod_act), method->id);
+	}
+
+	g_string_append(ui_string, "</menu></menu></menubar></ui>");
+	gtk_ui_manager_insert_action_group(gtkblist->ui, sort_action_group, 1);
+	sort_merge_id = gtk_ui_manager_add_ui_from_string(gtkblist->ui, ui_string->str, -1, NULL);
+
+	g_string_free(ui_string, TRUE);
+}
--- a/pidgin/gtkblist.h	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkblist.h	Wed Feb 02 23:26:42 2011 +0000
@@ -82,7 +82,7 @@
 
 	GtkCellRenderer *text_rend;
 
-	GtkItemFactory *ift;
+	GtkUIManager *ui;
 	GtkWidget *menutray;            /**< The menu tray widget. */
 	GtkWidget *menutrayicon;        /**< The menu tray icon. */
 
--- a/pidgin/gtkcellrendererexpander.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkcellrendererexpander.c	Wed Feb 02 23:26:42 2011 +0000
@@ -44,24 +44,23 @@
 static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass *class);
 static void pidgin_cell_renderer_expander_get_size   (GtkCellRenderer            *cell,
 						   GtkWidget                  *widget,
-						   GdkRectangle               *cell_area,
+						   const GdkRectangle         *cell_area,
 						   gint                       *x_offset,
 						   gint                       *y_offset,
 						   gint                       *width,
 						   gint                       *height);
 static void pidgin_cell_renderer_expander_render     (GtkCellRenderer            *cell,
-						   GdkWindow                  *window,
+						   cairo_t                  *cr,
 						   GtkWidget                  *widget,
-						   GdkRectangle               *background_area,
-						   GdkRectangle               *cell_area,
-						   GdkRectangle               *expose_area,
-						   guint                       flags);
+						   const GdkRectangle               *background_area,
+						   const GdkRectangle               *cell_area,
+						   GtkCellRendererState             flags);
 static gboolean pidgin_cell_renderer_expander_activate  (GtkCellRenderer            *r,
 						      GdkEvent                   *event,
 						      GtkWidget                  *widget,
 						      const gchar                *p,
-						      GdkRectangle               *bg,
-						      GdkRectangle               *cell,
+						      const GdkRectangle               *bg,
+						      const GdkRectangle               *cell,
 						      GtkCellRendererState        flags);
 static void  pidgin_cell_renderer_expander_finalize (GObject *gobject);
 
@@ -108,9 +107,10 @@
 
 static void pidgin_cell_renderer_expander_init (PidginCellRendererExpander *cellexpander)
 {
-	GTK_CELL_RENDERER(cellexpander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
-	GTK_CELL_RENDERER(cellexpander)->xpad = 0;
-	GTK_CELL_RENDERER(cellexpander)->ypad = 2;
+  g_object_set(G_OBJECT(cellexpander), "mode",
+               GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
+	/*GTK_CELL_RENDERER(cellexpander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;*/
+  gtk_cell_renderer_set_padding(GTK_CELL_RENDERER(cellexpander), 0, 2);
 }
 
 static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass *class)
@@ -190,7 +190,7 @@
 
 static void pidgin_cell_renderer_expander_get_size (GtkCellRenderer *cell,
 						 GtkWidget       *widget,
-						 GdkRectangle    *cell_area,
+						 const GdkRectangle    *cell_area,
 						 gint            *x_offset,
 						 gint            *y_offset,
 						 gint            *width,
@@ -199,11 +199,17 @@
 	gint calc_width;
 	gint calc_height;
 	gint expander_size;
-
+  gint xpad;
+  gint ypad;
+  gfloat xalign;
+  gfloat yalign;
+    
 	gtk_widget_style_get(widget, "expander-size", &expander_size, NULL);
 
-	calc_width = (gint) cell->xpad * 2 + expander_size;
-	calc_height = (gint) cell->ypad * 2 + expander_size;
+  gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
+  gtk_cell_renderer_get_alignment(cell, &xalign, &yalign); 
+	calc_width = (gint) xpad * 2 + expander_size;
+	calc_height = (gint) ypad * 2 + expander_size;
 
 	if (width)
 		*width = calc_width;
@@ -215,12 +221,12 @@
 		{
 			if (x_offset)
 				{
-					*x_offset = cell->xalign * (cell_area->width - calc_width);
+					*x_offset = xalign * (cell_area->width - calc_width);
 					*x_offset = MAX (*x_offset, 0);
 				}
 			if (y_offset)
 				{
-					*y_offset = cell->yalign * (cell_area->height - calc_height);
+					*y_offset = yalign * (cell_area->height - calc_height);
 					*y_offset = MAX (*y_offset, 0);
 				}
 		}
@@ -228,56 +234,64 @@
 
 
 static void pidgin_cell_renderer_expander_render(GtkCellRenderer *cell,
-					       GdkWindow       *window,
+					       cairo_t         *cr,
 					       GtkWidget       *widget,
-					       GdkRectangle    *background_area,
-					       GdkRectangle    *cell_area,
-					       GdkRectangle    *expose_area,
-					       guint            flags)
+					       const GdkRectangle    *background_area,
+					       const GdkRectangle    *cell_area,
+					       GtkCellRendererState  flags)
 {
 	PidginCellRendererExpander *cellexpander = (PidginCellRendererExpander *) cell;
 	gboolean set;
 	gint width, height;
 	GtkStateType state;
-
+  gint xpad;
+  gint ypad;
+  gboolean is_expanded;
+  GtkAllocation allocation;
+    
+  gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
+  g_object_get(G_OBJECT(cell), "is-expanded", &is_expanded, NULL);
+    
 	if (!cellexpander->is_expander)
 		return;
 
 	width = cell_area->width;
 	height = cell_area->height;
 
-	if (!cell->sensitive)
+	if (!gtk_widget_get_sensitive(widget))
 		state = GTK_STATE_INSENSITIVE;
 	else if (flags & GTK_CELL_RENDERER_PRELIT)
 		state = GTK_STATE_PRELIGHT;
-	else if (GTK_WIDGET_HAS_FOCUS (widget) && flags & GTK_CELL_RENDERER_SELECTED)
+	else if (gtk_widget_has_focus(widget) && flags & GTK_CELL_RENDERER_SELECTED)
 		state = GTK_STATE_ACTIVE;
 	else
 		state = GTK_STATE_NORMAL;
 
-	width -= cell->xpad*2;
-	height -= cell->ypad*2;
+	width -= xpad*2;
+	height -= ypad*2;
 
-	gtk_paint_expander (widget->style,
-			    window, state,
-			    NULL, widget, "treeview",
-			    cell_area->x + cell->xpad + (width / 2),
-			    cell_area->y + cell->ypad + (height / 2),
-			    cell->is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
+	gtk_paint_expander (gtk_widget_get_style(widget),
+			    cr, state,
+			    widget, "treeview",
+			    cell_area->x + xpad + (width / 2),
+			    cell_area->y + ypad + (height / 2),
+			    is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
 
 	/* only draw the line if the color isn't set - this prevents a bug where the hline appears only under the expander */
 	g_object_get(cellexpander, "cell-background-set", &set, NULL);
-	if (cell->is_expanded && !set)
-		gtk_paint_hline (widget->style, window, state, NULL, widget, NULL, 0,
-				 widget->allocation.width, cell_area->y + cell_area->height);
+  gtk_widget_get_allocation(widget, &allocation);
+
+  if (is_expanded && !set)
+		gtk_paint_hline (gtk_widget_get_style(widget), cr, state, widget, NULL, 0,
+				 allocation.width, cell_area->y + cell_area->height);
 }
 
 static gboolean pidgin_cell_renderer_expander_activate(GtkCellRenderer *r,
 						     GdkEvent *event,
 						     GtkWidget *widget,
 						     const gchar *p,
-						     GdkRectangle *bg,
-						     GdkRectangle *cell,
+						     const GdkRectangle *bg,
+						     const GdkRectangle *cell,
 						     GtkCellRendererState flags)
 {
 	GtkTreePath *path = gtk_tree_path_new_from_string(p);
--- a/pidgin/gtkconv.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkconv.c	Wed Feb 02 23:26:42 2011 +0000
@@ -160,7 +160,6 @@
 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
 static void update_typing_icon(PidginConversation *gtkconv);
 static void update_typing_message(PidginConversation *gtkconv, const char *message);
-static const char *item_factory_translate_func (const char *path, gpointer func_data);
 gboolean pidgin_conv_has_focus(PurpleConversation *conv);
 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
@@ -779,15 +778,17 @@
 	InviteBuddyInfo *info = (InviteBuddyInfo *)data;
 	const char *convprotocol;
 	gboolean success = TRUE;
-
+  GdkAtom target = gtk_selection_data_get_target(sd);
+    
 	convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv));
 
-	if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
+	if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
 	{
 		PurpleBlistNode *node = NULL;
 		PurpleBuddy *buddy;
-
-		memcpy(&node, sd->data, sizeof(node));
+    const guchar *data = gtk_selection_data_get_data(sd);
+      
+		memcpy(&node, data, sizeof(node));
 
 		if (PURPLE_BLIST_NODE_IS_CONTACT(node))
 			buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
@@ -806,15 +807,16 @@
 		else
 			gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy));
 
-		gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t);
-	}
-	else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE))
+		gtk_drag_finish(dc, success,
+      gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
+	}
+	else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
 	{
 		char *protocol = NULL;
 		char *username = NULL;
 		PurpleAccount *account;
 
-		if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account,
+		if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
 										&protocol, &username, NULL))
 		{
 			if (account == NULL)
@@ -839,7 +841,8 @@
 		g_free(username);
 		g_free(protocol);
 
-		gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t);
+		gtk_drag_finish(dc, success,
+      gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
 	}
 }
 
@@ -881,12 +884,15 @@
 		                                GTK_RESPONSE_OK);
 		gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE);
 		gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE);
+    /* TODO: set no separator using GTK+ 3.0 */
+    /*
 		gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE);
-
+    */
+    
 		info->window = GTK_WIDGET(invite_dialog);
 
 		/* Setup the outside spacing. */
-		vbox = GTK_DIALOG(invite_dialog)->vbox;
+		vbox = gtk_dialog_get_content_area(GTK_DIALOG(invite_dialog));
 
 		gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER);
 		gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE);
@@ -978,7 +984,7 @@
 }
 
 static void
-menu_new_conv_cb(gpointer data, guint action, GtkWidget *widget)
+menu_new_conv_cb(GtkAction *action, gpointer data)
 {
 	pidgin_dialogs_im();
 }
@@ -1025,7 +1031,7 @@
  * plaintext v. HTML file.
  */
 static void
-menu_save_as_cb(gpointer data, guint action, GtkWidget *widget)
+menu_save_as_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
@@ -1055,7 +1061,7 @@
 }
 
 static void
-menu_view_log_cb(gpointer data, guint action, GtkWidget *widget)
+menu_view_log_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1079,10 +1085,12 @@
 	gtkblist = pidgin_blist_get_default_gtk_blist();
 
 	cursor = gdk_cursor_new(GDK_WATCH);
-	gdk_window_set_cursor(gtkblist->window->window, cursor);
-	gdk_window_set_cursor(win->window->window, cursor);
+	gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), cursor);
+	gdk_window_set_cursor(gtk_widget_get_window(win->window), cursor);
 	gdk_cursor_unref(cursor);
+#if GTK_CHECK_VERSION(2,4,0) && !GTK_CHECK_VERSION(2,6,0) //FIXME: What?
 	gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
+#endif
 
 	name = purple_conversation_get_name(conv);
 	account = purple_conversation_get_account(conv);
@@ -1095,8 +1103,8 @@
 		{
 			pidgin_log_show_contact((PurpleContact *)node->parent);
 			g_slist_free(buddies);
-			gdk_window_set_cursor(gtkblist->window->window, NULL);
-			gdk_window_set_cursor(win->window->window, NULL);
+			gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
+			gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
 			return;
 		}
 	}
@@ -1104,12 +1112,12 @@
 
 	pidgin_log_show(type, name, account);
 
-	gdk_window_set_cursor(gtkblist->window->window, NULL);
-	gdk_window_set_cursor(win->window->window, NULL);
-}
-
-static void
-menu_clear_cb(gpointer data, guint action, GtkWidget *widget)
+	gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
+	gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
+}
+
+static void
+menu_clear_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1119,7 +1127,7 @@
 }
 
 static void
-menu_find_cb(gpointer data, guint action, GtkWidget *widget)
+menu_find_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *gtkwin = data;
 	PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin);
@@ -1129,7 +1137,7 @@
 
 #ifdef USE_VV
 static void
-menu_initiate_media_call_cb(gpointer data, guint action, GtkWidget *widget)
+menu_initiate_media_call_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = (PidginWindow *)data;
 	PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
@@ -1137,15 +1145,15 @@
 
 	purple_prpl_initiate_media(account,
 			purple_conversation_get_name(conv),
-			action == 0 ? PURPLE_MEDIA_AUDIO :
-			action == 1 ? PURPLE_MEDIA_VIDEO :
-			action == 2 ? PURPLE_MEDIA_AUDIO |
+			action == win->audio_call ? PURPLE_MEDIA_AUDIO :
+			action == win->video_call ? PURPLE_MEDIA_VIDEO :
+			action == win->audio_video_call ? PURPLE_MEDIA_AUDIO |
 			PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE);
 }
 #endif
 
 static void
-menu_send_file_cb(gpointer data, guint action, GtkWidget *widget)
+menu_send_file_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
@@ -1157,7 +1165,7 @@
 }
 
 static void
-menu_get_attention_cb(gpointer data, guint action, GtkWidget *widget)
+menu_get_attention_cb(GtkAction *ation, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
@@ -1169,7 +1177,7 @@
 }
 
 static void
-menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget)
+menu_add_pounce_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1181,7 +1189,7 @@
 }
 
 static void
-menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget)
+menu_insert_link_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PidginConversation *gtkconv;
@@ -1195,7 +1203,7 @@
 }
 
 static void
-menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget)
+menu_insert_image_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PidginConversation *gtkconv;
@@ -1210,7 +1218,7 @@
 
 
 static void
-menu_alias_cb(gpointer data, guint action, GtkWidget *widget)
+menu_alias_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1237,7 +1245,7 @@
 }
 
 static void
-menu_get_info_cb(gpointer data, guint action, GtkWidget *widget)
+menu_get_info_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1248,7 +1256,7 @@
 }
 
 static void
-menu_invite_cb(gpointer data, guint action, GtkWidget *widget)
+menu_invite_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1259,7 +1267,7 @@
 }
 
 static void
-menu_block_cb(gpointer data, guint action, GtkWidget *widget)
+menu_block_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1270,7 +1278,7 @@
 }
 
 static void
-menu_unblock_cb(gpointer data, guint action, GtkWidget *widget)
+menu_unblock_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1281,7 +1289,7 @@
 }
 
 static void
-menu_add_remove_cb(gpointer data, guint action, GtkWidget *widget)
+menu_add_remove_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1326,7 +1334,7 @@
 }
 
 static void
-menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget)
+menu_close_conv_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 
@@ -1334,7 +1342,7 @@
 }
 
 static void
-menu_logging_cb(gpointer data, guint action, GtkWidget *widget)
+menu_logging_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1346,7 +1354,7 @@
 	if (conv == NULL)
 		return;
 
-	logging = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+	logging = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
 
 	if (logging == purple_conversation_is_logging(conv))
 		return;
@@ -1399,14 +1407,14 @@
 }
 
 static void
-menu_toolbar_cb(gpointer data, guint action, GtkWidget *widget)
+menu_toolbar_cb(GtkAction *action, gpointer data)
 {
 	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar",
-	                    gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
-}
-
-static void
-menu_sounds_cb(gpointer data, guint action, GtkWidget *widget)
+	                    gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
+}
+
+static void
+menu_sounds_cb(GtkAction *action, gpointer data)
 {
 	PidginWindow *win = data;
 	PurpleConversation *conv;
@@ -1421,17 +1429,17 @@
 	gtkconv = PIDGIN_CONVERSATION(conv);
 
 	gtkconv->make_sound =
-		gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+		gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
 	node = get_conversation_blist_node(conv);
 	if (node)
 		purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound);
 }
 
 static void
-menu_timestamps_cb(gpointer data, guint action, GtkWidget *widget)
+menu_timestamps_cb(GtkAction *action, gpointer data)
 {
 	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps",
-		gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
+		gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
 }
 
 static void
@@ -1918,8 +1926,8 @@
 	/* If CTRL was held down... */
 	if (event->state & GDK_CONTROL_MASK) {
 		switch (event->keyval) {
-			case GDK_Page_Down:
- 			case GDK_KP_Page_Down:
+			case GDK_KEY_Page_Down:
+			case GDK_KEY_KP_Page_Down:
 			case ']':
 				if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1))
 					gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0);
@@ -1928,8 +1936,8 @@
 				return TRUE;
 				break;
 
-			case GDK_Page_Up:
- 			case GDK_KP_Page_Up:
+			case GDK_KEY_Page_Up:
+			case GDK_KEY_KP_Page_Up:
 			case '[':
 				if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1))
 					gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1);
@@ -1938,9 +1946,9 @@
 				return TRUE;
 				break;
 
-			case GDK_Tab:
-			case GDK_KP_Tab:
-			case GDK_ISO_Left_Tab:
+			case GDK_KEY_Tab:
+			case GDK_KEY_KP_Tab:
+			case GDK_KEY_ISO_Left_Tab:
 				if (event->state & GDK_SHIFT_MASK) {
 					move_to_next_unread_tab(gtkconv, FALSE);
 				} else {
@@ -1950,20 +1958,20 @@
 				return TRUE;
 				break;
 
-			case GDK_comma:
+			case GDK_KEY_comma:
 				gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
 						gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
 						curconv - 1);
 				return TRUE;
 				break;
 
-			case GDK_period:
+			case GDK_KEY_period:
 				gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
 						gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
 						(curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook)));
 				return TRUE;
 				break;
-			case GDK_F6:
+			case GDK_KEY_F6:
 				if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
 					return TRUE;
 				break;
@@ -1987,13 +1995,13 @@
 	else
 	{
 		switch (event->keyval) {
-		case GDK_F2:
+		case GDK_KEY_F2:
 			if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) {
 				infopane_entry_activate(gtkconv);
 				return TRUE;
 			}
 			break;
-		case GDK_F6:
+		case GDK_KEY_F6:
 			if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
 				return TRUE;
 			break;
@@ -2017,7 +2025,7 @@
 	/* If CTRL was held down... */
 	if (event->state & GDK_CONTROL_MASK) {
 		switch (event->keyval) {
-			case GDK_Up:
+			case GDK_KEY_Up:
 				if (!gtkconv->send_history)
 					break;
 
@@ -2068,7 +2076,7 @@
 				return TRUE;
 				break;
 
-			case GDK_Down:
+			case GDK_KEY_Down:
 				if (!gtkconv->send_history)
 					break;
 
@@ -2121,22 +2129,22 @@
 	/* If neither CTRL nor ALT were held down... */
 	else {
 		switch (event->keyval) {
-		case GDK_Tab:
-		case GDK_KP_Tab:
-		case GDK_ISO_Left_Tab:
+		case GDK_KEY_Tab:
+		case GDK_KEY_KP_Tab:
+		case GDK_KEY_ISO_Left_Tab:
 			if (gtkconv->entry != entry)
 				break;
 			return tab_complete(conv);
 			break;
 
-		case GDK_Page_Up:
- 		case GDK_KP_Page_Up:
+		case GDK_KEY_Page_Up:
+		case GDK_KEY_KP_Page_Up:
 			gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml));
 			return TRUE;
 			break;
 
-		case GDK_Page_Down:
- 		case GDK_KP_Page_Down:
+		case GDK_KEY_Page_Down:
+		case GDK_KEY_KP_Page_Down:
 			gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml));
 			return TRUE;
 			break;
@@ -2180,26 +2188,26 @@
 
 	/* If we have a valid key for the conversation display, then exit */
 	if ((event->state & GDK_CONTROL_MASK) ||
-		(event->keyval == GDK_F6) ||
-		(event->keyval == GDK_F10) ||
-		(event->keyval == GDK_Shift_L) ||
-		(event->keyval == GDK_Shift_R) ||
-		(event->keyval == GDK_Control_L) ||
-		(event->keyval == GDK_Control_R) ||
-		(event->keyval == GDK_Escape) ||
-		(event->keyval == GDK_Up) ||
-		(event->keyval == GDK_Down) ||
-		(event->keyval == GDK_Left) ||
-		(event->keyval == GDK_Right) ||
-		(event->keyval == GDK_Page_Up) ||
- 		(event->keyval == GDK_KP_Page_Up) ||
-		(event->keyval == GDK_Page_Down) ||
- 		(event->keyval == GDK_KP_Page_Down) ||
-		(event->keyval == GDK_Home) ||
-		(event->keyval == GDK_End) ||
-		(event->keyval == GDK_Tab) ||
-		(event->keyval == GDK_KP_Tab) ||
-		(event->keyval == GDK_ISO_Left_Tab))
+		(event->keyval == GDK_KEY_F6) ||
+		(event->keyval == GDK_KEY_F10) ||
+		(event->keyval == GDK_KEY_Shift_L) ||
+		(event->keyval == GDK_KEY_Shift_R) ||
+		(event->keyval == GDK_KEY_Control_L) ||
+		(event->keyval == GDK_KEY_Control_R) ||
+		(event->keyval == GDK_KEY_Escape) ||
+		(event->keyval == GDK_KEY_Up) ||
+		(event->keyval == GDK_KEY_Down) ||
+		(event->keyval == GDK_KEY_Left) ||
+		(event->keyval == GDK_KEY_Right) ||
+		(event->keyval == GDK_KEY_Page_Up) ||
+ 		(event->keyval == GDK_KEY_KP_Page_Up) ||
+		(event->keyval == GDK_KEY_Page_Down) ||
+		(event->keyval == GDK_KEY_KP_Page_Down) ||
+		(event->keyval == GDK_KEY_Home) ||
+		(event->keyval == GDK_KEY_End) ||
+		(event->keyval == GDK_KEY_Tab) ||
+		(event->keyval == GDK_KEY_KP_Tab) ||
+		(event->keyval == GDK_KEY_ISO_Left_Tab))
 	{
 		if (event->type == GDK_KEY_PRESS)
 			return conv_keypress_common(gtkconv, event);
@@ -2242,7 +2250,7 @@
 	gtkconv->active_conv = conv;
 
 	purple_conversation_set_logging(conv,
-		gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging)));
+		gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging)));
 
 	entry = GTK_IMHTML(gtkconv->entry);
 	protocol_name = purple_account_get_protocol_name(conv->account);
@@ -2667,7 +2675,7 @@
 }
 
 static void
-start_anim(GtkObject *obj, PidginConversation *gtkconv)
+start_anim(GtkWidget *widget, PidginConversation *gtkconv)
 {
 	int delay;
 
@@ -2840,7 +2848,7 @@
 }
 
 static void
-stop_anim(GtkObject *obj, PidginConversation *gtkconv)
+stop_anim(GtkWidget *widget, PidginConversation *gtkconv)
 {
 	if (gtkconv->u.im->icon_timer != 0)
 		g_source_remove(gtkconv->u.im->icon_timer);
@@ -2862,7 +2870,7 @@
 }
 
 static gboolean
-icon_menu(GtkObject *obj, GdkEventButton *e, PidginConversation *gtkconv)
+icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
 {
 	static GtkWidget *menu = NULL;
 	PurpleConversation *conv;
@@ -3056,6 +3064,101 @@
 	return gtkconv->win;
 }
 
+#if 1
+
+static GtkActionEntry menu_entries[] =
+/* TODO: fill out tooltips... */
+{
+	/* Conversation menu */
+	{ "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL },
+	{ "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) },
+	{ "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) },
+	{ "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) },
+	{ "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) },
+	{ "ClearScrollback", GTK_STOCK_CLEAR, N_("Clea_r Scrollback"), "<control>L", NULL, G_CALLBACK(menu_clear_cb) },
+
+#ifdef USE_VV
+	{ "MediaMenu", NULL, N_("M_edia"), NULL, NULL, NULL },
+	{ "AudioCall", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL, N_("_Audio Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
+	{ "VideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("_Video Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
+	{ "AudioVideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("Audio\\/Video _Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
+#endif
+
+	{ "SendFile", PIDGIN_STOCK_TOOLBAR_SEND_FILE, N_("Se_nd File..."), NULL, NULL, G_CALLBACK(menu_send_file_cb) },
+	{ "GetAttention", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, N_("Get _Attention"), NULL, NULL, G_CALLBACK(menu_get_attention_cb) },
+	{ "AddBuddyPounce", NULL, N_("Add Buddy _Pounce..."), NULL, NULL, G_CALLBACK(menu_add_pounce_cb) },
+	{ "GetInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("_Get Info"), "<control>O", NULL, G_CALLBACK(menu_get_info_cb) },
+	{ "Invite", NULL, N_("In_vite..."), NULL, NULL, G_CALLBACK(menu_invite_cb) },
+	{ "MoreMenu", NULL, N_("M_ore"), NULL, NULL, NULL },
+	{ "Alias", NULL, N_("Al_ias..."), NULL, NULL, G_CALLBACK(menu_alias_cb) },
+	{ "Block", PIDGIN_STOCK_TOOLBAR_BLOCK, N_("_Block..."), NULL, NULL, G_CALLBACK(menu_block_cb) },
+	{ "Unblock", PIDGIN_STOCK_TOOLBAR_UNBLOCK, N_("_Unblock..."), NULL, NULL, G_CALLBACK(menu_unblock_cb) },
+	{ "Add", GTK_STOCK_ADD, N_("_Add..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
+	{ "Remove", GTK_STOCK_REMOVE, N_("_Remove..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
+	{ "InsertLink", PIDGIN_STOCK_TOOLBAR_INSERT_LINK, N_("Insert Lin_k..."), NULL, NULL, G_CALLBACK(menu_insert_link_cb) },
+	{ "InsertImage", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, N_("Insert Imag_e..."), NULL, NULL, G_CALLBACK(menu_insert_image_cb) },
+	{ "Close", GTK_STOCK_CLOSE, N_("_Close"), NULL, NULL, G_CALLBACK(menu_close_conv_cb) },
+
+	/* Options */
+	{ "OptionsMenu", NULL, N_("_Options"), NULL, NULL, NULL },
+};
+
+/* Toggle items */
+static const GtkToggleActionEntry menu_toggle_entries[] = {
+	{ "EnableLogging", NULL, N_("Enable _Logging"), NULL, NULL, G_CALLBACK(menu_logging_cb), FALSE },
+	{ "EnableSounds", NULL, N_("Enable _Sounds"), NULL, NULL, G_CALLBACK(menu_sounds_cb), FALSE },
+	{ "ShowFormattingToolbars", NULL, N_("Show Formatting _Toolbars"), NULL, NULL, G_CALLBACK(menu_toolbar_cb), FALSE },
+	{ "ShowTimestamps", NULL, N_("Show Ti_mestamps"), NULL, NULL, G_CALLBACK(menu_timestamps_cb), FALSE },
+};
+
+static const char *conversation_menu =
+"<ui>"
+	"<menubar name='Conversation'>"
+		"<menu action='ConversationMenu'>"
+			"<menuitem action='NewInstantMessage'/>"
+			"<separator/>"
+			"<menuitem action='Find'/>"
+			"<menuitem action='ViewLog'/>"
+			"<menuitem action='SaveAs'/>"
+			"<menuitem action='ClearScrollback'/>"
+			"<separator/>"
+#ifdef USE_VV
+			"<menu action='MediaMenu'>"
+				"<menuitem action='AudioCall'/>"
+				"<menuitem action='VideoCall'/>"
+				"<menuitem action='AudioVideoCall'/>"
+			"</menu>"
+#endif
+			"<menuitem action='SendFile'/>"
+			"<menuitem action='GetAttention'/>"
+			"<menuitem action='AddBuddyPounce'/>"
+			"<menuitem action='GetInfo'/>"
+			"<menuitem action='Invite'/>"
+			"<menu action='MoreMenu'/>"
+			"<separator/>"
+			"<menuitem action='Alias'/>"
+			"<menuitem action='Block'/>"
+			"<menuitem action='Unblock'/>"
+			"<menuitem action='Add'/>"
+			"<menuitem action='Remove'/>"
+			"<separator/>"
+			"<menuitem action='InsertLink'/>"
+			"<menuitem action='InsertImage'/>"
+			"<separator/>"
+			"<menuitem action='Close'/>"
+		"</menu>"
+		"<menu action='OptionsMenu'>"
+			"<menuitem action='EnableLogging'/>"
+			"<menuitem action='EnableSounds'/>"
+			"<separator/>"
+			"<menuitem action='ShowFormattingToolbars'/>"
+			"<menuitem action='ShowTimestamps'/>"
+		"</menu>"
+	"</menubar>"
+"</ui>";
+
+#else
+
 static GtkItemFactoryEntry menu_items[] =
 {
 	/* Conversation menu */
@@ -3132,15 +3235,7 @@
 	{ N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL },
 	{ N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL },
 };
-
-static const int menu_item_count =
-sizeof(menu_items) / sizeof(*menu_items);
-
-static const char *
-item_factory_translate_func (const char *path, gpointer func_data)
-{
-	return _(path);
-}
+#endif
 
 static void
 sound_method_pref_changed_cb(const char *name, PurplePrefType type,
@@ -3151,19 +3246,18 @@
 
 	if (!strcmp(method, "none"))
 	{
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
-		                               FALSE);
-		gtk_widget_set_sensitive(win->menu.sounds, FALSE);
+		gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
+		                             FALSE);
+		gtk_action_set_sensitive(win->menu.sounds, FALSE);
 	}
 	else
 	{
 		PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win);
 
 		if (gtkconv != NULL)
-			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
-			                               gtkconv->make_sound);
-		gtk_widget_set_sensitive(win->menu.sounds, TRUE);
-
+			gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
+			                             gtkconv->make_sound);
+		gtk_action_set_sensitive(win->menu.sounds, TRUE);
 	}
 }
 
@@ -3291,25 +3385,25 @@
 				purple_prpl_get_media_caps(account,
 				purple_conversation_get_name(conv));
 
-		gtk_widget_set_sensitive(win->audio_call,
+		gtk_action_set_sensitive(win->audio_call,
 				caps & PURPLE_MEDIA_CAPS_AUDIO
 				? TRUE : FALSE);
-		gtk_widget_set_sensitive(win->video_call,
+		gtk_action_set_sensitive(win->video_call,
 				caps & PURPLE_MEDIA_CAPS_VIDEO
 				? TRUE : FALSE);
-		gtk_widget_set_sensitive(win->audio_video_call,
+		gtk_action_set_sensitive(win->audio_video_call,
 				caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO
 				? TRUE : FALSE);
 	} else if (purple_conversation_get_type(conv)
 			== PURPLE_CONV_TYPE_CHAT) {
 		/* for now, don't care about chats... */
-		gtk_widget_set_sensitive(win->audio_call, FALSE);
-		gtk_widget_set_sensitive(win->video_call, FALSE);
-		gtk_widget_set_sensitive(win->audio_video_call, FALSE);
+		gtk_action_set_sensitive(win->audio_call, FALSE);
+		gtk_action_set_sensitive(win->video_call, FALSE);
+		gtk_action_set_sensitive(win->audio_video_call, FALSE);
 	} else {
-		gtk_widget_set_sensitive(win->audio_call, FALSE);
-		gtk_widget_set_sensitive(win->video_call, FALSE);
-		gtk_widget_set_sensitive(win->audio_video_call, FALSE);
+		gtk_action_set_sensitive(win->audio_call, FALSE);
+		gtk_action_set_sensitive(win->video_call, FALSE);
+		gtk_action_set_sensitive(win->audio_video_call, FALSE);
 	}
 #endif
 }
@@ -3317,6 +3411,8 @@
 static void
 regenerate_options_items(PidginWindow *win)
 {
+#if GTK_CHECK_VERSION(2,6,0)
+#else
 	GtkWidget *menu;
 	PidginConversation *gtkconv;
 	GList *list;
@@ -3340,6 +3436,7 @@
 	}
 
 	gtk_widget_show_all(menu);
+#endif
 }
 
 static void
@@ -3353,6 +3450,8 @@
 static void
 regenerate_plugins_items(PidginWindow *win)
 {
+#if GTK_CHECK_VERSION(2,6,0)
+#else
 	GList *action_items;
 	GtkWidget *menu;
 	GList *list;
@@ -3394,8 +3493,10 @@
 		g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win);
 	}
 	g_object_set_data(G_OBJECT(win->window), "plugin-actions", action_items);
-}
-
+#endif
+}
+
+#if 0
 static void menubar_activated(GtkWidget *item, gpointer data)
 {
 	PidginWindow *win = data;
@@ -3419,134 +3520,145 @@
 	g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar),
 				G_CALLBACK(focus_out_from_menubar), win);
 }
+#endif
 
 static GtkWidget *
 setup_menubar(PidginWindow *win)
 {
 	GtkAccelGroup *accel_group;
 	const char *method;
-	GtkWidget *menuitem;
-
-	accel_group = gtk_accel_group_new ();
+	GtkActionGroup *action_group;
+	GError *error;
+
+	action_group = gtk_action_group_new("ConversationActions");
+	gtk_action_group_add_actions(action_group,
+	                             menu_entries,
+	                             G_N_ELEMENTS(menu_entries),
+	                             win);
+	gtk_action_group_add_toggle_actions(action_group,
+	                                    menu_toggle_entries,
+	                                    G_N_ELEMENTS(menu_toggle_entries),
+	                                    win);
+#ifdef ENABLE_NLS
+	gtk_action_group_set_translation_domain(action_group,
+	                                        PACKAGE);
+#endif
+
+	win->menu.ui = gtk_ui_manager_new();
+	gtk_ui_manager_insert_action_group(win->menu.ui, action_group, 0);
+
+	accel_group = gtk_ui_manager_get_accel_group(win->menu.ui);
 	gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group);
-	g_object_unref(accel_group);
-
-	win->menu.item_factory =
-		gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
-
-	gtk_item_factory_set_translate_func(win->menu.item_factory,
-	                                    (GtkTranslateFunc)item_factory_translate_func,
-	                                    NULL, NULL);
-
-	gtk_item_factory_create_items(win->menu.item_factory, menu_item_count,
-	                              menu_items, win);
 	g_signal_connect(G_OBJECT(accel_group), "accel-changed",
 	                 G_CALLBACK(pidgin_save_accels_cb), NULL);
 
-	/* Make sure the 'Conversation -> More' menuitems are regenerated whenever
-	 * the 'Conversation' menu pops up because the entries can change after the
-	 * conversation is created. */
-	menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation"));
-	g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win);
+	error = NULL;
+	if (!gtk_ui_manager_add_ui_from_string(win->menu.ui, conversation_menu, -1, &error))
+	{
+		g_message("building menus failed: %s", error->message);
+		g_error_free(error);
+		exit(EXIT_FAILURE);
+	}
 
 	win->menu.menubar =
-		gtk_item_factory_get_widget(win->menu.item_factory, "<main>");
+		gtk_ui_manager_get_widget(win->menu.ui, "/Conversation");
 
 	win->menu.view_log =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/View Log"));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/ViewLog");
 
 #ifdef USE_VV
 	win->audio_call =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-					    N_("/Conversation/Media/Audio Call"));
+		gtk_ui_manager_get_action(win->menu.ui,
+					    "/Conversation/ConversationMenu/MediaMenu/AudioCall");
 	win->video_call =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-					    N_("/Conversation/Media/Video Call"));
+		gtk_ui_manager_get_action(win->menu.ui,
+					    "/Conversation/ConversationMenu/MediaMenu/VideoCall");
 	win->audio_video_call =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-					    N_("/Conversation/Media/Audio\\/Video Call"));
+		gtk_ui_manager_get_action(win->menu.ui,
+					    "/Conversation/ConversationMenu/MediaMenu/AudioVideoCall");
 #endif
 
 	/* --- */
 
 	win->menu.send_file =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/Send File..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/SendFile");
 
 	g_object_set_data(G_OBJECT(win->window), "get_attention",
-		gtk_item_factory_get_widget(win->menu.item_factory,
-			                    N_("/Conversation/Get Attention")));
+		gtk_ui_manager_get_action(win->menu.ui,
+			"/Conversation/ConversationMenu/GetAttention"));
+
 	win->menu.add_pounce =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/Add Buddy Pounce..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/AddBuddyPounce");
 
 	/* --- */
 
 	win->menu.get_info =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/Get Info"));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/GetInfo");
 
 	win->menu.invite =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/Invite..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/Invite");
 
 	/* --- */
 
 	win->menu.alias =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/Alias..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/Alias");
 
 	win->menu.block =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/Block..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/Block");
 
 	win->menu.unblock =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-					    N_("/Conversation/Unblock..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+					    "/Conversation/ConversationMenu/Unblock");
 
 	win->menu.add =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/Add..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/Add");
 
 	win->menu.remove =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Conversation/Remove..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/ConversationMenu/Remove");
 
 	/* --- */
 
 	win->menu.insert_link =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-				N_("/Conversation/Insert Link..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+				"/Conversation/ConversationMenu/InsertLink");
 
 	win->menu.insert_image =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-				N_("/Conversation/Insert Image..."));
+		gtk_ui_manager_get_action(win->menu.ui,
+				"/Conversation/ConversationMenu/InsertImage");
 
 	/* --- */
 
 	win->menu.logging =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Options/Enable Logging"));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/OptionsMenu/EnableLogging");
 	win->menu.sounds =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Options/Enable Sounds"));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/OptionsMenu/EnableSounds");
 	method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
 	if (method != NULL && !strcmp(method, "none"))
 	{
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
+		gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
 		                               FALSE);
-		gtk_widget_set_sensitive(win->menu.sounds, FALSE);
+		gtk_action_set_sensitive(win->menu.sounds, FALSE);
 	}
 	purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method",
 				    sound_method_pref_changed_cb, win);
 
 	win->menu.show_formatting_toolbar =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Options/Show Formatting Toolbars"));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/OptionsMenu/ShowFormattingToolbars");
 	win->menu.show_timestamps =
-		gtk_item_factory_get_widget(win->menu.item_factory,
-		                            N_("/Options/Show Timestamps"));
+		gtk_ui_manager_get_action(win->menu.ui,
+		                          "/Conversation/OptionsMenu/ShowTimestamps");
 	win->menu.show_icon = NULL;
 
 	win->menu.tray = pidgin_menu_tray_new();
@@ -3727,7 +3839,7 @@
 	if (!(b = purple_find_buddy(account, conv->name)))
 		return FALSE;
 
-
+#if 0 /* TODO */
 	gtk_widget_show(win->menu.send_to);
 
 	menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to));
@@ -3749,6 +3861,7 @@
 			break;
 		}
 	}
+#endif
 
 	return FALSE;
 }
@@ -3858,6 +3971,7 @@
 static void
 generate_send_to_items(PidginWindow *win)
 {
+#if 0 /* TODO */
 	GtkWidget *menu;
 	GSList *group = NULL;
 	GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
@@ -3942,6 +4056,7 @@
 	if (!group)
 		gtk_widget_set_sensitive(win->menu.send_to, FALSE);
 	update_send_to_selection(win);
+#endif
 }
 
 static const char *
@@ -4560,13 +4675,22 @@
 	GdkRectangle oneline;
 	int height, diff;
 	int pad_top, pad_inside, pad_bottom;
-	int total_height = (gtkconv->imhtml->allocation.height + gtkconv->entry->allocation.height);
-	int max_height = total_height / 2;
+	int total_height;
+	int max_height;
 	int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines");
 	int min_height;
 	gboolean interior_focus;
 	int focus_width;
-
+	GtkAllocation imhtml_allocation;
+	GtkAllocation entry_allocation;
+	GtkAllocation lower_hbox_allocation;
+    
+	gtk_widget_get_allocation(gtkconv->imhtml, &imhtml_allocation);
+	gtk_widget_get_allocation(gtkconv->entry, &entry_allocation);
+	gtk_widget_get_allocation(gtkconv->lower_hbox, &lower_hbox_allocation);
+	total_height = imhtml_allocation.height + entry_allocation.height;
+	max_height = total_height / 2;
+    
 	pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry));
 	pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry));
 	pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry));
@@ -4599,12 +4723,15 @@
 	if (!interior_focus)
 		height += 2 * focus_width;
 
-	diff = height - gtkconv->entry->allocation.height;
+	diff = height - entry_allocation.height;
 	if (ABS(diff) < oneline.height / 2)
 		return FALSE;
 
+	purple_debug_info("pidgin", "resizing to %d, %d lines, diff %d\n",
+	                  diff + lower_hbox_allocation.height, min_lines, diff);
+
 	gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
-		diff + gtkconv->lower_hbox->allocation.height);
+		diff + lower_hbox_allocation.height);
 
 	return FALSE;
 }
@@ -4651,7 +4778,7 @@
 		if(prpl_info->set_chat_topic == NULL) {
 			gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE);
 		} else {
-			g_signal_connect(GTK_OBJECT(gtkchat->topic_text), "activate",
+			g_signal_connect(GTK_WIDGET(gtkchat->topic_text), "activate",
 					G_CALLBACK(topic_callback), gtkconv);
 		}
 
@@ -4826,7 +4953,7 @@
 	gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
 
 	gtk_imhtml_search_clear(GTK_IMHTML(gtkconv->imhtml));
-	gtk_widget_hide_all(gtkconv->quickfind.container);
+	gtk_widget_hide(gtkconv->quickfind.container);
 
 	gtk_widget_grab_focus(gtkconv->entry);
 	return TRUE;
@@ -4836,8 +4963,8 @@
 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv)
 {
 	switch (event->keyval) {
-		case GDK_Return:
-		case GDK_KP_Enter:
+		case GDK_KEY_Return:
+		case GDK_KEY_KP_Enter:
 			if (gtk_imhtml_search_find(GTK_IMHTML(gtkconv->imhtml), gtk_entry_get_text(GTK_ENTRY(entry)))) {
 				gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
 			} else {
@@ -4848,7 +4975,7 @@
 				gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col);
 			}
 			break;
-		case GDK_Escape:
+		case GDK_KEY_Escape:
 			pidgin_conv_end_quickfind(gtkconv);
 			break;
 		default:
@@ -4867,8 +4994,12 @@
 
 	close = pidgin_create_small_button(gtk_label_new("×"));
 	gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0);
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(close, _("Close Find bar"));
+#else
 	gtk_tooltips_set_tip(gtkconv->tooltips, close,
 	                     _("Close Find bar"), NULL);
+#endif
 
 	label = gtk_label_new(_("Find:"));
 	gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10);
@@ -5087,8 +5218,10 @@
 	PurpleAccount *convaccount = purple_conversation_get_account(conv);
 	PurpleConnection *gc = purple_account_get_connection(convaccount);
 	PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
-
-	if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
+  GdkAtom target = gtk_selection_data_get_target(sd);
+  const guchar *data = gtk_selection_data_get_data(sd);
+    
+	if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
 	{
 		PurpleBlistNode *n = NULL;
 		PurpleBuddy *b;
@@ -5096,7 +5229,7 @@
 		PurpleAccount *buddyaccount;
 		const char *buddyname;
 
-		n = *(PurpleBlistNode **)sd->data;
+		n = *(PurpleBlistNode **) data;
 
 		if (PURPLE_BLIST_NODE_IS_CONTACT(n))
 			b = purple_contact_get_priority_buddy((PurpleContact*)n);
@@ -5144,16 +5277,17 @@
 			pidgin_conv_window_switch_gtkconv(win, gtkconv);
 		}
 
-		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
-	}
-	else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE))
+		gtk_drag_finish(dc, TRUE,
+      gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
+	}
+	else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
 	{
 		char *protocol = NULL;
 		char *username = NULL;
 		PurpleAccount *account;
 		PidginConversation *gtkconv;
 
-		if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account,
+		if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
 						&protocol, &username, NULL))
 		{
 			if (account == NULL)
@@ -5184,12 +5318,14 @@
 		g_free(username);
 		g_free(protocol);
 
-		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
-	}
-	else if (sd->target == gdk_atom_intern("text/uri-list", FALSE)) {
+		gtk_drag_finish(dc, TRUE,
+      gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
+	}
+	else if (target == gdk_atom_intern("text/uri-list", FALSE)) {
 		if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
 			pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv));
-		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
+		gtk_drag_finish(dc, TRUE,
+      gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
 	}
 	else
 		gtk_drag_finish(dc, FALSE, FALSE, t);
@@ -5324,7 +5460,9 @@
 	gtkconv->send_history = g_list_append(NULL, NULL);
 
 	/* Setup some initial variables. */
+#if !GTK_CHECK_VERSION(2,12,0)
 	gtkconv->tooltips = gtk_tooltips_new();
+#endif
 	gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
 	gtkconv->unseen_count = 0;
 
@@ -5527,7 +5665,9 @@
 		g_free(gtkconv->u.chat);
 	}
 
+#if !GTK_CHECK_VERSION(2,12,0)
 	gtk_object_sink(GTK_OBJECT(gtkconv->tooltips));
+#endif
 
 	gtkconv->send_history = g_list_first(gtkconv->send_history);
 	g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL);
@@ -5591,21 +5731,28 @@
 		GdkEventButton *btn_event = (GdkEventButton*) event;
 		PurpleConversation *conv = data;
 		char *buddyname;
-
+    gchar *name;
+
+    g_object_get(G_OBJECT(tag), "name", &name, NULL);
+          
 		/* strlen("BUDDY " or "HILIT ") == 6 */
-		g_return_val_if_fail((tag->name != NULL)
-				&& (strlen(tag->name) > 6), FALSE);
-
-		buddyname = (tag->name) + 6;
-
+		g_return_val_if_fail((name != NULL) && (strlen(name) > 6), FALSE);
+
+		buddyname = name + 6;
+
+    
 		if (btn_event->button == 1 &&
 				event->type == GDK_2BUTTON_PRESS) {
 			chat_do_im(PIDGIN_CONVERSATION(conv), buddyname);
+      g_free(name);
+
 			return TRUE;
 		} else if (btn_event->button == 2
 				&& event->type == GDK_2BUTTON_PRESS) {
 			chat_do_info(PIDGIN_CONVERSATION(conv), buddyname);
 
+      g_free(name);
+            
 			return TRUE;
 		} else if (btn_event->button == 3
 				&& event->type == GDK_BUTTON_PRESS) {
@@ -5627,10 +5774,14 @@
 						btn_event->button,
 						btn_event->time);
 
+        g_free(name);
+ 
 				/* Don't propagate the event any further */
 				return TRUE;
 			}
 		}
+
+    g_free(name);
 	}
 
 	return FALSE;
@@ -6472,57 +6623,57 @@
 		/* Show stuff that applies to IMs, hide stuff that applies to chats */
 
 		/* Deal with menu items */
-		gtk_widget_show(win->menu.view_log);
-		gtk_widget_show(win->menu.send_file);
-		gtk_widget_show(g_object_get_data(G_OBJECT(win->window), "get_attention"));
-		gtk_widget_show(win->menu.add_pounce);
-		gtk_widget_show(win->menu.get_info);
-		gtk_widget_hide(win->menu.invite);
-		gtk_widget_show(win->menu.alias);
+		gtk_action_set_visible(win->menu.view_log, TRUE);
+		gtk_action_set_visible(win->menu.send_file, TRUE);
+		gtk_action_set_visible(GTK_ACTION(g_object_get_data(G_OBJECT(win->window), "get_attention")), TRUE);
+		gtk_action_set_visible(win->menu.add_pounce, TRUE);
+		gtk_action_set_visible(win->menu.get_info, TRUE);
+		gtk_action_set_visible(win->menu.invite, FALSE);
+		gtk_action_set_visible(win->menu.alias, TRUE);
  		if (purple_privacy_check(account, purple_conversation_get_name(conv))) {
- 			gtk_widget_hide(win->menu.unblock);
- 			gtk_widget_show(win->menu.block);
+ 			gtk_action_set_visible(win->menu.unblock, FALSE);
+ 			gtk_action_set_visible(win->menu.block, TRUE);
  		} else {
- 			gtk_widget_hide(win->menu.block);
- 			gtk_widget_show(win->menu.unblock);
+ 			gtk_action_set_visible(win->menu.block, FALSE);
+ 			gtk_action_set_visible(win->menu.unblock, TRUE);
  		}
 
 		if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
-			gtk_widget_show(win->menu.add);
-			gtk_widget_hide(win->menu.remove);
+			gtk_action_set_visible(win->menu.add, TRUE);
+			gtk_action_set_visible(win->menu.remove, FALSE);
 		} else {
-			gtk_widget_show(win->menu.remove);
-			gtk_widget_hide(win->menu.add);
-		}
-
-		gtk_widget_show(win->menu.insert_link);
-		gtk_widget_show(win->menu.insert_image);
+			gtk_action_set_visible(win->menu.remove, TRUE);
+			gtk_action_set_visible(win->menu.add, FALSE);
+		}
+
+		gtk_action_set_visible(win->menu.insert_link, TRUE);
+		gtk_action_set_visible(win->menu.insert_image, TRUE);
 	} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
 		/* Show stuff that applies to Chats, hide stuff that applies to IMs */
 
 		/* Deal with menu items */
-		gtk_widget_show(win->menu.view_log);
-		gtk_widget_hide(win->menu.send_file);
-		gtk_widget_hide(g_object_get_data(G_OBJECT(win->window), "get_attention"));
-		gtk_widget_hide(win->menu.add_pounce);
-		gtk_widget_hide(win->menu.get_info);
-		gtk_widget_show(win->menu.invite);
-		gtk_widget_show(win->menu.alias);
-		gtk_widget_hide(win->menu.block);
-		gtk_widget_hide(win->menu.unblock);
+		gtk_action_set_visible(win->menu.view_log, TRUE);
+		gtk_action_set_visible(win->menu.send_file, FALSE);
+		gtk_action_set_visible(g_object_get_data(G_OBJECT(win->window), "get_attention"), FALSE);
+		gtk_action_set_visible(win->menu.add_pounce, FALSE);
+		gtk_action_set_visible(win->menu.get_info, FALSE);
+		gtk_action_set_visible(win->menu.invite, TRUE);
+		gtk_action_set_visible(win->menu.alias, TRUE);
+		gtk_action_set_visible(win->menu.block, FALSE);
+		gtk_action_set_visible(win->menu.unblock, FALSE);
 
 		if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) {
 			/* If the chat is NOT in the buddy list */
-			gtk_widget_show(win->menu.add);
-			gtk_widget_hide(win->menu.remove);
+			gtk_action_set_visible(win->menu.add, TRUE);
+			gtk_action_set_visible(win->menu.remove, FALSE);
 		} else {
 			/* If the chat IS in the buddy list */
-			gtk_widget_hide(win->menu.add);
-			gtk_widget_show(win->menu.remove);
-		}
-
-		gtk_widget_show(win->menu.insert_link);
-		gtk_widget_show(win->menu.insert_image);
+			gtk_action_set_visible(win->menu.add, FALSE);
+			gtk_action_set_visible(win->menu.remove, TRUE);
+		}
+
+		gtk_action_set_visible(win->menu.insert_link, TRUE);
+		gtk_action_set_visible(win->menu.insert_image, TRUE);
 	}
 
 	/*
@@ -6567,30 +6718,30 @@
 			gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account));
 
 		/* Deal with menu items */
-		gtk_widget_set_sensitive(win->menu.view_log, TRUE);
-		gtk_widget_set_sensitive(win->menu.add_pounce, TRUE);
-		gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
-		gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
-		gtk_widget_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML));
-		gtk_widget_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES));
+		gtk_action_set_sensitive(win->menu.view_log, TRUE);
+		gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
+		gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
+		gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
+		gtk_action_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML));
+		gtk_action_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES));
 
 		if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
 		{
-			gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
-			gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
-			gtk_widget_set_sensitive(win->menu.send_file,
+			gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
+			gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
+			gtk_action_set_sensitive(win->menu.send_file,
 									 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
 									  prpl_info->can_receive_file(gc, purple_conversation_get_name(conv)))));
-			gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL));
-			gtk_widget_set_sensitive(win->menu.alias,
+			gtk_action_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL));
+			gtk_action_set_sensitive(win->menu.alias,
 									 (account != NULL) &&
 									 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
 		}
 		else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
 		{
-			gtk_widget_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
-			gtk_widget_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
-			gtk_widget_set_sensitive(win->menu.alias,
+			gtk_action_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
+			gtk_action_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
+			gtk_action_set_sensitive(win->menu.alias,
 									 (account != NULL) &&
 									 (purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL));
 		}
@@ -6600,18 +6751,18 @@
 		/* Or it's a chat that we've left. */
 
 		/* Then deal with menu items */
-		gtk_widget_set_sensitive(win->menu.view_log, TRUE);
-		gtk_widget_set_sensitive(win->menu.send_file, FALSE);
-		gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window),
+		gtk_action_set_sensitive(win->menu.view_log, TRUE);
+		gtk_action_set_sensitive(win->menu.send_file, FALSE);
+		gtk_action_set_sensitive(g_object_get_data(G_OBJECT(win->window),
 			"get_attention"), FALSE);
-		gtk_widget_set_sensitive(win->menu.add_pounce, TRUE);
-		gtk_widget_set_sensitive(win->menu.get_info, FALSE);
-		gtk_widget_set_sensitive(win->menu.invite, FALSE);
-		gtk_widget_set_sensitive(win->menu.alias, FALSE);
-		gtk_widget_set_sensitive(win->menu.add, FALSE);
-		gtk_widget_set_sensitive(win->menu.remove, FALSE);
-		gtk_widget_set_sensitive(win->menu.insert_link, TRUE);
-		gtk_widget_set_sensitive(win->menu.insert_image, FALSE);
+		gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
+		gtk_action_set_sensitive(win->menu.get_info, FALSE);
+		gtk_action_set_sensitive(win->menu.invite, FALSE);
+		gtk_action_set_sensitive(win->menu.alias, FALSE);
+		gtk_action_set_sensitive(win->menu.add, FALSE);
+		gtk_action_set_sensitive(win->menu.remove, FALSE);
+		gtk_action_set_sensitive(win->menu.insert_link, TRUE);
+		gtk_action_set_sensitive(win->menu.insert_image, FALSE);
 	}
 
 	/*
@@ -6691,8 +6842,13 @@
 			topic = purple_conv_chat_get_topic(chat);
 
 			gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
+#if GTK_CHECK_VERSION(2,12,0)
+			gtk_widget_set_tooltip_text(gtkchat->topic_text,
+			                            topic ? topic : "");
+#else
 			gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text,
 			                     topic ? topic : "", NULL);
+#endif
 		}
 	}
 
@@ -6752,7 +6908,7 @@
 		if (title != markup)
 			g_free(markup);
 
-		if (!GTK_WIDGET_REALIZED(gtkconv->tab_label))
+		if (!gtk_widget_get_realized(gtkconv->tab_label))
 			gtk_widget_realize(gtkconv->tab_label);
 
 		accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont);
@@ -7127,11 +7283,14 @@
 {
 	gint pane_x, pane_y, x_rel;
 	PidginConversation *gtkconv;
-
-	gdk_window_get_origin(win->notebook->window, &pane_x, &pane_y);
+  GtkAllocation allocation;
+
+  gtk_widget_get_allocation(gtkconv->infopane, &allocation);
+	gdk_window_get_origin(gtk_widget_get_window(win->notebook),
+                        &pane_x, &pane_y);
 	x_rel = x - pane_x;
 	gtkconv = pidgin_conv_window_get_active_gtkconv(win);
-	return (x_rel > gtkconv->infopane->allocation.x + gtkconv->infopane->allocation.width / 2);
+	return (x_rel > allocation.x + allocation.width / 2);
 }
 
 int
@@ -7149,7 +7308,7 @@
 
 	notebook = GTK_NOTEBOOK(win->notebook);
 
-	gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y);
+	gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
 	x_rel = x - nb_x;
 	y_rel = y - nb_y;
 
@@ -7159,30 +7318,32 @@
 	count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
 
 	for (i = 0; i < count; i++) {
+    	GtkAllocation allocation;
 
 		page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
 		tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
+		gtk_widget_get_allocation(tab, &allocation);
 
 		/* Make sure the tab is not hidden beyond an arrow */
-		if (!GTK_WIDGET_DRAWABLE(tab) && gtk_notebook_get_show_tabs(notebook))
+		if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook))
 			continue;
 
 		if (horiz) {
-			if (x_rel >= tab->allocation.x - PIDGIN_HIG_BOX_SPACE &&
-					x_rel <= tab->allocation.x + tab->allocation.width + PIDGIN_HIG_BOX_SPACE) {
+			if (x_rel >= allocation.x - PIDGIN_HIG_BOX_SPACE &&
+					x_rel <= allocation.x + allocation.width + PIDGIN_HIG_BOX_SPACE) {
 				page_num = i;
 
-				if (to_right && x_rel >= tab->allocation.x + tab->allocation.width/2)
+				if (to_right && x_rel >= allocation.x + allocation.width/2)
 					*to_right = TRUE;
 
 				break;
 			}
 		} else {
-			if (y_rel >= tab->allocation.y - PIDGIN_HIG_BOX_SPACE &&
-					y_rel <= tab->allocation.y + tab->allocation.height + PIDGIN_HIG_BOX_SPACE) {
+			if (y_rel >= allocation.y - PIDGIN_HIG_BOX_SPACE &&
+					y_rel <= allocation.y + allocation.height + PIDGIN_HIG_BOX_SPACE) {
 				page_num = i;
 
-				if (to_right && y_rel >= tab->allocation.y + tab->allocation.height/2)
+				if (to_right && y_rel >= allocation.y + allocation.height/2)
 					*to_right = TRUE;
 
 				break;
@@ -7289,8 +7450,8 @@
 		gtkconv = PIDGIN_CONVERSATION(conv);
 		win     = gtkconv->win;
 
-		gtk_check_menu_item_set_active(
-		        GTK_CHECK_MENU_ITEM(win->menu.show_timestamps),
+		gtk_toggle_action_set_active(
+		        GTK_TOGGLE_ACTION(win->menu.show_timestamps),
 		        (gboolean)GPOINTER_TO_INT(value));
 
 		gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
@@ -7317,8 +7478,8 @@
 		gtkconv = PIDGIN_CONVERSATION(conv);
 		win     = gtkconv->win;
 
-		gtk_check_menu_item_set_active(
-		        GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar),
+		gtk_toggle_action_set_active(
+		        GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
 		        (gboolean)GPOINTER_TO_INT(value));
 
 		if ((gboolean)GPOINTER_TO_INT(value))
@@ -8272,11 +8433,15 @@
 	gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog),
 	                               6);
 	gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE);
-	gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog),
+
+  /* TODO: figure out how to set no separator in GTK+ 3.0 */
+  /*
+  gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog),
 	                             FALSE);
-
+  */
+                               
 	/* Setup the outside spacing. */
-	vbox = GTK_DIALOG(warn_close_dialog)->vbox;
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(warn_close_dialog));
 
 	gtk_box_set_spacing(GTK_BOX(vbox), 12);
 	gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
@@ -8430,7 +8595,7 @@
 	   always be true after a button press. */
 	if (!gdk_pointer_is_grabbed())
 #endif
-		gdk_pointer_grab(gtkwin->notebook->window, FALSE,
+		gdk_pointer_grab(gtk_widget_get_window(gtkwin->notebook), FALSE,
 		                 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
 		                 NULL, cursor, GDK_CURRENT_TIME);
 }
@@ -8550,19 +8715,22 @@
 
 	if (e->button == 1) {
 		int nb_x, nb_y;
-
+    GtkAllocation allocation;
+
+    gtk_widget_get_allocation(gtkconv->infopane_hbox, &allocation);
+      
 		if (gtkconv->win->in_drag)
 			return TRUE;
 
 		gtkconv->win->in_predrag = TRUE;
 		gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont);
 
-		gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y);
-
-		gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x;
-		gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y;
-		gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x;
-		gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y;
+		gdk_window_get_origin(gtk_widget_get_window(gtkconv->infopane_hbox), &nb_x, &nb_y);
+
+		gtkconv->win->drag_min_x = allocation.x + nb_x;
+		gtkconv->win->drag_min_y = allocation.y + nb_y;
+		gtkconv->win->drag_max_x = allocation.width + gtkconv->win->drag_min_x;
+		gtkconv->win->drag_max_y = allocation.height + gtkconv->win->drag_min_y;
 
 		gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event",
 								    G_CALLBACK(notebook_motion_cb), gtkconv->win);
@@ -8575,6 +8743,7 @@
 		/* Right click was pressed. Popup the context menu. */
 		GtkWidget *menu = gtk_menu_new(), *sub;
 		gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE);
+#if 0 /* TODO */
 		sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
 
 		if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) {
@@ -8589,7 +8758,7 @@
 			gtk_widget_destroy(menu);
 			return FALSE;
 		}
-
+#endif
 		gtk_widget_show_all(menu);
 		gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time);
 		return TRUE;
@@ -8604,6 +8773,7 @@
 	int tab_clicked;
 	GtkWidget *page;
 	GtkWidget *tab;
+  GtkAllocation allocation;
 
 	if (e->button == 2 && e->type == GDK_BUTTON_PRESS) {
 		PidginConversation *gtkconv;
@@ -8641,7 +8811,7 @@
 	* Get the relative position of the press event, with regards to
 	* the position of the notebook.
 	*/
-	gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y);
+	gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
 
 	/* Reset the min/max x/y */
 	win->drag_min_x = 0;
@@ -8653,10 +8823,12 @@
 	page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked);
 	tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page);
 
-	win->drag_min_x = tab->allocation.x      + nb_x;
-	win->drag_min_y = tab->allocation.y      + nb_y;
-	win->drag_max_x = tab->allocation.width  + win->drag_min_x;
-	win->drag_max_y = tab->allocation.height + win->drag_min_y;
+  gtk_widget_get_allocation(tab, &allocation);
+
+	win->drag_min_x = allocation.x      + nb_x;
+	win->drag_min_y = allocation.y      + nb_y;
+	win->drag_max_x = allocation.width  + win->drag_min_x;
+	win->drag_max_y = allocation.height + win->drag_min_y;
 
 	/* Make sure the click occurred in the tab. */
 	if (e->x_root <  win->drag_min_x ||
@@ -8893,12 +9065,15 @@
 		close_conv_cb(NULL, gtkconv);
 }
 
+/* TODO: I don't know if this doable in GTK+ 3.0 */
+#if 0
 static gboolean
 right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win)
 {
-	GtkWidget *item, *menu;
+	GtkWidget *item;
 	PidginConversation *gtkconv;
-
+  GtkWidget *menu = gtk_notebook_get_menu
+    
 	if (event->type != GDK_BUTTON_PRESS || event->button != 3)
 		return FALSE;
 
@@ -8944,6 +9119,7 @@
 
 	return FALSE;
 }
+#endif
 
 static void
 remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry)
@@ -8965,7 +9141,7 @@
 static gboolean
 alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
 {
-	if (event->keyval == GDK_Escape) {
+	if (event->keyval == GDK_KEY_Escape) {
 		remove_edit_entry(user_data, widget);
 		return TRUE;
 	}
@@ -9010,7 +9186,7 @@
 	PurpleConversation *conv = gtkconv->active_conv;
 	const char *text = NULL;
 
-	if (!GTK_WIDGET_VISIBLE(gtkconv->infopane)) {
+	if (!gtk_widget_get_visible(gtkconv->infopane)) {
 		/* There's already an entry for alias. Let's not create another one. */
 		return FALSE;
 	}
@@ -9094,8 +9270,8 @@
 
 	/* Update the menubar */
 
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging),
-	                               purple_conversation_is_logging(conv));
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging),
+	                             purple_conversation_is_logging(conv));
 
 	generate_send_to_items(win);
 	regenerate_options_items(win);
@@ -9105,14 +9281,14 @@
 
 	sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
 	if (strcmp(sound_method, "none") != 0)
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds),
-		                               gtkconv->make_sound);
-
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar),
-	                               purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
-
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_timestamps),
-	                               purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
+		gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
+		                             gtkconv->make_sound);
+
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
+	                             purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
+
+	gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_timestamps),
+	                             purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
 
 	/*
 	 * We pause icons when they are not visible.  If this icon should
@@ -9172,14 +9348,14 @@
 static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
 	int x, y;
 
-	if (GTK_WIDGET_VISIBLE(w))
+	if (gtk_widget_get_visible(w))
 		gtk_window_get_position(GTK_WINDOW(w), &x, &y);
 	else
 		return FALSE; /* carry on normally */
 
 	/* Workaround for GTK+ bug # 169811 - "configure_event" is fired
 	* when the window is being maximized */
-	if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED)
+	if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
 		return FALSE;
 
 	/* don't save off-screen positioning */
@@ -9207,7 +9383,7 @@
 	 /* if the window exists, is hidden, we're saving positions, and the
           * position is sane... */
 	if (win && win->window &&
-			!GTK_WIDGET_VISIBLE(win->window) && conv_width != 0) {
+			!gtk_widget_get_visible(win->window) && conv_width != 0) {
 
 #ifdef _WIN32  /* only override window manager placement on Windows */
 		/* ...check position is on screen... */
@@ -9292,9 +9468,13 @@
 	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
 	gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE);
 
+  /* TODO: figure out how to add custom stuff to the right-click menu in
+     GtkNotebook in GTK+ 3.0 */
+  /*
 	g_signal_connect(G_OBJECT(win->notebook), "button-press-event",
 					G_CALLBACK(right_click_menu_cb), win);
-
+  */
+          
 	gtk_widget_show(win->notebook);
 
 	g_signal_connect(G_OBJECT(win->notebook), "switch_page",
@@ -9362,7 +9542,7 @@
 	}
 	gtk_widget_destroy(win->window);
 
-	g_object_unref(G_OBJECT(win->menu.item_factory));
+	g_object_unref(G_OBJECT(win->menu.ui));
 
 	purple_notify_close_with_handle(win);
 	purple_signals_disconnect_by_handle(win);
@@ -9385,7 +9565,7 @@
 void
 pidgin_conv_window_raise(PidginWindow *win)
 {
-	gdk_window_raise(GDK_WINDOW(win->window->window));
+	gdk_window_raise(GDK_WINDOW(gtk_widget_get_window(win->window)));
 }
 
 void
@@ -9440,8 +9620,12 @@
 
 	/* Close button. */
 	gtkconv->close = pidgin_create_small_button(gtk_label_new("×"));
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(gtkconv->close, _("Close conversation"));
+#else
 	gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
 	                     _("Close conversation"), NULL);
+#endif
 
 	g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv);
 
@@ -9556,7 +9740,7 @@
 	g_signal_connect(G_OBJECT(ebox), "enter-notify-event",
 			G_CALLBACK(gtkconv_tab_set_tip), gtkconv);
 
-	if (gtkconv->tab_label->parent == NULL) {
+	if (gtk_widget_get_parent(gtkconv->tab_label) == NULL) {
 		/* Pack if it's a new widget */
 		gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first,              FALSE, FALSE, 0);
 		gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE,  TRUE,  0);
@@ -9577,9 +9761,7 @@
 		gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox);
 	}
 
-	gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont,
-					   !tabs_side && !angle,
-					   TRUE, GTK_PACK_START);
+	g_object_set(G_OBJECT(win->notebook), "expand", !tabs_side && !angle, NULL);
 
 	if (pidgin_conv_window_get_gtkconv_count(win) == 1)
 		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
@@ -9603,8 +9785,12 @@
 
 	index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont);
 
+#if GTK_CHECK_VERSION(2,10,0)
+	g_object_ref_sink(G_OBJECT(gtkconv->tab_cont));
+#else
 	g_object_ref(gtkconv->tab_cont);
 	gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont));
+#endif
 
 	gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index);
 
@@ -9687,7 +9873,7 @@
 	for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) {
 		win = l->data;
 
-		if (gdkwin == win->window->window)
+		if (gdkwin == gtk_widget_get_window(win->window))
 			return win;
 	}
 
@@ -9809,14 +9995,14 @@
 	PurpleConversationType type = purple_conversation_get_type(conv->active_conv);
 	GList *all;
 
-	if (GTK_WIDGET_VISIBLE(w))
+	if (gtk_widget_get_visible(w))
 		gtk_window_get_position(GTK_WINDOW(w), &x, &y);
 	else
 		return FALSE; /* carry on normally */
 
 	/* Workaround for GTK+ bug # 169811 - "configure_event" is fired
 	* when the window is being maximized */
-	if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED)
+	if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
 		return FALSE;
 
 	/* don't save off-screen positioning */
--- a/pidgin/gtkconv.h	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkconv.h	Wed Feb 02 23:26:42 2011 +0000
@@ -122,7 +122,11 @@
 
 	gboolean make_sound;
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gpointer depr2;
+#else
 	GtkTooltips *tooltips;
+#endif
 
 	GtkWidget *tab_cont;
 	GtkWidget *tabby;
--- a/pidgin/gtkconvwin.h	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkconvwin.h	Wed Feb 02 23:26:42 2011 +0000
@@ -48,26 +48,27 @@
 	{
 		GtkWidget *menubar;
 
-		GtkWidget *view_log;
+		GtkAction *view_log;
 
-		GtkWidget *send_file;
-		GtkWidget *add_pounce;
-		GtkWidget *get_info;
-		GtkWidget *invite;
+		GtkAction *send_file;
+		GtkAction *add_pounce;
+		GtkAction *get_info;
+		GtkAction *invite;
 
-		GtkWidget *alias;
-		GtkWidget *block;
-		GtkWidget *unblock;
-		GtkWidget *add;
-		GtkWidget *remove;
+		GtkAction *alias;
+		GtkAction *block;
+		GtkAction *unblock;
+		GtkAction *add;
+		GtkAction *remove;
 
-		GtkWidget *insert_link;
-		GtkWidget *insert_image;
+		GtkAction *insert_link;
+		GtkAction *insert_image;
 
-		GtkWidget *logging;
-		GtkWidget *sounds;
-		GtkWidget *show_formatting_toolbar;
-		GtkWidget *show_timestamps;
+		GtkAction *logging;
+		GtkAction *sounds;
+		GtkAction *show_formatting_toolbar;
+		GtkAction *show_timestamps;
+
 		GtkWidget *show_icon;
 
 		GtkWidget *send_to;
@@ -76,7 +77,7 @@
 
 		GtkWidget *typing_icon;
 
-		GtkItemFactory *item_factory;
+		GtkUIManager *ui;
 
 	} menu;
 
@@ -98,9 +99,9 @@
 	gint drag_leave_signal;
 
 	/* Media menu options. */
-	GtkWidget *audio_call;
-	GtkWidget *video_call;
-	GtkWidget *audio_video_call;
+	GtkAction *audio_call;
+	GtkAction *video_call;
+	GtkAction *audio_video_call;
 };
 
 /*@}*/
--- a/pidgin/gtkdebug.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkdebug.c	Wed Feb 02 23:26:42 2011 +0000
@@ -128,7 +128,7 @@
 static gboolean
 configure_cb(GtkWidget *w, GdkEventConfigure *event, DebugWindow *win)
 {
-	if (GTK_WIDGET_VISIBLE(w)) {
+	if (gtk_widget_get_visible(w)) {
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/width",  event->width);
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/height", event->height);
 	}
@@ -622,8 +622,8 @@
 
 static void
 regex_key_release_cb(GtkWidget *w, GdkEventKey *e, DebugWindow *win) {
-	if(e->keyval == GDK_Return &&
-	   GTK_WIDGET_IS_SENSITIVE(win->filter) &&
+	if(e->keyval == GDK_KEY_Return &&
+	   gtk_widget_is_sensitive(win->filter) &&
 	   !gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
 	{
 		gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(win->filter), TRUE);
@@ -925,7 +925,7 @@
 		gtk_container_add(GTK_CONTAINER(item), gtk_label_new(_("Level ")));
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
 
-		win->filterlevel = gtk_combo_box_new_text();
+		win->filterlevel = gtk_combo_box_text_new();
 		item = gtk_tool_item_new();
 #if GTK_CHECK_VERSION(2,12,0)
 		gtk_widget_set_tooltip_text(win->filterlevel, _("Select the debug filter level."));
@@ -935,12 +935,12 @@
 		gtk_container_add(GTK_CONTAINER(item), win->filterlevel);
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
 
-		gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("All"));
-		gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Misc"));
-		gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Info"));
-		gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Warning"));
-		gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Error "));
-		gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Fatal Error"));
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("All"));
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Misc"));
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Info"));
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Warning"));
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Error "));
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(win->filterlevel), _("Fatal Error"));
 		gtk_combo_box_set_active(GTK_COMBO_BOX(win->filterlevel),
 					purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"));
 #ifdef USE_REGEX
--- a/pidgin/gtkdialogs.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkdialogs.c	Wed Feb 02 23:26:42 2011 +0000
@@ -454,7 +454,7 @@
 	button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE,
 	                G_CALLBACK(destroy_win), win);
 
-	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+  gtk_widget_set_can_default(button, TRUE);
 	gtk_widget_grab_default(button);
 
 	gtk_widget_show_all(win);
@@ -901,12 +901,15 @@
 
 	gtk_container_set_border_width (GTK_CONTAINER(window), PIDGIN_HIG_BOX_SPACE);
 	gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
-	gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(window)->vbox), PIDGIN_HIG_BORDER);
-	gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(window)->vbox), PIDGIN_HIG_BOX_SPACE);
+  /* TODO: figure out how to set no separator in a dialog in GTK+ 3.0 */
+  /*gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);*/
+	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
+                      PIDGIN_HIG_BORDER);
+	gtk_container_set_border_width (GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))),
+                                  PIDGIN_HIG_BOX_SPACE);
 
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), hbox);
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))), hbox);
 	img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_COOL, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
 	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
 
--- a/pidgin/gtkdialogs.h	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkdialogs.h	Wed Feb 02 23:26:42 2011 +0000
@@ -66,6 +66,6 @@
 			gtk_window_set_type_hint(GTK_WINDOW(x), GDK_WINDOW_TYPE_HINT_DIALOG)
 #endif
 
-#define PIDGIN_WINDOW_ICONIFIED(x) (gdk_window_get_state(GTK_WIDGET(x)->window) & GDK_WINDOW_STATE_ICONIFIED)
+#define PIDGIN_WINDOW_ICONIFIED(x) (gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(x))) & GDK_WINDOW_STATE_ICONIFIED)
 
 #endif /* _PIDGINDIALOGS_H_ */
--- a/pidgin/gtkdnd-hints.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkdnd-hints.c	Wed Feb 02 23:26:42 2011 +0000
@@ -57,28 +57,34 @@
 static GtkWidget *
 dnd_hints_init_window(const gchar *fname)
 {
+  /* TODO: this is likely very broken right now, I think this needs to be
+     Cairo-ified */
 	GdkPixbuf *pixbuf;
-	GdkPixmap *pixmap;
-	GdkBitmap *bitmap;
+	/*GdkPixmap *pixmap;*/
+	/*GdkBitmap *bitmap;*/
 	GtkWidget *pix;
 	GtkWidget *win;
 
 	pixbuf = gdk_pixbuf_new_from_file(fname, NULL);
 	g_return_val_if_fail(pixbuf, NULL);
 
+  /*
 	gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, &bitmap, 128);
 	g_object_unref(G_OBJECT(pixbuf));
-
-	gtk_widget_push_colormap(gdk_rgb_get_colormap());
+  */
+  
+	/*gtk_widget_push_colormap(gdk_rgb_get_colormap());*/
 	win = gtk_window_new(GTK_WINDOW_POPUP);
-	pix = gtk_image_new_from_pixmap(pixmap, bitmap);
+	pix = gtk_image_new_from_pixbuf(pixbuf);
 	gtk_container_add(GTK_CONTAINER(win), pix);
-	gtk_widget_shape_combine_mask(win, bitmap, 0, 0);
-	gtk_widget_pop_colormap();
+	/*gtk_widget_shape_combine_mask(win, bitmap, 0, 0);
+	gtk_widget_pop_colormap();*/
 
+  /*
 	g_object_unref(G_OBJECT(pixmap));
 	g_object_unref(G_OBJECT(bitmap));
-
+  */
+  
 	gtk_widget_show_all(pix);
 
 	return win;
@@ -88,17 +94,22 @@
 get_widget_coords(GtkWidget *w, gint *x1, gint *y1, gint *x2, gint *y2)
 {
 	gint ox, oy, width, height;
-
-	if (w->parent && w->parent->window == w->window)
+  GtkWidget *parent = gtk_widget_get_parent(w);
+    
+	if (parent && gtk_widget_get_window(parent) == gtk_widget_get_window(w))
 	{
-		get_widget_coords(w->parent, &ox, &oy, NULL, NULL);
-		height = w->allocation.height;
-		width = w->allocation.width;
+    GtkAllocation allocation;
+
+    gtk_widget_get_allocation(w, &allocation);
+		get_widget_coords(parent, &ox, &oy, NULL, NULL);
+		height = allocation.height;
+		width = allocation.width;
 	}
 	else
 	{
-		gdk_window_get_origin(w->window, &ox, &oy);
-		gdk_drawable_get_size(w->window, &width, &height);
+		gdk_window_get_origin(gtk_widget_get_window(w), &ox, &oy);
+    width = gdk_window_get_width(gtk_widget_get_window(w));
+    height = gdk_window_get_height(gtk_widget_get_window(w));
 	}
 
 	if (x1) *x1 = ox;
@@ -171,10 +182,13 @@
 {
 	gint x1, x2, y1, y2;
 	gint x = 0, y = 0;
+  GtkAllocation allocation;
+
+  gtk_widget_get_allocation(widget, &allocation);
 
 	get_widget_coords(widget, &x1, &y1, &x2, &y2);
-	x1 += widget->allocation.x;	x2 += widget->allocation.x;
-	y1 += widget->allocation.y;	y2 += widget->allocation.y;
+	x1 += allocation.x;	x2 += allocation.x;
+	y1 += allocation.y;	y2 += allocation.y;
 
 	switch (horiz)
 	{
--- a/pidgin/gtkdocklet-gtk.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkdocklet-gtk.c	Wed Feb 02 23:26:42 2011 +0000
@@ -148,18 +148,12 @@
 	if (icon_name) {
 		gtk_status_icon_set_from_icon_name(docklet, icon_name);
 	}
-
-	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")) {
-		gtk_status_icon_set_blinking(docklet, (pending && !connecting));
-	} else if (gtk_status_icon_get_blinking(docklet)) {
-		gtk_status_icon_set_blinking(docklet, FALSE);
-	}
 }
 
 static void
 docklet_gtk_status_set_tooltip(gchar *tooltip)
 {
-	gtk_status_icon_set_tooltip(docklet, tooltip);
+	gtk_status_icon_set_tooltip_text(docklet, tooltip);
 }
 
 static void
--- a/pidgin/gtkdocklet.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkdocklet.c	Wed Feb 02 23:26:42 2011 +0000
@@ -210,12 +210,6 @@
 		connecting = newconnecting;
 
 		pidgin_docklet_update_icon();
-
-		/* and schedule the blinker function if messages are pending */
-		if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")
-			&& pending && !connecting && docklet_blinking_timer == 0) {
-			docklet_blinking_timer = g_timeout_add(500, docklet_blink_icon, NULL);
-		}
 	}
 
 	return FALSE; /* for when we're called by the glib idle handler */
@@ -315,19 +309,14 @@
 static void
 docklet_toggle_mute(GtkWidget *toggle, void *data)
 {
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute", GTK_CHECK_MENU_ITEM(toggle)->active);
-}
-
-static void
-docklet_toggle_blink(GtkWidget *toggle, void *data)
-{
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/blink", GTK_CHECK_MENU_ITEM(toggle)->active);
+	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute",
+                        gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(toggle)));
 }
 
 static void
 docklet_toggle_blist(GtkWidget *toggle, void *data)
 {
-	purple_blist_set_visible(GTK_CHECK_MENU_ITEM(toggle)->active);
+	purple_blist_set_visible(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(toggle)));
 }
 
 #ifdef _WIN32
@@ -523,7 +512,7 @@
 		new_menu_item_with_status_icon(menu,
 			purple_status_type_get_name(status_type),
 			prim, G_CALLBACK(activate_status_account_cb),
-			status_type, 0, 0, NULL);
+			GINT_TO_POINTER(status_type), 0, 0, NULL);
 	}
 }
 
@@ -593,7 +582,7 @@
 
 
 static void
-plugin_act(GtkObject *obj, PurplePluginAction *pam)
+plugin_act(GtkWidget *widget, PurplePluginAction *pam)
 {
 	if (pam && pam->callback)
 		pam->callback(pam);
@@ -734,11 +723,6 @@
 	g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_mute), NULL);
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
-	menuitem = gtk_check_menu_item_new_with_mnemonic(_("_Blink on New Message"));
-	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink"));
-	g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_blink), NULL);
-	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-
 	pidgin_separator(menu);
 
 	/* add plugin actions */
--- a/pidgin/gtkidle.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkidle.c	Wed Feb 02 23:26:42 2011 +0000
@@ -107,14 +107,16 @@
 	int event_base, error_base;
 
 	if (has_extension == -1)
-		has_extension = XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base);
+		has_extension = XScreenSaverQueryExtension(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
+                                               &event_base, &error_base);
 
 	if (has_extension)
 	{
 		if (mit_info == NULL)
 			mit_info = XScreenSaverAllocInfo();
 
-		XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info);
+		XScreenSaverQueryInfo(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
+                          GDK_ROOT_WINDOW(), mit_info);
 		return (mit_info->idle) / 1000;
 	}
 	else
--- a/pidgin/gtkimhtml.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkimhtml.c	Wed Feb 02 23:26:42 2011 +0000
@@ -422,7 +422,7 @@
 
 	/* Don't scroll here if we're in the middle of a smooth scroll */
 	if (scroll && imhtml->scroll_time == NULL &&
-	    GTK_WIDGET_REALIZED(imhtml))
+	    gtk_widget_get_realized(GTK_WIDGET(imhtml)))
 		gtk_imhtml_scroll_to_end(imhtml, FALSE);
 }
 
@@ -511,18 +511,20 @@
 gtk_imhtml_tip_paint (GtkIMHtml *imhtml)
 {
 	PangoLayout *layout;
+	cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(imhtml->tip_window));
 
 	g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
 
 	layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
 
-	gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window,
-						GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window,
-						"tooltip", 0, 0, -1, -1);
-
-	gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL,
-					  FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout);
-
+	gtk_paint_flat_box (gtk_widget_get_style(imhtml->tip_window), cr,
+		GTK_STATE_NORMAL, GTK_SHADOW_OUT, imhtml->tip_window, "tooltip",
+		0, 0, -1, -1);
+
+	gtk_paint_layout (gtk_widget_get_style(imhtml->tip_window), cr,
+		GTK_STATE_NORMAL, TRUE, imhtml->tip_window, NULL, 4, 4, layout);
+
+	cairo_destroy(cr);
 	g_object_unref(layout);
 	return FALSE;
 }
@@ -534,12 +536,15 @@
 	PangoFontMetrics *font_metrics;
 	PangoLayout *layout;
 	PangoFont *font;
-
+	GtkStyle *style = gtk_widget_get_style(imhtml->tip_window);
+	GtkAllocation allocation;
 	gint gap, x, y, h, w, scr_w, baseline_skip;
 
 	g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
 
-	if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) {
+	gtk_widget_get_allocation(GTK_WIDGET(imhtml), &allocation);
+
+	if (!imhtml->tip || !gtk_widget_is_drawable(GTK_WIDGET(imhtml))) {
 		imhtml->tip_timer = 0;
 		return FALSE;
 	}
@@ -563,11 +568,10 @@
 	gtk_widget_ensure_style (imhtml->tip_window);
 	layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
 	font = pango_context_load_font(pango_layout_get_context(layout),
-			      imhtml->tip_window->style->font_desc);
+	                               style->font_desc);
 
 	if (font == NULL) {
-		char *tmp = pango_font_description_to_string(
-					imhtml->tip_window->style->font_desc);
+		char *tmp = pango_font_description_to_string(style->font_desc);
 
 		purple_debug(PURPLE_DEBUG_ERROR, "gtk_imhtml_tip",
 			"pango_context_load_font() couldn't load font: '%s'\n",
@@ -592,8 +596,8 @@
 	h = 8 + baseline_skip;
 
 	gdk_window_get_pointer (NULL, &x, &y, NULL);
-	if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml)))
-		y += GTK_WIDGET(imhtml)->allocation.y;
+	if ((!gtk_widget_get_has_window(GTK_WIDGET(imhtml))))
+		y += allocation.y;
 
 	scr_w = gdk_screen_width();
 
@@ -633,7 +637,7 @@
 
 	oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag;
 
-	gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL);
+	gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(imhtml)), NULL, NULL, NULL);
 	gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET,
 	                                      event->x, event->y, &x, &y);
 	gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y);
@@ -761,6 +765,8 @@
 	return FALSE;
 }
 
+/* TODO: I think this can be removed for GTK+ 3.0... */
+#if 0
 static gint
 gtk_imhtml_expose_event (GtkWidget      *widget,
 			 GdkEventExpose *event)
@@ -788,7 +794,8 @@
 			gdk_color_parse(GTK_IMHTML(widget)->edit.background, &gcolor);
 			gdk_cairo_set_source_color(cr, &gcolor);
 		} else {
-			gdk_cairo_set_source_color(cr, &(widget->style->base[GTK_WIDGET_STATE(widget)]));
+			gdk_cairo_set_source_color(cr,
+				&(gtk_widget_get_style(widget)->base[gtk_widget_get_state(widget)]));
 		}
 
 		cairo_rectangle(cr,
@@ -894,6 +901,7 @@
 
 	return FALSE;
 }
+#endif
 
 
 static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml)
@@ -1170,11 +1178,12 @@
 {
 	char *text;
 	GtkIMHtml *imhtml = data;
+	gint length = gtk_selection_data_get_length(selection_data);
 
 	if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)))
 		return;
 
-	if (imhtml->wbfo || selection_data->length <= 0) {
+	if (imhtml->wbfo || length <= 0) {
 		gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml);
 		return;
 	} else {
@@ -1198,13 +1207,13 @@
 		}
 #endif
 
-		text = g_malloc(selection_data->length + 1);
-		memcpy(text, selection_data->data, selection_data->length);
+		text = g_malloc(length + 1);
+		memcpy(text, gtk_selection_data_get_data(selection_data), length);
 		/* Make sure the paste data is null-terminated.  Given that
 		 * we're passed length (but assume later that it is
 		 * null-terminated), this seems sensible to me.
 		 */
-		text[selection_data->length] = '\0';
+		text[length] = '\0';
 	}
 
 #ifdef _WIN32
@@ -1215,10 +1224,10 @@
 	}
 #endif
 
-	if (selection_data->length >= 2 &&
+	if (length >= 2 &&
 		(*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) {
 		/* This is UTF-16 */
-		char *utf8 = utf16_to_utf8_with_bom_check(text, selection_data->length);
+		char *utf8 = utf16_to_utf8_with_bom_check(text, length);
 		g_free(text);
 		text = utf8;
 		if (!text) {
@@ -1579,7 +1588,8 @@
 
 	gobject_class->finalize = gtk_imhtml_finalize;
 	widget_class->drag_motion = gtk_text_view_drag_motion;
-	widget_class->expose_event = gtk_imhtml_expose_event;
+	/* TODO: I _think_ this should be removed for GTK+ 3.0 */
+	/*widget_class->expose_event = gtk_imhtml_expose_event;*/
 	parent_size_allocate = widget_class->size_allocate;
 	widget_class->size_allocate = gtk_imhtml_size_allocate;
 	parent_style_set = widget_class->style_set;
@@ -1641,20 +1651,20 @@
 	                                        TRUE, G_PARAM_READABLE));
 
 	binding_set = gtk_binding_set_by_class (parent_class);
-	gtk_binding_entry_add_signal (binding_set, GDK_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD);
-	gtk_binding_entry_add_signal (binding_set, GDK_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC);
-	gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE);
-	gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
-	gtk_binding_entry_add_signal (binding_set, GDK_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
-	gtk_binding_entry_add_signal (binding_set, GDK_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK);
 	binding_set = gtk_binding_set_by_class(klass);
-	gtk_binding_entry_add_signal (binding_set, GDK_r, GDK_CONTROL_MASK, "format_function_clear", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "message_send", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "message_send", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK, "undo", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_F14, 0, "undo", 0);
-	gtk_binding_entry_add_signal(binding_set, GDK_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text");
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "format_function_clear", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "message_send", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "message_send", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK, "undo", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_F14, 0, "undo", 0);
+	gtk_binding_entry_add_signal(binding_set, GDK_KEY_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text");
 }
 
 static void gtk_imhtml_init (GtkIMHtml *imhtml)
@@ -1881,13 +1891,13 @@
 		/* can't accept any of the offered targets */
 	} else {
 		GtkWidget *source_widget;
-		suggested_action = context->suggested_action;
+		suggested_action = gdk_drag_context_get_suggested_action(context);
 		source_widget = gtk_drag_get_source_widget (context);
 		if (source_widget == widget) {
 			/* Default to MOVE, unless the user has
 			 * pressed ctrl or alt to affect available actions
 			 */
-			if ((context->actions & GDK_ACTION_MOVE) != 0)
+			if ((gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) != 0)
 				suggested_action = GDK_ACTION_MOVE;
 		}
 	}
@@ -1919,21 +1929,22 @@
 {
 	gchar **links;
 	gchar *link;
-	char *text = (char *)sd->data;
+	char *text = (char *) gtk_selection_data_get_data(sd);
 	GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer);
 	GtkTextIter iter;
 	gint i = 0;
+	gint length = gtk_selection_data_get_length(sd);
 
 	gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark);
 
-	if(gtk_imhtml_get_editable(imhtml) && sd->data){
+	if (gtk_imhtml_get_editable(imhtml) && text) {
 		switch (info) {
 		case GTK_IMHTML_DRAG_URL:
 			/* TODO: Is it really ok to change sd->data...? */
-			purple_str_strip_char((char *)sd->data, '\r');
-
-			links = g_strsplit((char *)sd->data, "\n", 0);
-			while((link = links[i]) != NULL){
+			purple_str_strip_char(text, '\r');
+
+			links = g_strsplit(text, "\n", 0);
+			while ((link = links[i]) != NULL) {
 				if (gtk_imhtml_is_protocol(link)) {
 					gchar *label;
 
@@ -1971,8 +1982,8 @@
 			 * See also the comment on text/html here:
 			 * http://mail.gnome.org/archives/gtk-devel-list/2001-September/msg00114.html
 			 */
-			if (sd->length >= 2 && !g_utf8_validate(text, sd->length - 1, NULL)) {
-				utf8 = utf16_to_utf8_with_bom_check(text, sd->length);
+			if (length >= 2 && !g_utf8_validate(text, length - 1, NULL)) {
+				utf8 = utf16_to_utf8_with_bom_check(text, length);
 
 				if (!utf8) {
 					purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in drag_rcv_cb\n");
@@ -2001,7 +2012,8 @@
 			gtk_drag_finish(dc, FALSE, FALSE, t);
 			return;
 		}
-		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
+		gtk_drag_finish(dc, TRUE,
+		                gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
 	} else {
 		gtk_drag_finish(dc, FALSE, FALSE, t);
 	}
@@ -2532,8 +2544,8 @@
 static gboolean smooth_scroll_cb(gpointer data)
 {
 	GtkIMHtml *imhtml = data;
-	GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
-	gdouble max_val = adj->upper - adj->page_size;
+	GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
+	gdouble max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
 	gdouble scroll_val = gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3);
 
 	g_return_val_if_fail(imhtml->scroll_time != NULL, FALSE);
@@ -2556,9 +2568,10 @@
 static gboolean scroll_idle_cb(gpointer data)
 {
 	GtkIMHtml *imhtml = data;
-	GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
-	if(adj) {
-		gtk_adjustment_set_value(adj, adj->upper - adj->page_size);
+	GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
+	if (adj) {
+		gtk_adjustment_set_value(adj, gtk_adjustment_get_upper(adj) -
+		                              gtk_adjustment_get_page_size(adj));
 	}
 	imhtml->scroll_src = 0;
 	return FALSE;
@@ -4216,9 +4229,14 @@
 
 	for (l = tags; l; l = l->next) {
 		GtkTextTag *tag = l->data;
-
-		if (tag->name && !strncmp(tag->name, prefix, len))
+		gchar *name = NULL;
+
+		g_object_get(G_OBJECT(tag), "name", &name, NULL);
+
+		if (name && !strncmp(name, prefix, len))
 			gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, i, e);
+
+		g_free(name);
 	}
 
 	g_slist_free(tags);
@@ -4234,10 +4252,15 @@
 
 			for (l = tags; l; l = l->next) {
 				GtkTextTag *tag = l->data;
-
-				if (tag->name && !strncmp(tag->name, prefix, len))
+				gchar *name = NULL;
+
+				g_object_get(G_OBJECT(tag), "name", &name, NULL);
+
+				if (name && !strncmp(name, prefix, len))
 					gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, &iter, e);
-			}
+
+				g_free(name);
+      }
 
 			g_slist_free(tags);
 		}
@@ -4357,11 +4380,16 @@
 				gtk_text_iter_begins_tag(start, tag) &&			/* the tag starts with the selection */
 				(!gtk_text_iter_has_tag(end, tag) ||			/* the tag ends within the selection */
 					gtk_text_iter_ends_tag(end, tag))) {
+			gchar *name = NULL;
+
+			g_object_get(G_OBJECT(tag), "name", &name, NULL);
 			gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end);
-			if (tag->name &&
-					strncmp(tag->name, "LINK ", 5) == 0 && imhtml->edit.link) {
+
+			if (name && strncmp(name, "LINK ", 5) == 0 && imhtml->edit.link) {
 				gtk_imhtml_toggle_link(imhtml, NULL);
 			}
+
+			g_free(name);
 		}
 	}
 	g_slist_free(tags);
@@ -4583,27 +4611,32 @@
 
 	for (l = tags; l != NULL; l = l->next) {
 		GtkTextTag *tag = GTK_TEXT_TAG(l->data);
-
-		if (tag->name) {
-			if (strcmp(tag->name, "BOLD") == 0)
+		gchar *name = NULL;
+
+		g_object_get(G_OBJECT(tag), "name", &name, NULL);
+
+		if (name) {
+			if (strcmp(name, "BOLD") == 0)
 				imhtml->edit.bold = TRUE;
-			else if (strcmp(tag->name, "ITALICS") == 0)
+			else if (strcmp(name, "ITALICS") == 0)
 				imhtml->edit.italic = TRUE;
-			else if (strcmp(tag->name, "UNDERLINE") == 0)
+			else if (strcmp(name, "UNDERLINE") == 0)
 				imhtml->edit.underline = TRUE;
-			else if (strcmp(tag->name, "STRIKE") == 0)
+			else if (strcmp(name, "STRIKE") == 0)
 				imhtml->edit.strike = TRUE;
-			else if (strncmp(tag->name, "FORECOLOR ", 10) == 0)
-				imhtml->edit.forecolor = g_strdup(&(tag->name)[10]);
-			else if (strncmp(tag->name, "BACKCOLOR ", 10) == 0)
-				imhtml->edit.backcolor = g_strdup(&(tag->name)[10]);
-			else if (strncmp(tag->name, "FONT FACE ", 10) == 0)
-				imhtml->edit.fontface = g_strdup(&(tag->name)[10]);
-			else if (strncmp(tag->name, "FONT SIZE ", 10) == 0)
-				imhtml->edit.fontsize = strtol(&(tag->name)[10], NULL, 10);
-			else if ((strncmp(tag->name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
+			else if (strncmp(name, "FORECOLOR ", 10) == 0)
+				imhtml->edit.forecolor = g_strdup(&(name)[10]);
+			else if (strncmp(name, "BACKCOLOR ", 10) == 0)
+				imhtml->edit.backcolor = g_strdup(&(name)[10]);
+			else if (strncmp(name, "FONT FACE ", 10) == 0)
+				imhtml->edit.fontface = g_strdup(&(name)[10]);
+			else if (strncmp(name, "FONT SIZE ", 10) == 0)
+				imhtml->edit.fontsize = strtol(&(name)[10], NULL, 10);
+			else if ((strncmp(name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
 				imhtml->edit.link = tag;
 		}
+
+		g_free(name);
 	}
 
 	g_slist_free(tags);
@@ -4894,6 +4927,8 @@
 	gtk_text_buffer_end_user_action(imhtml->text_buffer);
 }
 
+/* TODO: I think this can be removed for GTK+ 3.0... */
+#if 0
 static gboolean
 image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
 {
@@ -4901,9 +4936,10 @@
 
 	return TRUE;
 }
+#endif
 
 /* In case the smiley gets removed from the imhtml before it gets removed from the queue */
-static void animated_smiley_destroy_cb(GtkObject *widget, GtkIMHtml *imhtml)
+static void animated_smiley_destroy_cb(GtkWidget *widget, GtkIMHtml *imhtml)
 {
 	GList *l = imhtml->animations->head;
 	while (l) {
@@ -4998,7 +5034,9 @@
 		 * images, and ensures that they are handled by the image
 		 * itself, without propagating to the textview and causing
 		 * a complete refresh */
+		/* TODO: I think this should be removed for GTK+ 3.0?
 		g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
+		*/
 
 		gtk_widget_show(icon);
 		if (ebox)
@@ -5100,22 +5138,29 @@
 
 static const gchar *tag_to_html_start(GtkTextTag *tag)
 {
-	const gchar *name;
 	static gchar buf[1024];
-
-	name = tag->name;
+	gchar *name = NULL;
+
 	g_return_val_if_fail(name != NULL, "");
+	g_object_get(G_OBJECT(tag), "name", &name, NULL);
 
 	if (strcmp(name, "BOLD") == 0) {
+		g_free(name);
 		return "<b>";
 	} else if (strcmp(name, "ITALICS") == 0) {
+		g_free(name);
 		return "<i>";
 	} else if (strcmp(name, "UNDERLINE") == 0) {
+		g_free(name);
 		return "<u>";
 	} else if (strcmp(name, "STRIKE") == 0) {
+		g_free(name);
 		return "<s>";
 	} else if (strncmp(name, "LINK ", 5) == 0) {
 		char *tmp = g_object_get_data(G_OBJECT(tag), "link_url");
+
+		g_free(name);
+
 		if (tmp) {
 			g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp);
 			buf[sizeof(buf)-1] = '\0';
@@ -5125,18 +5170,29 @@
 		}
 	} else if (strncmp(name, "FORECOLOR ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]);
+
+		g_free(name);
+
 		return buf;
 	} else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]);
+		g_free(name);
+
 		return buf;
 	} else if (strncmp(name, "BACKGROUND ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]);
+		g_free(name);
+
 		return buf;
 	} else if (strncmp(name, "FONT FACE ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]);
+		g_free(name);
+
 		return buf;
 	} else if (strncmp(name, "FONT SIZE ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]);
+		g_free(name);
+
 		return buf;
 	} else {
 		char *str = buf;
@@ -5199,6 +5255,7 @@
 		}
 
 		g_snprintf(str, sizeof(buf) - (str - buf), "'>");
+		g_free(name);
 
 		return (empty ? "" : buf);
 	}
@@ -5206,30 +5263,40 @@
 
 static const gchar *tag_to_html_end(GtkTextTag *tag)
 {
-	const gchar *name;
-
-	name = tag->name;
+	gchar *name;
+
 	g_return_val_if_fail(name != NULL, "");
+	g_object_get(G_OBJECT(tag), "name", &name, NULL);
 
 	if (strcmp(name, "BOLD") == 0) {
+		g_free(name);
 		return "</b>";
 	} else if (strcmp(name, "ITALICS") == 0) {
+		g_free(name);
 		return "</i>";
 	} else if (strcmp(name, "UNDERLINE") == 0) {
+		g_free(name);
 		return "</u>";
 	} else if (strcmp(name, "STRIKE") == 0) {
+		g_free(name);
 		return "</s>";
 	} else if (strncmp(name, "LINK ", 5) == 0) {
+		g_free(name);
 		return "</a>";
 	} else if (strncmp(name, "FORECOLOR ", 10) == 0) {
+		g_free(name);
 		return "</font>";
 	} else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
+		g_free(name);
 		return "</font>";
 	} else if (strncmp(name, "BACKGROUND ", 10) == 0) {
+		g_free(name);
 		return "</body>";
 	} else if (strncmp(name, "FONT FACE ", 10) == 0) {
+		g_free(name);
 		return "</font>";
 	} else if (strncmp(name, "FONT SIZE ", 10) == 0) {
+		g_free(name);
 		return "</font>";
 	} else {
 		const char *props[] = {"weight-set", "foreground-set", "background-set",
@@ -5242,6 +5309,8 @@
 				return "</span>";
 		}
 
+		g_free(name);
+
 		return "";
 	}
 }
--- a/pidgin/gtkimhtmltoolbar.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkimhtmltoolbar.c	Wed Feb 02 23:26:42 2011 +0000
@@ -124,11 +124,15 @@
 {
 	GtkFontSelection *sel;
 
-	sel = GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog)->fontsel);
-	gtk_widget_hide_all(gtk_widget_get_parent(sel->size_entry));
-	gtk_widget_show_all(sel->family_list);
-	gtk_widget_show(gtk_widget_get_parent(sel->family_list));
-	gtk_widget_show(gtk_widget_get_parent(gtk_widget_get_parent(sel->family_list)));
+	sel = GTK_FONT_SELECTION(
+          gtk_font_selection_dialog_get_font_selection(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog)));
+	gtk_widget_hide(gtk_widget_get_parent(
+                    gtk_font_selection_get_size_entry(sel)));
+	gtk_widget_show_all(gtk_font_selection_get_family_list(sel));
+	gtk_widget_show(gtk_widget_get_parent(
+                    gtk_font_selection_get_family_list(sel)));
+	gtk_widget_show(gtk_widget_get_parent(gtk_widget_get_parent(
+                    gtk_font_selection_get_family_list(sel))));
 }
 
 static void
@@ -191,10 +195,12 @@
 
 			g_signal_connect(G_OBJECT(toolbar->font_dialog), "delete_event",
 							 G_CALLBACK(destroy_toolbar_font), toolbar);
-			g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog)->ok_button), "clicked",
-							 G_CALLBACK(apply_font), toolbar->font_dialog);
-			g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog)->cancel_button), "clicked",
-							 G_CALLBACK(cancel_toolbar_font), toolbar);
+			g_signal_connect(G_OBJECT(
+        gtk_font_selection_dialog_get_ok_button(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog))),
+               "clicked", G_CALLBACK(apply_font), toolbar->font_dialog);
+			g_signal_connect(G_OBJECT(
+        gtk_font_selection_dialog_get_cancel_button(GTK_FONT_SELECTION_DIALOG(toolbar->font_dialog))),
+               "clicked", G_CALLBACK(cancel_toolbar_font), toolbar);
 			g_signal_connect_after(G_OBJECT(toolbar->font_dialog), "realize",
 							 G_CALLBACK(realize_toolbar_font), toolbar);
 		}
@@ -253,9 +259,12 @@
 		char *color = gtk_imhtml_get_current_forecolor(GTK_IMHTML(toolbar->imhtml));
 
 		if (!toolbar->fgcolor_dialog) {
-
+      GtkWidget *ok_button;
+      GtkWidget *cancel_button;
+        
 			toolbar->fgcolor_dialog = gtk_color_selection_dialog_new(_("Select Text Color"));
-			colorsel = GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog)->colorsel;
+			colorsel =
+            gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog));
 			if (color) {
 				gdk_color_parse(color, &fgcolor);
 				gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &fgcolor);
@@ -264,12 +273,14 @@
 
 			g_object_set_data(G_OBJECT(colorsel), "purple_toolbar", toolbar);
 
+      g_object_get(G_OBJECT(toolbar->fgcolor_dialog), "ok-button", &ok_button, NULL);
+      g_object_get(G_OBJECT(toolbar->fgcolor_dialog), "cancel-button",
+                   &cancel_button, NULL);
 			g_signal_connect(G_OBJECT(toolbar->fgcolor_dialog), "delete_event",
 							 G_CALLBACK(destroy_toolbar_fgcolor), toolbar);
-			g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog)->ok_button), "clicked",
-							 G_CALLBACK(do_fgcolor), colorsel);
-			g_signal_connect(G_OBJECT (GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog)->cancel_button), "clicked",
-							 G_CALLBACK(cancel_toolbar_fgcolor), toolbar);
+			g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(do_fgcolor), colorsel);
+			g_signal_connect(G_OBJECT(cancel_button), "clicked",
+                       G_CALLBACK(cancel_toolbar_fgcolor), toolbar);
 		}
 		gtk_window_present(GTK_WINDOW(toolbar->fgcolor_dialog));
 	} else {
@@ -333,10 +344,14 @@
 		char *color = gtk_imhtml_get_current_backcolor(GTK_IMHTML(toolbar->imhtml));
 
 		if (!toolbar->bgcolor_dialog) {
-
+      GtkWidget *ok_button;
+      GtkWidget *cancel_button;
+          
 			toolbar->bgcolor_dialog = gtk_color_selection_dialog_new(_("Select Background Color"));
-			colorsel = GTK_COLOR_SELECTION_DIALOG(toolbar->bgcolor_dialog)->colorsel;
-			if (color) {
+			colorsel =
+            gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(toolbar->fgcolor_dialog));
+
+      if (color) {
 				gdk_color_parse(color, &bgcolor);
 				gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &bgcolor);
 				g_free(color);
@@ -344,11 +359,14 @@
 
 			g_object_set_data(G_OBJECT(colorsel), "purple_toolbar", toolbar);
 
+      g_object_get(G_OBJECT(toolbar->bgcolor_dialog), "ok-button", &ok_button, NULL);
+      g_object_get(G_OBJECT(toolbar->bgcolor_dialog), "cancel-button",
+                   &cancel_button, NULL);
 			g_signal_connect(G_OBJECT(toolbar->bgcolor_dialog), "delete_event",
 							 G_CALLBACK(destroy_toolbar_bgcolor), toolbar);
-			g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(toolbar->bgcolor_dialog)->ok_button), "clicked",
-							 G_CALLBACK(do_bgcolor), colorsel);
-			g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(toolbar->bgcolor_dialog)->cancel_button), "clicked",
+			g_signal_connect(G_OBJECT(ok_button), "clicked",
+               G_CALLBACK(do_bgcolor), colorsel);
+			g_signal_connect(G_OBJECT(cancel_button), "clicked",
 							 G_CALLBACK(cancel_toolbar_bgcolor), toolbar);
 
 		}
@@ -658,7 +676,11 @@
 	g_object_set_data(G_OBJECT(button), "smiley_text", face);
 	g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(insert_smiley_text), toolbar);
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(button, face);
+#else
 	gtk_tooltips_set_tip(toolbar->tooltips, button, face, NULL);
+#endif
 
 	/* these look really weird with borders */
 	gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
@@ -672,7 +694,11 @@
 		g_snprintf(tip, sizeof(tip),
 			_("This smiley is disabled because a custom smiley exists for this shortcut:\n %s"),
 			face);
+#if GTK_CHECK_VERSION(2,12,0)
+		gtk_widget_set_tooltip_text(button, tip);
+#else
 		gtk_tooltips_set_tip(toolbar->tooltips, button, tip, NULL);
+#endif
 		gtk_widget_set_sensitive(button, FALSE);
 	} else if (psmiley) {
 		/* Remove the button if the smiley is destroyed */
@@ -714,7 +740,7 @@
 static gboolean
 smiley_dialog_input_cb(GtkWidget *dialog, GdkEvent *event, GtkIMHtmlToolbar *toolbar)
 {
-	if ((event->type == GDK_KEY_PRESS && event->key.keyval == GDK_Escape) ||
+	if ((event->type == GDK_KEY_PRESS && event->key.keyval == GDK_KEY_Escape) ||
 	    (event->type == GDK_BUTTON_PRESS && event->button.button == 1))
 	{
 		close_smiley_dialog(toolbar);
@@ -1087,19 +1113,21 @@
 {
 	GtkWidget *widget = GTK_WIDGET(data);
 	GtkRequisition menu_req;
-	gint ythickness = widget->style->ythickness;
+  GtkAllocation allocation;
+  gint ythickness = gtk_widget_get_style(widget)->ythickness;
 	int savy;
 
+  gtk_widget_get_allocation(widget, &allocation);    
 	gtk_widget_size_request(GTK_WIDGET (menu), &menu_req);
-	gdk_window_get_origin(widget->window, x, y);
-	*x += widget->allocation.x;
-	*y += widget->allocation.y + widget->allocation.height;
+	gdk_window_get_origin(gtk_widget_get_window(widget), x, y);
+	*x += allocation.x;
+	*y += allocation.y + allocation.height;
 	savy = *y;
 
 	pidgin_menu_position_func_helper(menu, x, y, push_in, data);
 
 	if (savy > *y + ythickness + 1)
-		*y -= widget->allocation.height;
+		*y -= allocation.height;
 }
 
 static gboolean
@@ -1158,7 +1186,9 @@
 	}
 
 	g_free(toolbar->sml);
+#if !GTK_CHECK_VERSION(2,12,0)
 	gtk_object_sink(GTK_OBJECT(toolbar->tooltips));
+#endif
 
 	menu = g_object_get_data(object, "font_menu");
 	if (menu)
@@ -1189,7 +1219,7 @@
 	if (event->button != 3)
 		return FALSE;
 
-	wide = GTK_WIDGET_VISIBLE(toolbar->bold);
+	wide = gtk_widget_get_visible(toolbar->bold);
 
 	menu = gtk_menu_new();
 	item = gtk_menu_item_new_with_mnemonic(wide ? _("Group Items") : _("Ungroup Items"));
@@ -1255,7 +1285,11 @@
 			g_signal_connect(G_OBJECT(button), "clicked",
 					 G_CALLBACK(buttons[iter].callback), toolbar);
 			*(buttons[iter].button) = button;
+#if GTK_CHECK_VERSION(2,12,0)
+			gtk_widget_set_tooltip_text(button, buttons[iter].tooltip);
+#else
 			gtk_tooltips_set_tip(toolbar->tooltips, button, buttons[iter].tooltip, NULL);
+#endif
 		} else
 			button = gtk_vseparator_new();
 		gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
@@ -1266,7 +1300,11 @@
 	g_signal_connect(G_OBJECT(button), "clicked",
 		G_CALLBACK(send_attention_cb), toolbar);
 	g_object_set_data(G_OBJECT(toolbar), "attention", button);
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(button, _("Send Attention"));
+#else
 	gtk_tooltips_set_tip(toolbar->tooltips, button, _("Send Attention"), NULL);
+#endif
 	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
 
 	gtk_box_pack_start(GTK_BOX(toolbar), hbox, FALSE, FALSE, 0);
@@ -1276,7 +1314,7 @@
 static void
 button_visibility_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
 {
-	if (GTK_WIDGET_VISIBLE(button))
+	if (gtk_widget_get_visible(button))
 		gtk_widget_hide(item);
 	else
 		gtk_widget_show(item);
@@ -1285,7 +1323,7 @@
 static void
 button_sensitiveness_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
 {
-	gtk_widget_set_sensitive(item, GTK_WIDGET_IS_SENSITIVE(button));
+	gtk_widget_set_sensitive(item, gtk_widget_get_sensitive(button));
 }
 
 static void
@@ -1308,10 +1346,10 @@
 		gconstpointer value, gpointer toolbar)
 {
 	if (value) {
-		gtk_widget_hide_all(g_object_get_data(G_OBJECT(toolbar), "lean-view"));
+		gtk_widget_hide(g_object_get_data(G_OBJECT(toolbar), "lean-view"));
 		gtk_widget_show_all(g_object_get_data(G_OBJECT(toolbar), "wide-view"));
 	} else {
-		gtk_widget_hide_all(g_object_get_data(G_OBJECT(toolbar), "wide-view"));
+		gtk_widget_hide(g_object_get_data(G_OBJECT(toolbar), "wide-view"));
 		gtk_widget_show_all(g_object_get_data(G_OBJECT(toolbar), "lean-view"));
 	}
 }
@@ -1364,7 +1402,9 @@
 	toolbar->smiley_dialog = NULL;
 	toolbar->image_dialog = NULL;
 
+#if !GTK_CHECK_VERSION(2,12,0)
 	toolbar->tooltips = gtk_tooltips_new();
+#endif
 
 	gtk_box_set_spacing(GTK_BOX(toolbar), 3);
 
--- a/pidgin/gtkimhtmltoolbar.h	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkimhtmltoolbar.h	Wed Feb 02 23:26:42 2011 +0000
@@ -46,7 +46,11 @@
 
 	GtkWidget *imhtml;
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gpointer depr1;
+#else
 	GtkTooltips *tooltips;
+#endif
 
 	GtkWidget *bold;
 	GtkWidget *italic;
--- a/pidgin/gtklog.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtklog.c	Wed Feb 02 23:26:42 2011 +0000
@@ -582,8 +582,10 @@
 	gtk_dialog_add_button(GTK_DIALOG(lv->window), _("_Browse logs folder"), GTK_RESPONSE_HELP);
 #endif
 	gtk_container_set_border_width (GTK_CONTAINER(lv->window), PIDGIN_HIG_BOX_SPACE);
-	gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE);
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(lv->window)->vbox), 0);
+  /* TODO: is it possible to set this in GTK+ 3.0?
+  gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE);
+  */
+  gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(lv->window))), 0);
 	g_signal_connect(G_OBJECT(lv->window), "response",
 					 G_CALLBACK(destroy_cb), ht);
 	gtk_window_set_role(GTK_WINDOW(lv->window), "log_viewer");
@@ -592,11 +594,12 @@
 	if (icon != NULL) {
 		title_box = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
 		gtk_container_set_border_width(GTK_CONTAINER(title_box), PIDGIN_HIG_BOX_SPACE);
-		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), title_box, FALSE, FALSE, 0);
+		gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(lv->window))),
+                       title_box, FALSE, FALSE, 0);
 
 		gtk_box_pack_start(GTK_BOX(title_box), icon, FALSE, FALSE, 0);
 	} else
-		title_box = GTK_DIALOG(lv->window)->vbox;
+		title_box = gtk_dialog_get_content_area(GTK_DIALOG(lv->window));
 
 	/* Label ************/
 	lv->label = gtk_label_new(NULL);
@@ -611,7 +614,8 @@
 	/* Pane *************/
 	pane = gtk_hpaned_new();
 	gtk_container_set_border_width(GTK_CONTAINER(pane), PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), pane, TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(lv->window))),
+                     pane, TRUE, TRUE, 0);
 
 	/* List *************/
 	sw = gtk_scrolled_window_new (NULL, NULL);
@@ -649,7 +653,8 @@
 		gtk_label_set_markup(GTK_LABEL(size_label), text);
 		/*		gtk_paned_add1(GTK_PANED(pane), size_label); */
 		gtk_misc_set_alignment(GTK_MISC(size_label), 0, 0);
-		gtk_box_pack_end(GTK_BOX(GTK_DIALOG(lv->window)->vbox), size_label, FALSE, FALSE, 0);
+		gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(lv->window))),
+                     size_label, FALSE, FALSE, 0);
 		g_free(sz_txt);
 		g_free(text);
 	}
--- a/pidgin/gtkmain.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkmain.c	Wed Feb 02 23:26:42 2011 +0000
@@ -490,7 +490,7 @@
 {
 	Display *xdisplay;
 
-	xdisplay = GDK_DISPLAY();
+	xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
 	sn_display = sn_display_new(xdisplay,
 								sn_error_trap_push,
 								sn_error_trap_pop);
--- a/pidgin/gtkmedia.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkmedia.c	Wed Feb 02 23:26:42 2011 +0000
@@ -445,9 +445,9 @@
 		window_id = GDK_WINDOW_HWND(priv->remote_video->window);
 #elif defined(HAVE_X11)
 	if (data->participant == NULL)
-		window_id = GDK_WINDOW_XWINDOW(priv->local_video->window);
+		window_id = gdk_x11_window_get_xid(gtk_widget_get_window(priv->local_video));
 	else
-		window_id = GDK_WINDOW_XWINDOW(priv->remote_video->window);
+		window_id = gdk_x11_window_get_xid(gtk_widget_get_window(priv->remote_video));
 #else
 #	error "Unsupported windowing system"
 #endif
--- a/pidgin/gtkmenutray.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkmenutray.c	Wed Feb 02 23:26:42 2011 +0000
@@ -44,7 +44,7 @@
  * Item Stuff
  *****************************************************************************/
 static void
-pidgin_menu_tray_select(GtkItem *item) {
+pidgin_menu_tray_select(GtkMenuItem *widget) {
 	/* this may look like nothing, but it's really overriding the
 	 * GtkMenuItem's select function so that it doesn't get highlighted like
 	 * a normal menu item would.
@@ -52,7 +52,7 @@
 }
 
 static void
-pidgin_menu_tray_deselect(GtkItem *item) {
+pidgin_menu_tray_deselect(GtkMenuItem *widget) {
 	/* Probably not necessary, but I'd rather be safe than sorry.  We're
 	 * overridding the select, so it makes sense to override deselect as well.
 	 */
@@ -104,9 +104,11 @@
 		gtk_widget_destroy(GTK_WIDGET(tray->tray));
 #endif
 
+#if !GTK_CHECK_VERSION(2,12,0)
 	if (tray->tooltips) {
 		gtk_object_sink(GTK_OBJECT(tray->tooltips));
 	}
+#endif
 
 	G_OBJECT_CLASS(parent_class)->finalize(obj);
 }
@@ -114,7 +116,7 @@
 static void
 pidgin_menu_tray_class_init(PidginMenuTrayClass *klass) {
 	GObjectClass *object_class = G_OBJECT_CLASS(klass);
-	GtkItemClass *item_class = GTK_ITEM_CLASS(klass);
+	GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS(klass);
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 	GParamSpec *pspec;
 
@@ -123,8 +125,8 @@
 	object_class->finalize = pidgin_menu_tray_finalize;
 	object_class->get_property = pidgin_menu_tray_get_property;
 
-	item_class->select = pidgin_menu_tray_select;
-	item_class->deselect = pidgin_menu_tray_deselect;
+	menu_item_class->select = pidgin_menu_tray_select;
+	menu_item_class->deselect = pidgin_menu_tray_deselect;
 
 	widget_class->map = pidgin_menu_tray_map;
 
@@ -205,7 +207,7 @@
 	g_return_if_fail(PIDGIN_IS_MENU_TRAY(menu_tray));
 	g_return_if_fail(GTK_IS_WIDGET(widget));
 
-	if (GTK_WIDGET_NO_WINDOW(widget))
+	if (!gtk_widget_get_has_window(widget))
 	{
 		GtkWidget *event;
 
@@ -238,21 +240,27 @@
 void
 pidgin_menu_tray_set_tooltip(PidginMenuTray *menu_tray, GtkWidget *widget, const char *tooltip)
 {
+#if !GTK_CHECK_VERSION(2,12,0)
 	if (!menu_tray->tooltips)
 		menu_tray->tooltips = gtk_tooltips_new();
+#endif
 
 	/* Should we check whether widget is a child of menu_tray? */
 
 	/*
-	 * If the widget does not have it's own window, then it
+	 * If the widget does not have its own window, then it
 	 * must have automatically been added to an event box
 	 * when it was added to the menu tray.  If this is the
 	 * case, we want to set the tooltip on the widget's parent,
 	 * not on the widget itself.
 	 */
-	if (GTK_WIDGET_NO_WINDOW(widget))
-		widget = widget->parent;
+	if (!gtk_widget_get_has_window(widget))
+		widget = gtk_widget_get_parent(widget);
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(widget, tooltip);
+#else
 	gtk_tooltips_set_tip(menu_tray->tooltips, widget, tooltip, NULL);
+#endif
 }
 
--- a/pidgin/gtkmenutray.h	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkmenutray.h	Wed Feb 02 23:26:42 2011 +0000
@@ -40,7 +40,11 @@
 struct _PidginMenuTray {
 	GtkMenuItem gparent;					/**< The parent instance */
 	GtkWidget *tray;						/**< The tray */
+#if GTK_CHECK_VERSION(2,12,0)
+	gpointer depr1;
+#else
 	GtkTooltips *tooltips;					/**< Tooltips */
+#endif
 };
 
 /** A PidginMenuTrayClass */
--- a/pidgin/gtknotify.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtknotify.c	Wed Feb 02 23:26:42 2011 +0000
@@ -534,12 +534,18 @@
 
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER);
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+  /* TODO: not sure if there is a way to do this in gtk+ 3, or
+     if we want to...
 	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
-	gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BOX_SPACE);
+  */
+  gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                      PIDGIN_HIG_BORDER);
+	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                                 PIDGIN_HIG_BOX_SPACE);
 
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                    hbox);
 
 	if (img != NULL)
 		gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
@@ -775,7 +781,7 @@
 		}
 	}
 
-	if (!GTK_WIDGET_VISIBLE(mail_dialog->dialog)) {
+	if (!gtk_widget_get_visible(mail_dialog->dialog)) {
 		GdkPixbuf *pixbuf = gtk_widget_render_icon(mail_dialog->dialog, PIDGIN_STOCK_DIALOG_MAIL,
 							   gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), NULL);
 		char *label_text = g_strdup_printf(ngettext("<b>%d new email.</b>",
@@ -791,7 +797,7 @@
 		g_free(label_text);
 		if (pixbuf)
 			g_object_unref(pixbuf);
-	} else if (!GTK_WIDGET_HAS_FOCUS(mail_dialog->dialog))
+	} else if (!gtk_widget_has_focus(mail_dialog->dialog))
 		pidgin_set_urgent(GTK_WINDOW(mail_dialog->dialog), TRUE);
 
 	return data;
@@ -800,7 +806,7 @@
 static gboolean
 formatted_input_cb(GtkWidget *win, GdkEventKey *event, gpointer data)
 {
-	if (event->keyval == GDK_Escape)
+	if (event->keyval == GDK_KEY_Escape)
 	{
 		purple_notify_close(PURPLE_NOTIFY_FORMATTED, win);
 
@@ -847,7 +853,7 @@
 					 G_CALLBACK(formatted_close_cb), NULL);
 
 	/* Setup the main vbox */
-	vbox = GTK_DIALOG(window)->vbox;
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(window));
 
 	/* Setup the descriptive label */
 	primary_esc = g_markup_escape_text(primary, -1);
@@ -978,7 +984,7 @@
 							 G_CALLBACK(searchresults_close_cb), data);
 
 	/* Setup the main vbox */
-	vbox = GTK_DIALOG(window)->vbox;
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(window));
 
 	/* Setup the descriptive label */
 	primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL;
@@ -1516,12 +1522,16 @@
 
 	/* Setup the dialog */
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BOX_SPACE);
-	gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BOX_SPACE);
+	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                                 PIDGIN_HIG_BOX_SPACE);
+  /* TODO: not sure if this is possible (or nessesary) in gtk+ 3
 	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
+  */
+	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                      PIDGIN_HIG_BORDER);
 
 	/* Vertical box */
-	vbox = GTK_DIALOG(dialog)->vbox;
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
 
 	/* Golden ratio it up! */
 	gtk_widget_set_size_request(dialog, 550, 400);
--- a/pidgin/gtkplugin.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkplugin.c	Wed Feb 02 23:26:42 2011 +0000
@@ -518,7 +518,7 @@
 			break;
 
 		dialog = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, GTK_WINDOW(d),
-						     GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
+						     GTK_DIALOG_DESTROY_WITH_PARENT,
 						     GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
 						     NULL);
 		if (plugin_pref_dialogs == NULL)
@@ -527,7 +527,7 @@
 		g_hash_table_insert(plugin_pref_dialogs, plug, dialog);
 
 		g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(pref_dialog_response_cb), plug);
-		gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), box);
+		gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), box);
 		gtk_window_set_role(GTK_WINDOW(dialog), "plugin_config");
 		gtk_window_set_title(GTK_WINDOW(dialog), _(purple_plugin_get_name(plug)));
 		gtk_widget_show_all(dialog);
@@ -562,10 +562,13 @@
 pidgin_plugins_paint_tooltip(GtkWidget *tipwindow, gpointer data)
 {
 	PangoLayout *layout = g_object_get_data(G_OBJECT(tipwindow), "tooltip-plugin");
-	gtk_paint_layout(tipwindow->style, tipwindow->window, GTK_STATE_NORMAL, FALSE,
-			NULL, tipwindow, "tooltip",
+  cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(tipwindow));
+  gtk_paint_layout(gtk_widget_get_style(tipwindow), cr, GTK_STATE_NORMAL, FALSE,
+			tipwindow, "tooltip",
 			6, 6, layout);
-	return TRUE;
+  cairo_destroy(cr);
+
+  return TRUE;
 }
 
 static gboolean
@@ -720,8 +723,9 @@
 
 	plugin_dialog = gtk_dialog_new_with_buttons(_("Plugins"),
 						    NULL,
-						    GTK_DIALOG_NO_SEPARATOR,
+						    0,
 						    NULL);
+
 	pref_button = gtk_dialog_add_button(GTK_DIALOG(plugin_dialog),
 						_("Configure Pl_ugin"), PIDGIN_RESPONSE_CONFIGURE);
 	gtk_dialog_add_button(GTK_DIALOG(plugin_dialog),
@@ -733,7 +737,8 @@
 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
 
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), sw, TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(plugin_dialog))),
+                     sw, TRUE, TRUE, 0);
 
 	ls = gtk_list_store_new(4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
 	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls),
@@ -793,8 +798,8 @@
 	gtk_expander_set_use_markup(GTK_EXPANDER(expander), TRUE);
 	gtk_widget_set_sensitive(expander, FALSE);
 	gtk_container_add(GTK_CONTAINER(expander), create_details());
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), expander,
-		FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(plugin_dialog))),
+    expander, FALSE, FALSE, 0);
 
 
 	g_signal_connect (G_OBJECT (sel), "changed", G_CALLBACK (prefs_plugin_sel), NULL);
--- a/pidgin/gtkpounce.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkpounce.c	Wed Feb 02 23:26:42 2011 +0000
@@ -410,13 +410,15 @@
 				GtkSelectionData *sd, guint info, guint t, gpointer data)
 {
 	PidginPounceDialog *dialog;
-
-	if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
+  GdkAtom target = gtk_selection_data_get_target(sd);
+  const guchar *sd_data = gtk_selection_data_get_data(sd);
+    
+	if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
 	{
 		PurpleBlistNode *node = NULL;
 		PurpleBuddy *buddy;
 
-		memcpy(&node, sd->data, sizeof(node));
+		memcpy(&node, sd_data, sizeof(node));
 
 		if (PURPLE_BLIST_NODE_IS_CONTACT(node))
 			buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
@@ -431,15 +433,15 @@
 		dialog->account = buddy->account;
 		pidgin_account_option_menu_set_selected(dialog->account_menu, buddy->account);
 
-		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
+		gtk_drag_finish(dc, TRUE, (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
 	}
-	else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE))
+	else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
 	{
 		char *protocol = NULL;
 		char *username = NULL;
 		PurpleAccount *account;
 
-		if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account,
+		if (pidgin_parse_x_im_contact((const char *) sd_data, FALSE, &account,
 										&protocol, &username, NULL))
 		{
 			if (account == NULL)
@@ -461,7 +463,7 @@
 		g_free(username);
 		g_free(protocol);
 
-		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
+		gtk_drag_finish(dc, TRUE, (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
 	}
 }
 
@@ -540,7 +542,7 @@
 					 G_CALLBACK(delete_win_cb), dialog);
 
 	/* Create the parent vbox for everything. */
-	vbox1 = GTK_DIALOG(window)->vbox;
+	vbox1 = gtk_dialog_get_content_area(GTK_DIALOG(window));
 
 	/* Create the vbox that will contain all the prefs stuff. */
 	vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
@@ -1018,7 +1020,7 @@
 static gboolean
 pounces_manager_configure_cb(GtkWidget *widget, GdkEventConfigure *event, PouncesManager *dialog)
 {
-	if (GTK_WIDGET_VISIBLE(widget)) {
+	if (gtk_widget_get_visible(widget)) {
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/pounces/dialog/width",  event->width);
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/pounces/dialog/height", event->height);
 	}
--- a/pidgin/gtkprefs.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkprefs.c	Wed Feb 02 23:26:42 2011 +0000
@@ -118,7 +118,7 @@
 		const char *key, int min, int max, GtkSizeGroup *sg)
 {
 	GtkWidget *spin;
-	GtkObject *adjust;
+	GtkAdjustment *adjust;
 	int val;
 
 	val = purple_prefs_get_int(key);
@@ -182,29 +182,49 @@
 	return pidgin_add_widget_to_vbox(GTK_BOX(page), title, sg, entry, TRUE, NULL);
 }
 
+/* TODO: Maybe move this up somewheres... */
+enum {
+	PREF_DROPDOWN_TEXT,
+	PREF_DROPDOWN_VALUE,
+	PREF_DROPDOWN_COUNT
+};
 
 static void
 dropdown_set(GObject *w, const char *key)
 {
 	const char *str_value;
 	int int_value;
+	gboolean bool_value;
 	PurplePrefType type;
+	GtkTreeIter iter;
+	GtkTreeModel *tree_model;
+
+	tree_model = gtk_combo_box_get_model(GTK_COMBO_BOX(w));
+	if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(w), &iter))
+		return;
 
 	type = GPOINTER_TO_INT(g_object_get_data(w, "type"));
 
 	if (type == PURPLE_PREF_INT) {
-		int_value = GPOINTER_TO_INT(g_object_get_data(w, "value"));
+		gtk_tree_model_get(tree_model, &iter,
+		                   PREF_DROPDOWN_VALUE, &int_value,
+		                   -1);
 
 		purple_prefs_set_int(key, int_value);
 	}
 	else if (type == PURPLE_PREF_STRING) {
-		str_value = (const char *)g_object_get_data(w, "value");
+		gtk_tree_model_get(tree_model, &iter,
+		                   PREF_DROPDOWN_VALUE, &str_value,
+		                   -1);
 
 		purple_prefs_set_string(key, str_value);
 	}
 	else if (type == PURPLE_PREF_BOOLEAN) {
-		purple_prefs_set_bool(key,
-				GPOINTER_TO_INT(g_object_get_data(w, "value")));
+		gtk_tree_model_get(tree_model, &iter,
+		                   PREF_DROPDOWN_VALUE, &bool_value,
+		                   -1);
+
+		purple_prefs_set_bool(key, bool_value);
 	}
 }
 
@@ -212,69 +232,86 @@
 pidgin_prefs_dropdown_from_list(GtkWidget *box, const gchar *title,
 		PurplePrefType type, const char *key, GList *menuitems)
 {
-	GtkWidget  *dropdown, *opt, *menu;
+	GtkWidget  *dropdown;
 	GtkWidget  *label = NULL;
 	gchar      *text;
 	const char *stored_str = NULL;
 	int         stored_int = 0;
+	gboolean    stored_bool = FALSE;
 	int         int_value  = 0;
 	const char *str_value  = NULL;
-	int         o = 0;
+	gboolean    bool_value = FALSE;
+	GtkListStore *store;
+	GtkTreeIter iter;
+	GtkTreeIter active;
+	GtkCellRenderer *renderer;
 
 	g_return_val_if_fail(menuitems != NULL, NULL);
 
-	dropdown = gtk_option_menu_new();
-	menu = gtk_menu_new();
-
-	if (type == PURPLE_PREF_INT)
+	if (type == PURPLE_PREF_INT) {
+		store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_INT);
 		stored_int = purple_prefs_get_int(key);
-	else if (type == PURPLE_PREF_STRING)
+	} else if (type == PURPLE_PREF_STRING) {
+		store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_STRING);
 		stored_str = purple_prefs_get_string(key);
-
-	while (menuitems != NULL && (text = (char *) menuitems->data) != NULL) {
+	} else if (type == PURPLE_PREF_BOOLEAN) {
+		store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_BOOLEAN);
+		stored_bool = purple_prefs_get_bool(key);
+	}
+
+	dropdown = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+	g_object_set_data(G_OBJECT(dropdown), "type", GINT_TO_POINTER(type));
+
+	while (menuitems != NULL && (text = (char *)menuitems->data) != NULL) {
 		menuitems = g_list_next(menuitems);
 		g_return_val_if_fail(menuitems != NULL, NULL);
 
-		opt = gtk_menu_item_new_with_label(text);
-
-		g_object_set_data(G_OBJECT(opt), "type", GINT_TO_POINTER(type));
+		gtk_list_store_append(store, &iter);
+		gtk_list_store_set(store, &iter,
+		                   PREF_DROPDOWN_TEXT, text,
+		                   -1);
 
 		if (type == PURPLE_PREF_INT) {
 			int_value = GPOINTER_TO_INT(menuitems->data);
-			g_object_set_data(G_OBJECT(opt), "value",
-							  GINT_TO_POINTER(int_value));
+			gtk_list_store_set(store, &iter,
+			                   PREF_DROPDOWN_VALUE, int_value,
+			                   -1);
 		}
 		else if (type == PURPLE_PREF_STRING) {
 			str_value = (const char *)menuitems->data;
-
-			g_object_set_data(G_OBJECT(opt), "value", (char *)str_value);
+			gtk_list_store_set(store, &iter,
+			                   PREF_DROPDOWN_VALUE, str_value,
+			                   -1);
 		}
 		else if (type == PURPLE_PREF_BOOLEAN) {
-			g_object_set_data(G_OBJECT(opt), "value",
-					menuitems->data);
+			bool_value = (gboolean)GPOINTER_TO_INT(menuitems->data);
+			gtk_list_store_set(store, &iter,
+			                   PREF_DROPDOWN_VALUE, bool_value,
+			                   -1);
 		}
 
-		g_signal_connect(G_OBJECT(opt), "activate",
-						 G_CALLBACK(dropdown_set), (char *)key);
-
-		gtk_widget_show(opt);
-		gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
-
 		if ((type == PURPLE_PREF_INT && stored_int == int_value) ||
 			(type == PURPLE_PREF_STRING && stored_str != NULL &&
 			 !strcmp(stored_str, str_value)) ||
 			(type == PURPLE_PREF_BOOLEAN &&
-			 (purple_prefs_get_bool(key) == GPOINTER_TO_INT(menuitems->data)))) {
-
-			gtk_menu_set_active(GTK_MENU(menu), o);
+			 (stored_bool == bool_value))) {
+
+			active = iter;
 		}
 
 		menuitems = g_list_next(menuitems);
-
-		o++;
 	}
 
-	gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu);
+	renderer = gtk_cell_renderer_text_new();
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dropdown), renderer, TRUE);
+	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dropdown), renderer,
+	                               "text", 0,
+	                               NULL);
+
+	gtk_combo_box_set_active_iter(GTK_COMBO_BOX(dropdown), &active);
+
+	g_signal_connect(G_OBJECT(dropdown), "changed",
+	                 G_CALLBACK(dropdown_set), (char *)key);
 
 	pidgin_add_widget_to_vbox(GTK_BOX(box), title, NULL, dropdown, FALSE, &label);
 
@@ -827,9 +864,10 @@
 theme_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
 		GtkSelectionData *sd, guint info, guint t, gpointer user_data)
 {
-	gchar *name = g_strchomp((gchar *)sd->data);
-
-	if ((sd->length >= 0) && (sd->format == 8)) {
+	gchar *name = g_strchomp((gchar *)gtk_selection_data_get_data(sd));
+
+	if ((gtk_selection_data_get_length(sd) >= 0)
+      && (gtk_selection_data_get_format(sd) == 8)) {
 		/* Well, it looks like the drag event was cool.
 		 * Let's do something with it */
 		gchar *temp;
@@ -2405,7 +2443,7 @@
 sound_page(void)
 {
 	GtkWidget *ret;
-	GtkWidget *vbox, *vbox2, *sw, *button;
+	GtkWidget *vbox, *vbox2, *sw, *button, *parent, *parent_parent, *parent_parent_parent;
 	GtkSizeGroup *sg;
 	GtkTreeIter iter;
 	GtkWidget *event_view;
@@ -2502,15 +2540,19 @@
 								sound_changed2_cb, vbox);
 #endif
 	vbox = pidgin_make_frame(ret, _("Sound Events"));
-
+  parent = gtk_widget_get_parent(vbox);
+  parent_parent = gtk_widget_get_parent(parent);
+  parent_parent_parent = gtk_widget_get_parent(parent_parent);
+    
 	/* The following is an ugly hack to make the frame expand so the
 	 * sound events list is big enough to be usable */
-	gtk_box_set_child_packing(GTK_BOX(vbox->parent), vbox, TRUE, TRUE, 0,
+	gtk_box_set_child_packing(GTK_BOX(parent), vbox, TRUE, TRUE, 0,
 			GTK_PACK_START);
-	gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent), vbox->parent, TRUE,
-			TRUE, 0, GTK_PACK_START);
-	gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent->parent),
-			vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START);
+	gtk_box_set_child_packing(GTK_BOX(parent_parent),
+      parent, TRUE, TRUE, 0, GTK_PACK_START);
+	gtk_box_set_child_packing(
+      GTK_BOX(parent_parent_parent),
+			parent_parent, TRUE, TRUE, 0, GTK_PACK_START);
 
 	/* SOUND SELECTION */
 	sw = gtk_scrolled_window_new(NULL,NULL);
--- a/pidgin/gtkprivacy.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkprivacy.c	Wed Feb 02 23:26:42 2011 +0000
@@ -243,7 +243,7 @@
 
 	gtk_widget_hide(dialog->allow_widget);
 	gtk_widget_hide(dialog->block_widget);
-	gtk_widget_hide_all(dialog->button_box);
+	gtk_widget_hide(dialog->button_box);
 
 	if (new_type == PURPLE_PRIVACY_ALLOW_USERS) {
 		gtk_widget_show(dialog->allow_widget);
@@ -371,12 +371,12 @@
 	dialog->account = pidgin_account_option_menu_get_selected(dropdown);
 
 	/* Add the drop-down list with the allow/block types. */
-	dialog->type_menu = gtk_combo_box_new_text();
+	dialog->type_menu = gtk_combo_box_text_new();
 	gtk_box_pack_start(GTK_BOX(vbox), dialog->type_menu, FALSE, FALSE, 0);
 	gtk_widget_show(dialog->type_menu);
 
 	for (i = 0; i < menu_entry_count; i++) {
-		gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->type_menu),
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(dialog->type_menu),
 		                          _(menu_entries[i].text));
 
 		if (menu_entries[i].num == dialog->account->perm_deny)
@@ -442,7 +442,7 @@
 		privacy_dialog = privacy_dialog_new();
 
 	gtk_widget_show(privacy_dialog->win);
-	gdk_window_raise(privacy_dialog->win->window);
+	gdk_window_raise(gtk_widget_get_window(privacy_dialog->win));
 }
 
 void
--- a/pidgin/gtkrequest.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkrequest.c	Wed Feb 02 23:26:42 2011 +0000
@@ -86,7 +86,9 @@
 {
 	GtkWidget *image;
 	GdkPixbuf *pixbuf;
+#if !GTK_CHECK_VERSION(2,12,0)
 	GtkTooltips *tips;
+#endif
 
 	if (!account)
 		return;
@@ -95,12 +97,18 @@
 	image = gtk_image_new_from_pixbuf(pixbuf);
 	g_object_unref(G_OBJECT(pixbuf));
 
+#if GTK_CHECK_VERSION(2,12,0)
+	gtk_widget_set_tooltip_text(image, purple_account_get_username(account));
+#else
 	tips = gtk_tooltips_new();
 	gtk_tooltips_set_tip(tips, image, purple_account_get_username(account), NULL);
+#endif
 
 	if (GTK_IS_DIALOG(cont)) {
-		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cont)->action_area), image, FALSE, TRUE, 0);
-		gtk_box_reorder_child(GTK_BOX(GTK_DIALOG(cont)->action_area), image, 0);
+		gtk_box_pack_start(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(cont))),
+                       image, FALSE, TRUE, 0);
+		gtk_box_reorder_child(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(cont))),
+                          image, 0);
 	} else if (GTK_IS_HBOX(cont)) {
 		gtk_misc_set_alignment(GTK_MISC(image), 0, 0);
 		gtk_box_pack_end(GTK_BOX(cont), image, FALSE, TRUE, 0);
@@ -257,7 +265,7 @@
 {
 	generic_response_start(data);
 
-	if (!GTK_WIDGET_HAS_FOCUS(button))
+	if (!gtk_widget_has_focus(button))
 		gtk_widget_grab_focus(button);
 
 	if (data->cbs[0] != NULL)
@@ -353,16 +361,21 @@
 
 	/* Setup the dialog */
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
-	gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
+	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                                 PIDGIN_HIG_BORDER / 2);
 	if (!multiline)
 		gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+  /* TODO: not sure how to do this with GTK+ 3 
 	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+  */
 	gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0);
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
+	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                      PIDGIN_HIG_BORDER);
 
 	/* Setup the main horizontal box */
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                    hbox);
 
 	/* Dialog icon. */
 	img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
@@ -530,14 +543,19 @@
 
 	/* Setup the dialog */
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
-	gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
+	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                                 PIDGIN_HIG_BORDER / 2);
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
+  /* TODO: don't know if this is possible with GTK+ 3
+  gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+  */
+	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                      PIDGIN_HIG_BORDER);
 
 	/* Setup the main horizontal box */
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                    hbox);
 
 	/* Dialog icon. */
 	img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
@@ -652,14 +670,19 @@
 
 	/* Setup the dialog */
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
-	gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
+	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                                 PIDGIN_HIG_BORDER / 2);
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
+  /* TODO: this is probably not supported by GTK+ 3
+  gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+  */
+	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                      PIDGIN_HIG_BORDER);
 
 	/* Setup the main horizontal box */
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+                    hbox);
 
 	/* Dialog icon. */
 	if (icon_data) {
@@ -730,8 +753,8 @@
 
 
 	if (default_action == PURPLE_DEFAULT_ACTION_NONE) {
-		GTK_WIDGET_SET_FLAGS(img, GTK_CAN_DEFAULT);
-		GTK_WIDGET_SET_FLAGS(img, GTK_CAN_FOCUS);
+    gtk_widget_set_can_default(img, TRUE);
+    gtk_widget_set_can_focus(img, TRUE);
 		gtk_widget_grab_focus(img);
 		gtk_widget_grab_default(img);
 	} else
@@ -976,12 +999,12 @@
 
 	if (num_labels > 5)
 	{
-		widget = gtk_combo_box_new_text();
+		widget = gtk_combo_box_text_new();
 
 		for (l = labels; l != NULL; l = l->next)
 		{
 			const char *text = l->data;
-			gtk_combo_box_append_text(GTK_COMBO_BOX(widget), text);
+			gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), text);
 		}
 
 		gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
@@ -1258,12 +1281,12 @@
 
 	/* Cancel button */
 	button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(cancel_text), G_CALLBACK(multifield_cancel_cb), data);
-	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+  gtk_widget_set_can_default(button, TRUE);
 
 	/* OK button */
 	button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(ok_text), G_CALLBACK(multifield_ok_cb), data);
 	data->ok_button = button;
-	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+  gtk_widget_set_can_default(button, TRUE);
 	gtk_window_set_default(GTK_WINDOW(win), button);
 
 	pidgin_widget_decorate_account(hbox, account);
--- a/pidgin/gtkroomlist.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkroomlist.c	Wed Feb 02 23:26:42 2011 +0000
@@ -359,8 +359,10 @@
 	int current_height, max_width;
 	int max_text_width;
 	GtkTextDirection dir = gtk_widget_get_direction(GTK_WIDGET(grl->tree));
-
-	style = grl->tipwindow->style;
+  cairo_t *cr =
+        gdk_cairo_create(gtk_widget_get_window(grl->tipwindow));
+    
+	style = gtk_widget_get_style(grl->tipwindow);
 
 	max_text_width = MAX(grl->tip_width, grl->tip_name_width);
 	max_width = TOOLTIP_BORDER + SMALL_SPACE + max_text_width + TOOLTIP_BORDER;
@@ -368,26 +370,28 @@
 	current_height = 12;
 
 	if (dir == GTK_TEXT_DIR_RTL) {
-		gtk_paint_layout(style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-				NULL, grl->tipwindow, "tooltip",
+		gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
+				grl->tipwindow, "tooltip",
 				max_width - (TOOLTIP_BORDER + SMALL_SPACE) - PANGO_PIXELS(600000),
 				current_height, grl->tip_name_layout);
 	} else {
-		gtk_paint_layout (style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-				NULL, grl->tipwindow, "tooltip",
+		gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
+				grl->tipwindow, "tooltip",
 				TOOLTIP_BORDER + SMALL_SPACE, current_height, grl->tip_name_layout);
 	}
 	if (dir != GTK_TEXT_DIR_RTL) {
-		gtk_paint_layout (style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-				NULL, grl->tipwindow, "tooltip",
+		gtk_paint_layout (style, cr, GTK_STATE_NORMAL, FALSE,
+				grl->tipwindow, "tooltip",
 				TOOLTIP_BORDER + SMALL_SPACE, current_height + grl->tip_name_height, grl->tip_layout);
 	} else {
-		gtk_paint_layout(style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-				NULL, grl->tipwindow, "tooltip",
+		gtk_paint_layout(style, cr, GTK_STATE_NORMAL, FALSE,
+				grl->tipwindow, "tooltip",
 				max_width - (TOOLTIP_BORDER + SMALL_SPACE) - PANGO_PIXELS(600000),
 				current_height + grl->tip_name_height,
 				grl->tip_layout);
 	}
+  cairo_destroy(cr);
+
 	return FALSE;
 }
 
--- a/pidgin/gtksavedstatuses.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtksavedstatuses.c	Wed Feb 02 23:26:42 2011 +0000
@@ -535,7 +535,7 @@
 static gboolean
 configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog)
 {
-	if (GTK_WIDGET_VISIBLE(widget))
+	if (gtk_widget_get_visible(widget))
 	{
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/status/dialog/width",  event->width);
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/status/dialog/height", event->height);
--- a/pidgin/gtkscrollbook.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkscrollbook.c	Wed Feb 02 23:26:42 2011 +0000
@@ -102,7 +102,7 @@
 
 	gtk_widget_show_all(GTK_WIDGET(scroll_book));
 	if (count < 1)
-		gtk_widget_hide_all(scroll_book->hbox);
+		gtk_widget_hide(scroll_book->hbox);
 	else {
 		gtk_widget_show_all(scroll_book->hbox);
 		if (count == 1) {
@@ -147,7 +147,7 @@
 }
 
 static void
-switch_page_cb(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, PidginScrollBook *scroll_book)
+switch_page_cb(GtkNotebook *notebook, GtkWidget *page, guint page_num, PidginScrollBook *scroll_book)
 {
 	int count;
 	count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook));
@@ -160,7 +160,7 @@
 	PidginScrollBook *scroll_book;
 
 	g_return_if_fail(GTK_IS_WIDGET (widget));
-	g_return_if_fail (widget->parent == NULL);
+	g_return_if_fail (gtk_widget_get_parent(widget) == NULL);
 
 	scroll_book = PIDGIN_SCROLL_BOOK(container);
 	scroll_book->children = g_list_append(scroll_book->children, widget);
--- a/pidgin/gtksmiley.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtksmiley.c	Wed Feb 02 23:26:42 2011 +0000
@@ -399,7 +399,7 @@
 
 	window = gtk_dialog_new_with_buttons(smiley ? _("Edit Smiley") : _("Add Smiley"),
 			widget ? GTK_WINDOW(widget) : NULL,
-			GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+			GTK_DIALOG_DESTROY_WITH_PARENT,
 			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 			smiley ? GTK_STOCK_SAVE : GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT,
 			NULL);
@@ -414,7 +414,8 @@
 
 	/* The vbox */
 	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), vbox);
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))),
+                    vbox);
 	gtk_widget_show(vbox);
 
 	/* The hbox */
@@ -727,9 +728,10 @@
 		GtkSelectionData *sd, guint info, guint t, gpointer user_data)
 {
 	SmileyManager *dialog = user_data;
-	gchar *name = g_strchomp((gchar *)sd->data);
-
-	if ((sd->length >= 0) && (sd->format == 8)) {
+	gchar *name = g_strchomp((gchar *) gtk_selection_data_get_data(sd));
+    
+	if ((gtk_selection_data_get_length(sd) >= 0)
+      && (gtk_selection_data_get_format(sd) == 8)) {
 		/* Well, it looks like the drag event was cool.
 		 * Let's do something with it */
 
@@ -895,7 +897,8 @@
 
 	/* The vbox */
 	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(win)->vbox), vbox);
+	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(win))),
+                    vbox);
 	gtk_widget_show(vbox);
 
 	/* get the scrolled window with all stuff */
--- a/pidgin/gtksourceundomanager.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtksourceundomanager.c	Wed Feb 02 23:26:42 2011 +0000
@@ -532,7 +532,8 @@
 					um->priv->document,
 					undo_action->action.insert_anchor.pos,
 					undo_action->action.insert_anchor.pos + 1);
-				undo_action->action.insert_anchor.anchor->segment = NULL; /* XXX: This may be a bug in GTK+ */
+				/* TODO: is this needed in GTK+ 3? */
+				/*gtk_text_child_anchor_set_segment(undo_action->action.insert_anchor.anchor, NULL); XXX: This may be a bug in GTK+ */
 				break;
 			default:
 				/* Unknown action type. */
--- a/pidgin/gtkstatusbox.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkstatusbox.c	Wed Feb 02 23:26:42 2011 +0000
@@ -82,9 +82,10 @@
 static void status_menu_refresh_iter(PidginStatusBox *status_box, gboolean status_changed);
 static void pidgin_status_box_regenerate(PidginStatusBox *status_box, gboolean status_changed);
 static void pidgin_status_box_changed(PidginStatusBox *box);
-static void pidgin_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition);
+static void pidgin_status_box_get_preferred_height (GtkWidget *widget,
+	gint *minimum_height, gint *natural_height);
 static void pidgin_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean pidgin_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event);
+static gboolean pidgin_status_box_draw (GtkWidget *widget, cairo_t *cr);
 static void pidgin_status_box_redisplay_buddy_icon(PidginStatusBox *status_box);
 static void pidgin_status_box_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
 static void pidgin_status_box_popup(PidginStatusBox *box);
@@ -282,7 +283,7 @@
 
 		if (!message || !*message)
 		{
-			gtk_widget_hide_all(status_box->vbox);
+			gtk_widget_hide(status_box->vbox);
 			status_box->imhtml_visible = FALSE;
 		}
 		else
@@ -343,9 +344,10 @@
 icon_box_dnd_cb(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
 		GtkSelectionData *sd, guint info, guint t, PidginStatusBox *box)
 {
-	gchar *name = (gchar *)sd->data;
-
-	if ((sd->length >= 0) && (sd->format == 8)) {
+	gchar *name = (gchar *) gtk_selection_data_get_data(sd);
+
+	if ((gtk_selection_data_get_length(sd) >= 0)
+      && (gtk_selection_data_get_format(sd) == 8)) {
 		/* Well, it looks like the drag event was cool.
 		 * Let's do something with it */
 		if (!g_ascii_strncasecmp(name, "file://", 7)) {
@@ -419,7 +421,7 @@
 static gboolean
 icon_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, PidginStatusBox *box)
 {
-	gdk_window_set_cursor(widget->window, box->hand_cursor);
+	gdk_window_set_cursor(gtk_widget_get_window(widget), box->hand_cursor);
 	gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon_hover);
 	return FALSE;
 }
@@ -427,7 +429,7 @@
 static gboolean
 icon_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, PidginStatusBox *box)
 {
-	gdk_window_set_cursor(widget->window, box->arrow_cursor);
+	gdk_window_set_cursor(gtk_widget_get_window(widget), box->arrow_cursor);
 	gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon) ;
 	return FALSE;
 }
@@ -615,9 +617,9 @@
 	parent_class = g_type_class_peek_parent(klass);
 
 	widget_class = (GtkWidgetClass*)klass;
-	widget_class->size_request = pidgin_status_box_size_request;
+	widget_class->get_preferred_height = pidgin_status_box_get_preferred_height;
 	widget_class->size_allocate = pidgin_status_box_size_allocate;
-	widget_class->expose_event = pidgin_status_box_expose_event;
+  	widget_class->draw = pidgin_status_box_draw;
 
 	container_class->child_type = pidgin_status_box_child_type;
 	container_class->forall = pidgin_status_box_forall;
@@ -931,7 +933,7 @@
 		if (!purple_savedstatus_is_transient(saved_status) || !message || !*message)
 		{
 			status_box->imhtml_visible = FALSE;
-			gtk_widget_hide_all(status_box->vbox);
+			gtk_widget_hide(status_box->vbox);
 		}
 		else
 		{
@@ -1135,7 +1137,7 @@
 
 static gboolean imhtml_remove_focus(GtkWidget *w, GdkEventKey *event, PidginStatusBox *status_box)
 {
-	if (event->keyval == GDK_Tab || event->keyval == GDK_KP_Tab || event->keyval == GDK_ISO_Left_Tab)
+	if (event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_KP_Tab || event->keyval == GDK_KEY_ISO_Left_Tab)
 	{
 		/* If last inserted character is a tab, then remove the focus from here */
 		GtkWidget *top = gtk_widget_get_toplevel(w);
@@ -1148,7 +1150,7 @@
 		return FALSE;
 
 	/* Reset the status if Escape was pressed */
-	if (event->keyval == GDK_Escape)
+	if (event->keyval == GDK_KEY_Escape)
 	{
 		purple_timeout_remove(status_box->typing);
 		status_box->typing = 0;
@@ -1299,13 +1301,15 @@
   GdkRectangle monitor;
   GtkRequisition popup_req;
   GtkPolicyType hpolicy, vpolicy;
-
-  gdk_window_get_origin (GTK_WIDGET(status_box)->window, x, y);
-
-  *x += GTK_WIDGET(status_box)->allocation.x;
-  *y += GTK_WIDGET(status_box)->allocation.y;
-
-  *width = GTK_WIDGET(status_box)->allocation.width;
+  GtkAllocation allocation;
+
+  gtk_widget_get_allocation(GTK_WIDGET(status_box), &allocation);
+  gdk_window_get_origin (gtk_widget_get_window(GTK_WIDGET(status_box)), x, y);
+
+  *x += allocation.x;
+  *y += allocation.y;
+
+  *width = allocation.width;
 
   hpolicy = vpolicy = GTK_POLICY_NEVER;
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (status_box->scrolled_window),
@@ -1324,7 +1328,7 @@
 
   screen = gtk_widget_get_screen (GTK_WIDGET (status_box));
   monitor_num = gdk_screen_get_monitor_at_window (screen,
-						  GTK_WIDGET (status_box)->window);
+						  gtk_widget_get_window(GTK_WIDGET (status_box)));
   gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
 
   if (*x < monitor.x)
@@ -1332,13 +1336,13 @@
   else if (*x + *width > monitor.x + monitor.width)
     *x = monitor.x + monitor.width - *width;
 
-  if (*y + GTK_WIDGET(status_box)->allocation.height + *height <= monitor.y + monitor.height)
-	  *y += GTK_WIDGET(status_box)->allocation.height;
+  if (*y + allocation.height + *height <= monitor.y + monitor.height)
+	  *y += allocation.height;
   else if (*y - *height >= monitor.y)
 	  *y -= *height;
-  else if (monitor.y + monitor.height - (*y + GTK_WIDGET(status_box)->allocation.height) > *y - monitor.y)
+  else if (monitor.y + monitor.height - (*y + allocation.height) > *y - monitor.y)
     {
-	    *y += GTK_WIDGET(status_box)->allocation.height;
+	    *y += allocation.height;
 	    *height = monitor.y + monitor.height - *y;
     }
   else
@@ -1369,7 +1373,7 @@
 		if (!grab_keyboard || gdk_keyboard_grab (window, TRUE, activate_time) == 0)
 			return TRUE;
 		else {
-			gdk_display_pointer_ungrab (gdk_drawable_get_display (window), activate_time);
+			gdk_display_pointer_ungrab (gdk_window_get_display (window), activate_time);
 			return FALSE;
 		}
 	}
@@ -1388,7 +1392,7 @@
 	gtk_window_move (GTK_WINDOW (box->popup_window), x, y);
 	gtk_widget_show(box->popup_window);
 	gtk_widget_grab_focus (box->tree_view);
-	if (!popup_grab_on_window (box->popup_window->window,
+	if (!popup_grab_on_window (gtk_widget_get_window(box->popup_window),
 				   GDK_CURRENT_TIME, TRUE)) {
 		gtk_widget_hide (box->popup_window);
 		return;
@@ -1419,10 +1423,10 @@
 toggle_key_press_cb(GtkWidget *widget, GdkEventKey *event, PidginStatusBox *box)
 {
 	switch (event->keyval) {
-		case GDK_Return:
-		case GDK_KP_Enter:
-		case GDK_KP_Space:
-		case GDK_space:
+		case GDK_KEY_Return:
+		case GDK_KEY_KP_Enter:
+		case GDK_KEY_KP_Space:
+		case GDK_KEY_space:
 			if (!box->popup_in_progress) {
 				pidgin_status_box_popup (box);
 				box->popup_in_progress = TRUE;
@@ -1654,7 +1658,7 @@
 			GdkEventKey *event, PidginStatusBox *box)
 {
 	if (box->popup_in_progress) {
-		if (event->keyval == GDK_Escape) {
+		if (event->keyval == GDK_KEY_Escape) {
 			pidgin_status_box_popdown(box);
 			return TRUE;
 		} else {
@@ -1665,9 +1669,9 @@
 			if (gtk_tree_selection_get_selected(sel, NULL, &iter)) {
 				gboolean ret = TRUE;
 				path = gtk_tree_model_get_path(GTK_TREE_MODEL(box->dropdown_store), &iter);
-				if (event->keyval == GDK_Return) {
+				if (event->keyval == GDK_KEY_Return) {
 					treeview_activate_current_selection(box, path);
-				} else if (event->keyval == GDK_Delete) {
+				} else if (event->keyval == GDK_KEY_Delete) {
 					tree_view_delete_current_selection(box, path);
 				} else
 					ret = FALSE;
@@ -1743,7 +1747,7 @@
 	GtkWidget *toplevel;
 	GtkTreeSelection *sel;
 
-	GTK_WIDGET_SET_FLAGS (status_box, GTK_NO_WINDOW);
+	gtk_widget_set_has_window(GTK_WIDGET(status_box), FALSE);
 	status_box->imhtml_visible = FALSE;
 	status_box->network_available = purple_network_is_available();
 	status_box->connecting = FALSE;
@@ -1928,24 +1932,27 @@
 }
 
 static void
-pidgin_status_box_size_request(GtkWidget *widget,
-								 GtkRequisition *requisition)
+pidgin_status_box_get_preferred_height(GtkWidget *widget, gint *minimum_height,
+                                       gint *natural_height)
 {
-	GtkRequisition box_req;
-	gint border_width = GTK_CONTAINER (widget)->border_width;
-
-	gtk_widget_size_request(PIDGIN_STATUS_BOX(widget)->toggle_button, requisition);
-
-	/* Make this icon the same size as other buddy icons in the list; unless it already wants to be bigger */
-	requisition->height = MAX(requisition->height, 34);
-	requisition->height += border_width * 2;
+	gint box_min_height, box_nat_height;
+	gint border_width = gtk_container_get_border_width(GTK_CONTAINER (widget));
+	
+	gtk_widget_get_preferred_height(PIDGIN_STATUS_BOX(widget)->toggle_button,
+		minimum_height, natural_height);
+
+	*minimum_height = MAX(*minimum_height, 34) + border_width * 2;
+	*natural_height = MAX(*natural_height, 34) + border_width * 2;
 
 	/* If the gtkimhtml is visible, then add some additional padding */
-	gtk_widget_size_request(PIDGIN_STATUS_BOX(widget)->vbox, &box_req);
-	if (box_req.height > 1)
-		requisition->height += box_req.height + border_width * 2;
-
-	requisition->width = 1;
+	gtk_widget_get_preferred_height(PIDGIN_STATUS_BOX(widget)->vbox,
+		&box_min_height, &box_nat_height);
+
+	if (box_min_height > 1)
+		*minimum_height += box_min_height + border_width * 2;
+
+	if (box_nat_height > 1)
+		*natural_height += box_nat_height + border_width * 2;
 }
 
 /* From gnome-panel */
@@ -1993,9 +2000,9 @@
 				  GtkAllocation *allocation)
 {
 	PidginStatusBox *status_box = PIDGIN_STATUS_BOX(widget);
-	GtkRequisition req = {0,0};
+	GtkRequisition req = {0,40};
 	GtkAllocation parent_alc, box_alc, icon_alc;
-	gint border_width = GTK_CONTAINER (widget)->border_width;
+	gint border_width = gtk_container_get_border_width(GTK_CONTAINER (widget));
 
 	gtk_widget_size_request(status_box->toggle_button, &req);
 	/* Make this icon the same size as other buddy icons in the list; unless it already wants to be bigger */
@@ -2034,19 +2041,24 @@
 		gtk_widget_size_allocate(status_box->icon_box, &icon_alc);
 	}
 	gtk_widget_size_allocate(status_box->toggle_button, &parent_alc);
-	widget->allocation = *allocation;
+  	gtk_widget_set_allocation(GTK_WIDGET(status_box), allocation);
+	purple_debug_info("pidgin", "statusbox allocation: width = %d, height = %d\n",
+	                  allocation->width, allocation->height);
 }
 
 static gboolean
-pidgin_status_box_expose_event(GtkWidget *widget,
-				 GdkEventExpose *event)
+pidgin_status_box_draw(GtkWidget *widget, cairo_t *cr)
 {
 	PidginStatusBox *status_box = PIDGIN_STATUS_BOX(widget);
-	gtk_container_propagate_expose(GTK_CONTAINER(widget), status_box->vbox, event);
-	gtk_container_propagate_expose(GTK_CONTAINER(widget), status_box->toggle_button, event);
+	gtk_widget_draw(status_box->vbox, cr);
+	gtk_widget_draw(status_box->toggle_button, cr);
+
 	if (status_box->icon_box && status_box->icon_opaque) {
-		gtk_paint_box(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL,
-				status_box->icon_box, "button", status_box->icon_box->allocation.x-1, status_box->icon_box->allocation.y-1,
+		GtkAllocation allocation;
+
+		gtk_widget_get_allocation(status_box->icon_box, &allocation);
+		gtk_paint_box(gtk_widget_get_style(widget), cr, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+				status_box->icon_box, "button", allocation.x-1, allocation.y-1,
 				34, 34);
 	}
 	return FALSE;
@@ -2333,7 +2345,7 @@
 	message = pidgin_status_box_get_message(status_box);
 	if (!message || !*message)
 	{
-		gtk_widget_hide_all(status_box->vbox);
+		gtk_widget_hide(status_box->vbox);
 		status_box->imhtml_visible = FALSE;
 		if (message != NULL)
 		{
@@ -2605,7 +2617,7 @@
 		purple_timeout_remove(status_box->typing);
 	status_box->typing = 0;
 
-	if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
+	if (gtk_widget_get_sensitive(GTK_WIDGET(status_box)))
 	{
 		if (type == PIDGIN_STATUS_BOX_TYPE_POPULAR || type == PIDGIN_STATUS_BOX_TYPE_SAVED_POPULAR)
 		{
@@ -2667,7 +2679,7 @@
 	}
 	g_list_free(accounts);
 
-	if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
+	if (gtk_widget_get_sensitive(GTK_WIDGET(status_box)))
 	{
 		if (status_box->imhtml_visible)
 		{
@@ -2687,7 +2699,7 @@
 		}
 		else
 		{
-			gtk_widget_hide_all(status_box->vbox);
+			gtk_widget_hide(status_box->vbox);
 			activate_currently_selected_status(status_box); /* This is where we actually set the status */
 		}
 	}
@@ -2723,7 +2735,7 @@
 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data)
 {
 	PidginStatusBox *status_box = (PidginStatusBox*)data;
-	if (GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(status_box)))
+	if (gtk_widget_get_sensitive(GTK_WIDGET(status_box)))
 	{
 		if (status_box->typing != 0) {
 			pidgin_status_box_pulse_typing(status_box);
--- a/pidgin/gtkutils.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkutils.c	Wed Feb 02 23:26:42 2011 +0000
@@ -70,7 +70,7 @@
 #include "pidgin/minidialog.h"
 
 typedef struct {
-	GtkWidget *menu;
+	GtkTreeModel *model;
 	gint default_item;
 } AopMenu;
 
@@ -180,7 +180,6 @@
 
 	wnd = GTK_WINDOW(gtk_dialog_new());
 	pidgin_window_init(wnd, title, border_width, role, resizable);
-	g_object_set(G_OBJECT(wnd), "has-separator", FALSE, NULL);
 
 	return GTK_WIDGET(wnd);
 }
@@ -188,7 +187,7 @@
 GtkWidget *
 pidgin_dialog_get_vbox_with_properties(GtkDialog *dialog, gboolean homogeneous, gint spacing)
 {
-	GtkBox *vbox = GTK_BOX(GTK_DIALOG(dialog)->vbox);
+	GtkBox *vbox = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
 	gtk_box_set_homogeneous(vbox, homogeneous);
 	gtk_box_set_spacing(vbox, spacing);
 	return GTK_WIDGET(vbox);
@@ -196,12 +195,12 @@
 
 GtkWidget *pidgin_dialog_get_vbox(GtkDialog *dialog)
 {
-	return GTK_DIALOG(dialog)->vbox;
+	return gtk_dialog_get_content_area(GTK_DIALOG(dialog));
 }
 
 GtkWidget *pidgin_dialog_get_action_area(GtkDialog *dialog)
 {
-	return GTK_DIALOG(dialog)->action_area;
+	return gtk_dialog_get_action_area(GTK_DIALOG(dialog));
 }
 
 GtkWidget *pidgin_dialog_add_button(GtkDialog *dialog, const char *label,
@@ -297,7 +296,7 @@
 	if (to_toggle == NULL)
 		return;
 
-	sensitivity = GTK_WIDGET_IS_SENSITIVE(to_toggle);
+	sensitivity = gtk_widget_get_sensitive(to_toggle);
 
 	gtk_widget_set_sensitive(to_toggle, !sensitivity);
 }
@@ -314,7 +313,7 @@
 		if (element == NULL)
 			continue;
 
-		sensitivity = GTK_WIDGET_IS_SENSITIVE(element);
+		sensitivity = gtk_widget_get_sensitive(element);
 
 		gtk_widget_set_sensitive(element, !sensitivity);
 	}
@@ -326,7 +325,7 @@
 	if (to_toggle == NULL)
 		return;
 
-	if (GTK_WIDGET_VISIBLE(to_toggle))
+	if (gtk_widget_get_visible(to_toggle))
 		gtk_widget_hide(to_toggle);
 	else
 		gtk_widget_show(to_toggle);
@@ -1299,8 +1298,8 @@
 
 	widget     = GTK_WIDGET(menu);
 	screen     = gtk_widget_get_screen(widget);
-	xthickness = widget->style->xthickness;
-	ythickness = widget->style->ythickness;
+	xthickness = gtk_widget_get_style(widget)->xthickness;
+	ythickness = gtk_widget_get_style(widget)->ythickness;
 	rtl        = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL);
 
 	/*
@@ -1438,9 +1437,9 @@
 	GtkTreePath *path;
 	GtkTreeViewColumn *col;
 	GdkRectangle rect;
-	gint ythickness = GTK_WIDGET(menu)->style->ythickness;
-
-	gdk_window_get_origin (widget->window, x, y);
+	gint ythickness = gtk_widget_get_style(GTK_WIDGET(menu))->ythickness;
+
+	gdk_window_get_origin (gtk_widget_get_window(widget), x, y);
 	gtk_tree_view_get_cursor (tv, &path, &col);
 	gtk_tree_view_get_cell_area (tv, path, col, &rect);
 
@@ -1557,7 +1556,7 @@
 pidgin_dnd_file_manage(GtkSelectionData *sd, PurpleAccount *account, const char *who)
 {
 	GdkPixbuf *pb;
-	GList *files = purple_uri_list_extract_filenames((const gchar *)sd->data);
+	GList *files = purple_uri_list_extract_filenames((const gchar *) gtk_selection_data_get_data(sd));
 	PurpleConnection *gc = purple_account_get_connection(account);
 	PurplePluginProtocolInfo *prpl_info = NULL;
 #ifndef _WIN32
@@ -1875,7 +1874,9 @@
 
 		group = gtk_menu_get_accel_group(GTK_MENU(menu));
 		if (group) {
-			char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label);
+			char *path = g_strdup_printf("%s/%s",
+                    gtk_menu_item_get_accel_path(GTK_MENU_ITEM(menuitem)),
+                    act->label);
 			gtk_menu_set_accel_path(GTK_MENU(submenu), path);
 			g_free(path);
 			gtk_menu_set_accel_group(GTK_MENU(submenu), group);
@@ -2198,23 +2199,23 @@
 	GdkCursor *cursor;
 
 	g_return_if_fail(widget != NULL);
-	if (widget->window == NULL)
+	if (gtk_widget_get_window(widget) == NULL)
 		return;
 
 	cursor = gdk_cursor_new(cursor_type);
-	gdk_window_set_cursor(widget->window, cursor);
+	gdk_window_set_cursor(gtk_widget_get_window(widget), cursor);
 	gdk_cursor_unref(cursor);
 
-	gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
+	gdk_display_flush(gdk_window_get_display(gtk_widget_get_window(widget)));
 }
 
 void pidgin_clear_cursor(GtkWidget *widget)
 {
 	g_return_if_fail(widget != NULL);
-	if (widget->window == NULL)
+	if (gtk_widget_get_window(widget) == NULL)
 		return;
 
-	gdk_window_set_cursor(widget->window, NULL);
+	gdk_window_set_cursor(gtk_widget_get_window(widget), NULL);
 }
 
 struct _icon_chooser {
@@ -2901,18 +2902,18 @@
 }
 
 static void
-combo_box_changed_cb(GtkComboBox *combo_box, GtkEntry *entry)
+combo_box_changed_cb(GtkComboBoxText *combo_box, GtkEntry *entry)
 {
-	char *text = gtk_combo_box_get_active_text(combo_box);
+	char *text = gtk_combo_box_text_get_active_text(combo_box);
 	gtk_entry_set_text(entry, text ? text : "");
 	g_free(text);
 }
 
 static gboolean
-entry_key_pressed_cb(GtkWidget *entry, GdkEventKey *key, GtkComboBox *combo)
+entry_key_pressed_cb(GtkWidget *entry, GdkEventKey *key, GtkComboBoxText *combo)
 {
-	if (key->keyval == GDK_Down || key->keyval == GDK_Up) {
-		gtk_combo_box_popup(combo);
+	if (key->keyval == GDK_KEY_Down || key->keyval == GDK_KEY_Up) {
+		gtk_combo_box_popup(GTK_COMBO_BOX(combo));
 		return TRUE;
 	}
 	return FALSE;
@@ -2921,10 +2922,10 @@
 GtkWidget *
 pidgin_text_combo_box_entry_new(const char *default_item, GList *items)
 {
-	GtkComboBox *ret = NULL;
+	GtkComboBoxText *ret = NULL;
 	GtkWidget *the_entry = NULL;
 
-	ret = GTK_COMBO_BOX(gtk_combo_box_entry_new_text());
+	ret = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
 	the_entry = gtk_entry_new();
 	gtk_container_add(GTK_CONTAINER(ret), the_entry);
 
@@ -2934,7 +2935,7 @@
 	for (; items != NULL ; items = items->next) {
 		char *text = items->data;
 		if (text && *text)
-			gtk_combo_box_append_text(ret, text);
+			gtk_combo_box_text_append_text(ret, text);
 	}
 
 	g_signal_connect(G_OBJECT(ret), "changed", (GCallback)combo_box_changed_cb, the_entry);
@@ -2945,12 +2946,12 @@
 
 const char *pidgin_text_combo_box_entry_get_text(GtkWidget *widget)
 {
-	return gtk_entry_get_text(GTK_ENTRY(GTK_BIN((widget))->child));
+	return gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((widget)))));
 }
 
 void pidgin_text_combo_box_entry_set_text(GtkWidget *widget, const char *text)
 {
-	gtk_entry_set_text(GTK_ENTRY(GTK_BIN((widget))->child), (text));
+	gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((widget)))), (text));
 }
 
 GtkWidget *
@@ -3071,12 +3072,12 @@
 		windows = g_list_delete_link(windows, windows);
 
 		if (window == widget ||
-				!GTK_WIDGET_VISIBLE(window)) {
+				!gtk_widget_get_visible(window)) {
 			continue;
 		}
 
 		if (gtk_window_has_toplevel_focus(GTK_WINDOW(window)) ||
-				(menu && menu == window->window)) {
+				(menu && menu == gtk_widget_get_window(window))) {
 			parent = window;
 			break;
 		}
--- a/pidgin/gtkutils.h	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkutils.h	Wed Feb 02 23:26:42 2011 +0000
@@ -402,21 +402,6 @@
 void pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *optmenu, gboolean all);
 
 /**
- * Check if the given path is a directory or not.  If it is, then modify
- * the given GtkFileSelection dialog so that it displays the given path.
- * If the given path is not a directory, then do nothing.
- *
- * @param path    The path entered in the file selection window by the user.
- * @param filesel The file selection window.
- *
- * @return TRUE if given path is a directory, FALSE otherwise.
- * @deprecated Pidgin no longer uses GtkFileSelection internally. It has also
- *             been deprecated by GTK+. Use GtkFileChooser instead and ignore
- *             this function.
- */
-gboolean pidgin_check_if_dir(const char *path, GtkFileSelection *filesel);
-
-/**
  * Sets up GtkSpell for the given GtkTextView, reporting errors
  * if encountered.
  *
--- a/pidgin/gtkwhiteboard.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkwhiteboard.c	Wed Feb 02 23:26:42 2011 +0000
@@ -280,13 +280,13 @@
 	/* TODO Ask if user wants to save picture before the session is closed */
 
 	/* Clear graphical memory */
-	if(gtkwb->pixmap)
+	if(gtkwb->pixbuf)
 	{
-		cairo_t *cr = g_object_get_data(G_OBJECT(gtkwb->pixmap), "cairo-context");
+		cairo_t *cr = g_object_get_data(G_OBJECT(gtkwb->pixbuf), "cairo-context");
 		if (cr)
 			cairo_destroy(cr);
-		g_object_unref(gtkwb->pixmap);
-		gtkwb->pixmap = NULL;
+		g_object_unref(gtkwb->pixbuf);
+		gtkwb->pixbuf = NULL;
 	}
 
 	colour_dialog = g_object_get_data(G_OBJECT(gtkwb->window), "colour-dialog");
@@ -356,28 +356,32 @@
 static gboolean pidgin_whiteboard_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixmap *pixmap = gtkwb->pixmap;
+	GdkPixbuf *pixbuf = gtkwb->pixbuf;
 	cairo_t *cr;
-
-	if (pixmap) {
-		cr = g_object_get_data(G_OBJECT(pixmap), "cairo-context");
+	GdkWindow *window = gtk_widget_get_window(widget);
+	GtkAllocation allocation;
+    
+	if (pixbuf) {
+		cr = g_object_get_data(G_OBJECT(pixbuf), "cairo-context");
 		if (cr)
 			cairo_destroy(cr);
-		g_object_unref(pixmap);
+		g_object_unref(pixbuf);
 	}
 
-	pixmap = gdk_pixmap_new(widget->window,
-							widget->allocation.width,
-							widget->allocation.height,
-							-1);
-	gtkwb->pixmap = pixmap;
+	gtk_widget_get_allocation(widget, &allocation);
+    
+	pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+    	FALSE, gdk_visual_get_depth(GDK_VISUAL(window)),
+		allocation.width, allocation.height);
+                                                    
+	gtkwb->pixbuf = pixbuf;
 
-	cr = gdk_cairo_create(GDK_DRAWABLE(pixmap));
-	g_object_set_data(G_OBJECT(pixmap), "cairo-context", cr);
-	gdk_cairo_set_source_color(cr, &widget->style->white);
+	cr = gdk_cairo_create(gtk_widget_get_window(widget));
+	g_object_set_data(G_OBJECT(pixbuf), "cairo-context", cr);
+	gdk_cairo_set_source_color(cr, &gtk_widget_get_style(widget)->white);
 	cairo_rectangle(cr,
 	                0, 0,
-	                widget->allocation.width, widget->allocation.height);
+	                allocation.width, allocation.height);
 	cairo_fill(cr);
 
 	return TRUE;
@@ -386,11 +390,11 @@
 static gboolean pidgin_whiteboard_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)(data);
-	GdkPixmap *pixmap = gtkwb->pixmap;
+	GdkPixbuf *pixbuf = gtkwb->pixbuf;
 	cairo_t *cr;
 
-	cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
-	gdk_cairo_set_source_pixmap(cr, pixmap, 0, 0);
+	cr = gdk_cairo_create(gtk_widget_get_window(widget));
+	gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
 	cairo_rectangle(cr,
 	                event->area.x, event->area.y,
 	                event->area.width, event->area.height);
@@ -403,7 +407,7 @@
 static gboolean pidgin_whiteboard_brush_down(GtkWidget *widget, GdkEventButton *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixmap *pixmap = gtkwb->pixmap;
+	GdkPixbuf *pixbuf = gtkwb->pixbuf;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = wb->draw_list;
@@ -418,7 +422,7 @@
 
 	BrushState = BRUSH_STATE_DOWN;
 
-	if(event->button == 1 && pixmap != NULL)
+	if(event->button == 1 && pixbuf != NULL)
 	{
 		/* Check if draw_list has contents; if so, clear it */
 		if(draw_list)
@@ -456,7 +460,7 @@
 	GdkModifierType state;
 
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixmap *pixmap = gtkwb->pixmap;
+	GdkPixbuf *pixbuf = gtkwb->pixbuf;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = wb->draw_list;
@@ -470,7 +474,7 @@
 		state = event->state;
 	}
 
-	if(state & GDK_BUTTON1_MASK && pixmap != NULL)
+	if(state & GDK_BUTTON1_MASK && pixbuf != NULL)
 	{
 		if((BrushState != BRUSH_STATE_DOWN) && (BrushState != BRUSH_STATE_MOTION))
 		{
@@ -536,7 +540,7 @@
 static gboolean pidgin_whiteboard_brush_up(GtkWidget *widget, GdkEventButton *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixmap *pixmap = gtkwb->pixmap;
+	GdkPixbuf *pixbuf = gtkwb->pixbuf;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = wb->draw_list;
@@ -551,7 +555,7 @@
 	}
 	BrushState = BRUSH_STATE_UP;
 
-	if(event->button == 1 && pixmap != NULL)
+	if(event->button == 1 && pixbuf != NULL)
 	{
 		/* If the brush was never moved, express two sets of two deltas That's a
 		 * 'point,' but not for Yahoo!
@@ -593,9 +597,9 @@
 {
 	PidginWhiteboard *gtkwb = wb->ui_data;
 	GtkWidget *widget = gtkwb->drawing_area;
-	GdkPixmap *pixmap = gtkwb->pixmap;
+	GdkPixbuf *pixbuf = gtkwb->pixbuf;
 
-	cairo_t *gfx_con = g_object_get_data(G_OBJECT(pixmap), "cairo-context");
+	cairo_t *gfx_con = g_object_get_data(G_OBJECT(pixbuf), "cairo-context");
 	GdkColor col;
 
 	/* Interpret and convert color */
@@ -701,21 +705,24 @@
 static void pidgin_whiteboard_clear(PurpleWhiteboard *wb)
 {
 	PidginWhiteboard *gtkwb = wb->ui_data;
-	GdkPixmap *pixmap = gtkwb->pixmap;
+	GdkPixbuf *pixbuf = gtkwb->pixbuf;
 	GtkWidget *drawing_area = gtkwb->drawing_area;
-	cairo_t *cr = g_object_get_data(G_OBJECT(pixmap), "cairo-context");
+	cairo_t *cr = g_object_get_data(G_OBJECT(pixbuf), "cairo-context");
+  GtkAllocation allocation;
 
-	gdk_cairo_set_source_color(cr, &drawing_area->style->white);
+  gtk_widget_get_allocation(drawing_area, &allocation);
+    
+	gdk_cairo_set_source_color(cr, &gtk_widget_get_style(drawing_area)->white);
 	cairo_rectangle(cr,
 	                0, 0,
-	                drawing_area->allocation.width,
-	                drawing_area->allocation.height);
+	                allocation.width,
+	                allocation.height);
 	cairo_fill(cr);
 
 	gtk_widget_queue_draw_area(drawing_area,
 							   0, 0,
-							   drawing_area->allocation.width,
-							   drawing_area->allocation.height);
+							   allocation.width,
+							   allocation.height);
 }
 
 static void pidgin_whiteboard_button_clear_press(GtkWidget *widget, gpointer data)
@@ -781,12 +788,15 @@
 		gtk_widget_destroy(dialog);
 
 		/* Makes an icon from the whiteboard's canvas 'image' */
+    pixbuf = gtkwb->pixbuf;
+    /*
 		pixbuf = gdk_pixbuf_get_from_drawable(NULL,
 											  (GdkDrawable*)(gtkwb->pixmap),
 											  gdk_drawable_get_colormap(gtkwb->pixmap),
 											  0, 0,
 											  0, 0,
 											  gtkwb->width, gtkwb->height);
+    */
 
 		if(gdk_pixbuf_save(pixbuf, filename, "jpeg", NULL, "quality", "100", NULL))
 			purple_debug_info("gtkwhiteboard", "File Saved...\n");
@@ -807,12 +817,15 @@
 	GdkPixbuf *pixbuf;
 
 	/* Makes an icon from the whiteboard's canvas 'image' */
+  pixbuf = gtkwb->pixbuf;
+  /*
 	pixbuf = gdk_pixbuf_get_from_drawable(NULL,
 										  (GdkDrawable*)(gtkwb->pixmap),
 										  gdk_drawable_get_colormap(gtkwb->pixmap),
 										  0, 0,
 										  0, 0,
 										  gtkwb->width, gtkwb->height);
+  */
 
 	gtk_window_set_icon((GtkWindow*)(gtkwb->window), pixbuf);
 }
@@ -853,23 +866,29 @@
 {
 	GdkColor color;
 	GtkColorSelectionDialog *dialog;
-
+  GtkWidget *ok_button;
+    
 	dialog = (GtkColorSelectionDialog *)gtk_color_selection_dialog_new(_("Select color"));
 	g_object_set_data(G_OBJECT(gtkwb->window), "colour-dialog", dialog);
 
-	g_signal_connect(G_OBJECT(dialog->colorsel), "color-changed",
+	g_signal_connect(G_OBJECT(gtk_color_selection_dialog_get_color_selection(dialog)),
+          "color-changed",
 					G_CALLBACK(change_color_cb), gtkwb);
 
+  /*
 	gtk_widget_destroy(dialog->cancel_button);
 	gtk_widget_destroy(dialog->help_button);
-
-	g_signal_connect(G_OBJECT(dialog->ok_button), "clicked",
+  */
+  g_object_get(G_OBJECT(dialog), "ok-button", &ok_button, NULL);
+      
+	g_signal_connect(G_OBJECT(ok_button), "clicked",
 					G_CALLBACK(color_selection_dialog_destroy), gtkwb);
 
-	gtk_color_selection_set_has_palette(GTK_COLOR_SELECTION(dialog->colorsel), TRUE);
+	gtk_color_selection_set_has_palette(GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(dialog)), TRUE);
 
 	pidgin_whiteboard_rgb24_to_rgb48(gtkwb->brush_color, &color);
-	gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(dialog->colorsel), &color);
+	gtk_color_selection_set_current_color(
+      GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(dialog)), &color);
 
 	gtk_widget_show_all(GTK_WIDGET(dialog));
 }
--- a/pidgin/gtkwhiteboard.h	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/gtkwhiteboard.h	Wed Feb 02 23:26:42 2011 +0000
@@ -51,7 +51,7 @@
 	GtkWidget *window;       /**< Window for the Doodle session */
 	GtkWidget *drawing_area; /**< Drawing area */
 
-	GdkPixmap *pixmap;       /**< Memory for drawing area */
+	GdkPixbuf *pixbuf;       /**< Memory for drawing area */
 
 	int  width;              /**< Canvas width */
 	int  height;             /**< Canvas height */
--- a/pidgin/minidialog.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/minidialog.c	Wed Feb 02 23:26:42 2011 +0000
@@ -160,7 +160,7 @@
 guint
 pidgin_mini_dialog_get_num_children(PidginMiniDialog *mini_dialog)
 {
-	return g_list_length(mini_dialog->contents->children);
+	return g_list_length(gtk_container_get_children(GTK_CONTAINER(mini_dialog->contents)));
 }
 
 static gboolean
--- a/pidgin/pidgintooltip.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/pidgintooltip.c	Wed Feb 02 23:26:42 2011 +0000
@@ -101,11 +101,16 @@
 }
 
 static gboolean
-pidgin_tooltip_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
+pidgin_tooltip_draw_cb(GtkWidget *widget, cairo_t *cr, gpointer data)
 {
+	GtkAllocation allocation;
+
+	gtk_widget_get_allocation(widget, &allocation);
+
 	if (pidgin_tooltip.paint_tooltip) {
-		gtk_paint_flat_box(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-				NULL, widget, "tooltip", 0, 0, -1, -1);
+		gtk_paint_flat_box(gtk_widget_get_style(widget), cr,
+			GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+			widget, "tooltip", 0, 0, allocation.width, allocation.height);
 		pidgin_tooltip.paint_tooltip(widget, data);
 	}
 	return FALSE;
@@ -179,8 +184,8 @@
 	gtk_window_move(GTK_WINDOW(tipwindow), x, y);
 	gtk_widget_show(tipwindow);
 
-	g_signal_connect(G_OBJECT(tipwindow), "expose_event",
-			G_CALLBACK(pidgin_tooltip_expose_event), data);
+	g_signal_connect(G_OBJECT(tipwindow), "draw",
+			G_CALLBACK(pidgin_tooltip_draw_cb), data);
 
 	/* Hide the tooltip when the widget is destroyed */
 	sig = g_signal_connect(G_OBJECT(pidgin_tooltip.widget), "destroy", G_CALLBACK(pidgin_tooltip_destroy), NULL);
--- a/pidgin/plugins/contact_priority.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/contact_priority.c	Wed Feb 02 23:26:42 2011 +0000
@@ -35,11 +35,11 @@
 }
 
 static void
-account_update(GtkWidget *widget, GtkOptionMenu *optmenu)
+account_update(GtkWidget *widget, GtkWidget *optmenu)
 {
 	PurpleAccount *account = NULL;
 
-	account = g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(optmenu)))), "account");
+	account = pidgin_account_option_menu_get_selected(optmenu);
 	purple_account_set_int(account, "score", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)));
 }
 
@@ -75,7 +75,7 @@
 	GtkWidget *ret = NULL, *hbox = NULL, *frame = NULL, *vbox = NULL;
 	GtkWidget *label = NULL, *spin = NULL, *check = NULL;
 	GtkWidget *optmenu = NULL;
-	GtkObject *adj = NULL;
+	GtkAdjustment *adj = NULL;
 	GtkSizeGroup *sg = NULL;
 	PurpleAccount *account = NULL;
 	int i;
@@ -147,8 +147,7 @@
 	gtk_box_pack_start(GTK_BOX(hbox), optmenu, FALSE, FALSE, 0);
 
 	/* this is where we set up the spin button we made above */
-	account = g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu))))),
-	                            "account");
+	account = pidgin_account_option_menu_get_selected(optmenu);
 	gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin),
 	                          (gdouble)purple_account_get_int(account, "score", 0));
 	gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(spin), GTK_ADJUSTMENT(adj));
--- a/pidgin/plugins/convcolors.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/convcolors.c	Wed Feb 02 23:26:42 2011 +0000
@@ -302,7 +302,7 @@
 }
 
 static void
-disconnect_prefs_callbacks(GtkObject *object, gpointer data)
+disconnect_prefs_callbacks(GtkWidget *widget, gpointer data)
 {
 	PurplePlugin *plugin = (PurplePlugin *)data;
 
@@ -383,7 +383,7 @@
 		purple_prefs_connect_callback(plugin, tmp2, enable_toggled, button);
 	}
 
-	g_signal_connect(GTK_OBJECT(ret), "destroy", G_CALLBACK(disconnect_prefs_callbacks), plugin);
+	g_signal_connect(ret, "destroy", G_CALLBACK(disconnect_prefs_callbacks), plugin);
 	frame = pidgin_make_frame(ret, _("General"));
 	pidgin_prefs_checkbox(_("Ignore incoming format"), PREF_IGNORE, frame);
 	pidgin_prefs_checkbox(_("Apply in Chats"), PREF_CHATS, frame);
--- a/pidgin/plugins/disco/gtkdisco.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/disco/gtkdisco.c	Wed Feb 02 23:26:42 2011 +0000
@@ -429,15 +429,12 @@
 static gboolean
 disco_paint_tooltip(GtkWidget *tipwindow, gpointer data)
 {
+	cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(tipwindow));
 	PangoLayout *layout = g_object_get_data(G_OBJECT(tipwindow), "tooltip-plugin");
-#if GTK_CHECK_VERSION(2,14,0)
 	gtk_paint_layout(gtk_widget_get_style(tipwindow),
-			gtk_widget_get_window(tipwindow),
+			cr,
 			GTK_STATE_NORMAL, FALSE,
-#else
-	gtk_paint_layout(tipwindow->style, tipwindow->window, GTK_STATE_NORMAL, FALSE,
-#endif
-			NULL, tipwindow, "tooltip",
+			tipwindow, "tooltip",
 			6, 6, layout);
 	return TRUE;
 }
--- a/pidgin/plugins/gestures/stroke-draw.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/gestures/stroke-draw.c	Wed Feb 02 23:26:42 2011 +0000
@@ -339,7 +339,7 @@
   unsigned int border_width;
   XSizeHints hints;
   Display *disp = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(widget));
-  Window wind = GDK_WINDOW_XWINDOW (gtk_widget_get_window(widget));
+  Window wind = gdk_x11_window_get_xid(gtk_widget_get_window(widget));
   int screen = DefaultScreen (disp);
 
 	if (!gstroke_draw_strokes())
--- a/pidgin/plugins/markerline.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/markerline.c	Wed Feb 02 23:26:42 2011 +0000
@@ -76,6 +76,7 @@
 	gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT,
 										0, last_y, 0, &y);
 
+  /* TODO: port this to using Cairo 
 	if (y >= event->area.y)
 	{
 		GdkColor red = {0, 0xffff, 0, 0};
@@ -88,6 +89,7 @@
 		cairo_stroke(cr);
 		cairo_destroy(cr);
 	}
+  */
 	return FALSE;
 }
 
--- a/pidgin/plugins/themeedit.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/themeedit.c	Wed Feb 02 23:26:42 2011 +0000
@@ -306,7 +306,6 @@
 		}
 	}
 
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), TRUE);
 #ifdef NOT_SADRUL
 	pidgin_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_SAVE, G_CALLBACK(save_blist_theme), dialog);
 #endif
--- a/pidgin/plugins/ticker/gtkticker.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/ticker/gtkticker.c	Wed Feb 02 23:26:42 2011 +0000
@@ -21,28 +21,24 @@
  * GtkTicker Copyright 2000 Syd Logan
  */
 
-/* FIXME: GTK+ deprecated GTK_WIDGET_MAPPED/REALIZED, but don't provide
-          accessor functions yet. */
-#undef GSEAL_ENABLE
-
 #include "gtkticker.h"
 #include <gtk/gtk.h>
 
-/* These don't seem to be in a release yet. See BZ #69872 */
-#define gtk_widget_is_mapped(x) GTK_WIDGET_MAPPED(x)
-#define gtk_widget_is_realized(x) GTK_WIDGET_REALIZED(x)
+#if !GTK_CHECK_VERSION(2,20,0)
+#define gtk_widget_get_mapped(x) GTK_WIDGET_MAPPED(x)
+#define gtk_widget_set_mapped(x,y) do {\
+	if (y) \
+		GTK_WIDGET_SET_FLAGS(x, GTK_MAPPED); \
+	else \
+		GTK_WIDGET_UNSET_FLAGS(x, GTK_MAPPED); \
+} while(0)
+#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x)
 #define gtk_widget_set_realized(x,y) do {\
 	if (y) \
 		GTK_WIDGET_SET_FLAGS(x, GTK_REALIZED); \
 	else \
 		GTK_WIDGET_UNSET_FLAGS(x, GTK_REALIZED); \
 } while(0)
-#define gtk_widget_set_mapped(x,y) do {\
-	if (y) \
-		GTK_WIDGET_SET_FLAGS(x, GTK_MAPPED); \
-	else \
-		GTK_WIDGET_UNSET_FLAGS(x, GTK_MAPPED); \
-} while(0)
 
 #if !GTK_CHECK_VERSION(2,18,0)
 #define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
@@ -51,6 +47,7 @@
 #define gtk_widget_get_window(x) x->window
 #endif
 #endif
+#endif
 
 static void gtk_ticker_compute_offsets (GtkTicker    *ticker);
 static void gtk_ticker_class_init    (GtkTickerClass    *klass);
@@ -131,7 +128,7 @@
 
 	widget_class->map = gtk_ticker_map;
 	widget_class->realize = gtk_ticker_realize;
-	widget_class->size_request = gtk_ticker_size_request;
+	/*widget_class->size_request = gtk_ticker_size_request;*/
 	widget_class->size_allocate = gtk_ticker_size_allocate;
 
 	container_class->add = gtk_ticker_add_real;
@@ -181,13 +178,13 @@
 
 	ticker->children = g_list_append (ticker->children, child_info);
 
-	if (gtk_widget_is_realized (ticker))
+	if (gtk_widget_get_realized (GTK_WIDGET(ticker)))
 		gtk_widget_realize (widget);
 
 	if (gtk_widget_get_visible (GTK_WIDGET (ticker)) &&
 		gtk_widget_get_visible (widget))
 	{
-		if (gtk_widget_is_mapped (GTK_WIDGET (ticker)))
+		if (gtk_widget_get_mapped (GTK_WIDGET (ticker)))
 			gtk_widget_map (widget);
 
 		gtk_widget_queue_resize (GTK_WIDGET (ticker));
@@ -298,7 +295,7 @@
 		children = children->next;
 
 		if (gtk_widget_get_visible (child->widget) &&
-				!gtk_widget_is_mapped (child->widget))
+				!gtk_widget_get_mapped (child->widget))
 			gtk_widget_map (child->widget);
 	}
 
@@ -335,11 +332,11 @@
 #endif
 	attributes.wclass = GDK_INPUT_OUTPUT;
 	attributes.visual = gtk_widget_get_visual (widget);
-	attributes.colormap = gtk_widget_get_colormap (widget);
+	/*attributes.colormap = gtk_widget_get_colormap (widget);*/
 	attributes.event_mask = gtk_widget_get_events (widget);
 	attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
 
-	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL /*| GDK_WA_COLORMAP*/;
 
 	window = gdk_window_new (gtk_widget_get_parent_window (widget),
 			&attributes, attributes_mask);
@@ -474,7 +471,7 @@
 #else
 	widget->allocation = *allocation;
 #endif
-	if (gtk_widget_is_realized (widget))
+	if (gtk_widget_get_realized (widget))
 		gdk_window_move_resize (gtk_widget_get_window (widget),
 				allocation->x,
 				allocation->y,
--- a/pidgin/plugins/timestamp.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/timestamp.c	Wed Feb 02 23:26:42 2011 +0000
@@ -134,7 +134,7 @@
 	GtkWidget *ret;
 	GtkWidget *frame, *label;
 	GtkWidget *vbox, *hbox;
-	GtkObject *adj;
+	GtkAdjustment *adj;
 	GtkWidget *spinner;
 
 	ret = gtk_vbox_new(FALSE, 18);
--- a/pidgin/plugins/timestamp_format.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/timestamp_format.c	Wed Feb 02 23:26:42 2011 +0000
@@ -155,8 +155,9 @@
 	if (!frame)
 		return;
 
+  /* GTK_DIALOG_NO_SEPARATOR seems to be gone in gtk+ 3.0... */
 	dialog = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, NULL,
-			GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
+			GTK_DIALOG_DESTROY_WITH_PARENT,
 			GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
 			NULL);
 	g_signal_connect_after(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), dialog);
--- a/pidgin/plugins/vvconfig.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/vvconfig.c	Wed Feb 02 23:26:42 2011 +0000
@@ -493,14 +493,14 @@
 }
 
 static void
-config_destroy(GtkObject *w, gpointer nul)
+config_destroy(GtkWidget *w, gpointer nul)
 {
 	purple_debug_info("vvconfig", "closing vv configuration window\n");
 	window = NULL;
 }
 
 static void
-config_close(GtkObject *w, gpointer nul)
+config_close(GtkWidget *w, gpointer nul)
 {
 	gtk_widget_destroy(GTK_WIDGET(window));
 }
--- a/pidgin/plugins/xmppconsole.c	Wed Feb 02 06:26:19 2011 +0000
+++ b/pidgin/plugins/xmppconsole.c	Wed Feb 02 23:26:42 2011 +0000
@@ -274,7 +274,7 @@
 							GTK_STOCK_OK,
 							GTK_RESPONSE_ACCEPT,
 							NULL);
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+	/* TODO: how to set no separator for GtkDialog in gtk+ 3.0... */
 	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
 #if GTK_CHECK_VERSION(2,14,0)
@@ -302,11 +302,11 @@
 
 	gtk_size_group_add_widget(sg, label);
 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	type_combo = gtk_combo_box_new_text();
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "get");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "set");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "result");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "error");
+	type_combo = gtk_combo_box_text_new();
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "get");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "set");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "result");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "error");
 	gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);
 	gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
 
@@ -325,7 +325,7 @@
 				 to && *to ? to : "",
 				 to && *to ? "'" : "",
 				 g_random_int(),
-				 gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo)));
+				 gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(type_combo)));
 
 	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry));
 	gtk_text_buffer_set_text(buffer, stanza, -1);
@@ -362,7 +362,9 @@
 							GTK_STOCK_OK,
 							GTK_RESPONSE_ACCEPT,
 							NULL);
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+
+  /* TODO: find a way to specify no separator for a dialog in gtk+ 3 */
+  /*gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);*/
 	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
 #if GTK_CHECK_VERSION(2,14,0)
@@ -389,15 +391,15 @@
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_size_group_add_widget(sg, label);
 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	type_combo = gtk_combo_box_new_text();
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "default");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unavailable");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "subscribe");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unsubscribe");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "subscribed");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "unsubscribed");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "probe");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "error");
+	type_combo = gtk_combo_box_text_new();
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "default");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "unavailable");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "subscribe");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "unsubscribe");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "subscribed");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "unsubscribed");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "probe");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "error");
 	gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);
 	gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
 
@@ -407,12 +409,12 @@
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_size_group_add_widget(sg, label);
 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	show_combo = gtk_combo_box_new_text();
-	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "default");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "away");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "dnd");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "xa");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(show_combo), "chat");
+	show_combo = gtk_combo_box_text_new();
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "default");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "away");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "dnd");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "xa");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(show_combo), "chat");
 
 	gtk_combo_box_set_active(GTK_COMBO_BOX(show_combo), 0);
 	gtk_box_pack_start(GTK_BOX(hbox), show_combo, FALSE, FALSE, 0);
@@ -450,10 +452,10 @@
 	}
 
 	to = gtk_entry_get_text(GTK_ENTRY(to_entry));
-	type = gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo));
+	type = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(type_combo));
 	if (!strcmp(type, "default"))
 		type = "";
-	show = gtk_combo_box_get_active_text(GTK_COMBO_BOX(show_combo));
+	show = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(show_combo));
 	if (!strcmp(show, "default"))
 		show = "";
 	status = gtk_entry_get_text(GTK_ENTRY(status_entry));
@@ -520,7 +522,8 @@
 							GTK_STOCK_OK,
 							GTK_RESPONSE_ACCEPT,
 							NULL);
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+  /* TODO: find a way to create a dialog without separtor in gtk+ 3 */
+	/*gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);*/
 	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
 #if GTK_CHECK_VERSION(2,14,0)
@@ -547,12 +550,12 @@
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_size_group_add_widget(sg, label);
 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	type_combo = gtk_combo_box_new_text();
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "chat");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "headline");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "groupchat");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "normal");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(type_combo), "error");
+	type_combo = gtk_combo_box_text_new();
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "chat");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "headline");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "groupchat");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "normal");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type_combo), "error");
 	gtk_combo_box_set_active(GTK_COMBO_BOX(type_combo), 0);
 	gtk_box_pack_start(GTK_BOX(hbox), type_combo, FALSE, FALSE, 0);
 
@@ -613,7 +616,8 @@
 	                         *to ? to : "",
 	                         *to ? "'" : "",
 	                         g_random_int(),
-	                         gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo)),
+	                         gtk_combo_box_text_get_active_text(
+                               GTK_COMBO_BOX_TEXT(type_combo)),
 
 	                         *body ? "<body>" : "",
 	                         *body ? body : "",
@@ -643,7 +647,8 @@
 	if (!console)
 		return;
 
-	gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown), purple_account_get_username(gc->account));
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(console->dropdown),
+      purple_account_get_username(gc->account));
 	console->accounts = g_list_append(console->accounts, gc);
 	console->count++;
 
@@ -674,7 +679,7 @@
 	if (l == NULL)
 		return;
 
-	gtk_combo_box_remove_text(GTK_COMBO_BOX(console->dropdown), i);
+	gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(console->dropdown), i);
 	console->accounts = g_list_remove(console->accounts, gc);
 	console->count--;
 
@@ -716,7 +721,7 @@
 }
 
 static void
-console_destroy(GtkObject *window, gpointer nul)
+console_destroy(GtkWidget *window, gpointer nul)
 {
 	g_list_free(console->accounts);
 	g_free(console);
@@ -731,8 +736,9 @@
 	if (!console)
 		return;
 
-	account = purple_accounts_find(gtk_combo_box_get_active_text(GTK_COMBO_BOX(console->dropdown)),
-				    "prpl-jabber");
+	account =
+      purple_accounts_find(gtk_combo_box_text_get_active_text(
+          GTK_COMBO_BOX_TEXT(console->dropdown)), "prpl-jabber");
 	if (!account || !account->gc)
 		return;
 
@@ -768,13 +774,13 @@
 	label = gtk_label_new(_("Account: "));
 	gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
 	gtk_box_pack_start(GTK_BOX(console->hbox), label, FALSE, FALSE, 0);
-	console->dropdown = gtk_combo_box_new_text();
+	console->dropdown = gtk_combo_box_text_new();
 	for (connections = purple_connections_get_all(); connections; connections = connections->next) {
 		PurpleConnection *gc = connections->data;
 		if (!strcmp(purple_account_get_protocol_id(purple_connection_get_account(gc)), "prpl-jabber")) {
 			console->count++;
 			console->accounts = g_list_append(console->accounts, gc);
-			gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown),
+			gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(console->dropdown),
 						  purple_account_get_username(purple_connection_get_account(gc)));
 			if (!console->gc)
 				console->gc = gc;