Merge GTK+3 branch.

Tue, 24 Jul 2012 03:43:55 -0400

author
Elliott Sales de Andrade <qulogic@pidgin.im>
date
Tue, 24 Jul 2012 03:43:55 -0400
changeset 33187
b2fdbd09f180
parent 33118
3113b96a5b7b (current diff)
parent 33186
b5cbcb29cc51 (diff)
child 33189
13e4ae613a6a
child 33190
78caf0131930

Merge GTK+3 branch.

Fixes #8932.

--- a/configure.ac	Mon Jul 23 20:13:26 2012 -0400
+++ b/configure.ac	Tue Jul 24 03:43:55 2012 -0400
@@ -372,6 +372,9 @@
 AC_ARG_ENABLE(gtkui, [AC_HELP_STRING([--disable-gtkui],
 		[compile without GTK+ user interface])],
 	enable_gtkui="$enableval", enable_gtkui="yes")
+AC_ARG_WITH(gtk, [AC_HELP_STRING([--with-gtk=<version>],
+		[compile with GTK+ 2 or 3 user interface (default: auto)])],
+	with_gtk="$withval", with_gtk="auto")
 AC_ARG_ENABLE(consoleui, [AC_HELP_STRING([--disable-consoleui],
 		[compile without console user interface])],
 	[enable_consoleui=$enableval force_finch=$enableval], [enable_consoleui=yes force_finch=no])
@@ -428,15 +431,35 @@
 fi
 
 if test "x$enable_gtkui" = "xyes" ; then
-	PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.10.0], , [
-		AC_MSG_RESULT(no)
-		AC_MSG_ERROR([
-
+	if test "x$with_gtk" = "x3"; then
+		PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 3.0.0], , [
+			AC_MSG_RESULT(no)
+			AC_MSG_ERROR([
+You must have GTK+ 3.0.0 or newer development headers installed to compile
+Pidgin.  If you want to build only Finch then specify --disable-gtkui when
+running configure.
+])])
+	elif test "x$with_gtk" = "x2"; then
+		PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.10.0], , [
+			AC_MSG_RESULT(no)
+			AC_MSG_ERROR([
 You must have GTK+ 2.10.0 or newer development headers installed to compile
 Pidgin.  If you want to build only Finch then specify --disable-gtkui when
 running configure.
 ])])
-
+	elif test "x$with_gtk" = "xauto"; then
+		PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 3.0.0], [with_gtk=3], [
+			AC_MSG_RESULT(no)
+			PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.10.0], [with_gtk=2], [
+				AC_MSG_RESULT(no)
+				AC_MSG_ERROR([
+You must have GTK+ 2.10.0 or newer development headers installed to compile
+Pidgin.  If you want to build only Finch then specify --disable-gtkui when
+running configure.
+])])])
+	else
+		AC_MSG_ERROR([--with-gtk must specify one of 2, 3 or auto.])
+	fi
 	AC_SUBST(GTK_CFLAGS)
 	AC_SUBST(GTK_LIBS)
 
@@ -444,13 +467,23 @@
 	PKG_CHECK_MODULES(PANGO, [pango >= 1.4.0],
 			AC_DEFINE(HAVE_PANGO14, 1, [Define if we have Pango 1.4 or newer.]),:)
 
-	PKG_CHECK_MODULES(WEBKIT, [webkit-1.0 >= 1.1.1], , [
-		AC_MSG_RESULT(no)
-		AC_MSG_ERROR([
+	if test "x$with_gtk" = "x3"; then
+		PKG_CHECK_MODULES(WEBKIT, [webkitgtk-3.0 >= 1.1.1], , [
+			AC_MSG_RESULT(no)
+			AC_MSG_ERROR([
 You must have WebKit 1.1.1 or newer development headers installed to compile
 Pidgin.  If you want to build only Finch then specify --disable-gtkui when
 running configure.
 ])])
+	else
+		PKG_CHECK_MODULES(WEBKIT, [webkit-1.0 >= 1.1.1], , [
+			AC_MSG_RESULT(no)
+			AC_MSG_ERROR([
+You must have WebKit 1.1.1 or newer development headers installed to compile
+Pidgin.  If you want to build only Finch then specify --disable-gtkui when
+running configure.
+])])
+	fi
 	AC_SUBST(WEBKIT_CFLAGS)
 	AC_SUBST(WEBKIT_LIBS)
 
@@ -565,6 +598,10 @@
 	dnl #######################################################################
 	dnl # Check for GtkSpell
 	dnl #######################################################################
+	dnl GtkSpell is not GTK+3 compatible yet
+	if test "x$with_gtk" = "x3"; then
+		enable_gtkspell="no"
+	fi
 	if test "x$enable_gtkspell" = "xyes" ; then
 		PKG_CHECK_MODULES(GTKSPELL, gtkspell-2.0 >= 2.0.2, , [
 			AC_MSG_RESULT(no)
@@ -629,16 +666,29 @@
 	dnl # Check for GCR for its certificate widgets
 	dnl #######################################################################
 	if test "x$enable_gcr" = "xyes"; then
-		PKG_CHECK_MODULES(GCR, gcr-0, [
-			AC_DEFINE(ENABLE_GCR, 1, [Define to 1 if GCR is found.])], [
-			AC_MSG_RESULT(no)
-			enable_gcr="no"
-			if test "x$force_deps" = "xyes" ; then
-				AC_MSG_ERROR([
+		if test "x$with_gtk" = "x3"; then
+			PKG_CHECK_MODULES(GCR, gcr-3, [
+				AC_DEFINE(ENABLE_GCR, 1, [Define to 1 if GCR is found.])], [
+				AC_MSG_RESULT(no)
+				enable_gcr="no"
+				if test "x$force_deps" = "xyes" ; then
+					AC_MSG_ERROR([
 GCR development headers not found.
 Use --disable-gcr if you do not need GCR certificate widgets.
 ])
-			fi])
+				fi])
+		else
+			PKG_CHECK_MODULES(GCR, gcr-0, [
+				AC_DEFINE(ENABLE_GCR, 1, [Define to 1 if GCR is found.])], [
+				AC_MSG_RESULT(no)
+				enable_gcr="no"
+				if test "x$force_deps" = "xyes" ; then
+					AC_MSG_ERROR([
+GCR development headers not found.
+Use --disable-gcr if you do not need GCR certificate widgets.
+])
+				fi])
+		fi
 	fi
 
 
@@ -2589,7 +2639,10 @@
 echo $PACKAGE $VERSION
 
 echo
-echo Build GTK+ 2.x UI............. : $enable_gtkui
+echo Build GTK+ UI................. : $enable_gtkui
+if test "x$enable_gtkui" = "xyes"; then
+	echo Build for GTK+ version........ : $with_gtk
+fi
 echo Build console UI.............. : $enable_consoleui
 echo Build for X11................. : $with_x
 echo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/gtk3compat.h	Tue Jul 24 03:43:55 2012 -0400
@@ -0,0 +1,172 @@
+/* pidgin
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+#ifndef _PIDGINGTK3COMPAT_H_
+#define _PIDGINGTK3COMPAT_H_
+
+/* This file is internal to Pidgin. Do not use!
+ * Also, any public API should not depend on this file.
+ */
+
+#if !GTK_CHECK_VERSION(3,0,0)
+
+#define gdk_x11_window_get_xid GDK_WINDOW_XWINDOW
+
+#if !GTK_CHECK_VERSION(2,24,0)
+
+#define gdk_x11_set_sm_client_id gdk_set_sm_client_id
+#define gdk_window_get_display gdk_drawable_get_display
+#define GtkComboBoxText GtkComboBox
+#define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX
+#define gtk_combo_box_text_new gtk_combo_box_new_text
+#define gtk_combo_box_text_append_text gtk_combo_box_append_text
+#define gtk_combo_box_text_get_active_text gtk_combo_box_get_active_text
+#define gtk_combo_box_text_remove gtk_combo_box_remove_text
+
+static inline gint gdk_window_get_width(GdkWindow *x)
+{
+	gint w;
+	gdk_drawable_get_size(GDK_DRAWABLE(x), &w, NULL);
+	return w;
+}
+
+static inline gint gdk_window_get_height(GdkWindow *x)
+{
+	gint h;
+	gdk_drawable_get_size(GDK_DRAWABLE(x), NULL, &h);
+	return h;
+}
+
+#if !GTK_CHECK_VERSION(2,22,0)
+
+#define gdk_drag_context_get_actions(x) (x)->action
+#define gdk_drag_context_get_suggested_action(x) (x)->suggested_action
+#define gtk_text_view_get_vadjustment(x) (x)->vadjustment
+#define gtk_font_selection_dialog_get_font_selection(x) (x)->fontsel
+
+#if !GTK_CHECK_VERSION(2,20,0)
+
+#define gtk_widget_get_mapped GTK_WIDGET_MAPPED
+#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 GTK_WIDGET_REALIZED
+#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)
+
+#if !GTK_CHECK_VERSION(2,18,0)
+
+#define gtk_widget_get_state GTK_WIDGET_STATE
+#define gtk_widget_is_drawable GTK_WIDGET_DRAWABLE
+#define gtk_widget_get_visible GTK_WIDGET_VISIBLE
+#define gtk_widget_has_focus GTK_WIDGET_HAS_FOCUS
+#define gtk_widget_is_sensitive GTK_WIDGET_IS_SENSITIVE
+#define gtk_widget_get_has_window(x) !GTK_WIDGET_NO_WINDOW(x)
+#define gtk_widget_set_has_window(x,y) do { \
+	if (!y) \
+		GTK_WIDGET_SET_FLAGS(x, GTK_NO_WINDOW); \
+	else \
+		GTK_WIDGET_UNSET_FLAGS(x, GTK_NO_WINDOW); \
+} while(0)
+#define gtk_widget_get_allocation(x,y) *(y) = (x)->allocation
+#define gtk_widget_set_allocation(x,y) (x)->allocation = *(y)
+#define gtk_widget_set_window(x,y) ((x)->window = (y))
+#define gtk_widget_set_can_default(w,y) do { \
+	if (y) \
+		GTK_WIDGET_SET_FLAGS((w), GTK_CAN_DEFAULT); \
+	else \
+		GTK_WIDGET_UNSET_FLAGS((w), GTK_CAN_DEFAULT); \
+} while (0)
+#define gtk_widget_set_can_focus(x,y) do {\
+	if (y) \
+		GTK_WIDGET_SET_FLAGS(x, GTK_CAN_FOCUS); \
+	else \
+		GTK_WIDGET_UNSET_FLAGS(x, GTK_CAN_FOCUS); \
+} while(0)
+#define gtk_cell_renderer_set_padding(x,y,z) do { \
+	(x)->xpad = (y); \
+	(x)->ypad = (z); \
+} while (0)
+#define gtk_cell_renderer_get_padding(x,y,z) do { \
+	*(y) = (x)->xpad; \
+	*(z) = (x)->ypad; \
+} while (0)
+#define gtk_cell_renderer_get_alignment(x,y,z) do { \
+	*(y) = (x)->xalign; \
+	*(z) = (x)->yalign; \
+} while (0)
+
+#if !GTK_CHECK_VERSION(2,16,0)
+
+#define gtk_status_icon_set_tooltip_text gtk_status_icon_set_tooltip
+
+#if !GTK_CHECK_VERSION(2,14,0)
+
+#define gtk_widget_get_window(x) (x)->window
+#define gtk_widget_set_style(x,y) (x)->style = (y)
+#define gtk_selection_data_get_data(x) (x)->data
+#define gtk_selection_data_get_length(x) (x)->length
+#define gtk_selection_data_get_format(x) (x)->format
+#define gtk_selection_data_get_target(x) (x)->target
+#define gtk_dialog_get_content_area(x) GTK_DIALOG(x)->vbox
+#define gtk_dialog_get_action_area(x) GTK_DIALOG(x)->action_area
+#define gtk_adjustment_get_page_size(x) (x)->page_size
+#define gtk_adjustment_get_lower(x) (x)->lower
+#define gtk_adjustment_get_upper(x) (x)->upper
+#define gtk_font_selection_get_size_entry(x) (x)->size_entry
+#define gtk_font_selection_get_family_list(x) (x)->family_list
+#define gtk_font_selection_dialog_get_ok_button(x) (x)->ok_button
+#define gtk_font_selection_dialog_get_cancel_button(x) (x)->cancel_button
+#define gtk_color_selection_dialog_get_color_selection(x) (x)->colorsel
+#define gtk_menu_item_get_accel_path(x) (x)->accel_path
+
+#if !GTK_CHECK_VERSION(2,12,0)
+
+#ifdef GTK_TOOLTIPS_VAR
+#define gtk_widget_set_tooltip_text(w, t) gtk_tooltips_set_tip(GTK_TOOLTIPS_VAR, (w), (t), NULL)
+#else
+#define gtk_widget_set_tooltip_text(w, t) gtk_tooltips_set_tip(tooltips, (w), (t), NULL)
+#endif
+
+#endif /* 2.12.0 */
+
+#endif /* 2.14.0 */
+
+#endif /* 2.16.0 */
+
+#endif /* 2.18.0 */
+
+#endif /* 2.20.0 */
+
+#endif /* 2.22.0 */
+
+#endif /* 2.24.0 */
+
+#endif /* 3.0.0 */
+
+#endif /* _PIDGINGTK3COMPAT_H_ */
+
--- a/pidgin/gtkaccount.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkaccount.c	Tue Jul 24 03:43:55 2012 -0400
@@ -48,6 +48,8 @@
 #include "pidginstock.h"
 #include "minidialog.h"
 
+#include "gtk3compat.h"
+
 enum
 {
 	COLUMN_ICON,
@@ -406,9 +408,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)) {
@@ -481,11 +485,7 @@
 
 	if (dialog->protocol_menu != NULL)
 	{
-#if GTK_CHECK_VERSION(2,12,0)
 		g_object_ref(G_OBJECT(dialog->protocol_menu));
-#else
-		gtk_widget_ref(dialog->protocol_menu);
-#endif
 		hbox = g_object_get_data(G_OBJECT(dialog->protocol_menu), "container");
 		gtk_container_remove(GTK_CONTAINER(hbox), dialog->protocol_menu);
 	}
@@ -512,21 +512,13 @@
 	{
 		dialog->protocol_menu = pidgin_protocol_option_menu_new(
 				dialog->protocol_id, G_CALLBACK(set_account_protocol_cb), dialog);
-#if GTK_CHECK_VERSION(2,12,0)
 		g_object_ref(G_OBJECT(dialog->protocol_menu));
-#else
-		gtk_widget_ref(dialog->protocol_menu);
-#endif
 	}
 
 	hbox = add_pref_box(dialog, vbox, _("Pro_tocol:"), dialog->protocol_menu);
 	g_object_set_data(G_OBJECT(dialog->protocol_menu), "container", hbox);
 
-#if GTK_CHECK_VERSION(2,12,0)
 	g_object_unref(G_OBJECT(dialog->protocol_menu));
-#else
-	gtk_widget_unref(dialog->protocol_menu);
-#endif
 
 	/* Username */
 	dialog->username_entry = gtk_entry_new();
@@ -1086,7 +1078,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);
@@ -1812,7 +1804,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;
@@ -1883,13 +1877,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)) {
@@ -2392,7 +2389,11 @@
 	width  = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/accounts/dialog/width");
 	height = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/accounts/dialog/height");
 
+#if GTK_CHECK_VERSION(3,0,0)
+	dialog->window = win = pidgin_create_dialog(_("Accounts"), 0, "accounts", TRUE);
+#else
 	dialog->window = win = pidgin_create_dialog(_("Accounts"), PIDGIN_HIG_BORDER, "accounts", TRUE);
+#endif
 	gtk_window_set_default_size(GTK_WINDOW(win), width, height);
 
 	g_signal_connect(G_OBJECT(win), "delete_event",
--- a/pidgin/gtkblist-theme-loader.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkblist-theme-loader.c	Tue Jul 24 03:43:55 2012 -0400
@@ -65,7 +65,9 @@
 	GdkColor color;
 
 	if (temp && gdk_color_parse(temp, &color)) {
+#if !GTK_CHECK_VERSION(3,0,0)
 		gdk_colormap_alloc_color(gdk_colormap_get_system(), &color, FALSE, TRUE);
+#endif
 		return gdk_color_copy(&color);
 	} else {
 		return NULL;
--- a/pidgin/gtkblist.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkblist.c	Tue Jul 24 03:43:55 2012 -0400
@@ -71,6 +71,8 @@
 #include <gtk/gtk.h>
 #include <gdk/gdk.h>
 
+#include "gtk3compat.h"
+
 typedef struct
 {
 	PurpleAccount *account;
@@ -121,9 +123,11 @@
 
 	PidginBlistTheme *current_theme;
 
+#if !GTK_CHECK_VERSION(3,0,0)
 	GdkCursor *hand_cursor;         /**< Hand cursor */
 	GdkCursor *arrow_cursor;        /**< Arrow cursor */
 	gboolean changing_style;        /**< True when changing GTK+ theme style */
+#endif
 
 } PidginBuddyListPrivate;
 
@@ -131,12 +135,7 @@
 	((PidginBuddyListPrivate *)((list)->priv))
 
 #define PIDGIN_WINDOW_ICONIFIED(x) \
-	(gdk_window_get_state(GTK_WIDGET(x)->window) & GDK_WINDOW_STATE_ICONIFIED)
-
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
-#define gtk_widget_has_focus(x) GTK_WIDGET_HAS_FOCUS(x)
-#endif
+	(gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(x))) & GDK_WINDOW_STATE_ICONIFIED)
 
 static GtkWidget *accountmenu = NULL;
 
@@ -475,9 +474,9 @@
 	GList *tmp;
 
 	/* First, we find the contact to merge the rest of the buddies into.
- 	 * This will be the contact with the most buddies in it; ties are broken
- 	 * by which contact is higher in the list
- 	 */
+	 * This will be the contact with the most buddies in it; ties are broken
+	 * by which contact is higher in the list
+	 */
 	for (tmp = merges; tmp; tmp = tmp->next) {
 		PurpleBlistNode *node = tmp->data;
 		PurpleBlistNode *b;
@@ -1013,20 +1012,21 @@
 	gtkblist = PIDGIN_BLIST(purple_get_blist());
 	blist_window = gtkblist ? GTK_WINDOW(gtkblist->window) : NULL;
 
-	data->window = gtk_dialog_new_with_buttons(title,
-		blist_window, GTK_DIALOG_NO_SEPARATOR,
-		NULL);
-
+	data->window = gtk_dialog_new();
+	gtk_window_set_title(GTK_WINDOW(data->window), title);
 	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);
 
@@ -1091,10 +1091,11 @@
 
 		if (pce->is_int)
 		{
-			GtkObject *adjust;
-			adjust = gtk_adjustment_new(pce->min, pce->min, pce->max,
-										1, 10, 10);
-			input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
+			GtkAdjustment *adjust;
+			adjust = GTK_ADJUSTMENT(gtk_adjustment_new(pce->min,
+			                                           pce->min, pce->max,
+			                                           1, 10, 10));
+			input = gtk_spin_button_new(adjust, 1, 0);
 			gtk_widget_set_size_request(input, 50, -1);
 			pidgin_add_widget_to_vbox(GTK_BOX(data->rq_data.vbox), pce->label, data->rq_data.sg, input, FALSE, NULL);
 		}
@@ -1587,7 +1588,7 @@
 		pidgin_append_blist_node_move_to_menu(menu, PURPLE_BLIST_NODE(contact));
 
 	if (node->parent && node->parent->child->next &&
-              !sub && !contact_expanded) {
+	    !sub && !contact_expanded) {
 		pidgin_separator(menu);
 		pidgin_append_blist_node_privacy_menu(menu, node);
 		pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS,
@@ -1636,11 +1637,11 @@
 			pidgin_retrieve_user_info(purple_account_get_connection(purple_buddy_get_account(buddy)), purple_buddy_get_name(buddy));
 	} 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 */
@@ -1662,7 +1663,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 */
@@ -2275,9 +2276,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;
@@ -2293,9 +2294,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;
@@ -2373,16 +2372,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;
@@ -2518,12 +2520,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;
@@ -2558,7 +2558,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)
@@ -2582,9 +2582,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;
@@ -2617,10 +2618,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;
 
@@ -2638,7 +2640,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, purple_buddy_get_account(b), purple_buddy_get_name(b));
-					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);
 				}
@@ -2960,10 +2963,9 @@
 }
 
 static gboolean
-pidgin_blist_paint_tip(GtkWidget *widget, gpointer null)
+pidgin_blist_paint_tip(GtkWidget *widget, cairo_t *cr, gpointer null)
 {
 	GtkStyle *style;
-	cairo_t *cr;
 	int current_height, max_width;
 	int max_text_width;
 	int max_avatar_width;
@@ -2975,7 +2977,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;
@@ -2997,7 +2999,6 @@
 	else
 		prpl_col = TOOLTIP_BORDER + status_size + SMALL_SPACE + max_text_width - PRPL_SIZE;
 
-	cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(gtkblist->tipwindow)));
 	current_height = 12;
 	for(l = gtkblist->tooltipdata; l; l = l->next)
 	{
@@ -3005,15 +3006,29 @@
 
 		if (td->avatar && pidgin_gdk_pixbuf_is_opaque(td->avatar))
 		{
+#if GTK_CHECK_VERSION(3,0,0)
+			if (dir == GTK_TEXT_DIR_RTL)
+				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, 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);
+#else
 			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);
+				                   NULL, 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",
-						max_width - (td->avatar_width+ TOOLTIP_BORDER)-1,
-						current_height-1,td->avatar_width+2, td->avatar_height+2);
+				                   NULL, gtkblist->tipwindow, "tooltip",
+				                   max_width - (td->avatar_width+ TOOLTIP_BORDER)-1,
+				                   current_height-1,td->avatar_width+2, td->avatar_height+2);
+#endif
 		}
 
 		if (td->status_icon) {
@@ -3029,7 +3044,7 @@
 			}
 		}
 
-		if(td->avatar) {
+		if (td->avatar) {
 			if (dir == GTK_TEXT_DIR_RTL) {
 				gdk_cairo_set_source_pixbuf(cr, td->avatar,
 				                            TOOLTIP_BORDER, current_height);
@@ -3050,36 +3065,62 @@
 		}
 
 		if (td->name_layout) {
+#if GTK_CHECK_VERSION(3,0,0)
+			if (dir == GTK_TEXT_DIR_RTL) {
+				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, cr, GTK_STATE_NORMAL, FALSE,
+				                 gtkblist->tipwindow, "tooltip",
+				                 TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height, td->name_layout);
+			}
+#else
 			if (dir == GTK_TEXT_DIR_RTL) {
 				gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-						NULL, gtkblist->tipwindow, "tooltip",
-						max_width  -(TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
-						current_height, td->name_layout);
+				                 NULL, 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",
-						TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height, td->name_layout);
+				gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
+				                 NULL, gtkblist->tipwindow, "tooltip",
+				                 TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height, td->name_layout);
 			}
+#endif
 		}
 
 		if (td->layout) {
+#if GTK_CHECK_VERSION(3,0,0)
 			if (dir != GTK_TEXT_DIR_RTL) {
-				gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-						NULL, gtkblist->tipwindow, "tooltip",
-						TOOLTIP_BORDER + status_size + SMALL_SPACE, current_height + td->name_height, td->layout);
+				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, 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);
+			}
+#else
+			if (dir != GTK_TEXT_DIR_RTL) {
+				gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
+				                 NULL, 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",
-						max_width - (TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
-						current_height + td->name_height,
-						td->layout);
+				                 NULL, gtkblist->tipwindow, "tooltip",
+				                 max_width - (TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
+				                 current_height + td->name_height,
+				                 td->layout);
 			}
+#endif
 		}
 
 		current_height += MAX(td->name_height + td->height, td->avatar_height) + td->padding;
 	}
 
-	cairo_destroy(cr);
 	return FALSE;
 }
 
@@ -3228,7 +3269,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)) {
@@ -3625,11 +3667,11 @@
 	}
 
 	purple_request_fields(gc, _("Edit User Mood"), _("Edit User Mood"),
-                              NULL, fields,
-                              _("OK"), G_CALLBACK(edit_mood_cb),
-                              _("Cancel"), NULL,
-                              gc ? purple_connection_get_account(gc) : NULL,
-                              NULL, NULL, gc);
+	                      NULL, fields,
+	                      _("OK"), G_CALLBACK(edit_mood_cb),
+	                      _("Cancel"), NULL,
+	                      gc ? purple_connection_get_account(gc) : NULL,
+	                      NULL, NULL, gc);
 
 	g_free(global_moods);
 }
@@ -5023,12 +5065,17 @@
 	widget = gtk_window_get_focus(GTK_WINDOW(gtkblist->window));
 
 	if (GTK_IS_IMHTML(widget) || GTK_IS_ENTRY(widget)) {
+#if GTK_CHECK_VERSION(3,0,0)
+		if (gtk_bindings_activate(G_OBJECT(widget), event->keyval, event->state))
+#else
 		if (gtk_bindings_activate(GTK_OBJECT(widget), event->keyval, event->state))
+#endif
 			return TRUE;
 	}
 	return FALSE;
 }
 
+#if !GTK_CHECK_VERSION(3,0,0)
 static gboolean
 headline_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event,
                       PidginBuddyListPrivate *priv)
@@ -5044,6 +5091,7 @@
 	gdk_window_set_cursor(widget->window, priv->arrow_cursor);
 	return FALSE;
 }
+#endif
 
 static void
 reset_headline(PidginBuddyList *gtkblist)
@@ -5063,6 +5111,43 @@
 	return FALSE;
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+
+static gboolean
+headline_response_cb(GtkInfoBar *infobar, int resp, PidginBuddyList *gtkblist)
+{
+	gtk_widget_hide(gtkblist->headline);
+
+	if (resp == GTK_RESPONSE_OK) {
+		if (gtkblist->headline_callback)
+			g_idle_add(headline_click_callback, NULL);
+		else {
+			if (gtkblist->headline_destroy)
+				gtkblist->headline_destroy(gtkblist->headline_data);
+			reset_headline(gtkblist);
+		}
+	}
+
+	return FALSE;
+}
+
+static void
+headline_realize_cb(GtkWidget *widget, gpointer data)
+{
+	GdkCursor *hand_cursor = gdk_cursor_new(GDK_HAND2);
+	gdk_window_set_cursor(gtk_widget_get_window(widget), hand_cursor);
+	gdk_cursor_unref(hand_cursor);
+}
+
+static gboolean
+headline_press_cb(GtkWidget *widget, GdkEventButton *event, GtkInfoBar *infobar)
+{
+	gtk_info_bar_response(infobar, GTK_RESPONSE_OK);
+	return TRUE;
+}
+
+#else
+
 static gboolean
 headline_close_press_cb(GtkButton *button, PidginBuddyList *gtkblist)
 {
@@ -5084,6 +5169,8 @@
 	return TRUE;
 }
 
+#endif
+
 /***********************************/
 /* Connection error handling stuff */
 /***********************************/
@@ -5175,7 +5262,7 @@
 }
 
 static void
-generic_error_destroy_cb(GtkObject *dialog,
+generic_error_destroy_cb(GtkWidget *dialog,
                          PurpleAccount *account)
 {
 	/* If the error dialog is being destroyed in response to the
@@ -5513,6 +5600,7 @@
 	}
 }
 
+#if !GTK_CHECK_VERSION(3,0,0)
 static gboolean
 paint_headline_hbox  (GtkWidget      *widget,
 		      GdkEventExpose *event,
@@ -5531,6 +5619,7 @@
 		      widget->allocation.height - 2);
 	return FALSE;
 }
+#endif
 
 /* This assumes there are not things like groupless buddies or multi-leveled groups.
  * I'm sure other things in this code assumes that also.
@@ -5548,6 +5637,7 @@
 	}
 }
 
+#if !GTK_CHECK_VERSION(3,0,0)
 static void
 headline_style_set (GtkWidget *widget,
 		    GtkStyle  *prev_style)
@@ -5593,6 +5683,7 @@
 	g_object_unref (tooltips);
 #endif
 }
+#endif
 
 /******************************************/
 /* End of connection error handling stuff */
@@ -5822,8 +5913,13 @@
 	void *handle;
 	GtkTreeViewColumn *column;
 	GtkWidget *menu;
+	GtkWidget *sep;
+#if GTK_CHECK_VERSION(3,0,0)
+	GtkWidget *infobar;
+	GtkWidget *content_area;
+#else
 	GtkWidget *ebox;
-	GtkWidget *sep;
+#endif
 	GtkWidget *label;
 	GtkWidget *close;
 	char *pretty, *tmp;
@@ -5865,7 +5961,11 @@
 			 G_CALLBACK(blist_focus_cb), gtkblist);
 	g_signal_connect(G_OBJECT(gtkblist->window), "focus-out-event",
 			 G_CALLBACK(blist_focus_cb), gtkblist);
+
+	/* TODO: how is this done in gtk+ 3.0? */
+#if !GTK_CHECK_VERSION(3,0,0)
 	GTK_WINDOW(gtkblist->window)->allow_shrink = TRUE;
+#endif
 
 	gtkblist->main_vbox = gtk_vbox_new(FALSE, 0);
 	gtk_widget_show(gtkblist->main_vbox);
@@ -5939,7 +6039,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);
@@ -5950,6 +6049,44 @@
 	gtk_widget_show_all(gtkblist->notebook);
 	pidgin_blist_select_notebook_page(gtkblist);
 
+	/****************************** Headline **********************************/
+#if GTK_CHECK_VERSION(3,0,0)
+
+	gtkblist->headline = gtk_event_box_new();
+	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->headline,
+	                   FALSE, FALSE, 0);
+	infobar = gtk_info_bar_new();
+	gtk_container_add(GTK_CONTAINER(gtkblist->headline), infobar);
+	gtk_info_bar_set_default_response(GTK_INFO_BAR(infobar), GTK_RESPONSE_OK);
+	gtk_info_bar_set_message_type(GTK_INFO_BAR(infobar), GTK_MESSAGE_INFO);
+
+	content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(infobar));
+	gtkblist->headline_image = gtk_image_new_from_pixbuf(NULL);
+	gtk_misc_set_alignment(GTK_MISC(gtkblist->headline_image), 0.5, 0.5);
+	gtkblist->headline_label = gtk_label_new(NULL);
+	gtk_label_set_line_wrap(GTK_LABEL(gtkblist->headline_label), TRUE);
+	gtk_box_pack_start(GTK_BOX(content_area), gtkblist->headline_image,
+	                   FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(content_area), gtkblist->headline_label,
+	                   TRUE, TRUE, 0);
+
+	close = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
+	close = pidgin_create_small_button(close);
+	gtk_widget_set_tooltip_text(close, _("Close"));
+	gtk_info_bar_add_action_widget(GTK_INFO_BAR(infobar), close,
+	                               GTK_RESPONSE_CLOSE);
+
+	g_signal_connect(infobar, "response", G_CALLBACK(headline_response_cb),
+	                 gtkblist);
+	g_signal_connect(infobar, "close", G_CALLBACK(gtk_info_bar_response),
+	                 GINT_TO_POINTER(GTK_RESPONSE_CLOSE));
+	g_signal_connect(gtkblist->headline, "realize",
+	                 G_CALLBACK(headline_realize_cb), NULL);
+	g_signal_connect(gtkblist->headline, "button-press-event",
+	                 G_CALLBACK(headline_press_cb), infobar);
+
+#else
+
 	ebox = gtk_event_box_new();
 	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), ebox, FALSE, FALSE, 0);
 	gtkblist->headline = gtk_hbox_new(FALSE, 3);
@@ -5990,6 +6127,8 @@
 	g_signal_connect(G_OBJECT(ebox), "leave-notify-event", G_CALLBACK(headline_box_leave_cb), priv);
 	g_signal_connect(G_OBJECT(ebox), "button-press-event", G_CALLBACK(headline_box_press_cb), gtkblist);
 
+#endif
+
 	/****************************** GtkTreeView **********************************/
 	gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS,
 						 GDK_TYPE_PIXBUF, /* Status icon */
@@ -6088,7 +6227,9 @@
 	gtkblist->statusbox = pidgin_status_box_new();
 	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->statusbox, FALSE, TRUE, 0);
 	gtk_widget_set_name(gtkblist->statusbox, "pidgin_blist_statusbox");
+#if !GTK_CHECK_VERSION(3,0,0)
 	gtk_container_set_border_width(GTK_CONTAINER(gtkblist->statusbox), 3);
+#endif
 	gtk_widget_show(gtkblist->statusbox);
 
 	/* set the Show Offline Buddies option. must be done
@@ -6991,10 +7132,12 @@
 
 	priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist);
 
+#if !GTK_CHECK_VERSION(3,0,0)
 	gdk_cursor_unref(priv->hand_cursor);
 	gdk_cursor_unref(priv->arrow_cursor);
 	priv->hand_cursor = NULL;
 	priv->arrow_cursor = NULL;
+#endif
 
 	if (priv->current_theme)
 		g_object_unref(priv->current_theme);
@@ -7012,7 +7155,8 @@
 		return;
 
 	if (show) {
-		if(!PIDGIN_WINDOW_ICONIFIED(gtkblist->window) && !gtk_widget_get_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));
@@ -7985,7 +8129,7 @@
 
 		if(PURPLE_BLIST_NODE_IS_CONTACT(n)) {
 			for (n2 = n->child; n2; n2 = n2->next) {
-                        	buddy = (PurpleBuddy*)n2;
+				buddy = (PurpleBuddy*)n2;
 				this_log_activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
 			}
 			this_buddy_name = purple_contact_get_alias((PurpleContact*)n);
@@ -8021,7 +8165,7 @@
 }
 
 static void
-plugin_act(GtkObject *obj, PurplePluginAction *pam)
+plugin_act(GtkWidget *obj, PurplePluginAction *pam)
 {
 	if (pam && pam->callback)
 		pam->callback(pam);
--- a/pidgin/gtkcellrendererexpander.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkcellrendererexpander.c	Tue Jul 24 03:43:55 2012 -0400
@@ -32,6 +32,14 @@
 #include <gtk/gtk.h>
 #include "gtkcellrendererexpander.h"
 
+#include "gtk3compat.h"
+
+#if GTK_CHECK_VERSION(3,0,0)
+#define GTK3_CONST const
+#else
+#define GTK3_CONST
+#endif
+
 static void pidgin_cell_renderer_expander_get_property  (GObject                    *object,
 						      guint                       param_id,
 						      GValue                     *value,
@@ -44,24 +52,30 @@
 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,
+						   GTK3_CONST GdkRectangle    *cell_area,
 						   gint                       *x_offset,
 						   gint                       *y_offset,
 						   gint                       *width,
 						   gint                       *height);
 static void pidgin_cell_renderer_expander_render     (GtkCellRenderer            *cell,
+#if GTK_CHECK_VERSION(3,0,0)
+						   cairo_t                    *cr,
+#else
 						   GdkWindow                  *window,
+#endif
 						   GtkWidget                  *widget,
-						   GdkRectangle               *background_area,
-						   GdkRectangle               *cell_area,
-						   GdkRectangle               *expose_area,
-						   guint                       flags);
+						   GTK3_CONST GdkRectangle    *background_area,
+						   GTK3_CONST GdkRectangle    *cell_area,
+#if !GTK_CHECK_VERSION(3,0,0)
+                           GdkRectangle               *export_area,
+#endif
+						   GtkCellRendererState        flags);
 static gboolean pidgin_cell_renderer_expander_activate  (GtkCellRenderer            *r,
 						      GdkEvent                   *event,
 						      GtkWidget                  *widget,
 						      const gchar                *p,
-						      GdkRectangle               *bg,
-						      GdkRectangle               *cell,
+						      GTK3_CONST GdkRectangle    *bg,
+						      GTK3_CONST GdkRectangle    *cell,
 						      GtkCellRendererState        flags);
 static void  pidgin_cell_renderer_expander_finalize (GObject *gobject);
 
@@ -108,9 +122,9 @@
 
 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_set_padding(GTK_CELL_RENDERER(cellexpander), 0, 2);
 }
 
 static void pidgin_cell_renderer_expander_class_init (PidginCellRendererExpanderClass *class)
@@ -188,9 +202,10 @@
 	return g_object_new(PIDGIN_TYPE_GTK_CELL_RENDERER_EXPANDER, NULL);
 }
 
-static void pidgin_cell_renderer_expander_get_size (GtkCellRenderer *cell,
+static void
+pidgin_cell_renderer_expander_get_size (GtkCellRenderer *cell,
 						 GtkWidget       *widget,
-						 GdkRectangle    *cell_area,
+						 GTK3_CONST GdkRectangle *cell_area,
 						 gint            *x_offset,
 						 gint            *y_offset,
 						 gint            *width,
@@ -199,11 +214,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,74 +236,101 @@
 		{
 			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);
 				}
 		}
 }
 
 
-static void pidgin_cell_renderer_expander_render(GtkCellRenderer *cell,
-					       GdkWindow       *window,
-					       GtkWidget       *widget,
-					       GdkRectangle    *background_area,
-					       GdkRectangle    *cell_area,
-					       GdkRectangle    *expose_area,
-					       guint            flags)
+static void
+pidgin_cell_renderer_expander_render(GtkCellRenderer *cell,
+#if GTK_CHECK_VERSION(3,0,0)
+					       cairo_t                 *cr,
+#else
+					       GdkWindow               *window,
+#endif
+					       GtkWidget               *widget,
+					       GTK3_CONST GdkRectangle *background_area,
+					       GTK3_CONST GdkRectangle *cell_area,
+#if !GTK_CHECK_VERSION(3,0,0)
+					       GdkRectangle            *expose_area,
+#endif
+					       GtkCellRendererState    flags)
 {
 	PidginCellRendererExpander *cellexpander = (PidginCellRendererExpander *) cell;
 	gboolean set;
 	gint width, height;
 	GtkStateType state;
+	gint xpad;
+	gint ypad;
+	gboolean is_expanded;
+	GtkAllocation allocation;
 
 	if (!cellexpander->is_expander)
 		return;
 
+	gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
+	g_object_get(G_OBJECT(cell), "is-expanded", &is_expanded, NULL);
+
 	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;
-#if GTK_CHECK_VERSION(2,18,0)
-	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
-	else if (GTK_WIDGET_HAS_FOCUS (widget) && flags & GTK_CELL_RENDERER_SELECTED)
-		state = GTK_STATE_ACTIVE;
-#endif
 	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);
+#if GTK_CHECK_VERSION(3,0,0)
+	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);
+#else
+	gtk_paint_expander(gtk_widget_get_style(widget),
+	                   window, state,
+	                   NULL, widget, "treeview",
+	                   cell_area->x + cell->xpad + (width / 2),
+	                   cell_area->y + cell->ypad + (height / 2),
+	                   is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
+#endif
 
 	/* 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 GTK_CHECK_VERSION(3,0,0)
+	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);
+#else
+	if (is_expanded && !set)
+		gtk_paint_hline(gtk_widget_get_style(widget), window, state, NULL, widget, NULL, 0,
+		                allocation.width, cell_area->y + cell_area->height);
+#endif
 }
 
-static gboolean pidgin_cell_renderer_expander_activate(GtkCellRenderer *r,
+static gboolean
+pidgin_cell_renderer_expander_activate(GtkCellRenderer *r,
 						     GdkEvent *event,
 						     GtkWidget *widget,
 						     const gchar *p,
-						     GdkRectangle *bg,
-						     GdkRectangle *cell,
+						     GTK3_CONST GdkRectangle *bg,
+						     GTK3_CONST GdkRectangle *cell,
 						     GtkCellRendererState flags)
 {
 	GtkTreePath *path = gtk_tree_path_new_from_string(p);
--- a/pidgin/gtkcertmgr.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkcertmgr.c	Tue Jul 24 03:43:55 2012 -0400
@@ -613,7 +613,11 @@
 
 	win = dlg->window =
 		pidgin_create_dialog(_("Certificate Manager"),/* Title */
+#if GTK_CHECK_VERSION(3,0,0)
+				     0, /*Window border*/
+#else
 				     PIDGIN_HIG_BORDER, /*Window border*/
+#endif
 				     "certmgr",         /* Role */
 				     TRUE); /* Allow resizing */
 	g_signal_connect(G_OBJECT(win), "delete_event",
--- a/pidgin/gtkconv.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkconv.c	Tue Jul 24 03:43:55 2012 -0400
@@ -80,14 +80,8 @@
 
 #include "gtknickcolors.h"
 
-#if !GTK_CHECK_VERSION(2,20,0)
-#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x)
-
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
-#define gtk_widget_is_drawable(x) GTK_WIDGET_DRAWABLE(x)
-#endif
-#endif
+#define GTK_TOOLTIPS_VAR gtkconv->tooltips
+#include "gtk3compat.h"
 
 /**
  * A GTK+ Instant Message pane.
@@ -851,15 +845,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);
@@ -878,15 +874,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)
@@ -911,7 +908,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);
 	}
 }
 
@@ -953,14 +951,11 @@
 		                                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);
-#if !GTK_CHECK_VERSION(2,22,0)
-		gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE);
-#endif
 
 		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);
@@ -1972,8 +1967,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);
@@ -1982,8 +1977,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);
@@ -1992,9 +1987,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 {
@@ -2004,20 +1999,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;
@@ -2041,13 +2036,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;
@@ -2071,7 +2066,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;
 
@@ -2122,7 +2117,7 @@
 				return TRUE;
 				break;
 
-			case GDK_Down:
+			case GDK_KEY_Down:
 				if (!gtkconv->send_history)
 					break;
 
@@ -2175,9 +2170,9 @@
 	/* 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;
 			{
@@ -2189,14 +2184,14 @@
 			}
 			break;
 
-		case GDK_Page_Up:
-		case GDK_KP_Page_Up:
+		case GDK_KEY_Page_Up:
+		case GDK_KEY_KP_Page_Up:
 			gtk_webview_page_up(GTK_WEBVIEW(gtkconv->webview));
 			return TRUE;
 			break;
 
-		case GDK_Page_Down:
-		case GDK_KP_Page_Down:
+		case GDK_KEY_Page_Down:
+		case GDK_KEY_KP_Page_Down:
 			gtk_webview_page_down(GTK_WEBVIEW(gtkconv->webview));
 			return TRUE;
 			break;
@@ -2240,26 +2235,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);
@@ -2729,7 +2724,7 @@
 }
 
 static void
-start_anim(GtkObject *obj, PidginConversation *gtkconv)
+start_anim(GtkWidget *widget, PidginConversation *gtkconv)
 {
 	int delay;
 
@@ -2902,7 +2897,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);
@@ -2924,7 +2919,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;
@@ -3766,10 +3761,10 @@
 		break;
 	}
 	if (gtkwin->menu.typing_icon == NULL) {
-		 gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
-		 pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray),
-                                                                  gtkwin->menu.typing_icon,
-                                                                  _("User is typing..."));
+		gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
+		pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray),
+		                        gtkwin->menu.typing_icon,
+		                        _("User is typing..."));
 	} else {
 		gtk_image_set_from_stock(GTK_IMAGE(gtkwin->menu.typing_icon), stock_id, GTK_ICON_SIZE_MENU);
 	}
@@ -4742,12 +4737,21 @@
 	GdkRectangle oneline;
 	int height, diff;
 	int pad_top, pad_inside, pad_bottom;
-	int total_height = (gtkconv->webview->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 webview_allocation;
+	GtkAllocation entry_allocation;
+	GtkAllocation lower_hbox_allocation;
+
+	gtk_widget_get_allocation(gtkconv->webview, &webview_allocation);
+	gtk_widget_get_allocation(gtkconv->entry, &entry_allocation);
+	gtk_widget_get_allocation(gtkconv->lower_hbox, &lower_hbox_allocation);
+	total_height = webview_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));
@@ -4781,12 +4785,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;
 }
@@ -4833,7 +4840,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(G_OBJECT(gtkchat->topic_text), "activate",
 					G_CALLBACK(topic_callback), gtkconv);
 		}
 
@@ -5004,7 +5011,7 @@
 	gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
 
 	webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview));
-	gtk_widget_hide_all(gtkconv->quickfind.container);
+	gtk_widget_hide(gtkconv->quickfind.container);
 
 	gtk_widget_grab_focus(gtkconv->entry);
 	return TRUE;
@@ -5014,8 +5021,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 (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) {
 				gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
 			} else {
@@ -5026,7 +5033,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:
@@ -5045,12 +5052,7 @@
 
 	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);
@@ -5488,8 +5490,10 @@
 	PurpleAccount *convaccount = purple_conversation_get_account(conv);
 	PurpleConnection *gc = purple_account_get_connection(convaccount);
 	PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : 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;
@@ -5497,7 +5501,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);
@@ -5545,16 +5549,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)
@@ -5585,12 +5590,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);
@@ -6003,33 +6010,37 @@
 		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;
 
 		/* emit chat-nick-clicked signal */
 		if (event->type == GDK_BUTTON_PRESS) {
 			gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
 						pidgin_conversations_get_handle(), "chat-nick-clicked",
 						data, buddyname, btn_event->button));
-			if (plugin_return)
+			if (plugin_return) {
+				g_free(name);
 				return TRUE;
-		}
-
-		if (btn_event->button == 1 &&
-				event->type == GDK_2BUTTON_PRESS) {
+			}
+		}
+
+		if (btn_event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
 			chat_do_im(PIDGIN_CONVERSATION(conv), buddyname);
-			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) {
+		} 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) {
 			GtkTextIter start, end;
 
 			/* we shouldn't display the popup
@@ -6048,10 +6059,14 @@
 						btn_event->button,
 						btn_event->time);
 
+				g_free(name);
+
 				/* Don't propagate the event any further */
 				return TRUE;
 			}
 		}
+
+		g_free(name);
 	}
 
 	return FALSE;
@@ -7286,13 +7301,8 @@
 			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
 		}
 	}
 
@@ -7303,7 +7313,7 @@
 
 	if ((fields & PIDGIN_CONV_COLORIZE_TITLE) ||
 			(fields & PIDGIN_CONV_SET_TITLE) ||
-    			(fields & PIDGIN_CONV_TOPIC))
+			(fields & PIDGIN_CONV_TOPIC))
 	{
 		char *title;
 		PurpleConvIm *im = NULL;
@@ -7669,7 +7679,7 @@
 	gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
 	gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), FALSE);
 	gtk_widget_add_events(event,
-                              GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
+	                      GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
 	g_signal_connect(G_OBJECT(event), "button-press-event",
 					 G_CALLBACK(icon_menu), gtkconv);
 
@@ -7711,11 +7721,14 @@
 {
 	gint pane_x, pane_y, x_rel;
 	PidginConversation *gtkconv;
-
-	gdk_window_get_origin(win->notebook->window, &pane_x, &pane_y);
+	GtkAllocation 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);
+	gtk_widget_get_allocation(gtkconv->infopane, &allocation);
+	return (x_rel > allocation.x + allocation.width / 2);
 }
 
 int
@@ -7733,7 +7746,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;
 
@@ -7743,30 +7756,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_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;
@@ -8503,7 +8518,7 @@
 	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
 								show_protocol_icons_pref_cb, NULL);
 	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new",
-                                hide_new_pref_cb, NULL);
+								hide_new_pref_cb, NULL);
 
 
 
@@ -8660,7 +8675,7 @@
 	window_list = g_list_remove(window_list, hidden_convwin);
 
 	purple_signal_connect(purple_accounts_get_handle(), "account-status-changed",
-                        handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
+						handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
 
 	/* Callbacks to update a conversation */
 	purple_signal_connect(blist_handle, "blist-node-added", handle,
@@ -8849,12 +8864,9 @@
 	gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog),
 	                               6);
 	gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE);
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), FALSE);
-#endif
 
 	/* 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);
@@ -9008,7 +9020,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);
 }
@@ -9128,6 +9140,9 @@
 
 	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;
@@ -9135,12 +9150,12 @@
 		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);
@@ -9182,6 +9197,7 @@
 	int tab_clicked;
 	GtkWidget *page;
 	GtkWidget *tab;
+	GtkAllocation allocation;
 
 	if (e->button == 2 && e->type == GDK_BUTTON_PRESS) {
 		PidginConversation *gtkconv;
@@ -9219,7 +9235,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;
@@ -9231,10 +9247,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 ||
@@ -9242,8 +9260,8 @@
 	    e->y_root <  win->drag_min_y ||
 	    e->y_root >= win->drag_max_y) {
 
-		    return FALSE;
-	    }
+		return FALSE;
+	}
 
 	win->in_predrag = TRUE;
 	win->drag_tab = tab_clicked;
@@ -9406,6 +9424,7 @@
 
 	stop_anim(NULL, gtkconv);
 }
+
 static void
 close_window(GtkWidget *w, PidginWindow *win)
 {
@@ -9413,17 +9432,16 @@
 }
 
 static void
-detach_tab_cb(GtkWidget *w, GObject *menu)
-{
-	PidginWindow *win, *new_window;
+detach_tab_cb(GtkWidget *w, PidginWindow *win)
+{
+	PidginWindow *new_window;
 	PidginConversation *gtkconv;
 
-	gtkconv = g_object_get_data(menu, "clicked_tab");
+	gtkconv = win->clicked_tab;
 
 	if (!gtkconv)
 		return;
 
-	win = pidgin_conv_get_window(gtkconv);
 	/* Nothing to do if there's only one tab in the window */
 	if (pidgin_conv_window_get_gtkconv_count(win) == 1)
 		return;
@@ -9436,19 +9454,16 @@
 }
 
 static void
-close_others_cb(GtkWidget *w, GObject *menu)
+close_others_cb(GtkWidget *w, PidginWindow *win)
 {
 	GList *iter;
 	PidginConversation *gtkconv;
-	PidginWindow *win;
-
-	gtkconv = g_object_get_data(menu, "clicked_tab");
+
+	gtkconv = win->clicked_tab;
 
 	if (!gtkconv)
 		return;
 
-	win = pidgin_conv_get_window(gtkconv);
-
 	for (iter = pidgin_conv_window_get_gtkconvs(win); iter; )
 	{
 		PidginConversation *gconv = iter->data;
@@ -9461,20 +9476,100 @@
 	}
 }
 
-static void close_tab_cb(GtkWidget *w, GObject *menu)
+static void
+close_tab_cb(GtkWidget *w, PidginWindow *win)
 {
 	PidginConversation *gtkconv;
 
-	gtkconv = g_object_get_data(menu, "clicked_tab");
+	gtkconv = win->clicked_tab;
 
 	if (gtkconv)
 		close_conv_cb(NULL, gtkconv);
 }
 
+static void
+notebook_menu_switch_cb(GtkWidget *item, GtkWidget *child)
+{
+	GtkNotebook *notebook;
+	int index;
+
+	notebook = GTK_NOTEBOOK(gtk_widget_get_parent(child));
+	index = gtk_notebook_page_num(notebook, child);
+	gtk_notebook_set_current_page(notebook, index);
+}
+
+static void
+notebook_menu_update_label_cb(GtkWidget *child, GParamSpec *pspec,
+                              GtkNotebook *notebook)
+{
+	GtkWidget *item;
+	GtkWidget *label;
+
+	item = g_object_get_data(G_OBJECT(child), "popup-menu-item");
+	label = gtk_bin_get_child(GTK_BIN(item));
+	if (label)
+		gtk_container_remove(GTK_CONTAINER(item), label);
+
+	label = gtk_notebook_get_menu_label(notebook, child);
+	if (label) {
+		gtk_widget_show(label);
+		gtk_container_add(GTK_CONTAINER(item), label);
+		gtk_widget_show(item);
+	} else {
+		gtk_widget_hide(item);
+	}
+}
+
+static void
+notebook_add_tab_to_menu_cb(GtkNotebook *notebook, GtkWidget *child,
+                            guint page_num, PidginWindow *win)
+{
+	GtkWidget *item;
+	GtkWidget *label;
+
+	item = gtk_menu_item_new();
+	label = gtk_notebook_get_menu_label(notebook, child);
+	if (label) {
+		gtk_widget_show(label);
+		gtk_container_add(GTK_CONTAINER(item), label);
+		gtk_widget_show(item);
+	}
+
+	g_signal_connect(child, "child-notify::menu-label",
+	                 G_CALLBACK(notebook_menu_update_label_cb), notebook); 
+	g_signal_connect(item, "activate",
+	                 G_CALLBACK(notebook_menu_switch_cb), child);
+	g_object_set_data(G_OBJECT(child), "popup-menu-item", item);
+
+	gtk_menu_shell_insert(GTK_MENU_SHELL(win->notebook_menu), item, page_num);
+}
+
+static void
+notebook_remove_tab_from_menu_cb(GtkNotebook *notebook, GtkWidget *child,
+                                 guint page_num, PidginWindow *win)
+{
+	GtkWidget *item;
+
+	item = g_object_get_data(G_OBJECT(child), "popup-menu-item");
+	gtk_container_remove(GTK_CONTAINER(win->notebook_menu), item);
+}
+
+
+static void
+notebook_reorder_tab_in_menu_cb(GtkNotebook *notebook, GtkWidget *child,
+                                guint page_num, PidginWindow *win)
+{
+	GtkWidget *item;
+
+	item = g_object_get_data(G_OBJECT(child), "popup-menu-item");
+	gtk_menu_reorder_child(GTK_MENU(win->notebook_menu), item, page_num);
+}
+
 static gboolean
-right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win)
-{
-	GtkWidget *item, *menu;
+notebook_right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event,
+                             PidginWindow *win)
+{
+	GtkWidget *menu;
 	PidginConversation *gtkconv;
 
 	if (event->type != GDK_BUTTON_PRESS || event->button != 3)
@@ -9483,44 +9578,13 @@
 	gtkconv = pidgin_conv_window_get_gtkconv_at_index(win,
 			pidgin_conv_get_tab_at_xy(win, event->x_root, event->y_root, NULL));
 
-	if (g_object_get_data(G_OBJECT(notebook->menu), "clicked_tab"))
-	{
-		g_object_set_data(G_OBJECT(notebook->menu), "clicked_tab", gtkconv);
-		return FALSE;
-	}
-
-	g_object_set_data(G_OBJECT(notebook->menu), "clicked_tab", gtkconv);
-
-	menu = notebook->menu;
-	pidgin_separator(GTK_WIDGET(menu));
-
-	item = gtk_menu_item_new_with_label(_("Close other tabs"));
-	gtk_widget_show(item);
-	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-	g_signal_connect(G_OBJECT(item), "activate",
-					G_CALLBACK(close_others_cb), menu);
-
-	item = gtk_menu_item_new_with_label(_("Close all tabs"));
-	gtk_widget_show(item);
-	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-	g_signal_connect(G_OBJECT(item), "activate",
-					G_CALLBACK(close_window), win);
-
-	pidgin_separator(menu);
-
-	item = gtk_menu_item_new_with_label(_("Detach this tab"));
-	gtk_widget_show(item);
-	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-	g_signal_connect(G_OBJECT(item), "activate",
-					G_CALLBACK(detach_tab_cb), menu);
-
-	item = gtk_menu_item_new_with_label(_("Close this tab"));
-	gtk_widget_show(item);
-	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-	g_signal_connect(G_OBJECT(item), "activate",
-					G_CALLBACK(close_tab_cb), menu);
-
-	return FALSE;
+	win->clicked_tab = gtkconv;
+
+	menu = win->notebook_menu;
+
+	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time);
+
+	return TRUE;
 }
 
 static void
@@ -9543,7 +9607,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;
 	}
@@ -9570,8 +9634,7 @@
 		PurpleBuddy *buddy;
 		buddy = purple_find_buddy(account, name);
 		if (buddy != NULL) {
-			purple_blist_alias_buddy(buddy,
-                                                 gtk_entry_get_text(entry));
+			purple_blist_alias_buddy(buddy, gtk_entry_get_text(entry));
 		}
 		serv_alias_buddy(buddy);
 	} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
@@ -9714,14 +9777,18 @@
 make_status_icon_list(const char *stock, GtkWidget *w)
 {
 	GList *l = NULL;
-	l = g_list_append(l, gtk_widget_render_icon (w, stock,
-                                       gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow"));
-	l = g_list_append(l, gtk_widget_render_icon (w, stock,
-                                       gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow"));
-	l = g_list_append(l, gtk_widget_render_icon (w, stock,
-                                       gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow"));
-	l = g_list_append(l, gtk_widget_render_icon (w, stock,
-                                       gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow"));
+	l = g_list_append(l,
+		gtk_widget_render_icon(w, stock,
+			gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow"));
+	l = g_list_append(l,
+		gtk_widget_render_icon(w, stock,
+			gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow"));
+	l = g_list_append(l,
+		gtk_widget_render_icon(w, stock,
+			gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow"));
+	l = g_list_append(l,
+		gtk_widget_render_icon(w, stock,
+			gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow"));
 	return l;
 }
 
@@ -9752,7 +9819,7 @@
 
 	/* 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 */
@@ -9777,8 +9844,8 @@
 pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y,
 		int conv_width, int conv_height)
 {
-	 /* if the window exists, is hidden, we're saving positions, and the
-          * position is sane... */
+	/* if the window exists, is hidden, we're saving positions, and the
+	 * position is sane... */
 	if (win && win->window &&
 			!gtk_widget_get_visible(win->window) && conv_width != 0) {
 
@@ -9817,6 +9884,8 @@
 	GtkPositionType pos;
 	GtkWidget *testidea;
 	GtkWidget *menubar;
+	GtkWidget *menu;
+	GtkWidget *item;
 	GdkModifierType state;
 
 	win = g_malloc0(sizeof(PidginWindow));
@@ -9861,12 +9930,48 @@
 #endif
 	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(win->notebook), pos);
 	gtk_notebook_set_scrollable(GTK_NOTEBOOK(win->notebook), TRUE);
-	gtk_notebook_popup_enable(GTK_NOTEBOOK(win->notebook));
 	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
 	gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE);
 
+	menu = win->notebook_menu = gtk_menu_new();
+
+	pidgin_separator(GTK_WIDGET(menu));
+
+	item = gtk_menu_item_new_with_label(_("Close other tabs"));
+	gtk_widget_show(item);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+	g_signal_connect(G_OBJECT(item), "activate",
+					G_CALLBACK(close_others_cb), win);
+
+	item = gtk_menu_item_new_with_label(_("Close all tabs"));
+	gtk_widget_show(item);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+	g_signal_connect(G_OBJECT(item), "activate",
+					G_CALLBACK(close_window), win);
+
+	pidgin_separator(menu);
+
+	item = gtk_menu_item_new_with_label(_("Detach this tab"));
+	gtk_widget_show(item);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+	g_signal_connect(G_OBJECT(item), "activate",
+					G_CALLBACK(detach_tab_cb), win);
+
+	item = gtk_menu_item_new_with_label(_("Close this tab"));
+	gtk_widget_show(item);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+	g_signal_connect(G_OBJECT(item), "activate",
+					G_CALLBACK(close_tab_cb), win);
+
+	g_signal_connect(G_OBJECT(win->notebook), "page-added",
+	                 G_CALLBACK(notebook_add_tab_to_menu_cb), win);
+	g_signal_connect(G_OBJECT(win->notebook), "page-removed",
+	                 G_CALLBACK(notebook_remove_tab_from_menu_cb), win);
+	g_signal_connect(G_OBJECT(win->notebook), "page-reordered",
+	                 G_CALLBACK(notebook_reorder_tab_in_menu_cb), win);
+
 	g_signal_connect(G_OBJECT(win->notebook), "button-press-event",
-					G_CALLBACK(right_click_menu_cb), win);
+					G_CALLBACK(notebook_right_click_menu_cb), win);
 
 	gtk_widget_show(win->notebook);
 
@@ -9929,6 +10034,7 @@
 		}
 		return;
 	}
+	gtk_widget_destroy(win->notebook_menu);
 	gtk_widget_destroy(win->window);
 
 	g_object_unref(G_OBJECT(win->menu.ui));
@@ -9954,7 +10060,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
@@ -9968,9 +10074,6 @@
 static gboolean
 gtkconv_tab_set_tip(GtkWidget *widget, GdkEventCrossing *event, PidginConversation *gtkconv)
 {
-#if GTK_CHECK_VERSION(2, 12, 0)
-#define gtk_tooltips_set_tip(tips, w, l, p)  gtk_widget_set_tooltip_text(w, l)
-#endif
 /* PANGO_VERSION_CHECK macro was introduced in 1.15. So we need this double check. */
 #ifndef PANGO_VERSION_CHECK
 #define pango_layout_is_ellipsized(l) TRUE
@@ -9980,13 +10083,12 @@
 	PangoLayout *layout;
 
 	layout = gtk_label_get_layout(GTK_LABEL(gtkconv->tab_label));
-	gtk_tooltips_set_tip(gtkconv->tooltips, widget,
-			pango_layout_is_ellipsized(layout) ? gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)) : NULL,
-			NULL);
+	if (pango_layout_is_ellipsized(layout))
+		gtk_widget_set_tooltip_text(widget, gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)));
+	else
+		gtk_widget_set_tooltip_text(widget, NULL);
+
 	return FALSE;
-#if GTK_CHECK_VERSION(2, 12, 0)
-#undef gtk_tooltips_set_tip
-#endif
 }
 
 void
@@ -10009,12 +10111,7 @@
 
 	/* 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);
 
@@ -10129,7 +10226,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);
@@ -10259,7 +10356,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;
 	}
 
@@ -10388,7 +10485,7 @@
 
 	/* 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/gtkconvwin.h	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkconvwin.h	Tue Jul 24 03:43:55 2012 -0400
@@ -42,6 +42,8 @@
 {
 	GtkWidget *window;           /**< The window.                      */
 	GtkWidget *notebook;         /**< The notebook of conversations.   */
+	GtkWidget *notebook_menu;    /**< The menu on the notebook.        */
+	PidginConversation *clicked_tab; /**< The menu currently clicked.      */
 	GList *gtkconvs;
 
 	struct
--- a/pidgin/gtkdebug.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkdebug.c	Tue Jul 24 03:43:55 2012 -0400
@@ -39,6 +39,8 @@
 
 #include <gdk/gdkkeysyms.h>
 
+#include "gtk3compat.h"
+
 typedef struct
 {
 	GtkWidget *window;
@@ -108,11 +110,7 @@
 static gboolean
 configure_cb(GtkWidget *w, GdkEventConfigure *event, DebugWindow *win)
 {
-#if GTK_CHECK_VERSION(2,18,0)
 	if (gtk_widget_get_visible(w)) {
-#else
-	if (GTK_WIDGET_VISIBLE(w)) {
-#endif
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/width",  event->width);
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/height", event->height);
 	}
@@ -511,12 +509,8 @@
 
 static void
 regex_key_release_cb(GtkWidget *w, GdkEventKey *e, DebugWindow *win) {
-	if(e->keyval == GDK_Return &&
-#if GTK_CHECK_VERSION(2,18,0)
+	if(e->keyval == GDK_KEY_Return &&
 	   gtk_widget_is_sensitive(win->filter) &&
-#else
-	   GTK_WIDGET_IS_SENSITIVE(win->filter) &&
-#endif
 	   !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);
@@ -689,22 +683,14 @@
 		/* Save */
 		item = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
 		gtk_tool_item_set_is_important(item, TRUE);
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_tool_item_set_tooltip_text(item, _("Save"));
-#else
-		gtk_tool_item_set_tooltip(item, tooltips, _("Save"), NULL);
-#endif
 		g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(save_cb), win);
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
 
 		/* Clear button */
 		item = gtk_tool_button_new_from_stock(GTK_STOCK_CLEAR);
 		gtk_tool_item_set_is_important(item, TRUE);
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_tool_item_set_tooltip_text(item, _("Clear"));
-#else
-		gtk_tool_item_set_tooltip(item, tooltips, _("Clear"), NULL);
-#endif
 		g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(clear_cb), win);
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
 
@@ -714,11 +700,7 @@
 		/* Pause */
 		item = gtk_toggle_tool_button_new_from_stock(PIDGIN_STOCK_PAUSE);
 		gtk_tool_item_set_is_important(item, TRUE);
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_tool_item_set_tooltip_text(item, _("Pause"));
-#else
-		gtk_tool_item_set_tooltip(item, tooltips, _("Pause"), NULL);
-#endif
 		g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(pause_cb), win);
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
 
@@ -731,11 +713,7 @@
 		gtk_tool_item_set_is_important(item, TRUE);
 		win->filter = GTK_WIDGET(item);
 		gtk_tool_button_set_label(GTK_TOOL_BUTTON(win->filter), _("Filter"));
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(win->filter), _("Filter"));
-#else
-		gtk_tooltips_set_tip(tooltips, win->filter, _("Filter"), NULL);
-#endif
 		g_signal_connect(G_OBJECT(win->filter), "clicked", G_CALLBACK(regex_filter_toggled_cb), win);
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(win->filter));
 
@@ -753,11 +731,7 @@
 		/* regex entry */
 		win->expression = gtk_entry_new();
 		item = gtk_tool_item_new();
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_widget_set_tooltip_text(win->expression, _("Right click for more options."));
-#else
-		gtk_tooltips_set_tip(tooltips, win->expression, _("Right click for more options."), NULL);
-#endif
 		gtk_container_add(GTK_CONTAINER(item), GTK_WIDGET(win->expression));
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
 
@@ -791,22 +765,18 @@
 		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."));
-#else
-		gtk_tooltips_set_tip(tooltips, win->filterlevel, _("Select the debug filter level."), NULL);
-#endif
 		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"));
 
--- a/pidgin/gtkdialogs.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkdialogs.c	Tue Jul 24 03:43:55 2012 -0400
@@ -44,6 +44,8 @@
 #include "gtkwebview.h"
 #include "pidginstock.h"
 
+#include "gtk3compat.h"
+
 static GList *dialogwindows = NULL;
 
 struct _PidginGroupMergeObject {
@@ -435,9 +437,14 @@
 	AtkObject *obj;
 	char *filename, *tmp;
 
+#if GTK_CHECK_VERSION(3,0,0)
+	win = pidgin_create_dialog(title, 0, role, TRUE);
+	vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, 0);
+#else
 	win = pidgin_create_dialog(title, PIDGIN_HIG_BORDER, role, TRUE);
 	vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER);
-	gtk_window_set_default_size(GTK_WINDOW(win), 450, 450);
+#endif
+	gtk_window_set_default_size(GTK_WINDOW(win), 475, 450);
 
 	/* Generate a logo with a version number */
 	filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "logo.png", NULL);
@@ -467,11 +474,7 @@
 	button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE,
 	                G_CALLBACK(destroy_win), win);
 
-#if GTK_CHECK_VERSION(2,18,0)
 	gtk_widget_set_can_default(button, TRUE);
-#else
-	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
-#endif
 	gtk_widget_grab_default(button);
 
 	gtk_widget_show_all(win);
@@ -977,14 +980,13 @@
 
 	gtk_container_set_border_width (GTK_CONTAINER(window), PIDGIN_HIG_BOX_SPACE);
 	gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
-#endif
-	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);
+	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/gtkdnd-hints.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkdnd-hints.c	Tue Jul 24 03:43:55 2012 -0400
@@ -34,6 +34,8 @@
 #include "win32dep.h"
 #endif
 
+#include "gtk3compat.h"
+
 typedef struct
 {
 	GtkWidget *widget;
@@ -54,6 +56,59 @@
 	{ NULL, NULL, 0, 0 }
 };
 
+#if GTK_CHECK_VERSION(3,0,0)
+
+static void
+dnd_hints_realized_cb(GtkWidget *window, GtkWidget *pix)
+{
+	GdkPixbuf *pixbuf;
+	cairo_surface_t *surface;
+	cairo_region_t *region;
+	cairo_t *cr;
+
+	pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(pix));
+
+	surface = cairo_image_surface_create(CAIRO_FORMAT_A1,
+	                                     gdk_pixbuf_get_width(pixbuf),
+	                                     gdk_pixbuf_get_height(pixbuf));
+
+	cr = cairo_create(surface);
+	gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
+	cairo_paint(cr);
+	cairo_destroy(cr);
+
+	region = gdk_cairo_region_create_from_surface(surface);
+	gtk_widget_shape_combine_region(window, region);
+	cairo_region_destroy(region);
+
+	cairo_surface_destroy(surface);
+}
+
+static GtkWidget *
+dnd_hints_init_window(const gchar *fname)
+{
+	GdkPixbuf *pixbuf;
+	GtkWidget *pix;
+	GtkWidget *win;
+
+	pixbuf = gdk_pixbuf_new_from_file(fname, NULL);
+	g_return_val_if_fail(pixbuf, NULL);
+
+	win = gtk_window_new(GTK_WINDOW_POPUP);
+	pix = gtk_image_new_from_pixbuf(pixbuf);
+	gtk_container_add(GTK_CONTAINER(win), pix);
+	gtk_widget_show_all(pix);
+
+	g_object_unref(G_OBJECT(pixbuf));
+
+	g_signal_connect(G_OBJECT(win), "realize",
+	                 G_CALLBACK(dnd_hints_realized_cb), pix);
+
+	return win;
+}
+
+#else
+
 static GtkWidget *
 dnd_hints_init_window(const gchar *fname)
 {
@@ -85,21 +140,29 @@
 	return win;
 }
 
+#endif
+
 static void
 get_widget_coords(GtkWidget *w, gint *x1, gint *y1, gint *x2, gint *y2)
 {
 	gint ox, oy, width, height;
+	GtkWidget *parent = gtk_widget_get_parent(w);
 
-	if (w->parent && w->parent->window == w->window)
+	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);
+		GdkWindow *win = gtk_widget_get_window(w);
+		gdk_window_get_origin(win, &ox, &oy);
+		width = gdk_window_get_width(win);
+		height = gdk_window_get_height(win);
 	}
 
 	if (x1) *x1 = ox;
@@ -172,10 +235,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.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkdocklet.c	Tue Jul 24 03:43:55 2012 -0400
@@ -45,6 +45,8 @@
 #include "gtkdocklet.h"
 #include "gtkdialogs.h"
 
+#include "gtk3compat.h"
+
 #ifndef DOCKLET_TOOLTIP_LINE_LIMIT
 #define DOCKLET_TOOLTIP_LINE_LIMIT 5
 #endif
@@ -104,11 +106,13 @@
 		gtk_status_icon_set_from_icon_name(docklet, icon_name);
 	}
 
+#if !GTK_CHECK_VERSION(3,0,0)
 	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);
 	}
+#endif
 }
 
 static GList *
@@ -196,7 +200,7 @@
 		if (tooltip_text->len > 0)
 			tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1);
 
-		gtk_status_icon_set_tooltip(docklet, tooltip_text->str);
+		gtk_status_icon_set_tooltip_text(docklet, tooltip_text->str);
 
 		g_string_free(tooltip_text, TRUE);
 		g_list_free(convs);
@@ -204,7 +208,7 @@
 	} else {
 		char *tooltip_text = g_strconcat(PIDGIN_NAME, " - ",
 			purple_savedstatus_get_title(saved_status), NULL);
-		gtk_status_icon_set_tooltip(docklet, tooltip_text);
+		gtk_status_icon_set_tooltip_text(docklet, tooltip_text);
 		g_free(tooltip_text);
 	}
 
@@ -328,19 +332,23 @@
 static void
 docklet_toggle_mute(GtkWidget *toggle, void *data)
 {
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/sound/mute", 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)));
 }
 
+#if !GTK_CHECK_VERSION(3,0,0)
 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 "/docklet/blink",
+	                      gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(toggle)));
 }
+#endif
 
 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
@@ -606,7 +614,7 @@
 
 
 static void
-plugin_act(GtkObject *obj, PurplePluginAction *pam)
+plugin_act(GtkWidget *widget, PurplePluginAction *pam)
 {
 	if (pam && pam->callback)
 		pam->callback(pam);
@@ -748,10 +756,12 @@
 	g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_mute), NULL);
 	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
+#if !GTK_CHECK_VERSION(3,0,0)
 	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);
+#endif
 
 	pidgin_separator(menu);
 
--- a/pidgin/gtkft.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkft.c	Tue Jul 24 03:43:55 2012 -0400
@@ -701,7 +701,7 @@
 {
 	PidginXferDialog *dialog;
 	GtkWidget *window;
-	GtkWidget *vbox1, *vbox2;
+	GtkWidget *vbox;
 	GtkWidget *expander;
 	GtkWidget *alignment;
 	GtkWidget *table;
@@ -715,24 +715,21 @@
 		purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/filetransfer/clear_finished");
 
 	/* Create the window. */
-	dialog->window = window = pidgin_create_window(_("File Transfers"), PIDGIN_HIG_BORDER, "file transfer", TRUE);
+#if GTK_CHECK_VERSION(3,0,0)
+	dialog->window = window = pidgin_create_dialog(_("File Transfers"), 0, "file transfer", TRUE);
+#else
+	dialog->window = window = pidgin_create_dialog(_("File Transfers"), PIDGIN_HIG_BORDER, "file transfer", TRUE);
+#endif
 	gtk_window_set_default_size(GTK_WINDOW(window), 450, 250);
 
 	g_signal_connect(G_OBJECT(window), "delete_event",
 					 G_CALLBACK(delete_win_cb), dialog);
 
-	/* Create the parent vbox for everything. */
-	vbox1 = gtk_vbox_new(FALSE, 0);
-	gtk_widget_show(vbox1);
-	gtk_container_add(GTK_CONTAINER(window), vbox1);
-
 	/* Create the main vbox for top half of the window. */
-	vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox1), vbox2, TRUE, TRUE, 0);
-	gtk_widget_show(vbox2);
+	vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(window), FALSE, PIDGIN_HIG_BORDER);
 
 	/* Setup the listbox */
-	gtk_box_pack_start(GTK_BOX(vbox2),
+	gtk_box_pack_start(GTK_BOX(vbox),
 		pidgin_make_scrollable(setup_tree(dialog), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 140),
 		TRUE, TRUE, 0);
 
@@ -743,7 +740,7 @@
 								 !dialog->keep_open);
 	g_signal_connect(G_OBJECT(checkbox), "toggled",
 					 G_CALLBACK(toggle_keep_open_cb), dialog);
-	gtk_box_pack_start(GTK_BOX(vbox2), checkbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0);
 	gtk_widget_show(checkbox);
 
 	/* "Clear finished transfers" */
@@ -753,13 +750,13 @@
 								 dialog->auto_clear);
 	g_signal_connect(G_OBJECT(checkbox), "toggled",
 					 G_CALLBACK(toggle_clear_finished_cb), dialog);
-	gtk_box_pack_start(GTK_BOX(vbox2), checkbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0);
 	gtk_widget_show(checkbox);
 
 	/* "Download Details" arrow */
 	expander = gtk_expander_new_with_mnemonic(_("File transfer _details"));
 	dialog->expander = expander;
-	gtk_box_pack_start(GTK_BOX(vbox2), expander, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), expander, FALSE, FALSE, 0);
 	gtk_widget_show(expander);
 
 	gtk_widget_set_sensitive(expander, FALSE);
@@ -775,11 +772,7 @@
 	gtk_container_add(GTK_CONTAINER(alignment), table);
 	gtk_widget_show(table);
 
-	bbox = gtk_hbutton_box_new();
-	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
-	gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_end(GTK_BOX(vbox1), bbox, FALSE, TRUE, 0);
-	gtk_widget_show(bbox);
+	bbox = pidgin_dialog_get_action_area(GTK_DIALOG(window));
 
 #define ADD_BUTTON(b, label, callback, callbackdata) do { \
 		GtkWidget *button = gtk_button_new_from_stock(label); \
--- a/pidgin/gtkimhtml.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkimhtml.c	Tue Jul 24 03:43:55 2012 -0400
@@ -65,15 +65,7 @@
 
 #define TOOLTIP_TIMEOUT 500
 
-#if !GTK_CHECK_VERSION(2,20,0)
-#define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x)
-
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_get_has_window(x) !GTK_WIDGET_NO_WINDOW(x)
-#define gtk_widget_get_state(x) GTK_WIDGET_STATE(x)
-#define gtk_widget_is_drawable(x) GTK_WIDGET_DRAWABLE(x)
-#endif
-#endif
+#include "gtk3compat.h"
 
 static GtkTextViewClass *parent_class = NULL;
 
@@ -553,21 +545,41 @@
 	}
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean
+gtk_imhtml_tip_paint(GtkIMHtml *imhtml, cairo_t *cr, GtkWidget *w)
+#else
 static gint
-gtk_imhtml_tip_paint (GtkIMHtml *imhtml)
+gtk_imhtml_tip_paint(GtkIMHtml *imhtml, GdkEvent *event, GtkWidget *w)
+#endif
 {
 	PangoLayout *layout;
+	GtkStyle *style;
 
 	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);
+	style = gtk_widget_get_style(imhtml->tip_window);
+
+#if GTK_CHECK_VERSION(3,0,0)
+	gtk_paint_flat_box(style, cr,
+	                   GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+	                   imhtml->tip_window, "tooltip",
+	                   0, 0, -1, -1);
+
+	gtk_paint_layout(style, cr,
+	                 GTK_STATE_NORMAL, TRUE, imhtml->tip_window, NULL,
+	                 4, 4, layout);
+#else
+	gtk_paint_flat_box(style, gtk_widget_get_window(imhtml->tip_window),
+	                   GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+	                   NULL, imhtml->tip_window,
+	                   "tooltip", 0, 0, -1, -1);
+
+	gtk_paint_layout(style, gtk_widget_get_window(imhtml->tip_window),
+	                 GTK_STATE_NORMAL, FALSE, NULL, imhtml->tip_window, NULL,
+	                 4, 4, layout);
+#endif
 
 	g_object_unref(layout);
 	return FALSE;
@@ -580,12 +592,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_is_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;
 	}
@@ -603,17 +618,21 @@
 	gtk_widget_set_name (imhtml->tip_window, "gtk-tooltips");
 	gtk_window_set_type_hint (GTK_WINDOW (imhtml->tip_window),
 		GDK_WINDOW_TYPE_HINT_TOOLTIP);
-	g_signal_connect_swapped (G_OBJECT (imhtml->tip_window), "expose_event",
-							  G_CALLBACK (gtk_imhtml_tip_paint), imhtml);
+#if GTK_CHECK_VERSION(3,0,0)
+	g_signal_connect_swapped(G_OBJECT(imhtml->tip_window), "draw",
+	                         G_CALLBACK(gtk_imhtml_tip_paint), imhtml);
+#else
+	g_signal_connect_swapped(G_OBJECT(imhtml->tip_window), "expose_event",
+	                         G_CALLBACK(gtk_imhtml_tip_paint), imhtml);
+#endif
 
 	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",
@@ -638,8 +657,8 @@
 	h = 8 + baseline_skip;
 
 	gdk_window_get_pointer (NULL, &x, &y, NULL);
-	if (!gtk_widget_get_has_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();
 
@@ -679,7 +698,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);
@@ -807,6 +826,8 @@
 	return FALSE;
 }
 
+/* TODO: I think this can be removed for GTK+ 3.0... */
+#if !GTK_CHECK_VERSION(3,0,0)
 static gint
 gtk_imhtml_expose_event (GtkWidget      *widget,
 			 GdkEventExpose *event)
@@ -834,7 +855,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_get_state(widget)]));
+			gdk_cairo_set_source_color(cr,
+				&(gtk_widget_get_style(widget)->base[gtk_widget_get_state(widget)]));
 		}
 
 		cairo_rectangle(cr,
@@ -940,6 +962,7 @@
 
 	return FALSE;
 }
+#endif
 
 
 static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml)
@@ -1111,7 +1134,7 @@
 	}
 	if (primary) /* This was allocated here */
 		g_free(text);
- }
+}
 
 static void gtk_imhtml_primary_clipboard_clear(GtkClipboard *clipboard, GtkIMHtml *imhtml)
 {
@@ -1216,11 +1239,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 {
@@ -1244,13 +1268,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
@@ -1261,10 +1285,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) {
@@ -1379,7 +1403,7 @@
 				       paste_received_cb, imhtml);
 
 		return TRUE;
-        }
+	}
 
 	return FALSE;
 }
@@ -1625,7 +1649,10 @@
 
 	gobject_class->finalize = gtk_imhtml_finalize;
 	widget_class->drag_motion = gtk_text_view_drag_motion;
+	/* TODO: I _think_ this should be removed for GTK+ 3.0 */
+#if !GTK_CHECK_VERSION(3,0,0)
 	widget_class->expose_event = gtk_imhtml_expose_event;
+#endif
 	parent_size_allocate = widget_class->size_allocate;
 	widget_class->size_allocate = gtk_imhtml_size_allocate;
 	parent_style_set = widget_class->style_set;
@@ -1687,20 +1714,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)
@@ -1927,23 +1954,23 @@
 		/* 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;
 		}
 	}
 
 	gdk_drag_status (context, suggested_action, time);
 
-  /* TRUE return means don't propagate the drag motion to parent
-   * widgets that may also be drop sites.
-   */
-  return TRUE;
+	/* TRUE return means don't propagate the drag motion to parent
+	 * widgets that may also be drop sites.
+	 */
+	return TRUE;
 }
 
 static void
@@ -1965,21 +1992,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;
 
@@ -2001,7 +2029,7 @@
 
 				i++;
 			}
-            g_strfreev(links);
+			g_strfreev(links);
 			break;
 		case GTK_IMHTML_DRAG_HTML:
 			{
@@ -2017,8 +2045,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");
@@ -2047,7 +2075,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);
 	}
@@ -2578,8 +2607,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);
@@ -2602,9 +2631,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;
@@ -4286,9 +4316,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);
@@ -4304,9 +4339,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, &iter, e);
+
+				g_free(name);
 			}
 
 			g_slist_free(tags);
@@ -4427,11 +4467,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);
@@ -4653,27 +4698,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);
@@ -4964,6 +5014,8 @@
 	gtk_text_buffer_end_user_action(imhtml->text_buffer);
 }
 
+/* TODO: I think this can be removed for GTK+ 3.0... */
+#if !GTK_CHECK_VERSION(3,0,0)
 static gboolean
 image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
 {
@@ -4971,9 +5023,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) {
@@ -5068,7 +5121,7 @@
 						}
 					}
 				} else {
- 					imhtml->num_animations++;
+					imhtml->num_animations++;
 				}
 				g_signal_connect(G_OBJECT(icon), "destroy", G_CALLBACK(animated_smiley_destroy_cb), imhtml);
 				g_queue_push_tail(imhtml->animations, icon);
@@ -5092,7 +5145,10 @@
 		 * 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? */
+#if !GTK_CHECK_VERSION(3,0,0)
 		g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
+#endif
 
 		gtk_widget_show(icon);
 		if (ebox)
@@ -5186,22 +5242,29 @@
 
 static const gchar *tag_to_html_start(GtkTextTag *tag)
 {
-	const gchar *name;
 	static gchar buf[1024];
-
-	name = tag->name;
+	gchar *name = NULL;
+
+	g_object_get(G_OBJECT(tag), "name", &name, NULL);
 	g_return_val_if_fail(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';
@@ -5211,18 +5274,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;
@@ -5285,6 +5359,7 @@
 		}
 
 		g_snprintf(str, sizeof(buf) - (str - buf), "'>");
+		g_free(name);
 
 		return (empty ? "" : buf);
 	}
@@ -5292,30 +5367,40 @@
 
 static const gchar *tag_to_html_end(GtkTextTag *tag)
 {
-	const gchar *name;
-
-	name = tag->name;
+	gchar *name;
+
+	g_object_get(G_OBJECT(tag), "name", &name, NULL);
 	g_return_val_if_fail(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",
@@ -5328,6 +5413,8 @@
 				return "</span>";
 		}
 
+		g_free(name);
+
 		return "";
 	}
 }
--- a/pidgin/gtkimhtmltoolbar.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkimhtmltoolbar.c	Tue Jul 24 03:43:55 2012 -0400
@@ -43,10 +43,8 @@
 
 #include <gdk/gdkkeysyms.h>
 
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
-#define gtk_widget_is_sensitive(x) GTK_WIDGET_IS_SENSITIVE(x)
-#endif
+#define GTK_TOOLTIPS_VAR toolbar->tooltips
+#include "gtk3compat.h"
 
 static GtkHBoxClass *parent_class = NULL;
 
@@ -129,11 +127,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
@@ -196,10 +198,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);
 		}
@@ -258,9 +262,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);
@@ -269,12 +276,13 @@
 
 			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 {
@@ -338,9 +346,13 @@
 		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;
+			colorsel =
+				gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(toolbar->bgcolor_dialog));
+
 			if (color) {
 				gdk_color_parse(color, &bgcolor);
 				gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &bgcolor);
@@ -349,11 +361,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);
 
 		}
@@ -466,12 +481,12 @@
 
 static void insert_hr_cb(GtkWidget *widget, GtkIMHtmlToolbar *toolbar)
 {
-        GtkTextIter iter;
-        GtkTextMark *ins;
+	GtkTextIter iter;
+	GtkTextMark *ins;
 	GtkIMHtmlScalable *hr;
 
-        ins = gtk_text_buffer_get_insert(gtk_text_view_get_buffer(GTK_TEXT_VIEW(toolbar->imhtml)));
-        gtk_text_buffer_get_iter_at_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(toolbar->imhtml)), &iter, ins);
+	ins = gtk_text_buffer_get_insert(gtk_text_view_get_buffer(GTK_TEXT_VIEW(toolbar->imhtml)));
+	gtk_text_buffer_get_iter_at_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(toolbar->imhtml)), &iter, ins);
 	hr = gtk_imhtml_hr_new();
 	gtk_imhtml_hr_add_to(hr, GTK_IMHTML(toolbar->imhtml), &iter);
 }
@@ -663,11 +678,7 @@
 	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);
@@ -681,11 +692,7 @@
 		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 */
@@ -727,7 +734,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);
@@ -1097,19 +1104,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
@@ -1268,11 +1277,7 @@
 			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);
@@ -1294,7 +1299,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
@@ -1317,10 +1322,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"));
 	}
 }
@@ -1418,7 +1423,8 @@
 
 	g_signal_connect(G_OBJECT(font_button), "button-press-event", G_CALLBACK(button_activate_on_click), toolbar);
 	g_signal_connect(G_OBJECT(font_button), "activate", G_CALLBACK(pidgin_menu_clicked), font_menu);
-	g_signal_connect(G_OBJECT(font_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate), font_button);
+	g_signal_connect_data(G_OBJECT(font_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate),
+	                      g_object_ref(font_button), (GClosureNotify)g_object_unref, 0);
 
 	/* Sep */
 	sep = gtk_vseparator_new();
@@ -1463,7 +1469,8 @@
 
 	g_signal_connect(G_OBJECT(insert_button), "button-press-event", G_CALLBACK(button_activate_on_click), toolbar);
 	g_signal_connect(G_OBJECT(insert_button), "activate", G_CALLBACK(pidgin_menu_clicked), insert_menu);
-	g_signal_connect(G_OBJECT(insert_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate), insert_button);
+	g_signal_connect_data(G_OBJECT(insert_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate),
+	                      g_object_ref(insert_button), (GClosureNotify)g_object_unref, 0);
 	toolbar->sml = NULL;
 
 	/* Sep */
--- a/pidgin/gtklog.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtklog.c	Tue Jul 24 03:43:55 2012 -0400
@@ -39,6 +39,8 @@
 #include "gtkutils.h"
 #include "gtkwebview.h"
 
+#include "gtk3compat.h"
+
 static GHashTable *log_viewers = NULL;
 static void populate_log_tree(PidginLogViewer *lv);
 static PidginLogViewer *syslog_viewer = NULL;
@@ -583,10 +585,7 @@
 	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);
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE);
-#endif
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(lv->window)->vbox), 0);
+	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");
@@ -595,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);
@@ -614,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 *************/
 	lv->treestore = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
@@ -649,7 +650,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/gtkmedia.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkmedia.c	Tue Jul 24 03:43:55 2012 -0400
@@ -46,6 +46,8 @@
 
 #include <gst/interfaces/xoverlay.h>
 
+#include "gtk3compat.h"
+
 #define PIDGIN_TYPE_MEDIA            (pidgin_media_get_type())
 #define PIDGIN_MEDIA(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), PIDGIN_TYPE_MEDIA, PidginMedia))
 #define PIDGIN_MEDIA_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), PIDGIN_TYPE_MEDIA, PidginMediaClass))
@@ -540,20 +542,12 @@
 	GdkWindow *window = NULL;
 
 	if (data->participant == NULL)
-#if GTK_CHECK_VERSION(2, 14, 0)
 		window = gtk_widget_get_window(priv->local_video);
-#else
-		window = (priv->local_video)->window;
-#endif
 	else {
 		GtkWidget *widget = pidgin_media_get_widget(data->gtkmedia,
 				data->session_id, data->participant);
 		if (widget)
-#if GTK_CHECK_VERSION(2, 14, 0)
 			window = gtk_widget_get_window(widget);
-#else
-			window = widget->window;
-#endif
 	}
 
 	if (window) {
@@ -561,7 +555,7 @@
 #ifdef _WIN32
 		window_id = GDK_WINDOW_HWND(window);
 #elif defined(HAVE_X11)
-		window_id = GDK_WINDOW_XWINDOW(window);
+		window_id = gdk_x11_window_get_xid(window);
 #elif defined(GDK_WINDOWING_QUARTZ)
 		window_id = (gulong) gdk_quartz_window_get_nsview(window);
 #else
--- a/pidgin/gtkmenutray.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkmenutray.c	Tue Jul 24 03:43:55 2012 -0400
@@ -23,6 +23,8 @@
 
 #include <gtk/gtk.h>
 
+#include "gtk3compat.h"
+
 /******************************************************************************
  * Enums
  *****************************************************************************/
@@ -43,15 +45,12 @@
  * Internal Stuff
  *****************************************************************************/
 
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_get_has_window(x) !GTK_WIDGET_NO_WINDOW(x)
-#endif
-
 /******************************************************************************
  * Item Stuff
  *****************************************************************************/
+#if GTK_CHECK_VERSION(3,0,0)
 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.
@@ -59,11 +58,26 @@
 }
 
 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.
 	 */
 }
+#else
+static void
+pidgin_menu_tray_select(GtkItem *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.
+	 */
+}
+static void
+pidgin_menu_tray_deselect(GtkItem *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.
+	 */
+}
+#endif
 
 /******************************************************************************
  * Widget Stuff
@@ -128,7 +142,11 @@
 static void
 pidgin_menu_tray_class_init(PidginMenuTrayClass *klass) {
 	GObjectClass *object_class = G_OBJECT_CLASS(klass);
-	GtkItemClass *item_class = GTK_ITEM_CLASS(klass);
+#if GTK_CHECK_VERSION(3,0,0)
+	GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS(klass);
+#else
+	GtkItemClass *menu_item_class = GTK_ITEM_CLASS(klass);
+#endif
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 	GParamSpec *pspec;
 
@@ -137,8 +155,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;
 
@@ -270,7 +288,7 @@
 	 * not on the widget itself.
 	 */
 	if (!gtk_widget_get_has_window(widget))
-		widget = widget->parent;
+		widget = gtk_widget_get_parent(widget);
 
 #if GTK_CHECK_VERSION(2,12,0)
 	gtk_widget_set_tooltip_text(widget, tooltip);
--- a/pidgin/gtknotify.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtknotify.c	Tue Jul 24 03:43:55 2012 -0400
@@ -534,14 +534,14 @@
 
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER);
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-#endif
-	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);
@@ -786,11 +786,7 @@
 		gtk_tree_selection_select_iter(sel, &iter);
 	}
 
-#if GTK_CHECK_VERSION(2,18,0)
 	if (!gtk_widget_get_visible(mail_dialog->dialog)) {
-#else
-	if (!GTK_WIDGET_VISIBLE(mail_dialog->dialog)) {
-#endif
 		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>",
@@ -806,11 +802,7 @@
 		g_free(label_text);
 		if (pixbuf)
 			g_object_unref(pixbuf);
-#if GTK_CHECK_VERSION(2,18,0)
 	} else if (!gtk_widget_has_focus(mail_dialog->dialog))
-#else
-	} else if (!GTK_WIDGET_HAS_FOCUS(mail_dialog->dialog))
-#endif
 		pidgin_set_urgent(GTK_WINDOW(mail_dialog->dialog), TRUE);
 
 	return data;
@@ -819,7 +811,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);
 
@@ -844,14 +836,16 @@
 
 	window = gtk_dialog_new();
 	gtk_window_set_title(GTK_WINDOW(window), title);
+#if !GTK_CHECK_VERSION(3,0,0)
 	gtk_container_set_border_width(GTK_CONTAINER(window), PIDGIN_HIG_BORDER);
+#endif
 	gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
 
 	g_signal_connect(G_OBJECT(window), "delete_event",
 					 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);
@@ -979,7 +973,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;
@@ -1510,16 +1504,13 @@
 
 	dialog = gtk_dialog_new();
 
+	/* Vertical box */
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
 	/* 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);
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-#endif
-	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
-
-	/* Vertical box */
-	vbox = GTK_DIALOG(dialog)->vbox;
+	gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE);
+	gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER);
 
 	/* Golden ratio it up! */
 	gtk_widget_set_size_request(dialog, 550, 400);
--- a/pidgin/gtkplugin.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkplugin.c	Tue Jul 24 03:43:55 2012 -0400
@@ -35,6 +35,8 @@
 
 #include <string.h>
 
+#include "gtk3compat.h"
+
 #define PIDGIN_RESPONSE_CONFIGURE 98121
 
 static void plugin_toggled_stage_two(PurplePlugin *plug, GtkTreeModel *model,
@@ -518,7 +520,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 +529,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);
@@ -559,12 +561,18 @@
 }
 
 static gboolean
-pidgin_plugins_paint_tooltip(GtkWidget *tipwindow, gpointer data)
+pidgin_plugins_paint_tooltip(GtkWidget *tipwindow, cairo_t *cr, gpointer data)
 {
 	PangoLayout *layout = g_object_get_data(G_OBJECT(tipwindow), "tooltip-plugin");
+#if GTK_CHECK_VERSION(3,0,0)
+	gtk_paint_layout(gtk_widget_get_style(tipwindow), cr, GTK_STATE_NORMAL, FALSE,
+	                 tipwindow, "tooltip",
+	                 6, 6, layout);
+#else
 	gtk_paint_layout(tipwindow->style, tipwindow->window, GTK_STATE_NORMAL, FALSE,
-			NULL, tipwindow, "tooltip",
-			6, 6, layout);
+	                 NULL, tipwindow, "tooltip",
+	                 6, 6, layout);
+#endif
 	return TRUE;
 }
 
@@ -717,10 +725,8 @@
 		return;
 	}
 
-	plugin_dialog = gtk_dialog_new_with_buttons(_("Plugins"),
-						    NULL,
-						    GTK_DIALOG_NO_SEPARATOR,
-						    NULL);
+	plugin_dialog = gtk_dialog_new();
+	gtk_window_set_title(GTK_WINDOW(plugin_dialog), _("Plugins"));
 	pref_button = gtk_dialog_add_button(GTK_DIALOG(plugin_dialog),
 						_("Configure Pl_ugin"), PIDGIN_RESPONSE_CONFIGURE);
 	gtk_dialog_add_button(GTK_DIALOG(plugin_dialog),
@@ -772,7 +778,7 @@
 	gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col);
 	gtk_tree_view_column_set_sort_column_id(col, 1);
 	g_object_unref(G_OBJECT(ls));
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), 
+	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(plugin_dialog))),
 		pidgin_make_scrollable(event_view, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1), 
 		TRUE, TRUE, 0);
 	gtk_tree_view_set_search_column(GTK_TREE_VIEW(event_view), 1);
@@ -788,8 +794,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/gtkpluginpref.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkpluginpref.c	Tue Jul 24 03:43:55 2012 -0400
@@ -211,7 +211,9 @@
 	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
 	parent = ret = gtk_vbox_new(FALSE, 16);
+#if !GTK_CHECK_VERSION(3,0,0)
 	gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER);
+#endif
 	gtk_widget_show(ret);
 
 	for(pp = purple_plugin_pref_frame_get_prefs(frame);
--- a/pidgin/gtkpounce.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkpounce.c	Tue Jul 24 03:43:55 2012 -0400
@@ -410,13 +410,15 @@
 				GtkSelectionData *sd, guint info, guint t, gpointer data)
 {
 	PidginPounceDialog *dialog;
+	GdkAtom target = gtk_selection_data_get_target(sd);
+	const guchar *sd_data = gtk_selection_data_get_data(sd);
 
-	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));
+		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 = purple_buddy_get_account(buddy);
 		pidgin_account_option_menu_set_selected(dialog->account_menu, purple_buddy_get_account(buddy));
 
-		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);
 	}
 }
 
@@ -534,13 +536,15 @@
 	dialog->window = window = gtk_dialog_new();
 	gtk_window_set_title(GTK_WINDOW(window), (cur_pounce == NULL ? _("Add Buddy Pounce") : _("Modify Buddy Pounce")));
 	gtk_window_set_role(GTK_WINDOW(window), "buddy_pounce");
+#if !GTK_CHECK_VERSION(3,0,0)
 	gtk_container_set_border_width(GTK_CONTAINER(dialog->window), PIDGIN_HIG_BORDER);
+#endif
 
 	g_signal_connect(G_OBJECT(window), "delete_event",
 					 G_CALLBACK(delete_win_cb), dialog);
 
-	/* Create the parent vbox for everything. */
-	vbox1 = GTK_DIALOG(window)->vbox;
+	/* Get the parent vbox for everything. */
+	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,11 +1022,7 @@
 static gboolean
 pounces_manager_configure_cb(GtkWidget *widget, GdkEventConfigure *event, PouncesManager *dialog)
 {
-#if GTK_CHECK_VERSION(2,18,0)
 	if (gtk_widget_get_visible(widget)) {
-#else
-	if (GTK_WIDGET_VISIBLE(widget)) {
-#endif
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/pounces/dialog/width",  event->width);
 		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/pounces/dialog/height", event->height);
 	}
@@ -1335,7 +1335,11 @@
 	width  = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/pounces/dialog/width");
 	height = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/pounces/dialog/height");
 
+#if GTK_CHECK_VERSION(3,0,0)
+	dialog->window = win = pidgin_create_dialog(_("Buddy Pounces"), 0, "pounces", TRUE);
+#else
 	dialog->window = win = pidgin_create_dialog(_("Buddy Pounces"), PIDGIN_HIG_BORDER, "pounces", TRUE);
+#endif
 	gtk_window_set_default_size(GTK_WINDOW(win), width, height);
 
 	g_signal_connect(G_OBJECT(win), "delete_event",
--- a/pidgin/gtkprefs.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkprefs.c	Tue Jul 24 03:43:55 2012 -0400
@@ -58,6 +58,8 @@
 #include "gtkwebviewtoolbar.h"
 #include "pidginstock.h"
 
+#include "gtk3compat.h"
+
 #define PROXYHOST 0
 #define PROXYPORT 1
 #define PROXYUSER 2
@@ -123,13 +125,13 @@
 		const char *key, int min, int max, GtkSizeGroup *sg)
 {
 	GtkWidget *spin;
-	GtkObject *adjust;
+	GtkAdjustment *adjust;
 	int val;
 
 	val = purple_prefs_get_int(key);
 
-	adjust = gtk_adjustment_new(val, min, max, 1, 1, 0);
-	spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
+	adjust = GTK_ADJUSTMENT(gtk_adjustment_new(val, min, max, 1, 1, 0));
+	spin = gtk_spin_button_new(adjust, 1, 0);
 	g_object_set_data(G_OBJECT(spin), "val", (char *)key);
 	if (max < 10000)
 		gtk_widget_set_size_request(spin, 50, -1);
@@ -902,9 +904,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;
@@ -2639,7 +2642,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;
@@ -2739,12 +2742,15 @@
 
 	/* 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,
+	parent = gtk_widget_get_parent(vbox);
+	parent_parent = gtk_widget_get_parent(parent);
+	parent_parent_parent = gtk_widget_get_parent(parent_parent);
+	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 */
 	event_store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
@@ -2981,7 +2987,11 @@
 	/* Back to instant-apply! I win!  BU-HAHAHA! */
 
 	/* Create the window */
+#if GTK_CHECK_VERSION(3,0,0)
+	prefs = pidgin_create_dialog(_("Preferences"), 0, "preferences", FALSE);
+#else
 	prefs = pidgin_create_dialog(_("Preferences"), PIDGIN_HIG_BORDER, "preferences", FALSE);
+#endif
 	g_signal_connect(G_OBJECT(prefs), "destroy",
 					 G_CALLBACK(delete_prefs), NULL);
 
--- a/pidgin/gtkprivacy.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkprivacy.c	Tue Jul 24 03:43:55 2012 -0400
@@ -36,6 +36,8 @@
 #include "gtkprivacy.h"
 #include "gtkutils.h"
 
+#include "gtk3compat.h"
+
 typedef struct
 {
 	GtkWidget *win;
@@ -235,7 +237,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);
@@ -363,12 +365,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 == purple_account_get_privacy_type(dialog->account))
@@ -434,7 +436,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	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkrequest.c	Tue Jul 24 03:43:55 2012 -0400
@@ -42,22 +42,16 @@
 #ifdef ENABLE_GCR
 #define GCR_API_SUBJECT_TO_CHANGE
 #include <gcr/gcr.h>
+#if !GTK_CHECK_VERSION(3,0,0)
 #include <gcr/gcr-simple-certificate.h>
 #endif
+#endif
 
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_set_can_default(x,y) do {\
-	if (y) \
-		GTK_WIDGET_SET_FLAGS(x, GTK_CAN_DEFAULT); \
-	else \
-		GTK_WIDGET_UNSET_FLAGS(x, GTK_CAN_DEFAULT); \
-} while(0)
-#define gtk_widget_set_can_focus(x,y) do {\
-	if (y) \
-		GTK_WIDGET_SET_FLAGS(x, GTK_CAN_FOCUS); \
-	else \
-		GTK_WIDGET_UNSET_FLAGS(x, GTK_CAN_FOCUS); \
-} while(0)
+#include "gtk3compat.h"
+
+#if !GTK_CHECK_VERSION(2,12,0)
+#undef gtk_widget_set_tooltip_text
+#define gtk_widget_set_tooltip_text(x,y)
 #endif
 
 static GtkWidget * create_account_field(PurpleRequestField *field);
@@ -107,9 +101,6 @@
 {
 	GtkWidget *image;
 	GdkPixbuf *pixbuf;
-#if !GTK_CHECK_VERSION(2,12,0)
-	GtkTooltips *tips;
-#endif
 
 	if (!account)
 		return;
@@ -118,16 +109,13 @@
 	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);
@@ -284,11 +272,7 @@
 {
 	generic_response_start(data);
 
-#if GTK_CHECK_VERSION(2,18,0)
 	if (!gtk_widget_has_focus(button))
-#else
-	if (!GTK_WIDGET_HAS_FOCUS(button))
-#endif
 		gtk_widget_grab_focus(button);
 
 	if (data->cbs[0] != NULL)
@@ -384,18 +368,18 @@
 
 	/* 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);
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-#endif
 	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,
@@ -553,16 +537,16 @@
 
 	/* 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);
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-#endif
-	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,
@@ -677,16 +661,16 @@
 
 	/* 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);
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-#endif
-	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. */
 	if (icon_data) {
@@ -896,9 +880,7 @@
 			gtk_text_buffer_set_text(buffer, value, -1);
 		}
 
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_widget_set_tooltip_text(textview, purple_request_field_get_tooltip(field));
-#endif
 
 		gtk_text_view_set_editable(GTK_TEXT_VIEW(textview),
 			purple_request_field_string_is_editable(field));
@@ -924,9 +906,7 @@
 		if (value != NULL)
 			gtk_entry_set_text(GTK_ENTRY(widget), value);
 
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
-#endif
 
 		if (purple_request_field_string_is_masked(field))
 		{
@@ -968,9 +948,7 @@
 		gtk_entry_set_text(GTK_ENTRY(widget), buf);
 	}
 
-#if GTK_CHECK_VERSION(2,12,0)
 	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
-#endif
 
 	g_signal_connect(G_OBJECT(widget), "focus-out-event",
 					 G_CALLBACK(field_int_focus_out_cb), field);
@@ -986,9 +964,7 @@
 	widget = gtk_check_button_new_with_label(
 		purple_request_field_get_label(field));
 
-#if GTK_CHECK_VERSION(2,12,0)
 	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
-#endif
 
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
 		purple_request_field_bool_get_default_value(field));
@@ -1009,20 +985,18 @@
 
 	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),
 						purple_request_field_choice_get_default_value(field));
 
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
-#endif
 
 		g_signal_connect(G_OBJECT(widget), "changed",
 						 G_CALLBACK(field_choice_menu_cb), field);
@@ -1041,9 +1015,7 @@
 
 		widget = box;
 
-#if GTK_CHECK_VERSION(2,12,0)
 		gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
-#endif
 
 		for (l = labels, i = 0; l != NULL; l = l->next, i++)
 		{
@@ -1087,9 +1059,7 @@
 	g_object_unref(G_OBJECT(buf));
 	g_object_unref(G_OBJECT(scale));
 
-#if GTK_CHECK_VERSION(2,12,0)
 	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
-#endif
 
 	return widget;
 }
@@ -1106,9 +1076,7 @@
 		purple_request_field_account_get_filter(field),
 		field);
 
-#if GTK_CHECK_VERSION(2,12,0)
 	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
-#endif
 
 	return widget;
 }
--- a/pidgin/gtkroomlist.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkroomlist.c	Tue Jul 24 03:43:55 2012 -0400
@@ -352,7 +352,7 @@
 #define TOOLTIP_BORDER 12
 
 static gboolean
-pidgin_roomlist_paint_tooltip(GtkWidget *widget, gpointer user_data)
+pidgin_roomlist_paint_tooltip(GtkWidget *widget, cairo_t *cr, gpointer user_data)
 {
 	PurpleRoomlist *list = user_data;
 	PidginRoomlist *grl = purple_roomlist_get_ui_data(list);
@@ -361,34 +361,69 @@
 	int max_text_width;
 	GtkTextDirection dir = gtk_widget_get_direction(GTK_WIDGET(grl->tree));
 
-	style = grl->tipwindow->style;
+	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;
 
 	current_height = 12;
 
+#if GTK_CHECK_VERSION(3,0,0)
 	if (dir == GTK_TEXT_DIR_RTL) {
-		gtk_paint_layout(style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
-				NULL, grl->tipwindow, "tooltip",
-				max_width - (TOOLTIP_BORDER + SMALL_SPACE) - PANGO_PIXELS(600000),
-				current_height, grl->tip_name_layout);
+		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",
-				TOOLTIP_BORDER + SMALL_SPACE, current_height, grl->tip_name_layout);
+		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",
-				TOOLTIP_BORDER + SMALL_SPACE, current_height + grl->tip_name_height, grl->tip_layout);
+		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, 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);
+	}
+#else
+	if (dir == GTK_TEXT_DIR_RTL) {
+		gtk_paint_layout(style, grl->tipwindow->window, GTK_STATE_NORMAL, FALSE,
+		                 NULL, 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",
-				max_width - (TOOLTIP_BORDER + SMALL_SPACE) - PANGO_PIXELS(600000),
-				current_height + grl->tip_name_height,
-				grl->tip_layout);
+		                 NULL, 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",
+		                 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",
+		                 max_width - (TOOLTIP_BORDER + SMALL_SPACE) - PANGO_PIXELS(600000),
+		                 current_height + grl->tip_name_height,
+		                 grl->tip_layout);
+	}
+#endif
+
 	return FALSE;
 }
 
@@ -533,7 +568,11 @@
 	dialog->account = account;
 
 	/* Create the window. */
+#if GTK_CHECK_VERSION(3,0,0)
+	dialog->window = window = pidgin_create_dialog(_("Room List"), 0, "room list", TRUE);
+#else
 	dialog->window = window = pidgin_create_dialog(_("Room List"), PIDGIN_HIG_BORDER, "room list", TRUE);
+#endif
 
 	g_signal_connect(G_OBJECT(window), "delete_event",
 					 G_CALLBACK(delete_win_cb), dialog);
--- a/pidgin/gtksavedstatuses.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtksavedstatuses.c	Tue Jul 24 03:43:55 2012 -0400
@@ -41,6 +41,8 @@
 #include "pidginstock.h"
 #include "gtkutils.h"
 
+#include "gtk3compat.h"
+
 /*
  * TODO: Should attach to the account-deleted and account-added signals
  *       and update the GtkListStores in any StatusEditor windows that
@@ -524,11 +526,7 @@
 static gboolean
 configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog)
 {
-#if GTK_CHECK_VERSION(2,18,0)
 	if (gtk_widget_get_visible(widget))
-#else
-	if (GTK_WIDGET_VISIBLE(widget))
-#endif
 	{
 		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	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkscrollbook.c	Tue Jul 24 03:43:55 2012 -0400
@@ -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) {
@@ -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/gtksession.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtksession.c	Tue Jul 24 03:43:55 2012 -0400
@@ -39,6 +39,8 @@
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 
+#include "gtk3compat.h"
+
 #define ERROR_LENGTH 512
 
 static IceIOErrorHandler ice_installed_io_error_handler;
@@ -349,7 +351,7 @@
 	free(tmp);
 
 	session_managed = TRUE;
-	gdk_set_sm_client_id(client_id);
+	gdk_x11_set_sm_client_id(client_id);
 
 	tmp = g_get_current_dir();
 	session_set_string(session, SmCurrentDirectory, tmp);
--- a/pidgin/gtksmiley.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtksmiley.c	Tue Jul 24 03:43:55 2012 -0400
@@ -37,6 +37,8 @@
 #include "gtkutils.h"
 #include "pidginstock.h"
 
+#include "gtk3compat.h"
+
 #define PIDGIN_RESPONSE_MODIFY 1000
 
 struct _PidginSmiley
@@ -399,7 +401,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);
@@ -407,14 +409,17 @@
 	if (smiley)
 		g_object_set_data(G_OBJECT(smiley), "edit-dialog", window);
 
+#if !GTK_CHECK_VERSION(3,0,0)
 	gtk_container_set_border_width(GTK_CONTAINER(window), PIDGIN_HIG_BORDER);
+#endif
 
 	gtk_dialog_set_default_response(GTK_DIALOG(window), GTK_RESPONSE_ACCEPT);
 	g_signal_connect(window, "response", G_CALLBACK(do_add_select_cb), s);
 
 	/* 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 */
@@ -724,9 +729,10 @@
 		GtkSelectionData *sd, guint info, guint t, gpointer user_data)
 {
 	SmileyManager *dialog = user_data;
-	gchar *name = g_strchomp((gchar *)sd->data);
+	gchar *name = g_strchomp((gchar *) gtk_selection_data_get_data(sd));
 
-	if ((sd->length >= 0) && (sd->format == 8)) {
+	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 */
 
@@ -872,7 +878,9 @@
 
 	gtk_window_set_default_size(GTK_WINDOW(win), 50, 400);
 	gtk_window_set_role(GTK_WINDOW(win), "custom_smiley_manager");
+#if !GTK_CHECK_VERSION(3,0,0)
 	gtk_container_set_border_width(GTK_CONTAINER(win),PIDGIN_HIG_BORDER);
+#endif
 	gtk_dialog_set_response_sensitive(GTK_DIALOG(win), GTK_RESPONSE_NO, FALSE);
 	gtk_dialog_set_response_sensitive(GTK_DIALOG(win),
 	                                  PIDGIN_RESPONSE_MODIFY, FALSE);
@@ -881,9 +889,7 @@
 			dialog);
 
 	/* The vbox */
-	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(win)->vbox), vbox);
-	gtk_widget_show(vbox);
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
 
 	/* get the scrolled window with all stuff */
 	sw = smiley_list_create(dialog);
@@ -892,3 +898,4 @@
 
 	gtk_widget_show(win);
 }
+
--- a/pidgin/gtksourceundomanager.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtksourceundomanager.c	Tue Jul 24 03:43:55 2012 -0400
@@ -532,7 +532,9 @@
 					um->priv->document,
 					undo_action->action.insert_anchor.pos,
 					undo_action->action.insert_anchor.pos + 1);
+#if !GTK_CHECK_VERSION(3,0,0)
 				undo_action->action.insert_anchor.anchor->segment = NULL; /* XXX: This may be a bug in GTK+ */
+#endif
 				break;
 			default:
 				/* Unknown action type. */
--- a/pidgin/gtkstatusbox.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkstatusbox.c	Tue Jul 24 03:43:55 2012 -0400
@@ -67,19 +67,11 @@
 #  endif
 #endif
 
+#include "gtk3compat.h"
+
 /* Timeout for typing notifications in seconds */
 #define TYPING_TIMEOUT 4
 
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_is_sensitive(x) GTK_WIDGET_IS_SENSITIVE(x)
-#define gtk_widget_set_has_window(x, y) do { \
-	if (y) \
-		GTK_WIDGET_UNSET_FLAGS(x, GTK_WIDGET_NO_WINDOW); \
-	else \
-		GTK_WIDGET_SET_FLAGS(x, GTK_WIDGET_NO_WINDOW); \
-} while (0)
-#endif
-
 static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data);
 static void imhtml_format_changed_cb(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons, void *data);
 static void remove_typing_cb(PidginStatusBox *box);
@@ -92,9 +84,15 @@
 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);
+#if GTK_CHECK_VERSION(3,0,0)
+static void pidgin_status_box_get_preferred_height (GtkWidget *widget,
+	gint *minimum_height, gint *natural_height);
+static gboolean pidgin_status_box_draw (GtkWidget *widget, cairo_t *cr);
+#else
 static void pidgin_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition);
+static gboolean pidgin_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event);
+#endif
 static void pidgin_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean pidgin_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event);
 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);
@@ -292,7 +290,7 @@
 
 		if (!message || !*message)
 		{
-			gtk_widget_hide_all(status_box->vbox);
+			gtk_widget_hide(status_box->vbox);
 			status_box->imhtml_visible = FALSE;
 		}
 		else
@@ -353,9 +351,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)) {
@@ -380,7 +379,7 @@
 
 static void
 statusbox_got_url(PurpleUtilFetchUrlData *url_data, gpointer user_data,
-                const gchar *themedata, size_t len, const gchar *error_message)
+                  const gchar *themedata, size_t len, const gchar *error_message)
 {
 	FILE *f;
 	gchar *path;
@@ -429,7 +428,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;
 }
@@ -437,7 +436,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;
 }
@@ -543,7 +542,7 @@
 
 static void
 pidgin_status_box_set_property(GObject *object, guint param_id,
-                                 const GValue *value, GParamSpec *pspec)
+                               const GValue *value, GParamSpec *pspec)
 {
 	PidginStatusBox *statusbox = PIDGIN_STATUS_BOX(object);
 
@@ -612,7 +611,7 @@
 static GType
 pidgin_status_box_child_type (GtkContainer *container)
 {
-    return GTK_TYPE_WIDGET;
+	return GTK_TYPE_WIDGET;
 }
 
 static void
@@ -625,9 +624,14 @@
 	parent_class = g_type_class_peek_parent(klass);
 
 	widget_class = (GtkWidgetClass*)klass;
+#if GTK_CHECK_VERSION(3,0,0)
+	widget_class->get_preferred_height = pidgin_status_box_get_preferred_height;
+	widget_class->draw = pidgin_status_box_draw;
+#else
 	widget_class->size_request = pidgin_status_box_size_request;
+	widget_class->expose_event = pidgin_status_box_expose_event;
+#endif
 	widget_class->size_allocate = pidgin_status_box_size_allocate;
-	widget_class->expose_event = pidgin_status_box_expose_event;
 
 	container_class->child_type = pidgin_status_box_child_type;
 	container_class->forall = pidgin_status_box_forall;
@@ -941,7 +945,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
 		{
@@ -1130,7 +1134,7 @@
 
 static gboolean combo_box_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkIMHtml *imhtml)
 {
-  	pidgin_status_box_popup(PIDGIN_STATUS_BOX(w));
+	pidgin_status_box_popup(PIDGIN_STATUS_BOX(w));
 	return TRUE;
 }
 
@@ -1145,7 +1149,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);
@@ -1158,7 +1162,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;
@@ -1304,88 +1308,88 @@
 static void
 pidgin_status_box_list_position (PidginStatusBox *status_box, int *x, int *y, int *width, int *height)
 {
-  GdkScreen *screen;
-  gint monitor_num;
-  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;
-
-  hpolicy = vpolicy = GTK_POLICY_NEVER;
+	GdkScreen *screen;
+	gint monitor_num;
+	GdkRectangle monitor;
+	GtkRequisition popup_req;
+	GtkPolicyType hpolicy, vpolicy;
+	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;
 	g_object_set(G_OBJECT(status_box->scrolled_window),
-		"hscrollbar-policy", hpolicy,
-		"vscrollbar-policy", vpolicy,
-		NULL);
-  gtk_widget_size_request (status_box->popup_frame, &popup_req);
-
-  if (popup_req.width > *width)
-    {
-      hpolicy = GTK_POLICY_ALWAYS;
-			g_object_set(G_OBJECT(status_box->scrolled_window),
-				"hscrollbar-policy", hpolicy,
-				"vscrollbar-policy", vpolicy,
-				NULL);
-      gtk_widget_size_request (status_box->popup_frame, &popup_req);
-    }
-
-  *height = popup_req.height;
-
-  screen = gtk_widget_get_screen (GTK_WIDGET (status_box));
-  monitor_num = gdk_screen_get_monitor_at_window (screen,
-						  GTK_WIDGET (status_box)->window);
-  gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
-
-  if (*x < monitor.x)
-    *x = monitor.x;
-  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;
-  else if (*y - *height >= monitor.y)
-	  *y -= *height;
-  else if (monitor.y + monitor.height - (*y + GTK_WIDGET(status_box)->allocation.height) > *y - monitor.y)
-    {
-	    *y += GTK_WIDGET(status_box)->allocation.height;
-	    *height = monitor.y + monitor.height - *y;
-    }
-  else
-    {
-	    *height = *y - monitor.y;
-	    *y = monitor.y;
-    }
-
-  if (popup_req.height > *height)
-    {
-      vpolicy = GTK_POLICY_ALWAYS;
-
-			g_object_set(G_OBJECT(status_box->scrolled_window),
-				"hscrollbar-policy", hpolicy,
-				"vscrollbar-policy", vpolicy,
-				NULL);
-    }
+	             "hscrollbar-policy", hpolicy,
+	             "vscrollbar-policy", vpolicy,
+	             NULL);
+	gtk_widget_size_request(status_box->popup_frame, &popup_req);
+
+	if (popup_req.width > *width) {
+		hpolicy = GTK_POLICY_ALWAYS;
+		g_object_set(G_OBJECT(status_box->scrolled_window),
+		             "hscrollbar-policy", hpolicy,
+		             "vscrollbar-policy", vpolicy,
+		             NULL);
+		gtk_widget_size_request(status_box->popup_frame, &popup_req);
+	}
+
+	*height = popup_req.height;
+
+	screen = gtk_widget_get_screen(GTK_WIDGET(status_box));
+	monitor_num = gdk_screen_get_monitor_at_window(screen,
+							gtk_widget_get_window(GTK_WIDGET(status_box)));
+	gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor);
+
+	if (*x < monitor.x)
+		*x = monitor.x;
+	else if (*x + *width > monitor.x + monitor.width)
+		*x = monitor.x + monitor.width - *width;
+
+	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 + allocation.height) > *y - monitor.y)
+	{
+		*y += allocation.height;
+		*height = monitor.y + monitor.height - *y;
+	}
+	else
+	{
+		*height = *y - monitor.y;
+		*y = monitor.y;
+	}
+
+	if (popup_req.height > *height)
+	{
+		vpolicy = GTK_POLICY_ALWAYS;
+
+		g_object_set(G_OBJECT(status_box->scrolled_window),
+		             "hscrollbar-policy", hpolicy,
+		             "vscrollbar-policy", vpolicy,
+		             NULL);
+	}
 }
 
 static gboolean
 popup_grab_on_window (GdkWindow *window,
-		      guint32    activate_time,
-		      gboolean   grab_keyboard)
+		      guint32    activate_time)
 {
 	if ((gdk_pointer_grab (window, TRUE,
 			 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
 			 GDK_POINTER_MOTION_MASK,
 			 NULL, NULL, activate_time) == 0))
 	{
-		if (!grab_keyboard || gdk_keyboard_grab (window, TRUE, activate_time) == 0)
+		if (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;
 		}
 	}
@@ -1404,8 +1408,8 @@
 	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,
-				   GDK_CURRENT_TIME, TRUE)) {
+	if (!popup_grab_on_window (gtk_widget_get_window(box->popup_window),
+				   GDK_CURRENT_TIME)) {
 		gtk_widget_hide (box->popup_window);
 		return;
 	}
@@ -1429,16 +1433,18 @@
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (box->toggle_button),
 				      FALSE);
 	gtk_grab_remove (box->popup_window);
+	gdk_pointer_ungrab(GDK_CURRENT_TIME);
+	gdk_keyboard_ungrab(GDK_CURRENT_TIME);
 }
 
 static gboolean
 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;
@@ -1670,7 +1676,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 {
@@ -1681,9 +1687,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;
@@ -1934,6 +1940,33 @@
 
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+static void
+pidgin_status_box_get_preferred_height(GtkWidget *widget, gint *minimum_height,
+                                       gint *natural_height)
+{
+	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 */
+	if (PIDGIN_STATUS_BOX(widget)->imhtml_visible) {
+		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;
+	}
+}
+#else
 static void
 pidgin_status_box_size_request(GtkWidget *widget,
 								 GtkRequisition *requisition)
@@ -1948,12 +1981,15 @@
 	requisition->height += 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;
+	if (PIDGIN_STATUS_BOX(widget)->imhtml_visible) {
+		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;
 }
+#endif
 
 /* From gnome-panel */
 static void
@@ -2002,7 +2038,7 @@
 	PidginStatusBox *status_box = PIDGIN_STATUS_BOX(widget);
 	GtkRequisition req = {0,0};
 	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 */
@@ -2041,9 +2077,27 @@
 		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);
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean
+pidgin_status_box_draw(GtkWidget *widget, cairo_t *cr)
+{
+	PidginStatusBox *status_box = PIDGIN_STATUS_BOX(widget);
+	gtk_widget_draw(status_box->toggle_button, cr);
+
+	if (status_box->icon_box && status_box->icon_opaque) {
+		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;
+}
+#else
 static gboolean
 pidgin_status_box_expose_event(GtkWidget *widget,
 				 GdkEventExpose *event)
@@ -2058,6 +2112,7 @@
 	}
 	return FALSE;
 }
+#endif
 
 static void
 pidgin_status_box_forall(GtkContainer *container,
@@ -2363,7 +2418,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)
 		{
@@ -2635,7 +2690,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)
 		{
@@ -2697,7 +2752,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)
 		{
@@ -2717,7 +2772,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 */
 		}
 	}
@@ -2753,7 +2808,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	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkutils.c	Tue Jul 24 03:43:55 2012 -0400
@@ -71,10 +71,7 @@
 #include "gtkwebviewtoolbar.h"
 #include "pidgin/minidialog.h"
 
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
-#define gtk_widget_is_sensitive(x) GTK_WIDGET_IS_SENSITIVE(x)
-#endif
+#include "gtk3compat.h"
 
 enum {
 	AOP_ICON_COLUMN,
@@ -220,7 +217,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);
 }
@@ -228,7 +224,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);
@@ -236,12 +232,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,
@@ -391,7 +387,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);
 }
@@ -408,7 +404,7 @@
 		if (element == NULL)
 			continue;
 
-		sensitivity = gtk_widget_is_sensitive(element);
+		sensitivity = gtk_widget_get_sensitive(element);
 
 		gtk_widget_set_sensitive(element, !sensitivity);
 	}
@@ -1294,8 +1290,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);
 
 	/*
@@ -1433,9 +1429,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);
 
@@ -1552,7 +1548,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,8 +1871,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,
-					purple_menu_action_get_label(act));
+			char *path = g_strdup_printf("%s/%s",
+				gtk_menu_item_get_accel_path(GTK_MENU_ITEM(menuitem)),
+				purple_menu_action_get_label(act));
 			gtk_menu_set_accel_path(GTK_MENU(submenu), path);
 			g_free(path);
 			gtk_menu_set_accel_group(GTK_MENU(submenu), group);
@@ -2204,23 +2201,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 {
@@ -2261,7 +2258,7 @@
 	gtk_widget_destroy(dialog->icon_filesel);
 	g_free(filename);
 	g_free(dialog);
- }
+}
 
 
 static void
@@ -2880,7 +2877,7 @@
 	if (!widget)
 		return "dim grey";
 
- 	style = gtk_widget_get_style(widget);
+	style = gtk_widget_get_style(widget);
 	if (!style)
 		return "dim grey";
 
@@ -2892,18 +2889,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;
@@ -2912,12 +2909,17 @@
 GtkWidget *
 pidgin_text_combo_box_entry_new(const char *default_item, GList *items)
 {
-	GtkComboBox *ret = NULL;
+	GtkComboBoxText *ret = NULL;
 	GtkWidget *the_entry = NULL;
 
+#if GTK_CHECK_VERSION(2,24,0)
+	ret = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new_with_entry());
+	the_entry = gtk_bin_get_child(GTK_BIN(ret));
+#else
 	ret = GTK_COMBO_BOX(gtk_combo_box_entry_new_text());
 	the_entry = gtk_entry_new();
 	gtk_container_add(GTK_CONTAINER(ret), the_entry);
+#endif
 
 	if (default_item)
 		gtk_entry_set_text(GTK_ENTRY(the_entry), default_item);
@@ -2925,7 +2927,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);
@@ -2936,12 +2938,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 *
@@ -3067,7 +3069,7 @@
 		}
 
 		if (gtk_window_has_toplevel_focus(GTK_WINDOW(window)) ||
-				(menu && menu == window->window)) {
+				(menu && menu == gtk_widget_get_window(window))) {
 			parent = window;
 			break;
 		}
@@ -3628,7 +3630,11 @@
 		if (width != -1 || height != -1)
 			gtk_widget_set_size_request(sw, width, height);
 		if (child) {
+#if GTK_CHECK_VERSION(3,0,0)
+			if (GTK_IS_SCROLLABLE(child))
+#else
 			if (GTK_WIDGET_GET_CLASS(child)->set_scroll_adjustments_signal)
+#endif
 				gtk_container_add(GTK_CONTAINER(sw), child);
 			else
 				gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), child);
--- a/pidgin/gtkwebview.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkwebview.c	Tue Jul 24 03:43:55 2012 -0400
@@ -31,6 +31,8 @@
 #include <gdk/gdkkeysyms.h>
 #include "gtkwebview.h"
 
+#include "gtk3compat.h"
+
 #define MAX_FONT_SIZE 7
 #define MAX_SCROLL_TIME 0.4 /* seconds */
 #define SCROLL_DELAY 33 /* milliseconds */
@@ -228,11 +230,7 @@
 	g_return_val_if_fail(priv->scroll_time != NULL, FALSE);
 
 	adj = priv->vadj;
-#if GTK_CHECK_VERSION(2,14,0)
 	max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
-#else
-	max_val = adj->upper - adj->page_size;
-#endif
 	scroll_val = gtk_adjustment_get_value(adj) +
 	             ((max_val - gtk_adjustment_get_value(adj)) / 3);
 
@@ -260,11 +258,7 @@
 	gdouble max_val;
 
 	if (adj) {
-#if GTK_CHECK_VERSION(2,14,0)
 		max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
-#else
-		max_val = adj->upper - adj->page_size;
-#endif
 		gtk_adjustment_set_value(adj, max_val);
 	}
 
@@ -675,13 +669,8 @@
 
 	priv = GTK_WEBVIEW_GET_PRIVATE(webview);
 	vadj = priv->vadj;
-#if GTK_CHECK_VERSION(2,14,0)
 	scroll_val = gtk_adjustment_get_value(vadj) - gtk_adjustment_get_page_size(vadj);
 	scroll_val = MAX(scroll_val, gtk_adjustment_get_lower(vadj));
-#else
-	scroll_val = gtk_adjustment_get_value(vadj) - vadj->page_size;
-	scroll_val = MAX(scroll_val, vadj->lower);
-#endif
 
 	gtk_adjustment_set_value(vadj, scroll_val);
 }
@@ -698,15 +687,9 @@
 
 	priv = GTK_WEBVIEW_GET_PRIVATE(webview);
 	vadj = priv->vadj;
-#if GTK_CHECK_VERSION(2,14,0)
 	page_size = gtk_adjustment_get_page_size(vadj);
 	scroll_val = gtk_adjustment_get_value(vadj) + page_size;
 	scroll_val = MIN(scroll_val, gtk_adjustment_get_upper(vadj) - page_size);
-#else
-	page_size = vadj->page_size;
-	scroll_val = gtk_adjustment_get_value(vadj) + page_size;
-	scroll_val = MIN(scroll_val, vadj->upper - page_size);
-#endif
 
 	gtk_adjustment_set_value(vadj, scroll_val);
 }
--- a/pidgin/gtkwebviewtoolbar.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkwebviewtoolbar.c	Tue Jul 24 03:43:55 2012 -0400
@@ -184,11 +184,15 @@
 	GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
 	GtkFontSelection *sel;
 
-	sel = GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(priv->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(priv->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
@@ -248,10 +252,12 @@
 
 			g_signal_connect(G_OBJECT(priv->font_dialog), "delete_event",
 							 G_CALLBACK(destroy_toolbar_font), toolbar);
-			g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(priv->font_dialog)->ok_button), "clicked",
-							 G_CALLBACK(apply_font), toolbar);
-			g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(priv->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(priv->font_dialog))),
+				"clicked", G_CALLBACK(apply_font), toolbar);
+			g_signal_connect(G_OBJECT(
+				gtk_font_selection_dialog_get_cancel_button(GTK_FONT_SELECTION_DIALOG(priv->font_dialog))),
+				"clicked", G_CALLBACK(cancel_toolbar_font), toolbar);
 			g_signal_connect_after(G_OBJECT(priv->font_dialog), "realize",
 							 G_CALLBACK(realize_toolbar_font), toolbar);
 		}
@@ -300,7 +306,7 @@
 	char *open_tag;
 
 	dialog = GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog);
-	colorsel = GTK_COLOR_SELECTION(dialog->colorsel);
+	colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(dialog));
 
 	open_tag = g_malloc(30);
 	gtk_color_selection_get_current_color(colorsel, &text_color);
@@ -325,18 +331,24 @@
 		char *color = gtk_webview_get_current_forecolor(GTK_WEBVIEW(toolbar->webview));
 
 		if (!priv->fgcolor_dialog) {
+			GtkWidget *ok_button;
+			GtkWidget *cancel_button;
+
 			priv->fgcolor_dialog = gtk_color_selection_dialog_new(_("Select Text Color"));
-			colorsel = GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog)->colorsel;
+			colorsel =
+				gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog));
 			if (color) {
 				gdk_color_parse(color, &fgcolor);
 				gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &fgcolor);
 			}
 
+			g_object_get(G_OBJECT(priv->fgcolor_dialog), "ok-button", &ok_button, NULL);
+			g_object_get(G_OBJECT(priv->fgcolor_dialog), "cancel-button", &cancel_button, NULL);
 			g_signal_connect(G_OBJECT(priv->fgcolor_dialog), "delete_event",
 							 G_CALLBACK(destroy_toolbar_fgcolor), toolbar);
-			g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog)->ok_button), "clicked",
+			g_signal_connect(G_OBJECT(ok_button), "clicked",
 							 G_CALLBACK(do_fgcolor), toolbar);
-			g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(priv->fgcolor_dialog)->cancel_button), "clicked",
+			g_signal_connect(G_OBJECT(cancel_button), "clicked",
 							 G_CALLBACK(cancel_toolbar_fgcolor), toolbar);
 		}
 
@@ -384,7 +396,7 @@
 	char *open_tag;
 
 	dialog = GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog);
-	colorsel = GTK_COLOR_SELECTION(dialog->colorsel);
+	colorsel = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(dialog));
 
 	open_tag = g_malloc(30);
 	gtk_color_selection_get_current_color(colorsel, &text_color);
@@ -409,18 +421,26 @@
 		char *color = gtk_webview_get_current_backcolor(GTK_WEBVIEW(toolbar->webview));
 
 		if (!priv->bgcolor_dialog) {
+			GtkWidget *ok_button;
+			GtkWidget *cancel_button;
+
 			priv->bgcolor_dialog = gtk_color_selection_dialog_new(_("Select Background Color"));
-			colorsel = GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog)->colorsel;
+			colorsel =
+				gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog));
+
 			if (color) {
 				gdk_color_parse(color, &bgcolor);
 				gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &bgcolor);
 			}
 
+			g_object_get(G_OBJECT(priv->bgcolor_dialog), "ok-button", &ok_button, NULL);
+			g_object_get(G_OBJECT(priv->bgcolor_dialog), "cancel-button",
+			             &cancel_button, NULL);
 			g_signal_connect(G_OBJECT(priv->bgcolor_dialog), "delete_event",
 							 G_CALLBACK(destroy_toolbar_bgcolor), toolbar);
-			g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog)->ok_button), "clicked",
+			g_signal_connect(G_OBJECT(ok_button), "clicked",
 							 G_CALLBACK(do_bgcolor), toolbar);
-			g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(priv->bgcolor_dialog)->cancel_button), "clicked",
+			g_signal_connect(G_OBJECT(cancel_button), "clicked",
 							 G_CALLBACK(cancel_toolbar_bgcolor), toolbar);
 		}
 
@@ -775,7 +795,7 @@
 smiley_dialog_input_cb(GtkWidget *dialog, GdkEvent *event,
                        GtkWebViewToolbar *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);
@@ -1145,19 +1165,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 void
@@ -1223,10 +1245,10 @@
 {
 	GtkWebViewToolbarPriv *priv = GTK_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar);
 	if (value) {
-		gtk_widget_hide_all(priv->lean_view);
+		gtk_widget_hide(priv->lean_view);
 		gtk_widget_show_all(priv->wide_view);
 	} else {
-		gtk_widget_hide_all(priv->wide_view);
+		gtk_widget_hide(priv->wide_view);
 		gtk_widget_show_all(priv->lean_view);
 	}
 }
--- a/pidgin/gtkwhiteboard.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/gtkwhiteboard.c	Tue Jul 24 03:43:55 2012 -0400
@@ -28,8 +28,13 @@
 #include "gtkwhiteboard.h"
 #include "gtkutils.h"
 
+#if GTK_CHECK_VERSION(3,0,0)
+#define GdkPixType GdkPixbuf
+#else
+#define GdkPixType GdkPixmap
+#endif
 struct _PidginWhiteboardPrivate {
-	GdkPixmap *pixmap;
+	GdkPixType *pix;
 	cairo_t   *cr;
 };
 
@@ -286,11 +291,11 @@
 	/* TODO Ask if user wants to save picture before the session is closed */
 
 	/* Clear graphical memory */
-	if (gtkwb->priv->pixmap) {
+	if (gtkwb->priv->pix) {
 		cairo_t *cr = gtkwb->priv->cr;
 		if (cr)
 			cairo_destroy(cr);
-		g_object_unref(gtkwb->priv->pixmap);
+		g_object_unref(gtkwb->priv->pix);
 	}
 
 	colour_dialog = g_object_get_data(G_OBJECT(gtkwb->window), "colour-dialog");
@@ -362,28 +367,43 @@
 static gboolean pidgin_whiteboard_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixmap *pixmap = gtkwb->priv->pixmap;
+	GdkPixType *pix = gtkwb->priv->pix;
 	cairo_t *cr;
+	GdkWindow *window = gtk_widget_get_window(widget);
+	GtkAllocation allocation;
 
-	if (pixmap) {
+	if (pix) {
 		cr = gtkwb->priv->cr;
 		if (cr)
 			cairo_destroy(cr);
-		g_object_unref(pixmap);
+		g_object_unref(pix);
 	}
 
-	pixmap = gdk_pixmap_new(widget->window,
-							widget->allocation.width,
-							widget->allocation.height,
-							-1);
-	gtkwb->priv->pixmap = pixmap;
+	gtk_widget_get_allocation(widget, &allocation);
 
-	cr = gdk_cairo_create(GDK_DRAWABLE(pixmap));
+#if GTK_CHECK_VERSION(3,0,0)
+	pix = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+	                     FALSE, gdk_visual_get_depth(GDK_VISUAL(window)),
+	                     allocation.width, allocation.height);
+#else
+	pix = gdk_pixmap_new(window,
+	                     allocation.width,
+	                     allocation.height,
+	                     -1);
+#endif
+
+	gtkwb->priv->pix = pix;
+
+#if GTK_CHECK_VERSION(3,0,0)
+	cr = gdk_cairo_create(window);
+#else
+	cr = gdk_cairo_create(GDK_DRAWABLE(pix));
+#endif
 	gtkwb->priv->cr = cr;
-	gdk_cairo_set_source_color(cr, &widget->style->white);
+	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;
@@ -392,11 +412,16 @@
 static gboolean pidgin_whiteboard_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)(data);
-	GdkPixmap *pixmap = gtkwb->priv->pixmap;
+	GdkPixType *pix = gtkwb->priv->pix;
 	cairo_t *cr;
 
+#if GTK_CHECK_VERSION(3,0,0)
+	cr = gdk_cairo_create(gtk_widget_get_window(widget));
+	gdk_cairo_set_source_pixbuf(cr, pix, 0, 0);
+#else
 	cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
-	gdk_cairo_set_source_pixmap(cr, pixmap, 0, 0);
+	gdk_cairo_set_source_pixmap(cr, pix, 0, 0);
+#endif
 	cairo_rectangle(cr,
 	                event->area.x, event->area.y,
 	                event->area.width, event->area.height);
@@ -409,7 +434,6 @@
 static gboolean pidgin_whiteboard_brush_down(GtkWidget *widget, GdkEventButton *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixmap *pixmap = gtkwb->priv->pixmap;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = purple_whiteboard_get_draw_list(wb);
@@ -424,7 +448,7 @@
 
 	BrushState = BRUSH_STATE_DOWN;
 
-	if(event->button == 1 && pixmap != NULL)
+	if(event->button == 1 && gtkwb->priv->pix != NULL)
 	{
 		/* Check if draw_list has contents; if so, clear it */
 		if(draw_list)
@@ -462,7 +486,6 @@
 	GdkModifierType state;
 
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixmap *pixmap = gtkwb->priv->pixmap;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = purple_whiteboard_get_draw_list(wb);
@@ -476,7 +499,7 @@
 		state = event->state;
 	}
 
-	if(state & GDK_BUTTON1_MASK && pixmap != NULL)
+	if(state & GDK_BUTTON1_MASK && gtkwb->priv->pix != NULL)
 	{
 		if((BrushState != BRUSH_STATE_DOWN) && (BrushState != BRUSH_STATE_MOTION))
 		{
@@ -542,7 +565,6 @@
 static gboolean pidgin_whiteboard_brush_up(GtkWidget *widget, GdkEventButton *event, gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-	GdkPixmap *pixmap = gtkwb->priv->pixmap;
 
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = purple_whiteboard_get_draw_list(wb);
@@ -557,7 +579,7 @@
 	}
 	BrushState = BRUSH_STATE_UP;
 
-	if(event->button == 1 && pixmap != NULL)
+	if(event->button == 1 && gtkwb->priv->pix != NULL)
 	{
 		/* If the brush was never moved, express two sets of two deltas That's a
 		 * 'point,' but not for Yahoo!
@@ -707,18 +729,21 @@
 	PidginWhiteboard *gtkwb = purple_whiteboard_get_ui_data(wb);
 	GtkWidget *drawing_area = gtkwb->drawing_area;
 	cairo_t *cr = gtkwb->priv->cr;
+	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);
+	                           0, 0,
+	                           allocation.width,
+	                           allocation.height);
 }
 
 static void pidgin_whiteboard_button_clear_press(GtkWidget *widget, gpointer data)
@@ -784,12 +809,16 @@
 		gtk_widget_destroy(dialog);
 
 		/* Makes an icon from the whiteboard's canvas 'image' */
+#if GTK_CHECK_VERSION(3,0,0)
+		pixbuf = gtkwb->priv->pix;
+#else
 		pixbuf = gdk_pixbuf_get_from_drawable(NULL,
-		                                      (GdkDrawable*)(gtkwb->priv->pixmap),
-		                                      gdk_drawable_get_colormap(gtkwb->priv->pixmap),
+		                                      (GdkDrawable*)(gtkwb->priv->pix),
+		                                      gdk_drawable_get_colormap(gtkwb->priv->pix),
 		                                      0, 0,
 		                                      0, 0,
 		                                      gtkwb->width, gtkwb->height);
+#endif
 
 		if(gdk_pixbuf_save(pixbuf, filename, "jpeg", NULL, "quality", "100", NULL))
 			purple_debug_info("gtkwhiteboard", "File Saved...\n");
@@ -810,12 +839,16 @@
 	GdkPixbuf *pixbuf;
 
 	/* Makes an icon from the whiteboard's canvas 'image' */
+#if GTK_CHECK_VERSION(3,0,0)
+	pixbuf = gtkwb->priv->pix;
+#else
 	pixbuf = gdk_pixbuf_get_from_drawable(NULL,
-	                                      (GdkDrawable*)(gtkwb->priv->pixmap),
-	                                      gdk_drawable_get_colormap(gtkwb->priv->pixmap),
+	                                      (GdkDrawable*)(gtkwb->priv->pix),
+	                                      gdk_drawable_get_colormap(gtkwb->priv->pix),
 	                                      0, 0,
 	                                      0, 0,
 	                                      gtkwb->width, gtkwb->height);
+#endif
 
 	gtk_window_set_icon((GtkWindow*)(gtkwb->window), pixbuf);
 }
@@ -856,23 +889,24 @@
 {
 	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_CALLBACK(change_color_cb), gtkwb);
+	g_signal_connect(G_OBJECT(gtk_color_selection_dialog_get_color_selection(dialog)),
+	                 "color-changed", G_CALLBACK(change_color_cb), gtkwb);
+
+	g_object_get(G_OBJECT(dialog), "ok-button", &ok_button, NULL);
 
-	gtk_widget_destroy(dialog->cancel_button);
-	gtk_widget_destroy(dialog->help_button);
+	g_signal_connect(G_OBJECT(ok_button), "clicked",
+	                 G_CALLBACK(color_selection_dialog_destroy), gtkwb);
 
-	g_signal_connect(G_OBJECT(dialog->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/minidialog.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/minidialog.c	Tue Jul 24 03:43:55 2012 -0400
@@ -184,7 +184,12 @@
 guint
 pidgin_mini_dialog_get_num_children(PidginMiniDialog *mini_dialog)
 {
-	return g_list_length(mini_dialog->contents->children);
+	GList *tmp;
+	guint len;
+	tmp = gtk_container_get_children(GTK_CONTAINER(mini_dialog->contents));
+	len = g_list_length(tmp);
+	g_list_free(tmp);
+	return len;
 }
 
 static gboolean
--- a/pidgin/pidginstock.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/pidginstock.c	Tue Jul 24 03:43:55 2012 -0400
@@ -95,7 +95,7 @@
 
 typedef struct {
 	const char *name;
- 	const char *dir;
+	const char *dir;
 	const char *filename;
 	gboolean microscopic;
 	gboolean extra_small;
--- a/pidgin/pidgintooltip.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/pidgintooltip.c	Tue Jul 24 03:43:55 2012 -0400
@@ -100,16 +100,37 @@
 	}
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean
+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(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, cr, data);
+	}
+	return FALSE;
+}
+#else
 static gboolean
 pidgin_tooltip_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
 {
 	if (pidgin_tooltip.paint_tooltip) {
+		cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(gtk_widget_get_window(widget)));
 		gtk_paint_flat_box(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-				NULL, widget, "tooltip", 0, 0, -1, -1);
-		pidgin_tooltip.paint_tooltip(widget, data);
+		                   NULL, widget, "tooltip", 0, 0, -1, -1);
+		pidgin_tooltip.paint_tooltip(widget, cr, data);
+		cairo_destroy(cr);
 	}
 	return FALSE;
 }
+#endif
 
 static GtkWidget*
 setup_tooltip_window(void)
@@ -189,8 +210,13 @@
 	gtk_window_move(GTK_WINDOW(tipwindow), x, y);
 	gtk_widget_show(tipwindow);
 
+#if GTK_CHECK_VERSION(3,0,0)
+	g_signal_connect(G_OBJECT(tipwindow), "draw",
+			G_CALLBACK(pidgin_tooltip_draw_cb), data);
+#else
 	g_signal_connect(G_OBJECT(tipwindow), "expose_event",
 			G_CALLBACK(pidgin_tooltip_expose_event), data);
+#endif
 
 	/* 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/pidgintooltip.h	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/pidgintooltip.h	Tue Jul 24 03:43:55 2012 -0400
@@ -53,11 +53,13 @@
 
 /**
  * @param  tipwindow   The window for the tooltip.
+ * @param  cr          The cairo context for drawing.
  * @param  userdata    The userdata set during pidgin_tooltip_setup_for_treeview or pidgin_tooltip_show.
  *
  * @return  @c TRUE if the tooltip was painted correctly, @c FALSE otherwise.
  */
-typedef gboolean (*PidginTooltipPaint)(GtkWidget *tipwindow, gpointer userdata);
+typedef gboolean (*PidginTooltipPaint)(GtkWidget *tipwindow, cairo_t *cr,
+			gpointer userdata);
 
 G_BEGIN_DECLS
 
--- a/pidgin/plugins/contact_priority.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/contact_priority.c	Tue Jul 24 03:43:55 2012 -0400
@@ -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;
@@ -105,8 +105,9 @@
 		gtk_size_group_add_widget(sg, label);
 		gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
 
-		adj = gtk_adjustment_new(purple_prefs_get_int(pref), -500, 500, 1, 1, 1);
-		spin = gtk_spin_button_new((GtkAdjustment *)adj, 1, 0);
+		adj = GTK_ADJUSTMENT(gtk_adjustment_new(purple_prefs_get_int(pref),
+		                                        -500, 500, 1, 1, 1));
+		spin = gtk_spin_button_new(adj, 1, 0);
 		g_signal_connect(G_OBJECT(spin), "value-changed", G_CALLBACK(pref_update), pref);
 		gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 0);
 
@@ -138,8 +139,8 @@
 
 	/* make this here so I can use it in the option menu callback, we'll
 	 * actually set it up later */
-	adj = gtk_adjustment_new(0, -500, 500, 1, 1, 1);
-	spin = gtk_spin_button_new((GtkAdjustment *)adj, 1, 0);
+	adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, -500, 500, 1, 1, 1));
+	spin = gtk_spin_button_new(adj, 1, 0);
 
 	optmenu = pidgin_account_option_menu_new(NULL, TRUE,
 	                                         G_CALLBACK(select_account),
--- a/pidgin/plugins/convcolors.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/convcolors.c	Tue Jul 24 03:43:55 2012 -0400
@@ -302,7 +302,7 @@
 }
 
 static void
-disconnect_prefs_callbacks(GtkObject *object, gpointer data)
+disconnect_prefs_callbacks(GtkAdjustment *object, 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(G_OBJECT(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	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/disco/gtkdisco.c	Tue Jul 24 03:43:55 2012 -0400
@@ -427,18 +427,22 @@
 }
 
 static gboolean
-disco_paint_tooltip(GtkWidget *tipwindow, gpointer data)
+disco_paint_tooltip(GtkWidget *tipwindow, cairo_t *cr, gpointer data)
 {
 	PangoLayout *layout = g_object_get_data(G_OBJECT(tipwindow), "tooltip-plugin");
-#if GTK_CHECK_VERSION(2,14,0)
+#if GTK_CHECK_VERSION(3,0,0)
 	gtk_paint_layout(gtk_widget_get_style(tipwindow),
-			gtk_widget_get_window(tipwindow),
-			GTK_STATE_NORMAL, FALSE,
+	                 cr,
+	                 GTK_STATE_NORMAL, FALSE,
+	                 tipwindow, "tooltip",
+	                 6, 6, layout);
 #else
-	gtk_paint_layout(tipwindow->style, tipwindow->window, GTK_STATE_NORMAL, FALSE,
+	gtk_paint_layout(gtk_widget_get_style(tipwindow),
+	                 gtk_widget_get_window(tipwindow),
+	                 GTK_STATE_NORMAL, FALSE,
+	                 NULL, tipwindow, "tooltip",
+	                 6, 6, layout);
 #endif
-			NULL, tipwindow, "tooltip",
-			6, 6, layout);
 	return TRUE;
 }
 
--- a/pidgin/plugins/gestures/stroke-draw.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/gestures/stroke-draw.c	Tue Jul 24 03:43:55 2012 -0400
@@ -19,9 +19,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
-#if !GTK_CHECK_VERSION(2,14,0)
-#define gtk_widget_get_window(x) x->window
-#endif
+#include "gtk3compat.h"
 
 static void gstroke_invisible_window_init (GtkWidget *widget);
 /*FIXME: Maybe these should be put in a structure, and not static...*/
@@ -339,7 +337,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/themeedit.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/themeedit.c	Tue Jul 24 03:43:55 2012 -0400
@@ -306,9 +306,6 @@
 		}
 	}
 
-#if !GTK_CHECK_VERSION(2,22,0)
-	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), TRUE);
-#endif
 #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	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/ticker/gtkticker.c	Tue Jul 24 03:43:55 2012 -0400
@@ -24,38 +24,24 @@
 #include "gtkticker.h"
 #include <gtk/gtk.h>
 
-#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)
-
-#if !GTK_CHECK_VERSION(2,18,0)
-#define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
-
-#if !GTK_CHECK_VERSION(2,14,0)
-#define gtk_widget_get_window(x) x->window
-#endif
-#endif
-#endif
+#include "gtk3compat.h"
 
 static void gtk_ticker_compute_offsets (GtkTicker    *ticker);
 static void gtk_ticker_class_init    (GtkTickerClass    *klass);
 static void gtk_ticker_init          (GtkTicker         *ticker);
 static void gtk_ticker_map           (GtkWidget        *widget);
 static void gtk_ticker_realize       (GtkWidget        *widget);
+#if GTK_CHECK_VERSION(3,0,0)
+static void gtk_ticker_get_preferred_width (GtkWidget *widget,
+		gint      *minimal_width,
+		gint      *natural_width);
+static void gtk_ticker_get_preferred_height (GtkWidget *widget,
+		gint      *minimal_height,
+		gint      *natural_height);
+#else
 static void gtk_ticker_size_request  (GtkWidget        *widget,
 		GtkRequisition   *requisition);
+#endif
 static void gtk_ticker_size_allocate (GtkWidget        *widget,
 		GtkAllocation    *allocation);
 static void gtk_ticker_add_real      (GtkContainer     *container,
@@ -128,7 +114,12 @@
 
 	widget_class->map = gtk_ticker_map;
 	widget_class->realize = gtk_ticker_realize;
+#if GTK_CHECK_VERSION(3,0,0)
+	widget_class->get_preferred_width = gtk_ticker_get_preferred_width;
+	widget_class->get_preferred_height = gtk_ticker_get_preferred_height;
+#else
 	widget_class->size_request = gtk_ticker_size_request;
+#endif
 	widget_class->size_allocate = gtk_ticker_size_allocate;
 
 	container_class->add = gtk_ticker_add_real;
@@ -144,11 +135,7 @@
 
 static void gtk_ticker_init (GtkTicker *ticker)
 {
-#if GTK_CHECK_VERSION(2,18,0)
 	gtk_widget_set_has_window (GTK_WIDGET (ticker), TRUE);
-#else
-	GTK_WIDGET_UNSET_FLAGS (ticker, GTK_NO_WINDOW);
-#endif
 
 	ticker->interval = (guint) 200;
 	ticker->scootch = (guint) 2;
@@ -308,9 +295,7 @@
 	gint attributes_mask;
 	GdkWindow *window;
 	GtkStyle *style;
-#if GTK_CHECK_VERSION(2,18,0)
 	GtkAllocation allocation;
-#endif
 
 	g_return_if_fail (widget != NULL);
 	g_return_if_fail (GTK_IS_TICKER (widget));
@@ -318,45 +303,110 @@
 	gtk_widget_set_realized (widget, TRUE);
 
 	attributes.window_type = GDK_WINDOW_CHILD;
-#if GTK_CHECK_VERSION(2,18,0)
 	gtk_widget_get_allocation (widget, &allocation);
 	attributes.x = allocation.x;
 	attributes.y = allocation.y;
 	attributes.width = allocation.width;
 	attributes.height = allocation.height;
-#else
-	attributes.x = widget->allocation.x;
-	attributes.y = widget->allocation.y;
-	attributes.width = widget->allocation.width;
-	attributes.height = widget->allocation.height;
-#endif
 	attributes.wclass = GDK_INPUT_OUTPUT;
 	attributes.visual = gtk_widget_get_visual (widget);
+#if !GTK_CHECK_VERSION(3,0,0)
 	attributes.colormap = gtk_widget_get_colormap (widget);
+#endif
 	attributes.event_mask = gtk_widget_get_events (widget);
 	attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
 
+#if GTK_CHECK_VERSION(3,0,0)
+	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+#else
 	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+#endif
 
 	window = gdk_window_new (gtk_widget_get_parent_window (widget),
 			&attributes, attributes_mask);
-#if GTK_CHECK_VERSION(2,18,0)
 	gtk_widget_set_window (widget, window);
-#else
-	widget->window = window;
-#endif
 	gdk_window_set_user_data (window, widget);
 
-#if GTK_CHECK_VERSION(2,14,0)
-	style = gtk_widget_get_style (widget);
-	style = gtk_style_attach (style, window);
+	style = gtk_style_attach (gtk_widget_get_style (widget), window);
 	gtk_widget_set_style (widget, style);
-#else
-	style = widget->style = gtk_style_attach (widget->style, window);
-#endif
 	gtk_style_set_background (style, window, GTK_STATE_NORMAL);
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+static void
+gtk_ticker_get_preferred_width (GtkWidget *widget,
+                                gint      *minimal_width,
+                                gint      *natural_width)
+{
+	GtkTicker *ticker;
+	GtkTickerChild *child;
+	GList *children;
+	gint child_min_width, child_nat_width;
+	gint width;
+	guint border_width;
+
+	ticker = GTK_TICKER (widget);
+	*minimal_width = width = 0;
+
+	children = ticker->children;
+	while (children)
+	{
+		child = children->data;
+		children = children->next;
+
+		if (gtk_widget_get_visible (child->widget))
+		{
+			gtk_widget_get_preferred_width (child->widget, &child_min_width, &child_nat_width);
+
+			width += child_nat_width + ticker->spacing;
+			*minimal_width = MAX(*minimal_width, child_min_width);
+		}
+	}
+	if ( width > ticker->spacing )
+		width -= ticker->spacing;
+
+	border_width = gtk_container_get_border_width (GTK_CONTAINER (ticker));
+	width += border_width * 2;
+
+	*natural_width = width;
+}
+
+static void
+gtk_ticker_get_preferred_height (GtkWidget *widget,
+                                 gint      *minimal_height,
+                                 gint      *natural_height)
+{
+	GtkTicker *ticker;
+	GtkTickerChild *child;
+	GList *children;
+	gint child_min_height, child_nat_height;
+	gint height;
+	guint border_width;
+
+	ticker = GTK_TICKER (widget);
+	height = 0;
+
+	children = ticker->children;
+	while (children)
+	{
+		child = children->data;
+		children = children->next;
+
+		if (gtk_widget_get_visible (child->widget))
+		{
+			gtk_widget_get_preferred_height (child->widget, &child_min_height, &child_nat_height);
+
+			height = MAX (height, child_nat_height);
+		}
+	}
+
+	border_width = gtk_container_get_border_width (GTK_CONTAINER (ticker));
+	height += border_width * 2;
+	*minimal_height = *natural_height = height;
+}
+
+#else
+
 static void gtk_ticker_size_request (GtkWidget *widget, GtkRequisition *requisition)
 {
 	GtkTicker *ticker;
@@ -395,9 +445,11 @@
 	requisition->height += border_width * 2;
 	requisition->width += border_width * 2;
 }
+#endif
 
 static void gtk_ticker_compute_offsets (GtkTicker *ticker)
 {
+	GtkAllocation allocation;
 	GtkTickerChild *child;
 	GtkRequisition child_requisition;
 	GList *children;
@@ -408,15 +460,8 @@
 
 	border_width = gtk_container_get_border_width (GTK_CONTAINER (ticker));
 
-#if GTK_CHECK_VERSION(2,18,0)
-	{
-		GtkAllocation allocation;
-		gtk_widget_get_allocation (GTK_WIDGET (ticker), &allocation);
-		ticker->width = allocation.width;
-	}
-#else
-	ticker->width = GTK_WIDGET(ticker)->allocation.width;
-#endif
+	gtk_widget_get_allocation (GTK_WIDGET (ticker), &allocation);
+	ticker->width = allocation.width;
 	ticker->total = 0;
 	children = ticker->children;
 	while (children) {
@@ -438,6 +483,7 @@
 		GtkAllocation *allocation)
 {
 	GtkTicker *ticker;
+	GtkAllocation a;
 	GtkTickerChild *child;
 	GtkAllocation child_allocation;
 	GtkRequisition child_requisition;
@@ -450,27 +496,15 @@
 
 	ticker = GTK_TICKER (widget);
 
-#if GTK_CHECK_VERSION(2,18,0)
-	{
-		GtkAllocation a;
-		gtk_widget_get_allocation (GTK_WIDGET (ticker), &a);
-		if ( a.width != ticker->width )
-			ticker->dirty = TRUE;
-	}
-#else
-	if ( GTK_WIDGET(ticker)->allocation.width != ticker->width )
+	gtk_widget_get_allocation (GTK_WIDGET (ticker), &a);
+	if ( a.width != ticker->width )
 		ticker->dirty = TRUE;
-#endif
 
 	if ( ticker->dirty == TRUE ) {
 		gtk_ticker_compute_offsets( ticker );
 	}
 
-#if GTK_CHECK_VERSION(2,18,0)
 	gtk_widget_set_allocation (widget, allocation);
-#else
-	widget->allocation = *allocation;
-#endif
 	if (gtk_widget_get_realized (widget))
 		gdk_window_move_resize (gtk_widget_get_window (widget),
 				allocation->x,
--- a/pidgin/plugins/timestamp.c	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/timestamp.c	Tue Jul 24 03:43:55 2012 -0400
@@ -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	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/timestamp_format.c	Tue Jul 24 03:43:55 2012 -0400
@@ -156,7 +156,7 @@
 		return;
 
 	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	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/vvconfig.c	Tue Jul 24 03:43:55 2012 -0400
@@ -505,14 +505,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	Mon Jul 23 20:13:26 2012 -0400
+++ b/pidgin/plugins/xmppconsole.c	Tue Jul 24 03:43:55 2012 -0400
@@ -31,6 +31,8 @@
 
 #include <gdk/gdkkeysyms.h>
 
+#include "gtk3compat.h"
+
 typedef struct {
 	PurpleConnection *gc;
 	GtkWidget *window;
@@ -314,11 +316,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);
 
@@ -339,7 +341,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)));
 
 	gtk_webview_load_html_string_with_selection(GTK_WEBVIEW(console->entry), stanza);
 	gtk_widget_grab_focus(console->entry);
@@ -403,15 +405,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);
 
@@ -421,12 +423,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);
@@ -464,10 +466,10 @@
 	}
 
 	to = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(to_entry)), -1);
-	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 = g_markup_escape_text(gtk_entry_get_text(GTK_ENTRY(status_entry)), -1);
@@ -563,12 +565,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);
 
@@ -630,7 +632,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 ? "&lt;body&gt;" : "",
 	                         *body ? body : "",
@@ -668,7 +671,8 @@
 	if (strcmp(purple_account_get_protocol_id(account), "prpl-jabber"))
 		return;
 
-	gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown), purple_account_get_username(account));
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(console->dropdown),
+		purple_account_get_username(account));
 	console->accounts = g_list_append(console->accounts, gc);
 	console->count++;
 
@@ -701,7 +705,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--;
 
@@ -745,7 +749,7 @@
 }
 
 static void
-console_destroy(GtkObject *window, gpointer nul)
+console_destroy(GtkWidget *window, gpointer nul)
 {
 	g_list_free(console->accounts);
 	g_free(console);
@@ -788,13 +792,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;

mercurial