After a little under seven months, Pidgin 3 is officially a GTK4 application!

Sun, 28 Aug 2022 22:18:46 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Sun, 28 Aug 2022 22:18:46 -0500
changeset 41614
983b2a56b270
parent 41517
5bafe75d3907 (current diff)
parent 41613
4be49932c288 (diff)
child 41616
08ea1d13edaa

After a little under seven months, Pidgin 3 is officially a GTK4 application!

.reviewboardrc file | annotate | diff | comparison | revisions
--- a/ChangeLog.API	Tue Aug 23 01:09:33 2022 -0500
+++ b/ChangeLog.API	Sun Aug 28 22:18:46 2022 -0500
@@ -829,6 +829,7 @@
 		* pidgin_append_menu_action
 		* pidgin_blist_add_alert
 		* pidgin_blist_draw_tooltip
+		* pidgin_blist_get_status_icon
 		* pidgin_blist_get_theme
 		* pidgin_blist_layout_get_type
 		* pidgin_blist_make_buddy_menu
@@ -927,6 +928,8 @@
 		* pidgin_conversations_fill_menu
 		* pidgin_conversations_get_unseen_all
 		* pidgin_create_dialog, use pidgin_dialog_new instead.
+		* pidgin_create_icon_from_protocol
+		* pidgin_create_protocol_icon
 		* pidgin_create_small_button, use pidgin_close_button_new instead.
 		* pidgin_create_status_icon
 		* pidgin_create_window, use pidgin_window_new instead.
@@ -936,6 +939,7 @@
 		* pidgin_dialog_get_vbox
 		* pidgin_dialog_get_vbox_with_properties
 		* pidgin_dialogs_alias_contact
+		* pidgin_dialogs_destroy_all
 		* pidgin_dialogs_log
 		* pidgin_get_dim_grey_string
 		* pidgin_gdk_pixbuf_make_round, use purple_gdk_pixbuf_make_round instead.
@@ -973,6 +977,9 @@
 		* pidgin_idle_get_ui_ops
 		* pidgin_load_accels
 		* pidgin_make_mini_dialog_with_custom_icon
+		* pidgin_make_scrollable
+		* pidgin_mini_dialog_new_with_custom_icon
+		* pidgin_mini_dialog_set_custom_icon
 		* pidgin_make_pretty_arrows
 		* PidginMiniDialog
 		* PidginMiniDialogCallback
@@ -1071,6 +1078,8 @@
 		* PIDGIN_TYPE_STOCK_ICON_THEME
 		* PidginStockIconTheme
 		* PidginStockIconThemeClass
+		* pidgin_text_combo_box_entry_new
+		* pidgin_text_combo_box_entry_get_text
 		* pidgin_text_combo_box_entry_set_text
 		* pidgin_theme_font_free
 		* pidgin_theme_font_get_color
--- a/doc/reference/pidgin/meson.build	Tue Aug 23 01:09:33 2022 -0500
+++ b/doc/reference/pidgin/meson.build	Sun Aug 28 22:18:46 2022 -0500
@@ -26,7 +26,7 @@
 			'--no-namespace-dir',
 			'--content-dir=@0@'.format(meson.current_source_dir()),
 			'--add-include-path=@0@'.format(meson.global_build_root() / 'subprojects/gplugin/gplugin'),
-			'--add-include-path=@0@'.format(meson.global_build_root() / 'subprojects/gplugin/gplugin-gtk3'),
+			'--add-include-path=@0@'.format(meson.global_build_root() / 'subprojects/gplugin/gplugin-gtk4'),
 			'--add-include-path=@0@'.format(meson.project_build_root() / 'libpurple'),
 			'--add-include-path=@0@'.format(meson.global_build_root() / 'subprojects/talkatu/talkatu'),
 			'@INPUT1@'
--- a/doc/reference/pidgin/pidgin.toml.in	Tue Aug 23 01:09:33 2022 -0500
+++ b/doc/reference/pidgin/pidgin.toml.in	Sun Aug 28 22:18:46 2022 -0500
@@ -7,7 +7,7 @@
 logo_url = ""
 license = "GPL-2.0-or-later"
 description = "Pidgin Universal Chat Client"
-dependencies = [ "GLib-2.0", "GObject-2.0", "Gtk-3.0", "Purple-3.0", "GPlugin-1.0", "GPlugin-Gtk3-1.0", "Talkatu-0.0" ]
+dependencies = [ "GLib-2.0", "GObject-2.0", "Gtk-4.0", "Purple-3.0", "GPlugin-1.0", "GPlugin-Gtk4-1.0", "Talkatu-0.0" ]
 devhelp = true
 search_index = true
 
@@ -21,10 +21,10 @@
   description = "The base type system library"
   docs_url = "https://docs.gtk.org/gobject/"
 
-  [dependencies."Gtk-3.0"]
+  [dependencies."Gtk-4.0"]
   name = "Gtk"
   description = "The GTK toolkit"
-  docs_url = "https://docs.gtk.org/gtk3/"
+  docs_url = "https://docs.gtk.org/gtk4/"
 
   [dependencies."Purple-3.0"]
   name = "Purple"
@@ -36,14 +36,14 @@
   description = "GPlugin Plugin Library"
   docs_urls = "https://docs.imfreedom.org/gplugin/"
 
-  [dependencies."GPlugin-Gtk3-1.0"]
-  name = "GPlugin-Gtk3"
-  description = "GPlugin Gtk3 Widget Library"
-  docs_urls = "https://docs.imfreedom.org/gplugin-gtk3/"
+  [dependencies."GPlugin-Gtk4-1.0"]
+  name = "GPlugin-Gtk"
+  description = "GPlugin Gtk4 Widget Library"
+  docs_urls = "https://docs.imfreedom.org/gplugin-gtk4/"
 
   [dependencies."Talkatu-0.0"]
   name = "Talkatu"
-  description = "Talkatu Gtk3 Chat Widgets"
+  description = "Talkatu Gtk Chat Widgets"
   docs_urls = "https://docs.imfreedom.org/talkatu/"
 
 [theme]
--- a/doc/reference/pidgin/urlmap.js	Tue Aug 23 01:09:33 2022 -0500
+++ b/doc/reference/pidgin/urlmap.js	Sun Aug 28 22:18:46 2022 -0500
@@ -6,8 +6,8 @@
     [ 'GLib', 'https://docs.gtk.org/glib/' ],
     [ 'GObject', 'https://docs.gtk.org/gobject/' ],
     [ 'GPlugin', 'https://docs.imfreedom.org/gplugin/' ],
-    [ 'GPlugin-Gtk3', 'https://docs.imfreedom.org/gplugin-gtk3/' ],
-    [ 'Gtk', 'https://docs.gtk.org/gtk3/' ],
+    [ 'GPlugin-Gtk4', 'https://docs.imfreedom.org/gplugin-gtk4/' ],
+    [ 'Gtk', 'https://docs.gtk.org/gtk4/' ],
     [ 'Purple3', 'https://docs.imfreedom.org/purple3/' ],
     [ 'Talkatu', 'https://docs.imfreedom.org/talkatu/' ],
 ]
--- a/meson.build	Tue Aug 23 01:09:33 2022 -0500
+++ b/meson.build	Sun Aug 28 22:18:46 2022 -0500
@@ -256,8 +256,8 @@
 # Check Pidgin dependencies
 #######################################################################
 if get_option('gtkui')
-	gtk = dependency('gtk+-3.0', version : '>= 3.24.0')
-	libhandy = dependency('libhandy-1', version : '>= 1')
+	gtk = dependency('gtk4', version : '>= 4.0.0')
+	libadwaita = dependency('libadwaita-1', version : '>= 1')
 
 	talkatu_dep = dependency('talkatu',
 		version: '>=0.1.0',
@@ -528,9 +528,9 @@
 	fallback : ['gplugin', 'gplugin_dep'])
 
 if get_option('gtkui')
-	gplugin_gtk_dep = dependency('gplugin-gtk3',
+	gplugin_gtk_dep = dependency('gplugin-gtk4',
 		version : gplugin_version,
-		fallback : ['gplugin-gtk', 'gplugin_gtk3_dep'])
+		fallback : ['gplugin-gtk4', 'gplugin_gtk4_dep'])
 endif
 
 #######################################################################
--- a/pidgin/gtkaccount.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkaccount.c	Sun Aug 28 22:18:46 2022 -0500
@@ -173,7 +173,9 @@
 	{
 		/* Show a placeholder icon */
 		gtk_image_set_from_icon_name(GTK_IMAGE(dialog->icon_entry),
-				"select-avatar", GTK_ICON_SIZE_LARGE_TOOLBAR);
+		                             "select-avatar");
+		gtk_image_set_icon_size(GTK_IMAGE(dialog->icon_entry),
+		                        GTK_ICON_SIZE_LARGE);
 	} else {
 		gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_entry), pixbuf);
 		g_object_unref(G_OBJECT(pixbuf));
@@ -208,14 +210,14 @@
 	if (!dialog->protocol ||
 	    !PURPLE_PROTOCOL_IMPLEMENTS(dialog->protocol, SERVER, register_user))
 	{
-		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->register_button), FALSE);
+		gtk_check_button_set_active(GTK_CHECK_BUTTON(dialog->register_button), FALSE);
 		gtk_widget_hide(dialog->register_button);
 	} else {
 		if (purple_protocol_get_options(dialog->protocol) &
 		    OPT_PROTO_REGISTER_NOSCREENNAME) {
 			gtk_widget_set_sensitive(dialog->register_button, TRUE);
 		} else {
-			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+			gtk_check_button_set_active(GTK_CHECK_BUTTON(
 				dialog->register_button), FALSE);
 			gtk_widget_set_sensitive(dialog->register_button, FALSE);
 		}
@@ -229,12 +231,12 @@
 	gboolean opt_noscreenname = (dialog->protocol != NULL &&
 		(purple_protocol_get_options(dialog->protocol) & OPT_PROTO_REGISTER_NOSCREENNAME));
 	gboolean username_valid = purple_validate(dialog->protocol,
-		gtk_entry_get_text(entry));
+		gtk_editable_get_text(GTK_EDITABLE(entry)));
 
 	if (dialog->ok_button) {
 		if (opt_noscreenname && dialog->register_button &&
-			gtk_toggle_button_get_active(
-				GTK_TOGGLE_BUTTON(dialog->register_button)))
+			gtk_check_button_get_active(
+				GTK_CHECK_BUTTON(dialog->register_button)))
 			gtk_widget_set_sensitive(dialog->ok_button, TRUE);
 		else
 			gtk_widget_set_sensitive(dialog->ok_button,
@@ -253,21 +255,21 @@
 static void
 register_button_cb(GtkWidget *checkbox, AccountPrefsDialog *dialog)
 {
-	int register_checked = gtk_toggle_button_get_active(
-		GTK_TOGGLE_BUTTON(dialog->register_button));
+	int register_checked = gtk_check_button_get_active(
+		GTK_CHECK_BUTTON(dialog->register_button));
 	int opt_noscreenname = (dialog->protocol != NULL &&
 		(purple_protocol_get_options(dialog->protocol) & OPT_PROTO_REGISTER_NOSCREENNAME));
 	int register_noscreenname = (opt_noscreenname && register_checked);
 
 	if (register_noscreenname) {
-		gtk_entry_set_text(GTK_ENTRY(dialog->username_entry), "");
+		gtk_editable_set_text(GTK_EDITABLE(dialog->username_entry), "");
 	}
 	gtk_widget_set_sensitive(dialog->username_entry, !register_noscreenname);
 
 	if (dialog->ok_button) {
 		gtk_widget_set_sensitive(dialog->ok_button,
 			(opt_noscreenname && register_checked) ||
-			*gtk_entry_get_text(GTK_ENTRY(dialog->username_entry))
+			*gtk_editable_get_text(GTK_EDITABLE(dialog->username_entry))
 				!= '\0');
 	}
 }
@@ -278,13 +280,19 @@
 	AccountPrefsDialog *dialog = data;
 
 	if (response == GTK_RESPONSE_ACCEPT) {
+		GFile *file = NULL;
 		gchar *filename = NULL;
 		gpointer data = NULL;
 		size_t len = 0;
 
-		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
+		file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(widget));
+		filename = g_file_get_path(file);
+
 		data = pidgin_convert_buddy_icon(dialog->protocol, filename, &len);
 		set_dialog_icon(dialog, data, len, filename);
+
+		g_free(filename);
+		g_object_unref(file);
 	}
 
 	g_clear_object(&dialog->icon_filesel);
@@ -374,11 +382,12 @@
 	{
 		g_object_ref(G_OBJECT(dialog->protocol_menu));
 		hbox = g_object_get_data(G_OBJECT(dialog->protocol_menu), "container");
-		gtk_container_remove(GTK_CONTAINER(hbox), dialog->protocol_menu);
+		gtk_box_remove(GTK_BOX(hbox), dialog->protocol_menu);
 	}
 
-	if (dialog->login_frame != NULL)
-		gtk_widget_destroy(dialog->login_frame);
+	if (dialog->login_frame != NULL) {
+		gtk_widget_unparent(dialog->login_frame);
+	}
 
 	/* Build the login options frame. */
 	frame = pidgin_make_frame(parent, _("Login Options"));
@@ -386,13 +395,11 @@
 	/* cringe */
 	dialog->login_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame));
 
-	gtk_box_reorder_child(GTK_BOX(parent), dialog->login_frame, 0);
-	gtk_widget_show(dialog->login_frame);
+	gtk_box_reorder_child_after(GTK_BOX(parent), dialog->login_frame, NULL);
 
 	/* Main vbox */
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-	gtk_container_add(GTK_CONTAINER(frame), vbox);
-	gtk_widget_show(vbox);
+	gtk_box_append(GTK_BOX(frame), vbox);
 
 	/* Protocol */
 	if(dialog->protocol_menu == NULL) {
@@ -401,7 +408,6 @@
 		                                        dialog->protocol_id);
 		g_signal_connect(G_OBJECT(dialog->protocol_menu), "changed",
 		                 G_CALLBACK(set_account_protocol_cb), dialog);
-		gtk_widget_show(dialog->protocol_menu);
 		g_object_ref(G_OBJECT(dialog->protocol_menu));
 	}
 
@@ -498,15 +504,17 @@
 		if (value == NULL)
 			value = purple_account_user_split_get_default_value(split);
 
-		if (value != NULL && entry != NULL)
-			gtk_entry_set_text(GTK_ENTRY(entry), value);
+		if (value != NULL && entry != NULL) {
+			gtk_editable_set_text(GTK_EDITABLE(entry), value);
+		}
 	}
 
 	g_list_free_full(user_splits,
 	                 (GDestroyNotify)purple_account_user_split_destroy);
 
-	if (username != NULL)
-		gtk_entry_set_text(GTK_ENTRY(dialog->username_entry), username);
+	if (username != NULL) {
+		gtk_editable_set_text(GTK_EDITABLE(dialog->username_entry), username);
+	}
 
 	g_free(username);
 
@@ -523,7 +531,7 @@
 static void
 icon_check_cb(GtkWidget *checkbox, AccountPrefsDialog *dialog)
 {
-	gtk_widget_set_sensitive(dialog->icon_hbox, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check)));
+	gtk_widget_set_sensitive(dialog->icon_hbox, gtk_check_button_get_active(GTK_CHECK_BUTTON(dialog->icon_check)));
 }
 
 static void
@@ -537,20 +545,20 @@
 	GtkWidget *button;
 	GtkWidget *label;
 
-	if (dialog->user_frame != NULL)
-		gtk_widget_destroy(dialog->user_frame);
+	if (dialog->user_frame != NULL) {
+		gtk_widget_unparent(dialog->user_frame);
+	}
 
 	/* Build the user options frame. */
 	frame = pidgin_make_frame(parent, _("User Options"));
 	dialog->user_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame));
 
-	gtk_box_reorder_child(GTK_BOX(parent), dialog->user_frame, 1);
-	gtk_widget_show(dialog->user_frame);
+	gtk_box_reorder_child_after(GTK_BOX(parent), dialog->user_frame,
+	                            gtk_widget_get_first_child(parent));
 
 	/* Main vbox */
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-	gtk_container_add(GTK_CONTAINER(frame), vbox);
-	gtk_widget_show(vbox);
+	gtk_box_append(GTK_BOX(frame), vbox);
 
 	/* Alias */
 	dialog->alias_entry = gtk_entry_new();
@@ -559,27 +567,22 @@
 	/* Buddy icon */
 	dialog->icon_check = gtk_check_button_new_with_mnemonic(_("Use this buddy _icon for this account:"));
 	g_signal_connect(G_OBJECT(dialog->icon_check), "toggled", G_CALLBACK(icon_check_cb), dialog);
-	gtk_widget_show(dialog->icon_check);
-	gtk_box_pack_start(GTK_BOX(vbox), dialog->icon_check, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(vbox), dialog->icon_check);
 
 	dialog->icon_hbox = hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-	gtk_widget_set_sensitive(hbox, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check)));
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-	gtk_widget_show(hbox);
+	gtk_widget_set_sensitive(hbox, gtk_check_button_get_active(GTK_CHECK_BUTTON(dialog->icon_check)));
+	gtk_box_append(GTK_BOX(vbox), hbox);
 
 	label = gtk_label_new("    ");
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	gtk_widget_show(label);
+	gtk_box_append(GTK_BOX(hbox), label);
 
 	button = gtk_button_new();
-	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
-	gtk_widget_show(button);
+	gtk_box_append(GTK_BOX(hbox), button);
 	g_signal_connect(G_OBJECT(button), "clicked",
 	                 G_CALLBACK(icon_select_cb), dialog);
 
 	dialog->icon_entry = gtk_image_new();
-	gtk_container_add(GTK_CONTAINER(button), dialog->icon_entry);
-	gtk_widget_show(dialog->icon_entry);
+	gtk_button_set_child(GTK_BUTTON(button), dialog->icon_entry);
 	/* TODO: Uh, isn't this next line pretty useless? */
 	pidgin_set_accessible_label(dialog->icon_entry, GTK_LABEL(label));
 	if (dialog->icon_img) {
@@ -588,18 +591,19 @@
 	}
 
 	vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
-	gtk_widget_show(vbox2);
+	gtk_widget_set_hexpand(vbox2, TRUE);
+	gtk_widget_set_halign(vbox2, GTK_ALIGN_FILL);
+	gtk_box_append(GTK_BOX(hbox), vbox2);
 
 	hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-	gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 12);
-	gtk_widget_show(hbox2);
+	gtk_widget_set_margin_top(hbox2, 12);
+	gtk_widget_set_margin_bottom(hbox2, 12);
+	gtk_box_append(GTK_BOX(vbox2), hbox2);
 
 	button = gtk_button_new_with_mnemonic(_("_Remove"));
 	g_signal_connect(G_OBJECT(button), "clicked",
 			 G_CALLBACK(icon_reset_cb), dialog);
-	gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0);
-	gtk_widget_show(button);
+	gtk_box_append(GTK_BOX(hbox2), button);
 
 	if (dialog->protocol != NULL) {
 		PurpleBuddyIconSpec *icon_spec = purple_protocol_get_icon_spec(dialog->protocol);
@@ -617,11 +621,12 @@
 		gpointer data = NULL;
 		size_t len = 0;
 
-		if (purple_account_get_private_alias(dialog->account))
-			gtk_entry_set_text(GTK_ENTRY(dialog->alias_entry),
-							   purple_account_get_private_alias(dialog->account));
+		if (purple_account_get_private_alias(dialog->account)) {
+			gtk_editable_set_text(GTK_EDITABLE(dialog->alias_entry),
+			                      purple_account_get_private_alias(dialog->account));
+		}
 
-		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->icon_check),
+		gtk_check_button_set_active(GTK_CHECK_BUTTON(dialog->icon_check),
 					     !purple_account_get_bool(dialog->account, "use-global-buddyicon",
 								       TRUE));
 
@@ -698,10 +703,8 @@
 
 	/* Main vbox */
 	dialog->protocol_frame = vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-	gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
 	gtk_notebook_insert_page(GTK_NOTEBOOK(dialog->notebook), vbox,
 			gtk_label_new_with_mnemonic(_("Ad_vanced")), 1);
-	gtk_widget_show(vbox);
 
 	for (l = opts; l != NULL; l = l->next)
 	{
@@ -731,11 +734,10 @@
 				opt_entry->widget = check = gtk_check_button_new_with_mnemonic(tmp);
 				g_free(tmp);
 
-				gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
-											 bool_value);
+				gtk_check_button_set_active(GTK_CHECK_BUTTON(check),
+				                            bool_value);
 
-				gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
-				gtk_widget_show(check);
+				gtk_box_append(GTK_BOX(vbox), check);
 				break;
 
 			case PURPLE_PREF_INT:
@@ -755,7 +757,7 @@
 				g_snprintf(buf, sizeof(buf), "%d", int_value);
 
 				opt_entry->widget = entry = gtk_entry_new();
-				gtk_entry_set_text(GTK_ENTRY(entry), buf);
+				gtk_editable_set_text(GTK_EDITABLE(entry), buf);
 
 				title = g_strdup_printf("_%s:",
 						purple_account_option_get_text(option));
@@ -789,10 +791,18 @@
 						gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(entry),
 						                               hint);
 					}
+					if (str_value != NULL) {
+						GtkWidget *real_entry = NULL;
+						real_entry = gtk_combo_box_get_child(GTK_COMBO_BOX(entry));
+						gtk_editable_set_text(GTK_EDITABLE(real_entry),
+						                      str_value);
+					}
+				} else {
+					entry = gtk_entry_new();
+					gtk_editable_set_text(GTK_EDITABLE(entry),
+					                      str_value ? str_value : "");
 				}
-				else
-					entry = gtk_entry_new();
-				
+
 				opt_entry->widget = entry;
 				if (purple_account_option_string_get_masked(option) && str_hints)
 					g_warn_if_reached();
@@ -801,12 +811,6 @@
 					gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
 				}
 
-				if (str_value != NULL && str_hints)
-					gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(entry))),
-					                   str_value);
-				else
-					gtk_entry_set_text(GTK_ENTRY(entry), str_value ? str_value : "");
-
 				title = g_strdup_printf("_%s:",
 						purple_account_option_get_text(option));
 				add_pref_box(dialog, vbox, title, entry);
@@ -888,7 +892,7 @@
 {
 	if (!dialog->protocol || !PURPLE_PROTOCOL_IMPLEMENTS(dialog->protocol, MEDIA, initiate_session)) {
 		if (dialog->voice_frame) {
-			gtk_widget_destroy(dialog->voice_frame);
+			gtk_widget_unparent(dialog->voice_frame);
 			dialog->voice_frame = NULL;
 			dialog->suppression_check = NULL;
 		}
@@ -897,31 +901,27 @@
 
 	if (!dialog->voice_frame) {
 		dialog->voice_frame = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-		gtk_container_set_border_width(GTK_CONTAINER(dialog->voice_frame), 12);
 
 		dialog->suppression_check =
 				gtk_check_button_new_with_mnemonic(_("Use _silence suppression"));
-		gtk_box_pack_start(GTK_BOX(dialog->voice_frame), dialog->suppression_check,
-				FALSE, FALSE, 0);
+		gtk_box_append(GTK_BOX(dialog->voice_frame), dialog->suppression_check);
 
 		gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook),
 				dialog->voice_frame, gtk_label_new_with_mnemonic(_("_Voice and Video")));
-		gtk_widget_show_all(dialog->voice_frame);
 	}
 
 	if (dialog->account) {
-		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->suppression_check),
-		                             purple_account_get_silence_suppression(dialog->account));
+		gtk_check_button_set_active(GTK_CHECK_BUTTON(dialog->suppression_check),
+		                            purple_account_get_silence_suppression(dialog->account));
 	} else {
-		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->suppression_check), FALSE);
+		gtk_check_button_set_active(GTK_CHECK_BUTTON(dialog->suppression_check), FALSE);
 	}
 }
 
-static gboolean
-account_win_destroy_cb(GtkWidget *w, GdkEvent *event,
-					   AccountPrefsDialog *dialog)
+static void
+account_win_destroy_cb(AccountPrefsDialog *dialog)
 {
-	gtk_widget_destroy(dialog->window);
+	gtk_window_destroy(GTK_WINDOW(dialog->window));
 
 	g_list_free(dialog->user_split_entries);
 	g_list_free_full(dialog->protocol_opt_entries, (GDestroyNotify)protocol_opt_entry_free);
@@ -936,7 +936,6 @@
 	purple_signals_disconnect_by_handle(dialog);
 
 	g_free(dialog);
-	return FALSE;
 }
 
 static void
@@ -971,7 +970,7 @@
 	manager = purple_account_manager_get_default();
 
 	/* Build the username string. */
-	username = g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->username_entry)));
+	username = g_strdup(gtk_editable_get_text(GTK_EDITABLE(dialog->username_entry)));
 
 	if (dialog->protocol != NULL)
 	{
@@ -984,7 +983,7 @@
 			GtkEntry *entry = l2->data;
 			char sep[2] = " ";
 
-			value = entry ? gtk_entry_get_text(entry) : "";
+			value = entry ? gtk_editable_get_text(GTK_EDITABLE(entry)) : "";
 			if (!value)
 				value = "";
 
@@ -1031,7 +1030,7 @@
 	}
 
 	/* Alias */
-	value = gtk_entry_get_text(GTK_ENTRY(dialog->alias_entry));
+	value = gtk_editable_get_text(GTK_EDITABLE(dialog->alias_entry));
 
 	if (*value != '\0')
 		purple_account_set_private_alias(account, value);
@@ -1047,13 +1046,13 @@
 		const char *filename;
 
 		if (new_acct || purple_account_get_bool(account, "use-global-buddyicon", TRUE) ==
-			gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check)))
+			gtk_check_button_get_active(GTK_CHECK_BUTTON(dialog->icon_check)))
 		{
 			icon_change = TRUE;
 		}
-		purple_account_set_bool(account, "use-global-buddyicon", !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check)));
+		purple_account_set_bool(account, "use-global-buddyicon", !gtk_check_button_get_active(GTK_CHECK_BUTTON(dialog->icon_check)));
 
-		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check)))
+		if (gtk_check_button_get_active(GTK_CHECK_BUTTON(dialog->icon_check)))
 		{
 			if (dialog->icon_img)
 			{
@@ -1100,18 +1099,18 @@
 					if (GTK_IS_COMBO_BOX(opt_entry->widget))
 						value = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(opt_entry->widget));
 					else
-						value = gtk_entry_get_text(GTK_ENTRY(opt_entry->widget));
+						value = gtk_editable_get_text(GTK_EDITABLE(opt_entry->widget));
 					purple_account_set_string(account, opt_entry->setting, value);
 					break;
 
 				case PURPLE_PREF_INT:
-					int_value = atoi(gtk_entry_get_text(GTK_ENTRY(opt_entry->widget)));
+					int_value = atoi(gtk_editable_get_text(GTK_EDITABLE(opt_entry->widget)));
 					purple_account_set_int(account, opt_entry->setting, int_value);
 					break;
 
 				case PURPLE_PREF_BOOLEAN:
 					bool_value =
-						gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(opt_entry->widget));
+						gtk_check_button_get_active(GTK_CHECK_BUTTON(opt_entry->widget));
 					purple_account_set_bool(account, opt_entry->setting, bool_value);
 					break;
 
@@ -1134,7 +1133,7 @@
 	/* Voice and Video settings */
 	if (dialog->voice_frame) {
 		purple_account_set_silence_suppression(account,
-				gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->suppression_check)));
+				gtk_check_button_get_active(GTK_CHECK_BUTTON(dialog->suppression_check)));
 	}
 
 	/* If this is a new account, add it to our list */
@@ -1145,7 +1144,7 @@
 	}
 
 	/* If this is a new account, then sign on! */
-	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->register_button))) {
+	if (gtk_check_button_get_active(GTK_CHECK_BUTTON(dialog->register_button))) {
 		purple_account_set_register_callback(account, account_register_cb, NULL);
 		purple_account_register(account);
 	} else if (new_acct) {
@@ -1159,7 +1158,7 @@
 	}
 
 	/* We no longer need the data from the dialog window */
-	account_win_destroy_cb(NULL, NULL, dialog);
+	account_win_destroy_cb(dialog);
 }
 
 static void
@@ -1171,7 +1170,8 @@
 			account_prefs_save(window);
 			break;
 		case RESPONSE_CLOSE:
-			account_win_destroy_cb(NULL, NULL, window);
+		case GTK_RESPONSE_DELETE_EVENT:
+			account_win_destroy_cb(window);
 			break;
 		default:
 			break;
@@ -1209,8 +1209,6 @@
 	dialog->window = win = pidgin_dialog_new((type == PIDGIN_ADD_ACCOUNT_DIALOG) ? _("Add Account") : _("Modify Account"),
 		6, "account", FALSE);
 
-	g_signal_connect(win, "delete_event", G_CALLBACK(account_win_destroy_cb),
-	                 dialog);
 	g_signal_connect(win, "response", G_CALLBACK(account_prefs_response_cb),
 	                 dialog);
 
@@ -1219,15 +1217,12 @@
 	gtk_box_set_spacing(GTK_BOX(main_vbox), 6);
 
 	dialog->notebook = notebook = gtk_notebook_new();
-	gtk_box_pack_start(GTK_BOX(main_vbox), notebook, FALSE, FALSE, 0);
-	gtk_widget_show(GTK_WIDGET(notebook));
+	gtk_box_append(GTK_BOX(main_vbox), notebook);
 
 	/* Setup the inner vbox */
 	dialog->top_vbox = vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-	gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
 	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox,
 			gtk_label_new_with_mnemonic(_("_Basic")));
-	gtk_widget_show(vbox);
 
 	/* Setup the top frames. */
 	add_login_options(dialog, vbox);
@@ -1235,8 +1230,7 @@
 
 	button = gtk_check_button_new_with_mnemonic(
 		_("Create _this new account on the server"));
-	gtk_box_pack_start(GTK_BOX(main_vbox), button, FALSE, FALSE, 0);
-	gtk_widget_show(button);
+	gtk_box_append(GTK_BOX(main_vbox), button);
 	dialog->register_button = button;
 	g_signal_connect(G_OBJECT(dialog->register_button), "toggled", G_CALLBACK(register_button_cb), dialog);
 	if (dialog->account == NULL)
@@ -1256,7 +1250,6 @@
 	}
 	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dialog->proxy_options,
 	                         gtk_label_new_with_mnemonic(_("Proxy")));
-	gtk_widget_show(dialog->proxy_options);
 
 	add_voice_options(dialog);
 
@@ -1279,7 +1272,6 @@
 /**************************************************************************
  * Accounts Dialog
  **************************************************************************/
-
 /* This still exists because gtkprivacy calls it to add the privacy ui ops */
 static PurpleAccountUiOps ui_ops = {};
 
--- a/pidgin/gtkblist.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkblist.c	Sun Aug 28 22:18:46 2022 -0500
@@ -44,9 +44,9 @@
 #include "pidgin/pidgincontactlistwindow.h"
 #include "pidgin/pidgincore.h"
 #include "pidgin/pidgindebug.h"
+#include "pidgin/pidginiconname.h"
 #include "pidgin/pidginmooddialog.h"
 #include "pidgin/pidginplugininfo.h"
-#include "pidgin/pidginstylecontext.h"
 
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
@@ -90,7 +90,7 @@
 	NODE_COLUMN,
 	EMBLEM_COLUMN,
 	EMBLEM_VISIBLE_COLUMN,
-	PROTOCOL_ICON_COLUMN,
+	PROTOCOL_ICON_NAME_COLUMN,
 	BLIST_COLUMNS
 };
 
@@ -134,11 +134,14 @@
 {
 	if (response == GTK_RESPONSE_ACCEPT) {
 		PurpleBlistNode *node = (PurpleBlistNode*)data;
+		GFile *file = NULL;
 		gchar *filename = NULL;
 
-		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
+		file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(widget));
+		filename = g_file_get_path(file);
 		purple_buddy_icons_node_set_custom_icon_from_file(node, filename);
 		g_free(filename);
+		g_object_unref(file);
 	}
 
 	g_object_set_data(G_OBJECT(data), "buddy-icon-chooser", NULL);
@@ -666,10 +669,10 @@
 	else
 		g_return_if_reached();
 
-	if (GTK_IS_ENTRY (editable)) {
-		GtkEntry *entry = GTK_ENTRY (editable);
-		gtk_entry_set_text(entry, text);
+	if(GTK_IS_EDITABLE(editable)) {
+		gtk_editable_set_text(GTK_EDITABLE(editable), text);
 	}
+
 	editing_blist = TRUE;
 }
 
@@ -866,7 +869,7 @@
 			{
 				g_hash_table_replace(components,
 					g_strdup(g_object_get_data(tmp->data, "identifier")),
-					g_strdup(gtk_entry_get_text(tmp->data)));
+					g_strdup(gtk_editable_get_text(GTK_EDITABLE(tmp->data))));
 			}
 		}
 
@@ -892,7 +895,7 @@
 		break;
 	}
 
-	gtk_widget_destroy(GTK_WIDGET(dialog));
+	gtk_window_destroy(GTK_WINDOW(dialog));
 	g_list_free(info->entries);
 	g_free(info);
 }
@@ -919,7 +922,7 @@
 		if (!g_object_get_data(tmp->data, "is_spin"))
 		{
 			required = GPOINTER_TO_INT(g_object_get_data(tmp->data, "required"));
-			text = gtk_entry_get_text(tmp->data);
+			text = gtk_editable_get_text(GTK_EDITABLE(tmp->data));
 			if (required && (*text == '\0'))
 				sensitive = FALSE;
 		}
@@ -990,8 +993,8 @@
 
 	data->account = account;
 
-	img = gtk_image_new_from_icon_name("dialog-question",
-			GTK_ICON_SIZE_DIALOG);
+	img = gtk_image_new_from_icon_name("dialog-question");
+	gtk_image_set_icon_size(GTK_IMAGE(img), GTK_ICON_SIZE_LARGE);
 
 	gtkblist = PIDGIN_BUDDY_LIST(purple_blist_get_default());
 	blist_window = gtkblist ? GTK_WINDOW(gtkblist->window) : NULL;
@@ -1000,31 +1003,25 @@
 	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), 6);
 	gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE);
 	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
 	                    12);
-	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(data->window))),
-	                               6);
-	gtk_window_set_role(GTK_WINDOW(data->window), window_role);
 
 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-	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_box_append(GTK_BOX(hbox), img);
 	gtk_widget_set_halign(img, GTK_ALIGN_START);
 	gtk_widget_set_valign(img, GTK_ALIGN_START);
 
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-	gtk_container_add(GTK_CONTAINER(hbox), vbox);
+	gtk_box_append(GTK_BOX(hbox), vbox);
 
 	label = gtk_label_new(label_text);
 
 	gtk_widget_set_size_request(label, 400, -1);
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 	gtk_label_set_xalign(GTK_LABEL(label), 0);
 	gtk_label_set_yalign(GTK_LABEL(label), 0);
-	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(vbox), label);
 
 	data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
@@ -1048,8 +1045,7 @@
 	                 G_CALLBACK(callback_func), data);
 
 	data->vbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 5));
-	gtk_container_set_border_width(GTK_CONTAINER(data->vbox), 0);
-	gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(data->vbox), FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(vbox), GTK_WIDGET(data->vbox));
 
 	g_signal_connect(G_OBJECT(data->window), "response", response_cb, data);
 
@@ -1063,6 +1059,7 @@
 {
 	PurpleConnection *gc;
 	PurpleProtocol *protocol;
+	GtkWidget *child = NULL;
 	GList *list = NULL, *tmp;
 	GHashTable *defaults = NULL;
 	PurpleProtocolChatEntry *pce;
@@ -1073,7 +1070,11 @@
 	gc = purple_account_get_connection(data->rq_data.account);
 	protocol = purple_connection_get_protocol(gc);
 
-	gtk_container_foreach(GTK_CONTAINER(data->rq_data.vbox), (GtkCallback)gtk_widget_destroy, NULL);
+	child = gtk_widget_get_first_child(GTK_WIDGET(data->rq_data.vbox));
+	while (child != NULL) {
+		gtk_widget_unparent(child);
+		child = gtk_widget_get_first_child(GTK_WIDGET(data->rq_data.vbox));
+	}
 
 	g_list_free(data->entries);
 	data->entries = NULL;
@@ -1104,8 +1105,9 @@
 			input = gtk_entry_new();
 			gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE);
 			value = g_hash_table_lookup(defaults, pce->identifier);
-			if (value != NULL)
-				gtk_entry_set_text(GTK_ENTRY(input), value);
+			if(value != NULL) {
+				gtk_editable_set_text(GTK_EDITABLE(input), value);
+			}
 			if (pce->secret)
 			{
 				gtk_entry_set_visibility(GTK_ENTRY(input), FALSE);
@@ -1134,8 +1136,6 @@
 
 	/* Set whether the "OK" button should be clickable initially */
 	set_sensitive_if_input_chat_cb(NULL, data);
-
-	gtk_widget_show_all(GTK_WIDGET(data->rq_data.vbox));
 }
 
 static void
@@ -1186,7 +1186,7 @@
 
 	rebuild_chat_entries(data, NULL);
 
-	gtk_widget_show_all(data->rq_data.window);
+	gtk_widget_show(data->rq_data.window);
 }
 
 static void gtk_blist_row_expanded_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data)
@@ -1450,7 +1450,8 @@
 }
 
 static gboolean
-pidgin_blist_show_context_menu(GtkWidget *tv, PurpleBlistNode *node, GdkEventButton *event)
+pidgin_blist_show_context_menu(GtkWidget *tv, PurpleBlistNode *node,
+                               gdouble x, gdouble y)
 {
 	PidginBlistNode *gtknode = g_object_get_data(G_OBJECT(node), UI_DATA);
 	GAction *action = NULL;
@@ -1462,7 +1463,7 @@
 
 	gtk_application = GTK_APPLICATION(g_application_get_default());
 
-	action_map = G_ACTION_MAP(gtk_widget_get_action_group(tv, "menu"));
+	action_map = G_ACTION_MAP(gtkblist->action_group);
 
 	/* Create a menu based on the thing we right-clicked on */
 	if (PURPLE_IS_GROUP(node)) {
@@ -1566,15 +1567,14 @@
 	g_simple_action_set_enabled(G_SIMPLE_ACTION(action), enabled);
 
 	/* Now display the menu */
-	if (menu != NULL && event != NULL) {
-		GtkWidget *popover_menu = gtk_popover_menu_new();
-
-		gtk_popover_bind_model(GTK_POPOVER(popover_menu), G_MENU_MODEL(menu),
-		                       NULL);
-		gtk_popover_set_relative_to(GTK_POPOVER(popover_menu), tv);
+	if (menu != NULL && x >= 0 && y >= 0) {
+		GtkWidget *popover_menu = NULL;
+
+		popover_menu = gtk_popover_menu_new_from_model(G_MENU_MODEL(menu));
+		gtk_widget_set_parent(popover_menu, tv);
 		gtk_popover_set_position(GTK_POPOVER(popover_menu), GTK_POS_BOTTOM);
 		gtk_popover_set_pointing_to(GTK_POPOVER(popover_menu),
-		                            &(const GdkRectangle){(int)event->x, (int)event->y, 1, 1});
+		                            &(const GdkRectangle){(gint)x, (gint)y, 1, 1});
 
 		gtk_popover_popup(GTK_POPOVER(popover_menu));
 
@@ -1585,8 +1585,14 @@
 }
 
 static gboolean
-gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_data)
+gtk_blist_button_press_cb(GtkGestureClick *click, gint n_press, gdouble x,
+                          gdouble y, gpointer data)
 {
+	PidginBuddyList *gtkblist = data;
+	GtkWidget *tv = NULL;
+	GdkEvent *event = NULL;
+	GdkModifierType state;
+	guint button = 0;
 	GtkTreePath *path;
 	PurpleBlistNode *node;
 	GtkTreeIter iter;
@@ -1595,20 +1601,27 @@
 	PidginBlistNode *gtknode;
 	gboolean handled = FALSE;
 
+	tv = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(click));
+	event = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(click));
+	button = gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(click));
+	state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(click));
+
 	/* Here we figure out which node was clicked */
-	if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL))
+	if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), x, y, &path, NULL,
+	                                   NULL, NULL)) {
 		return FALSE;
+	}
 	gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path);
 	gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
 	gtknode = g_object_get_data(G_OBJECT(node), UI_DATA);
 
 	/* Right click draws a context menu */
-	if (gdk_event_triggers_context_menu((GdkEvent *)event)) {
-		handled = pidgin_blist_show_context_menu(tv, node, event);
+	if (gdk_event_triggers_context_menu(event)) {
+		handled = pidgin_blist_show_context_menu(tv, node, x, y);
 
 	/* CTRL+middle click expands or collapse a contact */
-	} else if ((event->button == GDK_BUTTON_MIDDLE) && (event->type == GDK_BUTTON_PRESS) &&
-			   (event->state & GDK_CONTROL_MASK) && (PURPLE_IS_CONTACT(node))) {
+	} else if ((button == GDK_BUTTON_MIDDLE) && (n_press == 1) &&
+			   (state & GDK_CONTROL_MASK) && PURPLE_IS_CONTACT(node)) {
 		if (gtknode->contact_expanded)
 			pidgin_blist_collapse_contact_cb(NULL, node);
 		else
@@ -1616,8 +1629,8 @@
 		handled = TRUE;
 
 	/* Double middle click gets info */
-	} else if ((event->button == GDK_BUTTON_MIDDLE) && (event->type == GDK_2BUTTON_PRESS) &&
-			   ((PURPLE_IS_CONTACT(node)) || (PURPLE_IS_BUDDY(node)))) {
+	} else if ((button == GDK_BUTTON_MIDDLE) && (n_press == 2) &&
+			   (PURPLE_IS_CONTACT(node) || PURPLE_IS_BUDDY(node))) {
 		PurpleAccount *account;
 		PurpleBuddy *b;
 		if(PURPLE_IS_CONTACT(node))
@@ -1651,26 +1664,6 @@
 #endif
 	gtk_tree_path_free(path);
 
-	return FALSE;
-}
-
-static gboolean
-pidgin_blist_popup_menu_cb(GtkWidget *tv, void *user_data)
-{
-	PurpleBlistNode *node;
-	GtkTreeIter iter;
-	GtkTreeSelection *sel;
-	gboolean handled = FALSE;
-
-	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv));
-	if (!gtk_tree_selection_get_selected(sel, NULL, &iter))
-		return FALSE;
-
-	gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
-
-	/* Shift+F10 draws a context menu */
-	handled = pidgin_blist_show_context_menu(tv, node, NULL);
-
 	return handled;
 }
 
@@ -1897,37 +1890,93 @@
 static void
 add_tip_for_account(GtkWidget *grid, gint row, PurpleAccount *account)
 {
-	GdkPixbuf *protocol_icon = NULL;
+	PurpleProtocol *protocol = NULL;
 	GtkWidget *image = NULL;
 	GtkWidget *name = NULL;
-
-	protocol_icon = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
-	if (purple_account_is_disconnected(account)) {
-		gdk_pixbuf_saturate_and_pixelate(protocol_icon, protocol_icon, 0.0, FALSE);
-	}
-	image = gtk_image_new_from_pixbuf(protocol_icon);
+	const gchar *icon_name = NULL;
+
+	protocol = purple_account_get_protocol(account);
+	icon_name = purple_protocol_get_icon_name(protocol);
+
+	image = gtk_image_new_from_icon_name(icon_name);
 	gtk_image_set_pixel_size(GTK_IMAGE(image), STATUS_SIZE);
 	gtk_grid_attach(GTK_GRID(grid), image, 0, row, 1, 1);
-	g_clear_object(&protocol_icon);
 
 	name = gtk_label_new(purple_account_get_username(account));
 	gtk_label_set_xalign(GTK_LABEL(name), 0);
 	gtk_label_set_yalign(GTK_LABEL(name), 0);
-	gtk_label_set_line_wrap(GTK_LABEL(name), TRUE);
+	gtk_label_set_wrap(GTK_LABEL(name), TRUE);
 	gtk_label_set_max_width_chars(GTK_LABEL(name), 36);
 	gtk_grid_attach(GTK_GRID(grid), name, 1, row, 1, 1);
 }
 
+static const gchar *
+pidgin_blist_get_status_icon_name(PurpleBlistNode *node) {
+	const char *icon = NULL;
+	PidginBlistNode *gtknode = g_object_get_data(G_OBJECT(node), UI_DATA);
+	PidginBlistNode *gtkbuddynode = NULL;
+	PurpleBuddy *buddy = NULL;
+	PurpleChat *chat = NULL;
+
+	if(PURPLE_IS_CONTACT(node)) {
+		if(!gtknode->contact_expanded) {
+			buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
+			if(buddy != NULL) {
+				gtkbuddynode = g_object_get_data(G_OBJECT(buddy), UI_DATA);
+			}
+		}
+	} else if(PURPLE_IS_BUDDY(node)) {
+		buddy = (PurpleBuddy*)node;
+		gtkbuddynode = g_object_get_data(G_OBJECT(node), UI_DATA);
+	} else if(PURPLE_IS_CHAT(node)) {
+		chat = (PurpleChat*)node;
+	} else {
+		return NULL;
+	}
+
+	if(buddy || chat) {
+		PurpleAccount *account;
+		PurpleProtocol *protocol;
+
+		if(buddy)
+			account = purple_buddy_get_account(buddy);
+		else
+			account = purple_chat_get_account(chat);
+
+		protocol = purple_account_get_protocol(account);
+		if(!protocol)
+			return NULL;
+	}
+
+	if(buddy) {
+		PurplePresence *p = purple_buddy_get_presence(buddy);
+
+		if (PURPLE_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) {
+			icon = "log-in";
+		} else if (gtkbuddynode && gtkbuddynode->recent_signonoff) {
+			icon = "log-out";
+		} else {
+			icon = pidgin_icon_name_from_presence(p, "pidgin-user-available");
+		}
+	} else if (chat) {
+		icon = "chat";
+	} else {
+		icon = "person";
+	}
+
+	return icon;
+}
+
 static void
 add_tip_for_node(GtkWidget *grid, gint row, PurpleBlistNode *node, gboolean full)
 {
-	GdkPixbuf *status_icon = NULL;
 	GtkWidget *image = NULL;
 	GtkWidget *name = NULL;
 	GdkPixbuf *avatar = NULL;
 	GtkWidget *avatar_image = NULL;
 	PurpleAccount *account = NULL;
 	char *tmp = NULL, *node_name = NULL, *tooltip_text = NULL;
+	const gchar *status_icon = NULL;
 
 	if (PURPLE_IS_BUDDY(node)) {
 		account = purple_buddy_get_account(PURPLE_BUDDY(node));
@@ -1935,11 +1984,10 @@
 		account = purple_chat_get_account(PURPLE_CHAT(node));
 	}
 
-	status_icon = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_LARGE);
-	image = gtk_image_new_from_pixbuf(status_icon);
+	status_icon = pidgin_blist_get_status_icon_name(node);
+	image = gtk_image_new_from_icon_name(status_icon);
 	gtk_image_set_pixel_size(GTK_IMAGE(image), STATUS_SIZE);
 	gtk_grid_attach(GTK_GRID(grid), image, 0, row, 1, 1);
-	g_clear_object(&status_icon);
 
 	if (PURPLE_IS_BUDDY(node)) {
 		tmp = g_markup_escape_text(purple_buddy_get_name(PURPLE_BUDDY(node)), -1);
@@ -1965,13 +2013,13 @@
 	gtk_grid_attach(GTK_GRID(grid), name, 1, row, 1, 1);
 
 	if (account != NULL) {
-		GdkPixbuf *protocol_icon = pidgin_create_protocol_icon(
-		        account, PIDGIN_PROTOCOL_ICON_SMALL);
-		image = gtk_image_new_from_pixbuf(protocol_icon);
+		PurpleProtocol *protocol = purple_account_get_protocol(account);
+		const gchar *icon_name = purple_protocol_get_icon_name(protocol);
+
+		image = gtk_image_new_from_icon_name(icon_name);
 		gtk_image_set_pixel_size(GTK_IMAGE(image), STATUS_SIZE);
 		gtk_widget_set_halign(image, GTK_ALIGN_END);
 		gtk_grid_attach(GTK_GRID(grid), image, 2, row, 1, 1);
-		g_clear_object(&protocol_icon);
 	}
 
 	tooltip_text = pidgin_get_tooltip_text(node, full);
@@ -1980,18 +2028,12 @@
 		gtk_label_set_xalign(GTK_LABEL(contents), 0);
 		gtk_label_set_yalign(GTK_LABEL(contents), 0);
 		gtk_label_set_markup(GTK_LABEL(contents), tooltip_text);
-		gtk_label_set_line_wrap(GTK_LABEL(contents), TRUE);
+		gtk_label_set_wrap(GTK_LABEL(contents), TRUE);
 		gtk_label_set_max_width_chars(GTK_LABEL(contents), 36);
 		gtk_grid_attach(GTK_GRID(grid), contents, 1, row+1, 2, 1);
 	}
 
 	avatar = pidgin_blist_get_buddy_icon(node, !full, FALSE);
-#if 0  /* Protocol Icon as avatar */
-	if(!avatar && full) {
-		avatar = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_LARGE);
-	}
-#endif
-
 	if (avatar != NULL) {
 		avatar_image = gtk_image_new_from_pixbuf(avatar);
 		gtk_widget_set_halign(avatar_image, GTK_ALIGN_END);
@@ -2049,7 +2091,6 @@
 		return FALSE;
 	}
 
-	gtk_widget_show_all(grid);
 	gtk_tooltip_set_custom(tooltip, grid);
 
 	return TRUE;
@@ -2544,86 +2585,6 @@
 }
 
 
-GdkPixbuf *
-pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
-{
-	GdkPixbuf *ret;
-	const char *icon = NULL;
-	gboolean trans = FALSE;
-	PidginBlistNode *gtknode = g_object_get_data(G_OBJECT(node), UI_DATA);
-	PidginBlistNode *gtkbuddynode = NULL;
-	PurpleBuddy *buddy = NULL;
-	PurpleChat *chat = NULL;
-	gint icon_size = (size == PIDGIN_STATUS_ICON_LARGE) ? 16 : 11;
-
-	if(PURPLE_IS_CONTACT(node)) {
-		if(!gtknode->contact_expanded) {
-			buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
-			if(buddy != NULL) {
-				gtkbuddynode = g_object_get_data(G_OBJECT(buddy), UI_DATA);
-			}
-		}
-	} else if(PURPLE_IS_BUDDY(node)) {
-		buddy = (PurpleBuddy*)node;
-		gtkbuddynode = g_object_get_data(G_OBJECT(node), UI_DATA);
-	} else if(PURPLE_IS_CHAT(node)) {
-		chat = (PurpleChat*)node;
-	} else {
-		return NULL;
-	}
-
-	if(buddy || chat) {
-		PurpleAccount *account;
-		PurpleProtocol *protocol;
-
-		if(buddy)
-			account = purple_buddy_get_account(buddy);
-		else
-			account = purple_chat_get_account(chat);
-
-		protocol = purple_account_get_protocol(account);
-		if(!protocol)
-			return NULL;
-	}
-
-	if(buddy) {
-		PurplePresence *p = purple_buddy_get_presence(buddy);
-		trans = purple_presence_is_idle(p);
-
-		if (PURPLE_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) {
-			icon = "log-in";
-		} else if (gtkbuddynode && gtkbuddynode->recent_signonoff) {
-			icon = "log-out";
-		} else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE)) {
-			icon = "pidgin-user-busy";
-		} else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY)) {
-			icon = "pidgin-user-away";
-		} else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY)) {
-			icon = "pidgin-user-extended-away";
-		} else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_OFFLINE)) {
-			icon = "pidgin-user-offline";
-		} else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_INVISIBLE)) {
-			icon = "pidgin-user-invisible";
-		} else {
-			icon = "pidgin-user-available";
-		}
-	} else if (chat) {
-		icon = "chat";
-	} else {
-		icon = "person";
-	}
-
-	ret = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), icon, icon_size, 0, NULL);
-	if (trans) {
-		GdkPixbuf *copy = gdk_pixbuf_copy(ret);
-		g_object_unref(ret);
-		do_alphashift(copy, 77);
-		ret = copy;
-	}
-
-	return ret;
-}
-
 gchar *
 pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased)
 {
@@ -2707,7 +2668,7 @@
 		}
 	}
 
-	dim_grey = pidgin_style_context_is_dark() ? "light slate grey" : "dim grey";
+	dim_grey = "dim grey";
 
 	/* choose the colors of the text */
 	name_color = NULL;
@@ -2917,11 +2878,10 @@
  * I'm sure other things in this code assumes that also.
  */
 static void
-treeview_style_set(GtkWidget *widget,
-		    gpointer data)
-{
+icon_theme_changed_cb(G_GNUC_UNUSED GtkIconTheme *self, gpointer data) {
 	PurpleBuddyList *list = data;
 	PurpleBlistNode *node = purple_blist_get_root(list);
+
 	while (node) {
 		pidgin_blist_update_group(list, node);
 		node = node->next;
@@ -2947,7 +2907,7 @@
 	rend = gtk_cell_renderer_pixbuf_new();
 	gtk_tree_view_column_pack_start(column, rend, FALSE);
 	gtk_tree_view_column_set_attributes(column, rend,
-					    "pixbuf", STATUS_ICON_COLUMN,
+					    "icon-name", STATUS_ICON_COLUMN,
 					    "visible", STATUS_ICON_VISIBLE_COLUMN,
 					    NULL);
 	g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL);
@@ -2980,7 +2940,7 @@
 	rend = gtk_cell_renderer_pixbuf_new();
 	gtk_tree_view_column_pack_start(column, rend, FALSE);
 	gtk_tree_view_column_set_attributes(column, rend,
-	                                    "pixbuf", PROTOCOL_ICON_COLUMN,
+	                                    "icon-name", PROTOCOL_ICON_NAME_COLUMN,
 	                                    NULL);
 	g_object_set(rend, "xalign", 0.0, "xpad", 3, "ypad", 0, NULL);
 
@@ -3073,10 +3033,11 @@
 
 static void pidgin_blist_show(PurpleBuddyList *list)
 {
-	GSimpleActionGroup *action_group = NULL;
 	void *handle;
-	GtkWidget *sep;
+	GtkWidget *sep, *sw;
 	GtkEventController *key_controller = NULL;
+	GtkGesture *click = NULL;
+	GtkIconTheme *icon_theme;
 	GtkTreeSelection *selection;
 
 	gtkblist = PIDGIN_BUDDY_LIST(list);
@@ -3090,24 +3051,23 @@
 
 	/****************************** GtkTreeView **********************************/
 	gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS,
-						 GDK_TYPE_PIXBUF, /* Status icon */
+						 G_TYPE_STRING, /* Status icon */
 						 G_TYPE_BOOLEAN,  /* Status icon visible */
 						 G_TYPE_STRING,   /* Name */
 						 GDK_TYPE_PIXBUF, /* Buddy icon */
 						 G_TYPE_POINTER,  /* Node */
 						 GDK_TYPE_PIXBUF, /* Emblem */
 						 G_TYPE_BOOLEAN,  /* Emblem visible */
-						 GDK_TYPE_PIXBUF /* Protocol icon */
+						 G_TYPE_STRING /* Protocol icon */
 						);
 
 	gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel));
-
-	gtk_widget_show(gtkblist->treeview);
 	gtk_widget_set_name(gtkblist->treeview, "pidgin_blist_treeview");
 
-	g_signal_connect(gtkblist->treeview,
-			 "style-updated",
-			 G_CALLBACK(treeview_style_set), list);
+	icon_theme = gtk_icon_theme_get_for_display(gdk_display_get_default());
+	g_signal_connect(icon_theme, "changed",
+	                 G_CALLBACK(icon_theme_changed_cb), list);
+
 	/* Set up selection stuff */
 	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview));
 	g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(pidgin_blist_selection_changed), NULL);
@@ -3130,32 +3090,41 @@
 	                 G_CALLBACK(gtk_blist_row_expanded_cb), gtkblist);
 	g_signal_connect(G_OBJECT(gtkblist->treeview), "row-collapsed",
 	                 G_CALLBACK(gtk_blist_row_collapsed_cb), gtkblist);
-	g_signal_connect(G_OBJECT(gtkblist->treeview), "button-press-event", G_CALLBACK(gtk_blist_button_press_cb), NULL);
-	key_controller = gtk_event_controller_key_new(gtkblist->treeview);
+
+	click = gtk_gesture_click_new();
+	gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(click), 0);
+	g_signal_connect(click, "pressed", G_CALLBACK(gtk_blist_button_press_cb),
+	                 gtkblist);
+	gtk_widget_add_controller(gtkblist->treeview, GTK_EVENT_CONTROLLER(click));
+
+	key_controller = gtk_event_controller_key_new();
 	g_signal_connect(G_OBJECT(key_controller), "key-pressed",
 	                 G_CALLBACK(pidgin_blist_key_press_cb), gtkblist);
-	g_object_set_data_full(G_OBJECT(gtkblist->treeview), "key-controller",
-	                       key_controller, g_object_unref);
-	g_signal_connect(G_OBJECT(gtkblist->treeview), "popup-menu", G_CALLBACK(pidgin_blist_popup_menu_cb), NULL);
+	gtk_widget_add_controller(gtkblist->treeview, key_controller);
 
 	/* Enable CTRL+F searching */
 	gtk_tree_view_set_search_column(GTK_TREE_VIEW(gtkblist->treeview), NAME_COLUMN);
 	gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview),
 			pidgin_blist_search_equal_func, NULL, NULL);
 
-	gtk_box_pack_start(GTK_BOX(gtkblist->vbox),
-		pidgin_make_scrollable(gtkblist->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, -1),
-		TRUE, TRUE, 0);
+	sw = gtk_scrolled_window_new();
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+	                               GTK_POLICY_AUTOMATIC,
+	                               GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), gtkblist->treeview);
+
+	gtk_widget_set_vexpand(sw, TRUE);
+	gtk_widget_set_valign(sw, GTK_ALIGN_FILL);
+	gtk_box_append(GTK_BOX(gtkblist->vbox), sw);
 
 	sep = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
-	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sep, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(gtkblist->vbox), sep);
 
 	/* Update some dynamic things */
 	pidgin_blist_update_sort_methods();
 
 	/* OK... let's show this bad boy. */
 	pidgin_blist_refresh(list);
-	gtk_widget_show_all(GTK_WIDGET(gtkblist->vbox));
 	purple_blist_set_visible(TRUE);
 
 	handle = pidgin_blist_get_handle();
@@ -3184,11 +3153,12 @@
 	handle = pidgin_blist_get_handle();
 	purple_signal_emit(handle, "gtkblist-created", list);
 
-	action_group = g_simple_action_group_new();
-	g_action_map_add_action_entries(G_ACTION_MAP(action_group), menu_actions,
-	                                G_N_ELEMENTS(menu_actions), gtkblist);
+	gtkblist->action_group = G_ACTION_GROUP(g_simple_action_group_new());
+	g_action_map_add_action_entries(G_ACTION_MAP(gtkblist->action_group),
+	                                menu_actions, G_N_ELEMENTS(menu_actions),
+	                                gtkblist);
 	gtk_widget_insert_action_group(gtkblist->treeview, "menu",
-	                               G_ACTION_GROUP(action_group));
+	                               G_ACTION_GROUP(gtkblist->action_group));
 
 	pidgin_blist_populate_menus();
 }
@@ -3463,17 +3433,18 @@
 static void buddy_node(PurpleBuddy *buddy, GtkTreeIter *iter, PurpleBlistNode *node)
 {
 	PurplePresence *presence = purple_buddy_get_presence(buddy);
-	GdkPixbuf *status, *avatar, *emblem, *protocol_icon;
+	PurpleProtocol *protocol = NULL;
+	GdkPixbuf *avatar, *emblem;
 	char *mark;
 	char *idle = NULL;
 	gboolean selected = (gtkblist->selected_node == node);
+	const gchar *protocol_icon_name = NULL, *status_icon_name = NULL;
 
 	if(editing_blist) {
 		return;
 	}
 
-	status = pidgin_blist_get_status_icon(PURPLE_BLIST_NODE(buddy),
-	                                      PIDGIN_STATUS_ICON_LARGE);
+	status_icon_name = pidgin_blist_get_status_icon_name(PURPLE_BLIST_NODE(buddy));
 	avatar = pidgin_blist_get_buddy_icon(PURPLE_BLIST_NODE(buddy), TRUE, TRUE);
 
 	if(avatar != NULL) {
@@ -3485,28 +3456,25 @@
 	emblem = pidgin_blist_get_emblem(PURPLE_BLIST_NODE(buddy));
 	mark = pidgin_blist_get_name_markup(buddy, selected, TRUE);
 
-	protocol_icon = pidgin_create_protocol_icon(purple_buddy_get_account(buddy), PIDGIN_PROTOCOL_ICON_SMALL);
+	protocol = purple_account_get_protocol(purple_buddy_get_account(buddy));
+	protocol_icon_name = purple_protocol_get_icon_name(protocol);
 
 	gtk_tree_store_set(gtkblist->treemodel, iter,
-			   STATUS_ICON_COLUMN, status,
+			   STATUS_ICON_COLUMN, status_icon_name,
 			   STATUS_ICON_VISIBLE_COLUMN, TRUE,
 			   NAME_COLUMN, mark,
 			   BUDDY_ICON_COLUMN, avatar,
 			   EMBLEM_COLUMN, emblem,
 			   EMBLEM_VISIBLE_COLUMN, (emblem != NULL),
-			   PROTOCOL_ICON_COLUMN, protocol_icon,
+			   PROTOCOL_ICON_NAME_COLUMN, protocol_icon_name,
 			-1);
 
 	g_free(mark);
 	g_free(idle);
 	if(emblem)
 		g_object_unref(emblem);
-	if(status)
-		g_object_unref(status);
 	if(avatar)
 		g_object_unref(avatar);
-	if(protocol_icon)
-		g_object_unref(protocol_icon);
 }
 
 /* This is a variation on the original gtk_blist_update_contact. Here we
@@ -3547,23 +3515,20 @@
 		gtknode = g_object_get_data(G_OBJECT(cnode), UI_DATA);
 
 		if(gtknode->contact_expanded) {
-			GdkPixbuf *status;
 			gchar *mark;
+			const gchar *icon_name = NULL;
 
 			mark = g_markup_escape_text(purple_contact_get_alias(contact), -1);
 
-			status = pidgin_blist_get_status_icon(cnode,
-			                                      PIDGIN_STATUS_ICON_LARGE);
+			icon_name = pidgin_blist_get_status_icon_name(cnode);
 
 			gtk_tree_store_set(gtkblist->treemodel, &iter,
-					   STATUS_ICON_COLUMN, status,
+					   STATUS_ICON_COLUMN, icon_name,
 					   STATUS_ICON_VISIBLE_COLUMN, TRUE,
 					   NAME_COLUMN, mark,
 					   BUDDY_ICON_COLUMN, NULL,
 					-1);
 			g_free(mark);
-			if(status)
-				g_object_unref(status);
 		} else {
 			buddy_node(buddy, &iter, cnode);
 		}
@@ -3621,17 +3586,19 @@
 	chat = (PurpleChat*)node;
 
 	if(purple_account_is_connected(purple_chat_get_account(chat))) {
+		PurpleProtocol *protocol = NULL;
 		GtkTreeIter iter;
-		GdkPixbuf *status, *avatar, *emblem, *protocol_icon;
+		GdkPixbuf *avatar, *emblem;
 		const gchar *color = NULL;
 		gchar *mark, *tmp;
 		gboolean selected = (gtkblist->selected_node == node);
 		gboolean nick_said = FALSE;
+		const gchar *protocol_icon_name = NULL, *status_icon_name = NULL;
 
 		if (!insert_node(list, node, &iter))
 			return;
 
-		status = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_LARGE);
+		status_icon_name = pidgin_blist_get_status_icon_name(node);
 		emblem = pidgin_blist_get_emblem(node);
 		avatar = pidgin_blist_get_buddy_icon(node, TRUE, FALSE);
 
@@ -3648,28 +3615,24 @@
 			mark = tmp;
 		}
 
-		protocol_icon = pidgin_create_protocol_icon(purple_chat_get_account(chat), PIDGIN_PROTOCOL_ICON_SMALL);
+		protocol = purple_account_get_protocol(purple_chat_get_account(chat));
+		protocol_icon_name = purple_protocol_get_icon_name(protocol);
 
 		gtk_tree_store_set(gtkblist->treemodel, &iter,
-				STATUS_ICON_COLUMN, status,
+				STATUS_ICON_COLUMN, status_icon_name,
 				STATUS_ICON_VISIBLE_COLUMN, TRUE,
 				BUDDY_ICON_COLUMN, avatar,
 				EMBLEM_COLUMN, emblem,
 				EMBLEM_VISIBLE_COLUMN, emblem != NULL,
-				PROTOCOL_ICON_COLUMN, protocol_icon,
+				PROTOCOL_ICON_NAME_COLUMN, protocol_icon_name,
 				NAME_COLUMN, mark,
 				-1);
 
 		g_free(mark);
 		if(emblem)
 			g_object_unref(emblem);
-		if(status)
-			g_object_unref(status);
 		if(avatar)
 			g_object_unref(avatar);
-		if(protocol_icon)
-			g_object_unref(protocol_icon);
-
 	} else {
 		pidgin_blist_hide_node(list, node, TRUE);
 	}
@@ -3709,7 +3672,7 @@
 	} else {
 		if (!gtk_widget_get_visible(gtkblist->window))
 			gtk_widget_show(gtkblist->window);
-		gtk_window_iconify(GTK_WINDOW(gtkblist->window));
+		/* gtk_window_iconify(GTK_WINDOW(gtkblist->window)); */
 	}
 }
 
@@ -3907,7 +3870,7 @@
 
 	purple_signals_disconnect_by_handle(gtkblist);
 
-	gtk_widget_destroy(gtkblist->window);
+	gtk_window_destroy(GTK_WINDOW(gtkblist->window));
 
 	gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL;
 	g_clear_object(&gtkblist->treemodel);
--- a/pidgin/gtkblist.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkblist.h	Sun Aug 28 22:18:46 2022 -0500
@@ -69,7 +69,7 @@
 
 	GtkCellRenderer *text_rend;
 
-	GtkWidget *menu;
+	GActionGroup *action_group;
 
 	PurpleBlistNode *selected_node;
 };
@@ -143,16 +143,6 @@
 pidgin_blist_get_emblem(PurpleBlistNode *node);
 
 /**
- * pidgin_blist_get_status_icon:
- *
- * Useful for the buddy ticker
- *
- * Returns: (transfer full): A #GdkPixbuf of status icon.
- */
-GdkPixbuf *pidgin_blist_get_status_icon(PurpleBlistNode *node,
-		PidginStatusIconSize size);
-
-/**
  * pidgin_blist_node_is_contact_expanded:
  * @node: The node in question.
  *
--- a/pidgin/gtkconn.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkconn.c	Sun Aug 28 22:18:46 2022 -0500
@@ -60,8 +60,6 @@
 {
 	if (purple_connections_get_all() != NULL)
 		return;
-
-	pidgin_dialogs_destroy_all();
 }
 
 static void
--- a/pidgin/gtkconv.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkconv.c	Sun Aug 28 22:18:46 2022 -0500
@@ -52,7 +52,6 @@
 #include "pidgininvitedialog.h"
 #include "pidginmessage.h"
 #include "pidginpresenceicon.h"
-#include "pidginstylecontext.h"
 
 #define ADD_MESSAGE_HISTORY_AT_ONCE 100
 
@@ -554,50 +553,11 @@
 	return menu;
 }
 
-
 static gint
-gtkconv_chat_popup_menu_cb(GtkWidget *widget, PidginConversation *gtkconv)
+right_click_chat_cb(GtkGestureClick *click, gint n_press, gdouble x, gdouble y,
+                    gpointer data)
 {
-	PurpleConversation *conv = gtkconv->active_conv;
-	PurpleConnection *gc;
-	PurpleAccount *account;
-	GtkTreeSelection *sel;
-	GtkTreeIter iter;
-	GtkTreeModel *model;
-	GtkWidget *popover_menu = NULL;
-	GMenu *menu = NULL;
-	gchar *who;
-
-	gtkconv = PIDGIN_CONVERSATION(conv);
-	account = purple_conversation_get_account(conv);
-	gc      = purple_account_get_connection(account);
-
-	model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->list));
-
-	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkconv->list));
-	if(!gtk_tree_selection_get_selected(sel, NULL, &iter))
-		return FALSE;
-
-	gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
-	menu = create_chat_menu(PURPLE_CHAT_CONVERSATION(conv), who, gc, gtkconv);
-
-	popover_menu = gtk_popover_menu_new();
-	gtk_popover_bind_model(GTK_POPOVER(popover_menu), G_MENU_MODEL(menu),
-	                       NULL);
-	gtk_popover_set_relative_to(GTK_POPOVER(popover_menu), gtkconv->list);
-
-	gtk_popover_popup(GTK_POPOVER(popover_menu));
-
-	g_free(who);
-
-	return TRUE;
-}
-
-
-static gint
-right_click_chat_cb(GtkWidget *widget, GdkEventButton *event,
-					PidginConversation *gtkconv)
-{
+	PidginConversation *gtkconv = data;
 	PurpleConversation *conv = gtkconv->active_conv;
 	PurpleConnection *gc;
 	PurpleAccount *account;
@@ -606,15 +566,18 @@
 	GtkTreeModel *model;
 	GtkTreeViewColumn *column;
 	gchar *who;
-	int x, y;
+	GdkEvent *event = NULL;
+	guint button;
 
 	account = purple_conversation_get_account(conv);
 	gc      = purple_account_get_connection(account);
+	event = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(click));
+	button = gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(click));
 
 	model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->list));
 
-	gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkconv->list),
-								  event->x, event->y, &path, &column, &x, &y);
+	gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkconv->list), x, y,
+	                              &path, &column, NULL, NULL);
 
 	if (path == NULL)
 		return FALSE;
@@ -629,27 +592,26 @@
 	gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
 
 	/* emit chat-nick-clicked signal */
-	if (event->type == GDK_BUTTON_PRESS) {
+	if (n_press == 1) {
 		gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
 					pidgin_conversations_get_handle(), "chat-nick-clicked",
-					conv, who, event->button));
+					conv, who, button));
 		if (plugin_return)
 			goto handled;
 	}
 
-	if (event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) {
+	if (button == GDK_BUTTON_PRIMARY && n_press == 2) {
 		chat_do_im(gtkconv, who);
-	} else if (gdk_event_triggers_context_menu((GdkEvent *)event)) {
-		GtkWidget *popover_menu = gtk_popover_menu_new();
+	} else if (gdk_event_triggers_context_menu(event)) {
+		GtkWidget *popover_menu = NULL;
 		GMenu *menu = create_chat_menu(PURPLE_CHAT_CONVERSATION(conv), who, gc,
 		                               gtkconv);
 
-		gtk_popover_bind_model(GTK_POPOVER(popover_menu), G_MENU_MODEL(menu),
-		                       NULL);
-		gtk_popover_set_relative_to(GTK_POPOVER(popover_menu), gtkconv->list);
+		popover_menu = gtk_popover_menu_new_from_model(G_MENU_MODEL(menu));
+		gtk_widget_set_parent(popover_menu, gtkconv->list);
 		gtk_popover_set_position(GTK_POPOVER(popover_menu), GTK_POS_BOTTOM);
 		gtk_popover_set_pointing_to(GTK_POPOVER(popover_menu),
-		                            &(const GdkRectangle){(int)event->x, (int)event->y, 1, 1});
+		                            &(const GdkRectangle){(int)x, (int)y, 1, 1});
 
 		gtk_popover_popup(GTK_POPOVER(popover_menu));
 	}
@@ -763,30 +725,47 @@
 }
 
 static gboolean
-conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event)
+conv_keypress_common(PidginConversation *gtkconv, guint keyval,
+                     GdkModifierType state)
 {
 	/* If CTRL was held down... */
-	if (event->state & GDK_CONTROL_MASK) {
-		switch (event->keyval) {
+	if (state & GDK_CONTROL_MASK) {
+		switch (keyval) {
 			case GDK_KEY_F6:
-				if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
+				if (gtkconv_cycle_focus(gtkconv,
+				                        state & GDK_SHIFT_MASK ?
+				                        GTK_DIR_TAB_BACKWARD :
+				                        GTK_DIR_TAB_FORWARD))
+				{
 					return TRUE;
+				}
 				break;
 		} /* End of switch */
-	}
 
 	/* If ALT (or whatever) was held down... */
-	else if (event->state & GDK_MOD1_MASK)
-	{
-	}
+	} else if (state & GDK_ALT_MASK) {
 
 	/* If neither CTRL nor ALT were held down... */
-	else
-	{
-		switch (event->keyval) {
+	} else {
+		switch (keyval) {
 		case GDK_KEY_F6:
-			if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
+			if (gtkconv_cycle_focus(gtkconv,
+			                        state & GDK_SHIFT_MASK ?
+			                        GTK_DIR_TAB_BACKWARD :
+			                        GTK_DIR_TAB_FORWARD))
+			{
 				return TRUE;
+			}
+			break;
+		case GDK_KEY_Page_Up:
+		case GDK_KEY_KP_Page_Up:
+			talkatu_auto_scroller_decrement(TALKATU_AUTO_SCROLLER(gtkconv->vadjustment));
+			return TRUE;
+			break;
+		case GDK_KEY_Page_Down:
+		case GDK_KEY_KP_Page_Down:
+			talkatu_auto_scroller_increment(TALKATU_AUTO_SCROLLER(gtkconv->vadjustment));
+			return TRUE;
 			break;
 		}
 	}
@@ -794,53 +773,46 @@
 }
 
 static gboolean
-entry_key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer data)
+entry_key_press_cb(GtkEventControllerKey *controller, guint keyval,
+                   G_GNUC_UNUSED guint keycode, GdkModifierType state,
+                   gpointer data)
 {
+	GtkWidget *entry = NULL;
 	PurpleConversation *conv;
 	PidginConversation *gtkconv;
 
-	gtkconv  = (PidginConversation *)data;
-	conv     = gtkconv->active_conv;
-
-	if (conv_keypress_common(gtkconv, event))
+	entry = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(controller));
+	gtkconv = (PidginConversation *)data;
+	conv = gtkconv->active_conv;
+
+	if (conv_keypress_common(gtkconv, keyval, state)) {
 		return TRUE;
+	}
 
 	/* If CTRL was held down... */
-	if (event->state & GDK_CONTROL_MASK) {
-	}
+	if (state & GDK_CONTROL_MASK) {
+
 	/* If ALT (or whatever) was held down... */
-	else if (event->state & GDK_MOD1_MASK) 	{
-	}
+	} else if (state & GDK_ALT_MASK) {
 
 	/* If neither CTRL nor ALT were held down... */
-	else {
-		switch (event->keyval) {
+	} else {
+		switch (keyval) {
 		case GDK_KEY_Tab:
 		case GDK_KEY_KP_Tab:
 		case GDK_KEY_ISO_Left_Tab:
-			if (gtkconv->entry != entry)
+			if (gtkconv->entry != entry) {
 				break;
+			}
 			{
 				gint plugin_return;
 				plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
 							pidgin_conversations_get_handle(), "chat-nick-autocomplete",
-							conv, event->state & GDK_SHIFT_MASK));
+							conv, state & GDK_SHIFT_MASK));
 				return plugin_return;
 			}
 			break;
 
-		case GDK_KEY_Page_Up:
-		case GDK_KEY_KP_Page_Up:
-			talkatu_scrolled_window_page_up(TALKATU_SCROLLED_WINDOW(gtkconv->history_sw));
-			return TRUE;
-			break;
-
-		case GDK_KEY_Page_Down:
-		case GDK_KEY_KP_Page_Down:
-			talkatu_scrolled_window_page_down(TALKATU_SCROLLED_WINDOW(gtkconv->history_sw));
-			return TRUE;
-			break;
-
 		case GDK_KEY_KP_Enter:
 		case GDK_KEY_Return:
 			send_cb(entry, gtkconv);
@@ -853,7 +825,7 @@
 	if (PURPLE_IS_IM_CONVERSATION(conv) &&
 			purple_prefs_get_bool("/purple/conversations/im/send_typing")) {
 
-		switch (event->keyval) {
+		switch (keyval) {
 		case GDK_KEY_BackSpace:
 		case GDK_KEY_Delete:
 		case GDK_KEY_KP_Delete:
@@ -867,6 +839,41 @@
 	return FALSE;
 }
 
+static gboolean
+is_valid_conversation_key(guint keyval, GdkModifierType state)
+{
+	if (state & GDK_CONTROL_MASK) {
+		return TRUE;
+	}
+
+	switch (keyval) {
+		case GDK_KEY_F6:
+		case GDK_KEY_F10:
+		case GDK_KEY_Menu:
+		case GDK_KEY_Shift_L:
+		case GDK_KEY_Shift_R:
+		case GDK_KEY_Control_L:
+		case GDK_KEY_Control_R:
+		case GDK_KEY_Escape:
+		case GDK_KEY_Up:
+		case GDK_KEY_Down:
+		case GDK_KEY_Left:
+		case GDK_KEY_Right:
+		case GDK_KEY_Page_Up:
+		case GDK_KEY_KP_Page_Up:
+		case GDK_KEY_Page_Down:
+		case GDK_KEY_KP_Page_Down:
+		case GDK_KEY_Home:
+		case GDK_KEY_End:
+		case GDK_KEY_Tab:
+		case GDK_KEY_KP_Tab:
+		case GDK_KEY_ISO_Left_Tab:
+			return TRUE;
+		default:
+			return FALSE;
+	}
+}
+
 /*
  * If someone tries to type into the conversation backlog of a
  * conversation window then we yank focus from the conversation backlog
@@ -874,43 +881,26 @@
  * all the live long day and it will get entered into the entry box.
  */
 static gboolean
-refocus_entry_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
+refocus_entry_cb(GtkEventControllerKey *controller, guint keyval,
+                 G_GNUC_UNUSED guint keycode, GdkModifierType state,
+                 gpointer data)
 {
+	PidginConversation *gtkconv = data;
 	GtkWidget *input = NULL;
-	PidginConversation *gtkconv = data;
+	GdkEvent *event = NULL;
 
 	/* If we have a valid key for the conversation display, then exit */
-	if ((event->state & GDK_CONTROL_MASK) ||
-		(event->keyval == GDK_KEY_F6) ||
-		(event->keyval == GDK_KEY_F10) ||
-		(event->keyval == GDK_KEY_Menu) ||
-		(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);
+	event = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(controller));
+	if (is_valid_conversation_key(keyval, state)) {
+		if (gdk_event_get_event_type(event) == GDK_KEY_PRESS) {
+			return conv_keypress_common(gtkconv, keyval, state);
+		}
 		return FALSE;
 	}
 
 	input = talkatu_editor_get_input(TALKATU_EDITOR(gtkconv->editor));
 	gtk_widget_grab_focus(input);
-	gtk_widget_event(input, (GdkEvent *)event);
+	gtk_event_controller_key_forward(controller, input);
 
 	return TRUE;
 }
@@ -1100,7 +1090,7 @@
 		return;
 
 	gtkconv = PIDGIN_CONVERSATION(conv);
-	new_topic = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtkconv->topic_text)));
+	new_topic = g_strdup(gtk_editable_get_text(GTK_EDITABLE(gtkconv->topic_text)));
 	current_topic = purple_chat_conversation_get_topic(PURPLE_CHAT_CONVERSATION(conv));
 
 	if(current_topic && !g_utf8_collate(new_topic, current_topic)){
@@ -1108,10 +1098,11 @@
 		return;
 	}
 
-	if (current_topic)
-		gtk_entry_set_text(GTK_ENTRY(gtkconv->topic_text), current_topic);
-	else
-		gtk_entry_set_text(GTK_ENTRY(gtkconv->topic_text), "");
+	if (current_topic) {
+		gtk_editable_set_text(GTK_EDITABLE(gtkconv->topic_text), current_topic);
+	} else {
+		gtk_editable_set_text(GTK_EDITABLE(gtkconv->topic_text), "");
+	}
 
 	purple_protocol_chat_set_topic(PURPLE_PROTOCOL_CHAT(protocol), gc, purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv)),
 			new_topic);
@@ -1340,12 +1331,13 @@
 	if (purple_protocol_get_options(protocol) & OPT_PROTO_CHAT_TOPIC)
 	{
 		GtkWidget *hbox, *label;
+		GtkEventController *key = NULL;
 
 		hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-		gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+		gtk_box_append(GTK_BOX(vbox), hbox);
 
 		label = gtk_label_new(_("Topic:"));
-		gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+		gtk_box_append(GTK_BOX(hbox), label);
 
 		gtkconv->topic_text = gtk_entry_new();
 		gtk_widget_set_size_request(gtkconv->topic_text, -1, BUDDYICON_SIZE_MIN);
@@ -1357,9 +1349,14 @@
 					G_CALLBACK(topic_callback), gtkconv);
 		}
 
-		gtk_box_pack_start(GTK_BOX(hbox), gtkconv->topic_text, TRUE, TRUE, 0);
-		g_signal_connect(G_OBJECT(gtkconv->topic_text), "key_press_event",
-			             G_CALLBACK(entry_key_press_cb), gtkconv);
+		gtk_widget_set_hexpand(gtkconv->topic_text, TRUE);
+		gtk_widget_set_halign(gtkconv->topic_text, GTK_ALIGN_FILL);
+		gtk_box_append(GTK_BOX(hbox), gtkconv->topic_text);
+
+		key = gtk_event_controller_key_new();
+		g_signal_connect(key, "key-pressed", G_CALLBACK(entry_key_press_cb),
+		                 gtkconv);
+		gtk_widget_add_controller(gtkconv->topic_text, key);
 	}
 }
 
@@ -1432,7 +1429,8 @@
 static void
 setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned)
 {
-	GtkWidget *lbox, *list;
+	GtkWidget *lbox, *list, *sw;
+	GtkGesture *click = NULL;
 	GtkListStore *ls;
 	GtkCellRenderer *rend;
 	GtkTreeViewColumn *col;
@@ -1441,14 +1439,14 @@
 
 	/* Build the right pane. */
 	lbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-	gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE);
-	gtk_widget_show(lbox);
+	gtk_paned_set_end_child(GTK_PANED(hpaned), lbox);
+	gtk_paned_set_resize_end_child(GTK_PANED(hpaned), FALSE);
+	gtk_paned_set_shrink_end_child(GTK_PANED(hpaned), TRUE);
 
 	/* Setup the label telling how many people are in the room. */
 	gtkconv->count = gtk_label_new(_("0 people in room"));
 	gtk_label_set_ellipsize(GTK_LABEL(gtkconv->count), PANGO_ELLIPSIZE_END);
-	gtk_box_pack_start(GTK_BOX(lbox), gtkconv->count, FALSE, FALSE, 0);
-	gtk_widget_show(gtkconv->count);
+	gtk_box_append(GTK_BOX(lbox), gtkconv->count);
 
 	/* Setup the list of users. */
 
@@ -1469,12 +1467,13 @@
 	gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
 	gtk_tree_view_append_column(GTK_TREE_VIEW(list), col);
 
-	g_signal_connect(G_OBJECT(list), "button_press_event",
-					 G_CALLBACK(right_click_chat_cb), gtkconv);
+	click = gtk_gesture_click_new();
+	gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(click), 0);
+	g_signal_connect(click, "pressed", G_CALLBACK(right_click_chat_cb), gtkconv);
+	gtk_widget_add_controller(list, GTK_EVENT_CONTROLLER(click));
+
 	g_signal_connect(G_OBJECT(list), "row-activated",
 					 G_CALLBACK(activate_list_cb), gtkconv);
-	g_signal_connect(G_OBJECT(list), "popup-menu",
-			 G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv);
 
 	gtk_widget_set_has_tooltip(list, TRUE);
 	g_signal_connect(list, "query-tooltip",
@@ -1507,69 +1506,73 @@
 	gtk_tree_view_append_column(GTK_TREE_VIEW(list), col);
 
 	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE);
-	gtk_widget_show(list);
 
 	gtkconv->list = list;
 
-	gtk_box_pack_start(GTK_BOX(lbox),
-		pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1),
-		TRUE, TRUE, 0);
+	sw = gtk_scrolled_window_new();
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+	                               GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), list);
+
+	gtk_widget_set_vexpand(sw, TRUE);
+	gtk_widget_set_valign(sw, GTK_ALIGN_FILL);
+	gtk_box_append(GTK_BOX(lbox), sw);
 }
 
 static GtkWidget *
 setup_common_pane(PidginConversation *gtkconv)
 {
-	GtkWidget *vbox, *input, *hpaned;
+	GtkWidget *vbox, *input, *hpaned, *sw;
+	GtkEventController *key = NULL;
 	PurpleConversation *conv = gtkconv->active_conv;
 
 	/* Setup the top part of the pane */
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-	gtk_widget_show(vbox);
 
 	/* Setup the info pane */
 	gtkconv->infopane = pidgin_info_pane_new(conv);
-	gtk_box_pack_start(GTK_BOX(vbox), gtkconv->infopane, FALSE, FALSE, 0);
-	gtk_widget_show(gtkconv->infopane);
+	gtk_widget_set_vexpand(gtkconv->infopane, FALSE);
+	gtk_box_append(GTK_BOX(vbox), gtkconv->infopane);
 
 	/* Setup the history widget */
-	gtkconv->history_sw = talkatu_scrolled_window_new(NULL, NULL);
-	gtk_scrolled_window_set_shadow_type(
-		GTK_SCROLLED_WINDOW(gtkconv->history_sw),
-		GTK_SHADOW_IN
-	);
-	gtk_scrolled_window_set_policy(
-		GTK_SCROLLED_WINDOW(gtkconv->history_sw),
-		GTK_POLICY_NEVER,
-		GTK_POLICY_ALWAYS
-	);
+	sw = gtk_scrolled_window_new();
+	gtkconv->vadjustment = talkatu_auto_scroller_new();
+	gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(sw),
+	                                    gtkconv->vadjustment);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER,
+	                               GTK_POLICY_ALWAYS);
 
 	gtkconv->history = talkatu_history_new();
-	gtk_container_add(GTK_CONTAINER(gtkconv->history_sw), gtkconv->history);
+	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), gtkconv->history);
 
 	/* Add the topic */
 	setup_chat_topic(gtkconv, vbox);
 
 	/* Add the talkatu history */
 	hpaned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
-	gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0);
-	gtk_widget_show(hpaned);
-	gtk_paned_pack1(GTK_PANED(hpaned), gtkconv->history_sw, TRUE, TRUE);
+	gtk_widget_set_vexpand(hpaned, TRUE);
+	gtk_widget_set_valign(hpaned, GTK_ALIGN_FILL);
+	gtk_box_append(GTK_BOX(vbox), hpaned);
+	gtk_paned_set_start_child(GTK_PANED(hpaned), sw);
+	gtk_paned_set_resize_start_child(GTK_PANED(hpaned), TRUE);
+	gtk_paned_set_shrink_start_child(GTK_PANED(hpaned), TRUE);
 
 	/* Now add the userlist */
 	setup_chat_userlist(gtkconv, hpaned);
-	gtk_widget_show_all(gtkconv->history_sw);
 
 	g_object_set_data(G_OBJECT(gtkconv->history), "gtkconv", gtkconv);
 
-	g_signal_connect(G_OBJECT(gtkconv->history), "key_press_event",
-	                 G_CALLBACK(refocus_entry_cb), gtkconv);
-	g_signal_connect(G_OBJECT(gtkconv->history), "key_release_event",
-	                 G_CALLBACK(refocus_entry_cb), gtkconv);
+	key = gtk_event_controller_key_new();
+	g_signal_connect(key, "key-pressed", G_CALLBACK(refocus_entry_cb),
+	                 gtkconv);
+	g_signal_connect(key, "key-released", G_CALLBACK(refocus_entry_cb),
+	                 gtkconv);
+	gtk_widget_add_controller(gtkconv->history, key);
 
 	/* Setup the entry widget and all signals */
 	gtkconv->editor = talkatu_editor_new();
 	talkatu_editor_set_buffer(TALKATU_EDITOR(gtkconv->editor), talkatu_html_buffer_new());
-	gtk_box_pack_start(GTK_BOX(vbox), gtkconv->editor, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(vbox), gtkconv->editor);
 
 	input = talkatu_editor_get_input(TALKATU_EDITOR(gtkconv->editor));
 	gtk_widget_set_name(input, "pidgin_conv_entry");
@@ -1617,14 +1620,17 @@
 }
 
 static gboolean
-ignore_middle_click(GtkWidget *widget, GdkEventButton *e, gpointer null)
+ignore_middle_click(G_GNUC_UNUSED GtkGestureClick *click,
+                    gint n_press, G_GNUC_UNUSED gdouble x,
+                    G_GNUC_UNUSED gdouble y, G_GNUC_UNUSED gpointer data)
 {
 	/* A click on the pane is propagated to the notebook containing the pane.
 	 * So if Stu accidentally aims high and middle clicks on the pane-handle,
 	 * it causes a conversation tab to close. Let's stop that from happening.
 	 */
-	if (e->button == GDK_BUTTON_MIDDLE && e->type == GDK_BUTTON_PRESS)
+	if (n_press == 1) {
 		return TRUE;
+	}
 	return FALSE;
 }
 
@@ -1636,6 +1642,7 @@
 {
 	PidginConversation *gtkconv;
 	GtkWidget *tab_cont, *pane;
+	GtkGesture *click = NULL;
 
 	if (PURPLE_IS_IM_CONVERSATION(conv) && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
 		purple_debug_misc("gtkconv", "found existing gtkconv %p", gtkconv);
@@ -1661,25 +1668,23 @@
 		return;
 	}
 
-	g_signal_connect(G_OBJECT(pane), "button_press_event",
-	                 G_CALLBACK(ignore_middle_click), NULL);
+	click = gtk_gesture_click_new();
+	gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(click), GDK_BUTTON_MIDDLE);
+	g_signal_connect(click, "pressed", G_CALLBACK(ignore_middle_click), NULL);
+	gtk_widget_add_controller(pane, GTK_EVENT_CONTROLLER(click));
 
 	/* Setup the container for the tab. */
 	gtkconv->tab_cont = tab_cont = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
 	g_object_set_data(G_OBJECT(tab_cont), "PidginConversation", gtkconv);
-	gtk_container_set_border_width(GTK_CONTAINER(tab_cont), 6);
-	gtk_box_pack_start(GTK_BOX(tab_cont), pane, TRUE, TRUE, 0);
-	gtk_widget_show(pane);
+	gtk_widget_set_vexpand(pane, TRUE);
+	gtk_widget_set_valign(pane, GTK_ALIGN_FILL);
+	gtk_box_append(GTK_BOX(tab_cont), pane);
 
 	talkatu_editor_set_toolbar_visible(
 		TALKATU_EDITOR(gtkconv->editor),
 		purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")
 	);
 
-	g_signal_connect_swapped(G_OBJECT(pane), "focus",
-	                         G_CALLBACK(gtk_widget_grab_focus),
-	                         gtkconv->editor);
-
 	pidgin_conv_placement_place(gtkconv);
 }
 
@@ -1730,7 +1735,7 @@
 pidgin_conv_destroy(PurpleConversation *conv)
 {
 	PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
-	GtkWidget *win;
+	GtkRoot *win = NULL;
 
 	gtkconv->convs = g_list_remove(gtkconv->convs, conv);
 	/* Don't destroy ourselves until all our convos are gone */
@@ -1743,14 +1748,14 @@
 		return;
 	}
 
-	win = gtk_widget_get_toplevel(gtkconv->tab_cont);
+	win = gtk_widget_get_root(gtkconv->tab_cont);
 	pidgin_conversation_window_remove(PIDGIN_CONVERSATION_WINDOW(win), conv);
 
 	/* If the "Save Conversation" or "Save Icon" dialogs are open then close them */
 	purple_request_close_with_handle(gtkconv);
 	purple_notify_close_with_handle(gtkconv);
 
-	gtk_widget_destroy(gtkconv->tab_cont);
+	gtk_widget_unparent(gtkconv->tab_cont);
 
 	if (PURPLE_IS_IM_CONVERSATION(conv)) {
 		if (gtkconv->typing_timer != 0)
@@ -1759,6 +1764,8 @@
 		purple_signals_disconnect_by_handle(gtkconv);
 	}
 
+	g_clear_object(&gtkconv->vadjustment);
+
 	gtkconv->send_history = g_list_first(gtkconv->send_history);
 	g_list_free_full(gtkconv->send_history, g_free);
 
@@ -2005,10 +2012,10 @@
 pidgin_conv_has_focus(PurpleConversation *conv)
 {
 	PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
-	GtkWidget *win;
-
-	win = gtk_widget_get_toplevel(gtkconv->tab_cont);
-	if(gtk_window_has_toplevel_focus(GTK_WINDOW(win))) {
+	GtkRoot *win;
+
+	win = gtk_widget_get_root(gtkconv->tab_cont);
+	if(gtk_window_is_active(GTK_WINDOW(win))) {
 		PidginConversationWindow *convwin = PIDGIN_CONVERSATION_WINDOW(win);
 
 		if(pidgin_conversation_window_conversation_is_selected(convwin, conv)) {
@@ -2024,13 +2031,13 @@
 {
 	PidginConversation *gtkconv;
 	PidginConversationWindow *convwin;
-	GtkWidget *win;
+	GtkRoot *win;
 
 	gtkconv = PIDGIN_CONVERSATION(conv);
 	if (!gtkconv)
 		return;
 
-	win = gtk_widget_get_toplevel(gtkconv->tab_cont);
+	win = gtk_widget_get_root(gtkconv->tab_cont);
 	convwin = PIDGIN_CONVERSATION_WINDOW(win);
 
 	if (fields & PIDGIN_CONV_SET_TITLE)
@@ -2047,7 +2054,7 @@
 		{
 			topic = purple_chat_conversation_get_topic(PURPLE_CHAT_CONVERSATION(conv));
 
-			gtk_entry_set_text(GTK_ENTRY(gtkconv->topic_text), topic ? topic : "");
+			gtk_editable_set_text(GTK_EDITABLE(gtkconv->topic_text), topic ? topic : "");
 			gtk_widget_set_tooltip_text(gtkconv->topic_text,
 			                            topic ? topic : "");
 		}
@@ -2079,7 +2086,7 @@
 			}
 		} else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
 			const char *topic = gtkconv->topic_text
-				? gtk_entry_get_text(GTK_ENTRY(gtkconv->topic_text))
+				? gtk_editable_get_text(GTK_EDITABLE(gtkconv->topic_text))
 				: NULL;
 			const char *title = purple_conversation_get_title(conv);
 			const char *name = purple_conversation_get_name(conv);
--- a/pidgin/gtkconv.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkconv.h	Sun Aug 28 22:18:46 2022 -0500
@@ -67,7 +67,7 @@
 	GtkWidget *tab_cont;
 
 	PurpleMessageFlags last_flags;
-	GtkWidget *history_sw;
+	GtkAdjustment *vadjustment;
 	GtkWidget *history;
 
 	GtkWidget *editor;
--- a/pidgin/gtkdialogs.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkdialogs.c	Sun Aug 28 22:18:46 2022 -0500
@@ -42,20 +42,11 @@
 #include "pidgincore.h"
 #include "pidgindialog.h"
 
-static GList *dialogwindows = NULL;
-
 struct _PidginGroupMergeObject {
 	PurpleGroup* parent;
 	char *new_name;
 };
 
-void
-pidgin_dialogs_destroy_all()
-{
-	g_list_free_full(dialogwindows, (GDestroyNotify)gtk_widget_destroy);
-	dialogwindows = NULL;
-}
-
 static void
 pidgin_dialogs_im_cb(gpointer data, PurpleRequestFields *fields)
 {
@@ -146,93 +137,23 @@
 	purple_conversation_present(im);
 }
 
-static gboolean
-pidgin_dialogs_ee(const char *ee)
-{
-	GtkWidget *window;
-	GtkWidget *hbox;
-	GtkWidget *label;
-	GtkWidget *img;
-	gchar *norm = purple_strreplace(ee, "rocksmyworld", "");
-
-	label = gtk_label_new(NULL);
-	if (purple_strequal(norm, "zilding"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				     "<span weight=\"bold\" size=\"large\" foreground=\"purple\">Amazing!  Simply Amazing!</span>");
-	else if (purple_strequal(norm, "robflynn"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				     "<span weight=\"bold\" size=\"large\" foreground=\"#1f6bad\">Pimpin\' Penguin Style! *Waddle Waddle*</span>");
-	else if (purple_strequal(norm, "flynorange"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				      "<span weight=\"bold\" size=\"large\" foreground=\"blue\">You should be me.  I'm so cute!</span>");
-	else if (purple_strequal(norm, "ewarmenhoven"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				     "<span weight=\"bold\" size=\"large\" foreground=\"orange\">Now that's what I like!</span>");
-	else if (purple_strequal(norm, "markster97"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				     "<span weight=\"bold\" size=\"large\" foreground=\"brown\">Ahh, and excellent choice!</span>");
-	else if (purple_strequal(norm, "seanegn"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				     "<span weight=\"bold\" size=\"large\" foreground=\"#009900\">Every time you click my name, an angel gets its wings.</span>");
-	else if (purple_strequal(norm, "chipx86"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				     "<span weight=\"bold\" size=\"large\" foreground=\"red\">This sunflower seed taste like pizza.</span>");
-	else if (purple_strequal(norm, "markdoliner"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				     "<span weight=\"bold\" size=\"large\" foreground=\"#6364B1\">Hey!  I was in that tumbleweed!</span>");
-	else if (purple_strequal(norm, "lschiere"))
-		gtk_label_set_markup(GTK_LABEL(label),
-				     "<span weight=\"bold\" size=\"large\" foreground=\"gray\">I'm not anything.</span>");
-	g_free(norm);
-
-	if (strlen(gtk_label_get_label(GTK_LABEL(label))) <= 0)
-		return FALSE;
-
-	window = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, NULL, 0,
-			_("_Close"), GTK_RESPONSE_OK, NULL);
-	gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_OK);
-	g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), NULL);
-
-	gtk_container_set_border_width (GTK_CONTAINER(window), 6);
-	gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
-	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
-	                    12);
-	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))),
-	                               6);
-
-	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))), hbox);
-	img = gtk_image_new_from_icon_name("dialog-cool", GTK_ICON_SIZE_DIALOG);
-	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
-
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
-	gtk_label_set_xalign(GTK_LABEL(label), 0);
-	gtk_label_set_yalign(GTK_LABEL(label), 0);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
-	gtk_widget_show_all(window);
-	return TRUE;
-}
-
 static void
 pidgin_dialogs_info_cb(gpointer data, PurpleRequestFields *fields)
 {
 	char *username;
-	gboolean found = FALSE;
 	PurpleAccount *account;
+	const gchar *screenname = NULL;
 
-	account  = purple_request_fields_get_account(fields, "account");
+	account = purple_request_fields_get_account(fields, "account");
 
-	username = g_strdup(purple_normalize(account,
-		purple_request_fields_get_string(fields,  "screenname")));
+	screenname = purple_request_fields_get_string(fields,  "screenname");
+	username = g_strdup(purple_normalize(account, screenname));
 
-	if (username != NULL && g_str_has_suffix(username, "rocksmyworld")) {
-		found = pidgin_dialogs_ee(username);
+	if(username != NULL && *username != '\0' && account != NULL) {
+		pidgin_retrieve_user_info(purple_account_get_connection(account),
+		                          username);
 	}
 
-	if (!found && username != NULL && *username != '\0' && account != NULL)
-		pidgin_retrieve_user_info(purple_account_get_connection(account), username);
-
 	g_free(username);
 }
 
--- a/pidgin/gtkdialogs.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkdialogs.h	Sun Aug 28 22:18:46 2022 -0500
@@ -30,9 +30,6 @@
 
 G_BEGIN_DECLS
 
-/* Functions in gtkdialogs.c (these should actually stay in this file) */
-void pidgin_dialogs_destroy_all(void);
-
 void pidgin_dialogs_im(void);
 void pidgin_dialogs_im_with_user(PurpleAccount *account, const char *username);
 void pidgin_dialogs_info(void);
--- a/pidgin/gtkmedia.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkmedia.c	Sun Aug 28 22:18:46 2022 -0500
@@ -116,12 +116,14 @@
 };
 
 static gboolean
-pidgin_media_delete_event_cb(GtkWidget *widget,
-		GdkEvent *event, PidginMedia *media)
-{
-	if (media->priv->media)
+pidgin_media_close_request_cb(GtkWindow *window, gpointer data) {
+	PidginMedia *media = data;
+
+	if(media->priv->media) {
 		g_action_group_activate_action(G_ACTION_GROUP(media),
 				"Hangup", NULL);
+	}
+
 	return FALSE;
 }
 
@@ -160,7 +162,7 @@
 	                                             statusbar);
 
 	gtk_widget_class_bind_template_callback(widget_class,
-	                                        pidgin_media_delete_event_cb);
+	                                        pidgin_media_close_request_cb);
 
 }
 
@@ -291,7 +293,6 @@
 		PurpleMediaSessionType type =
 				purple_media_get_session_type(gtkmedia->priv->media, session_id);
 		gchar *key = create_key(session_id, participant);
-		GtkRequisition req;
 
 		if (type & PURPLE_MEDIA_AUDIO) {
 			g_hash_table_remove(gtkmedia->priv->recv_progressbars, key);
@@ -299,10 +300,10 @@
 			if (g_hash_table_size(gtkmedia->priv->recv_progressbars) == 0 &&
 				gtkmedia->priv->send_progress) {
 
-				gtk_widget_destroy(gtkmedia->priv->send_progress);
+				gtk_widget_unparent(gtkmedia->priv->send_progress);
 				gtkmedia->priv->send_progress = NULL;
 
-				gtk_widget_destroy(gtkmedia->priv->mute);
+				gtk_widget_unparent(gtkmedia->priv->mute);
 				gtkmedia->priv->mute = NULL;
 			}
 		} else if (type & PURPLE_MEDIA_VIDEO) {
@@ -311,20 +312,17 @@
 			if (g_hash_table_size(gtkmedia->priv->remote_videos) == 0 &&
 				gtkmedia->priv->local_video) {
 
-				gtk_widget_destroy(gtkmedia->priv->local_video);
+				gtk_widget_unparent(gtkmedia->priv->local_video);
 				gtkmedia->priv->local_video = NULL;
 
-				gtk_widget_destroy(gtkmedia->priv->pause);
+				gtk_widget_unparent(gtkmedia->priv->pause);
 				gtkmedia->priv->pause = NULL;
 			}
 		}
 
 		g_free(key);
 
-		gtk_widget_destroy(widget);
-
-		gtk_widget_get_preferred_size(GTK_WIDGET(gtkmedia), NULL, &req);
-		gtk_window_resize(GTK_WINDOW(gtkmedia), req.width, req.height);
+		gtk_widget_unparent(widget);
 	}
 }
 
@@ -529,7 +527,7 @@
 {
 	g_return_if_fail(GTK_IS_WIDGET(parent));
 
-	gtk_widget_destroy(parent);
+	gtk_widget_unparent(parent);
 }
 
 static GtkWidget *
@@ -559,19 +557,20 @@
 	/* Setup widget structure */
 	volume_widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
 	progress_parent = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-	gtk_box_pack_start(GTK_BOX(volume_widget),
-			progress_parent, TRUE, TRUE, 0);
+	gtk_widget_set_hexpand(progress_parent, TRUE);
+	gtk_widget_set_halign(progress_parent, GTK_ALIGN_FILL);
+	gtk_box_append(GTK_BOX(volume_widget), progress_parent);
 
 	/* Volume button */
 	volume = gtk_volume_button_new();
 	gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume), value/100.0);
-	gtk_box_pack_end(GTK_BOX(volume_widget),
-			volume, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(volume_widget), volume);
 
 	/* Volume level indicator */
 	progress = gtk_progress_bar_new();
 	gtk_widget_set_size_request(progress, 250, 10);
-	gtk_box_pack_end(GTK_BOX(progress_parent), progress, TRUE, FALSE, 0);
+	gtk_widget_set_vexpand(progress, TRUE);
+	gtk_box_append(GTK_BOX(progress_parent), progress);
 
 	if (type & PURPLE_MEDIA_SEND_AUDIO) {
 		g_signal_connect (G_OBJECT(volume), "value-changed",
@@ -593,8 +592,6 @@
 			G_CALLBACK(destroy_parent_widget_cb),
 			volume_widget);
 
-	gtk_widget_show_all(volume_widget);
-
 	return volume_widget;
 }
 
@@ -625,8 +622,6 @@
 	g_object_set_data_full(G_OBJECT(win), "session-id",
 		g_strdup(_sid), g_free);
 
-	gtk_widget_show_all(keypad);
-
 	return keypad;
 }
 
@@ -641,9 +636,11 @@
 			&& type & (PURPLE_MEDIA_RECV_VIDEO |
 			PURPLE_MEDIA_RECV_AUDIO)) {
 		recv_widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-		gtk_box_pack_start(GTK_BOX(gtkmedia->priv->display),
-				recv_widget, TRUE, TRUE, 0);
-		gtk_widget_show(recv_widget);
+		gtk_widget_set_hexpand(recv_widget, TRUE);
+		gtk_widget_set_halign(recv_widget, GTK_ALIGN_FILL);
+		gtk_widget_set_vexpand(recv_widget, TRUE);
+		gtk_widget_set_valign(recv_widget, GTK_ALIGN_FILL);
+		gtk_box_append(GTK_BOX(gtkmedia->priv->display), recv_widget);
 	} else {
 		recv_widget = gtkmedia->priv->recv_widget;
 	}
@@ -651,19 +648,18 @@
 			&& type & (PURPLE_MEDIA_SEND_VIDEO |
 			PURPLE_MEDIA_SEND_AUDIO)) {
 		send_widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-		gtk_box_pack_start(GTK_BOX(gtkmedia->priv->display),
-				send_widget, FALSE, TRUE, 0);
+		gtk_widget_set_halign(send_widget, GTK_ALIGN_FILL);
+		gtk_widget_set_valign(send_widget, GTK_ALIGN_FILL);
+		gtk_box_prepend(GTK_BOX(gtkmedia->priv->display), send_widget);
+
 		button_widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-		gtk_box_pack_end(GTK_BOX(recv_widget), button_widget,
-				FALSE, TRUE, 0);
-		gtk_widget_show(send_widget);
+		gtk_widget_set_valign(button_widget, GTK_ALIGN_FILL);
+		gtk_box_append(GTK_BOX(send_widget), button_widget);
 
 		/* Hold button */
 		gtkmedia->priv->hold =
 				gtk_toggle_button_new_with_mnemonic(_("_Hold"));
-		gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->hold,
-				FALSE, FALSE, 0);
-		gtk_widget_show(gtkmedia->priv->hold);
+		gtk_box_prepend(GTK_BOX(button_widget), gtkmedia->priv->hold);
 		gtk_actionable_set_action_name(
 				GTK_ACTIONABLE(gtkmedia->priv->hold),
 				"win.Hold");
@@ -688,7 +684,9 @@
 		}
 		g_object_get(G_OBJECT(sink), "widget", &remote_video, NULL);
 		gtk_widget_show(remote_video);
-		gtk_box_pack_start(GTK_BOX(recv_widget), remote_video, TRUE, TRUE, 0);
+		gtk_widget_set_valign(remote_video, GTK_ALIGN_FILL);
+		gtk_widget_set_vexpand(remote_video, TRUE);
+		gtk_box_append(GTK_BOX(recv_widget), remote_video);
 
 		pidgin_media_insert_widget(gtkmedia, remote_video, sid, priv->screenname);
 	}
@@ -709,13 +707,13 @@
 		}
 		g_object_get(G_OBJECT(sink), "widget", &local_video, NULL);
 		gtk_widget_show(local_video);
-		gtk_box_pack_start(GTK_BOX(send_widget), local_video, TRUE, TRUE, 0);
+		gtk_widget_set_valign(local_video, GTK_ALIGN_FILL);
+		gtk_widget_set_vexpand(local_video, TRUE);
+		gtk_box_append(GTK_BOX(send_widget), local_video);
 
 		gtkmedia->priv->pause =
 				gtk_toggle_button_new_with_mnemonic(_("_Pause"));
-		gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->pause,
-				FALSE, FALSE, 0);
-		gtk_widget_show(gtkmedia->priv->pause);
+		gtk_box_prepend(GTK_BOX(button_widget), gtkmedia->priv->pause);
 		gtk_actionable_set_action_name(
 				GTK_ACTIONABLE(gtkmedia->priv->pause),
 				"win.Pause");
@@ -723,28 +721,28 @@
 		gtkmedia->priv->local_video = local_video;
 	}
 	if (type & PURPLE_MEDIA_RECV_AUDIO) {
-		gtk_box_pack_end(GTK_BOX(recv_widget),
-				pidgin_media_add_audio_widget(gtkmedia,
-				PURPLE_MEDIA_RECV_AUDIO, sid), FALSE, FALSE, 0);
+		GtkWidget *audio = NULL;
+
+		audio = pidgin_media_add_audio_widget(gtkmedia, PURPLE_MEDIA_RECV_AUDIO,
+		                                      sid);
+		gtk_box_prepend(GTK_BOX(recv_widget), audio);
 	}
 
 	if (type & PURPLE_MEDIA_SEND_AUDIO) {
 		gtkmedia->priv->mute =
 				gtk_toggle_button_new_with_mnemonic(_("_Mute"));
-		gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->mute,
-				FALSE, FALSE, 0);
-		gtk_widget_show(gtkmedia->priv->mute);
+		gtk_box_prepend(GTK_BOX(button_widget), gtkmedia->priv->mute);
 		gtk_actionable_set_action_name(
 				GTK_ACTIONABLE(gtkmedia->priv->mute),
 				"win.Mute");
 
-		gtk_box_pack_end(GTK_BOX(recv_widget),
+		gtk_box_prepend(GTK_BOX(recv_widget),
 				pidgin_media_add_audio_widget(gtkmedia,
-				PURPLE_MEDIA_SEND_AUDIO, sid), FALSE, FALSE, 0);
+				PURPLE_MEDIA_SEND_AUDIO, sid));
 
-		gtk_box_pack_end(GTK_BOX(recv_widget),
+		gtk_box_prepend(GTK_BOX(recv_widget),
 				pidgin_media_add_dtmf_widget(gtkmedia,
-				PURPLE_MEDIA_SEND_AUDIO, sid), FALSE, FALSE, 0);
+				PURPLE_MEDIA_SEND_AUDIO, sid));
 	}
 
 	if (type & PURPLE_MEDIA_AUDIO &&
@@ -754,13 +752,14 @@
 				gtkmedia);
 	}
 
-	if (send_widget != NULL)
+	if (send_widget != NULL) {
 		gtkmedia->priv->send_widget = send_widget;
-	if (recv_widget != NULL)
+	}
+	if (recv_widget != NULL) {
 		gtkmedia->priv->recv_widget = recv_widget;
+	}
 	if (button_widget != NULL) {
 		gtkmedia->priv->button_widget = button_widget;
-		gtk_widget_show(GTK_WIDGET(button_widget));
 	}
 
 	if (purple_media_is_initiator(media, sid, NULL) == FALSE) {
@@ -778,8 +777,6 @@
 	} else if (type & PURPLE_MEDIA_AUDIO) {
 		gtk_window_set_icon_name(GTK_WINDOW(gtkmedia), "audio-call");
 	}
-
-	gtk_widget_show(gtkmedia->priv->display);
 }
 
 static void
@@ -794,7 +791,7 @@
 		} else if (sid == NULL && name == NULL) {
 			pidgin_media_emit_message(gtkmedia,
 					_("The call has been terminated."));
-			gtk_widget_destroy(GTK_WIDGET(gtkmedia));
+			gtk_window_destroy(GTK_WINDOW(gtkmedia));
 		}
 	} else if (state == PURPLE_MEDIA_STATE_NEW &&
 			sid != NULL && name != NULL) {
@@ -910,8 +907,8 @@
 			purple_buddy_get_contact_alias(buddy) : screenname;
 	gtk_window_set_title(GTK_WINDOW(gtkmedia), alias);
 
-	if (purple_media_is_initiator(media, NULL, NULL) == TRUE)
-		gtk_widget_show(GTK_WIDGET(gtkmedia));
+	gtk_widget_set_visible(GTK_WIDGET(gtkmedia),
+	                       purple_media_is_initiator(media, NULL, NULL));
 
 	return TRUE;
 }
--- a/pidgin/gtknotify.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtknotify.c	Sun Aug 28 22:18:46 2022 -0500
@@ -111,15 +111,17 @@
 static void
 pidgin_widget_decorate_account(GtkWidget *cont, PurpleAccount *account)
 {
+	PurpleProtocol *protocol = NULL;
 	GtkWidget *image;
-	GdkPixbuf *pixbuf;
+	const gchar *icon_name = NULL;
 
 	if (!account)
 		return;
 
-	pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
-	image = gtk_image_new_from_pixbuf(pixbuf);
-	g_object_unref(G_OBJECT(pixbuf));
+	protocol = purple_account_get_protocol(account);
+	icon_name = purple_protocol_get_icon_name(protocol);
+
+	image = gtk_image_new_from_icon_name(icon_name);
 
 	gtk_widget_set_tooltip_text(image,
 		purple_account_get_username(account));
@@ -127,9 +129,9 @@
 	if (GTK_IS_BOX(cont)) {
 		gtk_widget_set_halign(image, GTK_ALIGN_START);
 		gtk_widget_set_valign(image, GTK_ALIGN_START);
-		gtk_box_pack_end(GTK_BOX(cont), image, FALSE, TRUE, 0);
+		gtk_widget_set_hexpand(image, TRUE);
+		gtk_box_append(GTK_BOX(cont), image);
 	}
-	gtk_widget_show(image);
 }
 
 static void *
@@ -166,8 +168,8 @@
 
 	if (icon_name != NULL)
 	{
-		img = gtk_image_new_from_icon_name(icon_name,
-				GTK_ICON_SIZE_DIALOG);
+		img = gtk_image_new_from_icon_name(icon_name);
+		gtk_image_set_pixel_size(GTK_IMAGE(img), 48);
 		gtk_widget_set_halign(img, GTK_ALIGN_START);
 		gtk_widget_set_valign(img, GTK_ALIGN_START);
 	}
@@ -176,27 +178,20 @@
 										 NULL, 0, _("Close"),
 										 GTK_RESPONSE_CLOSE, NULL);
 
-	gtk_window_set_role(GTK_WINDOW(dialog), "notify_dialog");
-
 	g_signal_connect(G_OBJECT(dialog), "response",
 					 G_CALLBACK(message_response_cb), dialog);
 
-	gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
 	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
 	                    12);
-	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                               6);
 
 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                  hbox);
+	gtk_box_append(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+	               hbox);
 
-	if (img != NULL)
-		gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
-
-	pidgin_widget_decorate_account(hbox,
-		purple_request_cpar_get_account(cpar));
+	if (img != NULL) {
+		gtk_box_append(GTK_BOX(hbox), img);
+	}
 
 	primary_esc = g_markup_escape_text(primary, -1);
 	secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL;
@@ -210,26 +205,29 @@
 	label = gtk_label_new(NULL);
 
 	gtk_label_set_markup(GTK_LABEL(label), label_text);
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 	gtk_label_set_selectable(GTK_LABEL(label), TRUE);
 	gtk_label_set_xalign(GTK_LABEL(label), 0);
 	gtk_label_set_yalign(GTK_LABEL(label), 0);
-	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(hbox), label);
+
+	pidgin_widget_decorate_account(hbox,
+		purple_request_cpar_get_account(cpar));
 
 	g_object_set_data(G_OBJECT(dialog), "pidgin-parent-from",
 		purple_request_cpar_get_parent_from(cpar));
 	pidgin_auto_parent_window(dialog);
 
-	gtk_widget_show_all(dialog);
+	gtk_widget_show(dialog);
 
 	return dialog;
 }
 
 static gboolean
-formatted_input_cb(GtkWidget *win, GdkEventKey *event, gpointer data)
+formatted_input_cb(GtkWidget *win, guint keyval, G_GNUC_UNUSED guint keycode,
+                   G_GNUC_UNUSED GdkModifierType state, gpointer data)
 {
-	if (event->keyval == GDK_KEY_Escape)
-	{
+	if (keyval == GDK_KEY_Escape) {
 		purple_notify_close(PURPLE_NOTIFY_FORMATTED, win);
 
 		return TRUE;
@@ -246,6 +244,7 @@
 	GtkWidget *vbox;
 	GtkWidget *label;
 	GtkWidget *button;
+	GtkEventController *event = NULL;
 	GtkWidget *sw;
 	GtkWidget *view;
 	GtkTextBuffer *buffer;
@@ -276,32 +275,34 @@
 	label = gtk_label_new(NULL);
 
 	gtk_label_set_markup(GTK_LABEL(label), label_text);
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 	gtk_label_set_selectable(GTK_LABEL(label), TRUE);
 	gtk_label_set_xalign(GTK_LABEL(label), 0);
 	gtk_label_set_yalign(GTK_LABEL(label), 0);
-	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-	gtk_widget_show(label);
+	gtk_box_append(GTK_BOX(vbox), label);
 
 	/* Add the view */
-	sw = gtk_scrolled_window_new(NULL, NULL);
-	gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
+	sw = gtk_scrolled_window_new();
+	gtk_box_append(GTK_BOX(vbox), sw);
+	gtk_widget_set_valign(sw, GTK_ALIGN_FILL);
+	gtk_widget_set_vexpand(sw, TRUE);
 
 	buffer = talkatu_html_buffer_new();
 	view = talkatu_view_new_with_buffer(buffer);
-	gtk_container_add(GTK_CONTAINER(sw), view);
+	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view);
 	gtk_widget_set_name(view, "pidgin_notify_view");
 	gtk_widget_set_size_request(view, 300, 250);
-	gtk_widget_show_all(sw);
 
 	/* Add the Close button. */
 	button = gtk_dialog_add_button(GTK_DIALOG(window), _("Close"), GTK_RESPONSE_CLOSE);
 	gtk_widget_grab_focus(button);
 
 	g_signal_connect_swapped(G_OBJECT(button), "clicked",
-							 G_CALLBACK(formatted_close_cb), window);
-	g_signal_connect(G_OBJECT(window), "key_press_event",
-					 G_CALLBACK(formatted_input_cb), NULL);
+	                         G_CALLBACK(formatted_close_cb), window);
+	event = gtk_event_controller_key_new();
+	gtk_widget_add_controller(window, event);
+	g_signal_connect(G_OBJECT(event), "key-pressed",
+	                 G_CALLBACK(formatted_input_cb), NULL);
 
 	/* Make sure URLs are clickable */
 	linked_text = purple_markup_linkify(text);
@@ -323,20 +324,22 @@
 									   void *data_)
 {
 	PidginNotifySearchResultsData *data = data_;
+	PurpleProtocol *protocol = NULL;
 	GtkListStore *model = data->model;
 	GtkTreeIter iter;
-	GdkPixbuf *pixbuf;
 	GList *row, *column;
 	guint n;
+	const gchar *icon_name = NULL;
 
 	gtk_list_store_clear(data->model);
 
-	pixbuf = pidgin_create_protocol_icon(purple_connection_get_account(gc), PIDGIN_PROTOCOL_ICON_SMALL);
+	protocol = purple_account_get_protocol(purple_connection_get_account(gc));
+	icon_name = purple_protocol_get_icon_name(protocol);
 
 	for (row = results->rows; row != NULL; row = row->next) {
 
 		gtk_list_store_append(model, &iter);
-		gtk_list_store_set(model, &iter, 0, pixbuf, -1);
+		gtk_list_store_set(model, &iter, 0, icon_name, -1);
 
 		n = 1;
 		for (column = row->data; column != NULL; column = column->next) {
@@ -349,9 +352,6 @@
 			n++;
 		}
 	}
-
-	if (pixbuf != NULL)
-		g_object_unref(pixbuf);
 }
 
 static void *
@@ -371,6 +371,7 @@
 	GList *l;
 
 	GtkWidget *vbox;
+	GtkWidget *sw;
 	GtkWidget *label;
 	PidginNotifySearchResultsData *data;
 	char *label_text;
@@ -386,7 +387,6 @@
 	/* Create the window */
 	window = gtk_dialog_new();
 	gtk_window_set_title(GTK_WINDOW(window), title ? title :_("Search Results"));
-	gtk_container_set_border_width(GTK_CONTAINER(window), 12);
 	gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
 
 	g_signal_connect_swapped(G_OBJECT(window), "delete_event",
@@ -407,11 +407,10 @@
 	g_free(secondary_esc);
 	label = gtk_label_new(NULL);
 	gtk_label_set_markup(GTK_LABEL(label), label_text);
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 	gtk_label_set_xalign(GTK_LABEL(label), 0);
 	gtk_label_set_yalign(GTK_LABEL(label), 0);
-	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-	gtk_widget_show(label);
+	gtk_box_append(GTK_BOX(vbox), label);
 	g_free(label_text);
 
 	/* +1 is for the automagically created Status column. */
@@ -435,14 +434,17 @@
 	gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),
 								GTK_SELECTION_SINGLE);
 	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE);
-	gtk_box_pack_start(GTK_BOX(vbox),
-		pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
-		TRUE, TRUE, 0);
-	gtk_widget_show(treeview);
+	sw = gtk_scrolled_window_new();
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+	                               GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), treeview);
+	gtk_widget_set_valign(sw, GTK_ALIGN_FILL);
+	gtk_widget_set_vexpand(sw, TRUE);
+	gtk_box_append(GTK_BOX(vbox), sw);
 
 	renderer = gtk_cell_renderer_pixbuf_new();
 	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
-					-1, "", renderer, "pixbuf", 0, NULL);
+					-1, "", renderer, "icon-name", 0, NULL);
 
 	i = 1;
 	for (columniter = results->columns; columniter != NULL; columniter = columniter->next) {
@@ -591,22 +593,22 @@
 static void
 pidgin_close_notify(PurpleNotifyType type, void *ui_handle)
 {
-	if (type == PURPLE_NOTIFY_SEARCHRESULTS)
-	{
+	if (type == PURPLE_NOTIFY_SEARCHRESULTS) {
 		PidginNotifySearchResultsData *data = (PidginNotifySearchResultsData *)ui_handle;
 
-		gtk_widget_destroy(data->window);
+		gtk_window_destroy(GTK_WINDOW(data->window));
 		purple_notify_searchresults_free(data->results);
 
 		g_free(data);
+
+	} else if (ui_handle != NULL) {
+		gtk_window_destroy(GTK_WINDOW(ui_handle));
 	}
-	else if (ui_handle != NULL)
-		gtk_widget_destroy(GTK_WIDGET(ui_handle));
 }
 
 static void *
 pidgin_notify_uri(const char *uri) {
-	gtk_show_uri_on_window(NULL, uri, GDK_CURRENT_TIME, NULL);
+	gtk_show_uri(NULL, uri, GDK_CURRENT_TIME);
 
 	return NULL;
 }
--- a/pidgin/gtkpluginpref.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkpluginpref.c	Sun Aug 28 22:18:46 2022 -0500
@@ -30,7 +30,7 @@
 entry_cb(GtkWidget *entry, gpointer data) {
 	char *pref = data;
 
-	purple_prefs_set_string(pref, gtk_entry_get_text(GTK_ENTRY(entry)));
+	purple_prefs_set_string(pref, gtk_editable_get_text(GTK_EDITABLE(entry)));
 
 	return FALSE;
 }
@@ -75,7 +75,7 @@
 			if (format == PURPLE_STRING_FORMAT_TYPE_NONE)
 			{
 				entry = gtk_entry_new();
-				gtk_entry_set_text(GTK_ENTRY(entry), purple_prefs_get_string(pref_name));
+				gtk_editable_set_text(GTK_EDITABLE(entry), purple_prefs_get_string(pref_name));
 				gtk_entry_set_max_length(GTK_ENTRY(entry),
 									 purple_plugin_pref_get_max_length(pref));
 				if (purple_plugin_pref_get_masked(pref))
@@ -98,22 +98,22 @@
 				box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
 
 				gtk_widget_show(box);
-				gtk_box_pack_start(GTK_BOX(parent), box, FALSE, FALSE, 0);
+				gtk_box_append(GTK_BOX(parent), box);
 
 				gtk_label = gtk_label_new_with_mnemonic(pref_label);
 				gtk_label_set_xalign(GTK_LABEL(gtk_label), 0);
 				gtk_widget_show(gtk_label);
-				gtk_box_pack_start(GTK_BOX(box), gtk_label, FALSE, FALSE, 0);
+				gtk_box_append(GTK_BOX(box), gtk_label);
 
 				if(sg)
 					gtk_size_group_add_widget(sg, gtk_label);
 
 				hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-				gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
+				gtk_box_append(GTK_BOX(box), hbox);
 				gtk_widget_show(hbox);
 
 				spacer = gtk_label_new("    ");
-				gtk_box_pack_start(GTK_BOX(hbox), spacer, FALSE, FALSE, 0);
+				gtk_box_append(GTK_BOX(hbox), spacer);
 				gtk_widget_show(spacer);
 
 				editor = talkatu_editor_new();
@@ -136,7 +136,6 @@
 				}
 
 				gtk_label_set_mnemonic_widget(GTK_LABEL(gtk_label), input);
-				gtk_widget_show_all(editor);
 				g_object_set_data(G_OBJECT(buffer), "pref-key", (gpointer)pref_name);
 				g_signal_connect(G_OBJECT(buffer), "changed",
 				                 G_CALLBACK(multiline_cb), NULL);
@@ -145,7 +144,9 @@
 				g_signal_connect(G_OBJECT(view), "format-toggled",
 				                 G_CALLBACK(multiline_cb), NULL);
 				*/
-				gtk_box_pack_start(GTK_BOX(hbox), editor, TRUE, TRUE, 0);
+				gtk_box_append(GTK_BOX(hbox), editor);
+				gtk_widget_set_halign(editor, GTK_ALIGN_FILL);
+				gtk_widget_set_hexpand(editor, TRUE);
 			}
 
 			break;
@@ -187,8 +188,8 @@
 	GtkWidget *gtk_label = gtk_label_new(purple_plugin_pref_get_label(pref));
 	gtk_label_set_xalign(GTK_LABEL(gtk_label), 0);
 	gtk_label_set_yalign(GTK_LABEL(gtk_label), 0);
-	gtk_label_set_line_wrap(GTK_LABEL(gtk_label), TRUE);
-	gtk_box_pack_start(GTK_BOX(parent), gtk_label, FALSE, FALSE, 0);
+	gtk_label_set_wrap(GTK_LABEL(gtk_label), TRUE);
+	gtk_box_append(GTK_BOX(parent), gtk_label);
 	gtk_widget_show(gtk_label);
 }
 
--- a/pidgin/gtkprivacy.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkprivacy.c	Sun Aug 28 22:18:46 2022 -0500
@@ -187,8 +187,6 @@
 	gtk_widget_set_sensitive(dialog->remove_button, FALSE);
 	gtk_widget_set_sensitive(dialog->removeall_button, buttons_sensitive);
 
-	gtk_widget_show_all(dialog->close_button);
-
 	purple_blist_schedule_save();
 	pidgin_blist_refresh(purple_blist_get_default());
 }
@@ -335,18 +333,19 @@
 
 	if (privacy_dialog == NULL) {
 		privacy_dialog = g_object_new(PIDGIN_TYPE_PRIVACY_DIALOG, NULL);
-		g_signal_connect(privacy_dialog, "destroy",
-		                 G_CALLBACK(gtk_widget_destroyed), &privacy_dialog);
+		g_object_add_weak_pointer(G_OBJECT(privacy_dialog),
+		                          (gpointer)&privacy_dialog);
 	}
 
 	gtk_widget_show(GTK_WIDGET(privacy_dialog));
-	gdk_window_raise(gtk_widget_get_window(GTK_WIDGET(privacy_dialog)));
 }
 
 void
 pidgin_privacy_dialog_hide(void)
 {
-	gtk_widget_destroy(GTK_WIDGET(privacy_dialog));
+	if(GTK_IS_WIDGET(privacy_dialog)) {
+		gtk_window_destroy(GTK_WINDOW(privacy_dialog));
+	}
 }
 
 static void
--- a/pidgin/gtkrequest.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkrequest.c	Sun Aug 28 22:18:46 2022 -0500
@@ -89,29 +89,26 @@
 static void
 pidgin_widget_decorate_account(GtkWidget *cont, PurpleAccount *account)
 {
+	PurpleProtocol *protocol = NULL;
 	GtkWidget *image;
-	GdkPixbuf *pixbuf;
+	const gchar *icon_name = NULL;
 
 	if(!PURPLE_IS_ACCOUNT(account)) {
 		return;
 	}
 
-	pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
-	if(!GDK_IS_PIXBUF(pixbuf)) {
-		return;
-	}
-
-	image = gtk_image_new_from_pixbuf(pixbuf);
-	g_object_unref(G_OBJECT(pixbuf));
+	protocol = purple_account_get_protocol(account);
+	icon_name = purple_protocol_get_icon_name(protocol);
+
+	image = gtk_image_new_from_icon_name(icon_name);
 
 	gtk_widget_set_tooltip_text(image, purple_account_get_username(account));
 
 	if (GTK_IS_BOX(cont)) {
 		gtk_widget_set_halign(image, GTK_ALIGN_START);
 		gtk_widget_set_valign(image, GTK_ALIGN_START);
-		gtk_box_pack_end(GTK_BOX(cont), image, FALSE, TRUE, 0);
+		gtk_box_append(GTK_BOX(cont), image);
 	}
-	gtk_widget_show(image);
 }
 
 static void
@@ -151,7 +148,7 @@
 		value = multiline_value;
 	}
 	else {
-		value = gtk_entry_get_text(GTK_ENTRY(data->u.input.entry));
+		value = gtk_editable_get_text(GTK_EDITABLE(data->u.input.entry));
 	}
 
 	if (id >= 0 && (gsize)id < data->cb_count && data->cbs[id] != NULL)
@@ -181,6 +178,8 @@
 static void
 choice_response_cb(GtkDialog *dialog, gint id, PidginRequestData *data)
 {
+#warning please rewrite me
+#if 0
 	GtkWidget *radio = g_object_get_data(G_OBJECT(dialog), "radio");
 	GSList *group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
 
@@ -188,19 +187,21 @@
 
 	if (id >= 0 && (gsize)id < data->cb_count && data->cbs[id] != NULL)
 		while (group) {
-			if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(group->data))) {
+			if (gtk_check_button_get_active(GTK_CHECK_BUTTON(group->data))) {
 				((PurpleRequestChoiceCb)data->cbs[id])(data->user_data, g_object_get_data(G_OBJECT(group->data), "choice_value"));
 				break;
 			}
 			group = group->next;
 		}
 	purple_request_close(PURPLE_REQUEST_INPUT, data);
+#endif
 }
 
 static gboolean
-field_string_focus_out_cb(GtkWidget *entry, GdkEventFocus *event,
-						  PurpleRequestField *field)
+field_string_focus_out_cb(GtkEventControllerFocus *controller,
+                          PurpleRequestField *field)
 {
+	GtkWidget *entry = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(controller));
 	const char *value;
 
 	if (purple_request_field_string_is_multiline(field))
@@ -216,7 +217,7 @@
 		value = gtk_text_buffer_get_text(buffer, &start_iter, &end_iter, FALSE);
 	}
 	else
-		value = gtk_entry_get_text(GTK_ENTRY(entry));
+		value = gtk_editable_get_text(GTK_EDITABLE(entry));
 
 	purple_request_field_string_set_value(field,
 			(*value == '\0' ? NULL : value));
@@ -225,10 +226,10 @@
 }
 
 static void
-field_bool_cb(GtkToggleButton *button, PurpleRequestField *field)
+field_bool_cb(GtkCheckButton *button, PurpleRequestField *field)
 {
 	purple_request_field_bool_set_value(field,
-			gtk_toggle_button_get_active(button));
+			gtk_check_button_get_active(button));
 }
 
 static void
@@ -244,14 +245,17 @@
 }
 
 static void
-field_choice_option_cb(GtkRadioButton *button, PurpleRequestField *field)
+field_choice_option_cb(GtkCheckButton *button, PurpleRequestField *field)
 {
+#warning please rewrite me
+#if 0
 	int active;
 	gpointer *values = g_object_get_data(G_OBJECT(g_object_get_data(
 		G_OBJECT(button), "box")), "values");
 
-	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
+	if (!gtk_check_button_get_active(GTK_CHECK_BUTTON(button))) {
 		return;
+	}
 
 	active = (g_slist_length(gtk_radio_button_get_group(button)) -
 		g_slist_index(gtk_radio_button_get_group(button), button)) - 1;
@@ -260,6 +264,7 @@
 	g_return_if_fail(active >= 0);
 
 	purple_request_field_choice_set_value(field, values[active]);
+#endif
 }
 
 static void
@@ -314,8 +319,7 @@
 }
 
 static gboolean
-destroy_multifield_cb(GtkWidget *dialog, GdkEvent *event,
-					  PidginRequestData *data)
+destroy_multifield_cb(GtkWidget *self, PidginRequestData *data)
 {
 	multifield_cancel_cb(NULL, data);
 	return FALSE;
@@ -432,13 +436,14 @@
 		}
 	}
 
-	img = gtk_image_new_from_icon_name(icon_name, GTK_ICON_SIZE_DIALOG);
-
-	if (img || icon_type == PURPLE_REQUEST_ICON_REQUEST)
-		return img;
-
-	return gtk_image_new_from_icon_name("dialog-question",
-			GTK_ICON_SIZE_DIALOG);
+	if(icon_name == NULL) {
+		icon_name = "dialog-question";
+	}
+
+	img = gtk_image_new_from_icon_name(icon_name);
+	gtk_image_set_icon_size(GTK_IMAGE(img), GTK_ICON_SIZE_LARGE);
+
+	return img;
 }
 
 static void
@@ -489,6 +494,7 @@
 	GtkWidget *hbox;
 	GtkLabel *label;
 	GtkWidget *img;
+	GtkWidget *content;
 	char *label_text;
 	char *primary_esc, *secondary_esc;
 
@@ -514,9 +520,17 @@
 					 G_CALLBACK(input_response_cb), data);
 
 	/* Setup the dialog */
-	gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
-	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                               6);
+	gtk_widget_set_margin_top(dialog, 6);
+	gtk_widget_set_margin_bottom(dialog, 6);
+	gtk_widget_set_margin_start(dialog, 6);
+	gtk_widget_set_margin_end(dialog, 6);
+
+	content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_widget_set_margin_top(content, 6);
+	gtk_widget_set_margin_bottom(content, 6);
+	gtk_widget_set_margin_start(content, 6);
+	gtk_widget_set_margin_end(content, 6);
+
 	if (!multiline)
 		gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
 	gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0);
@@ -525,21 +539,21 @@
 
 	/* Setup the main horizontal box */
 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                  hbox);
+	gtk_box_append(GTK_BOX(content), hbox);
 
 	/* Dialog icon. */
 	img = pidgin_request_dialog_icon(PURPLE_REQUEST_INPUT, cpar);
 	gtk_widget_set_halign(img, GTK_ALIGN_START);
 	gtk_widget_set_valign(img, GTK_ALIGN_START);
-	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(hbox), img);
 
 	pidgin_request_add_help(GTK_DIALOG(dialog), cpar);
 
 	/* Vertical box */
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-
-	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
+	gtk_widget_set_halign(vbox, GTK_ALIGN_FILL);
+	gtk_widget_set_hexpand(vbox, TRUE);
+	gtk_box_append(GTK_BOX(hbox), vbox);
 
 	pidgin_widget_decorate_account(hbox, purple_request_cpar_get_account(cpar));
 
@@ -557,10 +571,10 @@
 	label = GTK_LABEL(gtk_label_new(NULL));
 
 	gtk_label_set_markup(label, label_text);
-	gtk_label_set_line_wrap(label, TRUE);
+	gtk_label_set_wrap(label, TRUE);
 	gtk_label_set_xalign(label, 0);
 	gtk_label_set_yalign(label, 0);
-	gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(label), FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(vbox), GTK_WIDGET(label));
 
 	g_free(label_text);
 
@@ -568,8 +582,6 @@
 	data->u.input.multiline = multiline;
 	data->u.input.hint = g_strdup(hint);
 
-	gtk_widget_show_all(hbox);
-
 	if(multiline || purple_strequal(data->u.input.hint, "html")) {
 		GtkWidget *editor = talkatu_editor_new();
 		GtkWidget *input = talkatu_editor_get_input(TALKATU_EDITOR(editor));
@@ -577,8 +589,9 @@
 
 		gtk_widget_set_size_request(input, 320, 130);
 		gtk_widget_set_name(input, "pidgin_request_input");
-		gtk_box_pack_start(GTK_BOX(vbox), editor, TRUE, TRUE, 0);
-		gtk_widget_show(editor);
+		gtk_widget_set_valign(editor, GTK_ALIGN_FILL);
+		gtk_widget_set_vexpand(editor, TRUE);
+		gtk_box_append(GTK_BOX(vbox), editor);
 
 		if (purple_strequal(data->u.input.hint, "html")) {
 			buffer = talkatu_html_buffer_new();
@@ -598,24 +611,26 @@
 
 		data->u.input.entry = input;
 	} else {
-		GtkWidget *entry = gtk_entry_new();
-
-		gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
-		gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
+		GtkWidget *entry = NULL;
+
+		if(masked) {
+			entry = gtk_password_entry_new();
+			g_object_set(entry, "activates-default", TRUE,
+			             "show-peek-icon", TRUE, NULL);
+		} else {
+			entry = gtk_entry_new();
+			gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+		}
+
+		gtk_box_append(GTK_BOX(vbox), entry);
 
 		if(default_value != NULL) {
-			gtk_entry_set_text(GTK_ENTRY(entry), default_value);
-		}
-
-		if(masked) {
-			gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+			gtk_editable_set_text(GTK_EDITABLE(entry), default_value);
 		}
 
 		data->u.input.entry = entry;
 	}
 
-	gtk_widget_show_all(vbox);
-
 	pidgin_set_accessible_label(data->u.input.entry, label);
 
 	pidgin_auto_parent_window(dialog);
@@ -638,7 +653,8 @@
 	GtkWidget *hbox;
 	GtkWidget *label;
 	GtkWidget *img;
-	GtkWidget *radio = NULL;
+	GtkWidget *first_radio = NULL;
+	GtkWidget *content;
 	char *label_text;
 	char *radio_text;
 	char *primary_esc, *secondary_esc;
@@ -668,23 +684,28 @@
 			 G_CALLBACK(choice_response_cb), data);
 
 	/* Setup the dialog */
-	gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
-	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                               6);
+	gtk_widget_set_margin_top(dialog, 6);
+	gtk_widget_set_margin_bottom(dialog, 6);
+	gtk_widget_set_margin_start(dialog, 6);
+	gtk_widget_set_margin_end(dialog, 6);
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
-	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                    12);
+
+	content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_widget_set_margin_top(content, 6);
+	gtk_widget_set_margin_bottom(content, 6);
+	gtk_widget_set_margin_start(content, 6);
+	gtk_widget_set_margin_end(content, 6);
+	gtk_box_set_spacing(GTK_BOX(content), 12);
 
 	/* Setup the main horizontal box */
 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                  hbox);
+	gtk_box_append(GTK_BOX(content), hbox);
 
 	/* Dialog icon. */
 	img = pidgin_request_dialog_icon(PURPLE_REQUEST_CHOICE, cpar);
 	gtk_widget_set_halign(img, GTK_ALIGN_START);
 	gtk_widget_set_valign(img, GTK_ALIGN_START);
-	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(hbox), img);
 
 	pidgin_widget_decorate_account(hbox, purple_request_cpar_get_account(cpar));
 
@@ -692,7 +713,7 @@
 
 	/* Vertical box */
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(hbox), vbox);
 
 	/* Descriptive label */
 	primary_esc = pidgin_request_escape(cpar, primary);
@@ -708,30 +729,44 @@
 	label = gtk_label_new(NULL);
 
 	gtk_label_set_markup(GTK_LABEL(label), label_text);
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 	gtk_label_set_xalign(GTK_LABEL(label), 0);
 	gtk_label_set_yalign(GTK_LABEL(label), 0);
-	gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
+	gtk_widget_set_valign(label, GTK_ALIGN_FILL);
+	gtk_widget_set_vexpand(label, TRUE);
+	gtk_box_append(GTK_BOX(vbox), label);
 
 	g_free(label_text);
 
 	vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-	gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(vbox), vbox2);
 	while ((radio_text = va_arg(args, char*))) {
-		       gpointer resp = va_arg(args, gpointer);
-		       radio = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio), radio_text);
-		       gtk_box_pack_start(GTK_BOX(vbox2), radio, FALSE, FALSE, 0);
-		       g_object_set_data(G_OBJECT(radio), "choice_value", resp);
-		       if (resp == default_value)
-			       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
+		GtkWidget *radio = NULL;
+		gpointer resp = va_arg(args, gpointer);
+
+		radio = gtk_check_button_new_with_label(radio_text);
+
+		if(first_radio == NULL) {
+			first_radio = radio;
+		} else {
+			gtk_check_button_set_group(GTK_CHECK_BUTTON(radio),
+			                           GTK_CHECK_BUTTON(first_radio));
+		}
+
+		gtk_box_append(GTK_BOX(vbox2), radio);
+
+		g_object_set_data(G_OBJECT(radio), "choice_value", resp);
+		if (resp == default_value) {
+			gtk_check_button_set_active(GTK_CHECK_BUTTON(radio), TRUE);
+		}
 	}
 
-	g_object_set_data(G_OBJECT(dialog), "radio", radio);
+	g_object_set_data(G_OBJECT(dialog), "radio", first_radio);
 
 	/* Show everything. */
 	pidgin_auto_parent_window(dialog);
 
-	gtk_widget_show_all(dialog);
+	gtk_widget_show(dialog);
 
 	return data;
 }
@@ -748,6 +783,7 @@
 	GtkWidget *hbox;
 	GtkWidget *label;
 	GtkWidget *img = NULL;
+	GtkWidget *content;
 	void **buttons;
 	char *label_text;
 	char *primary_esc, *secondary_esc;
@@ -792,26 +828,31 @@
 					 G_CALLBACK(action_response_cb), data);
 
 	/* Setup the dialog */
-	gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
-	gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                               6);
+	gtk_widget_set_margin_top(dialog, 6);
+	gtk_widget_set_margin_bottom(dialog, 6);
+	gtk_widget_set_margin_start(dialog, 6);
+	gtk_widget_set_margin_end(dialog, 6);
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
-	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                    12);
+
+	content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_widget_set_margin_top(content, 6);
+	gtk_widget_set_margin_bottom(content, 6);
+	gtk_widget_set_margin_start(content, 6);
+	gtk_widget_set_margin_end(content, 6);
+	gtk_box_set_spacing(GTK_BOX(content), 12);
 
 	/* Setup the main horizontal box */
 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
-	                  hbox);
+	gtk_box_append(GTK_BOX(content), hbox);
 
 	img = pidgin_request_dialog_icon(PURPLE_REQUEST_ACTION, cpar);
 	gtk_widget_set_halign(img, GTK_ALIGN_START);
 	gtk_widget_set_valign(img, GTK_ALIGN_START);
-	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(hbox), img);
 
 	/* Vertical box */
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(hbox), vbox);
 
 	pidgin_widget_decorate_account(hbox,
 		purple_request_cpar_get_account(cpar));
@@ -832,31 +873,29 @@
 	label = gtk_label_new(NULL);
 
 	gtk_label_set_markup(GTK_LABEL(label), label_text);
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 	gtk_label_set_xalign(GTK_LABEL(label), 0);
 	gtk_label_set_yalign(GTK_LABEL(label), 0);
 	gtk_label_set_selectable(GTK_LABEL(label), TRUE);
-	gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
+	gtk_widget_set_valign(label, GTK_ALIGN_FILL);
+	gtk_widget_set_vexpand(label, TRUE);
+	gtk_box_append(GTK_BOX(vbox), label);
 
 	g_free(label_text);
 
 
-	if (default_action == PURPLE_DEFAULT_ACTION_NONE) {
-		gtk_widget_set_can_default(img, TRUE);
-		gtk_widget_set_can_focus(img, TRUE);
-		gtk_widget_grab_focus(img);
-		gtk_widget_grab_default(img);
-	} else
+	if (default_action != PURPLE_DEFAULT_ACTION_NONE) {
 		/*
 		 * Need to invert the default_action number because the
 		 * buttons are added to the dialog in reverse order.
 		 */
 		gtk_dialog_set_default_response(GTK_DIALOG(dialog), action_count - 1 - default_action);
+	}
 
 	/* Show everything. */
 	pidgin_auto_parent_window(dialog);
 
-	gtk_widget_show_all(dialog);
+	gtk_widget_show(dialog);
 
 	return data;
 }
@@ -879,7 +918,7 @@
 	void *user_data)
 {
 	PidginRequestData *data;
-	GtkWidget *dialog;
+	GtkWidget *dialog, *content;
 	GtkWidget *hbox, *vbox, *img, *label, *button;
 	gchar *primary_esc, *secondary_esc, *label_text;
 
@@ -901,32 +940,36 @@
 		gtk_window_set_title(GTK_WINDOW(dialog), _("Please wait"));
 
 	/* Setup the dialog */
-	gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
-	gtk_container_set_border_width(GTK_CONTAINER(
-		gtk_dialog_get_content_area(GTK_DIALOG(dialog))), 6);
+	gtk_widget_set_margin_top(dialog, 6);
+	gtk_widget_set_margin_bottom(dialog, 6);
+	gtk_widget_set_margin_start(dialog, 6);
+	gtk_widget_set_margin_end(dialog, 6);
 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
-	gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(
-		GTK_DIALOG(dialog))), 12);
+
+	content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_widget_set_margin_top(content, 6);
+	gtk_widget_set_margin_bottom(content, 6);
+	gtk_widget_set_margin_start(content, 6);
+	gtk_widget_set_margin_end(content, 6);
+	gtk_box_set_spacing(GTK_BOX(content), 12);
 
 	/* Setup the main horizontal box */
 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(
-		GTK_DIALOG(dialog))), hbox);
+	gtk_box_append(GTK_BOX(content), hbox);
 
 	img = pidgin_request_dialog_icon(PURPLE_REQUEST_WAIT, cpar);
 	gtk_widget_set_halign(img, GTK_ALIGN_START);
 	gtk_widget_set_valign(img, GTK_ALIGN_START);
-	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(hbox), img);
 
 	/* Cancel button */
 	button = gtk_dialog_add_button(GTK_DIALOG(dialog), _("Cancel"), GTK_RESPONSE_CANCEL);
 	g_signal_connect(G_OBJECT(button), "clicked",
 		G_CALLBACK(wait_cancel_cb), data);
-	gtk_widget_set_can_default(button, FALSE);
 
 	/* Vertical box */
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(hbox), vbox);
 
 	pidgin_widget_decorate_account(hbox,
 		purple_request_cpar_get_account(cpar));
@@ -947,11 +990,13 @@
 	label = gtk_label_new(NULL);
 
 	gtk_label_set_markup(GTK_LABEL(label), label_text);
-	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 	gtk_label_set_xalign(GTK_LABEL(label), 0);
 	gtk_label_set_yalign(GTK_LABEL(label), 0);
 	gtk_label_set_selectable(GTK_LABEL(label), FALSE);
-	gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
+	gtk_widget_set_valign(label, GTK_ALIGN_FILL);
+	gtk_widget_set_vexpand(label, TRUE);
+	gtk_box_append(GTK_BOX(vbox), label);
 
 	g_free(label_text);
 
@@ -961,20 +1006,13 @@
 		bar = data->u.wait.progress_bar =
 			GTK_PROGRESS_BAR(gtk_progress_bar_new());
 		gtk_progress_bar_set_fraction(bar, 0);
-		gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(bar),
-			FALSE, FALSE, 0);
+		gtk_box_append(GTK_BOX(vbox), GTK_WIDGET(bar));
 	}
 
-	/* Move focus out of cancel button. */
-	gtk_widget_set_can_default(img, TRUE);
-	gtk_widget_set_can_focus(img, TRUE);
-	gtk_widget_grab_focus(img);
-	gtk_widget_grab_default(img);
-
 	/* Show everything. */
 	pidgin_auto_parent_window(dialog);
 
-	gtk_widget_show_all(dialog);
+	gtk_widget_show(dialog);
 
 	return data;
 }
@@ -1018,7 +1056,7 @@
 	else
 	{
 		const char *text = NULL;
-		text = gtk_entry_get_text(GTK_ENTRY(entry));
+		text = gtk_editable_get_text(GTK_EDITABLE(entry));
 		purple_request_field_string_set_value(field, (*text == '\0') ? NULL : text);
 	}
 }
@@ -1059,7 +1097,7 @@
 {
 	const char *type_hint;
 
-	gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+	g_object_set(entry, "activates-default", TRUE, NULL);
 
 	g_signal_connect(G_OBJECT(entry), "changed",
 		G_CALLBACK(req_entry_field_changed_cb), field);
@@ -1113,6 +1151,7 @@
 	if (purple_request_field_string_is_multiline(field))
 	{
 		GtkWidget *textview;
+		GtkEventController *controller;
 
 		textview = gtk_text_view_new();
 		gtk_text_view_set_editable(GTK_TEXT_VIEW(textview),
@@ -1120,8 +1159,6 @@
 		gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview),
 									GTK_WRAP_WORD_CHAR);
 
-		gtk_widget_show(textview);
-
 		if (value != NULL)
 		{
 			GtkTextBuffer *buffer;
@@ -1135,7 +1172,9 @@
 
 		gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), is_editable);
 
-		g_signal_connect(G_OBJECT(textview), "focus-out-event",
+		controller = gtk_event_controller_focus_new();
+		gtk_widget_add_controller(textview, controller);
+		g_signal_connect(controller, "leave",
 						 G_CALLBACK(field_string_focus_out_cb), field);
 
 	    if (purple_request_field_is_required(field))
@@ -1145,27 +1184,37 @@
 							 G_CALLBACK(req_entry_field_changed_cb), field);
 	    }
 
-		widget = pidgin_make_scrollable(textview, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, 75);
+		widget = gtk_scrolled_window_new();
+		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget),
+		                               GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+		gtk_widget_set_size_request(widget, -1, 75);
+		gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(widget), textview);
 	}
 	else
 	{
-		widget = gtk_entry_new();
+		GtkEventController *controller = NULL;
+
+		if (purple_request_field_string_is_masked(field)) {
+			widget = gtk_password_entry_new();
+			gtk_password_entry_set_show_peek_icon(GTK_PASSWORD_ENTRY(widget),
+			                                      TRUE);
+		} else {
+			widget = gtk_entry_new();
+		}
 
 		setup_entry_field(widget, field);
 
-		if (value != NULL)
-			gtk_entry_set_text(GTK_ENTRY(widget), value);
+		if(value != NULL) {
+			gtk_editable_set_text(GTK_EDITABLE(widget), value);
+		}
 
 		gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
 
-		if (purple_request_field_string_is_masked(field))
-		{
-			gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
-		}
-
 		gtk_editable_set_editable(GTK_EDITABLE(widget), is_editable);
 
-		g_signal_connect(G_OBJECT(widget), "focus-out-event",
+		controller = gtk_event_controller_focus_new();
+		gtk_widget_add_controller(widget, controller);
+		g_signal_connect(controller, "leave",
 						 G_CALLBACK(field_string_focus_out_cb), field);
 	}
 
@@ -1206,7 +1255,7 @@
 
 	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
 
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(widget),
 		purple_request_field_bool_get_default_value(field));
 
 	g_signal_connect(G_OBJECT(widget), "toggled",
@@ -1219,7 +1268,7 @@
 
 static GtkWidget *
 create_choice_field(PurpleRequestField *field,
-	PurpleRequestCommonParameters *cpar)
+                    PurpleRequestCommonParameters *cpar)
 {
 	GtkWidget *widget;
 	GList *elements = purple_request_field_choice_get_elements(field);
@@ -1260,11 +1309,15 @@
 		GtkWidget *box;
 		GtkWidget *first_radio = NULL;
 		GtkWidget *radio;
-
-		if (num_labels == 2)
+		GtkOrientation orientation = GTK_ORIENTATION_HORIZONTAL;
+
+		if(num_labels == 2) {
+			orientation = GTK_ORIENTATION_HORIZONTAL;
 			box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-		else
+		} else {
+			orientation = GTK_ORIENTATION_VERTICAL;
 			box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+		}
 
 		widget = box;
 
@@ -1275,21 +1328,31 @@
 		{
 			PurpleKeyValuePair *choice = l->data;
 
-			radio = gtk_radio_button_new_with_label_from_widget(
-				GTK_RADIO_BUTTON(first_radio), choice->key);
+			radio = gtk_check_button_new_with_label(choice->key);
 			g_object_set_data(G_OBJECT(radio), "box", box);
 
-			if (first_radio == NULL)
+			if(first_radio == NULL) {
 				first_radio = radio;
+			} else {
+				gtk_check_button_set_group(GTK_CHECK_BUTTON(radio),
+				                           GTK_CHECK_BUTTON(first_radio));
+			}
 
 			if (choice->value == default_value) {
-				gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
+				gtk_check_button_set_active(GTK_CHECK_BUTTON(radio), TRUE);
 				default_found = TRUE;
 			}
 			values[i++] = choice->value;
 
-			gtk_box_pack_start(GTK_BOX(box), radio, TRUE, TRUE, 0);
-			gtk_widget_show(radio);
+			if(orientation == GTK_ORIENTATION_VERTICAL) {
+				gtk_widget_set_valign(radio, GTK_ALIGN_FILL);
+				gtk_widget_set_vexpand(radio, TRUE);
+			} else if(orientation == GTK_ORIENTATION_HORIZONTAL) {
+				gtk_widget_set_halign(radio, GTK_ALIGN_FILL);
+				gtk_widget_set_hexpand(radio, TRUE);
+			}
+
+			gtk_box_append(GTK_BOX(box), radio);
 
 			g_signal_connect(G_OBJECT(radio), "toggled",
 							 G_CALLBACK(field_choice_option_cb), field);
@@ -1302,6 +1365,8 @@
 	g_object_set_data_full(G_OBJECT(widget), "values", values, g_free);
 
 	return widget;
+
+	return NULL;
 }
 
 static GtkWidget *
@@ -1366,7 +1431,6 @@
 	gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
 	g_signal_connect(widget, "changed",
 		G_CALLBACK(req_field_changed_cb), field);
-	gtk_widget_show(widget);
 
 	return widget;
 }
@@ -1395,6 +1459,7 @@
 static GtkWidget *
 create_list_field(PurpleRequestField *field)
 {
+	GtkWidget *sw;
 	GtkWidget *treeview;
 	GtkListStore *store;
 	GtkCellRenderer *renderer;
@@ -1481,16 +1546,18 @@
 	g_signal_connect(G_OBJECT(sel), "changed",
 					 G_CALLBACK(list_field_select_changed_cb), field);
 
-	gtk_widget_show(treeview);
-
-	return pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1);
+
+	sw = gtk_scrolled_window_new();
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+	                               GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), treeview);
+	return sw;
 }
 
 static GdkPixbuf*
 _pidgin_datasheet_stock_icon_get(const gchar *stock_name)
 {
 	GdkPixbuf *image = NULL;
-	gchar *domain, *id;
 
 	if (stock_name == NULL)
 		return NULL;
@@ -1505,46 +1572,9 @@
 		return image;
 	}
 
-	domain = g_strdup(stock_name);
-	id = strchr(domain, '/');
-	if (!id) {
-		g_free(domain);
-		return NULL;
-	}
-	id[0] = '\0';
-	id++;
-
-	if (purple_strequal(domain, "protocol")) {
-		PurpleAccount *account;
-		PurpleAccountManager *manager = NULL;
-		gchar *protocol_id, *accountname;
-
-		protocol_id = id;
-		accountname = strchr(id, ':');
-
-		if (!accountname) {
-			g_free(domain);
-			return NULL;
-		}
-
-		accountname[0] = '\0';
-		accountname++;
-
-		manager = purple_account_manager_get_default();
-		account = purple_account_manager_find(manager, accountname,
-		                                      protocol_id);
-		if(account) {
-			image = pidgin_create_protocol_icon(account,
-				PIDGIN_PROTOCOL_ICON_SMALL);
-		}
-	} else {
-		purple_debug_error("gtkrequest", "Unknown domain: %s", domain);
-		g_free(domain);
-		return NULL;
-	}
-
-	g_hash_table_insert(datasheet_stock, g_strdup(stock_name), image);
-	return image;
+	purple_debug_error("gtkrequest", "Unknown icon: %s", stock_name);
+
+	return NULL;
 }
 
 static PurpleRequestDatasheetRecord*
@@ -1599,6 +1629,7 @@
 static void
 datasheet_selection_changed(GtkWidget *sheet_widget)
 {
+#if 0
 	gpointer buttons_box;
 
 	g_return_if_fail(sheet_widget != NULL);
@@ -1606,6 +1637,7 @@
 	buttons_box = g_object_get_data(G_OBJECT(sheet_widget), "buttons");
 	gtk_container_foreach(GTK_CONTAINER(buttons_box),
 		datasheet_button_check_sens, sheet_widget);
+#endif
 }
 
 static void
@@ -1825,18 +1857,18 @@
 
 	gtk_widget_set_size_request(GTK_WIDGET(view), 400, 250);
 
-	scrollable = pidgin_make_scrollable(GTK_WIDGET(view),
-		GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1);
-	gtk_widget_show(GTK_WIDGET(view));
+	scrollable = gtk_scrolled_window_new();
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollable),
+	                               GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrollable),
+	                              GTK_WIDGET(view));
+	gtk_widget_set_halign(scrollable, GTK_ALIGN_FILL);
+	gtk_widget_set_hexpand(scrollable, TRUE);
+	gtk_box_append(GTK_BOX(main_box), scrollable);
 
 	buttons_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
 	gtk_size_group_add_widget(buttons_sg, buttons_box);
-
-	gtk_box_pack_start(GTK_BOX(main_box), scrollable, TRUE, TRUE, 0);
-	gtk_box_pack_start(GTK_BOX(main_box), buttons_box,
-		FALSE, FALSE, 0);
-	gtk_widget_show(scrollable);
-	gtk_widget_show(buttons_box);
+	gtk_box_append(GTK_BOX(main_box), buttons_box);
 
 	it = purple_request_datasheet_get_actions(sheet);
 	for (; it != NULL; it = g_list_next(it)) {
@@ -1853,9 +1885,7 @@
 		g_signal_connect(G_OBJECT(btn), "clicked",
 			G_CALLBACK(datasheet_action_clicked), act);
 
-		gtk_box_pack_start(GTK_BOX(buttons_box), GTK_WIDGET(btn),
-			FALSE, FALSE, 0);
-		gtk_widget_show(GTK_WIDGET(btn));
+		gtk_box_append(GTK_BOX(buttons_box), GTK_WIDGET(btn));
 	}
 
 	g_object_set_data(G_OBJECT(main_box), "view", view);
@@ -1882,14 +1912,13 @@
 {
 	PidginRequestData *data;
 	GtkWidget *win;
-	GtkNotebook *notebook;
-	GtkWidget **pages;
 	GtkWidget *hbox, *vbox;
 	GtkWidget *frame;
 	GtkWidget *label;
 	GtkWidget *grid;
 	GtkWidget *button;
 	GtkWidget *img;
+	GtkWidget *content;
 	GtkSizeGroup *sg, *datasheet_buttons_sg;
 	GList *gl, *fl;
 	PurpleRequestFieldGroup *group;
@@ -1899,8 +1928,6 @@
 	const gboolean compact = purple_request_cpar_is_compact(cpar);
 	GSList *extra_actions;
 	size_t i;
-	const gchar **tab_names;
-	guint tab_count;
 	gboolean ok_btn = (ok_text != NULL);
 
 	data            = g_new0(PidginRequestData, 1);
@@ -1920,21 +1947,19 @@
 
 	data->dialog = win = pidgin_dialog_new(title, 12, "multifield", TRUE) ;
 
-	g_signal_connect(G_OBJECT(win), "delete_event",
+	g_signal_connect(G_OBJECT(win), "close-request",
 					 G_CALLBACK(destroy_multifield_cb), data);
 
 	/* Setup the main horizontal box */
+	content = gtk_dialog_get_content_area(GTK_DIALOG(win));
 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(win))),
-	                  hbox);
-	gtk_widget_show(hbox);
+	gtk_box_append(GTK_BOX(content), hbox);
 
 	/* Dialog icon. */
 	img = pidgin_request_dialog_icon(PURPLE_REQUEST_FIELDS, cpar);
 	gtk_widget_set_halign(img, GTK_ALIGN_START);
 	gtk_widget_set_valign(img, GTK_ALIGN_START);
-	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
-	gtk_widget_show(img);
+	gtk_box_append(GTK_BOX(hbox), img);
 
 	pidgin_request_add_help(GTK_DIALOG(win), cpar);
 
@@ -1952,18 +1977,16 @@
 	button = gtk_dialog_add_button(GTK_DIALOG(win), cancel_text, GTK_RESPONSE_CANCEL);
 	g_signal_connect(G_OBJECT(button), "clicked",
 			G_CALLBACK(multifield_cancel_cb), data);
-	gtk_widget_set_can_default(button, TRUE);
 
 	/* OK button */
 	if (!ok_btn) {
-		gtk_window_set_default(GTK_WINDOW(win), button);
+		gtk_window_set_default_widget(GTK_WINDOW(win), button);
 	} else {
 		button = gtk_dialog_add_button(GTK_DIALOG(win), ok_text, GTK_RESPONSE_OK);
 		g_signal_connect(G_OBJECT(button), "clicked",
 				G_CALLBACK(multifield_ok_cb), data);
 		data->ok_button = button;
-		gtk_widget_set_can_default(button, TRUE);
-		gtk_window_set_default(GTK_WINDOW(win), button);
+		gtk_window_set_default_widget(GTK_WINDOW(win), button);
 	}
 
 	pidgin_widget_decorate_account(hbox,
@@ -1971,8 +1994,9 @@
 
 	/* Setup the vbox */
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
-	gtk_widget_show(vbox);
+	gtk_widget_set_halign(vbox, GTK_ALIGN_FILL);
+	gtk_widget_set_hexpand(vbox, TRUE);
+	gtk_box_append(GTK_BOX(hbox), vbox);
 
 	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 	datasheet_buttons_sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
@@ -1985,99 +2009,23 @@
 		label = gtk_label_new(NULL);
 
 		gtk_label_set_markup(GTK_LABEL(label), label_text);
-		gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+		gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 		gtk_label_set_xalign(GTK_LABEL(label), 0);
 		gtk_label_set_yalign(GTK_LABEL(label), 0);
-		gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-		gtk_widget_show(label);
+		gtk_box_append(GTK_BOX(vbox), label);
 		g_free(label_text);
 	}
 
-	/* Setup tabs */
-	tab_names = purple_request_fields_get_tab_names(fields);
-	if (tab_names == NULL) {
-		notebook = NULL;
-		tab_count = 1;
-
-		pages = g_new0(GtkWidget*, 1);
-		pages[0] = vbox;
-	} else {
-		tab_count = g_strv_length((gchar **)tab_names);
-		notebook = GTK_NOTEBOOK(gtk_notebook_new());
-
-		pages = g_new0(GtkWidget*, tab_count);
-
-		for (i = 0; i < tab_count; i++) {
-			pages[i] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-			gtk_container_set_border_width(GTK_CONTAINER(pages[i]), 12);
-			gtk_notebook_append_page(notebook, pages[i], NULL);
-			gtk_notebook_set_tab_label_text(notebook, pages[i], tab_names[i]);
-			gtk_widget_show(pages[i]);
-		}
-	}
-
-	for (i = 0; i < tab_count; i++) {
-		guint total_fields = 0;
-		GList *it;
-
-		it = purple_request_fields_get_groups(fields);
-		for (; it != NULL; it = g_list_next(it)) {
-			group = it->data;
-			if (purple_request_field_group_get_tab(group) != i)
-				continue;
-			total_fields += g_list_length(
-				purple_request_field_group_get_fields(group));
-		}
-
-		if(total_fields > 9) {
-			GtkWidget *hbox_for_spacing, *vbox_for_spacing;
-
-			gtk_container_set_border_width(
-				GTK_CONTAINER(pages[i]), 0);
-
-			hbox_for_spacing =
-				gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
-			gtk_box_pack_start(GTK_BOX(pages[i]),
-				pidgin_make_scrollable(hbox_for_spacing,
-					GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC,
-					GTK_SHADOW_NONE, -1, 200),
-				TRUE, TRUE, 0);
-			gtk_widget_show(hbox_for_spacing);
-
-			vbox_for_spacing =
-				gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-			gtk_box_pack_start(GTK_BOX(hbox_for_spacing),
-				vbox_for_spacing, TRUE, TRUE,
-				6);
-			gtk_widget_show(vbox_for_spacing);
-
-			pages[i] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
-			gtk_box_pack_start(GTK_BOX(vbox_for_spacing),
-				pages[i], TRUE, TRUE, 6);
-			gtk_widget_show(pages[i]);
-		}
-
-		if (notebook == NULL)
-			vbox = pages[0];
-	}
-
 	if (secondary) {
 		secondary_esc = pidgin_request_escape(cpar, secondary);
 		label = gtk_label_new(NULL);
 
 		gtk_label_set_markup(GTK_LABEL(label), secondary_esc);
 		g_free(secondary_esc);
-		gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+		gtk_label_set_wrap(GTK_LABEL(label), TRUE);
 		gtk_label_set_xalign(GTK_LABEL(label), 0);
 		gtk_label_set_yalign(GTK_LABEL(label), 0);
-		gtk_box_pack_start(GTK_BOX(vbox), label, (notebook == NULL),
-			(notebook == NULL), 0);
-		gtk_widget_show(label);
-	}
-
-	if (notebook != NULL) {
-		gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(notebook), TRUE, TRUE, 0);
-		gtk_widget_show(GTK_WIDGET(notebook));
+		gtk_box_append(GTK_BOX(vbox), label);
 	}
 
 	for (gl = purple_request_fields_get_groups(fields);
@@ -2088,44 +2036,21 @@
 		size_t field_count = 0;
 		size_t cols = 1;
 		size_t rows;
-#if 0
-		size_t col_num;
-#endif
 		size_t row_num = 0;
-		guint tab_no;
-		gboolean contains_resizable = FALSE, frame_fill;
+		gboolean contains_resizable = FALSE;
 
 		group      = gl->data;
 		field_list = purple_request_field_group_get_fields(group);
-		tab_no = purple_request_field_group_get_tab(group);
-		if (tab_no >= tab_count) {
-			purple_debug_warning("gtkrequest",
-				"Invalid tab number: %d", tab_no);
-			tab_no = 0;
+
+		if(purple_request_field_group_get_title(group) != NULL) {
+			frame = pidgin_make_frame(vbox,
+				purple_request_field_group_get_title(group));
+		} else {
+			frame = vbox;
 		}
 
-		if (purple_request_field_group_get_title(group) != NULL)
-		{
-			frame = pidgin_make_frame(pages[tab_no],
-				purple_request_field_group_get_title(group));
-		}
-		else
-			frame = pages[tab_no];
-
 		field_count = g_list_length(field_list);
-#if 0
-		if (field_count > 9)
-		{
-			rows = field_count / 2;
-			cols++;
-		}
-		else
-#endif
-			rows = field_count;
-
-#if 0
-		col_num = 0;
-#endif
+		rows = field_count;
 
 		for (fl = field_list; fl != NULL; fl = fl->next)
 		{
@@ -2140,61 +2065,47 @@
 
 			if (type == PURPLE_REQUEST_FIELD_LABEL)
 			{
-#if 0
-				if (col_num > 0)
-					rows++;
-#endif
-
 				rows++;
 			}
 			else if ((type == PURPLE_REQUEST_FIELD_LIST) ||
 				 (type == PURPLE_REQUEST_FIELD_STRING &&
 				  purple_request_field_string_is_multiline(field)))
 			{
-#if 0
-				if (col_num > 0)
-					rows++;
-#endif
-
 				rows += 2;
 			} else if (compact && type != PURPLE_REQUEST_FIELD_BOOLEAN)
 				rows++;
-
-#if 0
-			col_num++;
-
-			if (col_num >= cols)
-				col_num = 0;
-#endif
 		}
 
 		grid = gtk_grid_new();
 		gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
 		gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
 
-		frame_fill = (notebook == NULL || contains_resizable);
-		gtk_box_pack_start(GTK_BOX(frame), grid, frame_fill, frame_fill, 0);
-		gtk_widget_show(grid);
+		/* This box could be setup in a number of ways, so just set all of the
+		 * fill and expand properties instead of only setting the
+		 * minimums.
+		 */
+		g_object_set(G_OBJECT(grid),
+		             "hexpand", contains_resizable,
+		             "vexpand", contains_resizable,
+		             NULL);
+
+		if(contains_resizable) {
+			g_object_set(G_OBJECT(grid),
+			             "halign", GTK_ALIGN_FILL,
+			             "valign", GTK_ALIGN_FILL,
+			             NULL);
+		}
+		gtk_box_append(GTK_BOX(frame), grid);
 
 		for (row_num = 0, fl = field_list;
 			 row_num < rows && fl != NULL;
 			 row_num++)
 		{
-#if 0
-			for (col_num = 0;
-				 col_num < cols && fl != NULL;
-				 col_num++, fl = fl->next)
-#else
 			gboolean dummy_counter = TRUE;
 			/* it's the same as loop above */
 			for (; dummy_counter && fl != NULL; dummy_counter = FALSE, fl = fl->next)
-#endif
 			{
-#if 0
-				size_t col_offset = col_num * 2;
-#else
 				size_t col_offset = 0;
-#endif
 				PurpleRequestFieldType type;
 				GtkWidget *widget = NULL;
 				gchar *field_label;
@@ -2203,9 +2114,6 @@
 				field = fl->data;
 
 				if (!purple_request_field_is_visible(field)) {
-#if 0
-					col_num--;
-#endif
 					continue;
 				}
 
@@ -2239,18 +2147,10 @@
 						(type == PURPLE_REQUEST_FIELD_STRING &&
 						 purple_request_field_string_is_multiline(field)))
 					{
-#if 0
-						if(col_num > 0)
-							row_num++;
-#endif
-
 						gtk_grid_attach(GTK_GRID(grid), label,
 							0, row_num, 2 * cols, 1);
 
 						row_num++;
-#if 0
-						col_num=cols;
-#endif
 					}
 					else
 					{
@@ -2258,7 +2158,6 @@
 							col_offset, row_num, 1, 1);
 					}
 
-					gtk_widget_show(label);
 					g_free(field_label);
 				}
 
@@ -2321,8 +2220,6 @@
 						1, row_num, 2 * cols - 1, 1);
 				}
 
-				gtk_widget_show(widget);
-
 				purple_request_field_set_ui_data(field, widget);
 			}
 		}
@@ -2337,8 +2234,6 @@
 	if (!purple_request_fields_all_valid(fields))
 		gtk_widget_set_sensitive(data->ok_button, FALSE);
 
-	g_free(pages);
-
 	pidgin_auto_parent_window(win);
 
 	gtk_widget_show(win);
@@ -2349,7 +2244,7 @@
 static void
 file_ok_check_if_exists_cb(GtkWidget *widget, gint response, PidginRequestData *data)
 {
-	gchar *current_folder;
+	GFile *current_path;
 
 	if (response != GTK_RESPONSE_ACCEPT) {
 		if (data->cbs[0] != NULL)
@@ -2358,9 +2253,10 @@
 		return;
 	}
 
-	data->u.file.name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(data->dialog));
-	current_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(data->dialog));
-	if (current_folder != NULL) {
+	data->u.file.name = gtk_file_chooser_get_current_name(GTK_FILE_CHOOSER(data->dialog));
+	current_path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(data->dialog));
+	if (current_path != NULL) {
+		gchar *current_folder = g_file_get_path(current_path);
 		if (data->u.file.savedialog) {
 			purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_save_folder", current_folder);
 		} else {
@@ -2372,6 +2268,8 @@
 		((PurpleRequestFileCb)data->cbs[1])(data->user_data, data->u.file.name);
 	}
 	purple_request_close(data->type, data);
+
+	g_clear_object(&current_path);
 }
 
 static void *
@@ -2382,6 +2280,7 @@
 	PidginRequestData *data;
 	GtkFileChooserNative *filesel;
 #ifdef _WIN32
+	GFile *file = NULL;
 	const gchar *current_folder;
 	gboolean folder_set = FALSE;
 #endif
@@ -2402,14 +2301,17 @@
 	        savedialog ? GTK_FILE_CHOOSER_ACTION_SAVE
 	                   : GTK_FILE_CHOOSER_ACTION_OPEN,
 	        savedialog ? _("_Save") : _("_Open"), _("_Cancel"));
-	gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(filesel),
-	                                               TRUE);
 
 	if ((filename != NULL) && (*filename != '\0')) {
-		if (savedialog)
-			gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(filesel), filename);
-		else if (g_file_test(filename, G_FILE_TEST_EXISTS))
-			gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(filesel), filename);
+		GFile *path = g_file_new_for_path(filename);
+
+		if(savedialog) {
+			gtk_file_chooser_set_file(GTK_FILE_CHOOSER(filesel), path, NULL);
+		} else if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
+			gtk_file_chooser_set_file(GTK_FILE_CHOOSER(filesel), path, NULL);
+		}
+
+		g_object_unref(path);
 	}
 
 #ifdef _WIN32
@@ -2420,20 +2322,27 @@
 	}
 
 	if ((filename == NULL || *filename == '\0' || !g_file_test(filename, G_FILE_TEST_EXISTS)) &&
-				(current_folder != NULL) && (*current_folder != '\0')) {
-		folder_set = gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filesel), current_folder);
+		(current_folder != NULL) && (*current_folder != '\0'))
+	{
+		file = g_file_new_for_path(current_folder);
+		folder_set = gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filesel), file, NULL);
 	}
 
 	if (!folder_set && (filename == NULL || *filename == '\0' || !g_file_test(filename, G_FILE_TEST_EXISTS))) {
 		char *my_documents = wpurple_get_special_folder(CSIDL_PERSONAL);
 
+		g_clear_object(&file);
+
 		if (my_documents != NULL) {
+			file = g_file_new_for_path(my_documents);
 			gtk_file_chooser_set_current_folder(
-					GTK_FILE_CHOOSER(filesel), my_documents);
+					GTK_FILE_CHOOSER(filesel), file, NULL);
 
 			g_free(my_documents);
 		}
 	}
+
+	g_clear_object(&file);
 #endif
 
 	g_signal_connect(G_OBJECT(GTK_FILE_CHOOSER(filesel)), "response",
@@ -2471,8 +2380,14 @@
 	        title ? title : _("Select Folder..."), NULL,
 	        GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, _("_OK"), _("_Cancel"));
 
-	if ((dirname != NULL) && (*dirname != '\0'))
-		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dirsel), dirname);
+	if ((dirname != NULL) && (*dirname != '\0')) {
+		GFile *path = g_file_new_for_path(dirname);
+
+		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dirsel), path,
+		                                    NULL);
+
+		g_object_unref(path);
+	}
 
 	g_signal_connect(G_OBJECT(GTK_FILE_CHOOSER(dirsel)), "response",
 						G_CALLBACK(file_ok_check_if_exists_cb), data);
@@ -2529,7 +2444,7 @@
 	} else {
 		pidgin_window_detach_children(GTK_WINDOW(data->dialog));
 
-		gtk_widget_destroy(data->dialog);
+		gtk_window_destroy(GTK_WINDOW(data->dialog));
 	}
 
 	if (type == PURPLE_REQUEST_FIELDS)
--- a/pidgin/gtkroomlist.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkroomlist.c	Sun Aug 28 22:18:46 2022 -0500
@@ -27,7 +27,6 @@
 
 #include "gtkroomlist.h"
 
-#include "gtkutils.h"
 #include "pidginaccountchooser.h"
 
 #define PIDGIN_TYPE_ROOMLIST_DIALOG (pidgin_roomlist_dialog_get_type())
@@ -36,12 +35,20 @@
 
 #define PIDGIN_ROOMLIST_UI_DATA "pidgin-ui"
 
+enum {
+	RESPONSE_STOP = 0,
+	RESPONSE_LIST,
+	RESPONSE_ADD,
+	RESPONSE_JOIN,
+};
+
 struct _PidginRoomlistDialog {
 	GtkDialog parent;
 
 	GtkWidget *account_widget;
 	GtkWidget *progress;
 	GtkWidget *tree;
+	GtkTreeSelection *tree_selection;
 
 	GtkWidget *stop_button;
 	GtkWidget *list_button;
@@ -49,6 +56,8 @@
 	GtkWidget *join_button;
 	GtkWidget *close_button;
 
+	GtkWidget *popover;
+
 	PurpleAccount *account;
 	PurpleRoomlist *roomlist;
 
@@ -70,30 +79,27 @@
 	NUM_OF_COLUMNS,
 };
 
-static gboolean
-_search_func(GtkTreeModel *model, gint column, const gchar *key,
-             GtkTreeIter *iter, gpointer search_data)
-{
-	gboolean result;
-	gchar *name, *fold, *fkey;
 
-	gtk_tree_model_get(model, iter, column, &name, -1);
-	fold = g_utf8_casefold(name, -1);
-	fkey = g_utf8_casefold(key, -1);
-
-	result = (g_strstr_len(fold, strlen(fold), fkey) == NULL);
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static PurpleRoomlistRoom *
+pidgin_roomlist_get_selected(PidginRoomlistDialog *dialog)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model = NULL;
+	PurpleRoomlistRoom *room = NULL;
 
-	g_free(fold);
-	g_free(fkey);
-	g_free(name);
+	if(gtk_tree_selection_get_selected(dialog->tree_selection, &model, &iter)) {
+		gtk_tree_model_get(model, &iter, ROOM_COLUMN, &room, -1);
+	}
 
-	return result;
+	return room;
 }
 
-static gint delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d)
+static void
+pidgin_roomlist_close(PidginRoomlistDialog *dialog)
 {
-	PidginRoomlistDialog *dialog = PIDGIN_ROOMLIST_DIALOG(w);
-
 	if (dialog->roomlist && purple_roomlist_get_in_progress(dialog->roomlist))
 		purple_roomlist_cancel_get_list(dialog->roomlist);
 
@@ -116,30 +122,10 @@
 	}
 
 	dialog->progress = NULL;
-
-	return FALSE;
 }
 
 static void
-dialog_select_account_cb(GtkWidget *w, PidginRoomlistDialog *dialog) {
-	PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(w);
-	PurpleAccount *account = pidgin_account_chooser_get_selected(chooser);
-	gboolean change = (account != dialog->account);
-	dialog->account = account;
-
-	if (change && dialog->roomlist) {
-		PidginRoomlist *rl = NULL;
-
-		rl = g_object_get_data(G_OBJECT(dialog->roomlist),
-		                       PIDGIN_ROOMLIST_UI_DATA);
-
-		g_clear_object(&rl->model);
-		g_object_unref(dialog->roomlist);
-		dialog->roomlist = NULL;
-	}
-}
-
-static void list_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
+pidgin_roomlist_start_listing(PidginRoomlistDialog *dialog)
 {
 	PurpleConnection *gc;
 	PidginRoomlist *rl;
@@ -183,7 +169,8 @@
 	gtk_widget_set_sensitive(dialog->join_button, FALSE);
 }
 
-static void stop_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
+static void
+pidgin_roomlist_stop_listing(PidginRoomlistDialog *dialog)
 {
 	purple_roomlist_cancel_get_list(dialog->roomlist);
 
@@ -195,53 +182,21 @@
 	gtk_widget_set_sensitive(dialog->join_button, FALSE);
 }
 
-struct _menu_cb_info {
-	PurpleRoomlist *list;
-	PurpleRoomlistRoom *room;
-};
-
 static void
-selection_changed_cb(GtkTreeSelection *selection,
-                     PidginRoomlistDialog *dialog)
+pidgin_roomlist_add_to_blist(PidginRoomlistDialog *dialog)
 {
-	GtkTreeIter iter;
-	PurpleRoomlistRoom *room;
-	static struct _menu_cb_info *info;
-	PidginRoomlist *grl = NULL;
-
-	grl = g_object_get_data(G_OBJECT(dialog->roomlist),
-	                        PIDGIN_ROOMLIST_UI_DATA);
-
-	if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
-		gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter,
-		                   ROOM_COLUMN, &room,
-		                   -1);
+	char *name = NULL;
+	PurpleAccount *account = NULL;
+	PurpleConnection *gc = NULL;
+	PurpleProtocol *protocol = NULL;
+	PurpleRoomlistRoom *room = NULL;
 
-		info = g_new0(struct _menu_cb_info, 1);
-		info->list = dialog->roomlist;
-		info->room = room;
-
-		g_object_set_data_full(G_OBJECT(dialog->join_button), "room-info",
-							   info, g_free);
-		g_object_set_data(G_OBJECT(dialog->add_button), "room-info", info);
-
-		gtk_widget_set_sensitive(dialog->add_button, TRUE);
-		gtk_widget_set_sensitive(dialog->join_button, TRUE);
+	account = purple_roomlist_get_account(dialog->roomlist);
+	gc = purple_account_get_connection(account);
 
-		g_object_unref(room);
-	} else {
-		gtk_widget_set_sensitive(dialog->add_button, FALSE);
-		gtk_widget_set_sensitive(dialog->join_button, FALSE);
-	}
-}
+	room = pidgin_roomlist_get_selected(dialog);
 
-static void
-do_add_room_cb(G_GNUC_UNUSED GtkWidget *w, struct _menu_cb_info *info)
-{
-	char *name;
-	PurpleAccount *account = purple_roomlist_get_account(info->list);
-	PurpleConnection *gc = purple_account_get_connection(account);
-	PurpleProtocol *protocol = NULL;
+	g_return_if_fail(room != NULL);
 
 	if(gc != NULL) {
 		protocol = purple_connection_get_protocol(gc);
@@ -249,9 +204,9 @@
 
 	if(protocol != NULL && PURPLE_PROTOCOL_IMPLEMENTS(protocol, ROOMLIST, room_serialize)) {
 		name = purple_protocol_roomlist_room_serialize(PURPLE_PROTOCOL_ROOMLIST(protocol),
-		                                               info->room);
+		                                               room);
 	} else {
-		name = g_strdup(purple_roomlist_room_get_name(info->room));
+		name = g_strdup(purple_roomlist_room_get_name(room));
 	}
 
 	purple_blist_request_add_chat(account, NULL, NULL, name);
@@ -259,26 +214,135 @@
 	g_free(name);
 }
 
+static gboolean
+_search_func(GtkTreeModel *model, gint column, const gchar *key,
+             GtkTreeIter *iter, gpointer search_data)
+{
+	gboolean result;
+	gchar *name, *fold, *fkey;
+
+	gtk_tree_model_get(model, iter, column, &name, -1);
+	fold = g_utf8_casefold(name, -1);
+	fkey = g_utf8_casefold(key, -1);
+
+	result = (g_strstr_len(fold, strlen(fold), fkey) == NULL);
+
+	g_free(fold);
+	g_free(fkey);
+	g_free(name);
+
+	return result;
+}
+
 static void
-add_room_to_blist_cb(GtkButton *button, G_GNUC_UNUSED gpointer data)
+pidgin_roomlist_join(PidginRoomlistDialog *dialog)
+{
+	PurpleRoomlistRoom *room = NULL;
+
+	room = pidgin_roomlist_get_selected(dialog);
+
+	if(room != NULL) {
+		purple_roomlist_join_room(dialog->roomlist, room);
+	}
+}
+
+/******************************************************************************
+ * Actions
+ *****************************************************************************/
+static void
+pidgin_roomlist_add_to_blist_cb(G_GNUC_UNUSED GSimpleAction *action,
+				G_GNUC_UNUSED GVariant *parameter,
+                                gpointer data)
+{
+	pidgin_roomlist_add_to_blist(data);
+}
+
+
+static void
+pidgin_roomlist_join_cb(GSimpleAction *action, GVariant *parameter,
+                        gpointer data)
 {
-	struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
+	pidgin_roomlist_join(data);
+}
+
+static GActionEntry actions[] = {
+	{
+		.name = "add",
+		.activate = pidgin_roomlist_add_to_blist_cb,
+	}, {
+		.name = "join",
+		.activate = pidgin_roomlist_join_cb,
+	},
+};
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+pidgin_roomlist_response_cb(GtkDialog *gtk_dialog, gint response_id,
+                            gpointer data)
+{
+	PidginRoomlistDialog *dialog = PIDGIN_ROOMLIST_DIALOG(gtk_dialog);
 
-	if(info != NULL) {
-		do_add_room_cb(NULL, info);
+	switch(response_id) {
+	case RESPONSE_STOP:
+		pidgin_roomlist_stop_listing(dialog);
+		break;
+	case RESPONSE_LIST:
+		pidgin_roomlist_start_listing(dialog);
+		break;
+	case RESPONSE_ADD:
+		pidgin_roomlist_add_to_blist(dialog);
+		break;
+	case RESPONSE_JOIN:
+		pidgin_roomlist_join(dialog);
+		break;
+	case GTK_RESPONSE_CLOSE:
+	case GTK_RESPONSE_DELETE_EVENT:
+		gtk_window_destroy(GTK_WINDOW(gtk_dialog));
+		break;
+	}
+}
+
+static gboolean
+close_request_cb(GtkWidget *w, G_GNUC_UNUSED gpointer d)
+{
+	pidgin_roomlist_close(PIDGIN_ROOMLIST_DIALOG(w));
+
+	gtk_window_destroy(GTK_WINDOW(w));
+
+	return TRUE;
+}
+
+static void
+dialog_select_account_cb(G_GNUC_UNUSED GtkWidget *w, PidginRoomlistDialog *dialog) {
+	PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(w);
+	PurpleAccount *account = pidgin_account_chooser_get_selected(chooser);
+	gboolean change = (account != dialog->account);
+	dialog->account = account;
+
+	if (change && dialog->roomlist) {
+		PidginRoomlist *rl = NULL;
+
+		rl = g_object_get_data(G_OBJECT(dialog->roomlist),
+		                       PIDGIN_ROOMLIST_UI_DATA);
+
+		g_clear_object(&rl->model);
+		g_object_unref(dialog->roomlist);
+		dialog->roomlist = NULL;
 	}
 }
 
 static void
-do_join_cb(G_GNUC_UNUSED GtkWidget *w, struct _menu_cb_info *info) {
-	purple_roomlist_join_room(info->list, info->room);
-}
+selection_changed_cb(GtkTreeSelection *selection,
+                     PidginRoomlistDialog *dialog)
+{
+	gboolean found = FALSE;
 
-static void
-join_button_cb(GtkButton *button, G_GNUC_UNUSED gpointer data) {
-	struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
+	found = gtk_tree_selection_get_selected(selection, NULL, NULL);
 
-	purple_roomlist_join_room(info->list, info->room);
+	gtk_widget_set_sensitive(dialog->add_button, found);
+	gtk_widget_set_sensitive(dialog->join_button, found);
 }
 
 static void
@@ -289,72 +353,41 @@
 	PidginRoomlist *grl = NULL;
 	GtkTreeIter iter;
 	PurpleRoomlistRoom *room;
-	struct _menu_cb_info info;
 
 	grl = g_object_get_data(G_OBJECT(dialog->roomlist), PIDGIN_ROOMLIST_UI_DATA);
 
 	gtk_tree_model_get_iter(GTK_TREE_MODEL(grl->model), &iter, path);
 	gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &room, -1);
 
-	info.list = dialog->roomlist;
-	info.room = room;
-
-	do_join_cb(NULL, &info);
+	if(PURPLE_IS_ROOMLIST_ROOM(room)) {
+		purple_roomlist_join_room(dialog->roomlist, room);
+	}
 
 	g_clear_object(&room);
 }
 
-static gboolean
-room_click_cb(GtkWidget *tv, GdkEventButton *event, gpointer data) {
+static void
+room_click_cb(G_GNUC_UNUSED GtkGestureClick *self, gint n_press, gdouble x,
+              gdouble y, gpointer data)
+{
 	PidginRoomlistDialog *dialog = data;
-	GtkTreePath *path;
-	PidginRoomlist *grl = NULL;
-	PurpleRoomlistRoom *room;
-	GtkTreeIter iter;
-	GtkWidget *menu;
-	GtkWidget *menuitem;
-	static struct _menu_cb_info info; /* XXX? */
 
-	if (!gdk_event_triggers_context_menu((GdkEvent *)event))
-		return FALSE;
-
-	grl = g_object_get_data(G_OBJECT(dialog->roomlist), PIDGIN_ROOMLIST_UI_DATA);
-
-	/* Here we figure out which room was clicked */
-	if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL))
-		return FALSE;
-	gtk_tree_model_get_iter(GTK_TREE_MODEL(grl->model), &iter, path);
-	gtk_tree_path_free(path);
-	gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &room, -1);
+	if(n_press != 1) {
+		return;
+	}
 
-	info.list = dialog->roomlist;
-	info.room = room;
-
-	/* The current implementation isn't expecting a ref to unref the one we got
-	 * when we pulled the room out of the model.
-	 */
-	g_clear_object(&room);
-
-	menu = gtk_menu_new();
+	if(!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(dialog->tree), (gint)x,
+	                                  (gint)y, NULL, NULL, NULL, NULL))
+	{
+		return;
+	}
 
-	menuitem = gtk_menu_item_new_with_mnemonic(_("_Join"));
-	g_signal_connect(G_OBJECT(menuitem), "activate",
-	                 G_CALLBACK(do_join_cb), &info);
-	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+	gtk_popover_set_pointing_to(GTK_POPOVER(dialog->popover),
+	                            &(const GdkRectangle){(int)x, (int)y, 0, 0});
 
-	menuitem = gtk_menu_item_new_with_mnemonic(_("_Add"));
-	g_signal_connect(G_OBJECT(menuitem), "activate",
-	                 G_CALLBACK(do_add_room_cb), &info);
-	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-
-	gtk_widget_show_all(menu);
-	gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
-
-	return FALSE;
+	gtk_popover_popup(GTK_POPOVER(dialog->popover));
 }
 
-#define SMALL_SPACE 6
-
 static gboolean
 pidgin_roomlist_query_tooltip(GtkWidget *widget, int x, int y,
                               gboolean keyboard_mode, GtkTooltip *tooltip,
@@ -370,8 +403,7 @@
 	grl = g_object_get_data(G_OBJECT(dialog->roomlist), PIDGIN_ROOMLIST_UI_DATA);
 
 	if (keyboard_mode) {
-		GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
-		if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) {
+		if (!gtk_tree_selection_get_selected(dialog->tree_selection, NULL, &iter)) {
 			return FALSE;
 		}
 		path = gtk_tree_model_get_path(GTK_TREE_MODEL(grl->model), &iter);
@@ -449,6 +481,8 @@
 	gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
 	                                     tree);
 	gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
+	                                     tree_selection);
+	gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
 	                                     add_button);
 	gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
 	                                     close_button);
@@ -460,10 +494,10 @@
 	                                     progress);
 	gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
 	                                     stop_button);
+	gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
+	                                     popover);
 
-	gtk_widget_class_bind_template_callback(widget_class,
-	                                        add_room_to_blist_cb);
-	gtk_widget_class_bind_template_callback(widget_class, delete_win_cb);
+	gtk_widget_class_bind_template_callback(widget_class, close_request_cb);
 	gtk_widget_class_bind_template_callback(widget_class, row_activated_cb);
 	gtk_widget_class_bind_template_callback(widget_class, room_click_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
@@ -472,14 +506,15 @@
 	                                        selection_changed_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_roomlist_query_tooltip);
-	gtk_widget_class_bind_template_callback(widget_class, join_button_cb);
-	gtk_widget_class_bind_template_callback(widget_class, list_button_cb);
-	gtk_widget_class_bind_template_callback(widget_class, stop_button_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_roomlist_response_cb);
 }
 
 static void
 pidgin_roomlist_dialog_init(PidginRoomlistDialog *self)
 {
+	GSimpleActionGroup *group = NULL;
+
 	gtk_widget_init_template(GTK_WIDGET(self));
 
 	pidgin_account_chooser_set_filter_func(
@@ -488,6 +523,13 @@
 
 	gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(self->tree),
 	                                    _search_func, NULL, NULL);
+
+	/* Now setup our actions. */
+	group = g_simple_action_group_new();
+	g_action_map_add_action_entries(G_ACTION_MAP(group), actions,
+	                                G_N_ELEMENTS(actions), self);
+	gtk_widget_insert_action_group(GTK_WIDGET(self), "roomlist",
+	                               G_ACTION_GROUP(group));
 }
 
 static PidginRoomlistDialog *
@@ -519,10 +561,7 @@
 {
 	PidginRoomlistDialog *dialog = pidgin_roomlist_dialog_new_with_account(account);
 
-	if (!dialog)
-		return;
-
-	list_button_cb(GTK_BUTTON(dialog->list_button), dialog);
+	pidgin_roomlist_start_listing(dialog);
 }
 
 void pidgin_roomlist_dialog_show(void)
@@ -604,18 +643,12 @@
 }
 
 static void
-pidgin_roomlist_destroy(PidginRoomlist *rl)
-{
-	g_free(rl);
-}
-
-static void
 pidgin_roomlist_new(PurpleRoomlist *list)
 {
 	PidginRoomlist *rl = g_new0(PidginRoomlist, 1);
 
 	g_object_set_data_full(G_OBJECT(list), PIDGIN_ROOMLIST_UI_DATA, rl,
-	                       (GDestroyNotify)pidgin_roomlist_destroy);
+	                       (GDestroyNotify)g_free);
 
 	rl->model = gtk_tree_store_new(3, G_TYPE_OBJECT, G_TYPE_STRING,
 	                               G_TYPE_STRING);
--- a/pidgin/gtkutils.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkutils.c	Sun Aug 28 22:18:46 2022 -0500
@@ -71,11 +71,6 @@
  * Structs
  *****************************************************************************/
 
-typedef struct {
-	GtkTreeModel *model;
-	gint default_item;
-} AopMenu;
-
 typedef struct
 {
 	GtkWidget *entry;
@@ -87,13 +82,6 @@
 	GtkListStore *store;
 } PidginCompletionData;
 
-struct _icon_chooser {
-	GtkFileChooserNative *icon_filesel;
-
-	void (*callback)(const char*,gpointer);
-	gpointer data;
-};
-
 /******************************************************************************
  * Code
  *****************************************************************************/
@@ -106,8 +94,7 @@
 	char *labeltitle;
 
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-	gtk_box_pack_start(GTK_BOX(parent), vbox, FALSE, FALSE, 0);
-	gtk_widget_show(vbox);
+	gtk_box_append(GTK_BOX(parent), vbox);
 
 	label = GTK_LABEL(gtk_label_new(NULL));
 
@@ -117,79 +104,23 @@
 
 	gtk_label_set_xalign(GTK_LABEL(label), 0);
 	gtk_label_set_yalign(GTK_LABEL(label), 0);
-	gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(label), FALSE, FALSE, 0);
-	gtk_widget_show(GTK_WIDGET(label));
+	gtk_box_append(GTK_BOX(vbox), GTK_WIDGET(label));
 	pidgin_set_accessible_label(vbox, label);
 
 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-	gtk_widget_show(hbox);
+	gtk_box_append(GTK_BOX (vbox), hbox);
 
 	label = GTK_LABEL(gtk_label_new("    "));
-	gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), FALSE, FALSE, 0);
-	gtk_widget_show(GTK_WIDGET(label));
+	gtk_box_append(GTK_BOX(hbox), GTK_WIDGET(label));
 
 	vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-	gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 0);
-	gtk_widget_show(vbox2);
+	gtk_box_append(GTK_BOX(hbox), vbox2);
 
 	g_object_set_data(G_OBJECT(vbox2), "main-vbox", vbox);
 
 	return vbox2;
 }
 
-GdkPixbuf *
-pidgin_create_icon_from_protocol(PurpleProtocol *protocol,
-                                 PidginProtocolIconSize size,
-                                 PurpleAccount *account)
-{
-	GdkPixbuf *pixbuf;
-	const char *protoname = NULL;
-	const gchar *icon_name = NULL;
-	char *tmp;
-	GtkIconTheme *theme = NULL;
-	gint dimensions = 0;
-
-	theme = gtk_icon_theme_get_default();
-	if(size == PIDGIN_PROTOCOL_ICON_SMALL) {
-		dimensions = 16;
-	} else if(size == PIDGIN_PROTOCOL_ICON_MEDIUM) {
-		dimensions = 22;
-	} else {
-		dimensions = 48;
-	}
-
-	/* If the protocol specified an icon-name try to load it from the icon
-	 * theme.
-	 */
-	icon_name = purple_protocol_get_icon_name(protocol);
-	if(icon_name != NULL) {
-		pixbuf = gtk_icon_theme_load_icon(theme, icon_name, dimensions,
-		                                  GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
-
-		if(GDK_IS_PIXBUF(pixbuf)) {
-			return pixbuf;
-		}
-
-	}
-
-	protoname = purple_protocol_get_list_icon(protocol, account, NULL);
-	if (protoname == NULL) {
-		return NULL;
-	}
-
-	/*
-	 * Status icons will be themeable too, and then it will look up
-	 * protoname from the theme
-	 */
-	tmp = g_strconcat("im-", protoname, NULL);
-	pixbuf = gtk_icon_theme_load_icon(theme, tmp, dimensions,
-					  GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
-	g_free(tmp);
-
-	return pixbuf;
-}
-
 static void
 aop_option_menu_select_by_data(GtkWidget *optmenu, gpointer data)
 {
@@ -244,52 +175,23 @@
 void
 pidgin_set_accessible_label(GtkWidget *w, GtkLabel *l)
 {
-	AtkObject *acc;
-	const gchar *label_text;
-	const gchar *existing_name;
-
-	acc = gtk_widget_get_accessible (w);
-
-	/* If this object has no name, set it's name with the label text */
-	existing_name = atk_object_get_name (acc);
-	if (!existing_name) {
-		label_text = gtk_label_get_text(l);
-		if (label_text)
-			atk_object_set_name (acc, label_text);
-	}
-
 	pidgin_set_accessible_relations(w, l);
 }
 
 void
 pidgin_set_accessible_relations (GtkWidget *w, GtkLabel *l)
 {
-	AtkObject *acc, *label;
-	AtkObject *rel_obj[1];
-	AtkRelationSet *set;
-	AtkRelation *relation;
+	GtkAccessible *acc, *label;
 
-	acc = gtk_widget_get_accessible (w);
-	label = gtk_widget_get_accessible(GTK_WIDGET(l));
+	acc = GTK_ACCESSIBLE(w);
+	label = GTK_ACCESSIBLE(l);
 
 	/* Make sure mnemonics work */
 	gtk_label_set_mnemonic_widget(l, w);
 
 	/* Create the labeled-by relation */
-	set = atk_object_ref_relation_set (acc);
-	rel_obj[0] = label;
-	relation = atk_relation_new (rel_obj, 1, ATK_RELATION_LABELLED_BY);
-	atk_relation_set_add (set, relation);
-	g_object_unref (relation);
-	g_object_unref(set);
-
-	/* Create the label-for relation */
-	set = atk_object_ref_relation_set (label);
-	rel_obj[0] = acc;
-	relation = atk_relation_new (rel_obj, 1, ATK_RELATION_LABEL_FOR);
-	atk_relation_set_add (set, relation);
-	g_object_unref (relation);
-	g_object_unref(set);
+	gtk_accessible_update_relation(acc, GTK_ACCESSIBLE_RELATION_LABELLED_BY,
+	                               label, NULL, -1);
 }
 
 void pidgin_buddy_icon_get_scale_size(GdkPixbuf *buf, PurpleBuddyIconSpec *spec, PurpleBuddyIconScaleFlags rules, int *width, int *height)
@@ -309,19 +211,6 @@
 		*height = 100;
 }
 
-GdkPixbuf *
-pidgin_create_protocol_icon(PurpleAccount *account, PidginProtocolIconSize size)
-{
-	PurpleProtocol *protocol;
-
-	g_return_val_if_fail(account != NULL, NULL);
-
-	protocol = purple_account_get_protocol(account);
-	if (protocol == NULL)
-		return NULL;
-	return pidgin_create_icon_from_protocol(protocol, size, account);
-}
-
 static gboolean buddyname_completion_match_func(GtkEntryCompletion *completion,
 		const gchar *key, GtkTreeIter *iter, gpointer user_data)
 {
@@ -362,7 +251,7 @@
 
 	val.g_type = 0;
 	gtk_tree_model_get_value(model, iter, COMPLETION_BUDDY_COLUMN, &val);
-	gtk_entry_set_text(GTK_ENTRY(data->entry), g_value_get_string(&val));
+	gtk_editable_set_text(GTK_EDITABLE(data->entry), g_value_get_string(&val));
 	g_value_unset(&val);
 
 	gtk_tree_model_get_value(model, iter, COMPLETION_ACCOUNT_COLUMN, &val);
@@ -888,64 +777,6 @@
 	return result;
 }
 
-static void
-combo_box_changed_cb(GtkComboBoxText *combo_box, GtkEntry *entry)
-{
-	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(G_GNUC_UNUSED GtkEventControllerKey *controller,
-                     guint keyval, G_GNUC_UNUSED guint keycode,
-                     G_GNUC_UNUSED GdkModifierType state,
-                     gpointer data)
-{
-	GtkComboBoxText *combo = data;
-
-	if (keyval == GDK_KEY_Down || keyval == GDK_KEY_Up) {
-		gtk_combo_box_popup(GTK_COMBO_BOX(combo));
-		return TRUE;
-	}
-	return FALSE;
-}
-
-GtkWidget *
-pidgin_text_combo_box_entry_new(const char *default_item, GList *items)
-{
-	GtkComboBoxText *ret = NULL;
-	GtkWidget *the_entry = NULL;
-	GtkEventController *controller = NULL;
-
-	ret = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new_with_entry());
-	the_entry = gtk_bin_get_child(GTK_BIN(ret));
-
-	if (default_item)
-		gtk_entry_set_text(GTK_ENTRY(the_entry), default_item);
-
-	for (; items != NULL ; items = items->next) {
-		char *text = items->data;
-		if (text && *text)
-			gtk_combo_box_text_append_text(ret, text);
-	}
-
-	g_signal_connect(G_OBJECT(ret), "changed", (GCallback)combo_box_changed_cb, the_entry);
-
-	controller = gtk_event_controller_key_new(the_entry);
-	g_object_set_data_full(G_OBJECT(the_entry), "pidgin-event-controller",
-	                       controller, g_object_unref);
-	g_signal_connect_after(G_OBJECT(controller), "key-pressed",
-	                       G_CALLBACK(entry_key_pressed_cb), ret);
-
-	return GTK_WIDGET(ret);
-}
-
-const char *pidgin_text_combo_box_entry_get_text(GtkWidget *widget)
-{
-	return gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((widget)))));
-}
-
 GtkWidget *
 pidgin_add_widget_to_vbox(GtkBox *vbox, const char *widget_label, GtkSizeGroup *sg, GtkWidget *widget, gboolean expand, GtkWidget **p_label)
 {
@@ -954,22 +785,26 @@
 
 	if (widget_label) {
 		hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
-		gtk_widget_show(hbox);
-		gtk_box_pack_start(vbox, hbox, FALSE, FALSE, 0);
+		gtk_box_append(vbox, hbox);
 
 		label = gtk_label_new_with_mnemonic(widget_label);
-		gtk_widget_show(label);
 		if (sg) {
 			gtk_label_set_xalign(GTK_LABEL(label), 0);
 			gtk_size_group_add_widget(sg, label);
 		}
-		gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+		gtk_box_append(GTK_BOX(hbox), label);
+
+		gtk_widget_set_hexpand(widget, expand);
+		gtk_widget_set_halign(widget, GTK_ALIGN_FILL);
+		gtk_box_append(GTK_BOX(hbox), widget);
 	} else {
+		gtk_widget_set_vexpand(widget, expand);
+		gtk_widget_set_valign(widget, GTK_ALIGN_FILL);
+		gtk_box_append(vbox, widget);
+
 		hbox = GTK_WIDGET(vbox);
 	}
 
-	gtk_widget_show(widget);
-	gtk_box_pack_start(GTK_BOX(hbox), widget, expand, TRUE, 0);
 	if (label) {
 		gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget);
 		pidgin_set_accessible_label(widget, GTK_LABEL(label));
@@ -982,67 +817,9 @@
 
 gboolean pidgin_auto_parent_window(GtkWidget *widget)
 {
-#if 0
-	/* This looks at the most recent window that received focus, and makes
-	 * that the parent window. */
-#ifndef _WIN32
-	static GdkAtom _WindowTime = GDK_NONE;
-	static GdkAtom _Cardinal = GDK_NONE;
-	GList *windows = NULL;
-	GtkWidget *parent = NULL;
-	time_t window_time = 0;
-
-	windows = gtk_window_list_toplevels();
-
-	if (_WindowTime == GDK_NONE) {
-		_WindowTime = gdk_x11_xatom_to_atom(gdk_x11_get_xatom_by_name("_NET_WM_USER_TIME"));
-	}
-	if (_Cardinal == GDK_NONE) {
-		_Cardinal = gdk_atom_intern("CARDINAL", FALSE);
-	}
-
-	while (windows) {
-		GtkWidget *window = windows->data;
-		guchar *data = NULL;
-		int al = 0;
-		time_t value;
-
-		windows = g_list_delete_link(windows, windows);
-
-		if (window == widget ||
-				!gtk_widget_get_visible(window))
-			continue;
-
-		if (!gdk_property_get(window->window, _WindowTime, _Cardinal, 0, sizeof(time_t), FALSE,
-				NULL, NULL, &al, &data))
-			continue;
-		value = *(time_t *)data;
-		if (window_time < value) {
-			window_time = value;
-			parent = window;
-		}
-		g_free(data);
-	}
-	if (windows)
-		g_list_free(windows);
-	if (parent) {
-		if (!gtk_get_current_event() && gtk_window_has_toplevel_focus(GTK_WINDOW(parent))) {
-			/* The window is in focus, and the new window was not triggered by a keypress/click
-			 * event. So do not set it transient, to avoid focus stealing and all that.
-			 */
-			return FALSE;
-		}
-		gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(parent));
-		return TRUE;
-	}
-	return FALSE;
-#endif
-#else
 	/* This finds the currently active window and makes that the parent window. */
 	GList *windows = NULL;
 	GtkWindow *parent = NULL;
-	GdkEvent *event = gtk_get_current_event();
-	GdkWindow *menu = NULL;
 	gpointer parent_from;
 	PurpleNotifyType notify_type;
 
@@ -1062,20 +839,6 @@
 		return TRUE;
 	}
 
-	if (event == NULL)
-		/* The window was not triggered by a user action. */
-		return FALSE;
-
-	/* We need to special case events from a popup menu. */
-	if (event->type == GDK_BUTTON_RELEASE) {
-		/* XXX: Neither of the following works:
-			menu = event->button.window;
-			menu = gdk_window_get_parent(event->button.window);
-			menu = gdk_window_get_toplevel(event->button.window);
-		*/
-	} else if (event->type == GDK_KEY_PRESS)
-		menu = event->key.window;
-
 	windows = gtk_window_list_toplevels();
 	while (windows) {
 		GtkWindow *window = GTK_WINDOW(windows->data);
@@ -1093,8 +856,7 @@
 			continue;
 		}
 
-		if (gtk_window_has_toplevel_focus(window) ||
-				(menu && menu == gtk_widget_get_window(GTK_WIDGET(window)))) {
+		if (gtk_window_is_active(window)) {
 			parent = window;
 			break;
 		}
@@ -1106,26 +868,4 @@
 		return TRUE;
 	}
 	return FALSE;
-#endif
 }
-
-GtkWidget *
-pidgin_make_scrollable(GtkWidget *child, GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy, GtkShadowType shadow_type, int width, int height)
-{
-	GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
-
-	if (G_LIKELY(sw)) {
-		gtk_widget_show(sw);
-		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), hscrollbar_policy, vscrollbar_policy);
-		gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), shadow_type);
-		if (width != -1 || height != -1)
-			gtk_widget_set_size_request(sw, width, height);
-		if (child) {
-			gtk_container_add(GTK_CONTAINER(sw), child);
-		}
-		return sw;
-	}
-
-	return child;
-}
-
--- a/pidgin/gtkutils.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkutils.h	Sun Aug 28 22:18:46 2022 -0500
@@ -140,44 +140,6 @@
 void pidgin_buddy_icon_get_scale_size(GdkPixbuf *buf, PurpleBuddyIconSpec *spec, PurpleBuddyIconScaleFlags rules, int *width, int *height);
 
 /**
- * pidgin_create_protocol_icon:
- * @account:      The account.
- * @size:         The size of the icon to return.
- *
- * Returns the base image to represent the account, based on
- * the currently selected theme.
- *
- * Returns: (transfer full): A newly-created pixbuf with a reference count of 1,
- *         or NULL if any of several error conditions occurred:
- *         the file could not be opened, there was no loader
- *         for the file's format, there was not enough memory
- *         to allocate the image buffer, or the image file
- *         contained invalid data.
- */
-GdkPixbuf *pidgin_create_protocol_icon(PurpleAccount *account, PidginProtocolIconSize size);
-
-/**
- * pidgin_create_icon_from_protocol:
- * @protocol: The #PurpleProtocol instance.
- * @size: The size of the icon to return.
- * @account: (nullable): An optional #PurpleAccount to use.
- *
- * Returns the base image to represent @protocol based on the currently
- * selected theme.  If @account is not %NULL then the returned icon will
- * represent the account.
- *
- * Returns: (transfer full): A newly-created pixbuf with a reference count of 1,
- *         or NULL if any of several error conditions occurred:
- *         the file could not be opened, there was no loader
- *         for the file's format, there was not enough memory
- *         to allocate the image buffer, or the image file
- *         contained invalid data.
- *
- * Since: 3.0.0
- */
-GdkPixbuf *pidgin_create_icon_from_protocol(PurpleProtocol *protocol, PidginProtocolIconSize size, PurpleAccount *account);
-
-/**
  * pidgin_convert_buddy_icon:
  * @protocol:   The protocol to convert the icon
  * @path:       The path of a file to convert
@@ -203,28 +165,6 @@
 			const gchar *key, GtkTreeIter *iter, gpointer data);
 
 /**
- * pidgin_text_combo_box_entry_new:
- * @default_item: Initial contents of GtkEntry
- * @items: (element-type utf8): GList containing strings to add to GtkComboBox
- *
- * Create a simple text GtkComboBoxEntry equivalent
- *
- * Returns: (transfer full): A newly created text GtkComboBox containing a GtkEntry
- *          child.
- */
-GtkWidget *pidgin_text_combo_box_entry_new(const char *default_item, GList *items);
-
-/**
- * pidgin_text_combo_box_entry_get_text:
- * @widget:         The simple text GtkComboBoxEntry equivalent widget
- *
- * Retrieve the text from the entry of the simple text GtkComboBoxEntry equivalent
- *
- * Returns:               The text in the widget's entry. It must not be freed
- */
-const char *pidgin_text_combo_box_entry_get_text(GtkWidget *widget);
-
-/**
  * pidgin_auto_parent_window:
  * @window:    The window to make transient.
  *
@@ -249,21 +189,6 @@
  */
 GtkWidget *pidgin_add_widget_to_vbox(GtkBox *vbox, const char *widget_label, GtkSizeGroup *sg, GtkWidget *widget, gboolean expand, GtkWidget **p_label);
 
-/**
- * pidgin_make_scrollable:
- * @child:              The child widget
- * @hscrollbar_policy:  Horizontal scrolling policy
- * @vscrollbar_policy:  Vertical scrolling policy
- * @shadow_type:        Shadow type
- * @width:              Desired widget width, or -1 for default
- * @height:             Desired widget height, or -1 for default
- *
- * Add scrollbars to a widget
- *
- * Returns: (transfer full): A scrolled window with @child packed inside of it.
- */
-GtkWidget *pidgin_make_scrollable(GtkWidget *child, GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy, GtkShadowType shadow_type, int width, int height);
-
 G_END_DECLS
 
 #endif /* _PIDGINUTILS_H_ */
--- a/pidgin/gtkwhiteboard.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkwhiteboard.c	Sun Aug 28 22:18:46 2022 -0500
@@ -32,12 +32,6 @@
 #include "gtkwhiteboard.h"
 #include "gtkutils.h"
 
-typedef enum {
-	PIDGIN_WHITEBOARD_BRUSH_UP,
-	PIDGIN_WHITEBOARD_BRUSH_DOWN,
-	PIDGIN_WHITEBOARD_BRUSH_MOTION
-} PidginWhiteboardBrushState;
-
 #define UI_DATA "pidgin-ui-data"
 #define PIDGIN_TYPE_WHITEBOARD (pidgin_whiteboard_get_type())
 G_DECLARE_FINAL_TYPE(PidginWhiteboard, pidgin_whiteboard, PIDGIN, WHITEBOARD,
@@ -74,13 +68,12 @@
 	int height;
 	int brush_color;
 	int brush_size;
-	PidginWhiteboardBrushState brush_state;
 
 	/* Tracks last position of the mouse when drawing */
-	gint last_x;
-	gint last_y;
-	/* Tracks how many brush motions made */
-	gint motion_count;
+	gdouble start_x;
+	gdouble start_y;
+	gdouble last_x;
+	gdouble last_y;
 };
 
 G_DEFINE_TYPE(PidginWhiteboard, pidgin_whiteboard, GTK_TYPE_WINDOW)
@@ -94,7 +87,7 @@
 	color->red = ((color_rgb >> 16) & 0xFF) / 255.0f;
 	color->green = ((color_rgb >> 8) & 0xFF) / 255.0f;
 	color->blue = (color_rgb & 0xFF) / 255.0f;
-	color->alpha = 1.0;
+	color->alpha = 1.0f;
 }
 
 static gboolean
@@ -108,30 +101,24 @@
 	return FALSE;
 }
 
-static gboolean pidgin_whiteboard_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
+static void
+pidgin_whiteboard_resize(GtkDrawingArea *self, gint width, gint height,
+                         gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
+	GdkRGBA white = {1.0f, 1.0f, 1.0f, 1.0f};
 	cairo_t *cr;
-	GtkAllocation allocation;
-	GdkRGBA white = {1.0, 1.0, 1.0, 1.0};
 
-	if (gtkwb->cr) {
-		cairo_destroy(gtkwb->cr);
-	}
-	if (gtkwb->surface) {
-		cairo_surface_destroy(gtkwb->surface);
-	}
+	g_clear_pointer(&gtkwb->cr, cairo_destroy);
+	g_clear_pointer(&gtkwb->surface, cairo_surface_destroy);
 
-	gtk_widget_get_allocation(widget, &allocation);
-
-	gtkwb->surface = cairo_image_surface_create(
-	        CAIRO_FORMAT_RGB24, allocation.width, allocation.height);
+	gtkwb->surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width,
+	                                            height);
 	gtkwb->cr = cr = cairo_create(gtkwb->surface);
+
 	gdk_cairo_set_source_rgba(cr, &white);
-	cairo_rectangle(cr, 0, 0, allocation.width, allocation.height);
+	cairo_rectangle(cr, 0, 0, width, height);
 	cairo_fill(cr);
-
-	return TRUE;
 }
 
 static gboolean
@@ -147,18 +134,6 @@
 }
 
 static void
-pidgin_whiteboard_set_canvas_as_icon(PidginWhiteboard *gtkwb)
-{
-	GdkPixbuf *pixbuf;
-
-	/* Makes an icon from the whiteboard's canvas 'image' */
-	pixbuf = gdk_pixbuf_get_from_surface(gtkwb->surface, 0, 0, gtkwb->width,
-	                                     gtkwb->height);
-	gtk_window_set_icon(GTK_WINDOW(gtkwb), pixbuf);
-	g_object_unref(pixbuf);
-}
-
-static void
 pidgin_whiteboard_draw_brush_point(PurpleWhiteboard *wb, int x, int y,
                                    int color, int size)
 {
@@ -175,9 +150,9 @@
 	cairo_arc(gfx_con, x, y, size / 2.0, 0.0, 2.0 * M_PI);
 	cairo_fill(gfx_con);
 
-	gtk_widget_queue_draw_area(widget, x - size / 2, y - size / 2, size,
-	                           size);
+	gtk_widget_queue_draw(widget);
 }
+
 /* Uses Bresenham's algorithm (as provided by Wikipedia) */
 static void
 pidgin_whiteboard_draw_brush_line(PurpleWhiteboard *wb, int x0, int y0, int x1,
@@ -254,179 +229,86 @@
 	}
 }
 
-static gboolean pidgin_whiteboard_brush_down(GtkWidget *widget, GdkEventButton *event, gpointer data)
+static void
+pidgin_whiteboard_brush_down(GtkGestureDrag* self, gdouble x, gdouble y,
+                             gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = purple_whiteboard_get_draw_list(wb);
 
-	if (gtkwb->brush_state != PIDGIN_WHITEBOARD_BRUSH_UP) {
-		/* Potential double-click DOWN to DOWN? */
-		gtkwb->brush_state = PIDGIN_WHITEBOARD_BRUSH_DOWN;
-
-		/* return FALSE; */
-	}
-
-	gtkwb->brush_state = PIDGIN_WHITEBOARD_BRUSH_DOWN;
-
-	if (event->button == GDK_BUTTON_PRIMARY && gtkwb->cr != NULL) {
+	if(gtkwb->cr != NULL) {
 		/* Check if draw_list has contents; if so, clear it */
-		if(draw_list)
-		{
+		if(draw_list) {
 			purple_whiteboard_draw_list_destroy(draw_list);
 			draw_list = NULL;
 		}
 
 		/* Set tracking variables */
-		gtkwb->last_x = event->x;
-		gtkwb->last_y = event->y;
+		gtkwb->start_x = x;
+		gtkwb->start_y = y;
 
-		gtkwb->motion_count = 0;
+		gtkwb->last_x = 0;
+		gtkwb->last_y = 0;
 
-		draw_list = g_list_append(draw_list,
-		                          GINT_TO_POINTER(gtkwb->last_x));
-		draw_list = g_list_append(draw_list,
-		                          GINT_TO_POINTER(gtkwb->last_y));
+		draw_list = g_list_append(draw_list, GINT_TO_POINTER(gtkwb->start_x));
+		draw_list = g_list_append(draw_list, GINT_TO_POINTER(gtkwb->start_y));
 
-		pidgin_whiteboard_draw_brush_point(gtkwb->wb,
-											 event->x, event->y,
-											 gtkwb->brush_color, gtkwb->brush_size);
+		pidgin_whiteboard_draw_brush_point(gtkwb->wb, gtkwb->start_x,
+		                                   gtkwb->start_y, gtkwb->brush_color,
+		                                   gtkwb->brush_size);
 	}
 
 	purple_whiteboard_set_draw_list(wb, draw_list);
-
-	return TRUE;
 }
 
-static gboolean pidgin_whiteboard_brush_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
+static void
+pidgin_whiteboard_brush_motion(GtkGestureDrag* self, gdouble x, gdouble y,
+                               gpointer data)
 {
-	int x;
-	int y;
-	int dx;
-	int dy;
-
-	GdkModifierType state;
-
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = purple_whiteboard_get_draw_list(wb);
 
-	if(event->is_hint)
-		gdk_window_get_device_position(event->window, event->device, &x, &y,
-		                               &state);
-	else
-	{
-		x = event->x;
-		y = event->y;
-		state = event->state;
-	}
-
-	if (state & GDK_BUTTON1_MASK && gtkwb->cr != NULL) {
-		if ((gtkwb->brush_state != PIDGIN_WHITEBOARD_BRUSH_DOWN) &&
-		    (gtkwb->brush_state != PIDGIN_WHITEBOARD_BRUSH_MOTION)) {
-			purple_debug_error(
-			        "gtkwhiteboard",
-			        "***Bad brush state transition %d to MOTION\n",
-			        gtkwb->brush_state);
-
-			gtkwb->brush_state = PIDGIN_WHITEBOARD_BRUSH_MOTION;
-
-			return FALSE;
-		}
-		gtkwb->brush_state = PIDGIN_WHITEBOARD_BRUSH_MOTION;
-
-		dx = x - gtkwb->last_x;
-		dy = y - gtkwb->last_y;
-
-		gtkwb->motion_count++;
+	if (gtkwb->cr != NULL) {
+		gdouble dx, dy;
 
-		/* NOTE 100 is a temporary constant for how many deltas/motions in a
-		 * stroke (needs UI Ops?)
+		/* x and y are relative to the starting post, but we need to know where
+		 * there are according to the last point, so we have to do the algebra.
 		 */
-		if (gtkwb->motion_count == 100) {
-			draw_list = g_list_append(draw_list, GINT_TO_POINTER(dx));
-			draw_list = g_list_append(draw_list, GINT_TO_POINTER(dy));
-
-			/* Send draw list to the draw_list handler */
-			purple_whiteboard_send_draw_list(gtkwb->wb, draw_list);
-
-			/* The brush stroke is finished, clear the list for another one */
-			if(draw_list)
-			{
-				purple_whiteboard_draw_list_destroy(draw_list);
-				draw_list = NULL;
-			}
-
-			/* Reset motion tracking */
-			gtkwb->motion_count = 0;
-
-			draw_list = g_list_append(
-			        draw_list, GINT_TO_POINTER(gtkwb->last_x));
-			draw_list = g_list_append(
-			        draw_list, GINT_TO_POINTER(gtkwb->last_y));
-
-			dx = x - gtkwb->last_x;
-			dy = y - gtkwb->last_y;
-		}
+		dx = (x + gtkwb->start_x - gtkwb->last_x);
+		dy = (y + gtkwb->start_y - gtkwb->last_y);
 
 		draw_list = g_list_append(draw_list, GINT_TO_POINTER(dx));
 		draw_list = g_list_append(draw_list, GINT_TO_POINTER(dy));
 
-		pidgin_whiteboard_draw_brush_line(
-		        gtkwb->wb, gtkwb->last_x, gtkwb->last_y, x, y,
-		        gtkwb->brush_color, gtkwb->brush_size);
+		pidgin_whiteboard_draw_brush_line(gtkwb->wb,
+		                                  gtkwb->start_x + gtkwb->last_x,
+		                                  gtkwb->start_y + gtkwb->last_y,
+		                                  gtkwb->start_x + x,
+		                                  gtkwb->start_y + y,
+		                                  gtkwb->brush_color,
+		                                  gtkwb->brush_size);
 
-		/* Set tracking variables */
 		gtkwb->last_x = x;
 		gtkwb->last_y = y;
 	}
 
 	purple_whiteboard_set_draw_list(wb, draw_list);
-
-	return TRUE;
 }
 
-static gboolean pidgin_whiteboard_brush_up(GtkWidget *widget, GdkEventButton *event, gpointer data)
+static void
+pidgin_whiteboard_brush_up(GtkGestureDrag *self, gdouble x, gdouble y,
+                           gpointer data)
 {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)data;
-
 	PurpleWhiteboard *wb = gtkwb->wb;
 	GList *draw_list = purple_whiteboard_get_draw_list(wb);
 
-	if ((gtkwb->brush_state != PIDGIN_WHITEBOARD_BRUSH_DOWN) &&
-	    (gtkwb->brush_state != PIDGIN_WHITEBOARD_BRUSH_MOTION)) {
-		purple_debug_error("gtkwhiteboard",
-		                   "***Bad brush state transition %d to UP\n",
-		                   gtkwb->brush_state);
-
-		gtkwb->brush_state = PIDGIN_WHITEBOARD_BRUSH_UP;
-
-		return FALSE;
-	}
-	gtkwb->brush_state = PIDGIN_WHITEBOARD_BRUSH_UP;
-
-	if (event->button == GDK_BUTTON_PRIMARY && gtkwb->cr != NULL) {
-		/* If the brush was never moved, express two sets of two deltas That's a
-		 * 'point,' but not for Yahoo!
-		 */
-		if (gtkwb->motion_count == 0) {
-			int index;
-
-			/* For Yahoo!, a (0 0) indicates the end of drawing */
-			/* FIXME: Yahoo Doodle specific! */
-			for (index = 0; index < 2; index++) {
-				draw_list = g_list_append(draw_list, 0);
-				draw_list = g_list_append(draw_list, 0);
-			}
-		}
-
+	if(gtkwb->cr != NULL) {
 		/* Send draw list to protocol draw_list handler */
 		purple_whiteboard_send_draw_list(gtkwb->wb, draw_list);
 
-		pidgin_whiteboard_set_canvas_as_icon(gtkwb);
-
 		/* The brush stroke is finished, clear the list for another one
 		 */
 		if (draw_list) {
@@ -435,8 +317,6 @@
 
 		purple_whiteboard_set_draw_list(wb, NULL);
 	}
-
-	return TRUE;
 }
 
 static void pidgin_whiteboard_set_dimensions(PurpleWhiteboard *wb, int width, int height)
@@ -461,7 +341,7 @@
 	GtkWidget *drawing_area = gtkwb->drawing_area;
 	cairo_t *cr = gtkwb->cr;
 	GtkAllocation allocation;
-	GdkRGBA white = {1.0, 1.0, 1.0, 1.0};
+	GdkRGBA white = {1.0f, 1.0f, 1.0f, 1.0f};
 
 	gtk_widget_get_allocation(drawing_area, &allocation);
 
@@ -469,12 +349,27 @@
 	cairo_rectangle(cr, 0, 0, allocation.width, allocation.height);
 	cairo_fill(cr);
 
-	gtk_widget_queue_draw_area(drawing_area, 0, 0,
-		allocation.width, allocation.height);
+	gtk_widget_queue_draw(drawing_area);
 }
 
-static void pidgin_whiteboard_button_clear_press(GtkWidget *widget, gpointer data)
+static void
+pidgin_whiteboard_clear_response(GtkDialog *self, guint response,
+                                 gpointer data)
 {
+	PidginWhiteboard *gtkwb = (PidginWhiteboard *)data;
+
+	if(response == GTK_RESPONSE_YES) {
+		pidgin_whiteboard_clear(gtkwb->wb);
+
+		/* Do protocol specific clearing procedures */
+		purple_whiteboard_send_clear(gtkwb->wb);
+	}
+
+	gtk_window_destroy(GTK_WINDOW(self));
+}
+
+static void
+pidgin_whiteboard_button_clear_press(GtkWidget *widget, gpointer data) {
 	PidginWhiteboard *gtkwb = (PidginWhiteboard*)(data);
 
 	/* Confirm whether the user really wants to clear */
@@ -482,62 +377,67 @@
 	        GTK_WINDOW(gtkwb), GTK_DIALOG_DESTROY_WITH_PARENT,
 	        GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "%s",
 	        _("Do you really want to clear?"));
-	gint response = gtk_dialog_run(GTK_DIALOG(dialog));
-	gtk_widget_destroy(dialog);
+
+	g_signal_connect(dialog, "response",
+	                 G_CALLBACK(pidgin_whiteboard_clear_response), gtkwb);
+
+	gtk_widget_show(dialog);
+}
 
-	if (response == GTK_RESPONSE_YES)
-	{
-		pidgin_whiteboard_clear(gtkwb->wb);
+static void
+pidgin_whiteboard_save_response(GtkNativeDialog *self, gint response_id,
+                                gpointer data)
+{
+	PidginWhiteboard *gtkwb = (PidginWhiteboard *)data;
+	GdkPixbuf *pixbuf;
+
+	if(response_id == GTK_RESPONSE_ACCEPT) {
+		gboolean success;
+		GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(self));
+		gchar *filename = g_file_get_path(file);
+
+		pixbuf = gdk_pixbuf_get_from_surface(gtkwb->surface, 0, 0,
+		                                     gtkwb->width, gtkwb->height);
 
-		pidgin_whiteboard_set_canvas_as_icon(gtkwb);
+		success = gdk_pixbuf_save(pixbuf, filename, "png", NULL,
+		                          "compression", "9", NULL);
+		g_object_unref(pixbuf);
 
-		/* Do protocol specific clearing procedures */
-		purple_whiteboard_send_clear(gtkwb->wb);
+		if (success) {
+			purple_debug_info("gtkwhiteboard", "whiteboard saved to \"%s\"",
+			                  filename);
+		} else {
+			purple_notify_error(NULL, _("Whiteboard"),
+			                    _("Unable to save the file"), NULL, NULL);
+			purple_debug_error("gtkwhiteboard", "whiteboard "
+			                   "couldn't be saved to \"%s\"", filename);
+		}
+
+		g_free(filename);
+		g_object_unref(file);
 	}
+
+	g_object_unref(self);
 }
 
+
 static void
 pidgin_whiteboard_button_save_press(GtkWidget *widget, gpointer _gtkwb)
 {
 	PidginWhiteboard *gtkwb = _gtkwb;
-	GdkPixbuf *pixbuf;
 	GtkFileChooserNative *chooser;
-	int result;
 
 	chooser = gtk_file_chooser_native_new(_("Save File"), GTK_WINDOW(gtkwb),
 	                                      GTK_FILE_CHOOSER_ACTION_SAVE,
 	                                      _("_Save"), _("_Cancel"));
 
-	gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser),
-	                                               TRUE);
 	gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(chooser),
 	                                  "whiteboard.png");
 
-	result = gtk_native_dialog_run(GTK_NATIVE_DIALOG(chooser));
-	if (result == GTK_RESPONSE_ACCEPT) {
-		gboolean success;
-		gchar *filename =
-		        gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
-
-		pixbuf = gdk_pixbuf_get_from_surface(
-		        gtkwb->surface, 0, 0, gtkwb->width, gtkwb->height);
+	g_signal_connect(chooser, "response",
+	                 G_CALLBACK(pidgin_whiteboard_save_response), gtkwb);
 
-		success = gdk_pixbuf_save(pixbuf, filename, "png", NULL,
-			"compression", "9", NULL);
-		g_object_unref(pixbuf);
-		if (success) {
-			purple_debug_info("gtkwhiteboard",
-				"whiteboard saved to \"%s\"", filename);
-		} else {
-			purple_notify_error(NULL, _("Whiteboard"),
-				_("Unable to save the file"), NULL, NULL);
-			purple_debug_error("gtkwhiteboard", "whiteboard "
-				"couldn't be saved to \"%s\"", filename);
-		}
-		g_free(filename);
-	}
-
-	g_object_unref(chooser);
+	gtk_native_dialog_show(GTK_NATIVE_DIALOG(chooser));
 }
 
 static void
@@ -606,8 +506,6 @@
 	/* Make all this (window) visible */
 	gtk_widget_show(GTK_WIDGET(gtkwb));
 
-	pidgin_whiteboard_set_canvas_as_icon(gtkwb);
-
 	/* TODO Specific protocol/whiteboard assignment here? Needs a UI Op? */
 	/* Set default brush size and color */
 	/*
@@ -635,16 +533,12 @@
  * GObject implementation
  *****************************************************************************/
 static void
-pidgin_whiteboard_init(PidginWhiteboard *self)
-{
+pidgin_whiteboard_init(PidginWhiteboard *self) {
 	gtk_widget_init_template(GTK_WIDGET(self));
-
-	self->brush_state = PIDGIN_WHITEBOARD_BRUSH_UP;
 }
 
 static void
-pidgin_whiteboard_finalize(GObject *obj)
-{
+pidgin_whiteboard_finalize(GObject *obj) {
 	PidginWhiteboard *gtkwb = PIDGIN_WHITEBOARD(obj);
 
 	/* Clear graphical memory */
@@ -675,7 +569,7 @@
 	gtk_widget_class_bind_template_callback(
 	        widget_class, pidgin_whiteboard_draw_event);
 	gtk_widget_class_bind_template_callback(
-	        widget_class, pidgin_whiteboard_configure_event);
+	        widget_class, pidgin_whiteboard_resize);
 	gtk_widget_class_bind_template_callback(
 	        widget_class, pidgin_whiteboard_brush_down);
 	gtk_widget_class_bind_template_callback(
--- a/pidgin/gtkxfer.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/gtkxfer.c	Sun Aug 28 22:18:46 2022 -0500
@@ -368,12 +368,9 @@
 /**************************************************************************
  * Callbacks
  **************************************************************************/
-static gint
-delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d)
-{
-	PidginXferDialog *dialog;
-
-	dialog = (PidginXferDialog *)d;
+static gboolean
+close_request_cb(GtkWidget *w, gpointer d) {
+	PidginXferDialog *dialog = (PidginXferDialog *)d;
 
 	pidgin_xfer_dialog_hide(dialog);
 
@@ -432,21 +429,10 @@
 open_button_cb(GtkButton *button, PidginXferDialog *dialog)
 {
 	gchar *uri = NULL;
-	GError *error = NULL;
 
 	uri = g_strdup_printf("file://%s",
 	                      purple_xfer_get_local_filename(dialog->selected_xfer));
-	if(!gtk_show_uri_on_window(GTK_WINDOW(dialog), uri, GDK_CURRENT_TIME,
-	                           &error))
-	{
-		gchar *tmp = g_strdup_printf(
-		    _("Error launching %s: %s"),
-		    purple_xfer_get_local_filename(dialog->selected_xfer),
-		    error->message);
-		purple_notify_error(dialog, NULL, _("Unable to open file."), tmp, NULL);
-		g_free(tmp);
-		g_error_free(error);
-	}
+	gtk_show_uri(GTK_WINDOW(dialog), uri, GDK_CURRENT_TIME);
 	g_free(uri);
 }
 
@@ -486,7 +472,7 @@
 	gtk_widget_class_set_template_from_resource(
 	        widget_class, "/im/pidgin/Pidgin3/Xfer/xfer.ui");
 
-	gtk_widget_class_bind_template_callback(widget_class, delete_win_cb);
+	gtk_widget_class_bind_template_callback(widget_class, close_request_cb);
 
 	gtk_widget_class_bind_template_child(widget_class, PidginXferDialog,
 	                                     tree);
@@ -565,11 +551,6 @@
 	        GTK_TOGGLE_BUTTON(dialog->auto_clear),
 	        purple_prefs_get_bool(PIDGIN_PREFS_ROOT
 	                              "/filetransfer/clear_finished"));
-
-#ifdef _WIN32
-	g_signal_connect(G_OBJECT(dialog), "show",
-	                 G_CALLBACK(winpidgin_ensure_onscreen), NULL);
-#endif
 }
 
 void
@@ -579,7 +560,7 @@
 
 	purple_notify_close_with_handle(dialog);
 
-	gtk_widget_destroy(GTK_WIDGET(dialog));
+	gtk_window_destroy(GTK_WINDOW(dialog));
 }
 
 void
--- a/pidgin/libpidgin.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/libpidgin.c	Sun Aug 28 22:18:46 2022 -0500
@@ -153,14 +153,17 @@
 
 static void
 purple_ui_add_protocol_theme_paths(PurpleProtocol *protocol) {
+	GdkDisplay *display = NULL;
 	GtkIconTheme *theme = NULL;
 	const gchar *path = NULL;
 
-	theme = gtk_icon_theme_get_default();
+	display = gdk_display_get_default();
+
+	theme = gtk_icon_theme_get_for_display(display);
 
 	path = purple_protocol_get_icon_search_path(protocol);
 	if(path != NULL) {
-		gtk_icon_theme_prepend_search_path(theme, path);
+		gtk_icon_theme_add_search_path(theme, path);
 	}
 
 	path = purple_protocol_get_icon_resource_path(protocol);
@@ -219,16 +222,18 @@
 pidgin_ui_init(void)
 {
 	PurpleProtocolManager *protocol_manager = NULL;
+	GdkDisplay *display = NULL;
 	GtkIconTheme *theme = NULL;
 	GError *error = NULL;
 	gchar *path;
 
 	pidgin_debug_init();
 
-	theme = gtk_icon_theme_get_default();
+	display = gdk_display_get_default();
+	theme = gtk_icon_theme_get_for_display(display);
 
 	path = g_build_filename(PURPLE_DATADIR, "pidgin", "icons", NULL);
-	gtk_icon_theme_prepend_search_path(theme, path);
+	gtk_icon_theme_add_search_path(theme, path);
 	g_free(path);
 
 	/* Add a callback for when a protocol is registered to add its icon paths
--- a/pidgin/meson.build	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/meson.build	Sun Aug 28 22:18:46 2022 -0500
@@ -59,7 +59,6 @@
 	'pidginstatusmanager.c',
 	'pidginstatusprimitivechooser.c',
 	'pidginstatusprimitivestore.c',
-	'pidginstylecontext.c',
 	'pidgintalkatu.c',
 	'prefs/pidginprefs.c',
 	'prefs/pidginawayprefs.c',
@@ -131,7 +130,6 @@
 	'pidginstatusmanager.h',
 	'pidginstatusprimitivechooser.h',
 	'pidginstatusprimitivestore.h',
-	'pidginstylecontext.h',
 	'pidgintalkatu.h',
 ]
 
@@ -225,7 +223,7 @@
 		gtk,
 		IOKIT,
 		json,
-		libhandy,
+		libadwaita,
 		math,
 		nice,
 		libsoup,
@@ -258,7 +256,7 @@
 	    include_directories : [toplevel_inc, libpidgin_inc],
 	    link_with : libpidgin,
 	    sources : libpidgin_built_headers,
-	    dependencies : [gtk, glib, libhandy, math, talkatu_dep, gplugin_gtk_dep])
+	    dependencies : [gtk, glib, libadwaita, math, talkatu_dep, gplugin_gtk_dep])
 
 	pidgin = executable('pidgin3',
 	    pidgin_SOURCES,
@@ -273,12 +271,12 @@
 	pkgconfig.generate(
 	    libpidgin,
 	    name : 'Pidgin',
-	    description : 'Pidgin is a GTK3-based instant messenger application.',
+	    description : 'Pidgin is a GTK based instant messenger application.',
 	    version : meson.project_version(),
 	    filebase : pidgin_filebase,
 	    subdirs : pidgin_filebase,
 	    # NOTE: Don't use dependencies from subprojects.
-	    requires : [gtk, libhandy, libpurple, 'talkatu', 'gplugin-gtk3'],
+	    requires : [gtk, libadwaita, libpurple, 'talkatu', 'gplugin-gtk4'],
 	    variables : ['plugindir=${libdir}/pidgin-@0@'.format(purple_major_version)])
 
 	PIDGIN_DESKTOP_FILE = 'im.pidgin.Pidgin3.desktop'
@@ -308,7 +306,7 @@
 		pidgin_gir = gnome.generate_gir(libpidgin,
 			sources : introspection_sources,
 			header : 'pidgin.h',
-			includes : ['GLib-2.0', 'GObject-2.0', 'Gtk-3.0', libpurple_gir[0], 'Talkatu-0.0'],
+			includes : ['GLib-2.0', 'GObject-2.0', 'Gtk-4.0', libpurple_gir[0], 'Talkatu-0.0'],
 			namespace : 'Pidgin',
 			symbol_prefix : 'pidgin',
 			identifier_prefix : 'Pidgin',
--- a/pidgin/pidginabout.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginabout.c	Sun Aug 28 22:18:46 2022 -0500
@@ -314,9 +314,9 @@
 	/* add the gtk version */
 	pidgin_about_dialog_build_info_add_version(about->build_info_store,
 	                                           &section, _("GTK Version"),
-	                                           gtk_major_version,
-	                                           gtk_minor_version,
-	                                           gtk_micro_version);
+	                                           gtk_get_major_version(),
+	                                           gtk_get_minor_version(),
+	                                           gtk_get_micro_version());
 }
 
 static void
@@ -324,9 +324,9 @@
 	GtkTreeIter section, iter;
 	gchar *markup = NULL;
 	gchar *cursor_theme_name = NULL, *theme_name = NULL;
-	gchar *icon_theme_name = NULL, *fallback_icon_theme = NULL;
+	gchar *icon_theme_name = NULL;
 	gchar *im_module = NULL;
-	gchar *key_theme_name = NULL, *sound_theme_name = NULL;
+	gchar *sound_theme_name = NULL;
 	gboolean enable_animations = FALSE;
 	gboolean shell_shows_app_menu = FALSE, shell_shows_menubar = FALSE;
 
@@ -343,10 +343,8 @@
 		gtk_settings_get_default(),
 		"gtk-cursor-theme-name", &cursor_theme_name,
 		"gtk-enable-animations", &enable_animations,
-		"gtk-fallback-icon-theme", &fallback_icon_theme,
 		"gtk-icon-theme-name", &icon_theme_name,
 		"gtk-im-module", &im_module,
-		"gtk-key-theme-name", &key_theme_name,
 		"gtk-shell-shows-app-menu", &shell_shows_app_menu,
 		"gtk-shell-shows-menubar", &shell_shows_menubar,
 		"gtk-sound-theme-name", &sound_theme_name,
@@ -367,12 +365,6 @@
 
 	gtk_tree_store_append(about->build_info_store, &iter, &section);
 	gtk_tree_store_set(about->build_info_store, &iter,
-	                   0, "gtk-fallback-icon-theme",
-	                   1, (fallback_icon_theme != NULL) ? fallback_icon_theme : _("(not set)"),
-	                   -1);
-
-	gtk_tree_store_append(about->build_info_store, &iter, &section);
-	gtk_tree_store_set(about->build_info_store, &iter,
 	                   0, "gtk-icon-theme-name",
 	                   1, (icon_theme_name != NULL) ? icon_theme_name : _("(not set)"),
 	                   -1);
@@ -385,12 +377,6 @@
 
 	gtk_tree_store_append(about->build_info_store, &iter, &section);
 	gtk_tree_store_set(about->build_info_store, &iter,
-	                   0, "gtk-key-theme-name",
-	                   1, (key_theme_name != NULL) ? key_theme_name : _("(not set)"),
-	                   -1);
-
-	gtk_tree_store_append(about->build_info_store, &iter, &section);
-	gtk_tree_store_set(about->build_info_store, &iter,
 	                   0, "gtk-shell-shows-app-menu",
 	                   1, shell_shows_app_menu ? _("yes") : _("no"),
 	                   -1);
@@ -414,10 +400,8 @@
 	                   -1);
 
 	g_free(cursor_theme_name);
-	g_free(fallback_icon_theme);
 	g_free(icon_theme_name);
 	g_free(im_module);
-	g_free(key_theme_name);
 	g_free(sound_theme_name);
 	g_free(theme_name);
 }
@@ -444,7 +428,7 @@
 
 		gtk_tree_store_append(about->build_info_store, &iter, &section);
 		gtk_tree_store_set(about->build_info_store, &iter,
-		                   0, (gchar*)(paths->data),
+		                   1, (gchar*)(paths->data),
 		                   -1);
 
 		paths = paths->next;
@@ -512,7 +496,8 @@
 {
 	switch(response_id) {
 		case GTK_RESPONSE_CLOSE:
-			gtk_widget_destroy(GTK_WIDGET(dialog));
+		case GTK_RESPONSE_DELETE_EVENT:
+			gtk_window_destroy(GTK_WINDOW(dialog));
 			break;
 	}
 }
--- a/pidgin/pidginaccounteditor.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginaccounteditor.c	Sun Aug 28 22:18:46 2022 -0500
@@ -107,7 +107,7 @@
 		pidgin_account_editor_save_account(PIDGIN_ACCOUNT_EDITOR(dialog));
 	}
 
-	gtk_widget_destroy(GTK_WIDGET(dialog));
+	gtk_window_destroy(GTK_WINDOW(dialog));
 }
 
 /******************************************************************************
--- a/pidgin/pidginaccountmanager.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginaccountmanager.c	Sun Aug 28 22:18:46 2022 -0500
@@ -217,7 +217,7 @@
 	switch(response_id) {
 		case RESPONSE_ADD:
 			editor = pidgin_account_editor_new(NULL);
-			gtk_widget_show_all(editor);
+			gtk_widget_show(editor);
 			break;
 		case RESPONSE_ADD_OLD:
 			pidgin_account_dialog_show(PIDGIN_ADD_ACCOUNT_DIALOG, NULL);
@@ -226,7 +226,7 @@
 			account = pidgin_account_manager_get_selected_account(manager);
 
 			editor = pidgin_account_editor_new(account);
-			gtk_widget_show_all(editor);
+			gtk_widget_show(editor);
 
 			g_clear_object(&account);
 			break;
@@ -246,10 +246,9 @@
 			g_clear_object(&account);
 
 			break;
+		case GTK_RESPONSE_CLOSE:
 		case GTK_RESPONSE_DELETE_EVENT:
-			/* fallthrough */
-		case GTK_RESPONSE_CLOSE:
-			gtk_widget_destroy(GTK_WIDGET(dialog));
+			gtk_window_destroy(GTK_WINDOW(dialog));
 			break;
 		default:
 			g_warning("not sure how you got here...");
--- a/pidgin/pidginaccountstore.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginaccountstore.c	Sun Aug 28 22:18:46 2022 -0500
@@ -37,12 +37,13 @@
 pidgin_account_store_add_account(PidginAccountStore *store,
                                  PurpleAccount *account)
 {
+	PurpleProtocol *protocol = NULL;
 	GtkTreeIter iter;
-	GdkPixbuf *pixbuf = NULL;
 	gchar *markup = NULL;
-	const gchar *alias = NULL;
+	const gchar *alias = NULL, *icon_name = NULL;
 
-	pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
+	protocol = purple_account_get_protocol(account);
+	icon_name = purple_protocol_get_icon_name(protocol);
 
 	alias = purple_account_get_private_alias(account);
 	if(alias != NULL) {
@@ -62,11 +63,10 @@
 		&iter,
 		PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT, account,
 		PIDGIN_ACCOUNT_STORE_COLUMN_MARKUP, markup,
-		PIDGIN_ACCOUNT_STORE_COLUMN_ICON, pixbuf,
+		PIDGIN_ACCOUNT_STORE_COLUMN_ICON_NAME, icon_name,
 		-1
 	);
 
-	g_clear_object(&pixbuf);
 	g_free(markup);
 }
 
@@ -150,7 +150,7 @@
 	GType types[PIDGIN_ACCOUNT_STORE_N_COLUMNS] = {
 		PURPLE_TYPE_ACCOUNT,
 		G_TYPE_STRING,
-		GDK_TYPE_PIXBUF,
+		G_TYPE_STRING,
 	};
 
 	gtk_list_store_set_column_types(
--- a/pidgin/pidginaccountstore.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginaccountstore.h	Sun Aug 28 22:18:46 2022 -0500
@@ -57,7 +57,7 @@
 typedef enum {
 	PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT,
 	PIDGIN_ACCOUNT_STORE_COLUMN_MARKUP,
-	PIDGIN_ACCOUNT_STORE_COLUMN_ICON,
+	PIDGIN_ACCOUNT_STORE_COLUMN_ICON_NAME,
 	/*< private >*/
 	PIDGIN_ACCOUNT_STORE_N_COLUMNS,
 } PidginAccountStoreColumn;
--- a/pidgin/pidginaddbuddydialog.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginaddbuddydialog.c	Sun Aug 28 22:18:46 2022 -0500
@@ -85,7 +85,7 @@
 
 		protocol = purple_account_get_protocol(account);
 		if(PURPLE_IS_PROTOCOL(protocol)) {
-			const gchar *username = gtk_entry_get_text(GTK_ENTRY(dialog->username));
+			const gchar *username = gtk_editable_get_text(GTK_EDITABLE(dialog->username));
 
 			valid = purple_validate(protocol, username);
 		}
@@ -115,9 +115,9 @@
 
 		/* Grab all of the values that the user entered. */
 		account = pidgin_account_chooser_get_selected(PIDGIN_ACCOUNT_CHOOSER(abdialog->account));
-		username = gtk_entry_get_text(GTK_ENTRY(abdialog->username));
-		alias = gtk_entry_get_text(GTK_ENTRY(abdialog->alias));
-		message = gtk_entry_get_text(GTK_ENTRY(abdialog->message));
+		username = gtk_editable_get_text(GTK_EDITABLE(abdialog->username));
+		alias = gtk_editable_get_text(GTK_EDITABLE(abdialog->alias));
+		message = gtk_editable_get_text(GTK_EDITABLE(abdialog->message));
 		groupname = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(abdialog->group));
 
 		/* Make anything that is an empty string NULL. */
@@ -194,7 +194,7 @@
 		g_free(groupname);
 	}
 
-	gtk_widget_destroy(GTK_WIDGET(abdialog));
+	gtk_window_destroy(GTK_WINDOW(abdialog));
 }
 
 static void
@@ -304,22 +304,22 @@
 	}
 
 	if(username != NULL) {
-		gtk_entry_set_text(GTK_ENTRY(abdialog->username), username);
+		gtk_editable_set_text(GTK_EDITABLE(abdialog->username), username);
 	}
 
 	if(alias != NULL) {
-		gtk_entry_set_text(GTK_ENTRY(abdialog->alias), alias);
+		gtk_editable_set_text(GTK_EDITABLE(abdialog->alias), alias);
 	}
 
 	if(message != NULL) {
-		gtk_entry_set_text(GTK_ENTRY(abdialog->message), message);
+		gtk_editable_set_text(GTK_EDITABLE(abdialog->message), message);
 	}
 
 	if(group != NULL) {
 		GtkWidget *entry = NULL;
 
-		entry = gtk_bin_get_child(GTK_BIN(abdialog->group));
-		gtk_entry_set_text(GTK_ENTRY(entry), group);
+		entry = gtk_combo_box_get_child(GTK_COMBO_BOX(abdialog->group));
+		gtk_editable_set_text(GTK_EDITABLE(entry), group);
 	}
 
 	return dialog;
--- a/pidgin/pidginaddchatdialog.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginaddchatdialog.c	Sun Aug 28 22:18:46 2022 -0500
@@ -51,7 +51,6 @@
 G_DEFINE_TYPE(PidginAddChatDialog, pidgin_add_chat_dialog, GTK_TYPE_DIALOG)
 
 /* ugh, prototypes... */
-static void pidgin_add_chat_dialog_remove_widget_cb(GtkWidget *child, gpointer data);
 static void pidgin_add_chat_dialog_input_changed_cb(GtkEditable *editable, gpointer data);
 
 /******************************************************************************
@@ -68,7 +67,7 @@
 		if(required) {
 			const gchar *value = NULL;
 
-			value = gtk_entry_get_text(GTK_ENTRY(data));
+			value = gtk_editable_get_text(GTK_EDITABLE(data));
 			if(value == NULL || *value == '\0') {
 				*valid = FALSE;
 			}
@@ -96,6 +95,7 @@
 	PurpleAccount *account = NULL;
 	PurpleConnection *connection = NULL;
 	PurpleProtocol *protocol = NULL;
+	GtkWidget *child = NULL;
 	GList *info = NULL;
 	GHashTable *defaults = NULL;
 	gboolean focus_set = FALSE;
@@ -105,9 +105,9 @@
 	protocol = purple_account_get_protocol(account);
 
 	/* Clean up the dynamic box and our list of entires. */
-	gtk_container_foreach(GTK_CONTAINER(dialog->dynamic_box),
-	                      pidgin_add_chat_dialog_remove_widget_cb,
-	                      dialog->dynamic_box);
+	while((child = gtk_widget_get_first_child(dialog->dynamic_box)) != NULL) {
+		gtk_box_remove(GTK_BOX(dialog->dynamic_box), child);
+	}
 	g_clear_pointer(&dialog->inputs, g_list_free);
 
 	info = purple_protocol_chat_info(PURPLE_PROTOCOL_CHAT(protocol),
@@ -134,7 +134,7 @@
 
 			value = g_hash_table_lookup(defaults, pce->identifier);
 			if(value != NULL) {
-				gtk_entry_set_text(GTK_ENTRY(input), value);
+				gtk_editable_set_text(GTK_EDITABLE(input), value);
 			}
 
 			if(pce->secret) {
@@ -145,15 +145,18 @@
 		}
 
 		box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-		gtk_box_pack_start(GTK_BOX(dialog->dynamic_box), box, FALSE, FALSE, 0);
+		gtk_box_append(GTK_BOX(dialog->dynamic_box), box);
 
 		label = gtk_label_new_with_mnemonic(pce->label);
 		gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
 		gtk_label_set_yalign(GTK_LABEL(label), 0.0f);
-		gtk_box_pack_start(GTK_BOX(box), label, FALSE, TRUE, 0);
+		gtk_widget_set_halign(label, GTK_ALIGN_FILL);
+		gtk_box_append(GTK_BOX(box), label);
 		gtk_size_group_add_widget(dialog->sg, label);
 
-		gtk_box_pack_start(GTK_BOX(box), input, TRUE, TRUE, 0);
+		gtk_widget_set_hexpand(input, TRUE);
+		gtk_widget_set_halign(input, GTK_ALIGN_FILL);
+		gtk_box_append(GTK_BOX(box), input);
 		if(!focus_set) {
 			gtk_widget_grab_focus(input);
 			focus_set = TRUE;
@@ -175,8 +178,6 @@
 
 	g_hash_table_destroy(defaults);
 
-	gtk_widget_show_all(dialog->dynamic_box);
-
 	pidgin_add_chat_dialog_validate(dialog);
 }
 
@@ -223,7 +224,7 @@
 
 		value = g_strdup_printf("%d", int_value);
 	} else {
-		const gchar *str_value = gtk_entry_get_text(GTK_ENTRY(data));
+		const gchar *str_value = gtk_editable_get_text(GTK_EDITABLE(data));
 
 		if(*str_value != '\0') {
 			value = g_strdup(str_value);
@@ -252,13 +253,6 @@
 }
 
 static void
-pidgin_add_chat_dialog_remove_widget_cb(GtkWidget *child, gpointer data) {
-	GtkContainer *parent = data;
-
-	gtk_container_remove(parent, child);
-}
-
-static void
 pidgin_add_chat_dialog_response_cb(GtkDialog *dialog, gint response_id,
                                    G_GNUC_UNUSED gpointer data)
 {
@@ -283,7 +277,7 @@
 		               pidgin_add_chat_dialog_add_input_to_components,
 		               components);
 
-		alias = gtk_entry_get_text(GTK_ENTRY(acdialog->alias));
+		alias = gtk_editable_get_text(GTK_EDITABLE(acdialog->alias));
 
 		chat = purple_chat_new(account, alias, components);
 
@@ -319,7 +313,7 @@
 	}
 
 	if(close) {
-		gtk_widget_destroy(GTK_WIDGET(dialog));
+		gtk_window_destroy(GTK_WINDOW(dialog));
 	}
 }
 
@@ -446,14 +440,15 @@
 	}
 
 	if(alias != NULL) {
-		gtk_entry_set_text(GTK_ENTRY(acdialog->alias), alias);
+		gtk_editable_set_text(GTK_EDITABLE(acdialog->alias), alias);
 	}
 
 	if(PURPLE_IS_GROUP(group)) {
 		GtkWidget *entry = NULL;
 
-		entry = gtk_bin_get_child(GTK_BIN(acdialog->group));
-		gtk_entry_set_text(GTK_ENTRY(entry), purple_group_get_name(group));
+		entry = gtk_combo_box_get_child(GTK_COMBO_BOX(acdialog->group));
+		gtk_editable_set_text(GTK_EDITABLE(entry),
+		                      purple_group_get_name(group));
 	}
 
 	acdialog->default_name = name;
--- a/pidgin/pidginapplication.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginapplication.c	Sun Aug 28 22:18:46 2022 -0500
@@ -31,7 +31,7 @@
 #include <gplugin.h>
 #include <purple.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include "pidginapplication.h"
 
@@ -223,7 +223,7 @@
 		g_object_add_weak_pointer(G_OBJECT(about), (gpointer)&about);
 	}
 
-	gtk_widget_show_all(about);
+	gtk_widget_show(about);
 }
 
 static void
@@ -402,7 +402,7 @@
 	gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
 #endif
 
-	gtk_widget_show_all(dialog);
+	gtk_widget_show(dialog);
 }
 
 static void
@@ -451,7 +451,7 @@
 		g_object_add_weak_pointer(G_OBJECT(manager), (gpointer)&manager);
 	}
 
-	gtk_widget_show_all(manager);
+	gtk_widget_show(manager);
 }
 
 static GActionEntry app_entries[] = {
@@ -678,14 +678,12 @@
 pidgin_application_startup(GApplication *application) {
 	PurpleAccountManager *manager = NULL;
 	PurpleUiInfo *ui_info = NULL;
-	GtkCssProvider *provider = NULL;
-	GError *error = NULL;
 	GList *active_accounts = NULL;
-	gchar *search_path = NULL;
 	gpointer handle = NULL;
 
 	G_APPLICATION_CLASS(pidgin_application_parent_class)->startup(application);
-	hdy_init();
+
+	adw_init();
 
 	/* set a user-specified config directory */
 	if (opt_config_dir_arg != NULL) {
@@ -710,23 +708,6 @@
 	pidgin_debug_set_print_enabled(opt_debug);
 #endif
 
-	provider = gtk_css_provider_new();
-
-	search_path = g_build_filename(purple_config_dir(), "gtk-3.0.css", NULL);
-	gtk_css_provider_load_from_path(provider, search_path, &error);
-	if(error != NULL) {
-		purple_debug_info("gtk", "Unable to load custom gtk-3.0.css: %s\n",
-		                  error->message);
-		g_clear_error(&error);
-	} else {
-		GdkScreen *screen = gdk_screen_get_default();
-		gtk_style_context_add_provider_for_screen(screen,
-		                                          GTK_STYLE_PROVIDER(provider),
-		                                          GTK_STYLE_PROVIDER_PRIORITY_USER);
-	}
-
-	g_free(search_path);
-
 #ifdef _WIN32
 	winpidgin_init();
 #endif
@@ -803,11 +784,6 @@
 	/* Populate our dynamic menus. */
 	pidgin_application_populate_dynamic_menus(PIDGIN_APPLICATION(application));
 
-	/* GTK clears the notification for us when opening the first window, but we
-	 * may have launched with only a status icon, so clear it just in case.
-	 */
-	gdk_notify_startup_complete();
-
 	/* TODO: Use GtkApplicationWindow or add a window instead */
 	g_application_hold(application);
 
--- a/pidgin/pidginavatar.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginavatar.c	Sun Aug 28 22:18:46 2022 -0500
@@ -25,7 +25,7 @@
 #include "pidgin/pidginavatar.h"
 
 struct _PidginAvatar {
-	GtkEventBox parent;
+	GtkBox parent;
 
 	GtkWidget *icon;
 
@@ -45,7 +45,7 @@
 };
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
 
-G_DEFINE_TYPE(PidginAvatar, pidgin_avatar, GTK_TYPE_EVENT_BOX)
+G_DEFINE_TYPE(PidginAvatar, pidgin_avatar, GTK_TYPE_BOX)
 
 /******************************************************************************
  * Actions
@@ -67,13 +67,16 @@
 
 	if(icon != NULL) {
 		GtkFileChooser *chooser = GTK_FILE_CHOOSER(native);
+		GFile *file = NULL;
 		gchar *filename = NULL;
 
-		filename = gtk_file_chooser_get_filename(chooser);
+		file = gtk_file_chooser_get_file(chooser);
+		filename = g_file_get_path(file);
 
 		purple_buddy_icon_save_to_filename(icon, filename, NULL);
 
 		g_free(filename);
+		g_object_unref(file);
 	}
 
 	gtk_native_dialog_destroy(native);
@@ -99,7 +102,7 @@
 	name = purple_buddy_get_name(avatar->buddy);
 	filename = g_strdup_printf("%s.%s", purple_normalize(account, name), ext);
 
-	window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(avatar)));
+	window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(avatar)));
 	native = gtk_file_chooser_native_new(_("Save Avatar"),
 	                                     window,
 	                                     GTK_FILE_CHOOSER_ACTION_SAVE,
@@ -110,8 +113,7 @@
 
 	chooser = GTK_FILE_CHOOSER(native);
 
-	gtk_file_chooser_set_do_overwrite_confirmation(chooser, TRUE);
-	gtk_file_chooser_set_filename(chooser, filename);
+	gtk_file_chooser_set_current_name(chooser, filename);
 	g_free(filename);
 
 	gtk_native_dialog_show(GTK_NATIVE_DIALOG(native));
@@ -123,6 +125,7 @@
 {
 	PidginAvatar *avatar = PIDGIN_AVATAR(data);
 	GtkFileChooser *chooser = GTK_FILE_CHOOSER(native);
+	GFile *file = NULL;
 	gchar *filename = NULL;
 
 	if(response != GTK_RESPONSE_ACCEPT || !PURPLE_IS_BUDDY(avatar->buddy)) {
@@ -131,7 +134,8 @@
 		return;
 	}
 
-	filename = gtk_file_chooser_get_filename(chooser);
+	file = gtk_file_chooser_get_file(chooser);
+	filename = g_file_get_path(file);
 	if(filename != NULL) {
 		PurpleContact *contact = purple_buddy_get_contact(avatar->buddy);
 		PurpleBlistNode *node = PURPLE_BLIST_NODE(contact);
@@ -139,6 +143,9 @@
 		purple_buddy_icons_node_set_custom_icon_from_file(node, filename);
 	}
 
+	g_free(filename);
+	g_object_unref(file);
+
 	gtk_native_dialog_destroy(native);
 }
 
@@ -150,7 +157,7 @@
 	GtkFileChooserNative *native = NULL;
 	GtkWindow *window = NULL;
 
-	window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(avatar)));
+	window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(avatar)));
 	native = gtk_file_chooser_native_new(_("Set Custom Avatar"),
 	                                     window,
 	                                     GTK_FILE_CHOOSER_ACTION_OPEN,
@@ -253,6 +260,7 @@
 pidgin_avatar_update(PidginAvatar *avatar) {
 	PurpleAccount *account = NULL;
 	GdkPixbufAnimation *animation = NULL;
+	GdkPixbuf *pixbuf = NULL;
 
 	if(PURPLE_IS_BUDDY(avatar->buddy)) {
 		animation = pidgin_avatar_find_buddy_icon(avatar->buddy, NULL);
@@ -275,18 +283,13 @@
 
 	if(GDK_IS_PIXBUF_ANIMATION(avatar->animation)) {
 		if(avatar->animate) {
-			gtk_image_set_from_animation(GTK_IMAGE(avatar->icon),
-			                             avatar->animation);
+			pixbuf = GDK_PIXBUF(avatar->animation);
 		} else {
-			GdkPixbuf *frame = NULL;
+			pixbuf = gdk_pixbuf_animation_get_static_image(avatar->animation);
+		}
+	}
 
-			frame = gdk_pixbuf_animation_get_static_image(avatar->animation);
-
-			gtk_image_set_from_pixbuf(GTK_IMAGE(avatar->icon), frame);
-		}
-	} else {
-		gtk_image_clear(GTK_IMAGE(avatar->icon));
-	}
+	gtk_picture_set_pixbuf(GTK_PICTURE(avatar->icon), pixbuf);
 
 	g_clear_object(&animation);
 }
@@ -295,7 +298,10 @@
  * Callbacks
  *****************************************************************************/
 static gboolean
-pidgin_avatar_button_press_handler(GtkWidget *widget, GdkEventButton *event,
+pidgin_avatar_button_press_handler(G_GNUC_UNUSED GtkGestureClick *event,
+                                   G_GNUC_UNUSED gint n_press,
+                                   gdouble x,
+                                   gdouble y,
                                    gpointer data)
 {
 	PidginAvatar *avatar = PIDGIN_AVATAR(data);
@@ -303,18 +309,13 @@
 	GtkWidget *menu = NULL;
 	GMenuModel *model = NULL;
 
-	if(!gdk_event_triggers_context_menu((GdkEvent *)event)) {
-		return FALSE;
-	}
-
 	builder = gtk_builder_new_from_resource("/im/pidgin/Pidgin3/Avatar/menu.ui");
 	model = (GMenuModel *)gtk_builder_get_object(builder, "menu");
 
-	menu = gtk_popover_menu_new();
-	gtk_popover_bind_model(GTK_POPOVER(menu), model, NULL);
-	gtk_popover_set_relative_to(GTK_POPOVER(menu), GTK_WIDGET(avatar));
+	menu = gtk_popover_menu_new_from_model(model);
+	gtk_widget_set_parent(menu, GTK_WIDGET(avatar));
 	gtk_popover_set_pointing_to(GTK_POPOVER(menu),
-	                            &(const GdkRectangle){(int)event->x, (int)event->y, 0, 0});
+	                            &(const GdkRectangle){(int)x, (int)y, 0, 0});
 
 	g_clear_object(&builder);
 
@@ -351,10 +352,12 @@
 }
 
 static gboolean
-pidgin_avatar_enter_notify_handler(GtkWidget *widget, GdkEvent *event,
+pidgin_avatar_enter_notify_handler(G_GNUC_UNUSED GtkEventControllerMotion *event,
+                                   G_GNUC_UNUSED gdouble x,
+                                   G_GNUC_UNUSED gdouble y,
                                    gpointer data)
 {
-	PidginAvatar *avatar = PIDGIN_AVATAR(widget);
+	PidginAvatar *avatar = PIDGIN_AVATAR(data);
 
 	pidgin_avatar_set_animate(avatar, TRUE);
 
@@ -362,10 +365,10 @@
 }
 
 static gboolean
-pidgin_avatar_leave_notify_handler(GtkWidget *widget, GdkEvent *event,
-                                   gpointer user_data)
+pidgin_avatar_leave_notify_handler(G_GNUC_UNUSED GtkEventControllerMotion *event,
+                                   gpointer data)
 {
-	PidginAvatar *avatar = PIDGIN_AVATAR(widget);
+	PidginAvatar *avatar = PIDGIN_AVATAR(data);
 
 	pidgin_avatar_set_animate(avatar, FALSE);
 
@@ -437,12 +440,6 @@
 
 	gtk_widget_init_template(GTK_WIDGET(avatar));
 
-	/* For development/design purposes, the avatar defaults to the
-	 * "image-missing" icon.  However, we don't want to display that to users,
-	 * so we clear it during run time.
-	 */
-	gtk_image_clear(GTK_IMAGE(avatar->icon));
-
 	/* Now setup our actions. */
 	group = g_simple_action_group_new();
 	g_action_map_add_action_entries(G_ACTION_MAP(group), actions,
@@ -527,8 +524,8 @@
 
 	if(GDK_IS_PIXBUF_ANIMATION(avatar->animation)) {
 		if(avatar->animate) {
-			gtk_image_set_from_animation(GTK_IMAGE(avatar->icon),
-			                             avatar->animation);
+			gtk_image_set_from_pixbuf(GTK_IMAGE(avatar->icon),
+			                          GDK_PIXBUF(avatar->animation));
 		} else {
 			GdkPixbuf *frame = NULL;
 
--- a/pidgin/pidginavatar.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginavatar.h	Sun Aug 28 22:18:46 2022 -0500
@@ -45,8 +45,7 @@
  */
 
 #define PIDGIN_TYPE_AVATAR (pidgin_avatar_get_type())
-G_DECLARE_FINAL_TYPE(PidginAvatar, pidgin_avatar,
-                     PIDGIN, AVATAR, GtkEventBox)
+G_DECLARE_FINAL_TYPE(PidginAvatar, pidgin_avatar, PIDGIN, AVATAR, GtkBox)
 
 /**
  * pidgin_avatar_new:
--- a/pidgin/pidgincolor.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidgincolor.c	Sun Aug 28 22:18:46 2022 -0500
@@ -22,8 +22,6 @@
 
 #include "pidgincolor.h"
 
-#include "pidginstylecontext.h"
-
 /******************************************************************************
  * Public API
  *****************************************************************************/
@@ -33,11 +31,12 @@
     GChecksum *checksum = NULL;
     guchar digest[20];
     gsize digest_len = sizeof(digest);
-    gdouble hue = 0, red = 0, green = 0, blue = 0;
+    gfloat hue = 0, red = 0, green = 0, blue = 0;
 
     g_return_if_fail(color != NULL);
 
-    pidgin_style_context_get_background_color(&background);
+#warning figure out how to get the background color
+    gdk_rgba_parse(&background, "#FFFFFFFF");
 
     /* hash the string and get the first 2 bytes of the digest */
     checksum = g_checksum_new(G_CHECKSUM_SHA1);
@@ -50,16 +49,16 @@
     /* Calculate the hue based on the digest.  We need a value between 0 and 1
      * so we divide the value by 65535 which is the maximum value for 2 bytes.
      */
-    hue = (digest[0] << 8 | digest[1]) / 65535.0;
+    hue = (digest[0] << 8 | digest[1]) / 65535.0f;
 
     /* Get the rgb values for the hue at full saturation and value. */
-    gtk_hsv_to_rgb(hue, 1.0, 1.0, &red, &green, &blue);
+    gtk_hsv_to_rgb(hue, 1.0f, 1.0f, &red, &green, &blue);
 
     /* Finally calculate the color summing 20% of the inverted background color
      * with 80% of the color.
      */
-    color->red = (0.2 * (1 - background.red)) + (0.8 * red);
-    color->green = (0.2 * (1 - background.green)) + (0.8 * green);
-    color->blue = (0.2 * (1 - background.blue)) + (0.8 * blue);
-    color->alpha = 1.0;
+    color->red = (0.2f * (1 - background.red)) + (0.8f * red);
+    color->green = (0.2f * (1 - background.green)) + (0.8f * green);
+    color->blue = (0.2f * (1 - background.blue)) + (0.8f * blue);
+    color->alpha = 1.0f;
 }
--- a/pidgin/pidgincontactlistwindow.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidgincontactlistwindow.c	Sun Aug 28 22:18:46 2022 -0500
@@ -68,7 +68,10 @@
  *****************************************************************************/
 GtkWidget *
 pidgin_contact_list_window_new(void) {
-	return g_object_new(PIDGIN_TYPE_CONTACT_LIST_WINDOW, NULL);
+	return g_object_new(
+		PIDGIN_TYPE_CONTACT_LIST_WINDOW,
+		"show-menubar", TRUE,
+		NULL);
 }
 
 GtkWidget *
--- a/pidgin/pidginconversationwindow.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginconversationwindow.c	Sun Aug 28 22:18:46 2022 -0500
@@ -116,7 +116,7 @@
 		}
 	}
 
-	gtk_widget_destroy(GTK_WIDGET(invite_dialog));
+	gtk_window_destroy(GTK_WINDOW(invite_dialog));
 }
 
 /******************************************************************************
@@ -218,7 +218,7 @@
 			                 NULL);
 		}
 
-		gtk_widget_show_all(invite_dialog);
+		gtk_widget_show(invite_dialog);
 	}
 }
 
@@ -371,7 +371,7 @@
 	}
 
 	/* If ALT (or whatever) was held down... */
-	else if (state & GDK_MOD1_MASK) {
+	else if (state & GDK_ALT_MASK) {
 		if ('1' <= keyval && keyval <= '9') {
 			guint switchto = keyval - '1';
 			pidgin_conversation_window_select_nth(window, switchto);
@@ -435,13 +435,12 @@
 	g_action_map_add_action_entries(G_ACTION_MAP(window), win_entries,
 	                                G_N_ELEMENTS(win_entries), window);
 
-	key = gtk_event_controller_key_new(GTK_WIDGET(window));
+	key = gtk_event_controller_key_new();
 	gtk_event_controller_set_propagation_phase(key, GTK_PHASE_CAPTURE);
 	g_signal_connect(G_OBJECT(key), "key-pressed",
 	                 G_CALLBACK(pidgin_conversation_window_key_pressed_cb),
 	                 window);
-	g_object_set_data_full(G_OBJECT(window), "key-press-controller", key,
-	                       g_object_unref);
+	gtk_widget_add_controller(GTK_WIDGET(window), key);
 
 	/* Add our toplevels to the tree store. */
 	gtk_tree_store_append(window->model, &iter, NULL);
@@ -510,6 +509,9 @@
 
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_conversation_window_selection_changed);
+
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_conversation_window_key_pressed_cb);
 }
 
 /******************************************************************************
@@ -528,7 +530,10 @@
 
 GtkWidget *
 pidgin_conversation_window_new(void) {
-	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_CONVERSATION_WINDOW, NULL));
+	return g_object_new(
+		PIDGIN_TYPE_CONVERSATION_WINDOW,
+		"show-menubar", TRUE,
+		NULL);
 }
 
 void
@@ -564,11 +569,11 @@
 
 		if(GTK_IS_WIDGET(parent)) {
 			g_object_ref(gtkconv->tab_cont);
-			gtk_container_remove(GTK_CONTAINER(parent), gtkconv->tab_cont);
+			gtk_widget_unparent(gtkconv->tab_cont);
 		}
 
 		gtk_stack_add_named(GTK_STACK(window->stack), gtkconv->tab_cont, markup);
-		gtk_widget_show_all(gtkconv->tab_cont);
+		gtk_widget_show(gtkconv->tab_cont);
 
 		if(GTK_IS_WIDGET(parent)) {
 			g_object_unref(gtkconv->tab_cont);
@@ -590,7 +595,7 @@
 
 
 	if(!gtk_widget_is_visible(GTK_WIDGET(window))) {
-		gtk_widget_show_all(GTK_WIDGET(window));
+		gtk_widget_show(GTK_WIDGET(window));
 	}
 }
 
@@ -630,7 +635,7 @@
 			child = gtk_stack_get_child_by_name(GTK_STACK(window->stack),
 			                                    name);
 			if(GTK_IS_WIDGET(child)) {
-				gtk_container_remove(GTK_CONTAINER(window->stack), child);
+				gtk_widget_unparent(child);
 			}
 
 			gtk_tree_store_remove(window->model, &iter);
@@ -646,16 +651,16 @@
 
 guint
 pidgin_conversation_window_get_count(PidginConversationWindow *window) {
-	GList *children = NULL;
+	GtkSelectionModel *model = NULL;
 	guint count = 0;
 
 	g_return_val_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window), 0);
 
-	children = gtk_container_get_children(GTK_CONTAINER(window));
-	while(children != NULL) {
-		children = g_list_delete_link(children, children);
-		count++;
-	}
+	model = gtk_stack_get_pages(GTK_STACK(window->stack));
+
+	count = g_list_model_get_n_items(G_LIST_MODEL(model));
+
+	g_object_unref(model);
 
 	return count;
 }
--- a/pidgin/pidgindebug.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidgindebug.c	Sun Aug 28 22:18:46 2022 -0500
@@ -82,30 +82,15 @@
 
 G_DEFINE_TYPE(PidginDebugWindow, pidgin_debug_window, GTK_TYPE_WINDOW);
 
-static gint
-debug_window_destroy(GtkWidget *w, GdkEvent *event, void *unused)
+static gboolean
+save_default_size_cb(GObject *gobject, G_GNUC_UNUSED GParamSpec *pspec,
+                     G_GNUC_UNUSED gpointer data)
 {
-	purple_prefs_disconnect_by_handle(pidgin_debug_get_handle());
-
-	if (debug_win->regex != NULL)
-		g_regex_unref(debug_win->regex);
-
-	/* If the "Save Log" dialog is open then close it */
-	purple_request_close_with_handle(debug_win);
-
-	debug_win = NULL;
-
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/enabled", FALSE);
-
-	return FALSE;
-}
-
-static gboolean
-configure_cb(GtkWidget *w, GdkEventConfigure *event, void *unused)
-{
-	if (gtk_widget_get_visible(w)) {
-		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/width",  event->width);
-		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/height", event->height);
+	if (gtk_widget_get_visible(GTK_WIDGET(gobject))) {
+		gint width, height;
+		gtk_window_get_default_size(GTK_WINDOW(gobject), &width, &height);
+		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/width",  width);
+		purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/height", height);
 	}
 
 	return FALSE;
@@ -122,32 +107,82 @@
 }
 
 static void
-save_writefile_cb(void *user_data, const char *filename)
+save_response_cb(GtkNativeDialog *self, gint response_id, gpointer data)
 {
-	PidginDebugWindow *win = (PidginDebugWindow *)user_data;
-	FILE *fp;
-	GtkTextIter start, end;
-	char *tmp;
+	PidginDebugWindow *win = (PidginDebugWindow *)data;
+
+	if(response_id == GTK_RESPONSE_ACCEPT) {
+		GFile *file = NULL;
+		GFileOutputStream *output = NULL;
+		GtkTextIter start, end;
+		gchar *tmp = NULL;
+		GError *error = NULL;
+
+		file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(self));
+		output = g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL,
+		                        &error);
+		g_object_unref(file);
+
+		if(output == NULL) {
+			purple_debug_error("debug",
+			                   "Unable to open file to save debug log: %s",
+			                   error->message);
+			g_error_free(error);
+			g_object_unref(self);
+			return;
+		}
 
-	if ((fp = g_fopen(filename, "w+")) == NULL) {
-		purple_notify_error(win, NULL, _("Unable to open file."), NULL, NULL);
-		return;
+		tmp = g_strdup_printf("Pidgin Debug Log : %s\n", purple_date_format_full(NULL));
+		g_output_stream_write_all(G_OUTPUT_STREAM(output), tmp, strlen(tmp),
+		                          NULL, NULL, &error);
+		g_free(tmp);
+
+		if(error != NULL) {
+			purple_debug_error("debug", "Unable to save debug log: %s",
+			                   error->message);
+			g_error_free(error);
+			g_object_unref(output);
+			g_object_unref(self);
+			return;
+		}
+
+		gtk_text_buffer_get_bounds(win->buffer, &start, &end);
+		tmp = gtk_text_buffer_get_text(win->buffer, &start, &end, TRUE);
+		g_output_stream_write_all(G_OUTPUT_STREAM(output), tmp, strlen(tmp),
+		                          NULL, NULL, &error);
+		g_free(tmp);
+
+		if(error != NULL) {
+			purple_debug_error("debug", "Unable to save debug log: %s",
+			                   error->message);
+			g_error_free(error);
+			g_object_unref(output);
+			g_object_unref(self);
+			return;
+		}
+
+		g_object_unref(output);
 	}
 
-	gtk_text_buffer_get_bounds(win->buffer, &start, &end);
-	tmp = gtk_text_buffer_get_text(win->buffer, &start, &end, TRUE);
-	fprintf(fp, "Pidgin Debug Log : %s\n", purple_date_format_full(NULL));
-	fprintf(fp, "%s", tmp);
-	g_free(tmp);
-
-	fclose(fp);
+	g_object_unref(self);
 }
 
 static void
 save_cb(GtkWidget *w, PidginDebugWindow *win)
 {
-	purple_request_file(win, _("Save Debug Log"), "purple-debug.log", TRUE,
-		G_CALLBACK(save_writefile_cb), NULL, NULL, win);
+	GtkFileChooserNative *filesel;
+
+	filesel = gtk_file_chooser_native_new(_("Save Debug Log"), GTK_WINDOW(win),
+	                                      GTK_FILE_CHOOSER_ACTION_SAVE,
+	                                      _("_Save"), _("_Cancel"));
+
+	gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(filesel),
+	                                  "purple-debug.log");
+
+	g_signal_connect(filesel, "response", G_CALLBACK(save_response_cb), win);
+
+	gtk_native_dialog_set_modal(GTK_NATIVE_DIALOG(filesel), TRUE);
+	gtk_native_dialog_show(GTK_NATIVE_DIALOG(filesel));
 }
 
 static void
@@ -159,7 +194,7 @@
 static void
 pause_cb(GtkWidget *w, PidginDebugWindow *win)
 {
-	win->paused = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(w));
+	win->paused = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
 
 	if (!win->paused) {
 		GtkTextIter start, end;
@@ -177,8 +212,7 @@
 static void
 regex_clear_color(GtkWidget *w) {
 	GtkStyleContext *context = gtk_widget_get_style_context(w);
-	gtk_style_context_remove_class(context, "good-filter");
-	gtk_style_context_remove_class(context, "bad-filter");
+	gtk_style_context_remove_class(context, "error");
 }
 
 static void
@@ -186,11 +220,9 @@
 	GtkStyleContext *context = gtk_widget_get_style_context(w);
 
 	if (success) {
-		gtk_style_context_add_class(context, "good-filter");
-		gtk_style_context_remove_class(context, "bad-filter");
+		gtk_style_context_remove_class(context, "error");
 	} else {
-		gtk_style_context_add_class(context, "bad-filter");
-		gtk_style_context_remove_class(context, "good-filter");
+		gtk_style_context_add_class(context, "error");
 	}
 }
 
@@ -291,19 +323,10 @@
 	if (!win)
 		return;
 
-	current = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter));
-	if (active != current)
-		gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(win->filter), active);
-}
-
-static void
-regex_pref_expression_cb(const gchar *name, PurplePrefType type,
-						 gconstpointer val, gpointer data)
-{
-	PidginDebugWindow *win = (PidginDebugWindow *)data;
-	const gchar *exp = (const gchar *)val;
-
-	gtk_entry_set_text(GTK_ENTRY(win->expression), exp);
+	current = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win->filter));
+	if (active != current) {
+		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win->filter), active);
+	}
 }
 
 static void
@@ -315,8 +338,9 @@
 
 	win->invert = active;
 
-	if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
+	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win->filter))) {
 		regex_toggle_filter(win, TRUE);
+	}
 }
 
 static void
@@ -328,20 +352,20 @@
 
 	win->highlight = active;
 
-	if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
+	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win->filter))) {
 		regex_toggle_filter(win, TRUE);
+	}
 }
 
 static void
 regex_changed_cb(GtkWidget *w, PidginDebugWindow *win) {
 	const gchar *text;
 
-	if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter))) {
-		gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(win->filter),
-									 FALSE);
+	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win->filter))) {
+		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win->filter), FALSE);
 	}
 
-	text = gtk_entry_get_text(GTK_ENTRY(win->expression));
+	text = gtk_editable_get_text(GTK_EDITABLE(win->expression));
 	purple_prefs_set_string(PIDGIN_PREFS_ROOT "/debug/regex", text);
 
 	if (text == NULL || *text == '\0') {
@@ -367,18 +391,21 @@
 }
 
 static void
-regex_key_release_cb(GtkWidget *w, GdkEventKey *e, PidginDebugWindow *win) {
+regex_key_released_cb(G_GNUC_UNUSED GtkEventControllerKey *controller,
+                      guint keyval, G_GNUC_UNUSED guint keycode,
+                      G_GNUC_UNUSED GdkModifierType state, gpointer data)
+{
+	PidginDebugWindow *win = data;
+
 	if (gtk_widget_is_sensitive(win->filter)) {
-		GtkToggleToolButton *tb = GTK_TOGGLE_TOOL_BUTTON(win->filter);
-		if ((e->keyval == GDK_KEY_Return || e->keyval == GDK_KEY_KP_Enter) &&
-			!gtk_toggle_tool_button_get_active(tb))
+		GtkToggleButton *tb = GTK_TOGGLE_BUTTON(win->filter);
+		if ((keyval == GDK_KEY_Return || keyval == GDK_KEY_KP_Enter) &&
+			!gtk_toggle_button_get_active(tb))
 		{
-			gtk_toggle_tool_button_set_active(tb, TRUE);
+			gtk_toggle_button_set_active(tb, TRUE);
 		}
-		if (e->keyval == GDK_KEY_Escape &&
-			gtk_toggle_tool_button_get_active(tb))
-		{
-			gtk_toggle_tool_button_set_active(tb, FALSE);
+		if (keyval == GDK_KEY_Escape && gtk_toggle_button_get_active(tb)) {
+			gtk_toggle_button_set_active(tb, FALSE);
 		}
 	}
 }
@@ -388,7 +415,7 @@
 {
 	gboolean active;
 
-	active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));
+	active = gtk_check_button_get_active(GTK_CHECK_BUTTON(item));
 
 	if (item == win->popover_highlight) {
 		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/highlight", active);
@@ -398,25 +425,22 @@
 }
 
 static void
-regex_popup_cb(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event,
-		PidginDebugWindow *win)
+regex_popup_cb(G_GNUC_UNUSED GtkGestureClick* self, G_GNUC_UNUSED gint n_press,
+               gdouble x, gdouble y, gpointer data)
 {
-	GdkRectangle rect;
-	if (icon_pos != GTK_ENTRY_ICON_PRIMARY) {
-		return;
-	}
+	PidginDebugWindow *win = data;
 
-	gtk_entry_get_icon_area(entry, icon_pos, &rect);
-	gtk_popover_set_pointing_to(GTK_POPOVER(win->popover), &rect);
+	gtk_popover_set_pointing_to(GTK_POPOVER(win->popover),
+	                            &(const GdkRectangle){(int)x, (int)y, 0, 0});
 	gtk_popover_popup(GTK_POPOVER(win->popover));
 }
 
 static void
-regex_filter_toggled_cb(GtkToggleToolButton *button, PidginDebugWindow *win)
+regex_filter_toggled_cb(GtkToggleButton *button, PidginDebugWindow *win)
 {
 	gboolean active;
 
-	active = gtk_toggle_tool_button_get_active(button);
+	active = gtk_toggle_button_get_active(button);
 
 	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/filter", active);
 
@@ -461,9 +485,38 @@
 }
 
 static void
+pidgin_debug_window_dispose(GObject *object)
+{
+	PidginDebugWindow *win = PIDGIN_DEBUG_WINDOW(object);
+
+	gtk_widget_unparent(win->popover);
+
+	G_OBJECT_CLASS(pidgin_debug_window_parent_class)->dispose(object);
+}
+
+static void
+pidgin_debug_window_finalize(GObject *object)
+{
+	PidginDebugWindow *win = PIDGIN_DEBUG_WINDOW(object);
+
+	purple_prefs_disconnect_by_handle(pidgin_debug_get_handle());
+
+	g_clear_pointer(&win->regex, g_regex_unref);
+
+	debug_win = NULL;
+	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/enabled", FALSE);
+
+	G_OBJECT_CLASS(pidgin_debug_window_parent_class)->finalize(object);
+}
+
+static void
 pidgin_debug_window_class_init(PidginDebugWindowClass *klass) {
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 
+	obj_class->dispose = pidgin_debug_window_dispose;
+	obj_class->finalize = pidgin_debug_window_finalize;
+
 	gtk_widget_class_set_template_from_resource(
 		widget_class,
 		"/im/pidgin/Pidgin3/Debug/debug.ui"
@@ -519,7 +572,7 @@
 	gtk_widget_class_bind_template_callback(widget_class, regex_popup_cb);
 	gtk_widget_class_bind_template_callback(widget_class, regex_menu_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
-			regex_key_release_cb);
+			regex_key_released_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
 			filter_level_changed_cb);
 }
@@ -530,12 +583,11 @@
 	gint width, height;
 	void *handle;
 	GtkTextIter end;
-	GtkStyleContext *context;
-	GtkCssProvider *filter_css;
-	const gchar *res = "/im/pidgin/Pidgin3/Debug/filter.css";
 
 	gtk_widget_init_template(GTK_WIDGET(win));
 
+	gtk_widget_set_parent(win->popover, win->filter);
+
 	width  = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/width");
 	height = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/height");
 
@@ -544,10 +596,10 @@
 
 	gtk_window_set_default_size(GTK_WINDOW(win), width, height);
 
-	g_signal_connect(G_OBJECT(win), "delete_event",
-	                 G_CALLBACK(debug_window_destroy), NULL);
-	g_signal_connect(G_OBJECT(win), "configure_event",
-	                 G_CALLBACK(configure_cb), NULL);
+	g_signal_connect(G_OBJECT(win), "notify::default-width",
+	                 G_CALLBACK(save_default_size_cb), NULL);
+	g_signal_connect(G_OBJECT(win), "notify::default-height",
+	                 G_CALLBACK(save_default_size_cb), NULL);
 
 	handle = pidgin_debug_get_handle();
 
@@ -559,24 +611,14 @@
 		 * toggle button sensitive.
 		 */
 		gtk_widget_set_sensitive(win->filter, FALSE);
-		gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(win->filter),
-									 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/filter"));
+		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win->filter),
+		                             purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/filter"));
 		purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/filter",
 									regex_pref_filter_cb, win);
 
 		/* regex entry */
-		filter_css = gtk_css_provider_new();
-		gtk_css_provider_load_from_resource(filter_css, res);
-
-		context = gtk_widget_get_style_context(win->expression);
-		gtk_style_context_add_provider(context,
-		                               GTK_STYLE_PROVIDER(filter_css),
-		                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-
-		gtk_entry_set_text(GTK_ENTRY(win->expression),
-						   purple_prefs_get_string(PIDGIN_PREFS_ROOT "/debug/regex"));
-		purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/regex",
-									regex_pref_expression_cb, win);
+		gtk_editable_set_text(GTK_EDITABLE(win->expression),
+		                      purple_prefs_get_string(PIDGIN_PREFS_ROOT "/debug/regex"));
 
 		/* connect the rest of our pref callbacks */
 		win->invert = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/invert");
@@ -593,10 +635,10 @@
 		purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/filterlevel",
 						filter_level_pref_changed, win);
 
-		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win->popover_invert),
-				win->invert);
-		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win->popover_highlight),
-				win->highlight);
+		gtk_check_button_set_active(GTK_CHECK_BUTTON(win->popover_invert),
+		                            win->invert);
+		gtk_check_button_set_active(GTK_CHECK_BUTTON(win->popover_highlight),
+		                            win->highlight);
 	}
 
 	/* The *start* and *end* marks bound the beginning and end of an
@@ -811,8 +853,7 @@
 pidgin_debug_window_hide(void)
 {
 	if (debug_win != NULL) {
-		gtk_widget_destroy(GTK_WIDGET(debug_win));
-		debug_window_destroy(NULL, NULL, NULL);
+		gtk_window_destroy(GTK_WINDOW(debug_win));
 	}
 }
 
--- a/pidgin/pidgindialog.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidgindialog.c	Sun Aug 28 22:18:46 2022 -0500
@@ -56,8 +56,6 @@
 	return GTK_WIDGET(g_object_new(
 		PIDGIN_TYPE_DIALOG,
 		"title", title,
-		"border-width", border_width,
-		"role", role,
 		"resizable", resizable,
 		NULL));
 }
--- a/pidgin/pidgininvitedialog.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidgininvitedialog.c	Sun Aug 28 22:18:46 2022 -0500
@@ -203,7 +203,7 @@
 
 	priv = pidgin_invite_dialog_get_instance_private(dialog);
 
-	return gtk_entry_get_text(GTK_ENTRY(priv->contact));
+	return gtk_editable_get_text(GTK_EDITABLE(priv->contact));
 }
 
 void
@@ -217,7 +217,7 @@
 	priv = pidgin_invite_dialog_get_instance_private(dialog);
 
 	if(contact != NULL) {
-		gtk_entry_set_text(GTK_ENTRY(priv->contact), contact);
+		gtk_editable_set_text(GTK_EDITABLE(priv->contact), contact);
 
 		g_object_notify_by_pspec(G_OBJECT(dialog), properties[PROP_CONTACT]);
 	}
@@ -231,7 +231,7 @@
 
 	priv = pidgin_invite_dialog_get_instance_private(dialog);
 
-	return gtk_entry_get_text(GTK_ENTRY(priv->message));
+	return gtk_editable_get_text(GTK_EDITABLE(priv->message));
 }
 
 void
@@ -245,7 +245,7 @@
 	priv = pidgin_invite_dialog_get_instance_private(dialog);
 
 	if(message != NULL) {
-		gtk_entry_set_text(GTK_ENTRY(priv->message), message);
+		gtk_editable_set_text(GTK_EDITABLE(priv->message), message);
 
 		g_object_notify_by_pspec(G_OBJECT(dialog), properties[PROP_MESSAGE]);
 	}
--- a/pidgin/pidginkeypad.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginkeypad.c	Sun Aug 28 22:18:46 2022 -0500
@@ -143,10 +143,9 @@
 	g_return_if_fail(PIDGIN_IS_KEYPAD(keypad));
 	g_return_if_fail(GTK_IS_WIDGET(widget));
 
-	controller = gtk_event_controller_key_new(widget);
+	controller = gtk_event_controller_key_new();
 	gtk_event_controller_set_propagation_phase(controller, GTK_PHASE_CAPTURE);
 	g_signal_connect(controller, "key-pressed",
 	                 G_CALLBACK(pidgin_keypad_key_pressed_cb), keypad);
-	g_object_set_data_full(G_OBJECT(widget), "pidgin-keypad-key-controller",
-	                       controller, g_object_unref);
+	gtk_widget_add_controller(widget, controller);
 }
--- a/pidgin/pidginnotificationaddcontact.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginnotificationaddcontact.c	Sun Aug 28 22:18:46 2022 -0500
@@ -29,7 +29,7 @@
 #include "pidgin/gtkdialogs.h"
 
 struct _PidginNotificationAddContact {
-	HdyActionRow parent;
+	AdwActionRow parent;
 
 	PurpleNotification *notification;
 
@@ -45,7 +45,7 @@
 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
 
 G_DEFINE_TYPE(PidginNotificationAddContact, pidgin_notification_add_contact,
-              HDY_TYPE_ACTION_ROW)
+              ADW_TYPE_ACTION_ROW)
 
 /******************************************************************************
  * Helpers
@@ -61,11 +61,11 @@
 	g_return_if_fail(PIDGIN_IS_NOTIFICATION_ADD_CONTACT(add_contact));
 
 	if(!PURPLE_IS_NOTIFICATION(add_contact->notification)) {
-		hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(add_contact),
+		adw_preferences_row_set_title(ADW_PREFERENCES_ROW(add_contact),
 		                              _("Notification missing"));
 
-		hdy_action_row_set_icon_name(HDY_ACTION_ROW(add_contact), NULL);
-		hdy_action_row_set_subtitle(HDY_ACTION_ROW(add_contact), NULL);
+		adw_action_row_set_icon_name(ADW_ACTION_ROW(add_contact), NULL);
+		adw_action_row_set_subtitle(ADW_ACTION_ROW(add_contact), NULL);
 
 		gtk_widget_hide(add_contact->add);
 		gtk_widget_hide(add_contact->message);
@@ -75,11 +75,11 @@
 
 	account = purple_notification_get_account(add_contact->notification);
 	if(!PURPLE_IS_ACCOUNT(account)) {
-		hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(add_contact),
+		adw_preferences_row_set_title(ADW_PREFERENCES_ROW(add_contact),
 		                              _("Notification is missing an account"));
 
-		hdy_action_row_set_icon_name(HDY_ACTION_ROW(add_contact), NULL);
-		hdy_action_row_set_subtitle(HDY_ACTION_ROW(add_contact), NULL);
+		adw_action_row_set_icon_name(ADW_ACTION_ROW(add_contact), NULL);
+		adw_action_row_set_subtitle(ADW_ACTION_ROW(add_contact), NULL);
 
 		gtk_widget_hide(add_contact->add);
 		gtk_widget_hide(add_contact->message);
@@ -101,13 +101,13 @@
 			icon_name = "dialog-question";
 		}
 	}
-	hdy_action_row_set_icon_name(HDY_ACTION_ROW(add_contact), icon_name);
+	adw_action_row_set_icon_name(ADW_ACTION_ROW(add_contact), icon_name);
 
 	title = purple_notification_get_title(add_contact->notification);
-	hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(add_contact), title);
+	adw_preferences_row_set_title(ADW_PREFERENCES_ROW(add_contact), title);
 
 	message = purple_add_contact_request_get_message(request);
-	hdy_action_row_set_subtitle(HDY_ACTION_ROW(add_contact), message);
+	adw_action_row_set_subtitle(ADW_ACTION_ROW(add_contact), message);
 
 	gtk_widget_show(add_contact->add);
 	gtk_widget_show(add_contact->message);
--- a/pidgin/pidginnotificationaddcontact.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginnotificationaddcontact.h	Sun Aug 28 22:18:46 2022 -0500
@@ -31,7 +31,7 @@
 
 #include <gtk/gtk.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include <purple.h>
 
@@ -49,7 +49,7 @@
 
 #define PIDGIN_TYPE_NOTIFICATION_ADD_CONTACT (pidgin_notification_add_contact_get_type())
 G_DECLARE_FINAL_TYPE(PidginNotificationAddContact, pidgin_notification_add_contact,
-                     PIDGIN, NOTIFICATION_ADD_CONTACT, HdyActionRow)
+                     PIDGIN, NOTIFICATION_ADD_CONTACT, AdwActionRow)
 
 /**
  * pidgin_notification_add_contact_new:
--- a/pidgin/pidginnotificationauthorizationrequest.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginnotificationauthorizationrequest.c	Sun Aug 28 22:18:46 2022 -0500
@@ -29,7 +29,7 @@
 #include "pidgin/gtkdialogs.h"
 
 struct _PidginNotificationAuthorizationRequest {
-	HdyActionRow parent;
+	AdwActionRow parent;
 
 	PurpleNotification *notification;
 
@@ -46,7 +46,7 @@
 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
 
 G_DEFINE_TYPE(PidginNotificationAuthorizationRequest,
-              pidgin_notification_authorization_request, HDY_TYPE_ACTION_ROW)
+              pidgin_notification_authorization_request, ADW_TYPE_ACTION_ROW)
 
 /******************************************************************************
  * Helpers
@@ -61,11 +61,11 @@
 	g_return_if_fail(PIDGIN_IS_NOTIFICATION_AUTHORIZATION_REQUEST(request));
 
 	if(!PURPLE_IS_NOTIFICATION(request->notification)) {
-		hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(request),
+		adw_preferences_row_set_title(ADW_PREFERENCES_ROW(request),
 		                              _("Notification missing"));
 
-		hdy_action_row_set_icon_name(HDY_ACTION_ROW(request), NULL);
-		hdy_action_row_set_subtitle(HDY_ACTION_ROW(request), NULL);
+		adw_action_row_set_icon_name(ADW_ACTION_ROW(request), NULL);
+		adw_action_row_set_subtitle(ADW_ACTION_ROW(request), NULL);
 
 		gtk_widget_hide(request->accept);
 		gtk_widget_hide(request->deny);
@@ -76,11 +76,11 @@
 
 	account = purple_notification_get_account(request->notification);
 	if(!PURPLE_IS_ACCOUNT(account)) {
-		hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(request),
+		adw_preferences_row_set_title(ADW_PREFERENCES_ROW(request),
 		                              _("Notification is missing an account"));
 
-		hdy_action_row_set_icon_name(HDY_ACTION_ROW(request), NULL);
-		hdy_action_row_set_subtitle(HDY_ACTION_ROW(request), NULL);
+		adw_action_row_set_icon_name(ADW_ACTION_ROW(request), NULL);
+		adw_action_row_set_subtitle(ADW_ACTION_ROW(request), NULL);
 
 		gtk_widget_hide(request->accept);
 		gtk_widget_hide(request->deny);
@@ -103,13 +103,13 @@
 			icon_name = "dialog-question";
 		}
 	}
-	hdy_action_row_set_icon_name(HDY_ACTION_ROW(request), icon_name);
+	adw_action_row_set_icon_name(ADW_ACTION_ROW(request), icon_name);
 
 	title = purple_notification_get_title(request->notification);
-	hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(request), title);
+	adw_preferences_row_set_title(ADW_PREFERENCES_ROW(request), title);
 
 	message = purple_authorization_request_get_message(purple_request);
-	hdy_action_row_set_subtitle(HDY_ACTION_ROW(request), message);
+	adw_action_row_set_subtitle(ADW_ACTION_ROW(request), message);
 
 	gtk_widget_show(request->accept);
 	gtk_widget_show(request->deny);
--- a/pidgin/pidginnotificationauthorizationrequest.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginnotificationauthorizationrequest.h	Sun Aug 28 22:18:46 2022 -0500
@@ -31,7 +31,7 @@
 
 #include <gtk/gtk.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include <purple.h>
 
@@ -49,7 +49,7 @@
 
 #define PIDGIN_TYPE_NOTIFICATION_AUTHORIZATION_REQUEST (pidgin_notification_authorization_request_get_type())
 G_DECLARE_FINAL_TYPE(PidginNotificationAuthorizationRequest, pidgin_notification_authorization_request,
-                     PIDGIN, NOTIFICATION_AUTHORIZATION_REQUEST, HdyActionRow)
+                     PIDGIN, NOTIFICATION_AUTHORIZATION_REQUEST, AdwActionRow)
 
 /**
  * pidgin_notification_authorization_request_new:
--- a/pidgin/pidginnotificationconnectionerror.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginnotificationconnectionerror.c	Sun Aug 28 22:18:46 2022 -0500
@@ -27,7 +27,7 @@
 #include "pidgin/pidginnotificationconnectionerror.h"
 
 struct _PidginNotificationConnectionError {
-	HdyActionRow parent;
+	AdwActionRow parent;
 
 	PurpleNotification *notification;
 
@@ -44,7 +44,7 @@
 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
 
 G_DEFINE_TYPE(PidginNotificationConnectionError,
-              pidgin_notification_connection_error, HDY_TYPE_ACTION_ROW)
+              pidgin_notification_connection_error, ADW_TYPE_ACTION_ROW)
 
 /******************************************************************************
  * Helpers
@@ -59,11 +59,11 @@
 	g_return_if_fail(PIDGIN_IS_NOTIFICATION_CONNECTION_ERROR(error));
 
 	if(!PURPLE_IS_NOTIFICATION(error->notification)) {
-		hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(error),
+		adw_preferences_row_set_title(ADW_PREFERENCES_ROW(error),
 		                              _("Notification missing"));
 
-		hdy_action_row_set_icon_name(HDY_ACTION_ROW(error), NULL);
-		hdy_action_row_set_subtitle(HDY_ACTION_ROW(error), NULL);
+		adw_action_row_set_icon_name(ADW_ACTION_ROW(error), NULL);
+		adw_action_row_set_subtitle(ADW_ACTION_ROW(error), NULL);
 
 		gtk_widget_hide(error->reconnect);
 		gtk_widget_hide(error->reenable);
@@ -74,11 +74,11 @@
 
 	account = purple_notification_get_account(error->notification);
 	if(!PURPLE_IS_ACCOUNT(account)) {
-		hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(error),
+		adw_preferences_row_set_title(ADW_PREFERENCES_ROW(error),
 		                              _("Notification is missing an account"));
 
-		hdy_action_row_set_icon_name(HDY_ACTION_ROW(error), NULL);
-		hdy_action_row_set_subtitle(HDY_ACTION_ROW(error), NULL);
+		adw_action_row_set_icon_name(ADW_ACTION_ROW(error), NULL);
+		adw_action_row_set_subtitle(ADW_ACTION_ROW(error), NULL);
 
 		gtk_widget_hide(error->reconnect);
 		gtk_widget_hide(error->reenable);
@@ -99,19 +99,19 @@
 	/* Set the icon name if one was specified. */
 	icon_name = purple_notification_get_icon_name(error->notification);
 	if(icon_name != NULL) {
-		hdy_action_row_set_icon_name(HDY_ACTION_ROW(error), icon_name);
+		adw_action_row_set_icon_name(ADW_ACTION_ROW(error), icon_name);
 	}
 
 	enabled = purple_account_get_enabled(account);
 
 	title = purple_notification_get_title(error->notification);
-	hdy_preferences_row_set_title(HDY_PREFERENCES_ROW(error), title);
+	adw_preferences_row_set_title(ADW_PREFERENCES_ROW(error), title);
 
 	info = purple_notification_get_data(error->notification);
 	if(info != NULL) {
-		hdy_action_row_set_subtitle(HDY_ACTION_ROW(error), info->description);
+		adw_action_row_set_subtitle(ADW_ACTION_ROW(error), info->description);
 	} else {
-		hdy_action_row_set_subtitle(HDY_ACTION_ROW(error), NULL);
+		adw_action_row_set_subtitle(ADW_ACTION_ROW(error), NULL);
 	}
 
 	/* If the account is still enabled, reconnect should be visible, otherwise
--- a/pidgin/pidginnotificationconnectionerror.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginnotificationconnectionerror.h	Sun Aug 28 22:18:46 2022 -0500
@@ -31,7 +31,7 @@
 
 #include <gtk/gtk.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include <purple.h>
 
@@ -48,7 +48,7 @@
 
 #define PIDGIN_TYPE_NOTIFICATION_CONNECTION_ERROR (pidgin_notification_connection_error_get_type())
 G_DECLARE_FINAL_TYPE(PidginNotificationConnectionError, pidgin_notification_connection_error,
-                     PIDGIN, NOTIFICATION_CONNECTION_ERROR, HdyActionRow)
+                     PIDGIN, NOTIFICATION_CONNECTION_ERROR, AdwActionRow)
 
 /**
  * pidgin_notification_connection_error_new:
--- a/pidgin/pidginpluginsdialog.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginpluginsdialog.c	Sun Aug 28 22:18:46 2022 -0500
@@ -36,258 +36,21 @@
 struct _PidginPluginsDialog {
 	GtkDialog parent;
 
-	GtkWidget *tree_view;
-	GtkWidget *configure_plugin_button;
-	GtkWidget *plugin_info;
-
-	GtkListStore *plugin_store;
+	GtkWidget *view;
 };
 
-/* this has a short life left to it... */
-typedef struct
-{
-	enum
-	{
-		PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME,
-		PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST
-	} type;
-
-	union
-	{
-		struct
-		{
-			GtkWidget *dialog;
-			PurplePluginPrefFrame *pref_frame;
-		} frame;
-
-		gpointer request_handle;
-	} u;
-} PidginPluginUiData;
-
-/******************************************************************************
- * Helpers
- *****************************************************************************/
-static gboolean
-pidgin_plugins_dialog_plugin_has_config(GPluginPlugin *plugin) {
-	GPluginPluginInfo *ginfo = gplugin_plugin_get_info(plugin);
-	PurplePluginInfo *info = PURPLE_PLUGIN_INFO(ginfo);
-	GPluginPluginState state;
-
-	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
-
-	state = gplugin_plugin_get_state(plugin);
-
-	if (state != GPLUGIN_PLUGIN_STATE_LOADED) {
-		return FALSE;
-	}
-
-	return (purple_plugin_info_get_pref_frame_cb(info) ||
-	       purple_plugin_info_get_pref_request_cb(info));
-}
-
-static GPluginPlugin *
-pidgin_plugins_dialog_get_selected(PidginPluginsDialog *dialog) {
-	GPluginPlugin *plugin = NULL;
-	GtkTreeSelection *selection = NULL;
-	GtkTreeModel *model = NULL;
-	GtkTreeIter iter;
-
-	g_return_val_if_fail(PIDGIN_IS_PLUGINS_DIALOG(dialog), NULL);
-
-	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->tree_view));
-	/* not sure if this is necessary, but playing defense. - grim 20191112 */
-	if(selection == NULL) {
-		return NULL;
-	}
-
-	if(gtk_tree_selection_get_selected(selection, &model, &iter)) {
-		gtk_tree_model_get(model, &iter,
-		                   GPLUGIN_GTK_STORE_PLUGIN_COLUMN, &plugin,
-		                   -1);
-	}
-
-	return plugin;
-}
-
-static void
-pidgin_plugins_dialog_pref_dialog_close(GPluginPlugin *plugin) {
-	GPluginPluginInfo *ginfo = gplugin_plugin_get_info(plugin);
-	PurplePluginInfo *info = PURPLE_PLUGIN_INFO(ginfo);
-	PidginPluginUiData *ui_data;
-
-	ui_data = g_object_get_data(G_OBJECT(info), "pidgin-ui-data");
-	if (ui_data == NULL) {
-		purple_debug_info("PidginPluginsDialog", "failed to find uidata\n");
-		return;
-	}
-
-	if (ui_data->type == PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST) {
-		purple_request_close(PURPLE_REQUEST_FIELDS,
-			ui_data->u.request_handle);
-		return;
-	}
-
-	g_return_if_fail(ui_data->type == PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME);
-
-	gtk_widget_destroy(ui_data->u.frame.dialog);
-
-	if (ui_data->u.frame.pref_frame) {
-		purple_plugin_pref_frame_destroy(ui_data->u.frame.pref_frame);
-	}
-
-	g_object_set_data(G_OBJECT(info), "pidgin-ui-data", NULL);
-}
-
 /******************************************************************************
  * Callbacks
  *****************************************************************************/
 static void
-pidgin_plugins_dialog_selection_cb(GtkTreeSelection *sel, gpointer data) {
-	PidginPluginsDialog *dialog = PIDGIN_PLUGINS_DIALOG(data);
-	GPluginPlugin *plugin = NULL;
-	GtkTreeModel *model = NULL;
-	GtkTreeIter iter;
-
-	if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
-		gtk_tree_model_get(model, &iter,
-		                   GPLUGIN_GTK_STORE_PLUGIN_COLUMN, &plugin,
-		                   -1);
-	}
-
-	gplugin_gtk_plugin_info_set_plugin(
-		GPLUGIN_GTK_PLUGIN_INFO(dialog->plugin_info),
-		plugin
-	);
-
-	if(GPLUGIN_IS_PLUGIN(plugin)) {
-		gtk_widget_set_sensitive(
-			GTK_WIDGET(dialog->configure_plugin_button),
-			pidgin_plugins_dialog_plugin_has_config(plugin)
-		);
-
-		g_object_unref(G_OBJECT(plugin));
-	}
-}
-
-static void
-pidgin_plugins_dialog_pref_dialog_response_cb(GtkWidget *dialog, int response,
-                                              gpointer data)
+pidgin_plugins_dialog_response_cb(GtkDialog* self, gint response_id,
+                                  G_GNUC_UNUSED gpointer data)
 {
-	if (response == GTK_RESPONSE_CLOSE ||
-		response == GTK_RESPONSE_DELETE_EVENT)
-	{
-		pidgin_plugins_dialog_pref_dialog_close(GPLUGIN_PLUGIN(data));
-	}
-}
-
-static void
-pidgin_plugins_dialog_request_close_cb(PurplePluginInfo *info)
-{
-	g_object_set_data(G_OBJECT(info), "pidgin-ui-data", NULL);
-}
-
-static void
-pidgin_plugins_dialog_config_plugin_cb(GtkWidget *button, gpointer data) {
-	PidginPluginsDialog *dialog = PIDGIN_PLUGINS_DIALOG(data);
-	PidginPluginUiData *ui_data;
-	PurplePluginInfo *info;
-	PurplePluginPrefFrameCb pref_frame_cb;
-	PurplePluginPrefRequestCb pref_request_cb;
-	GPluginPlugin *plugin = NULL;
-	GPluginPluginInfo *ginfo = NULL;
-	gint prefs_count;
-
-	plugin = pidgin_plugins_dialog_get_selected(dialog);
-	if(!GPLUGIN_IS_PLUGIN(plugin)) {
-		return;
-	}
-
-	ginfo = gplugin_plugin_get_info(plugin);
-	info = PURPLE_PLUGIN_INFO(ginfo);
-
-	if (g_object_get_data(G_OBJECT(info), "pidgin-ui-data")) {
-		g_object_unref(G_OBJECT(plugin));
-		return;
+	switch(response_id) {
+		case GTK_RESPONSE_DELETE_EVENT:
+			gtk_window_destroy(GTK_WINDOW(self));
+			break;
 	}
-
-	pref_frame_cb = purple_plugin_info_get_pref_frame_cb(info);
-	pref_request_cb = purple_plugin_info_get_pref_request_cb(info);
-
-	ui_data = g_new0(PidginPluginUiData, 1);
-	g_object_set_data_full(G_OBJECT(info), "pidgin-ui-data", ui_data, g_free);
-
-	prefs_count = 0;
-	if (pref_frame_cb) {
-		prefs_count++;
-
-		ui_data->u.frame.pref_frame = pref_frame_cb(plugin);
-	}
-
-	if (pref_request_cb) {
-		prefs_count++;
-	}
-
-	if (prefs_count > 1) {
-		purple_debug_warning("gtkplugin",
-		                     "Plugin %s contains more than one prefs "
-		                     "callback, some will be ignored.",
-		                     gplugin_plugin_info_get_name(ginfo));
-	}
-	g_return_if_fail(prefs_count > 0);
-
-
-	/* Priority: pidgin frame > purple request > purple frame
-	 * Purple frame could be replaced with purple request some day.
-	 */
-	if (pref_request_cb) {
-		ui_data->type = PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST;
-		ui_data->u.request_handle = pref_request_cb(plugin);
-		purple_request_add_close_notify(
-		        ui_data->u.request_handle,
-		        (GDestroyNotify)pidgin_plugins_dialog_request_close_cb, info);
-	} else {
-		GtkWidget *box, *pdialog, *content, *sw;
-
-		ui_data->type = PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME;
-
-		box = pidgin_plugin_pref_create_frame(ui_data->u.frame.pref_frame);
-		if (box == NULL) {
-			purple_debug_error("gtkplugin",
-				"Failed to display prefs frame");
-			g_object_set_data(G_OBJECT(info), "pidgin-ui-data", NULL);
-			g_object_unref(G_OBJECT(plugin));
-			return;
-		}
-		gtk_widget_set_vexpand(box, TRUE);
-
-		ui_data->u.frame.dialog = pdialog = gtk_dialog_new_with_buttons(
-			PIDGIN_ALERT_TITLE, GTK_WINDOW(dialog),
-			GTK_DIALOG_DESTROY_WITH_PARENT,
-			_("Close"), GTK_RESPONSE_CLOSE,
-			NULL);
-
-		g_signal_connect(G_OBJECT(pdialog), "response",
-			G_CALLBACK(pidgin_plugins_dialog_pref_dialog_response_cb), plugin);
-
-		content = gtk_dialog_get_content_area(GTK_DIALOG(pdialog));
-
-		sw = gtk_scrolled_window_new(NULL, NULL);
-		gtk_container_add(GTK_CONTAINER(content), sw);
-		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
-		                               GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-		gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
-		                                    GTK_SHADOW_IN);
-		gtk_widget_set_size_request(sw, 400, 400);
-
-		gtk_container_add(GTK_CONTAINER(sw), box);
-
-		gtk_window_set_role(GTK_WINDOW(pdialog), "plugin_config");
-		gtk_window_set_title(GTK_WINDOW(pdialog),
-		                     _(gplugin_plugin_info_get_name(
-		                             GPLUGIN_PLUGIN_INFO(info))));
-		gtk_widget_show_all(pdialog);
-	}
-	g_object_unref(G_OBJECT(plugin));
 }
 
 /******************************************************************************
@@ -304,25 +67,21 @@
 		"/im/pidgin/Pidgin3/Plugins/dialog.ui"
 	);
 
-	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog, tree_view);
-	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog, configure_plugin_button);
-	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog, plugin_info);
-	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog, plugin_store);
+	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog,
+	                                     view);
 
-	gtk_widget_class_bind_template_callback(widget_class, pidgin_plugins_dialog_selection_cb);
-	gtk_widget_class_bind_template_callback(widget_class, pidgin_plugins_dialog_config_plugin_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_plugins_dialog_response_cb);
 }
 
 static void
 pidgin_plugins_dialog_init(PidginPluginsDialog *dialog) {
+	GPluginManager *manager = NULL;
+
 	gtk_widget_init_template(GTK_WIDGET(dialog));
 
-	/* set the sort column for the plugin_store */
-	gtk_tree_sortable_set_sort_column_id(
-		GTK_TREE_SORTABLE(dialog->plugin_store),
-		GPLUGIN_GTK_STORE_MARKUP_COLUMN,
-		GTK_SORT_ASCENDING
-	);
+	manager = gplugin_manager_get_default();
+	gplugin_gtk_view_set_manager(GPLUGIN_GTK_VIEW(dialog->view), manager);
 }
 
 /******************************************************************************
@@ -332,4 +91,3 @@
 pidgin_plugins_dialog_new(void) {
 	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_PLUGINS_DIALOG, NULL));
 }
-
--- a/pidgin/pidginpresenceicon.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginpresenceicon.c	Sun Aug 28 22:18:46 2022 -0500
@@ -31,7 +31,6 @@
 
 	PurplePresence *presence;
 	gchar *fallback;
-	GtkIconSize icon_size;
 };
 
 enum {
@@ -54,8 +53,7 @@
 
 	icon_name = pidgin_icon_name_from_presence(icon->presence, icon->fallback);
 
-	gtk_image_set_from_icon_name(GTK_IMAGE(icon->icon), icon_name,
-	                             icon->icon_size);
+	gtk_image_set_from_icon_name(GTK_IMAGE(icon->icon), icon_name);
 }
 
 static void
@@ -167,7 +165,7 @@
 		"icon-size", "icon-size",
 		"The GtkIconSize to use",
 		GTK_TYPE_ICON_SIZE,
-		GTK_ICON_SIZE_MENU,
+		GTK_ICON_SIZE_NORMAL,
 		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
 
 	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -271,9 +269,9 @@
 
 GtkIconSize
 pidgin_presence_icon_get_icon_size(PidginPresenceIcon *icon) {
-	g_return_val_if_fail(PIDGIN_IS_PRESENCE_ICON(icon), GTK_ICON_SIZE_INVALID);
+	g_return_val_if_fail(PIDGIN_IS_PRESENCE_ICON(icon), GTK_ICON_SIZE_INHERIT);
 
-	return icon->icon_size;
+	return gtk_image_get_icon_size(GTK_IMAGE(icon->icon));
 }
 
 void
@@ -282,7 +280,7 @@
 {
 	g_return_if_fail(PIDGIN_IS_PRESENCE_ICON(icon));
 
-	icon->icon_size = icon_size;
+	gtk_image_set_icon_size(GTK_IMAGE(icon->icon), icon_size);
 
 	g_object_freeze_notify(G_OBJECT(icon));
 
--- a/pidgin/pidginproxyoptions.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginproxyoptions.c	Sun Aug 28 22:18:46 2022 -0500
@@ -166,32 +166,6 @@
 	gtk_widget_set_sensitive(options->options, sensitive);
 }
 
-static void
-pidgin_proxy_options_ports_popup_cb(G_GNUC_UNUSED GtkEntry *entry,
-                                    GtkWidget *widget,
-                                    G_GNUC_UNUSED gpointer data)
-{
-	GtkWidget *item = NULL;
-
-	/* This is an easter egg. The items are in reverse order because they are
-	 * prepended to the menu.
-	 *
-	 * It means one of two things, both intended as humorous:
-	 * A) your network is really slow and you have nothing better to do than
-	 *    look at butterflies.
-	 * B) You are looking really closely at something that shouldn't matter.
-	 */
-
-	item = gtk_menu_item_new_with_label(_("you can see the butterflies mating"));
-	gtk_menu_shell_prepend(GTK_MENU_SHELL(widget), item);
-	gtk_widget_show(item);
-
-	/* This is also an easter egg, see the previous comment. */
-	item = gtk_menu_item_new_with_label(_("If you look real closely"));
-	gtk_menu_shell_prepend(GTK_MENU_SHELL(widget), item);
-	gtk_widget_show(item);
-}
-
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
@@ -327,8 +301,6 @@
 
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_proxy_options_proxy_type_changed_cb);
-	gtk_widget_class_bind_template_callback(widget_class,
-	                                        pidgin_proxy_options_ports_popup_cb);
 }
 
 /******************************************************************************
--- a/pidgin/pidginstatuseditor.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginstatuseditor.c	Sun Aug 28 22:18:46 2022 -0500
@@ -84,7 +84,7 @@
 		message = "";
 	}
 
-	gtk_entry_set_text(GTK_ENTRY(editor->title), title);
+	gtk_editable_set_text(GTK_EDITABLE(editor->title), title);
 	chooser = PIDGIN_STATUS_PRIMITIVE_CHOOSER(editor->primitive);
 	pidgin_status_primitive_chooser_set_selected(chooser, primitive);
 	talkatu_markup_set_html(TALKATU_BUFFER(editor->buffer), message, -1);
@@ -99,7 +99,7 @@
 	gchar *message = NULL;
 	const gchar *title = NULL;
 
-	title = gtk_entry_get_text(GTK_ENTRY(editor->title));
+	title = gtk_editable_get_text(GTK_EDITABLE(editor->title));
 
 	chooser = PIDGIN_STATUS_PRIMITIVE_CHOOSER(editor->primitive);
 	primitive = pidgin_status_primitive_chooser_get_selected(chooser);
@@ -147,7 +147,7 @@
 			break;
 	}
 
-	gtk_widget_destroy(GTK_WIDGET(dialog));
+	gtk_window_destroy(GTK_WINDOW(dialog));
 }
 
 static void
@@ -156,7 +156,7 @@
 	gboolean title_changed = FALSE, sensitive = FALSE;
 	const gchar *title = NULL;
 
-	title = gtk_entry_get_text(GTK_ENTRY(editor->title));
+	title = gtk_editable_get_text(GTK_EDITABLE(editor->title));
 
 	if(editor->status != NULL) {
 		/* If we're editing a status, check if the title is the same. */
--- a/pidgin/pidginstatusmanager.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/pidginstatusmanager.c	Sun Aug 28 22:18:46 2022 -0500
@@ -115,7 +115,7 @@
 		-1);
 
 	if(GTK_IS_WIDGET(editor)) {
-		gtk_widget_destroy(editor);
+		gtk_window_destroy(GTK_WINDOW(editor));
 
 		g_clear_object(&editor);
 	}
@@ -219,7 +219,8 @@
 			pidgin_status_manager_remove_selected(manager);
 			break;
 		case GTK_RESPONSE_CLOSE:
-			gtk_widget_destroy(GTK_WIDGET(dialog));
+		case GTK_RESPONSE_DELETE_EVENT:
+			gtk_window_destroy(GTK_WINDOW(dialog));
 			break;
 	}
 }
--- a/pidgin/pidginstylecontext.c	Tue Aug 23 01:09:33 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Pidgin - Internet Messenger
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * 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
- * 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 library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "pidgin/pidginstylecontext.h"
-
-/* Assume light mode */
-static gboolean dark_mode_have_cache = FALSE;
-static gboolean dark_mode_cached_value = FALSE;
-
-/******************************************************************************
- * Public API
- *****************************************************************************/
-void
-pidgin_style_context_get_background_color(GdkRGBA *color) {
-	/* This value will leak, we could put a shutdown function in but right now
-	 * that seems like a bit much for a few bytes.
-	 */
-	static GdkRGBA *background = NULL;
-
-	if(g_once_init_enter(&background)) {
-		GdkRGBA *bg = NULL;
-		GtkStyleContext *context = NULL;
-		GtkWidget *window = NULL;
-
-		/* We create a window to get its background color from its style
-		 * context.  This _is_ doable without creating a window, but you still
-		 * need the window class and about four times as much code, so that's
-		 * why we do it this way.
-		 */
-		window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-		context = gtk_widget_get_style_context(window);
-
-		gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL,
-		                      GTK_STYLE_PROPERTY_BACKGROUND_COLOR, &bg,
-		                      NULL);
-		gtk_widget_destroy(window);
-
-		g_once_init_leave(&background, bg);
-	}
-
-	*color = *background;
-}
-
-gboolean
-pidgin_style_context_is_dark(void) {
-	GdkRGBA bg;
-	gdouble luminance = 0.0;
-
-	if(dark_mode_have_cache) {
-		return dark_mode_cached_value;
-	}
-
-	pidgin_style_context_get_background_color(&bg);
-
-	/* 709 coefficients from https://en.wikipedia.org/wiki/Luma_(video) */
-	luminance = (0.2126 * bg.red) + (0.7152 * bg.green) + (0.0722 * bg.blue);
-
-	dark_mode_cached_value = (luminance < 0.5);
-	dark_mode_have_cache = TRUE;
-
-	return dark_mode_cached_value;
-}
--- a/pidgin/pidginstylecontext.h	Tue Aug 23 01:09:33 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Pidgin - Internet Messenger
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * 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 library; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PIDGIN_GLOBAL_HEADER_INSIDE) && !defined(PIDGIN_COMPILATION)
-# error "only <pidgin.h> may be included directly"
-#endif
-
-#ifndef PIDGIN_STYLE_CONTEXT_H
-#define PIDGIN_STYLE_CONTEXT_H
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-/**
- * pidgin_style_context_get_background_color:
- * @color: (out): A return address of a #GdkRGBA for the background color.
- *
- * Gets the background color for #GtkWindow in the currently selected theme
- * and sets @color to that value.
- *
- * Since: 3.0.0
- */
-void pidgin_style_context_get_background_color(GdkRGBA *color);
-
-/**
- * pidgin_style_context_is_dark:
- *
- * Gets whether or not dark mode is enabled.
- *
- * Returns: %TRUE if dark mode is enabled and foreground colours should be
- *          inverted.
- *
- * Since: 3.0.0
- */
-gboolean pidgin_style_context_is_dark(void);
-
-G_END_DECLS
-
-#endif /* PIDGIN_STYLE_CONTEXT_H */
-
--- a/pidgin/plugins/disco/gtkdisco.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/disco/gtkdisco.c	Sun Aug 28 22:18:46 2022 -0500
@@ -281,9 +281,11 @@
 }
 
 static gboolean
-service_click_cb(GtkTreeView *tree, GdkEventButton *event, gpointer user_data)
+service_click_cb(G_GNUC_UNUSED GtkGestureClick *click,
+                 G_GNUC_UNUSED gint n_press,
+                 gdouble x, gdouble y, gpointer data)
 {
-	PidginDiscoDialog *dialog = user_data;
+	PidginDiscoDialog *dialog = data;
 	XmppDiscoService *service;
 
 	GtkTreePath *path;
@@ -292,13 +294,9 @@
 
 	GdkRectangle rect;
 
-	if (!gdk_event_triggers_context_menu((GdkEvent *)event)) {
-		return FALSE;
-	}
-
 	/* Figure out what was clicked */
-	if (!gtk_tree_view_get_path_at_pos(tree, event->x, event->y, &path,
-		                               NULL, NULL, NULL))
+	if (!gtk_tree_view_get_path_at_pos(dialog->tree, (gint)x, (gint)y, &path,
+	                                   NULL, NULL, NULL))
 	{
 		return FALSE;
 	}
@@ -314,8 +312,7 @@
 	}
 
 	gtk_tree_view_convert_bin_window_to_widget_coords(dialog->tree,
-	                                                  (gint)event->x,
-	                                                  (gint)event->y,
+	                                                  (gint)x, (gint)y,
 	                                                  &rect.x, &rect.y);
 	rect.width = rect.height = 1;
 
@@ -428,11 +425,6 @@
 	pidgin_disco_list_set_in_progress(dialog->discolist, FALSE);
 }
 
-static void close_button_cb(GtkButton *button, PidginDiscoDialog *dialog)
-{
-	gtk_widget_destroy(GTK_WIDGET(dialog));
-}
-
 static gboolean
 disco_query_tooltip(GtkWidget *widget, int x, int y, gboolean keyboard_mode,
                     GtkTooltip *tooltip, gpointer data)
@@ -565,7 +557,7 @@
 	while (dialogs) {
 		GtkWidget *dialog = dialogs->data;
 
-		gtk_widget_destroy(dialog);
+		gtk_window_destroy(GTK_WINDOW(dialog));
 		/* destroy_win_cb removes the dialog from the list */
 	}
 }
@@ -594,11 +586,8 @@
 	                                     model);
 	gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
 	                                     popover);
-	gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
-	                                     popover_menu);
 
 	gtk_widget_class_bind_template_callback(widget_class, destroy_win_cb);
-	gtk_widget_class_bind_template_callback(widget_class, close_button_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        dialog_select_account_cb);
 	gtk_widget_class_bind_template_callback(widget_class, row_activated_cb);
@@ -660,9 +649,6 @@
 
 	gtk_widget_insert_action_group(GTK_WIDGET(dialog), "disco",
 	                               G_ACTION_GROUP(action_group));
-
-	gtk_popover_bind_model(GTK_POPOVER(dialog->popover), dialog->popover_menu,
-	                       NULL);
 }
 
 /******************************************************************************
@@ -679,7 +665,7 @@
 pidgin_disco_dialog_new(void)
 {
 	PidginDiscoDialog *dialog = g_object_new(PIDGIN_TYPE_DISCO_DIALOG, NULL);
-	gtk_widget_show_all(GTK_WIDGET(dialog));
+	gtk_widget_show(GTK_WIDGET(dialog));
 	return dialog;
 }
 
--- a/pidgin/plugins/disco/gtkdisco.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/disco/gtkdisco.h	Sun Aug 28 22:18:46 2022 -0500
@@ -49,7 +49,6 @@
 	PidginDiscoList *discolist;
 
 	GtkPopoverMenu *popover;
-	GMenuModel *popover_menu;
 
 	gpointer prompt_handle;
 };
--- a/pidgin/plugins/disco/resources/disco.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/disco/resources/disco.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -15,12 +15,11 @@
 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  02110-1301, USA.
+along with this program; if not, see <https://www.gnu.org/licenses/>.
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.18"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -38,11 +37,6 @@
       </item>
     </section>
   </menu>
-  <object class="GtkPopoverMenu" id="popover">
-    <property name="can_focus">False</property>
-    <property name="relative-to">tree</property>
-    <property name="position">bottom</property>
-  </object>
   <object class="PidginAccountStore" id="accounts"/>
   <object class="PidginAccountFilterConnected" id="accounts_connected">
     <property name="child_model">accounts</property>
@@ -64,192 +58,147 @@
     </columns>
   </object>
   <template class="PidginDiscoDialog" parent="GtkDialog">
-    <property name="can_focus">False</property>
-    <property name="title" translatable="yes">Service Discovery</property>
-    <property name="role">service discovery</property>
-    <property name="type_hint">dialog</property>
+    <property name="title" translatable="1">Service Discovery</property>
     <signal name="destroy" handler="destroy_win_cb" swapped="no"/>
-    <child internal-child="vbox">
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can_focus">False</property>
+        <property name="vexpand">1</property>
         <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="1">_Account:</property>
+                <property name="use_underline">1</property>
+                <property name="xalign">0</property>
+              </object>
+            </child>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">_Account:</property>
-                    <property name="use_underline">True</property>
-                    <property name="xalign">0</property>
+              <object class="PidginAccountChooser" id="account_chooser">
+                <property name="model">xmpp_accounts</property>
+                <property name="active">0</property>
+                <signal name="changed" handler="dialog_select_account_cb" object="PidginDiscoDialog" swapped="no"/>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow">
+            <property name="vexpand">1</property>
+            <property name="focusable">1</property>
+            <property name="hscrollbar_policy">always</property>
+            <property name="vscrollbar_policy">always</property>
+            <property name="min_content_height">250</property>
+            <property name="child">
+              <object class="GtkTreeView" id="tree">
+                <property name="focusable">1</property>
+                <property name="model">model</property>
+                <signal name="row-activated" handler="row_activated_cb" object="PidginDiscoDialog" swapped="no"/>
+                <signal name="row-expanded" handler="row_expanded_cb" object="PidginDiscoDialog" swapped="no"/>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection">
+                    <signal name="changed" handler="selection_changed_cb" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="PidginAccountChooser" id="account_chooser">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="model">xmpp_accounts</property>
-                    <property name="active">0</property>
-                    <signal name="changed" handler="dialog_select_account_cb" object="PidginDiscoDialog" swapped="no"/>
+                  <object class="GtkGestureClick">
+                    <property name="button">3</property>
+                    <signal name="pressed" handler="service_click_cb" object="PidginDiscoDialog" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
+                </child>
+                <child>
+                  <object class="GtkPopoverMenu" id="popover">
+                    <property name="menu-model">popover_menu</property>
+                  </object>
                 </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkScrolledWindow">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">always</property>
-                <property name="vscrollbar_policy">always</property>
-                <property name="shadow_type">in</property>
-                <property name="min_content_height">250</property>
                 <child>
-                  <object class="GtkTreeView" id="tree">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="model">model</property>
-                    <signal name="button-press-event" handler="service_click_cb" object="PidginDiscoDialog" swapped="no"/>
-                    <signal name="row-activated" handler="row_activated_cb" object="PidginDiscoDialog" swapped="no"/>
-                    <signal name="row-expanded" handler="row_expanded_cb" object="PidginDiscoDialog" swapped="no"/>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection">
-                        <signal name="changed" handler="selection_changed_cb" swapped="no"/>
-                      </object>
+                  <object class="GtkTreeViewColumn">
+                    <property name="resizable">1</property>
+                    <property name="title" translatable="1">Name</property>
+                    <property name="reorderable">1</property>
+                    <property name="sort_column_id">1</property>
+                    <child>
+                      <object class="GtkCellRendererPixbuf"/>
+                      <attributes>
+                        <attribute name="pixbuf">0</attribute>
+                      </attributes>
                     </child>
                     <child>
-                      <object class="GtkTreeViewColumn">
-                        <property name="resizable">True</property>
-                        <property name="title" translatable="yes">Name</property>
-                        <property name="reorderable">True</property>
-                        <property name="sort_column_id">1</property>
-                        <child>
-                          <object class="GtkCellRendererPixbuf"/>
-                          <attributes>
-                            <attribute name="pixbuf">0</attribute>
-                          </attributes>
-                        </child>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">1</attribute>
-                          </attributes>
-                        </child>
-                      </object>
+                      <object class="GtkCellRendererText"/>
+                      <attributes>
+                        <attribute name="text">1</attribute>
+                      </attributes>
                     </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn">
+                    <property name="resizable">1</property>
+                    <property name="title" translatable="1">Description</property>
+                    <property name="reorderable">1</property>
+                    <property name="sort_column_id">2</property>
                     <child>
-                      <object class="GtkTreeViewColumn">
-                        <property name="resizable">True</property>
-                        <property name="title" translatable="yes">Description</property>
-                        <property name="reorderable">True</property>
-                        <property name="sort_column_id">2</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">2</attribute>
-                          </attributes>
-                        </child>
-                      </object>
+                      <object class="GtkCellRendererText"/>
+                      <attributes>
+                        <attribute name="text">2</attribute>
+                      </attributes>
                     </child>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkProgressBar" id="progress">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
+            </property>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
+        </child>
+        <child>
+          <object class="GtkProgressBar" id="progress">
+            <property name="valign">center</property>
+          </object>
         </child>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="stop_button">
-        <property name="label" translatable="yes">_Stop</property>
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">True</property>
-        <property name="use_underline">True</property>
+        <property name="label" translatable="1">_Stop</property>
+        <property name="focusable">1</property>
+        <property name="receives_default">1</property>
+        <property name="use_underline">1</property>
         <property name="action-name">disco.stop</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="browse_button">
-        <property name="label" translatable="yes">_Browse</property>
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">True</property>
-        <property name="use_underline">True</property>
+        <property name="label" translatable="1">_Browse</property>
+        <property name="focusable">1</property>
+        <property name="receives_default">1</property>
+        <property name="use_underline">1</property>
         <property name="action-name">disco.browse</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="register_button">
-        <property name="label" translatable="yes">Register</property>
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">True</property>
+        <property name="label" translatable="1">Register</property>
+        <property name="focusable">1</property>
+        <property name="receives_default">1</property>
         <property name="action-name">disco.register</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="add_button">
-        <property name="label" translatable="yes">_Add</property>
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">True</property>
-        <property name="use_underline">True</property>
+        <property name="label" translatable="1">_Add</property>
+        <property name="focusable">1</property>
+        <property name="receives_default">1</property>
+        <property name="use_underline">1</property>
         <property name="action-name">disco.add</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="close_button">
-        <property name="label" translatable="yes">_Close</property>
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">True</property>
-        <property name="use_underline">True</property>
-        <signal name="clicked" handler="close_button_cb" swapped="no"/>
+        <property name="label" translatable="1">_Close</property>
+        <property name="focusable">1</property>
+        <property name="receives_default">1</property>
+        <property name="use_underline">1</property>
+        <signal name="clicked" handler="gtk_window_destroy" object="PidginDiscoDialog" swapped="yes"/>
       </object>
     </child>
     <action-widgets>
--- a/pidgin/plugins/gestures/meson.build	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/gestures/meson.build	Sun Aug 28 22:18:46 2022 -0500
@@ -10,6 +10,7 @@
     c_args : ['-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="PidginPlugin-Gestures"'],
     dependencies : [libpurple_dep, libpidgin_dep, glib],
     name_prefix : '',
+    build_by_default : false,  # FIXME: Port to GTK4
     install : true, install_dir : PIDGIN_PLUGINDIR)
 
 devenv.append('PIDGIN_PLUGIN_PATH', meson.current_build_dir())
--- a/pidgin/plugins/iconaway.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/iconaway.c	Sun Aug 28 22:18:46 2022 -0500
@@ -43,7 +43,7 @@
 
 	application = g_application_get_default();
 	windows = gtk_application_get_windows(GTK_APPLICATION(application));
-	g_list_foreach(windows, (GFunc)gtk_window_iconify, NULL);
+	g_list_foreach(windows, (GFunc)gtk_window_minimize, NULL);
 }
 
 /*
@@ -60,12 +60,12 @@
 
 	return pidgin_plugin_info_new(
 		"id",           ICONAWAY_PLUGIN_ID,
-		"name",         N_("Iconify on Away"),
+		"name",         N_("Minimize on Away"),
 		"version",      DISPLAY_VERSION,
 		"category",     N_("User interface"),
-		"summary",      N_("Iconifies the buddy list and your conversations "
+		"summary",      N_("Minimizes the buddy list and your conversations "
 		                   "when you go away."),
-		"description",  N_("Iconifies the buddy list and your conversations "
+		"description",  N_("Minimizes the buddy list and your conversations "
 		                   "when you go away."),
 		"authors",      authors,
 		"website",      PURPLE_WEBSITE,
@@ -89,4 +89,4 @@
 	return TRUE;
 }
 
-GPLUGIN_NATIVE_PLUGIN_DECLARE(icon_away)
\ No newline at end of file
+GPLUGIN_NATIVE_PLUGIN_DECLARE(icon_away)
--- a/pidgin/plugins/notify.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/notify.c	Sun Aug 28 22:18:46 2022 -0500
@@ -554,7 +554,7 @@
 		gtk_widget_set_sensitive(entry, on);
 
 		purple_prefs_set_string("/plugins/gtk/X11/notify/title_string",
-		                      gtk_entry_get_text(GTK_ENTRY(entry)));
+		                        gtk_editable_get_text(GTK_EDITABLE(entry)));
 	}
 
 	apply_method();
@@ -582,7 +582,7 @@
 
 	if (purple_strequal(data, "method_string")) {
 		purple_prefs_set_string("/plugins/gtk/X11/notify/title_string",
-		                      gtk_entry_get_text(GTK_ENTRY(widget)));
+		                        gtk_editable_get_text(GTK_EDITABLE(widget)));
 	}
 
 	apply_method();
@@ -708,8 +708,8 @@
 	gtk_entry_set_max_length(GTK_ENTRY(entry), 10);
 	gtk_widget_set_sensitive(GTK_WIDGET(entry),
 	                         purple_prefs_get_bool("/plugins/gtk/X11/notify/method_string"));
-	gtk_entry_set_text(GTK_ENTRY(entry),
-	                   purple_prefs_get_string("/plugins/gtk/X11/notify/title_string"));
+	gtk_editable_set_text(GTK_EDITABLE(entry),
+	                      purple_prefs_get_string("/plugins/gtk/X11/notify/title_string"));
 	g_object_set_data(G_OBJECT(toggle), "title-entry", entry);
 	g_signal_connect(G_OBJECT(toggle), "toggled",
 	                 G_CALLBACK(method_toggle_cb), "method_string");
--- a/pidgin/plugins/spellchk.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/spellchk.c	Sun Aug 28 22:18:46 2022 -0500
@@ -1919,7 +1919,7 @@
 static void list_add_new(void)
 {
 	GtkTreeIter iter;
-	const char *word = gtk_entry_get_text(GTK_ENTRY(bad_entry));
+	const char *word = gtk_editable_get_text(GTK_EDITABLE(bad_entry));
 	gboolean case_sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(case_toggle));
 
 	if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) {
@@ -1965,7 +1965,7 @@
 
 				purple_notify_error(NULL, _("Duplicate Correction"),
 					_("The specified word already exists in the correction list."),
-					gtk_entry_get_text(GTK_ENTRY(bad_entry)), NULL);
+					gtk_editable_get_text(GTK_EDITABLE(bad_entry)), NULL);
 				return;
 			}
 
@@ -1980,7 +1980,7 @@
 	gtk_list_store_append(model, &iter);
 	gtk_list_store_set(model, &iter,
 		BAD_COLUMN, word,
-		GOOD_COLUMN, gtk_entry_get_text(GTK_ENTRY(good_entry)),
+		GOOD_COLUMN, gtk_editable_get_text(GTK_EDITABLE(good_entry)),
 		WORD_ONLY_COLUMN, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(complete_toggle)),
 		CASE_SENSITIVE_COLUMN, case_sensitive,
 		-1);
@@ -2092,8 +2092,8 @@
 static void on_entry_changed(GtkEditable *editable, gpointer data)
 {
 	gtk_widget_set_sensitive((GtkWidget*)data,
-		non_empty(gtk_entry_get_text(GTK_ENTRY(bad_entry))) &&
-		non_empty(gtk_entry_get_text(GTK_ENTRY(good_entry))));
+		non_empty(gtk_editable_get_text(GTK_EDITABLE(bad_entry))) &&
+		non_empty(gtk_editable_get_text(GTK_EDITABLE(good_entry))));
 }
 
 static void whole_words_button_toggled(GtkToggleButton *complete_toggle, GtkToggleButton *case_toggle)
@@ -2108,6 +2108,7 @@
 get_config_frame(PurplePlugin *plugin)
 {
 	GtkWidget *ret, *vbox;
+	GtkWidget *sw;
 	GtkWidget *hbox;
 	GtkWidget *button;
 	GtkSizeGroup *sg;
@@ -2181,10 +2182,14 @@
 
 	gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)),
 		 GTK_SELECTION_MULTIPLE);
-	gtk_box_pack_start(GTK_BOX(vbox),
-		pidgin_make_scrollable(tree, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
-		TRUE, TRUE, 0);
-	gtk_widget_show(tree);
+
+	sw = gtk_scrolled_window_new();
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER,
+	                               GTK_POLICY_ALWAYS);
+	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), tree);
+	gtk_widget_set_vexpand(sw, TRUE);
+	gtk_widget_set_valign(sw, GTK_ALIGN_FILL);
+	gtk_box_append(GTK_BOX(vbox), sw);
 
 	hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
--- a/pidgin/plugins/unity.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/unity.c	Sun Aug 28 22:18:46 2022 -0500
@@ -151,13 +151,15 @@
 	gint count;
 	PidginConversation *gtkconv = NULL;
 	PidginConversationWindow *convwin = NULL;
+	GtkRoot *root = NULL;
 	GtkWidget *win = NULL;
 
 	if (conv == NULL || PIDGIN_CONVERSATION(conv) == NULL)
 		return 0;
 
 	gtkconv = PIDGIN_CONVERSATION(conv);
-	win = gtk_widget_get_toplevel(gtkconv->tab_cont);
+	root = gtk_widget_get_root(gtkconv->tab_cont);
+	win = GTK_WIDGET(root);
 	convwin = PIDGIN_CONVERSATION_WINDOW(win);
 
 	if (!gtk_widget_has_focus(win) ||
@@ -285,16 +287,19 @@
 	}
 
 	if (conv) {
+		GtkRoot *root = NULL;
 		GtkWidget *win = NULL;
 		PidginConversationWindow *convwin = NULL;
 
-		win = gtk_widget_get_toplevel(PIDGIN_CONVERSATION(conv)->tab_cont);
+		root = gtk_widget_get_root(PIDGIN_CONVERSATION(conv)->tab_cont);
+		win = GTK_WIDGET(root);
 		convwin = PIDGIN_CONVERSATION_WINDOW(win);
 
 		unalert(conv);
 
 		pidgin_conversation_window_select(convwin, conv);
-		gdk_window_focus(gtk_widget_get_window(win), time(NULL));
+
+		gtk_root_set_focus(root, PIDGIN_CONVERSATION(conv)->entry);
 	}
 	g_strfreev (sections);
 }
@@ -479,20 +484,19 @@
 get_config_frame(PurplePlugin *plugin)
 {
 	GtkWidget *ret = NULL, *frame = NULL;
-	GtkWidget *vbox = NULL, *toggle = NULL;
+	GtkWidget *vbox = NULL, *toggle = NULL, *group = NULL;
 
 	ret = gtk_box_new(GTK_ORIENTATION_VERTICAL, 18);
-	gtk_container_set_border_width(GTK_CONTAINER (ret), 12);
 
 	/* Alerts */
 
 	frame = pidgin_make_frame(ret, _("Chatroom alerts"));
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-	gtk_container_add(GTK_CONTAINER(frame), vbox);
+	gtk_box_append(GTK_BOX(frame), vbox);
 
 	toggle = gtk_check_button_new_with_mnemonic(_("Chatroom message alerts _only where someone says your username"));
-	gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle),
+	gtk_box_append(GTK_BOX(vbox), toggle);
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(toggle),
 			purple_prefs_get_bool("/plugins/gtk/unity/alert_chat_nick"));
 	g_signal_connect(G_OBJECT(toggle), "toggled",
 			G_CALLBACK(alert_config_cb), NULL);
@@ -501,27 +505,32 @@
 
 	frame = pidgin_make_frame(ret, _("Launcher Icon"));
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-	gtk_container_add(GTK_CONTAINER(frame), vbox);
+	gtk_box_append(GTK_BOX(frame), vbox);
 
-	toggle = gtk_radio_button_new_with_mnemonic(NULL, _("_Disable launcher integration"));
-	gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle),
+	toggle = gtk_check_button_new_with_mnemonic(_("_Disable launcher integration"));
+	group = toggle;
+	gtk_box_append(GTK_BOX(vbox), toggle);
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(toggle),
 		purple_prefs_get_int("/plugins/gtk/unity/launcher_count") == LAUNCHER_COUNT_DISABLE);
 	g_signal_connect(G_OBJECT(toggle), "toggled",
 			G_CALLBACK(launcher_config_cb), GUINT_TO_POINTER(LAUNCHER_COUNT_DISABLE));
 
-	toggle = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(toggle),
+	toggle = gtk_check_button_new_with_mnemonic(
 			_("Show number of unread _messages on launcher icon"));
-	gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle),
+	gtk_check_button_set_group(GTK_CHECK_BUTTON(toggle),
+	                           GTK_CHECK_BUTTON(group));
+	gtk_box_append(GTK_BOX(vbox), toggle);
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(toggle),
 		purple_prefs_get_int("/plugins/gtk/unity/launcher_count") == LAUNCHER_COUNT_MESSAGES);
 	g_signal_connect(G_OBJECT(toggle), "toggled",
 			G_CALLBACK(launcher_config_cb), GUINT_TO_POINTER(LAUNCHER_COUNT_MESSAGES));
 
-	toggle = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(toggle),
+	toggle = gtk_check_button_new_with_mnemonic(
 			_("Show number of unread co_nversations on launcher icon"));
-	gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle),
+	gtk_check_button_set_group(GTK_CHECK_BUTTON(toggle),
+	                           GTK_CHECK_BUTTON(group));
+	gtk_box_append(GTK_BOX(vbox), toggle);
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(toggle),
 		purple_prefs_get_int("/plugins/gtk/unity/launcher_count") == LAUNCHER_COUNT_SOURCES);
 	g_signal_connect(G_OBJECT(toggle), "toggled",
 			G_CALLBACK(launcher_config_cb), GUINT_TO_POINTER(LAUNCHER_COUNT_SOURCES));
@@ -530,25 +539,27 @@
 
 	frame = pidgin_make_frame(ret, _("Messaging Menu"));
 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-	gtk_container_add(GTK_CONTAINER(frame), vbox);
+	gtk_box_append(GTK_BOX(frame), vbox);
 
-	toggle = gtk_radio_button_new_with_mnemonic(NULL,
+	toggle = gtk_check_button_new_with_mnemonic(
 			_("Show number of _unread messages for conversations in messaging menu"));
-	gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle),
+	group = toggle;
+	gtk_box_append(GTK_BOX(vbox), toggle);
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(toggle),
 		purple_prefs_get_int("/plugins/gtk/unity/messaging_menu_text") == MESSAGING_MENU_COUNT);
 	g_signal_connect(G_OBJECT(toggle), "toggled",
 			G_CALLBACK(messaging_menu_config_cb), GUINT_TO_POINTER(MESSAGING_MENU_COUNT));
 
-	toggle = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(toggle),
+	toggle = gtk_check_button_new_with_mnemonic(
 			_("Show _elapsed time for unread conversations in messaging menu"));
-	gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle),
+	gtk_check_button_set_group(GTK_CHECK_BUTTON(toggle),
+	                           GTK_CHECK_BUTTON(group));
+	gtk_box_append(GTK_BOX(vbox), toggle);
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(toggle),
 		purple_prefs_get_int("/plugins/gtk/unity/messaging_menu_text") == MESSAGING_MENU_TIME);
 	g_signal_connect(G_OBJECT(toggle), "toggled",
 			G_CALLBACK(messaging_menu_config_cb), GUINT_TO_POINTER(MESSAGING_MENU_TIME));
 
-	gtk_widget_show_all(ret);
 	return ret;
 }
 
--- a/pidgin/plugins/xmppconsole/console.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/xmppconsole/console.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -20,7 +20,7 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.18"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -92,210 +92,127 @@
     <property name="tag_table">tags.table</property>
   </object>
   <template parent="GtkWindow" class="PidginXmppConsole">
-    <property name="can_focus">False</property>
     <property name="title" translatable="yes">XMPP Console</property>
     <property name="default_width">580</property>
     <property name="default_height">400</property>
-    <child>
+    <property name="child">
       <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="margin_left">6</property>
+            <property name="margin-start">6</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
                 <property name="label" translatable="yes">Account:</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="PidginAccountChooser">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
                 <property name="model">connected_xmpp_accounts</property>
                 <property name="active">0</property>
+                <property name="halign">fill</property>
+                <property name="hexpand">1</property>
                 <signal name="changed" handler="dropdown_changed_cb" object="PidginXmppConsole" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkScrolledWindow">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="shadow_type">etched-in</property>
-            <child>
+            <property name="valign">fill</property>
+            <property name="vexpand">1</property>
+            <property name="focusable">1</property>
+            <property name="child">
               <object class="GtkTextView">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="editable">False</property>
+                <property name="focusable">1</property>
+                <property name="editable">0</property>
                 <property name="wrap_mode">word</property>
                 <property name="buffer">buffer</property>
               </object>
+            </property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <style>
+              <class name="toolbar"/>
+            </style>
+            <child>
+              <object class="GtkMenuButton">
+                <property name="label">&lt;iq/&gt;</property>
+                <property name="popover">iq.popover</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkMenuButton">
+                <property name="label">&lt;presence/&gt;</property>
+                <property name="popover">presence.popover</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkMenuButton">
+                <property name="label">&lt;message/&gt;</property>
+                <property name="popover">message.popover</property>
+              </object>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
         <child>
-          <object class="GtkToolbar">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="toolbar_style">text</property>
-            <child>
-              <object class="GtkToolItem">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
+          <object class="GtkScrolledWindow" id="sw">
+            <property name="focusable">1</property>
+            <property name="child">
+              <object class="GtkTextView" id="entry">
+                <property name="focusable">1</property>
+                <property name="wrap_mode">word</property>
+                <property name="buffer">entry_buffer</property>
                 <child>
-                  <object class="GtkMenuButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label">&lt;iq/&gt;</property>
-                    <property name="popover">iq.popover</property>
+                  <object class="GtkEventControllerKey">
+                    <signal name="key-pressed" handler="message_send_cb" object="PidginXmppConsole" swapped="no"/>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolItem">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <child>
-                  <object class="GtkMenuButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label">&lt;presence/&gt;</property>
-                    <property name="popover">presence.popover</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolItem">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <child>
-                  <object class="GtkMenuButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label">&lt;message/&gt;</property>
-                    <property name="popover">message.popover</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">False</property>
-              </packing>
-            </child>
+            </property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkScrolledWindow" id="sw">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="shadow_type">etched-in</property>
-            <child>
-              <object class="GtkTextView" id="entry">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="wrap_mode">word</property>
-                <property name="buffer">entry_buffer</property>
-                <signal name="key-press-event" handler="message_send_cb" object="PidginXmppConsole" swapped="no"/>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">3</property>
-          </packing>
         </child>
       </object>
-    </child>
+    </property>
   </template>
   <object class="GtkPopover" id="iq.popover">
-    <property name="can_focus">False</property>
     <property name="position">right</property>
-    <child>
+    <property name="child">
       <object class="GtkGrid">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
         <property name="column_spacing">6</property>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">To:</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">0</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Type:</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">1</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkEntry" id="iq.to">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="activates_default">True</property>
+            <property name="focusable">1</property>
+            <property name="activates_default">1</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">0</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkComboBoxText" id="iq.type">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="active">0</property>
             <items>
               <item>get</item>
@@ -303,163 +220,138 @@
               <item>result</item>
               <item>error</item>
             </items>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">1</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkButton">
             <property name="label" translatable="yes">Insert</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="can_default">True</property>
-            <property name="has_default">True</property>
-            <property name="receives_default">True</property>
+            <property name="focusable">1</property>
+            <property name="receives_default">1</property>
             <signal name="clicked" handler="iq_clicked_cb" swapped="no"/>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">2</property>
+              <property name="column-span">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">2</property>
-            <property name="width">2</property>
-          </packing>
         </child>
       </object>
-    </child>
+    </property>
   </object>
   <object class="GtkPopover" id="message.popover">
-    <property name="can_focus">False</property>
     <property name="position">right</property>
-    <child>
+    <property name="child">
       <object class="GtkGrid">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
         <property name="column_spacing">6</property>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">To:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">0</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Type:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">1</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Body:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Subject:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">3</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">3</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Thread:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">4</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">4</property>
-          </packing>
         </child>
         <child>
           <object class="GtkEntry" id="message.to">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="activates_default">True</property>
+            <property name="focusable">1</property>
+            <property name="activates_default">1</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">0</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkEntry" id="message.body">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="activates_default">True</property>
+            <property name="focusable">1</property>
+            <property name="activates_default">1</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkEntry" id="message.subject">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="activates_default">True</property>
+            <property name="focusable">1</property>
+            <property name="activates_default">1</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">3</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">3</property>
-          </packing>
         </child>
         <child>
           <object class="GtkEntry" id="message.thread">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="activates_default">True</property>
+            <property name="focusable">1</property>
+            <property name="activates_default">1</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">4</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">4</property>
-          </packing>
         </child>
         <child>
           <object class="GtkButton">
             <property name="label" translatable="yes">Insert</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="can_default">True</property>
-            <property name="has_default">True</property>
-            <property name="receives_default">True</property>
+            <property name="focusable">1</property>
+            <property name="receives_default">1</property>
             <signal name="clicked" handler="message_clicked_cb" swapped="no"/>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">5</property>
+              <property name="column-span">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">5</property>
-            <property name="width">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkComboBoxText" id="message.type">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="active">0</property>
             <items>
               <item>chat</item>
@@ -468,97 +360,81 @@
               <item>normal</item>
               <item>error</item>
             </items>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">1</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">1</property>
-          </packing>
         </child>
       </object>
-    </child>
+    </property>
   </object>
   <object class="GtkPopover" id="presence.popover">
-    <property name="can_focus">False</property>
     <property name="position">right</property>
-    <child>
+    <property name="child">
       <object class="GtkGrid">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
         <property name="column_spacing">6</property>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">To:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">0</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Type:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">1</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Show:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Status:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">3</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">3</property>
-          </packing>
         </child>
         <child>
           <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="label" translatable="yes">Priority:</property>
             <property name="xalign">0</property>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">4</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">4</property>
-          </packing>
         </child>
         <child>
           <object class="GtkEntry" id="presence.to">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
+            <property name="focusable">1</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">0</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkComboBoxText" id="presence.type">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="active">0</property>
             <items>
               <item>default</item>
@@ -570,16 +446,14 @@
               <item>probe</item>
               <item>error</item>
             </items>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">1</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkComboBoxText" id="presence.show">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
             <property name="active">0</property>
             <items>
               <item>default</item>
@@ -588,52 +462,47 @@
               <item>xa</item>
               <item>chat</item>
             </items>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkEntry" id="presence.status">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="activates_default">True</property>
+            <property name="focusable">1</property>
+            <property name="activates_default">1</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">3</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">3</property>
-          </packing>
         </child>
         <child>
           <object class="GtkButton">
             <property name="label" translatable="yes">Insert</property>
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="can_default">True</property>
-            <property name="has_default">True</property>
-            <property name="receives_default">True</property>
+            <property name="focusable">1</property>
+            <property name="receives_default">1</property>
             <signal name="clicked" handler="presence_clicked_cb" swapped="no"/>
+            <layout>
+              <property name="column">0</property>
+              <property name="row">5</property>
+              <property name="column-span">2</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">5</property>
-            <property name="width">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkSpinButton" id="presence.priority">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
+            <property name="focusable">1</property>
             <property name="adjustment">presence.priority_adjustment</property>
-            <property name="numeric">True</property>
+            <property name="numeric">1</property>
+            <layout>
+              <property name="column">1</property>
+              <property name="row">4</property>
+            </layout>
           </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">4</property>
-          </packing>
         </child>
       </object>
-    </child>
+    </property>
   </object>
 </interface>
--- a/pidgin/plugins/xmppconsole/xmppconsole.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/plugins/xmppconsole/xmppconsole.c	Sun Aug 28 22:18:46 2022 -0500
@@ -219,15 +219,20 @@
 }
 
 static gboolean
-message_send_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) {
+message_send_cb(G_GNUC_UNUSED GtkEventControllerKey *event, guint keyval,
+                G_GNUC_UNUSED guint keycode,
+                G_GNUC_UNUSED GdkModifierType state,
+                gpointer data)
+{
 	PidginXmppConsole *console = data;
 	PurpleProtocol *protocol = NULL;
 	PurpleConnection *gc;
 	gchar *text;
 	GtkTextIter start, end;
 
-	if (event->keyval != GDK_KEY_KP_Enter && event->keyval != GDK_KEY_Return)
+	if (keyval != GDK_KEY_KP_Enter && keyval != GDK_KEY_Return) {
 		return FALSE;
+	}
 
 	gc = console->gc;
 
@@ -295,9 +300,9 @@
 	node = purple_xmlnode_from_str(xmlstr, -1);
 	style = gtk_widget_get_style_context(console->entry);
 	if (node) {
-		gtk_style_context_remove_class(style, GTK_STYLE_CLASS_ERROR);
+		gtk_style_context_remove_class(style, "error");
 	} else {
-		gtk_style_context_add_class(style, GTK_STYLE_CLASS_ERROR);
+		gtk_style_context_add_class(style, "error");
 	}
 	g_free(str);
 	g_free(xmlstr);
@@ -335,7 +340,7 @@
 	const gchar *to;
 	char *stanza;
 
-	to = gtk_entry_get_text(console->iq.to);
+	to = gtk_editable_get_text(GTK_EDITABLE(console->iq.to));
 	stanza = g_strdup_printf(
 	        "<iq %s%s%s id='console%x' type='%s'>", to && *to ? "to='" : "",
 	        to && *to ? to : "", to && *to ? "'" : "", g_random_int(),
@@ -345,7 +350,7 @@
 	g_free(stanza);
 
 	/* Reset everything. */
-	gtk_entry_set_text(console->iq.to, "");
+	gtk_editable_set_text(GTK_EDITABLE(console->iq.to), "");
 	gtk_combo_box_set_active(GTK_COMBO_BOX(console->iq.type), 0);
 	gtk_popover_popdown(console->iq.popover);
 }
@@ -358,7 +363,7 @@
 	gchar *type, *show;
 	char *stanza;
 
-	to = gtk_entry_get_text(console->presence.to);
+	to = gtk_editable_get_text(GTK_EDITABLE(console->presence.to));
 	type = gtk_combo_box_text_get_active_text(console->presence.type);
 	if (purple_strequal(type, "default")) {
 		g_free(type);
@@ -369,8 +374,8 @@
 		g_free(show);
 		show = g_strdup("");
 	}
-	status = gtk_entry_get_text(console->presence.status);
-	priority = gtk_entry_get_text(console->presence.priority);
+	status = gtk_editable_get_text(GTK_EDITABLE(console->presence.status));
+	priority = gtk_editable_get_text(GTK_EDITABLE(console->presence.priority));
 	if (purple_strequal(priority, "0"))
 		priority = "";
 
@@ -404,11 +409,11 @@
 	g_free(show);
 
 	/* Reset everything. */
-	gtk_entry_set_text(console->presence.to, "");
+	gtk_editable_set_text(GTK_EDITABLE(console->presence.to), "");
 	gtk_combo_box_set_active(GTK_COMBO_BOX(console->presence.type), 0);
 	gtk_combo_box_set_active(GTK_COMBO_BOX(console->presence.show), 0);
-	gtk_entry_set_text(console->presence.status, "");
-	gtk_entry_set_text(console->presence.priority, "0");
+	gtk_editable_set_text(GTK_EDITABLE(console->presence.status), "");
+	gtk_editable_set_text(GTK_EDITABLE(console->presence.priority), "0");
 	gtk_popover_popdown(console->presence.popover);
 }
 
@@ -419,10 +424,10 @@
 	const gchar *to, *body, *thread, *subject;
 	char *stanza;
 
-	to = gtk_entry_get_text(console->message.to);
-	body = gtk_entry_get_text(console->message.body);
-	thread = gtk_entry_get_text(console->message.thread);
-	subject = gtk_entry_get_text(console->message.subject);
+	to = gtk_editable_get_text(GTK_EDITABLE(console->message.to));
+	body = gtk_editable_get_text(GTK_EDITABLE(console->message.body));
+	thread = gtk_editable_get_text(GTK_EDITABLE(console->message.thread));
+	subject = gtk_editable_get_text(GTK_EDITABLE(console->message.subject));
 
 	stanza = g_strdup_printf(
 	        "<message %s%s%s id='console%x' type='%s'>"
@@ -446,11 +451,11 @@
 	g_free(stanza);
 
 	/* Reset everything. */
-	gtk_entry_set_text(console->message.to, "");
+	gtk_editable_set_text(GTK_EDITABLE(console->message.to), "");
 	gtk_combo_box_set_active(GTK_COMBO_BOX(console->message.type), 0);
-	gtk_entry_set_text(console->message.body, "");
-	gtk_entry_set_text(console->message.subject, "0");
-	gtk_entry_set_text(console->message.thread, "0");
+	gtk_editable_set_text(GTK_EDITABLE(console->message.body), "");
+	gtk_editable_set_text(GTK_EDITABLE(console->message.subject), "0");
+	gtk_editable_set_text(GTK_EDITABLE(console->message.thread), "0");
 	gtk_popover_popdown(console->message.popover);
 }
 
@@ -568,8 +573,8 @@
 
 	entry_css = gtk_css_provider_new();
 	gtk_css_provider_load_from_data(entry_css,
-	                                "textview." GTK_STYLE_CLASS_ERROR " text {background-color:#ffcece;}",
-	                                -1, NULL);
+	                                "textview.error text {background-color:#ffcece;}",
+	                                -1);
 	context = gtk_widget_get_style_context(console->entry);
 	gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(entry_css),
 	                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
@@ -662,7 +667,7 @@
 xmpp_console_unload(GPluginPlugin *plugin, gboolean shutdown, GError **error)
 {
 	if (console) {
-		gtk_widget_destroy(GTK_WIDGET(console));
+		gtk_window_destroy(GTK_WINDOW(console));
 	}
 	return TRUE;
 }
--- a/pidgin/prefs/pidginawayprefs.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginawayprefs.c	Sun Aug 28 22:18:46 2022 -0500
@@ -22,7 +22,7 @@
 
 #include <purple.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include "pidginawayprefs.h"
 #include "gtksavedstatuses.h"
@@ -30,7 +30,7 @@
 #include "pidginprefsinternal.h"
 
 struct _PidginAwayPrefs {
-	HdyPreferencesPage parent;
+	AdwPreferencesPage parent;
 
 	PidginPrefCombo idle_reporting;
 	GtkWidget *mins_before_away;
@@ -42,7 +42,7 @@
 	GtkWidget *startup_label;
 };
 
-G_DEFINE_TYPE(PidginAwayPrefs, pidgin_away_prefs, HDY_TYPE_PREFERENCES_PAGE)
+G_DEFINE_TYPE(PidginAwayPrefs, pidgin_away_prefs, ADW_TYPE_PREFERENCES_PAGE)
 
 /******************************************************************************
  * Helpers
@@ -112,8 +112,7 @@
 	/* TODO: Show something useful if we don't have any saved statuses. */
 	menu = pidgin_status_menu(purple_savedstatus_get_idleaway(),
 	                          G_CALLBACK(set_idle_away));
-	gtk_widget_show_all(menu);
-	gtk_box_pack_start(GTK_BOX(prefs->idle_hbox), menu, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(prefs->idle_hbox), menu);
 
 	g_object_bind_property(prefs->away_when_idle, "active",
 			menu, "sensitive",
@@ -131,8 +130,7 @@
 	/* TODO: Show something useful if we don't have any saved statuses. */
 	menu = pidgin_status_menu(purple_savedstatus_get_startup(),
 	                          G_CALLBACK(set_startupstatus));
-	gtk_widget_show_all(menu);
-	gtk_box_pack_start(GTK_BOX(prefs->startup_hbox), menu, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(prefs->startup_hbox), menu);
 	gtk_label_set_mnemonic_widget(GTK_LABEL(prefs->startup_label), menu);
 	pidgin_set_accessible_label(menu, GTK_LABEL(prefs->startup_label));
 	g_object_bind_property(prefs->startup_current_status, "active",
--- a/pidgin/prefs/pidginawayprefs.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginawayprefs.h	Sun Aug 28 22:18:46 2022 -0500
@@ -30,7 +30,7 @@
 #include <glib.h>
 
 #include <gtk/gtk.h>
-#include <handy.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
@@ -44,7 +44,7 @@
  */
 #define PIDGIN_TYPE_AWAY_PREFS (pidgin_away_prefs_get_type())
 G_DECLARE_FINAL_TYPE(PidginAwayPrefs, pidgin_away_prefs,
-                     PIDGIN, AWAY_PREFS, HdyPreferencesPage)
+                     PIDGIN, AWAY_PREFS, AdwPreferencesPage)
 
 /**
  * pidgin_away_prefs_new:
--- a/pidgin/prefs/pidginconversationprefs.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginconversationprefs.c	Sun Aug 28 22:18:46 2022 -0500
@@ -24,7 +24,7 @@
 
 #include <purple.h>
 
-#include <handy.h>
+#include <adwaita.h>
 #include <talkatu.h>
 
 #include "pidginconversationprefs.h"
@@ -32,7 +32,7 @@
 #include "pidginprefsinternal.h"
 
 struct _PidginConversationPrefs {
-	HdyPreferencesPage parent;
+	AdwPreferencesPage parent;
 
 	GtkWidget *show_incoming_formatting;
 	struct {
@@ -48,7 +48,7 @@
 };
 
 G_DEFINE_TYPE(PidginConversationPrefs, pidgin_conversation_prefs,
-              HDY_TYPE_PREFERENCES_PAGE)
+              ADW_TYPE_PREFERENCES_PAGE)
 
 /******************************************************************************
  * Helpers
--- a/pidgin/prefs/pidginconversationprefs.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginconversationprefs.h	Sun Aug 28 22:18:46 2022 -0500
@@ -30,7 +30,7 @@
 #include <glib.h>
 
 #include <gtk/gtk.h>
-#include <handy.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
@@ -44,7 +44,7 @@
  */
 #define PIDGIN_TYPE_CONVERSATION_PREFS (pidgin_conversation_prefs_get_type())
 G_DECLARE_FINAL_TYPE(PidginConversationPrefs, pidgin_conversation_prefs,
-                     PIDGIN, CONVERSATION_PREFS, HdyPreferencesPage)
+                     PIDGIN, CONVERSATION_PREFS, AdwPreferencesPage)
 
 /**
  * pidgin_conversation_prefs_new:
--- a/pidgin/prefs/pidgincredentialprefs.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidgincredentialprefs.c	Sun Aug 28 22:18:46 2022 -0500
@@ -22,20 +22,20 @@
 
 #include <purple.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include "pidgincredentialprefs.h"
 
 #include "pidgincredentialproviderrow.h"
 
 struct _PidginCredentialPrefs {
-	HdyPreferencesPage parent;
+	AdwPreferencesPage parent;
 
 	GtkWidget *credential_list;
 };
 
 G_DEFINE_TYPE(PidginCredentialPrefs, pidgin_credential_prefs,
-              HDY_TYPE_PREFERENCES_PAGE)
+              ADW_TYPE_PREFERENCES_PAGE)
 
 /******************************************************************************
  * Helpers
@@ -114,15 +114,17 @@
 pidgin_credential_prefs_set_active_provider(PidginCredentialPrefs *prefs,
                                             const gchar *new_id)
 {
-	GList *rows = NULL;
+	GtkWidget *child = NULL;
 
-	rows = gtk_container_get_children(GTK_CONTAINER(prefs->credential_list));
-	for (; rows; rows = g_list_delete_link(rows, rows)) {
+	for (child = gtk_widget_get_first_child(prefs->credential_list);
+	     child;
+	     child = gtk_widget_get_next_sibling(child))
+	{
 		PidginCredentialProviderRow *row = NULL;
 		PurpleCredentialProvider *provider = NULL;
 		const gchar *id = NULL;
 
-		row = PIDGIN_CREDENTIAL_PROVIDER_ROW(rows->data);
+		row = PIDGIN_CREDENTIAL_PROVIDER_ROW(child);
 		provider = pidgin_credential_provider_row_get_provider(row);
 		id = purple_credential_provider_get_id(provider);
 
--- a/pidgin/prefs/pidgincredentialprefs.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidgincredentialprefs.h	Sun Aug 28 22:18:46 2022 -0500
@@ -30,7 +30,7 @@
 #include <glib.h>
 
 #include <gtk/gtk.h>
-#include <handy.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
@@ -43,7 +43,7 @@
  */
 #define PIDGIN_TYPE_CREDENTIAL_PREFS (pidgin_credential_prefs_get_type())
 G_DECLARE_FINAL_TYPE(PidginCredentialPrefs, pidgin_credential_prefs,
-                     PIDGIN, CREDENTIAL_PREFS, HdyPreferencesPage)
+                     PIDGIN, CREDENTIAL_PREFS, AdwPreferencesPage)
 
 /**
  * PidginCredentialPrefs:
--- a/pidgin/prefs/pidgincredentialproviderrow.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidgincredentialproviderrow.c	Sun Aug 28 22:18:46 2022 -0500
@@ -22,12 +22,12 @@
 
 #include <purple.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include "pidgincredentialproviderrow.h"
 
 struct _PidginCredentialProviderRow {
-	HdyActionRow parent;
+	AdwActionRow parent;
 
 	PurpleCredentialProvider *provider;
 
@@ -44,7 +44,7 @@
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
 
 G_DEFINE_TYPE(PidginCredentialProviderRow, pidgin_credential_provider_row,
-              HDY_TYPE_ACTION_ROW)
+              ADW_TYPE_ACTION_ROW)
 
 /******************************************************************************
  * Helpers
@@ -58,11 +58,11 @@
 	}
 
 	if(PURPLE_IS_CREDENTIAL_PROVIDER(provider)) {
-		hdy_preferences_row_set_title(
-		    HDY_PREFERENCES_ROW(row),
+		adw_preferences_row_set_title(
+		    ADW_PREFERENCES_ROW(row),
 		    purple_credential_provider_get_name(provider));
-		hdy_action_row_set_subtitle(
-		    HDY_ACTION_ROW(row),
+		adw_action_row_set_subtitle(
+		    ADW_ACTION_ROW(row),
 		    purple_credential_provider_get_description(provider));
 		/* Not implemented yet, so always hide the configure button. */
 		gtk_widget_set_visible(row->configure, FALSE);
--- a/pidgin/prefs/pidgincredentialproviderrow.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidgincredentialproviderrow.h	Sun Aug 28 22:18:46 2022 -0500
@@ -31,7 +31,7 @@
 
 #include <gtk/gtk.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
@@ -45,7 +45,7 @@
 #define PIDGIN_TYPE_CREDENTIAL_PROVIDER_ROW (pidgin_credential_provider_row_get_type())
 G_DECLARE_FINAL_TYPE(PidginCredentialProviderRow,
                      pidgin_credential_provider_row,
-                     PIDGIN, CREDENTIAL_PROVIDER_ROW, HdyActionRow)
+                     PIDGIN, CREDENTIAL_PROVIDER_ROW, AdwActionRow)
 
 /**
  * PidginCredentialProviderRow:
--- a/pidgin/prefs/pidginnetworkprefs.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginnetworkprefs.c	Sun Aug 28 22:18:46 2022 -0500
@@ -24,14 +24,14 @@
 
 #include <purple.h>
 
-#include <handy.h>
+#include <adwaita.h>
 #include <nice.h>
 
 #include "pidginnetworkprefs.h"
 #include "pidginprefsinternal.h"
 
 struct _PidginNetworkPrefs {
-	HdyPreferencesPage parent;
+	AdwPreferencesPage parent;
 
 	GtkWidget *stun_server;
 	GtkWidget *auto_ip;
@@ -50,16 +50,16 @@
 };
 
 G_DEFINE_TYPE(PidginNetworkPrefs, pidgin_network_prefs,
-              HDY_TYPE_PREFERENCES_PAGE)
+              ADW_TYPE_PREFERENCES_PAGE)
 
 /******************************************************************************
  * Helpers
  *****************************************************************************/
 static void
-network_ip_changed(GtkEntry *entry, gpointer data)
+network_ip_changed(GtkEditable *editable, gpointer data)
 {
-	const gchar *text = gtk_entry_get_text(entry);
-	GtkStyleContext *context = gtk_widget_get_style_context(GTK_WIDGET(entry));
+	const gchar *text = gtk_editable_get_text(GTK_EDITABLE(editable));
+	GtkStyleContext *context = gtk_widget_get_style_context(GTK_WIDGET(editable));
 
 	if (text && *text) {
 		if (g_hostname_is_ip_address(text)) {
@@ -78,28 +78,26 @@
 	}
 }
 
-static gboolean
-network_stun_server_changed_cb(GtkWidget *widget,
-                               GdkEventFocus *event, gpointer data)
+static void
+network_stun_server_changed_cb(G_GNUC_UNUSED GtkEventControllerFocus *focus,
+                               gpointer data)
 {
-	GtkEntry *entry = GTK_ENTRY(widget);
+	GtkEditable *editable = data;
+
 	purple_prefs_set_string("/purple/network/stun_server",
-		gtk_entry_get_text(entry));
-	purple_network_set_stun_server(gtk_entry_get_text(entry));
-
-	return FALSE;
+	                        gtk_editable_get_text(editable));
+	purple_network_set_stun_server(gtk_editable_get_text(editable));
 }
 
-static gboolean
-network_turn_server_changed_cb(GtkWidget *widget,
-                               GdkEventFocus *event, gpointer data)
+static void
+network_turn_server_changed_cb(G_GNUC_UNUSED GtkEventControllerFocus *focus,
+                               gpointer data)
 {
-	GtkEntry *entry = GTK_ENTRY(widget);
+	GtkEditable *editable = data;
+
 	purple_prefs_set_string("/purple/network/turn_server",
-		gtk_entry_get_text(entry));
-	purple_network_set_turn_server(gtk_entry_get_text(entry));
-
-	return FALSE;
+	                        gtk_editable_get_text(editable));
+	purple_network_set_turn_server(gtk_editable_get_text(editable));
 }
 
 static void
@@ -138,7 +136,7 @@
 	}
 
 	auto_ip_text = g_strdup_printf(_("Use _automatically detected IP address: %s"), ip);
-	gtk_button_set_label(GTK_BUTTON(button), auto_ip_text);
+	gtk_check_button_set_label(GTK_CHECK_BUTTON(button), auto_ip_text);
 	g_free(auto_ip_text);
 	g_list_free_full(list, g_free);
 }
@@ -201,14 +199,14 @@
 
 	gtk_widget_init_template(GTK_WIDGET(prefs));
 
-	gtk_entry_set_text(GTK_ENTRY(prefs->stun_server),
-			purple_prefs_get_string("/purple/network/stun_server"));
+	gtk_editable_set_text(GTK_EDITABLE(prefs->stun_server),
+	                      purple_prefs_get_string("/purple/network/stun_server"));
 
 	pidgin_prefs_bind_checkbox("/purple/network/auto_ip", prefs->auto_ip);
 	auto_ip_button_clicked_cb(prefs->auto_ip, NULL); /* Update label */
 
-	gtk_entry_set_text(GTK_ENTRY(prefs->public_ip),
-			purple_network_get_public_ip());
+	gtk_editable_set_text(GTK_EDITABLE(prefs->public_ip),
+	                      purple_network_get_public_ip());
 
 	ip_css = gtk_css_provider_new();
 	gtk_css_provider_load_from_resource(ip_css,
@@ -238,8 +236,8 @@
 			prefs->ports_range_end);
 
 	/* TURN server */
-	gtk_entry_set_text(GTK_ENTRY(prefs->turn_server),
-			purple_prefs_get_string("/purple/network/turn_server"));
+	gtk_editable_set_text(GTK_EDITABLE(prefs->turn_server),
+	                      purple_prefs_get_string("/purple/network/turn_server"));
 
 	pidgin_prefs_bind_spin_button("/purple/network/turn_port",
 			prefs->turn_port_udp);
--- a/pidgin/prefs/pidginnetworkprefs.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginnetworkprefs.h	Sun Aug 28 22:18:46 2022 -0500
@@ -30,7 +30,7 @@
 #include <glib.h>
 
 #include <gtk/gtk.h>
-#include <handy.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
@@ -44,7 +44,7 @@
  */
 #define PIDGIN_TYPE_NETWORK_PREFS (pidgin_network_prefs_get_type())
 G_DECLARE_FINAL_TYPE(PidginNetworkPrefs, pidgin_network_prefs,
-                     PIDGIN, NETWORK_PREFS, HdyPreferencesPage)
+                     PIDGIN, NETWORK_PREFS, AdwPreferencesPage)
 
 /**
  * pidgin_network_prefs_new:
--- a/pidgin/prefs/pidginprefs.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginprefs.c	Sun Aug 28 22:18:46 2022 -0500
@@ -80,7 +80,6 @@
 		gtk_widget_set_size_request(spin, 60, -1);
 	g_signal_connect(G_OBJECT(adjust), "value-changed",
 					 G_CALLBACK(update_spin_value), GTK_WIDGET(spin));
-	gtk_widget_show(spin);
 
 	return pidgin_add_widget_to_vbox(GTK_BOX(box), title, sg, spin, FALSE, NULL);
 }
@@ -105,7 +104,7 @@
 {
 	const char *key = (const char*)data;
 
-	purple_prefs_set_string(key, gtk_entry_get_text(entry));
+	purple_prefs_set_string(key, gtk_editable_get_text(GTK_EDITABLE(entry)));
 }
 
 void
@@ -115,7 +114,7 @@
 
 	value = purple_prefs_get_string(key);
 
-	gtk_entry_set_text(GTK_ENTRY(entry), value);
+	gtk_editable_set_text(GTK_EDITABLE(entry), value);
 	g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(entry_set),
 			(char*)key);
 }
@@ -371,7 +370,7 @@
 set_bool_pref(GtkWidget *w, const char *key)
 {
 	purple_prefs_set_bool(key,
-			gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
+			gtk_check_button_get_active(GTK_CHECK_BUTTON(w)));
 }
 
 GtkWidget *
@@ -380,23 +379,21 @@
 	GtkWidget *button;
 
 	button = gtk_check_button_new_with_mnemonic(text);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(button),
 			purple_prefs_get_bool(key));
 
-	gtk_box_pack_start(GTK_BOX(page), button, FALSE, FALSE, 0);
+	gtk_box_append(GTK_BOX(page), button);
 
 	g_signal_connect(G_OBJECT(button), "clicked",
 			G_CALLBACK(set_bool_pref), (char *)key);
 
-	gtk_widget_show(button);
-
 	return button;
 }
 
 void
 pidgin_prefs_bind_checkbox(const char *key, GtkWidget *button)
 {
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
+	gtk_check_button_set_active(GTK_CHECK_BUTTON(button),
 			purple_prefs_get_bool(key));
 	g_signal_connect(G_OBJECT(button), "toggled",
 			G_CALLBACK(set_bool_pref), (char *)key);
--- a/pidgin/prefs/pidginproxyprefs.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginproxyprefs.c	Sun Aug 28 22:18:46 2022 -0500
@@ -24,20 +24,22 @@
 
 #include <purple.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include "pidginproxyprefs.h"
 #include "pidginprefsinternal.h"
 
 struct _PidginProxyPrefs {
-	HdyPreferencesPage parent;
+	AdwPreferencesPage parent;
 
-	GtkWidget *stack;
 	/* GNOME version */
+	GtkWidget *gnome;
 	GtkWidget *gnome_not_found;
 	GtkWidget *gnome_program;
 	gchar *gnome_program_path;
+
 	/* Non-GNOME version */
+	GtkWidget *nongnome;
 	GtkWidget *socks4_remotedns;
 	PidginPrefCombo type;
 	GtkWidget *options;
@@ -47,7 +49,7 @@
 	GtkWidget *password;
 };
 
-G_DEFINE_TYPE(PidginProxyPrefs, pidgin_proxy_prefs, HDY_TYPE_PREFERENCES_PAGE)
+G_DEFINE_TYPE(PidginProxyPrefs, pidgin_proxy_prefs, ADW_TYPE_PREFERENCES_PAGE)
 
 /******************************************************************************
  * Helpers
@@ -59,11 +61,9 @@
 	PidginProxyPrefs *prefs = data;
 	const char *proxy = value;
 
-	if (!purple_strequal(proxy, "none") && !purple_strequal(proxy, "envvar")) {
-		gtk_widget_show_all(prefs->options);
-	} else {
-		gtk_widget_hide(prefs->options);
-	}
+	gtk_widget_set_visible(prefs->options,
+	                       !purple_strequal(proxy, "none") &&
+	                       !purple_strequal(proxy, "envvar"));
 }
 
 static void
@@ -73,17 +73,17 @@
 
 	if (entry == prefs->host) {
 		purple_prefs_set_string("/purple/proxy/host",
-				gtk_entry_get_text(GTK_ENTRY(entry)));
+		                        gtk_editable_get_text(GTK_EDITABLE(entry)));
 	} else if (entry == prefs->port) {
 		purple_prefs_set_int("/purple/proxy/port",
 				gtk_spin_button_get_value_as_int(
 					GTK_SPIN_BUTTON(entry)));
 	} else if (entry == prefs->username) {
 		purple_prefs_set_string("/purple/proxy/username",
-				gtk_entry_get_text(GTK_ENTRY(entry)));
+		                        gtk_editable_get_text(GTK_EDITABLE(entry)));
 	} else if (entry == prefs->password) {
 		purple_prefs_set_string("/purple/proxy/password",
-				gtk_entry_get_text(GTK_ENTRY(entry)));
+		                        gtk_editable_get_text(GTK_EDITABLE(entry)));
 	}
 }
 
@@ -130,11 +130,14 @@
 	);
 
 	gtk_widget_class_bind_template_child(
-			widget_class, PidginProxyPrefs, stack);
+			widget_class, PidginProxyPrefs, gnome);
 	gtk_widget_class_bind_template_child(
 			widget_class, PidginProxyPrefs, gnome_not_found);
 	gtk_widget_class_bind_template_child(
 			widget_class, PidginProxyPrefs, gnome_program);
+
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginProxyPrefs, nongnome);
 	gtk_widget_class_bind_template_child(
 			widget_class, PidginProxyPrefs, socks4_remotedns);
 	gtk_widget_class_bind_template_child(
@@ -165,8 +168,8 @@
 	if(purple_running_gnome()) {
 		gchar *path = NULL;
 
-		gtk_stack_set_visible_child_name(GTK_STACK(prefs->stack),
-				"gnome");
+		gtk_widget_set_visible(prefs->gnome, TRUE);
+		gtk_widget_set_visible(prefs->nongnome, FALSE);
 
 		path = g_find_program_in_path("gnome-network-properties");
 		if (path == NULL) {
@@ -184,9 +187,10 @@
 		prefs->gnome_program_path = path;
 		gtk_widget_set_visible(prefs->gnome_not_found, path == NULL);
 		gtk_widget_set_visible(prefs->gnome_program, path != NULL);
+
 	} else {
-		gtk_stack_set_visible_child_name(GTK_STACK(prefs->stack),
-				"nongnome");
+		gtk_widget_set_visible(prefs->gnome, FALSE);
+		gtk_widget_set_visible(prefs->nongnome, TRUE);
 
 		/* This is a global option that affects SOCKS4 usage even with
 		 * account-specific proxy settings */
@@ -202,9 +206,11 @@
 				proxy_changed_cb, prefs);
 
 		if (proxy_info != NULL) {
-			if (purple_proxy_info_get_hostname(proxy_info)) {
-				gtk_entry_set_text(GTK_ENTRY(prefs->host),
-						purple_proxy_info_get_hostname(proxy_info));
+			const gchar *value = NULL;
+
+			value = purple_proxy_info_get_hostname(proxy_info);
+			if(value != NULL) {
+				gtk_editable_set_text(GTK_EDITABLE(prefs->host), value);
 			}
 
 			if (purple_proxy_info_get_port(proxy_info) != 0) {
@@ -213,14 +219,14 @@
 						purple_proxy_info_get_port(proxy_info));
 			}
 
-			if (purple_proxy_info_get_username(proxy_info) != NULL) {
-				gtk_entry_set_text(GTK_ENTRY(prefs->username),
-						purple_proxy_info_get_username(proxy_info));
+			value = purple_proxy_info_get_username(proxy_info);
+			if(value != NULL) {
+				gtk_editable_set_text(GTK_EDITABLE(prefs->username), value);
 			}
 
-			if (purple_proxy_info_get_password(proxy_info) != NULL) {
-				gtk_entry_set_text(GTK_ENTRY(prefs->password),
-						purple_proxy_info_get_password(proxy_info));
+			value = purple_proxy_info_get_password(proxy_info);
+			if(value != NULL) {
+				gtk_editable_set_text(GTK_EDITABLE(prefs->password), value);
 			}
 		}
 
--- a/pidgin/prefs/pidginproxyprefs.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginproxyprefs.h	Sun Aug 28 22:18:46 2022 -0500
@@ -30,7 +30,7 @@
 #include <glib.h>
 
 #include <gtk/gtk.h>
-#include <handy.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
@@ -44,7 +44,7 @@
  */
 #define PIDGIN_TYPE_PROXY_PREFS (pidgin_proxy_prefs_get_type())
 G_DECLARE_FINAL_TYPE(PidginProxyPrefs, pidgin_proxy_prefs,
-                     PIDGIN, PROXY_PREFS, HdyPreferencesPage)
+                     PIDGIN, PROXY_PREFS, AdwPreferencesPage)
 
 /**
  * pidgin_proxy_prefs_new:
--- a/pidgin/prefs/pidginvvprefs.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginvvprefs.c	Sun Aug 28 22:18:46 2022 -0500
@@ -30,14 +30,14 @@
 
 #include <purple.h>
 
-#include <handy.h>
+#include <adwaita.h>
 
 #include "pidginvvprefs.h"
 #include "pidgincore.h"
 #include "pidginprefsinternal.h"
 
 struct _PidginVVPrefs {
-	HdyPreferencesPage parent;
+	AdwPreferencesPage parent;
 
 	struct {
 		PidginPrefCombo input;
@@ -54,13 +54,12 @@
 		PidginPrefCombo input;
 		PidginPrefCombo output;
 		GtkWidget *frame;
-		GtkWidget *sink_widget;
 		GtkWidget *test;
 		GstElement *pipeline;
 	} video;
 };
 
-G_DEFINE_TYPE(PidginVVPrefs, pidgin_vv_prefs, HDY_TYPE_PREFERENCES_PAGE)
+G_DEFINE_TYPE(PidginVVPrefs, pidgin_vv_prefs, ADW_TYPE_PREFERENCES_PAGE)
 
 /******************************************************************************
  * Helpers
@@ -105,7 +104,7 @@
 }
 
 static GstElement *
-create_voice_pipeline(void)
+create_voice_pipeline(PidginVVPrefs *prefs)
 {
 	GstElement *pipeline;
 	GstElement *src, *sink;
@@ -121,6 +120,10 @@
 	level = gst_element_factory_make("level", "level");
 	valve = gst_element_factory_make("valve", "valve");
 
+	g_object_set(volume, "volume",
+	             gtk_scale_button_get_value(GTK_SCALE_BUTTON(prefs->voice.volume)) / 100.0,
+	             NULL);
+
 	gst_bin_add_many(GST_BIN(pipeline), src, volume, level, valve, sink, NULL);
 	gst_element_link_many(src, volume, level, valve, sink, NULL);
 
@@ -219,7 +222,7 @@
 {
 	GstBus *bus;
 
-	prefs->voice.pipeline = create_voice_pipeline();
+	prefs->voice.pipeline = create_voice_pipeline(prefs);
 	bus = gst_pipeline_get_bus(GST_PIPELINE(prefs->voice.pipeline));
 	gst_bus_add_signal_watch(bus);
 	g_signal_connect(bus, "message", G_CALLBACK(gst_bus_cb), prefs);
@@ -339,13 +342,13 @@
 	g_object_get(sink, "widget", &video, NULL);
 	gtk_widget_show(video);
 
-	g_clear_pointer(&prefs->video.sink_widget, gtk_widget_destroy);
 	gtk_widget_set_size_request(prefs->video.frame, 400, 300);
-	gtk_container_add(GTK_CONTAINER(prefs->video.frame), video);
-	prefs->video.sink_widget = video;
+	gtk_aspect_frame_set_child(GTK_ASPECT_FRAME(prefs->video.frame), video);
 
 	gst_element_set_state(GST_ELEMENT(prefs->video.pipeline),
 	                      GST_STATE_PLAYING);
+
+	g_object_unref(video);
 }
 
 static void
--- a/pidgin/prefs/pidginvvprefs.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/prefs/pidginvvprefs.h	Sun Aug 28 22:18:46 2022 -0500
@@ -30,7 +30,7 @@
 #include <glib.h>
 
 #include <gtk/gtk.h>
-#include <handy.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
@@ -44,7 +44,7 @@
  */
 #define PIDGIN_TYPE_VV_PREFS (pidgin_vv_prefs_get_type())
 G_DECLARE_FINAL_TYPE(PidginVVPrefs, pidgin_vv_prefs,
-                     PIDGIN, VV_PREFS, HdyPreferencesPage)
+                     PIDGIN, VV_PREFS, AdwPreferencesPage)
 
 /**
  * pidgin_vv_prefs_new:
--- a/pidgin/resources/About/about.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/About/about.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -20,7 +20,7 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="Talkatu" version="0.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -42,10 +42,7 @@
       <column type="gfloat"/>
     </columns>
   </object>
-  <object class="TalkatuTagTable" id="main_tag_table"/>
-  <object class="TalkatuMarkdownBuffer" id="main_buffer">
-    <property name="tag-table">main_tag_table</property>
-  </object>
+  <object class="TalkatuMarkdownBuffer" id="main_buffer"/>
   <object class="GtkTreeStore" id="translators_store">
     <columns>
       <!-- column-name markup -->
@@ -55,262 +52,206 @@
     </columns>
   </object>
   <template class="PidginAboutDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="border-width">5</property>
-    <property name="resizable">False</property>
-    <property name="window-position">center</property>
-    <property name="type-hint">dialog</property>
+    <property name="resizable">0</property>
     <signal name="response" handler="pidgin_about_dialog_response_cb" swapped="no"/>
-    <child internal-child="vbox">
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox">
-            <property name="can-focus">False</property>
-            <property name="layout-style">spread</property>
-            <child>
-              <object class="GtkStackSwitcher" id="switcher">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="stack">stack</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="close_button">
-                <property name="label" translatable="yes">Close</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="border-width">12</property>
+            <property name="vexpand">1</property>
+            <property name="valign">fill</property>
             <property name="orientation">vertical</property>
             <property name="spacing">5</property>
             <child>
-              <object class="GtkEventBox" id="event-box">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="above-child">True</property>
-                <child>
-                  <object class="GtkImage" id="logo">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="resource">/im/pidgin/Pidgin3/logo.png</property>
-                    <property name="icon_size">6</property>
-                  </object>
-                </child>
+              <object class="GtkPicture" id="logo">
+                <property name="file">resource:///im/pidgin/Pidgin3/logo.png</property>
+                <property name="halign">center</property>
+                <property name="valign">center</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="application_name">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Pidgin</property>
+                <property name="label" translatable="1">Pidgin</property>
                 <property name="justify">center</property>
-                <property name="selectable">True</property>
+                <property name="selectable">1</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
+                  <attribute name="weight" value="bold"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkStack" id="stack">
+                <property name="vexpand">1</property>
+                <property name="valign">fill</property>
                 <property name="width-request">400</property>
                 <property name="height-request">150</property>
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="margin-bottom">2</property>
                 <property name="transition-type">slide-up</property>
                 <child>
-                  <object class="GtkScrolledWindow" id="main_scrolled_window">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="hscrollbar-policy">never</property>
-                    <property name="shadow-type">in</property>
-                    <child>
-                      <object class="TalkatuView" id="main_page">
-                        <property name="can-focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="editable">False</property>
-                        <property name="wrap-mode">word</property>
-                        <property name="buffer">main_buffer</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
+                  <object class="GtkStackPage">
                     <property name="name">main</property>
-                    <property name="title" translatable="yes">General</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow" id="developers_page">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="hscrollbar-policy">never</property>
-                    <property name="shadow-type">in</property>
-                    <child>
-                      <object class="GtkTreeView" id="developers_treeview">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="model">developers_store</property>
-                        <property name="headers-visible">False</property>
-                        <property name="show-expanders">False</property>
-                        <child internal-child="selection">
-                          <object class="GtkTreeSelection"/>
-                        </child>
+                    <property name="title" translatable="1">General</property>
+                    <property name="child">
+                      <object class="GtkScrolledWindow" id="main_scrolled_window">
+                        <property name="focusable">1</property>
+                        <property name="hscrollbar-policy">never</property>
                         <child>
-                          <object class="GtkTreeViewColumn" id="developers_column">
-                            <property name="resizable">True</property>
-                            <property name="sizing">autosize</property>
-                            <child>
-                              <object class="GtkCellRendererText" id="developers_cell_renderer"/>
-                              <attributes>
-                                <attribute name="xalign">1</attribute>
-                                <attribute name="markup">0</attribute>
-                              </attributes>
-                            </child>
+                          <object class="TalkatuView" id="main_page">
+                            <property name="focusable">1</property>
+                            <property name="editable">0</property>
+                            <property name="margin-start">12</property>
+                            <property name="margin-end">12</property>
+                            <property name="wrap-mode">word</property>
+                            <property name="buffer">main_buffer</property>
                           </object>
                         </child>
                       </object>
-                    </child>
+                    </property>
                   </object>
-                  <packing>
-                    <property name="name">developers</property>
-                    <property name="title" translatable="yes">Developers</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkScrolledWindow" id="translators_page">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="shadow-type">in</property>
-                    <child>
-                      <object class="GtkTreeView" id="translators_treeview">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="model">translators_store</property>
-                        <property name="headers-visible">False</property>
-                        <property name="show-expanders">False</property>
-                        <child internal-child="selection">
-                          <object class="GtkTreeSelection"/>
-                        </child>
-                        <child>
-                          <object class="GtkTreeViewColumn" id="translators_column">
+                  <object class="GtkStackPage">
+                    <property name="name">developers</property>
+                    <property name="title" translatable="1">Developers</property>
+                    <property name="child">
+                      <object class="GtkScrolledWindow" id="developers_page">
+                        <property name="focusable">1</property>
+                        <property name="hscrollbar-policy">never</property>
+                        <property name="child">
+                          <object class="GtkTreeView" id="developers_treeview">
+                            <property name="focusable">1</property>
+                            <property name="model">developers_store</property>
+                            <property name="headers-visible">0</property>
+                            <property name="show-expanders">0</property>
+                            <child internal-child="selection">
+                              <object class="GtkTreeSelection"/>
+                            </child>
                             <child>
-                              <object class="GtkCellRendererText" id="translators_cell_renderer"/>
-                              <attributes>
-                                <attribute name="xalign">1</attribute>
-                                <attribute name="markup">0</attribute>
-                              </attributes>
+                              <object class="GtkTreeViewColumn" id="developers_column">
+                                <property name="resizable">1</property>
+                                <property name="sizing">autosize</property>
+                                <child>
+                                  <object class="GtkCellRendererText" id="developers_cell_renderer"/>
+                                  <attributes>
+                                    <attribute name="xalign">1</attribute>
+                                    <attribute name="markup">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
                             </child>
                           </object>
-                        </child>
+                        </property>
                       </object>
-                    </child>
+                    </property>
                   </object>
-                  <packing>
-                    <property name="name">translators</property>
-                    <property name="title" translatable="yes">Translators</property>
-                    <property name="position">2</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkScrolledWindow" id="build_info_page">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="hscrollbar-policy">never</property>
-                    <property name="shadow-type">in</property>
-                    <child>
-                      <object class="GtkTreeView" id="build_info_treeview">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="model">build_info_store</property>
-                        <property name="headers-visible">False</property>
-                        <property name="show-expanders">False</property>
-                        <child internal-child="selection">
-                          <object class="GtkTreeSelection"/>
-                        </child>
-                        <child>
-                          <object class="GtkTreeViewColumn">
+                  <object class="GtkStackPage">
+                    <property name="name">translators</property>
+                    <property name="title" translatable="1">Translators</property>
+                    <property name="child">
+                      <object class="GtkScrolledWindow" id="translators_page">
+                        <property name="focusable">1</property>
+                        <property name="child">
+                          <object class="GtkTreeView" id="translators_treeview">
+                            <property name="focusable">1</property>
+                            <property name="model">translators_store</property>
+                            <property name="headers-visible">0</property>
+                            <property name="show-expanders">0</property>
+                            <child internal-child="selection">
+                              <object class="GtkTreeSelection"/>
+                            </child>
                             <child>
-                              <object class="GtkCellRendererText"/>
-                              <attributes>
-                                <attribute name="markup">0</attribute>
-                              </attributes>
+                              <object class="GtkTreeViewColumn" id="translators_column">
+                                <child>
+                                  <object class="GtkCellRendererText" id="translators_cell_renderer"/>
+                                  <attributes>
+                                    <attribute name="xalign">1</attribute>
+                                    <attribute name="markup">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
                             </child>
                           </object>
-                        </child>
-                        <child>
-                          <object class="GtkTreeViewColumn">
+                        </property>
+                      </object>
+                    </property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkStackPage">
+                    <property name="name">build-info</property>
+                    <property name="title" translatable="1">Build Information</property>
+                    <property name="child">
+                      <object class="GtkScrolledWindow" id="build_info_page">
+                        <property name="focusable">1</property>
+                        <property name="hscrollbar-policy">never</property>
+                        <property name="child">
+                          <object class="GtkTreeView" id="build_info_treeview">
+                            <property name="focusable">1</property>
+                            <property name="model">build_info_store</property>
+                            <property name="headers-visible">0</property>
+                            <property name="show-expanders">0</property>
+                            <child internal-child="selection">
+                              <object class="GtkTreeSelection"/>
+                            </child>
                             <child>
-                              <object class="GtkCellRendererText"/>
-                              <attributes>
-                                <attribute name="markup">1</attribute>
-                              </attributes>
+                              <object class="GtkTreeViewColumn">
+                                <child>
+                                  <object class="GtkCellRendererText"/>
+                                  <attributes>
+                                    <attribute name="markup">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn">
+                                <child>
+                                  <object class="GtkCellRendererText"/>
+                                  <attributes>
+                                    <attribute name="markup">1</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
                             </child>
                           </object>
-                        </child>
+                        </property>
                       </object>
-                    </child>
+                    </property>
                   </object>
-                  <packing>
-                    <property name="name">build-info</property>
-                    <property name="title" translatable="yes">Build Information</property>
-                    <property name="position">3</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
     <action-widgets>
       <action-widget response="-7">close_button</action-widget>
     </action-widgets>
+    <child internal-child="action_area">
+      <object class="GtkBox">
+        <property name="valign">center</property>
+        <child>
+          <object class="GtkStackSwitcher" id="switcher">
+            <property name="stack">stack</property>
+            <property name="hexpand">1</property>
+            <property name="halign">fill</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton" id="close_button">
+            <property name="label" translatable="1">Close</property>
+            <property name="focusable">1</property>
+            <property name="receives-default">1</property>
+            <property name="hexpand">1</property>
+            <property name="halign">fill</property>
+          </object>
+        </child>
+      </object>
+    </child>
   </template>
 </interface>
--- a/pidgin/resources/Accounts/chooser.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Accounts/chooser.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,23 +14,19 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.20"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginAccountChooser" parent="GtkComboBox">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
     <child>
       <object class="GtkCellRendererPixbuf"/>
       <attributes>
-        <attribute name="pixbuf">2</attribute>
+        <attribute name="icon-name">2</attribute>
       </attributes>
     </child>
     <child>
--- a/pidgin/resources/Accounts/editor.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Accounts/editor.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -19,100 +19,60 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginAccountEditor" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="type-hint">dialog</property>
     <signal name="response" handler="pidgin_account_editor_response_cb" swapped="no"/>
-    <child internal-child="vbox">
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox">
-            <property name="can-focus">False</property>
-            <property name="layout-style">end</property>
+        <child>
+          <object class="GtkNotebook" id="notebook">
+            <property name="focusable">1</property>
             <child>
-              <object class="GtkButton" id="button1">
-                <property name="label" translatable="yes">_Cancel</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
+              <object class="GtkNotebookPage">
                 <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button2">
-                <property name="label" translatable="yes">_Save</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
+                <property name="child">
+                  <object class="PidginProxyOptions" id="proxy_options">
+                    <property name="margin-start">12</property>
+                    <property name="margin-end">12</property>
+                    <property name="margin-top">12</property>
+                    <property name="margin-bottom">12</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">6</property>
+                  </object>
+                </property>
+                <property name="tab">
+                  <object class="GtkLabel">
+                    <property name="label" translatable="1">_Proxy</property>
+                    <property name="use-underline">1</property>
+                  </object>
+                </property>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
         </child>
-        <child>
-          <object class="GtkNotebook" id="notebook">
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <child>
-              <object class="PidginProxyOptions" id="proxy_options">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="margin-left">12</property>
-                <property name="margin-right">12</property>
-                <property name="margin-start">12</property>
-                <property name="margin-end">12</property>
-                <property name="margin-top">12</property>
-                <property name="margin-bottom">12</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">6</property>
-              </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child type="tab">
-              <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">_Proxy</property>
-                <property name="use-underline">True</property>
-              </object>
-              <packing>
-                <property name="position">0</property>
-                <property name="tab-fill">False</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="button1">
+        <property name="label" translatable="1">_Cancel</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="button2">
+        <property name="label" translatable="1">_Save</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <action-widgets>
--- a/pidgin/resources/Accounts/manager.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Accounts/manager.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -19,7 +19,7 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -41,99 +41,83 @@
     </columns>
   </object>
   <template class="PidginAccountManager" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Accounts</property>
+    <property name="title" translatable="1">Accounts</property>
     <property name="default-width">500</property>
     <property name="default-height">300</property>
-    <property name="type-hint">dialog</property>
     <signal name="response" handler="pidgin_account_manager_response_cb" swapped="no"/>
-    <child internal-child="vbox">
-      <object class="GtkBox">
-        <property name="can-focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
+    <child internal-child="content_area">
+      <object class="GtkScrolledWindow">
+        <property name="vexpand">1</property>
+        <property name="valign">fill</property>
+        <property name="focusable">1</property>
         <child>
-          <object class="GtkScrolledWindow">
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="shadow-type">in</property>
+          <object class="GtkTreeView">
+            <property name="focusable">1</property>
+            <property name="model">model</property>
+            <signal name="row-activated" handler="pidgin_account_manager_row_activated_cb" object="PidginAccountManager" swapped="no"/>
+            <child internal-child="selection">
+              <object class="GtkTreeSelection" id="selection">
+                <signal name="changed" handler="pidgin_account_manager_selection_changed_cb" object="PidginAccountManager" swapped="no"/>
+              </object>
+            </child>
             <child>
-              <object class="GtkTreeView">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="model">model</property>
-                <signal name="row-activated" handler="pidgin_account_manager_row_activated_cb" object="PidginAccountManager" swapped="no"/>
-                <child internal-child="selection">
-                  <object class="GtkTreeSelection" id="selection">
-                    <signal name="changed" handler="pidgin_account_manager_selection_changed_cb" object="PidginAccountManager" swapped="no"/>
+              <object class="GtkTreeViewColumn">
+                <property name="title" translatable="1">Enabled</property>
+                <child>
+                  <object class="GtkCellRendererToggle">
+                    <signal name="toggled" handler="pidgin_account_manager_enable_toggled_cb" object="PidginAccountManager" swapped="no"/>
                   </object>
+                  <attributes>
+                    <attribute name="active">0</attribute>
+                  </attributes>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkTreeViewColumn">
+                <property name="resizable">1</property>
+                <property name="title" translatable="1">Username</property>
+                <child>
+                  <object class="GtkCellRendererPixbuf"/>
+                  <attributes>
+                    <attribute name="pixbuf">1</attribute>
+                  </attributes>
                 </child>
                 <child>
-                  <object class="GtkTreeViewColumn">
-                    <property name="title" translatable="yes">Enabled</property>
-                    <child>
-                      <object class="GtkCellRendererToggle">
-                        <signal name="toggled" handler="pidgin_account_manager_enable_toggled_cb" object="PidginAccountManager" swapped="no"/>
-                      </object>
-                      <attributes>
-                        <attribute name="active">0</attribute>
-                      </attributes>
-                    </child>
-                  </object>
+                  <object class="GtkCellRendererText"/>
+                  <attributes>
+                    <attribute name="markup">2</attribute>
+                  </attributes>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkTreeViewColumn">
+                <property name="resizable">1</property>
+                <property name="title" translatable="1">Protocol</property>
+                <child>
+                  <object class="GtkCellRendererPixbuf"/>
+                  <attributes>
+                    <attribute name="icon-name">3</attribute>
+                  </attributes>
                 </child>
                 <child>
-                  <object class="GtkTreeViewColumn">
-                    <property name="resizable">True</property>
-                    <property name="title" translatable="yes">Username</property>
-                    <child>
-                      <object class="GtkCellRendererPixbuf"/>
-                      <attributes>
-                        <attribute name="pixbuf">1</attribute>
-                      </attributes>
-                    </child>
-                    <child>
-                      <object class="GtkCellRendererText"/>
-                      <attributes>
-                        <attribute name="markup">2</attribute>
-                      </attributes>
-                    </child>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkTreeViewColumn">
-                    <property name="resizable">True</property>
-                    <property name="title" translatable="yes">Protocol</property>
-                    <child>
-                      <object class="GtkCellRendererPixbuf"/>
-                      <attributes>
-                        <attribute name="icon-name">3</attribute>
-                      </attributes>
-                    </child>
-                    <child>
-                      <object class="GtkCellRendererText"/>
-                      <attributes>
-                        <attribute name="markup">4</attribute>
-                      </attributes>
-                    </child>
-                  </object>
+                  <object class="GtkCellRendererText"/>
+                  <attributes>
+                    <attribute name="markup">4</attribute>
+                  </attributes>
                 </child>
               </object>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button1">
-        <property name="label" translatable="yes">τ</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">τ</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <style>
           <class name="circular"/>
         </style>
@@ -141,53 +125,48 @@
     </child>
     <child type="action">
       <object class="GtkButton" id="praetorians">
-        <property name="label" translatable="yes">π</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="focus-on-click">False</property>
-        <property name="receives-default">True</property>
-        <property name="relief">none</property>
+        <property name="label" translatable="1">π</property>
+        <property name="focusable">1</property>
+        <property name="focus-on-click">0</property>
+        <property name="receives-default">1</property>
         <style>
+          <class name="flat"/>
           <class name="circular"/>
         </style>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button3">
-        <property name="label" translatable="yes">_Add...</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Add...</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="modify_button">
-        <property name="label" translatable="yes">_Modify...</property>
-        <property name="visible">True</property>
-        <property name="sensitive">False</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Modify...</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="remove_button">
-        <property name="label" translatable="yes">_Remove</property>
-        <property name="visible">True</property>
-        <property name="sensitive">False</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Remove</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button2">
-        <property name="label" translatable="yes">_Close</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Close</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <action-widgets>
--- a/pidgin/resources/Avatar/avatar.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Avatar/avatar.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -20,24 +20,30 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <template class="PidginAvatar" parent="GtkEventBox">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
-    <property name="events">GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property>
-    <signal name="button-press-event" handler="pidgin_avatar_button_press_handler" object="PidginAvatar" swapped="no"/>
-    <signal name="enter-notify-event" handler="pidgin_avatar_enter_notify_handler" swapped="no"/>
-    <signal name="leave-notify-event" handler="pidgin_avatar_leave_notify_handler" swapped="no"/>
+  <template class="PidginAvatar" parent="GtkBox">
+    <child>
+      <object class="GtkPicture" id="icon">
+        <property name="height-request">64</property>
+        <property name="width-request">64</property>
+        <property name="content-fit">scale-down</property>
+        <property name="keep-aspect-ratio">1</property>
+      </object>
+    </child>
     <child>
-      <object class="GtkImage" id="icon">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="icon-name">image-missing</property>
-        <property name="icon_size">3</property>
+      <object class="GtkGestureClick">
+        <property name="button">3</property>
+        <signal name="pressed" handler="pidgin_avatar_button_press_handler" object="PidginAvatar" swapped="no"/>
+      </object>
+    </child>
+    <child>
+      <object class="GtkEventControllerMotion">
+        <signal name="enter" handler="pidgin_avatar_enter_notify_handler" object="PidginAvatar" swapped="no"/>
+        <signal name="leave" handler="pidgin_avatar_leave_notify_handler" object="PidginAvatar" swapped="no"/>
       </object>
     </child>
   </template>
--- a/pidgin/resources/Avatar/menu.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Avatar/menu.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -20,7 +20,7 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
--- a/pidgin/resources/BuddyList/window.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/BuddyList/window.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -20,20 +20,17 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginContactListWindow" parent="GtkApplicationWindow">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Contact List</property>
-    <property name="role">contact_list</property>
+    <property name="title" translatable="1">Contact List</property>
+    <property name="show-menubar">1</property>
     <child>
       <object class="GtkBox" id="vbox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
       </object>
     </child>
--- a/pidgin/resources/Conversations/infopane.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Conversations/infopane.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,97 +14,52 @@
 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, see <https://www.gnu.org/licenses/>.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginInfoPane" parent="GtkBox">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
     <child>
       <object class="GtkBox" id="hbox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="spacing">6</property>
         <child>
           <object class="PidginPresenceIcon" id="presence_icon">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="fallback">chat</property>
-            <property name="icon_size">3</property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="hexpand">1</property>
+            <property name="halign">fill</property>
             <property name="orientation">vertical</property>
             <child>
               <object class="GtkLabel" id="name">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">[Place Holder]</property>
+                <property name="label" translatable="1">[Place Holder]</property>
                 <property name="xalign">0</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="1.2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="1.2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="topic">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="wrap">True</property>
+                <property name="wrap">1</property>
                 <property name="xalign">0</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
         <child>
           <object class="PidginAvatar" id="avatar">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="pack-type">end</property>
-            <property name="position">2</property>
-          </packing>
         </child>
       </object>
-      <packing>
-        <property name="expand">True</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
   </template>
 </interface>
--- a/pidgin/resources/Conversations/invite_dialog.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Conversations/invite_dialog.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,129 +14,101 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginInviteDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="border-width">6</property>
-    <property name="title" translatable="yes">Invite to conversation...</property>
-    <property name="resizable">False</property>
-    <property name="type-hint">dialog</property>
-    <child internal-child="vbox">
+    <property name="title" translatable="1">Invite to conversation...</property>
+    <property name="resizable">0</property>
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">2</property>
         <child>
-          <!-- n-columns=3 n-rows=3 -->
           <object class="GtkGrid">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="vexpand">1</property>
+            <property name="valign">fill</property>
             <property name="margin-bottom">6</property>
             <property name="row-spacing">6</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Please enter the name of the user you wish to invite, along with an optional invite message.</property>
-                <property name="wrap">True</property>
+                <property name="label" translatable="1">Please enter the name of the user you wish to invite, along with an optional invite message.</property>
+                <property name="wrap">1</property>
                 <property name="xalign">0</property>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">0</property>
+                  <property name="column-span">2</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left-attach">0</property>
-                <property name="top-attach">0</property>
-                <property name="width">2</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Contact:</property>
+              <object class="GtkLabel" id="label_contact">
+                <property name="label" translatable="1">Contact:</property>
                 <property name="xalign">0</property>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">1</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left-attach">0</property>
-                <property name="top-attach">1</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Message:</property>
+              <object class="GtkLabel" id="label_message">
+                <property name="label" translatable="1">Message:</property>
                 <property name="xalign">0</property>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">2</property>
+                </layout>
               </object>
-              <packing>
-                <property name="left-attach">0</property>
-                <property name="top-attach">2</property>
-              </packing>
             </child>
             <child>
               <object class="GtkEntry" id="contact">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="has-focus">True</property>
-                <property name="activates-default">True</property>
+                <property name="focusable">1</property>
+                <property name="activates-default">1</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">1</property>
+                </layout>
+                <accessibility>
+                  <relation name="labelled-by">label_contact</relation>
+                </accessibility>
               </object>
-              <packing>
-                <property name="left-attach">1</property>
-                <property name="top-attach">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkEntry" id="message">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="activates-default">True</property>
+                <property name="focusable">1</property>
+                <property name="activates-default">1</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">2</property>
+                </layout>
+                <accessibility>
+                  <relation name="labelled-by">label_message</relation>
+                </accessibility>
               </object>
-              <packing>
-                <property name="left-attach">1</property>
-                <property name="top-attach">2</property>
-              </packing>
-            </child>
-            <child>
-              <placeholder/>
-            </child>
-            <child>
-              <placeholder/>
-            </child>
-            <child>
-              <placeholder/>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button1">
-        <property name="label" translatable="yes">Cancel</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Cancel</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button2">
-        <property name="label" translatable="yes">Invite</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="can-default">True</property>
-        <property name="has-default">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Invite</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
       </object>
     </child>
     <action-widgets>
--- a/pidgin/resources/Conversations/window.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Conversations/window.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,13 +14,11 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
-  <requires lib="libhandy" version="1.2"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -40,48 +37,42 @@
     </columns>
   </object>
   <template class="PidginConversationWindow" parent="GtkApplicationWindow">
-    <property name="can-focus">False</property>
-    <property name="role">conversation</property>
+    <property name="show-menubar">1</property>
+    <child>
+      <object class="GtkEventControllerKey">
+        <property name="propagation-phase">capture</property>
+        <signal name="key-pressed" handler="pidgin_conversation_window_key_pressed_cb"/>
+      </object>
+    </child>
     <child>
       <object class="GtkBox" id="vbox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <child>
           <object class="GtkPaned" id="paned">
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
+            <property name="vexpand">1</property>
+            <property name="focusable">1</property>
             <property name="position">100</property>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="border-width">6</property>
+                <property name="margin-top">6</property>
+                <property name="margin-start">6</property>
+                <property name="margin-end">6</property>
+                <property name="margin-bottom">6</property>
                 <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
                 <child>
-                  <object class="PidginStatusBox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
+                  <object class="PidginStatusBox"/>
                 </child>
                 <child>
                   <object class="GtkScrolledWindow">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="shadow-type">out</property>
-                    <property name="propagate-natural-width">True</property>
-                    <child>
+                    <property name="vexpand">1</property>
+                    <property name="focusable">1</property>
+                    <property name="propagate-natural-width">1</property>
+                    <property name="child">
                       <object class="GtkTreeView" id="view">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
+                        <property name="focusable">1</property>
                         <property name="model">model</property>
-                        <property name="headers-visible">False</property>
+                        <property name="headers-visible">0</property>
                         <property name="search-column">3</property>
                         <child internal-child="selection">
                           <object class="GtkTreeSelection" id="selection">
@@ -106,66 +97,42 @@
                           </object>
                         </child>
                       </object>
-                    </child>
+                    </property>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="resize">True</property>
-                <property name="shrink">True</property>
-              </packing>
             </child>
             <child>
               <object class="GtkStack" id="stack">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <child>
-                  <object class="PidginNotificationList" id="notification_list">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="orientation">vertical</property>
-                    <child>
-                      <placeholder/>
-                    </child>
+                  <object class="GtkStackPage">
+                    <property name="name">__notifications__</property>
+                    <property name="child">
+                      <object class="GtkScrolledWindow">
+                        <child>
+                          <object class="PidginNotificationList" id="notification_list">
+                            <property name="orientation">vertical</property>
+                          </object>
+                        </child>
+                      </object>
+                    </property>
                   </object>
-                  <packing>
-                    <property name="name">__notifications__</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="HdyStatusPage">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="icon-name">mail-send-symbolic</property>
-                    <property name="title" translatable="yes">Conversations</property>
-                    <property name="description" translatable="yes">When you send a message to a friend or join a chat it will show up here!</property>
-                    <child>
-                      <placeholder/>
-                    </child>
+                  <object class="GtkStackPage">
+                    <property name="name">__conversations__</property>
+                    <property name="child">
+                      <object class="AdwStatusPage">
+                        <property name="icon-name">mail-send-symbolic</property>
+                        <property name="title" translatable="1">Conversations</property>
+                        <property name="description" translatable="1">When you send a message to a friend or join a chat it will show up here!</property>
+                      </object>
+                    </property>
                   </object>
-                  <packing>
-                    <property name="name">__conversations__</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="resize">True</property>
-                <property name="shrink">True</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="pack-type">end</property>
-            <property name="position">0</property>
-          </packing>
         </child>
       </object>
     </child>
--- a/pidgin/resources/Debug/debug.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Debug/debug.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,9 +14,7 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <!--

@@ -46,8 +43,8 @@
 
     <child type="tag">
       <object class="GtkTextTag" id="tags.filtered_visible">
-        <property name="invisible">False</property>
-        <property name="invisible-set">True</property>
+        <property name="invisible">0</property>
+        <property name="invisible-set">1</property>
       </object>
     </child>
 
@@ -64,7 +61,7 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -72,32 +69,32 @@
   <object class="GtkTextTagTable" id="message-format">
     <child type="tag">
       <object class="GtkTextTag" id="tags.level[0]">
-        <property name="foreground-rgba">rgb(0,0,0)</property>
+        <property name="foreground">rgb(0,0,0)</property>
       </object>
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.level[1]">
-        <property name="foreground-rgba">rgb(102,102,102)</property>
+        <property name="foreground">rgb(102,102,102)</property>
       </object>
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.level[2]">
-        <property name="foreground-rgba">rgb(0,0,0)</property>
+        <property name="foreground">rgb(0,0,0)</property>
       </object>
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.level[3]">
-        <property name="foreground-rgba">rgb(102,0,0)</property>
+        <property name="foreground">rgb(102,0,0)</property>
       </object>
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.level[4]">
-        <property name="foreground-rgba">rgb(255,0,0)</property>
+        <property name="foreground">rgb(255,0,0)</property>
       </object>
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.level[5]">
-        <property name="foreground-rgba">rgb(255,0,0)</property>
+        <property name="foreground">rgb(255,0,0)</property>
         <property name="weight">700</property>
       </object>
     </child>
@@ -108,24 +105,24 @@
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.filtered_invisible">
-        <property name="invisible">True</property>
+        <property name="invisible">1</property>
       </object>
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.filtered_visible">
-        <property name="invisible">False</property>
-        <property name="invisible-set">True</property>
+        <property name="invisible">0</property>
+        <property name="invisible-set">1</property>
       </object>
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.match">
-        <property name="background-rgba">rgb(255,175,175)</property>
+        <property name="background">rgb(255,175,175)</property>
         <property name="weight">700</property>
       </object>
     </child>
     <child type="tag">
       <object class="GtkTextTag" id="tags.paused">
-        <property name="invisible">True</property>
+        <property name="invisible">1</property>
       </object>
     </child>
   </object>
@@ -133,252 +130,145 @@
     <property name="tag-table">message-format</property>
   </object>
   <template class="PidginDebugWindow" parent="GtkWindow">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Debug Window</property>
-    <child>
+    <property name="title" translatable="1">Debug Window</property>
+    <property name="child">
       <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <child>
-          <object class="GtkToolbar" id="toolbar">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="icon_size">2</property>
+          <object class="GtkBox" id="toolbar">
+            <style>
+              <class name="toolbar"/>
+            </style>
             <child>
-              <object class="GtkToolButton" id="save">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="tooltip-text" translatable="yes">Save</property>
-                <property name="is-important">True</property>
-                <property name="label" translatable="yes">_Save...</property>
-                <property name="use-underline">True</property>
+              <object class="GtkButton" id="save">
+                <property name="tooltip-text" translatable="1">Save</property>
+                <property name="label" translatable="1">_Save...</property>
+                <property name="use-underline">1</property>
                 <property name="icon-name">document-save</property>
                 <signal name="clicked" handler="save_cb" object="PidginDebugWindow" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkToolButton" id="clear">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="tooltip-text" translatable="yes">Clear</property>
-                <property name="is-important">True</property>
-                <property name="label" translatable="yes">_Clear</property>
-                <property name="use-underline">True</property>
+              <object class="GtkButton" id="clear">
+                <property name="tooltip-text" translatable="1">Clear</property>
+                <property name="label" translatable="1">_Clear</property>
+                <property name="use-underline">1</property>
                 <property name="icon-name">edit-clear</property>
                 <signal name="clicked" handler="clear_cb" object="PidginDebugWindow" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
+            </child>
+            <child>
+              <object class="GtkSeparator">
+                <property name="orientation">vertical</property>
+              </object>
             </child>
             <child>
-              <object class="GtkSeparatorToolItem">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+              <object class="GtkToggleButton" id="pause">
+                <property name="tooltip-text" translatable="1">Pause</property>
+                <property name="label" translatable="1">_Pause</property>
+                <property name="use-underline">1</property>
+                <property name="icon-name">media-playback-pause</property>
+                <signal name="toggled" handler="pause_cb" object="PidginDebugWindow" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToggleToolButton" id="pause">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="tooltip-text" translatable="yes">Pause</property>
-                <property name="is-important">True</property>
-                <property name="label" translatable="yes">_Pause</property>
-                <property name="use-underline">True</property>
-                <property name="icon-name">media-playback-pause</property>
-                <signal name="clicked" handler="pause_cb" object="PidginDebugWindow" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkSeparatorToolItem">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+              <object class="GtkSeparator">
+                <property name="orientation">vertical</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkToggleToolButton" id="filter">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="tooltip-text" translatable="yes">Filter</property>
-                <property name="is-important">True</property>
-                <property name="label" translatable="yes">_Filter</property>
-                <property name="use-underline">True</property>
+              <object class="GtkToggleButton" id="filter">
+                <property name="tooltip-text" translatable="1">Filter</property>
+                <property name="label" translatable="1">_Filter</property>
+                <property name="use-underline">1</property>
                 <property name="icon-name">edit-find</property>
-                <signal name="clicked" handler="regex_filter_toggled_cb" object="PidginDebugWindow" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolItem">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+                <signal name="toggled" handler="regex_filter_toggled_cb" object="PidginDebugWindow" swapped="no"/>
                 <child>
-                  <object class="GtkSearchEntry" id="expression">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="primary-icon-name">edit-find-symbolic</property>
-                    <property name="primary-icon-activatable">True</property>
-                    <property name="primary-icon-sensitive">True</property>
-                    <property name="primary-icon-tooltip-text" translatable="yes">Click for more options.</property>
-                    <signal name="icon-press" handler="regex_popup_cb" object="PidginDebugWindow" swapped="no"/>
-                    <signal name="key-release-event" handler="regex_key_release_cb" object="PidginDebugWindow" swapped="no"/>
-                    <signal name="search-changed" handler="regex_changed_cb" object="PidginDebugWindow" swapped="no"/>
+                  <object class="GtkGestureClick">
+                    <property name="button">3</property>
+                    <signal name="pressed" handler="regex_popup_cb" object="PidginDebugWindow" swapped="no"/>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkSeparatorToolItem">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolItem">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+              <object class="GtkSearchEntry" id="expression">
                 <child>
-                  <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Level </property>
-                    <accessibility>
-                      <relation type="label-for" target="filterlevel"/>
-                    </accessibility>
+                  <object class="GtkEventControllerKey">
+                    <signal name="key-released" handler="regex_key_released_cb" object="PidginDebugWindow" swapped="no"/>
                   </object>
                 </child>
+                <property name="focusable">1</property>
+                <signal name="search-changed" handler="regex_changed_cb" object="PidginDebugWindow" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
+            </child>
+            <child>
+              <object class="GtkSeparator">
+                <property name="orientation">vertical</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="filterlevel-label">
+                <property name="label" translatable="1">Level </property>
+              </object>
             </child>
             <child>
-              <object class="GtkToolItem">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <child>
-                  <object class="GtkComboBoxText" id="filterlevel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="tooltip-text" translatable="yes">Select the debug filter level.</property>
-                    <property name="active">0</property>
-                    <items>
-                      <item translatable="yes">All</item>
-                      <item translatable="yes">Misc</item>
-                      <item translatable="yes">Info</item>
-                      <item translatable="yes">Warning</item>
-                      <item translatable="yes">Error</item>
-                      <item translatable="yes">Fatal Error</item>
-                    </items>
-                    <signal name="changed" handler="filter_level_changed_cb" object="PidginDebugWindow" swapped="no"/>
-                  </object>
-                </child>
+              <object class="GtkComboBoxText" id="filterlevel">
+                <property name="tooltip-text" translatable="1">Select the debug filter level.</property>
+                <property name="active">0</property>
+                <items>
+                  <item translatable="yes">All</item>
+                  <item translatable="yes">Misc</item>
+                  <item translatable="yes">Info</item>
+                  <item translatable="yes">Warning</item>
+                  <item translatable="yes">Error</item>
+                  <item translatable="yes">Fatal Error</item>
+                </items>
+                <signal name="changed" handler="filter_level_changed_cb" object="PidginDebugWindow" swapped="no"/>
+                <accessibility>
+                  <relation name="labelled-by">filterlevel-label</relation>
+                </accessibility>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkScrolledWindow">
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="shadow-type">in</property>
-            <child>
+            <property name="vexpand">1</property>
+            <property name="focusable">1</property>
+            <property name="child">
               <object class="GtkTextView" id="textview">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="editable">False</property>
+                <property name="focusable">1</property>
+                <property name="editable">0</property>
                 <property name="wrap-mode">word</property>
                 <property name="buffer">buffer</property>
               </object>
-            </child>
+            </property>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
-    </child>
+    </property>
   </template>
   <object class="GtkPopover" id="popover">
-    <property name="can-focus">False</property>
-    <property name="relative-to">expression</property>
-    <child>
+    <property name="position">bottom</property>
+    <property name="child">
       <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <child>
           <object class="GtkCheckButton" id="popover_invert">
-            <property name="label" translatable="yes">Invert</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
+            <property name="label" translatable="1">Invert</property>
+            <property name="focusable">1</property>
             <signal name="toggled" handler="regex_menu_cb" object="PidginDebugWindow" swapped="no"/>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkCheckButton" id="popover_highlight">
-            <property name="label" translatable="yes">Highlight matches</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
+            <property name="label" translatable="1">Highlight matches</property>
+            <property name="focusable">1</property>
             <signal name="toggled" handler="regex_menu_cb" object="PidginDebugWindow" swapped="no"/>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
-    </child>
+    </property>
   </object>
 </interface>
--- a/pidgin/resources/Debug/filter.css	Tue Aug 23 01:09:33 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-.bad-filter {
-	color: @error_fg_color;
-	text-shadow: 0 1px @error_text_shadow;
-	background-image: none;
-	background-color: @error_bg_color;
-}
-
-.good-filter {
-	color: @question_fg_color;
-	text-shadow: 0 1px @question_text_shadow;
-	background-image: none;
-	background-color: @success_color;
-}
--- a/pidgin/resources/Debug/plugininfo.ui	Tue Aug 23 01:09:33 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
-Pidgin - Internet Messenger
-Copyright (C) Pidgin Developers <devel@pidgin.im>
-
-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  02110-1301, USA.
-
--->
-<interface>
-  <requires lib="Talkatu" version="0.0"/>
-  <requires lib="gtk+" version="3.22"/>
-  <!-- interface-local-resource-path ../ -->
-  <!-- interface-license-type gplv2 -->
-  <!-- interface-name Pidgin -->
-  <!-- interface-description Internet Messenger -->
-  <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <object class="TalkatuHtmlBuffer" id="buffer"/>
-  <template class="PidginDebugPluginInfo" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Pidgin Plugin Information</property>
-    <property name="role">plugins_info</property>
-    <property name="default-width">475</property>
-    <property name="default-height">450</property>
-    <property name="type-hint">dialog</property>
-    <child internal-child="vbox">
-      <object class="GtkBox">
-        <property name="can-focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child>
-          <object class="GtkImage" id="logo">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="resource">/im/pidgin/Pidgin3/logo.png</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkScrolledWindow">
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="shadow-type">in</property>
-            <child>
-              <object class="TalkatuView" id="view">
-                <property name="can-focus">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="editable">False</property>
-                <property name="buffer">buffer</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-    <child type="action">
-      <object class="GtkButton">
-        <property name="label" translatable="yes">Close</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <signal name="clicked" handler="gtk_widget_destroy" object="PidginDebugPluginInfo" swapped="yes"/>
-      </object>
-    </child>
-  </template>
-</interface>
--- a/pidgin/resources/Dialogs/addbuddy.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Dialogs/addbuddy.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -15,12 +15,11 @@
 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  02110-1301, USA.
+along with this program; if not, see <https://www.gnu.org/licenses/>.
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -34,302 +33,150 @@
     <property name="child-model">account_filter_connected</property>
   </object>
   <template class="PidginAddBuddyDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="border-width">12</property>
-    <property name="title" translatable="yes">Add Buddy</property>
-    <property name="resizable">False</property>
-    <property name="type-hint">dialog</property>
+    <property name="title" translatable="1">Add Buddy</property>
+    <property name="resizable">0</property>
     <signal name="response" handler="pidgin_add_buddy_dialog_response_cb" swapped="no"/>
-    <child internal-child="vbox">
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">12</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox">
-            <property name="can-focus">False</property>
-            <property name="layout-style">end</property>
-            <child>
-              <object class="GtkButton" id="button1">
-                <property name="label" translatable="yes">_Cancel</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button2">
-                <property name="label" translatable="yes">_Add</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="can-default">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="label" translatable="1">Add a buddy.</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="spacer"/>
         </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">12</property>
+            <property name="spacing">5</property>
+            <child>
+              <object class="GtkLabel" id="label1">
+                <property name="label" translatable="1">A_ccount:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">account</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+              </object>
+            </child>
             <child>
-              <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Add a buddy.</property>
+              <object class="PidginAccountChooser" id="account">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="model">filter</property>
+                <signal name="changed" handler="pidgin_add_buddy_dialog_account_changed_cb" object="PidginAddBuddyDialog" swapped="no"/>
+                <accessibility>
+                  <relation name="labelled-by">label1</relation>
+                </accessibility>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="spacing">5</property>
+            <child>
+              <object class="GtkLabel" id="label2">
+                <property name="label" translatable="1">Buddy&apos;s _username:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">username</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="spacer">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label1">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">A_ccount:</property>
-                    <property name="use-underline">True</property>
-                    <property name="mnemonic-widget">account</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="PidginAccountChooser" id="account">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="model">filter</property>
-                    <signal name="changed" handler="pidgin_add_buddy_dialog_account_changed_cb" object="PidginAddBuddyDialog" swapped="no"/>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+              <object class="GtkEntry" id="username">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="focusable">1</property>
+                <property name="activates-default">1</property>
+                <signal name="changed" handler="pidgin_add_buddy_dialog_username_changed_cb" object="PidginAddBuddyDialog" swapped="no"/>
+                <accessibility>
+                  <relation name="labelled-by">label2</relation>
+                </accessibility>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="spacing">5</property>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label2">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Buddy's _username:</property>
-                    <property name="use-underline">True</property>
-                    <property name="mnemonic-widget">username</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="username">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="has-focus">True</property>
-                    <property name="can-default">True</property>
-                    <property name="activates-default">True</property>
-                    <signal name="changed" handler="pidgin_add_buddy_dialog_username_changed_cb" object="PidginAddBuddyDialog" swapped="no"/>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+              <object class="GtkLabel" id="label3">
+                <property name="label" translatable="1">(Optional) A_lias:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">alias</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label3">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">(Optional) A_lias:</property>
-                    <property name="use-underline">True</property>
-                    <property name="mnemonic-widget">alias</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="alias">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+              <object class="GtkEntry" id="alias">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="focusable">1</property>
+                <accessibility>
+                  <relation name="labelled-by">label3</relation>
+                </accessibility>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">4</property>
-              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="spacing">5</property>
+            <child>
+              <object class="GtkLabel" id="label4">
+                <property name="label" translatable="1">(Optional) _Invite message:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">message</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+              </object>
             </child>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label4">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">(Optional) _Invite message:</property>
-                    <property name="use-underline">True</property>
-                    <property name="mnemonic-widget">message</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="message">
-                    <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can-focus">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+              <object class="GtkEntry" id="message">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="sensitive">0</property>
+                <property name="focusable">1</property>
+                <accessibility>
+                  <relation name="labelled-by">label4</relation>
+                </accessibility>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">5</property>
-              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="spacing">5</property>
+            <child>
+              <object class="GtkLabel" id="label5">
+                <property name="label" translatable="1">Add buddy to _group:</property>
+                <property name="use-underline">1</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+              </object>
             </child>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label5">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Add buddy to _group:</property>
-                    <property name="use-underline">True</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
+              <object class="GtkComboBoxText" id="group">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="has-entry">1</property>
+                <property name="child">
+                  <object class="GtkEntry">
+                    <property name="focusable">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBoxText" id="group">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="has-entry">True</property>
-                    <child internal-child="entry">
-                      <object class="GtkEntry">
-                        <property name="can-focus">True</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+                </property>
+                <accessibility>
+                  <relation name="labelled-by">label5</relation>
+                </accessibility>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">6</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
@@ -337,6 +184,23 @@
       <action-widget response="-6">button1</action-widget>
       <action-widget response="-5">button2</action-widget>
     </action-widgets>
+    <child type="action">
+      <object class="GtkButton" id="button1">
+        <property name="label" translatable="1">_Cancel</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="button2">
+        <property name="label" translatable="1">_Add</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
   </template>
   <object class="GtkSizeGroup">
     <widgets>
--- a/pidgin/resources/Dialogs/addchat.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Dialogs/addchat.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -15,12 +15,11 @@
 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  02110-1301, USA.
+along with this program; if not, see <https://www.gnu.org/licenses/>.
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -34,256 +33,146 @@
     <property name="child-model">account_filter_connected</property>
   </object>
   <template class="PidginAddChatDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="border-width">12</property>
-    <property name="title" translatable="yes">Add Chat</property>
-    <property name="resizable">False</property>
-    <property name="type-hint">dialog</property>
+    <property name="title" translatable="1">Add Chat</property>
+    <property name="resizable">0</property>
     <signal name="response" handler="pidgin_add_chat_dialog_response_cb" swapped="no"/>
-    <child internal-child="vbox">
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">12</property>
         <child>
+          <object class="GtkLabel">
+            <property name="label" translatable="1">Please enter an alias, and the appropriate information about the chat you would like to add to your buddy list.</property>
+            <property name="wrap">1</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel" id="spacer"/>
+        </child>
+        <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">12</property>
+            <property name="spacing">5</property>
             <child>
-              <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Please enter an alias, and the appropriate information about the chat you would like to add to your buddy list.</property>
-                <property name="wrap">True</property>
+              <object class="GtkLabel" id="label1">
+                <property name="label" translatable="1">A_ccount:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">account</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="spacer">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+                <property name="halign">fill</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label1">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">A_ccount:</property>
-                    <property name="use-underline">True</property>
-                    <property name="mnemonic-widget">account</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="PidginAccountChooser" id="account">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="model">filter</property>
-                    <signal name="changed" handler="pidgin_add_chat_dialog_account_changed_cb" object="PidginAddChatDialog" swapped="no"/>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkBox" id="dynamic_box">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">6</property>
-                <child>
-                  <placeholder/>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label4">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">A_lias:</property>
-                    <property name="use-underline">True</property>
-                    <property name="mnemonic-widget">alias</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="alias">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+              <object class="PidginAccountChooser" id="account">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="model">filter</property>
+                <signal name="changed" handler="pidgin_add_chat_dialog_account_changed_cb" object="PidginAddChatDialog" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">4</property>
-              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox" id="dynamic_box">
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <property name="hexpand">1</property>
+            <property name="halign">fill</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="spacing">5</property>
+            <child>
+              <object class="GtkLabel" id="label4">
+                <property name="label" translatable="1">A_lias:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">alias</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="halign">fill</property>
+              </object>
             </child>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label5">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_Group:</property>
-                    <property name="use-underline">True</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBoxText" id="group">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="has-entry">True</property>
-                    <child internal-child="entry">
-                      <object class="GtkEntry">
-                        <property name="can-focus">True</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+              <object class="GtkEntry" id="alias">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="focusable">1</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">5</property>
-              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="spacing">5</property>
+            <child>
+              <object class="GtkLabel" id="label5">
+                <property name="label" translatable="1">_Group:</property>
+                <property name="use-underline">1</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="halign">fill</property>
+              </object>
             </child>
             <child>
-              <object class="GtkCheckButton" id="autojoin">
-                <property name="label" translatable="yes">Automatically _join when account connects</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="halign">start</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+              <object class="GtkComboBoxText" id="group">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="has-entry">1</property>
+                <property name="child">
+                  <object class="GtkEntry">
+                    <property name="focusable">1</property>
+                  </object>
+                </property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">6</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkCheckButton" id="persistent">
-                <property name="label" translatable="yes">_Remain in chat after window is closed</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="halign">start</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">7</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="autojoin">
+            <property name="label" translatable="1">Automatically _join when account connects</property>
+            <property name="focusable">1</property>
+            <property name="halign">start</property>
+            <property name="use-underline">1</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="persistent">
+            <property name="label" translatable="1">_Remain in chat after window is closed</property>
+            <property name="focusable">1</property>
+            <property name="halign">start</property>
+            <property name="use-underline">1</property>
+          </object>
         </child>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button3">
-        <property name="label" translatable="yes">Room List</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Room List</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button1">
-        <property name="label" translatable="yes">_Cancel</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Cancel</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button2">
-        <property name="label" translatable="yes">_Add</property>
-        <property name="visible">True</property>
-        <property name="sensitive">False</property>
-        <property name="can-focus">True</property>
-        <property name="can-default">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Add</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <action-widgets>
--- a/pidgin/resources/Keypad/keypad.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Keypad/keypad.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -20,24 +20,19 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <!-- n-columns=3 n-rows=4 -->
   <template class="PidginKeypad" parent="GtkGrid">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
-    <property name="row-homogeneous">True</property>
-    <property name="column-homogeneous">True</property>
+    <property name="row-homogeneous">1</property>
+    <property name="column-homogeneous">1</property>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -46,55 +41,35 @@
         <property name="action-target">49</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">1</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="secondary_labels[1]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
+              <object class="GtkLabel" id="secondary_labels[1]"/>
             </child>
           </object>
         </child>
         <style>
           <class name="image-button"/>
         </style>
+        <layout>
+          <property name="column">0</property>
+          <property name="row">0</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">0</property>
-        <property name="top-attach">0</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -103,60 +78,41 @@
         <property name="action-target">50</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">2</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[2]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <!-- Translators: These are the letters on the '2' key of a numeric
                   keypad; translate according to the tables in §7 of ETSI ES 202 130:
                   http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
                 -->
-                <property name="label" translatable="yes">ABC</property>
+                <property name="label" translatable="1">ABC</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">1</property>
+          <property name="row">0</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">1</property>
-        <property name="top-attach">0</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -165,60 +121,41 @@
         <property name="action-target">51</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">3</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[3]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <!-- Translators: These are the letters on the '3' key of a numeric
                   keypad; translate according to the tables in §7 of ETSI ES 202 130:
                   http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
                 -->
-                <property name="label" translatable="yes">DEF</property>
+                <property name="label" translatable="1">DEF</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">2</property>
+          <property name="row">0</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">2</property>
-        <property name="top-attach">0</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -227,60 +164,41 @@
         <property name="action-target">52</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">4</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[4]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <!-- Translators: These are the letters on the '4' key of a numeric
                   keypad; translate according to the tables in §7 of ETSI ES 202 130:
                   http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
                 -->
-                <property name="label" translatable="yes">GHI</property>
+                <property name="label" translatable="1">GHI</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">0</property>
+          <property name="row">1</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">0</property>
-        <property name="top-attach">1</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -289,60 +207,41 @@
         <property name="action-target">53</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">5</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[5]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <!-- Translators: These are the letters on the '5' key of a numeric
                   keypad; translate according to the tables in §7 of ETSI ES 202 130:
                   http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
                 -->
-                <property name="label" translatable="yes">JKL</property>
+                <property name="label" translatable="1">JKL</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">1</property>
+          <property name="row">1</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">1</property>
-        <property name="top-attach">1</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -351,60 +250,41 @@
         <property name="action-target">54</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">6</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[6]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <!-- Translators: These are the letters on the '6' key of a numeric
                   keypad; translate according to the tables in §7 of ETSI ES 202 130:
                   http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
                 -->
-                <property name="label" translatable="yes">MNO</property>
+                <property name="label" translatable="1">MNO</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">2</property>
+          <property name="row">1</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">2</property>
-        <property name="top-attach">1</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -413,60 +293,41 @@
         <property name="action-target">55</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">7</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[7]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <!-- Translators: These are the letters on the '7' key of a numeric
                   keypad; translate according to the tables in §7 of ETSI ES 202 130:
                   http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
                 -->
-                <property name="label" translatable="yes">PQRS</property>
+                <property name="label" translatable="1">PQRS</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">0</property>
+          <property name="row">2</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">0</property>
-        <property name="top-attach">2</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -475,60 +336,41 @@
         <property name="action-target">56</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">8</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[8]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <!-- Translators: These are the letters on the '8' key of a numeric
                   keypad; translate according to the tables in §7 of ETSI ES 202 130:
                   http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
                 -->
-                <property name="label" translatable="yes">TUV</property>
+                <property name="label" translatable="1">TUV</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">1</property>
+          <property name="row">2</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">1</property>
-        <property name="top-attach">2</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -537,60 +379,41 @@
         <property name="action-target">57</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">9</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[9]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <!-- Translators: These are the letters on the '9' key of a numeric
                   keypad; translate according to the tables in §7 of ETSI ES 202 130:
                   http://webapp.etsi.org/WorkProgram/Report_WorkItem.asp?WKI_ID=11730
                 -->
-                <property name="label" translatable="yes">WXYZ</property>
+                <property name="label" translatable="1">WXYZ</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">2</property>
+          <property name="row">2</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">2</property>
-        <property name="top-attach">2</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -599,55 +422,36 @@
         <property name="action-target">42</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">*</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="asterisk">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">0</property>
+          <property name="row">3</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">0</property>
-        <property name="top-attach">3</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -656,55 +460,36 @@
         <property name="action-target">48</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">0</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="secondary_labels[0]">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">1</property>
+          <property name="row">3</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">1</property>
-        <property name="top-attach">3</property>
-      </packing>
     </child>
     <child>
       <object class="GtkButton">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="margin-left">2</property>
-        <property name="margin-right">2</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="margin-start">2</property>
         <property name="margin-end">2</property>
         <property name="margin-top">2</property>
@@ -713,47 +498,31 @@
         <property name="action-target">35</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
-            <property name="homogeneous">True</property>
+            <property name="homogeneous">1</property>
             <child>
               <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="label">#</property>
                 <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="2"/>
+                  <attribute name="weight" value="bold"></attribute>
+                  <attribute name="scale" value="2"></attribute>
                 </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="octothorpe">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <style>
                   <class name="dim-label"/>
                 </style>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
+        <layout>
+          <property name="column">2</property>
+          <property name="row">3</property>
+        </layout>
       </object>
-      <packing>
-        <property name="left-attach">2</property>
-        <property name="top-attach">3</property>
-      </packing>
     </child>
   </template>
 </interface>
--- a/pidgin/resources/Log/log-viewer.ui	Tue Aug 23 01:09:33 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
-Pidgin - Internet Messenger
-Copyright (C) Pidgin Developers <devel@pidgin.im>
-
-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  02110-1301, USA.
-
--->
-<interface>
-  <requires lib="Talkatu" version="0.0"/>
-  <requires lib="gtk+" version="3.22"/>
-  <!-- interface-license-type gplv2 -->
-  <!-- interface-name Pidgin -->
-  <!-- interface-description Internet Messenger -->
-  <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <object class="TalkatuHtmlBuffer" id="log_buffer"/>
-  <object class="GtkTreeStore" id="treestore">
-    <columns>
-      <!-- column-name markup -->
-      <column type="gchararray"/>
-      <!-- column-name log -->
-      <column type="gpointer"/>
-    </columns>
-  </object>
-  <template class="PidginLogViewer" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="role">log_viewer</property>
-    <property name="type-hint">dialog</property>
-    <child internal-child="vbox">
-      <object class="GtkBox">
-        <property name="can-focus">False</property>
-        <property name="margin-top">6</property>
-        <property name="margin-bottom">6</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child>
-          <object class="GtkBox" id="title_box">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="spacing">6</property>
-            <child>
-              <placeholder/>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Conversations with buddy</property>
-                <property name="track-visited-links">False</property>
-                <property name="xalign">0</property>
-                <property name="yalign">0</property>
-                <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="1.2"/>
-                </attributes>
-                <accessibility>
-                  <relation type="label-for" target="PidginLogViewer"/>
-                </accessibility>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkPaned">
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="border-width">0</property>
-            <child>
-              <object class="GtkScrolledWindow">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="hscrollbar-policy">never</property>
-                <property name="vscrollbar-policy">always</property>
-                <property name="shadow-type">in</property>
-                <child>
-                  <object class="GtkTreeView" id="treeview">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="model">treestore</property>
-                    <property name="headers-visible">False</property>
-                    <signal name="button-press-event" handler="log_button_press_cb" object="PidginLogViewer" swapped="no"/>
-                    <signal name="popup-menu" handler="log_popup_menu_cb" object="PidginLogViewer" swapped="no"/>
-                    <signal name="row-activated" handler="log_row_activated_cb" object="PidginLogViewer" swapped="no"/>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection">
-                        <signal name="changed" handler="log_select_cb" object="PidginLogViewer" swapped="no"/>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkTreeViewColumn" id="time">
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="markup">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="resize">False</property>
-                <property name="shrink">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <object class="GtkSearchBar">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <child>
-                      <object class="GtkSearchEntry" id="entry">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="primary-icon-name">edit-find-symbolic</property>
-                        <property name="primary-icon-activatable">False</property>
-                        <property name="primary-icon-sensitive">False</property>
-                        <signal name="search-changed" handler="entry_search_changed_cb" object="PidginLogViewer" swapped="no"/>
-                        <signal name="stop-search" handler="entry_stop_search_cb" object="PidginLogViewer" swapped="no"/>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow">
-                    <property name="width-request">320</property>
-                    <property name="height-request">200</property>
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="shadow-type">in</property>
-                    <child>
-                      <object class="TalkatuView" id="log_view">
-                        <property name="name">pidgin_log_view</property>
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="hexpand-set">True</property>
-                        <property name="vexpand-set">True</property>
-                        <property name="editable">False</property>
-                        <property name="wrap-mode">word</property>
-                        <property name="buffer">log_buffer</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="resize">True</property>
-                <property name="shrink">True</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="size_label">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="label" translatable="yes">&lt;b&gt;Total log size:&lt;/b&gt; 123 KiB</property>
-            <property name="use-markup">True</property>
-            <property name="xalign">0</property>
-            <property name="yalign">0</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-    <child type="action">
-      <object class="GtkButton" id="browse_button">
-        <property name="label" translatable="yes">_Browse logs folder</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
-      </object>
-    </child>
-    <child type="action">
-      <object class="GtkButton" id="close_button">
-        <property name="label" translatable="yes">_Close</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="-11">browse_button</action-widget>
-      <action-widget response="-7">close_button</action-widget>
-    </action-widgets>
-    <accessibility>
-      <relation type="labelled-by" target="label"/>
-    </accessibility>
-  </template>
-</interface>
--- a/pidgin/resources/Media/window.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Media/window.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,85 +14,53 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginMedia" parent="GtkApplicationWindow">
-    <property name="can-focus">False</property>
-    <signal name="delete-event" handler="pidgin_media_delete_event_cb" swapped="no"/>
+    <signal name="close-request" handler="pidgin_media_close_request_cb" swapped="no"/>
     <child>
       <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <child>
-          <object class="GtkToolbar">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="toolbar-style">both</property>
+          <object class="GtkBox">
+            <property name="css-classes">toolbar</property>
+            <property name="can-focus">0</property>
             <child>
-              <object class="GtkToolButton">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="tooltip-text" translatable="yes">Hangup</property>
+              <object class="GtkButton">
+                <property name="can-focus">0</property>
+                <property name="tooltip-text" translatable="1">Hangup</property>
                 <property name="action-name">win.Hangup</property>
-                <property name="label" translatable="yes">Hangup</property>
-                <property name="use-underline">True</property>
+                <property name="label" translatable="1">Hangup</property>
+                <property name="use-underline">1</property>
                 <property name="icon-name">media-playback-stop</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkBox" id="display">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="vexpand">1</property>
+            <property name="valign">fill</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <placeholder/>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkStatusbar" id="statusbar">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="margin-left">10</property>
-            <property name="margin-right">10</property>
             <property name="margin-start">10</property>
             <property name="margin-end">10</property>
             <property name="margin-top">6</property>
             <property name="margin-bottom">6</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">2</property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
         </child>
       </object>
     </child>
--- a/pidgin/resources/Notifications/addcontact.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Notifications/addcontact.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -19,24 +19,22 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
-  <requires lib="libhandy" version="0.0"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <template class="PidginNotificationAddContact" parent="HdyActionRow">
-    <property name="visible">True</property>
-    <property name="can-focus">True</property>
-    <property name="activatable">False</property>
+  <template class="PidginNotificationAddContact" parent="AdwActionRow">
+    <property name="focusable">1</property>
+    <property name="activatable">0</property>
     <property name="title-lines">3</property>
     <property name="subtitle-lines">3</property>
     <child>
       <object class="GtkButton" id="add">
-        <property name="label" translatable="yes">Add</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Add</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <signal name="clicked" handler="pidgin_notification_add_contact_add_cb" object="PidginNotificationAddContact" swapped="no"/>
@@ -47,10 +45,9 @@
     </child>
     <child>
       <object class="GtkButton" id="message">
-        <property name="label" translatable="yes">Message</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Message</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <signal name="clicked" handler="pidgin_notification_add_contact_message_cb" object="PidginNotificationAddContact" swapped="no"/>
@@ -58,17 +55,16 @@
     </child>
     <child>
       <object class="GtkButton" id="remove">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
-        <property name="relief">none</property>
         <signal name="clicked" handler="pidgin_notification_add_contact_remove_cb" object="PidginNotificationAddContact" swapped="no"/>
+        <style>
+          <class name="flat"/>
+        </style>
         <child>
           <object class="GtkImage">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="icon-name">edit-delete-symbolic</property>
           </object>
         </child>
--- a/pidgin/resources/Notifications/authorizationrequest.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Notifications/authorizationrequest.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -19,24 +19,22 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
-  <requires lib="libhandy" version="0.0"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <template class="PidginNotificationAuthorizationRequest" parent="HdyActionRow">
-    <property name="visible">True</property>
-    <property name="can-focus">True</property>
-    <property name="activatable">False</property>
+  <template class="PidginNotificationAuthorizationRequest" parent="AdwActionRow">
+    <property name="focusable">1</property>
+    <property name="activatable">0</property>
     <property name="title-lines">3</property>
     <property name="subtitle-lines">3</property>
     <child>
       <object class="GtkButton" id="accept">
-        <property name="label" translatable="yes">Accept</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Accept</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <signal name="clicked" handler="pidgin_notification_authorization_request_accept_cb" object="PidginNotificationAuthorizationRequest" swapped="no"/>
@@ -47,10 +45,9 @@
     </child>
     <child>
       <object class="GtkButton" id="deny">
-        <property name="label" translatable="yes">Deny</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Deny</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <signal name="clicked" handler="pidgin_notification_authorization_request_deny_cb" object="PidginNotificationAuthorizationRequest" swapped="no"/>
@@ -61,10 +58,9 @@
     </child>
     <child>
       <object class="GtkButton" id="message">
-        <property name="label" translatable="yes">Message</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Message</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <signal name="clicked" handler="pidgin_notification_authorization_request_message_cb" object="PidginNotificationAuthorizationRequest" swapped="no"/>
@@ -72,17 +68,16 @@
     </child>
     <child>
       <object class="GtkButton" id="remove">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
-        <property name="relief">none</property>
         <signal name="clicked" handler="pidgin_notification_authorization_request_remove_cb" object="PidginNotificationAuthorizationRequest" swapped="no"/>
+        <style>
+          <class name="flat"/>
+        </style>
         <child>
           <object class="GtkImage">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="icon-name">edit-delete-symbolic</property>
           </object>
         </child>
--- a/pidgin/resources/Notifications/connectionerror.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Notifications/connectionerror.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,27 +14,24 @@
 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, see <https://www.gnu.org/licenses/>.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
-  <requires lib="libhandy" version="0.0"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <template class="PidginNotificationConnectionError" parent="HdyActionRow">
-    <property name="visible">True</property>
-    <property name="can-focus">True</property>
-    <property name="activatable">False</property>
+  <template class="PidginNotificationConnectionError" parent="AdwActionRow">
+    <property name="focusable">1</property>
+    <property name="activatable">0</property>
     <property name="subtitle-lines">3</property>
     <child>
       <object class="GtkButton" id="reconnect">
-        <property name="label" translatable="yes">Reconnect</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Reconnect</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <property name="action-name">app.connect-account</property>
@@ -43,10 +39,9 @@
     </child>
     <child>
       <object class="GtkButton" id="reenable">
-        <property name="label" translatable="yes">Re-enable</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Re-enable</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <property name="action-name">app.enable-account</property>
@@ -54,10 +49,9 @@
     </child>
     <child>
       <object class="GtkButton" id="modify">
-        <property name="label" translatable="yes">Modify Account</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="label" translatable="1">Modify Account</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
         <property name="action-name">app.edit-account</property>
@@ -65,17 +59,16 @@
     </child>
     <child>
       <object class="GtkButton" id="remove">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
-        <property name="relief">none</property>
         <signal name="clicked" handler="pidgin_notification_connection_error_remove_cb" object="PidginNotificationConnectionError" swapped="no"/>
+        <style>
+          <class name="flat"/>
+        </style>
         <child>
           <object class="GtkImage">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="icon-name">edit-delete-symbolic</property>
           </object>
         </child>
--- a/pidgin/resources/Notifications/list.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Notifications/list.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,43 +14,34 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
-  <requires lib="libhandy" version="1.2"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginNotificationList" parent="GtkBox">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
     <property name="orientation">vertical</property>
     <child>
       <object class="GtkListBox" id="list_box">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
+        <property name="vexpand">1</property>
+        <property name="valign">fill</property>
         <child type="placeholder">
-          <object class="HdyStatusPage">
+          <object class="AdwStatusPage">
             <property name="visible">True</property>
             <property name="can-focus">False</property>
             <property name="icon-name">mail-read-symbolic</property>
-            <property name="title" translatable="yes">Notifications</property>
-            <property name="description" translatable="yes">You're all caught up!</property>
+            <property name="title" translatable="1">Notifications</property>
+            <property name="description" translatable="1">You&apos;re all caught up!</property>
             <child>
               <placeholder/>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">True</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
   </template>
 </interface>
--- a/pidgin/resources/Plugins/dialog.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Plugins/dialog.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,121 +14,29 @@
 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  02110-1301, USA.
-
+along with this program; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
-  <requires lib="gplugin-gtk" version="0.28"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="gplugin-gtk4" version="0.35"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <object class="GPluginGtkStore" type-func="gplugin_gtk_store_get_type" id="raw_plugin_store"/>
-  <object class="GtkTreeModelSort" id="plugin_store">
-    <property name="model">raw_plugin_store</property>
-  </object>
   <template class="PidginPluginsDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Plugins</property>
-    <property name="type-hint">dialog</property>
-    <signal name="delete-event" handler="gtk_widget_destroy" swapped="no"/>
-    <child internal-child="vbox">
+    <property name="title" translatable="1">Plugins</property>
+    <signal name="response" handler="pidgin_plugins_dialog_response_cb" swapped="no"/>
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox">
-            <property name="can-focus">False</property>
-            <property name="layout-style">end</property>
-            <child>
-              <object class="GtkButton" id="configure_plugin_button">
-                <property name="label" translatable="yes">Configure Plugin</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <signal name="clicked" handler="pidgin_plugins_dialog_config_plugin_cb" object="PidginPluginsDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton">
-                <property name="label" translatable="yes">Close</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <signal name="clicked" handler="gtk_widget_destroy" object="PidginPluginsDialog" swapped="yes"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
+        <child>
+          <object class="GPluginGtkView" id="view">
+            <property name="vexpand">1</property>
+            <property name="valign">fill</property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="homogeneous">True</property>
-            <child>
-              <object class="GtkScrolledWindow">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="shadow-type">in</property>
-                <child>
-                  <object class="GPluginGtkView" type-func="gplugin_gtk_view_get_type" id="tree_view">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="model">plugin_store</property>
-                    <property name="headers-clickable">False</property>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection">
-                        <signal name="changed" handler="pidgin_plugins_dialog_selection_cb" object="PidginPluginsDialog" swapped="no"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GPluginGtkPluginInfo" type-func="gplugin_gtk_plugin_info_get_type" id="plugin_info">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="orientation">vertical</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
+    <child internal-child="action_area"/>
   </template>
 </interface>
--- a/pidgin/resources/Plugins/menu.ui	Tue Aug 23 01:09:33 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
-Pidgin - Internet Messenger
-Copyright (C) Pidgin Developers <devel@pidgin.im>
-
-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  02110-1301, USA.
-
--->
-<interface>
-  <requires lib="gtk+" version="3.22"/>
-  <!-- interface-license-type gplv2 -->
-  <!-- interface-name Pidgin -->
-  <!-- interface-description Internet Messenger -->
-  <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <template class="PidginPluginsMenu" parent="GtkMenu">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="separator">
-        <property name="can-focus">False</property>
-      </object>
-    </child>
-  </template>
-</interface>
--- a/pidgin/resources/Prefs/away.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Prefs/away.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -16,10 +15,10 @@
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, see <https://www.gnu.org/licenses/>.
-
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -75,45 +74,28 @@
     <property name="step-increment">1</property>
     <property name="page-increment">10</property>
   </object>
-  <template class="PidginAwayPrefs" parent="HdyPreferencesPage">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
+  <template class="PidginAwayPrefs" parent="AdwPreferencesPage">
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Idle</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Idle</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label12">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_Report idle time:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">_Report idle time:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">idle_reporting.combo</property>
                     <property name="xalign">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkComboBox" id="idle_reporting.combo">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
                     <property name="model">idle_reporting.store</property>
                     <child>
                       <object class="GtkCellRendererText"/>
@@ -122,133 +104,68 @@
                       </attributes>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label13">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_Minutes before becoming idle:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">_Minutes before becoming idle:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">mins_before_away</property>
                     <property name="xalign">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkSpinButton" id="mins_before_away">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
+                    <property name="focusable">1</property>
                     <property name="adjustment">mins_before_adjustment</property>
-                    <property name="numeric">True</property>
+                    <property name="numeric">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox" id="idle_hbox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkCheckButton" id="away_when_idle">
-                    <property name="label" translatable="yes">Change to this status when _idle:</property>
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="receives-default">False</property>
-                    <property name="use-underline">True</property>
-                    <property name="draw-indicator">True</property>
+                    <property name="label" translatable="1">Change to this status when _idle:</property>
+                    <property name="focusable">1</property>
+                    <property name="use-underline">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <placeholder/>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Away</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Away</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label14">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_Auto-reply:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">_Auto-reply:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">auto_reply.combo</property>
                     <property name="xalign">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkComboBox" id="auto_reply.combo">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
                     <property name="model">auto_reply.store</property>
                     <child>
                       <object class="GtkCellRendererText"/>
@@ -257,92 +174,46 @@
                       </attributes>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">1</property>
-      </packing>
     </child>
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Status at Startup</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Status at Startup</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkCheckButton" id="startup_current_status">
-                <property name="label" translatable="yes">Use status from last _exit at startup</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+                <property name="label" translatable="1">Use status from last _exit at startup</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox" id="startup_hbox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="startup_label">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Status to a_pply at startup:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">Status to a_pply at startup:</property>
+                    <property name="use-underline">1</property>
                     <property name="xalign">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <placeholder/>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">2</property>
-      </packing>
     </child>
   </template>
   <object class="GtkSizeGroup" id="sg">
--- a/pidgin/resources/Prefs/conversation.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Prefs/conversation.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -16,19 +15,17 @@
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, see <https://www.gnu.org/licenses/>.
-
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <requires lib="Talkatu" version="0.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <object class="TalkatuTagTable" id="format_tag_table"/>
   <object class="TalkatuWholeBuffer" id="format_buffer">
-    <property name="tag-table">format_tag_table</property>
-    <property name="text" translatable="yes">This is how your outgoing message text will appear when you use protocols that support formatting.</property>
+    <property name="text" translatable="1">This is how your outgoing message text will appear when you use protocols that support formatting.</property>
     <property name="style">whole</property>
   </object>
   <object class="GtkAdjustment" id="minimum_entry_lines.adjustment">
@@ -39,197 +36,94 @@
     <property name="page-increment">1</property>
   </object>
   <object class="GtkSizeGroup" id="iface.sg"/>
-  <template class="PidginConversationPrefs" parent="HdyPreferencesPage">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
+  <template class="PidginConversationPrefs" parent="AdwPreferencesPage">
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Conversations</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Conversations</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkCheckButton" id="show_incoming_formatting">
-                <property name="label" translatable="yes">Show _formatting on incoming messages</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+                <property name="label" translatable="1">Show _formatting on incoming messages</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkCheckButton" id="im.send_typing">
-                <property name="label" translatable="yes">_Notify buddies that you are typing to them</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+                <property name="label" translatable="1">_Notify buddies that you are typing to them</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkCheckButton" id="use_smooth_scrolling">
-                <property name="label" translatable="yes">Use smooth-scrolling</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="draw-indicator">True</property>
+                <property name="label" translatable="1">Use smooth-scrolling</property>
+                <property name="focusable">1</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
             <child>
               <object class="GtkCheckButton" id="win32.blink_im">
-                <property name="label" translatable="yes">F_lash window when IMs are received</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+                <property name="label" translatable="1">F_lash window when IMs are received</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Minimum input area height in lines:</property>
+                    <property name="label" translatable="1">Minimum input area height in lines:</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkSpinButton" id="minimum_entry_lines">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="input-purpose">digits</property>
+                    <property name="focusable">1</property>
                     <property name="adjustment">minimum_entry_lines.adjustment</property>
-                    <property name="numeric">True</property>
+                    <property name="numeric">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">4</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Default Formatting</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Default Formatting</property>
         <child>
           <object class="GtkBox" id="sample_box">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <child>
               <object class="TalkatuEditor">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                 <property name="orientation">vertical</property>
                 <child internal-child="send_button">
                   <object class="GtkButton">
-                    <property name="can-focus">False</property>
-                    <property name="receives-default">False</property>
+                    <property name="visible">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child internal-child="toolbar">
-                  <object class="TalkatuToolbar">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
+                  <object class="TalkatuToolbar"/>
                 </child>
                 <child internal-child="input">
                   <object class="TalkatuInput" id="format_view">
+                    <property name="buffer">format_buffer</property>
+                    <property name="focusable">1</property>
                     <property name="width-request">450</property>
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="wrap-mode">word</property>
-                    <property name="buffer">format_buffer</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">1</property>
-      </packing>
     </child>
   </template>
 </interface>
--- a/pidgin/resources/Prefs/credentialprovider.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Prefs/credentialprovider.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -20,29 +20,27 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
-  <requires lib="libhandy" version="0.0"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="libadwaita" version="0.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <object class="GtkImage" id="image1">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
-    <property name="icon-name">document-properties-symbolic</property>
-  </object>
-  <template class="PidginCredentialProviderRow" parent="HdyActionRow">
-    <property name="visible">True</property>
-    <property name="can-focus">True</property>
-    <property name="activatable">True</property>
+  <template class="PidginCredentialProviderRow" parent="AdwActionRow">
+    <property name="focusable">1</property>
+    <property name="activatable">1</property>
     <child>
       <object class="GtkButton" id="configure">
-        <property name="sensitive">False</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
         <property name="halign">center</property>
         <property name="valign">center</property>
-        <property name="image">image1</property>
+        <child>
+          <object class="GtkImage">
+            <property name="icon-name">document-properties-symbolic</property>
+          </object>
+        </child>
         <style>
           <class name="circular"/>
         </style>
@@ -50,11 +48,11 @@
     </child>
     <child>
       <object class="GtkImage" id="active">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="valign">center</property>
-        <property name="xpad">6</property>
-        <property name="ypad">6</property>
+        <property name="margin-start">6</property>
+        <property name="margin-end">6</property>
+        <property name="margin-top">6</property>
+        <property name="margin-bottom">6</property>
         <property name="icon-name">emblem-default-symbolic</property>
       </object>
     </child>
--- a/pidgin/resources/Prefs/credentials.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Prefs/credentials.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -15,31 +15,24 @@
 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  02110-1301, USA.
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
-  <requires lib="libhandy" version="0.0"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="libadwaita" version="0.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <template class="PidginCredentialPrefs" parent="HdyPreferencesPage">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Credentials</property>
+  <template class="PidginCredentialPrefs" parent="AdwPreferencesPage">
+    <property name="title" translatable="1">Credentials</property>
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="description" translatable="yes">Pidgin does not store passwords directly, but uses the provider selected below to store passwords. Changing providers will not migrate existing stored passwords.</property>
-        <property name="title" translatable="yes">Credential Provider</property>
+      <object class="AdwPreferencesGroup">
+        <property name="description" translatable="1">Pidgin does not store passwords directly, but uses the provider selected below to store passwords. Changing providers will not migrate existing stored passwords.</property>
+        <property name="title" translatable="1">Credential Provider</property>
         <child>
           <object class="GtkListBox" id="credential_list">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="selection-mode">none</property>
             <signal name="row-activated" handler="pidgin_credential_prefs_list_row_activated_cb" after="yes" swapped="no"/>
             <style>
--- a/pidgin/resources/Prefs/network.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Prefs/network.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -16,10 +15,10 @@
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, see <https://www.gnu.org/licenses/>.
-
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -44,434 +43,230 @@
     <property name="step-increment">1</property>
     <property name="page-increment">10</property>
   </object>
-  <template class="PidginNetworkPrefs" parent="HdyPreferencesPage">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
+  <template class="PidginNetworkPrefs" parent="AdwPreferencesPage">
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">IP Address</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">IP Address</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label8">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">ST_UN server:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">ST_UN server:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">stun_server</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkEntry" id="stun_server">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="placeholder-text" translatable="yes">Example: stunserver.org</property>
+                    <property name="halign">fill</property>
+                    <property name="hexpand">1</property>
+                    <property name="focusable">1</property>
+                    <property name="placeholder-text" translatable="1">Example: stunserver.org</property>
                     <property name="input-purpose">url</property>
-                    <signal name="focus-out-event" handler="network_stun_server_changed_cb" swapped="no"/>
+                    <child>
+                      <object class="GtkEventControllerFocus">
+                        <signal name="leave" handler="network_stun_server_changed_cb" object="stun_server" swapped="no"/>
+                      </object>
+                    </child>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkCheckButton" id="auto_ip">
-                <property name="label" translatable="yes">Use _automatically detected IP address</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+                <property name="label" translatable="1">Use _automatically detected IP address</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
                 <signal name="toggled" handler="auto_ip_button_clicked_cb" after="yes" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox" id="public_ip_hbox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label9">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Public _IP:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">Public _IP:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">public_ip</property>
                     <property name="xalign">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkEntry" id="public_ip">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
+                    <property name="focusable">1</property>
                     <signal name="changed" handler="network_ip_changed" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Ports</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Ports</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkCheckButton" id="map_ports">
-                <property name="label" translatable="yes">_Enable automatic router port forwarding</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+                <property name="label" translatable="1">_Enable automatic router port forwarding</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkCheckButton" id="ports_range_use">
-                    <property name="label" translatable="yes">_Manually specify range of ports to listen on:</property>
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="receives-default">False</property>
-                    <property name="use-underline">True</property>
-                    <property name="draw-indicator">True</property>
+                    <property name="label" translatable="1">_Manually specify range of ports to listen on:</property>
+                    <property name="focusable">1</property>
+                    <property name="use-underline">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkBox" id="ports_range_hbox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">_Start:</property>
-                        <property name="use-underline">True</property>
+                        <property name="label" translatable="1">_Start:</property>
+                        <property name="use-underline">1</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkSpinButton" id="ports_range_start">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="text" translatable="yes">0</property>
+                        <property name="focusable">1</property>
+                        <property name="text" translatable="1">0</property>
                         <property name="adjustment">ports_range_start.adjustment</property>
-                        <property name="numeric">True</property>
+                        <property name="numeric">1</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">_End:</property>
-                        <property name="use-underline">True</property>
+                        <property name="label" translatable="1">_End:</property>
+                        <property name="use-underline">1</property>
                         <property name="mnemonic-widget">ports_range_end</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">2</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkSpinButton" id="ports_range_end">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="text" translatable="yes">0</property>
+                        <property name="focusable">1</property>
+                        <property name="text" translatable="1">0</property>
                         <property name="adjustment">ports_range_end.adjustment</property>
-                        <property name="numeric">True</property>
+                        <property name="numeric">1</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">3</property>
-                      </packing>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">1</property>
-      </packing>
     </child>
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Relay Server (TURN)</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Relay Server (TURN)</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label10">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_TURN server:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">_TURN server:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">turn_server</property>
                     <property name="xalign">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkEntry" id="turn_server">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <signal name="focus-out-event" handler="network_turn_server_changed_cb" swapped="no"/>
+                    <property name="focusable">1</property>
+                    <child>
+                      <object class="GtkEventControllerFocus">
+                        <signal name="leave" handler="network_turn_server_changed_cb" swapped="no"/>
+                      </object>
+                    </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_UDP Port:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">_UDP Port:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">turn_port_udp</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkSpinButton" id="turn_port_udp">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
+                    <property name="focusable">1</property>
                     <property name="adjustment">turn_port_udp.adjustment</property>
-                    <property name="numeric">True</property>
+                    <property name="numeric">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">3</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">T_CP Port:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">T_CP Port:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">turn_port_tcp</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">4</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkSpinButton" id="turn_port_tcp">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
+                    <property name="focusable">1</property>
                     <property name="adjustment">turn_port_tcp.adjustment</property>
-                    <property name="numeric">True</property>
+                    <property name="numeric">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">5</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label11">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Use_rname:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">Use_rname:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">turn_username</property>
                     <property name="xalign">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkEntry" id="turn_username">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
+                    <property name="focusable">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Pass_word:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">Pass_word:</property>
+                    <property name="use-underline">1</property>
                     <property name="mnemonic-widget">turn_password</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkEntry" id="turn_password">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="visibility">False</property>
-                    <property name="invisible-char">●</property>
-                    <property name="input-purpose">password</property>
+                  <object class="GtkPasswordEntry" id="turn_password">
+                    <property name="focusable">1</property>
+                    <property name="show-peek-icon">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">3</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">2</property>
-      </packing>
     </child>
   </template>
   <object class="GtkSizeGroup" id="sg">
--- a/pidgin/resources/Prefs/prefs.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Prefs/prefs.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -20,136 +20,92 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginPrefsWindow" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Preferences</property>
-    <property name="type-hint">dialog</property>
+    <property name="title" translatable="1">Preferences</property>
     <signal name="destroy" handler="delete_prefs" swapped="no"/>
-    <child internal-child="vbox">
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
+        <property name="vexpand">1</property>
+        <property name="orientation">horizontal</property>
+        <child>
+          <object class="GtkStackSidebar">
+            <property name="stack">stack</property>
+          </object>
+        </child>
         <child>
-          <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+          <object class="GtkStack" id="stack">
+            <signal name="notify::visible-child" handler="vv_test_switch_page_cb" object="vv" swapped="no"/>
             <child>
-              <object class="GtkStackSidebar">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="stack">stack</property>
+              <object class="GtkStackPage">
+                <property name="name">conversations</property>
+                <property name="title" translatable="1">Conversations</property>
+                <property name="child">
+                  <object class="PidginConversationPrefs"/>
+                </property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
+            </child>
+            <child>
+              <object class="GtkStackPage">
+                <property name="name">network</property>
+                <property name="title" translatable="1">Network</property>
+                <property name="child">
+                  <object class="PidginNetworkPrefs"/>
+                </property>
+              </object>
             </child>
             <child>
-              <object class="GtkStack" id="stack">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <signal name="notify::visible-child" handler="vv_test_switch_page_cb" object="vv" swapped="no"/>
-                <child>
-                  <object class="PidginConversationPrefs">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                  </object>
-                  <packing>
-                    <property name="name">conversations</property>
-                    <property name="title" translatable="yes">Conversations</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="PidginNetworkPrefs">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                  </object>
-                  <packing>
-                    <property name="name">network</property>
-                    <property name="title" translatable="yes">Network</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="PidginProxyPrefs">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                  </object>
-                  <packing>
-                    <property name="name">proxy</property>
-                    <property name="title" translatable="yes">Proxy</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="PidginAwayPrefs">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                  </object>
-                  <packing>
-                    <property name="name">away</property>
-                    <property name="title" translatable="yes">Status / Idle</property>
-                    <property name="position">3</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="PidginCredentialPrefs">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                  </object>
-                  <packing>
-                    <property name="name">credentials</property>
-                    <property name="title" translatable="yes">Credentials</property>
-                    <property name="position">4</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="PidginVVPrefs" id="vv">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                  </object>
-                  <packing>
-                    <property name="name">vv</property>
-                    <property name="title" translatable="yes">Voice/Video</property>
-                    <property name="position">5</property>
-                  </packing>
-                </child>
+              <object class="GtkStackPage">
+                <property name="name">proxy</property>
+                <property name="title" translatable="1">Proxy</property>
+                <property name="child">
+                  <object class="PidginProxyPrefs"/>
+                </property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
+            </child>
+            <child>
+              <object class="GtkStackPage">
+                <property name="name">away</property>
+                <property name="title" translatable="1">Status / Idle</property>
+                <property name="child">
+                  <object class="PidginAwayPrefs"/>
+                </property>
+              </object>
             </child>
             <child>
-              <placeholder/>
+              <object class="GtkStackPage">
+                <property name="name">credentials</property>
+                <property name="title" translatable="1">Credentials</property>
+                <property name="child">
+                  <object class="PidginCredentialPrefs"/>
+                </property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkStackPage">
+                <property name="name">vv</property>
+                <property name="title" translatable="1">Voice/Video</property>
+                <property name="child">
+                  <object class="PidginVVPrefs" id="vv"/>
+                </property>
+              </object>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
         </child>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton">
-        <property name="label" translatable="yes">_Close</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
-        <signal name="clicked" handler="gtk_widget_destroy" object="PidginPrefsWindow" swapped="yes"/>
+        <property name="label" translatable="1">_Close</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+        <signal name="clicked" handler="gtk_window_destroy" object="PidginPrefsWindow" swapped="yes"/>
       </object>
     </child>
   </template>
--- a/pidgin/resources/Prefs/proxy.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Prefs/proxy.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -16,10 +15,10 @@
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, see <https://www.gnu.org/licenses/>.
-
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -63,306 +62,193 @@
       </row>
     </data>
   </object>
-  <template class="PidginProxyPrefs" parent="HdyPreferencesPage">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
+  <template class="PidginProxyPrefs" parent="AdwPreferencesPage">
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Proxy Server</property>
+      <object class="AdwPreferencesGroup" id="gnome">
+        <property name="title" translatable="1">Proxy Server</property>
+        <property name="description" translatable="1">Proxy preferences are configured in GNOME preferences</property>
         <child>
-          <object class="GtkStack" id="stack">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="margin-start">12</property>
-            <property name="hhomogeneous">False</property>
-            <property name="vhomogeneous">False</property>
+          <object class="GtkBox">
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Proxy preferences are configured in GNOME preferences</property>
-                    <property name="xalign">0</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkBox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="gnome_not_found">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Proxy configuration program was not found.</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="gnome_program">
-                        <property name="label" translatable="yes">Configure _Proxy</property>
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="receives-default">True</property>
-                        <property name="use-underline">True</property>
-                        <signal name="clicked" handler="proxy_button_clicked_cb" object="PidginProxyPrefs" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+              <object class="GtkLabel">
+                <property name="xalign">0</property>
               </object>
-              <packing>
-                <property name="name">gnome</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
                 <child>
-                  <object class="GtkCheckButton" id="socks4_remotedns">
-                    <property name="label" translatable="yes">Use remote _DNS with SOCKS4 proxies</property>
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="receives-default">False</property>
-                    <property name="use-underline">True</property>
-                    <property name="draw-indicator">True</property>
+                  <object class="GtkLabel" id="gnome_not_found">
+                    <property name="label" translatable="1">Proxy configuration program was not found.</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"></attribute>
+                    </attributes>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkBox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Proxy t_ype:</property>
-                        <property name="use-underline">True</property>
-                        <property name="mnemonic-widget">type.combo</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="type.combo">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="model">type.store</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
                 <child>
-                  <!-- n-columns=4 n-rows=3 -->
-                  <object class="GtkGrid" id="options">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="row-spacing">10</property>
-                    <property name="column-spacing">5</property>
-                    <child>
-                      <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">_Host:</property>
-                        <property name="use-underline">True</property>
-                        <property name="mnemonic-widget">host</property>
-                        <property name="xalign">1</property>
-                        <accessibility>
-                          <relation type="label-for" target="host"/>
-                        </accessibility>
-                      </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="host">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">P_ort:</property>
-                        <property name="use-underline">True</property>
-                        <property name="xalign">1</property>
-                        <accessibility>
-                          <relation type="label-for" target="port"/>
-                        </accessibility>
-                      </object>
-                      <packing>
-                        <property name="left-attach">2</property>
-                        <property name="top-attach">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkSpinButton" id="port">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="text" translatable="yes">0</property>
-                        <property name="adjustment">port.adjustment</property>
-                        <property name="numeric">True</property>
-                        <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="left-attach">3</property>
-                        <property name="top-attach">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">User_name:</property>
-                        <property name="use-underline">True</property>
-                        <property name="mnemonic-widget">username</property>
-                        <property name="xalign">1</property>
-                      </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="username">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Pa_ssword:</property>
-                        <property name="use-underline">True</property>
-                        <property name="mnemonic-widget">password</property>
-                        <property name="xalign">1</property>
-                        <accessibility>
-                          <relation type="label-for" target="password"/>
-                        </accessibility>
-                      </object>
-                      <packing>
-                        <property name="left-attach">2</property>
-                        <property name="top-attach">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="password">
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="visibility">False</property>
-                        <property name="invisible-char">●</property>
-                        <property name="input-purpose">password</property>
-                        <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="left-attach">3</property>
-                        <property name="top-attach">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
+                  <object class="GtkButton" id="gnome_program">
+                    <property name="label" translatable="1">Configure _Proxy</property>
+                    <property name="focusable">1</property>
+                    <property name="receives-default">1</property>
+                    <property name="use-underline">1</property>
+                    <signal name="clicked" handler="proxy_button_clicked_cb" object="PidginProxyPrefs" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="name">nongnome</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
+    </child>
+    <child>
+      <object class="AdwPreferencesGroup" id="nongnome">
+        <property name="title" translatable="1">Proxy Server</property>
+        <child>
+          <object class="GtkBox">
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkCheckButton" id="socks4_remotedns">
+                <property name="label" translatable="1">Use remote _DNS with SOCKS4 proxies</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkBox">
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="label" translatable="1">Proxy t_ype:</property>
+                    <property name="use-underline">1</property>
+                    <property name="mnemonic-widget">type.combo</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkComboBox" id="type.combo">
+                    <property name="model">type.store</property>
+                    <child>
+                      <object class="GtkCellRendererText"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <!-- n-columns=4 n-rows=3 -->
+              <object class="GtkGrid" id="options">
+                <property name="row-spacing">10</property>
+                <property name="column-spacing">5</property>
+                <child>
+                  <object class="GtkLabel" id="host-label">
+                    <property name="label" translatable="1">_Host:</property>
+                    <property name="use-underline">1</property>
+                    <property name="mnemonic-widget">host</property>
+                    <property name="xalign">1</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">0</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="host">
+                    <property name="focusable">1</property>
+                    <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
+                    <accessibility>
+                      <relation name="labelled-by">host-label</relation>
+                    </accessibility>
+                    <layout>
+                      <property name="column">1</property>
+                      <property name="row">0</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="port-label">
+                    <property name="label" translatable="1">P_ort:</property>
+                    <property name="use-underline">1</property>
+                    <property name="xalign">1</property>
+                    <layout>
+                      <property name="column">2</property>
+                      <property name="row">0</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkSpinButton" id="port">
+                    <property name="focusable">1</property>
+                    <property name="text" translatable="1">0</property>
+                    <property name="adjustment">port.adjustment</property>
+                    <property name="numeric">1</property>
+                    <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
+                    <accessibility>
+                      <relation name="labelled-by">port-label</relation>
+                    </accessibility>
+                    <layout>
+                      <property name="column">3</property>
+                      <property name="row">0</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="label" translatable="1">User_name:</property>
+                    <property name="use-underline">1</property>
+                    <property name="mnemonic-widget">username</property>
+                    <property name="xalign">1</property>
+                    <layout>
+                      <property name="column">0</property>
+                      <property name="row">1</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="username">
+                    <property name="focusable">1</property>
+                    <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
+                    <layout>
+                      <property name="column">1</property>
+                      <property name="row">1</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="password-label">
+                    <property name="label" translatable="1">Pa_ssword:</property>
+                    <property name="use-underline">1</property>
+                    <property name="mnemonic-widget">password</property>
+                    <property name="xalign">1</property>
+                    <layout>
+                      <property name="column">2</property>
+                      <property name="row">1</property>
+                    </layout>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkPasswordEntry" id="password">
+                    <property name="focusable">1</property>
+                    <property name="show-peek-icon">1</property>
+                    <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
+                    <accessibility>
+                      <relation name="labelled-by">password-label</relation>
+                    </accessibility>
+                    <layout>
+                      <property name="column">3</property>
+                      <property name="row">1</property>
+                    </layout>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
     </child>
   </template>
 </interface>
--- a/pidgin/resources/Prefs/vv.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Prefs/vv.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,12 +14,11 @@
 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  02110-1301, USA.
-
+along with this program; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -67,50 +65,29 @@
       <column type="gchararray"/>
     </columns>
   </object>
-  <template class="PidginVVPrefs" parent="HdyPreferencesPage">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
+  <template class="PidginVVPrefs" parent="AdwPreferencesPage">
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Audio</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Audio</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkFrame">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label-xalign">0</property>
-                <property name="shadow-type">none</property>
-                <child>
+                <property name="child">
                   <object class="GtkBox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
                     <property name="margin-start">12</property>
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkLabel" id="label1">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes" context="Device for Audio Input">Device</property>
+                        <property name="label" translatable="1" context="Device for Audio Input">Device</property>
                         <property name="xalign">0</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkComboBox" id="voice.input.combo">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="id-column">1</property>
                         <property name="model">voice.input.store</property>
                         <child>
@@ -120,60 +97,33 @@
                           </attributes>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
                     </child>
                   </object>
-                </child>
+                </property>
                 <child type="label">
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes" context="Input for Audio">Input</property>
+                    <property name="label" translatable="1" context="Input for Audio">Input</property>
                     <attributes>
-                      <attribute name="weight" value="bold"/>
+                      <attribute name="weight" value="bold"></attribute>
                     </attributes>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkFrame">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label-xalign">0</property>
-                <property name="shadow-type">none</property>
-                <child>
+                <property name="child">
                   <object class="GtkBox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
                     <property name="margin-start">12</property>
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkLabel" id="label2">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes" context="Device for Audio Output">Device</property>
+                        <property name="label" translatable="1" context="Device for Audio Output">Device</property>
                         <property name="xalign">0</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkComboBox" id="voice.output.combo">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="id-column">1</property>
                         <property name="model">voice.output.store</property>
                         <child>
@@ -183,195 +133,93 @@
                           </attributes>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
                     </child>
                   </object>
-                </child>
+                </property>
                 <child type="label">
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes" context="Output for Audio">Output</property>
+                    <property name="label" translatable="1" context="Output for Audio">Output</property>
                     <attributes>
-                      <attribute name="weight" value="bold"/>
+                      <attribute name="weight" value="bold"></attribute>
                     </attributes>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Volume:</property>
+                    <property name="label" translatable="1">Volume:</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkVolumeButton" id="voice.volume">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="focus-on-click">False</property>
-                    <property name="receives-default">True</property>
-                    <property name="relief">none</property>
+                    <property name="focusable">1</property>
+                    <property name="focus-on-click">0</property>
+                    <property name="receives-default">1</property>
                     <property name="orientation">vertical</property>
                     <property name="adjustment">adjustment2</property>
                     <signal name="value-changed" handler="volume_changed_cb" swapped="no"/>
-                    <child internal-child="plus_button">
-                      <object class="GtkButton">
-                        <property name="can-focus">True</property>
-                        <property name="receives-default">True</property>
-                        <property name="halign">center</property>
-                        <property name="valign">center</property>
-                        <property name="relief">none</property>
-                      </object>
-                    </child>
-                    <child internal-child="minus_button">
-                      <object class="GtkButton">
-                        <property name="can-focus">True</property>
-                        <property name="receives-default">True</property>
-                        <property name="halign">center</property>
-                        <property name="valign">center</property>
-                        <property name="relief">none</property>
-                      </object>
-                    </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
             <child>
               <object class="GtkLabel" id="voice.threshold_label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Silence threshold:</property>
+                <property name="label" translatable="1">Silence threshold:</property>
                 <property name="xalign">0</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
             </child>
             <child>
               <object class="GtkScale" id="voice.threshold">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
+                <property name="focusable">1</property>
                 <property name="adjustment">adjustment1</property>
                 <property name="round-digits">0</property>
                 <property name="digits">0</property>
-                <property name="draw-value">False</property>
                 <signal name="value-changed" handler="threshold_value_changed_cb" object="PidginVVPrefs" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">4</property>
-              </packing>
             </child>
             <child>
               <object class="GtkToggleButton" id="voice.test">
-                <property name="label" translatable="yes">Test Audio</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
+                <property name="label" translatable="1">Test Audio</property>
+                <property name="focusable">1</property>
+                <property name="receives-default">1</property>
                 <signal name="toggled" handler="toggle_voice_test_cb" object="PidginVVPrefs" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">5</property>
-              </packing>
             </child>
             <child>
               <object class="GtkProgressBar" id="voice.level">
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">False</property>
+                <property name="sensitive">0</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">6</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
     <child>
-      <object class="HdyPreferencesGroup">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="title" translatable="yes">Video</property>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Video</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="margin-start">12</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkFrame">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label-xalign">0</property>
-                <property name="shadow-type">none</property>
-                <child>
+                <property name="child">
                   <object class="GtkBox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
                     <property name="margin-start">12</property>
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkLabel" id="label3">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes" context="Device for Video Input">Device</property>
+                        <property name="label" translatable="1" context="Device for Video Input">Device</property>
                         <property name="xalign">0</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkComboBox" id="video.input.combo">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="id-column">1</property>
                         <property name="model">video.input.store</property>
                         <child>
@@ -381,60 +229,33 @@
                           </attributes>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
                     </child>
                   </object>
-                </child>
+                </property>
                 <child type="label">
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes" context="Input for Video">Input</property>
+                    <property name="label" translatable="1" context="Input for Video">Input</property>
                     <attributes>
-                      <attribute name="weight" value="bold"/>
+                      <attribute name="weight" value="bold"></attribute>
                     </attributes>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkFrame">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label-xalign">0</property>
-                <property name="shadow-type">none</property>
-                <child>
+                <property name="child">
                   <object class="GtkBox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
                     <property name="margin-start">12</property>
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkLabel" id="label4">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes" context="Device for Video Output">Device</property>
+                        <property name="label" translatable="1" context="Device for Video Output">Device</property>
                         <property name="xalign">0</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkComboBox" id="video.output.combo">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="id-column">1</property>
                         <property name="model">video.output.store</property>
                         <child>
@@ -444,70 +265,40 @@
                           </attributes>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
                     </child>
                   </object>
-                </child>
+                </property>
                 <child type="label">
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes" context="Output for Video">Output</property>
+                    <property name="label" translatable="1" context="Output for Video">Output</property>
                     <attributes>
-                      <attribute name="weight" value="bold"/>
+                      <attribute name="weight" value="bold"></attribute>
                     </attributes>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkAspectFrame" id="video.frame">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label-xalign">0</property>
-                <property name="shadow-type">none</property>
+                <property name="valign">fill</property>
+                <property name="vexpand">1</property>
                 <property name="ratio">1.33</property>
                 <child>
                   <placeholder/>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
             <child>
               <object class="GtkToggleButton" id="video.test">
-                <property name="label" translatable="yes">Test Video</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
+                <property name="label" translatable="1">Test Video</property>
+                <property name="focusable">1</property>
+                <property name="receives-default">1</property>
                 <signal name="toggled" handler="toggle_video_test_cb" object="PidginVVPrefs" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
             </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="expand">True</property>
-        <property name="fill">True</property>
-        <property name="position">1</property>
-      </packing>
     </child>
   </template>
   <object class="GtkSizeGroup" id="sg">
--- a/pidgin/resources/Privacy/dialog.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Privacy/dialog.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,12 +14,10 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -32,229 +29,161 @@
   </object>
   <object class="GtkListStore" id="allow_store">
     <columns>
-      <!-- column-name column1 -->
       <column type="gchararray"/>
     </columns>
   </object>
   <object class="GtkListStore" id="block_store">
     <columns>
-      <!-- column-name column1 -->
       <column type="gchararray"/>
     </columns>
   </object>
   <template class="PidginPrivacyDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Privacy</property>
-    <property name="role">privacy</property>
-    <property name="type-hint">dialog</property>
-    <signal name="close" handler="gtk_widget_destroy" swapped="no"/>
-    <child internal-child="vbox">
+    <property name="title" translatable="1">Privacy</property>
+    <signal name="close" handler="gtk_window_destroy" swapped="no"/>
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="valign">center</property>
+            <property name="label" translatable="1">Changes to privacy settings take effect immediately.</property>
+            <property name="xalign">0</property>
+          </object>
+        </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">6</property>
+            <property name="spacing">5</property>
             <child>
-              <object class="GtkLabel">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Changes to privacy settings take effect immediately.</property>
-                <property name="xalign">0</property>
+              <object class="GtkLabel" id="label1">
+                <property name="halign">center</property>
+                <property name="label" translatable="1">Set privacy for:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">account_chooser</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="GtkLabel" id="label1">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Set privacy for:</property>
-                    <property name="use-underline">True</property>
-                    <property name="mnemonic-widget">account_chooser</property>
-                    <accessibility>
-                      <relation type="label-for" target="account_chooser"/>
-                    </accessibility>
+              <object class="PidginAccountChooser" id="account_chooser">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="model">connected_account_store</property>
+                <property name="active">0</property>
+                <signal name="changed" handler="select_account_cb" object="PidginPrivacyDialog" swapped="no"/>
+                <accessibility>
+                  <relation name="labelled-by">label1</relation>
+                </accessibility>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkComboBoxText" id="type_menu">
+            <property name="valign">fill</property>
+            <signal name="changed" handler="type_changed_cb" object="PidginPrivacyDialog" swapped="no"/>
+          </object>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="allow_widget">
+            <property name="vexpand">1</property>
+            <property name="valign">fill</property>
+            <property name="height-request">200</property>
+            <property name="focusable">1</property>
+            <property name="child">
+              <object class="GtkTreeView" id="allow_list">
+                <property name="focusable">1</property>
+                <property name="model">allow_store</property>
+                <property name="headers-visible">0</property>
+                <property name="search-column">0</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection">
+                    <signal name="changed" handler="user_selected_cb" object="PidginPrivacyDialog" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="PidginAccountChooser" id="account_chooser">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="model">connected_account_store</property>
-                    <property name="active">0</property>
-                    <signal name="changed" handler="select_account_cb" object="PidginPrivacyDialog" swapped="no"/>
-                    <accessibility>
-                      <relation type="labelled-by" target="label1"/>
-                    </accessibility>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkComboBoxText" id="type_menu">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <signal name="changed" handler="type_changed_cb" object="PidginPrivacyDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkScrolledWindow" id="allow_widget">
-                <property name="height-request">200</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="shadow-type">in</property>
-                <child>
-                  <object class="GtkTreeView" id="allow_list">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="model">allow_store</property>
-                    <property name="headers-visible">False</property>
-                    <property name="search-column">0</property>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection">
-                        <signal name="changed" handler="user_selected_cb" object="PidginPrivacyDialog" swapped="no"/>
-                      </object>
-                    </child>
+                  <object class="GtkTreeViewColumn">
+                    <property name="clickable">1</property>
+                    <property name="sort-column-id">0</property>
                     <child>
-                      <object class="GtkTreeViewColumn">
-                        <property name="clickable">True</property>
-                        <property name="sort-column-id">0</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
+                      <object class="GtkCellRendererText"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
                     </child>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkScrolledWindow" id="block_widget">
-                <property name="height-request">200</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="shadow-type">in</property>
+            </property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="block_widget">
+            <property name="vexpand">1</property>
+            <property name="valign">fill</property>
+            <property name="height-request">200</property>
+            <property name="focusable">1</property>
+            <property name="child">
+              <object class="GtkTreeView" id="block_list">
+                <property name="focusable">1</property>
+                <property name="model">block_store</property>
+                <property name="headers-visible">0</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection">
+                    <signal name="changed" handler="user_selected_cb" object="PidginPrivacyDialog" swapped="no"/>
+                  </object>
+                </child>
                 <child>
-                  <object class="GtkTreeView" id="block_list">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="model">block_store</property>
-                    <property name="headers-visible">False</property>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection">
-                        <signal name="changed" handler="user_selected_cb" object="PidginPrivacyDialog" swapped="no"/>
-                      </object>
-                    </child>
+                  <object class="GtkTreeViewColumn">
+                    <property name="clickable">1</property>
+                    <property name="sort-column-id">0</property>
                     <child>
-                      <object class="GtkTreeViewColumn">
-                        <property name="clickable">True</property>
-                        <property name="sort-column-id">0</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="text">0</attribute>
-                          </attributes>
-                        </child>
-                      </object>
+                      <object class="GtkCellRendererText"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
                     </child>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">4</property>
-              </packing>
-            </child>
+            </property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="add_button">
         <property name="label">_Add</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
         <signal name="clicked" handler="add_cb" object="PidginPrivacyDialog" swapped="no"/>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="remove_button">
         <property name="label">_Remove</property>
-        <property name="visible">True</property>
-        <property name="sensitive">False</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
         <signal name="clicked" handler="remove_cb" object="PidginPrivacyDialog" swapped="no"/>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="removeall_button">
-        <property name="label" translatable="yes">Remove Al_l</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">Remove Al_l</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
         <signal name="clicked" handler="removeall_cb" object="PidginPrivacyDialog" swapped="no"/>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="close_button">
         <property name="label">_Close</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
-        <signal name="clicked" handler="gtk_widget_destroy" object="PidginPrivacyDialog" swapped="yes"/>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+        <signal name="clicked" handler="gtk_window_destroy" object="PidginPrivacyDialog" swapped="yes"/>
       </object>
     </child>
   </template>
--- a/pidgin/resources/Protocols/chooser.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Protocols/chooser.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,12 +14,10 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface domain="pidgin">
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -31,8 +28,6 @@
     <property name="model">raw_model</property>
   </object>
   <template class="PidginProtocolChooser" parent="GtkComboBox">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
     <property name="model">model</property>
     <child>
       <object class="GtkCellRendererPixbuf" id="icon"/>
--- a/pidgin/resources/Roomlist/roomlist.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Roomlist/roomlist.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,12 +14,10 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
@@ -28,226 +25,157 @@
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <object class="PidginAccountStore" id="accounts"/>
   <template class="PidginRoomlistDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Room List</property>
-    <property name="role">room list</property>
-    <property name="type-hint">dialog</property>
-    <signal name="delete-event" handler="delete_win_cb" swapped="no"/>
-    <child internal-child="vbox">
+    <property name="title" translatable="1">Room List</property>
+    <signal name="close-request" handler="close_request_cb" swapped="no"/>
+    <signal name="response" handler="pidgin_roomlist_response_cb" swapped="no"/>
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox">
-            <property name="can-focus">False</property>
-            <property name="layout-style">end</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkBox">
+            <property name="spacing">5</property>
             <child>
-              <object class="GtkButton" id="stop_button">
-                <property name="label">_Stop</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="stop_button_cb" object="PidginRoomlistDialog" swapped="no"/>
+              <object class="GtkLabel" id="label1">
+                <property name="halign">start</property>
+                <property name="label" translatable="1">_Account:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">account_widget</property>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="list_button">
-                <property name="label" translatable="yes">_Get List</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="list_button_cb" object="PidginRoomlistDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkButton" id="add_button">
-                <property name="label" translatable="yes">_Add Chat</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="add_room_to_blist_cb" object="PidginRoomlistDialog" swapped="no"/>
+              <object class="PidginAccountChooser" id="account_widget">
+                <property name="hexpand">1</property>
+                <property name="can-focus">1</property>
+                <property name="model">accounts</property>
+                <property name="active">0</property>
+                <property name="halign">fill</property>
+                <signal name="changed" handler="dialog_select_account_cb" object="PidginRoomlistDialog" swapped="no"/>
+                <accessibility>
+                  <relation name="labelled-by">label1</relation>
+                </accessibility>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="join_button">
-                <property name="label" translatable="yes">_Join</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="join_button_cb" object="PidginRoomlistDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="close_button">
-                <property name="label">_Close</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="gtk_widget_destroy" object="PidginRoomlistDialog" swapped="yes"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">4</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
         </child>
         <child>
-          <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">12</property>
-            <child>
-              <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="spacing">5</property>
+          <object class="GtkScrolledWindow" id="sw">
+            <property name="vexpand">1</property>
+            <property name="focusable">1</property>
+            <property name="min-content-height">250</property>
+            <property name="child">
+              <object class="GtkTreeView" id="tree">
+                <property name="focusable">1</property>
+                <property name="search-column">1</property>
+                <signal name="query-tooltip" handler="pidgin_roomlist_query_tooltip" object="PidginRoomlistDialog" swapped="no"/>
+                <signal name="row-activated" handler="row_activated_cb" object="PidginRoomlistDialog" swapped="no"/>
                 <child>
-                  <object class="GtkLabel" id="label1">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_Account:</property>
-                    <property name="use-underline">True</property>
-                    <property name="mnemonic-widget">account_widget</property>
-                    <accessibility>
-                      <relation type="label-for" target="account_widget"/>
-                    </accessibility>
+                  <object class="GtkGestureClick">
+                    <property name="button">3</property>
+                    <signal name="pressed" handler="room_click_cb" object="PidginRoomlistDialog" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
+                </child>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection" id="tree_selection">
+                    <signal name="changed" handler="selection_changed_cb" object="PidginRoomlistDialog" swapped="no"/>
+                  </object>
                 </child>
                 <child>
-                  <object class="PidginAccountChooser" id="account_widget">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="model">accounts</property>
-                    <property name="active">0</property>
-                    <signal name="changed" handler="dialog_select_account_cb" object="PidginRoomlistDialog" swapped="no"/>
-                    <accessibility>
-                      <relation type="labelled-by" target="label1"/>
-                    </accessibility>
+                  <object class="GtkPopoverMenu" id="popover">
+                    <property name="menu-model">popover_menu</property>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkScrolledWindow" id="sw">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="shadow-type">in</property>
-                <property name="min-content-height">250</property>
                 <child>
-                  <object class="GtkTreeView" id="tree">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="search-column">1</property>
-                    <signal name="button-press-event" handler="room_click_cb" object="PidginRoomlistDialog" swapped="no"/>
-                    <signal name="query-tooltip" handler="pidgin_roomlist_query_tooltip" object="PidginRoomlistDialog" swapped="no"/>
-                    <signal name="row-activated" handler="row_activated_cb" object="PidginRoomlistDialog" swapped="no"/>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection" id="tree_selection">
-                        <signal name="changed" handler="selection_changed_cb" object="PidginRoomlistDialog" swapped="no"/>
-                      </object>
-                    </child>
+                  <object class="GtkTreeViewColumn">
+                    <property name="title" translatable="1">Name</property>
                     <child>
-                      <object class="GtkTreeViewColumn">
-                        <property name="title" translatable="yes">Name</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="markup">1</attribute>
-                          </attributes>
-                        </child>
-                      </object>
+                      <object class="GtkCellRendererText"/>
+                      <attributes>
+                        <attribute name="markup">1</attribute>
+                      </attributes>
                     </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn">
+                    <property name="title" translatable="1">Description</property>
                     <child>
-                      <object class="GtkTreeViewColumn">
-                        <property name="title" translatable="yes">Description</property>
-                        <child>
-                          <object class="GtkCellRendererText"/>
-                          <attributes>
-                            <attribute name="markup">2</attribute>
-                          </attributes>
-                        </child>
-                      </object>
+                      <object class="GtkCellRendererText"/>
+                      <attributes>
+                        <attribute name="markup">2</attribute>
+                      </attributes>
                     </child>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkProgressBar" id="progress">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
+            </property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
+        </child>
+        <child>
+          <object class="GtkProgressBar" id="progress">
+          </object>
         </child>
       </object>
     </child>
+    <child type="action">
+      <object class="GtkButton" id="stop_button">
+        <property name="label">_Stop</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="list_button">
+        <property name="label" translatable="1">_Get List</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="add_button">
+        <property name="label" translatable="1">_Add Chat</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="join_button">
+        <property name="label" translatable="1">_Join</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="close_button">
+        <property name="label">_Close</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">stop_button</action-widget>
+      <action-widget response="1">list_button</action-widget>
+      <action-widget response="2">add_button</action-widget>
+      <action-widget response="3">join_button</action-widget>
+      <action-widget response="-7">close_button</action-widget>
+    </action-widgets>
   </template>
+  <menu id="popover_menu">
+    <item>
+      <attribute name="label" translatable="yes">_Join</attribute>
+      <attribute name="action">roomlist.join</attribute>
+    </item>
+    <item>
+      <attribute name="label" translatable="yes">_Add</attribute>
+      <attribute name="action">roomlist.add</attribute>
+    </item>
+  </menu>
 </interface>
--- a/pidgin/resources/Status/box.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Status/box.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -19,7 +19,7 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -43,13 +43,11 @@
     </columns>
   </object>
   <template class="PidginStatusBox" parent="GtkBox">
-    <property name="visible">True</property>
-    <property name="can-focus">True</property>
+    <property name="focusable">1</property>
     <property name="orientation">vertical</property>
     <child>
       <object class="GtkComboBox" id="combo">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
+        <property name="focusable">1</property>
         <property name="model">model</property>
         <property name="id-column">0</property>
         <signal name="changed" handler="pidgin_status_box_combo_changed_cb" object="PidginStatusBox" swapped="no"/>
@@ -61,9 +59,6 @@
         </child>
         <child>
           <object class="GtkCellRendererText" id="text"/>
-          <cell-packing>
-            <property name="expand">true</property>
-          </cell-packing>
           <attributes>
             <attribute name="markup">4</attribute>
           </attributes>
@@ -77,11 +72,6 @@
           </attributes>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
   </template>
 </interface>
--- a/pidgin/resources/Status/editor.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Status/editor.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -14,12 +13,11 @@
 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 Lesser General Public
-License along with this library; if not, see <https://www.gnu.org/licenses/>.
-
+You should have received a copy of the GNU General Public License
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <requires lib="Talkatu" version="0.1"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
@@ -27,244 +25,138 @@
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginStatusEditor" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Status</property>
-    <property name="type-hint">dialog</property>
-    <property name="destroy-with-parent">True</property>
+    <property name="title" translatable="1">Status</property>
+    <property name="destroy-with-parent">1</property>
     <signal name="response" handler="pidgin_status_editor_response_cb" swapped="no"/>
-    <child internal-child="vbox">
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox">
-            <property name="can-focus">False</property>
-            <property name="layout-style">end</property>
-            <child>
-              <object class="GtkButton" id="cancel">
-                <property name="label" translatable="yes">_Cancel</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="use">
-                <property name="label" translatable="yes">_Use</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="sensitive">False</property>
-                <property name="use-underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="save">
-                <property name="label" translatable="yes">_Save</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="sensitive">False</property>
-                <property name="use-underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="vexpand">1</property>
             <property name="orientation">vertical</property>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+                <property name="vexpand">1</property>
+                <property name="valign">GTK_ALIGN_FILL</property>
                 <child>
                   <object class="GtkLabel" id="label1">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_Title:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">_Title:</property>
+                    <property name="use-underline">1</property>
                     <property name="xalign">0</property>
                     <property name="yalign">0</property>
                     <property name="mnemonic-widget">title</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkEntry" id="title">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
+                    <property name="hexpand">1</property>
+                    <property name="halign">GTK_ALIGN_FILL</property>
+                    <property name="focusable">1</property>
                     <signal name="changed" handler="pidgin_status_editor_title_changed_cb" object="PidginStatusEditor" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+                <property name="vexpand">1</property>
+                <property name="valign">GTK_ALIGN_FILL</property>
                 <child>
                   <object class="GtkLabel" id="label2">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">St_atus:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">St_atus:</property>
+                    <property name="use-underline">1</property>
                     <property name="xalign">0</property>
                     <property name="yalign">0</property>
                     <property name="mnemonic-widget">primitive</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="PidginStatusPrimitiveChooser" id="primitive">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                    <property name="hexpand">1</property>
+                    <property name="halign">GTK_ALIGN_FILL</property>
                     <property name="id-column">0</property>
                     <property name="model">primitive_store</property>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkBox">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+                <property name="vexpand">1</property>
+                <property name="valign">GTK_ALIGN_FILL</property>
                 <child>
                   <object class="GtkLabel" id="label3">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">_Message:</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">_Message:</property>
+                    <property name="use-underline">1</property>
                     <property name="xalign">0</property>
                     <property name="yalign">0</property>
                     <property name="mnemonic-widget">message</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="TalkatuEditor">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="halign">GTK_ALIGN_FILL</property>
+                    <property name="hexpand">1</property>
                     <property name="orientation">vertical</property>
+                    <property name="valign">GTK_ALIGN_FILL</property>
+                    <property name="vexpand">1</property>
                     <child internal-child="send_button">
                       <object class="GtkButton">
-                        <property name="can-focus">False</property>
-                        <property name="receives-default">False</property>
+                        <property name="visible">0</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                     <child internal-child="toolbar">
-                      <object class="TalkatuToolbar">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
+                      <object class="TalkatuToolbar"/>
                     </child>
                     <child internal-child="input">
                       <object class="TalkatuInput" id="message">
+                        <property name="buffer">buffer</property>
+                        <property name="halign">GTK_ALIGN_FILL</property>
+                        <property name="hexpand">1</property>
+                        <property name="valign">GTK_ALIGN_FILL</property>
+                        <property name="vexpand">1</property>
                         <property name="width-request">450</property>
-                        <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                         <property name="wrap-mode">word</property>
-                        <property name="buffer">buffer</property>
                       </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
+    <child type="action">
+      <object class="GtkButton" id="cancel">
+        <property name="label" translatable="1">_Cancel</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="use">
+        <property name="label" translatable="1">_Use</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="sensitive">0</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="save">
+        <property name="label" translatable="1">_Save</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="sensitive">0</property>
+        <property name="use-underline">1</property>
+      </object>
+    </child>
     <action-widgets>
-      <action-widget response="-6">cancel</action-widget>
+      <action-widget response="cancel">cancel</action-widget>
       <action-widget response="0">use</action-widget>
       <action-widget response="1">save</action-widget>
     </action-widgets>
@@ -276,9 +168,6 @@
       <widget name="label3"/>
     </widgets>
   </object>
-  <object class="TalkatuTagTable" id="tag_table"/>
-  <object class="TalkatuHtmlBuffer" id="buffer">
-    <property name="tag-table">tag_table</property>
-  </object>
+  <object class="TalkatuHtmlBuffer" id="buffer"/>
   <object class="PidginStatusPrimitiveStore" id="primitive_store"/>
 </interface>
--- a/pidgin/resources/Status/manager.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Status/manager.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -19,7 +19,7 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -41,144 +41,124 @@
     </columns>
   </object>
   <template class="PidginStatusManager" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Saved Statuses</property>
+    <property name="title" translatable="1">Saved Statuses</property>
     <property name="default-width">550</property>
     <property name="default-height">250</property>
-    <property name="type-hint">dialog</property>
     <signal name="response" handler="pidgin_status_manager_response_cb" swapped="no"/>
-    <child internal-child="vbox">
-      <object class="GtkBox">
-        <property name="can-focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
+    <child internal-child="content_area">
+      <object class="GtkScrolledWindow">
+        <property name="vexpand">1</property>
+        <property name="valign">fill</property>
+        <property name="focusable">1</property>
         <child>
-          <object class="GtkScrolledWindow">
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="shadow-type">in</property>
+          <object class="GtkTreeView">
+            <property name="focusable">1</property>
+            <property name="model">model</property>
+            <property name="search-column">0</property>
+            <signal name="row-activated" handler="pidgin_status_manager_row_activated_cb" object="PidginStatusManager" swapped="no"/>
+            <child internal-child="selection">
+              <object class="GtkTreeSelection" id="selection">
+                <signal name="changed" handler="pidgin_status_manager_selection_changed_cb" object="PidginStatusManager" swapped="no"/>
+              </object>
+            </child>
             <child>
-              <object class="GtkTreeView">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="model">model</property>
-                <property name="search-column">0</property>
-                <signal name="row-activated" handler="pidgin_status_manager_row_activated_cb" object="PidginStatusManager" swapped="no"/>
-                <child internal-child="selection">
-                  <object class="GtkTreeSelection" id="selection">
-                    <signal name="changed" handler="pidgin_status_manager_selection_changed_cb" object="PidginStatusManager" swapped="no"/>
+              <object class="GtkTreeViewColumn">
+                <property name="resizable">1</property>
+                <property name="min-width">100</property>
+                <property name="title" translatable="1">Title</property>
+                <property name="clickable">1</property>
+                <property name="sort-column-id">0</property>
+                <child>
+                  <object class="GtkCellRendererText">
+                    <property name="ellipsize">end</property>
                   </object>
+                  <attributes>
+                    <attribute name="markup">0</attribute>
+                  </attributes>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkTreeViewColumn">
+                <property name="resizable">1</property>
+                <property name="title" translatable="1">Type</property>
+                <property name="clickable">1</property>
+                <property name="sort-column-id">2</property>
+                <child>
+                  <object class="GtkCellRendererPixbuf"/>
+                  <attributes>
+                    <attribute name="icon-name">1</attribute>
+                  </attributes>
                 </child>
                 <child>
-                  <object class="GtkTreeViewColumn">
-                    <property name="resizable">True</property>
-                    <property name="min-width">100</property>
-                    <property name="title" translatable="yes">Title</property>
-                    <property name="clickable">True</property>
-                    <property name="sort-column-id">0</property>
-                    <child>
-                      <object class="GtkCellRendererText">
-                        <property name="ellipsize">end</property>
-                      </object>
-                      <attributes>
-                        <attribute name="markup">0</attribute>
-                      </attributes>
-                    </child>
-                  </object>
+                  <object class="GtkCellRendererText"/>
+                  <attributes>
+                    <attribute name="markup">2</attribute>
+                  </attributes>
                 </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkTreeViewColumn">
+                <property name="resizable">1</property>
+                <property name="title" translatable="1">Message</property>
+                <property name="clickable">1</property>
+                <property name="sort-column-id">4</property>
                 <child>
-                  <object class="GtkTreeViewColumn">
-                    <property name="resizable">True</property>
-                    <property name="title" translatable="yes">Type</property>
-                    <property name="clickable">True</property>
-                    <property name="sort-column-id">2</property>
-                    <child>
-                      <object class="GtkCellRendererPixbuf"/>
-                      <attributes>
-                        <attribute name="icon-name">1</attribute>
-                      </attributes>
-                    </child>
-                    <child>
-                      <object class="GtkCellRendererText"/>
-                      <attributes>
-                        <attribute name="markup">2</attribute>
-                      </attributes>
-                    </child>
+                  <object class="GtkCellRendererText">
+                    <property name="ellipsize">end</property>
                   </object>
-                </child>
-                <child>
-                  <object class="GtkTreeViewColumn">
-                    <property name="resizable">True</property>
-                    <property name="title" translatable="yes">Message</property>
-                    <property name="clickable">True</property>
-                    <property name="sort-column-id">4</property>
-                    <child>
-                      <object class="GtkCellRendererText">
-                        <property name="ellipsize">end</property>
-                      </object>
-                      <attributes>
-                        <attribute name="markup">3</attribute>
-                      </attributes>
-                    </child>
-                  </object>
+                  <attributes>
+                    <attribute name="markup">3</attribute>
+                  </attributes>
                 </child>
               </object>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="use_button">
-        <property name="label" translatable="yes">_Use</property>
-        <property name="visible">True</property>
-        <property name="sensitive">False</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Use</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button1">
-        <property name="label" translatable="yes">_Add</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Add</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="modify_button">
-        <property name="label" translatable="yes">_Modify</property>
-        <property name="visible">True</property>
-        <property name="sensitive">False</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Modify</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="remove_button">
-        <property name="label" translatable="yes">_Remove</property>
-        <property name="visible">True</property>
-        <property name="sensitive">False</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Remove</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <child type="action">
       <object class="GtkButton" id="button2">
-        <property name="label" translatable="yes">_Close</property>
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
-        <property name="receives-default">True</property>
-        <property name="use-underline">True</property>
+        <property name="label" translatable="1">_Close</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
       </object>
     </child>
     <action-widgets>
--- a/pidgin/resources/Whiteboard/whiteboard.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Whiteboard/whiteboard.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,102 +14,74 @@
 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  02110-1301, USA.
+along with this program; if not, see <https://www.gnu.org/licenses/>.
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginWhiteboard" parent="GtkWindow">
-    <property name="can-focus">False</property>
     <property name="title" translatable="yes">Pidgin Whiteboard</property>
-    <property name="resizable">False</property>
+    <property name="resizable">0</property>
     <signal name="delete-event" handler="whiteboard_close_cb" swapped="no"/>
-    <child>
+    <property name="child">
       <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="spacing">6</property>
         <child>
           <object class="GtkDrawingArea" id="drawing_area">
+            <property name="hexpand">1</property>
             <property name="width-request">300</property>
             <property name="height-request">250</property>
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK</property>
-            <signal name="button-press-event" handler="pidgin_whiteboard_brush_down" object="PidginWhiteboard" swapped="no"/>
-            <signal name="button-release-event" handler="pidgin_whiteboard_brush_up" object="PidginWhiteboard" swapped="no"/>
-            <signal name="configure-event" handler="pidgin_whiteboard_configure_event" object="PidginWhiteboard" swapped="no"/>
-            <signal name="draw" handler="pidgin_whiteboard_draw_event" object="PidginWhiteboard" swapped="no"/>
-            <signal name="motion-notify-event" handler="pidgin_whiteboard_brush_motion" object="PidginWhiteboard" swapped="no"/>
+            <signal name="resize" handler="pidgin_whiteboard_resize" object="PidginWhiteboard" swapped="no"/>
+            <child>
+              <object class="GtkGestureDrag">
+                <property name="button">1</property>
+                <signal name="drag-begin">pidgin_whiteboard_brush_down</signal>
+                <signal name="drag-end">pidgin_whiteboard_brush_up</signal>
+                <signal name="drag-update">pidgin_whiteboard_brush_motion</signal>
+              </object>
+            </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="halign">center</property>
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkButton">
+                <property name="valign">center</property>
                 <property name="label" translatable="yes">_Clear</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
+                <property name="focusable">1</property>
+                <property name="receives-default">1</property>
+                <property name="use-underline">1</property>
                 <signal name="clicked" handler="pidgin_whiteboard_button_clear_press" object="PidginWhiteboard" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkButton">
+                <property name="valign">center</property>
                 <property name="label" translatable="yes">_Save</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
+                <property name="focusable">1</property>
+                <property name="receives-default">1</property>
+                <property name="use-underline">1</property>
                 <signal name="clicked" handler="pidgin_whiteboard_button_save_press" object="PidginWhiteboard" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkColorButton" id="color_button">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
+                <property name="valign">center</property>
+                <property name="focusable">1</property>
+                <property name="receives-default">1</property>
                 <signal name="color-set" handler="color_selected" object="PidginWhiteboard" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
-    </child>
+    </property>
   </template>
 </interface>
--- a/pidgin/resources/Xfer/xfer.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/Xfer/xfer.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,12 +14,10 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
@@ -42,105 +39,26 @@
     </columns>
   </object>
   <template class="PidginXferDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">File Transfer</property>
-    <property name="role">file transfer</property>
+    <property name="title" translatable="1">File Transfer</property>
     <property name="default-width">450</property>
     <property name="default-height">250</property>
-    <property name="type-hint">normal</property>
-    <signal name="delete-event" handler="delete_win_cb" swapped="no"/>
-    <child internal-child="vbox">
+    <signal name="close-request" handler="close_request_cb" swapped="no"/>
+    <child internal-child="content_area">
       <object class="GtkBox">
-        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox">
-            <property name="can-focus">False</property>
-            <property name="layout-style">end</property>
-            <child>
-              <object class="GtkButton" id="open_button">
-                <property name="label" translatable="yes">_Open</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="open_button_cb" object="PidginXferDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="remove_button">
-                <property name="label" translatable="yes">_Remove</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="remove_button_cb" object="PidginXferDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="stop_button">
-                <property name="label" translatable="yes">_Stop</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="stop_button_cb" object="PidginXferDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="close_button">
-                <property name="label" translatable="yes">_Close</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <property name="use-underline">True</property>
-                <signal name="clicked" handler="close_button_cb" object="PidginXferDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="vexpand">1</property>
             <property name="orientation">vertical</property>
             <child>
               <object class="GtkScrolledWindow">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="shadow-type">in</property>
+                <property name="vexpand">1</property>
+                <property name="focusable">1</property>
                 <property name="min-content-height">140</property>
-                <child>
+                <property name="child">
                   <object class="GtkTreeView" id="tree">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
+                    <property name="focusable">1</property>
                     <property name="model">model</property>
                     <child internal-child="selection">
                       <object class="GtkTreeSelection">
@@ -149,7 +67,7 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn">
-                        <property name="resizable">True</property>
+                        <property name="resizable">1</property>
                         <property name="sizing">fixed</property>
                         <property name="fixed-width">25</property>
                         <child>
@@ -162,8 +80,8 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn">
-                        <property name="resizable">True</property>
-                        <property name="title" translatable="yes">Progress</property>
+                        <property name="resizable">1</property>
+                        <property name="title" translatable="1">Progress</property>
                         <child>
                           <object class="GtkCellRendererProgress"/>
                           <attributes>
@@ -174,8 +92,8 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn">
-                        <property name="resizable">True</property>
-                        <property name="title" translatable="yes">Filename</property>
+                        <property name="resizable">1</property>
+                        <property name="title" translatable="1">Filename</property>
                         <child>
                           <object class="GtkCellRendererText"/>
                           <attributes>
@@ -186,8 +104,8 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn">
-                        <property name="resizable">True</property>
-                        <property name="title" translatable="yes">Size</property>
+                        <property name="resizable">1</property>
+                        <property name="title" translatable="1">Size</property>
                         <child>
                           <object class="GtkCellRendererText"/>
                           <attributes>
@@ -198,8 +116,8 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn">
-                        <property name="resizable">True</property>
-                        <property name="title" translatable="yes">Remaining</property>
+                        <property name="resizable">1</property>
+                        <property name="title" translatable="1">Remaining</property>
                         <child>
                           <object class="GtkCellRendererText"/>
                           <attributes>
@@ -209,377 +127,314 @@
                       </object>
                     </child>
                   </object>
-                </child>
+                </property>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkCheckButton" id="keep_open">
-                <property name="label" translatable="yes">Close this window when all transfers _finish</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+                <property name="valign">center</property>
+                <property name="label" translatable="1">Close this window when all transfers _finish</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
                 <signal name="toggled" handler="toggle_keep_open_cb" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="GtkCheckButton" id="auto_clear">
-                <property name="label" translatable="yes">C_lear finished transfers</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">False</property>
-                <property name="use-underline">True</property>
-                <property name="draw-indicator">True</property>
+                <property name="valign">center</property>
+                <property name="label" translatable="1">C_lear finished transfers</property>
+                <property name="focusable">1</property>
+                <property name="use-underline">1</property>
                 <signal name="toggled" handler="toggle_clear_finished_cb" swapped="no"/>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
             </child>
             <child>
               <object class="GtkExpander" id="expander">
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="resize-toplevel">True</property>
+                <property name="valign">center</property>
+                <property name="sensitive">0</property>
+                <property name="focusable">1</property>
+                <property name="resize-toplevel">1</property>
                 <child>
-                  <!-- n-columns=3 n-rows=10 -->
                   <object class="GtkGrid">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
                     <property name="margin-start">20</property>
                     <property name="row-spacing">6</property>
                     <property name="column-spacing">6</property>
                     <child>
                       <object class="GtkLabel" id="local_user_desc_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="remote_user_desc_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">1</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">1</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Protocol:</property>
+                        <property name="label" translatable="1">Protocol:</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">2</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">2</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Filename:</property>
+                        <property name="label" translatable="1">Filename:</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">3</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">3</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Local File:</property>
+                        <property name="label" translatable="1">Local File:</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">4</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">4</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Status:</property>
+                        <property name="label" translatable="1">Status:</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">5</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">5</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Speed:</property>
+                        <property name="label" translatable="1">Speed:</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">6</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">6</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Time Elapsed:</property>
+                        <property name="label" translatable="1">Time Elapsed:</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">7</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">7</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label" translatable="yes">Time Remaining:</property>
+                        <property name="label" translatable="1">Time Remaining:</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
                         <attributes>
-                          <attribute name="weight" value="bold"/>
+                          <attribute name="weight" value="bold"></attribute>
                         </attributes>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">8</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">8</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="local_user_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="hexpand">True</property>
+                        <property name="hexpand">1</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">0</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">0</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="remote_user_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="hexpand">True</property>
+                        <property name="hexpand">1</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">1</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">1</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="protocol_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">2</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">2</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="filename_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">3</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">3</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="localfile_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">4</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">4</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="status_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">5</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">5</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="speed_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">6</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">6</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="time_elapsed_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">7</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">7</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="time_remaining_label">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
                         <property name="justify">right</property>
                         <property name="xalign">0</property>
+                        <layout>
+                          <property name="column">1</property>
+                          <property name="row">8</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">1</property>
-                        <property name="top-attach">8</property>
-                      </packing>
                     </child>
                     <child>
                       <object class="GtkProgressBar" id="progress">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="show-text">True</property>
+                        <property name="show-text">1</property>
+                        <layout>
+                          <property name="column">0</property>
+                          <property name="row">9</property>
+                          <property name="column-span">2</property>
+                        </layout>
                       </object>
-                      <packing>
-                        <property name="left-attach">0</property>
-                        <property name="top-attach">9</property>
-                        <property name="width">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
                     </child>
                   </object>
                 </child>
                 <child type="label">
                   <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">File transfer _details</property>
-                    <property name="use-underline">True</property>
+                    <property name="label" translatable="1">File transfer _details</property>
+                    <property name="use-underline">1</property>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">3</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
     </child>
+    <child type="action">
+      <object class="GtkButton" id="open_button">
+        <property name="label" translatable="1">_Open</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+        <signal name="clicked" handler="open_button_cb" object="PidginXferDialog" swapped="no"/>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="remove_button">
+        <property name="label" translatable="1">_Remove</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+        <signal name="clicked" handler="remove_button_cb" object="PidginXferDialog" swapped="no"/>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="stop_button">
+        <property name="label" translatable="1">_Stop</property>
+        <property name="sensitive">0</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+        <signal name="clicked" handler="stop_button_cb" object="PidginXferDialog" swapped="no"/>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="close_button">
+        <property name="label" translatable="1">_Close</property>
+        <property name="focusable">1</property>
+        <property name="receives-default">1</property>
+        <property name="use-underline">1</property>
+        <signal name="clicked" handler="close_button_cb" object="PidginXferDialog" swapped="no"/>
+      </object>
+    </child>
   </template>
 </interface>
--- a/pidgin/resources/gtk/menus.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/gtk/menus.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -18,7 +18,7 @@
 along with this program; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
--- a/pidgin/resources/pidgin.gresource.xml	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/pidgin.gresource.xml	Sun Aug 28 22:18:46 2022 -0500
@@ -17,12 +17,9 @@
     <file compressed="true">Conversations/tab-label.css</file>
     <file compressed="true">Conversations/window.ui</file>
     <file compressed="true">Debug/debug.ui</file>
-    <file compressed="true">Debug/filter.css</file>
-    <file compressed="true">Debug/plugininfo.ui</file>
     <file compressed="true">Dialogs/addbuddy.ui</file>
     <file compressed="true">Dialogs/addchat.ui</file>
     <file compressed="true">Keypad/keypad.ui</file>
-    <file compressed="true">Log/log-viewer.ui</file>
     <file compressed="true">Media/window.ui</file>
     <file compressed="true">Notifications/addcontact.ui</file>
     <file compressed="true">Notifications/authorizationrequest.ui</file>
--- a/pidgin/resources/presenceicon.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/presenceicon.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,32 +14,24 @@
 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, see <https://www.gnu.org/licenses/>.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginPresenceIcon" parent="GtkBox">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
     <property name="orientation">vertical</property>
     <child>
       <object class="GtkImage" id="icon">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
+        <property name="vexpand">1</property>
+        <property name="valign">fill</property>
         <property name="icon-name">image-missing</property>
-        <property name="use-fallback">True</property>
-        <property name="icon_size">6</property>
+        <property name="use-fallback">1</property>
+        <property name="icon_size">large</property>
       </object>
-      <packing>
-        <property name="expand">True</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
   </template>
 </interface>
--- a/pidgin/resources/proxyoptions.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/proxyoptions.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,21 +14,17 @@
 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  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <object class="GtkListStore" id="model">
     <columns>
-      <!-- column-name type -->
       <column type="PurpleProxyType"/>
-      <!-- column-name description -->
       <column type="gchararray"/>
     </columns>
     <data>
@@ -73,8 +68,6 @@
     <property name="page-increment">10</property>
   </object>
   <template class="PidginProxyOptions" parent="GtkBox">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
     <property name="margin-start">12</property>
     <property name="margin-end">12</property>
     <property name="margin-top">12</property>
@@ -83,29 +76,19 @@
     <property name="spacing">6</property>
     <child>
       <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
         <property name="spacing">6</property>
         <child>
           <object class="GtkLabel" id="proxy_type_label">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="label" translatable="yes">Proxy _type:</property>
-            <property name="use-underline">True</property>
+            <property name="label" translatable="1">Proxy _type:</property>
+            <property name="use-underline">1</property>
             <property name="mnemonic-widget">proxy_type</property>
             <property name="xalign">0</property>
-            <property name="yalign">0.5</property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
         </child>
         <child>
           <object class="GtkComboBox" id="proxy_type">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="hexpand">1</property>
+            <property name="halign">fill</property>
             <property name="model">filter</property>
             <signal name="changed" handler="pidgin_proxy_options_proxy_type_changed_cb" object="PidginProxyOptions" swapped="no"/>
             <child>
@@ -115,193 +98,98 @@
               </attributes>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
     </child>
     <child>
       <object class="GtkBox" id="options">
-        <property name="visible">True</property>
-        <property name="sensitive">False</property>
-        <property name="can-focus">False</property>
+        <property name="sensitive">0</property>
         <property name="orientation">vertical</property>
         <property name="spacing">6</property>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkLabel" id="host_label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">_Host:</property>
-                <property name="use-underline">True</property>
+                <property name="label" translatable="1">_Host:</property>
+                <property name="use-underline">1</property>
                 <property name="mnemonic-widget">hostname</property>
                 <property name="xalign">0</property>
-                <property name="yalign">0.5</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="GtkEntry" id="hostname">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="progress-pulse-step">0</property>
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="focusable">1</property>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="spacing">6</property>
-            <child>
-              <object class="GtkLabel" id="port_label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">_Port:</property>
-                <property name="use-underline">True</property>
-                <property name="mnemonic-widget">port</property>
-                <property name="xalign">0</property>
-                <property name="yalign">0.5</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkSpinButton" id="port">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="input-hints">GTK_INPUT_HINT_NO_EMOJI | GTK_INPUT_HINT_NONE</property>
-                <property name="adjustment">port_adjustment</property>
-                <property name="numeric">True</property>
-                <signal name="populate-popup" handler="pidgin_proxy_options_ports_popup_cb" object="PidginProxyOptions" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
             <property name="spacing">6</property>
             <child>
-              <object class="GtkLabel" id="username_label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">_Username:</property>
-                <property name="use-underline">True</property>
-                <property name="mnemonic-widget">username</property>
+              <object class="GtkLabel" id="port_label">
+                <property name="label" translatable="1">_Port:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">port</property>
                 <property name="xalign">0</property>
-                <property name="yalign">0.5</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkEntry" id="username">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
+              <object class="GtkSpinButton" id="port">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="focusable">1</property>
+                <property name="adjustment">port_adjustment</property>
+                <property name="numeric">1</property>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
         </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="username_label">
+                <property name="label" translatable="1">_Username:</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">username</property>
+                <property name="xalign">0</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkEntry" id="username">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="focusable">1</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
             <property name="spacing">6</property>
             <child>
               <object class="GtkLabel" id="password_label">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="label" translatable="yes">Pa_ssword:</property>
-                <property name="use-underline">True</property>
+                <property name="label" translatable="1">Pa_ssword:</property>
+                <property name="use-underline">1</property>
                 <property name="mnemonic-widget">password</property>
                 <property name="xalign">0</property>
-                <property name="yalign">0.5</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
-              <object class="GtkEntry" id="password">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
+              <object class="GtkPasswordEntry" id="password">
+                <property name="hexpand">1</property>
+                <property name="halign">fill</property>
+                <property name="focusable">1</property>
+                <property name="show-peek-icon">1</property>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">3</property>
-          </packing>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">1</property>
-      </packing>
     </child>
   </template>
   <object class="GtkSizeGroup">
@@ -313,4 +201,22 @@
       <widget name="password_label"/>
     </widgets>
   </object>
+  <menu id="extra">
+    <item>
+      <!-- TRANSLATORS: This is an easter egg.
+           It means one of two things, both intended as humorous:
+           A) your network is really slow and you have nothing better to do than look at butterflies.
+           B) You are looking really closely at something that shouldn't matter.
+      -->
+      <attribute name="label" translatable="yes">If you look real closely</attribute>
+    </item>
+    <item>
+      <!-- TRANSLATORS: This is an easter egg.
+           It means one of two things, both intended as humorous:
+           A) your network is really slow and you have nothing better to do than look at butterflies.
+           B) You are looking really closely at something that shouldn't matter.
+      -->
+      <attribute name="label" translatable="yes">you can see the butterflies mating</attribute>
+    </item>
+  </menu>
 </interface>
--- a/pidgin/resources/statusprimitivechooser.ui	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/resources/statusprimitivechooser.ui	Sun Aug 28 22:18:46 2022 -0500
@@ -19,14 +19,12 @@
 
 -->
 <interface>
-  <requires lib="gtk+" version="3.24"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
   <template class="PidginStatusPrimitiveChooser" parent="GtkComboBox">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
     <property name="id-column">0</property>
     <child>
       <object class="GtkCellRendererPixbuf"/>
--- a/pidgin/win32/gtkwin32dep.c	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/win32/gtkwin32dep.c	Sun Aug 28 22:18:46 2022 -0500
@@ -34,7 +34,6 @@
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <gtk/gtk.h>
-#include <gdk/gdkwin32.h>
 
 #include <purple.h>
 
@@ -132,39 +131,6 @@
 	return 1;
 }
 
-void winpidgin_shell_execute(const char *target, const char *verb, const char *clazz) {
-
-	SHELLEXECUTEINFOW wsinfo;
-	wchar_t *w_uri, *w_verb, *w_clazz = NULL;
-
-	g_return_if_fail(target != NULL);
-	g_return_if_fail(verb != NULL);
-
-	w_uri = g_utf8_to_utf16(target, -1, NULL, NULL, NULL);
-	w_verb = g_utf8_to_utf16(verb, -1, NULL, NULL, NULL);
-
-	memset(&wsinfo, 0, sizeof(wsinfo));
-	wsinfo.cbSize = sizeof(wsinfo);
-	wsinfo.lpVerb = w_verb;
-	wsinfo.lpFile = w_uri;
-	wsinfo.nShow = SW_SHOWNORMAL;
-	wsinfo.fMask |= SEE_MASK_FLAG_NO_UI;
-	if (clazz != NULL) {
-		w_clazz = g_utf8_to_utf16(clazz, -1, NULL, NULL, NULL);
-		wsinfo.fMask |= SEE_MASK_CLASSNAME;
-		wsinfo.lpClass = w_clazz;
-	}
-
-	if(!ShellExecuteExW(&wsinfo))
-		purple_debug_error("winpidgin", "Error opening URI: %s error: %d\n",
-			target, (int) wsinfo.hInstApp);
-
-	g_free(w_uri);
-	g_free(w_verb);
-	g_free(w_clazz);
-
-}
-
 #define PIDGIN_WM_FOCUS_REQUEST (WM_APP + 13)
 #define PIDGIN_WM_PROTOCOL_HANDLE (WM_APP + 14)
 
@@ -300,9 +266,6 @@
 		g_free(locale_debug_dir);
 	}
 
-	purple_debug_info("winpidgin", "GTK: %u.%u.%u\n",
-		gtk_major_version, gtk_minor_version, gtk_micro_version);
-
 	messagewin_hwnd = winpidgin_message_window_init();
 
 	if (purple_debug_is_verbose())
@@ -327,135 +290,12 @@
 	return TRUE;
 }
 
-static gboolean
-get_WorkingAreaRectForWindow(HWND hwnd, RECT *workingAreaRc) {
-
-	HMONITOR monitor;
-	MONITORINFO info;
-
-	monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
-
-	info.cbSize = sizeof(info);
-	if(!GetMonitorInfo(monitor, &info))
-		return FALSE;
-
-	CopyRect(workingAreaRc, &(info.rcWork));
-	return TRUE;
-}
-
 typedef HRESULT (WINAPI* DwmIsCompositionEnabledFunction)(BOOL*);
 typedef HRESULT (WINAPI* DwmGetWindowAttributeFunction)(HWND, DWORD, PVOID, DWORD);
-static HMODULE dwmapi_module = NULL;
-static DwmIsCompositionEnabledFunction DwmIsCompositionEnabled = NULL;
-static DwmGetWindowAttributeFunction DwmGetWindowAttribute = NULL;
 #ifndef DWMWA_EXTENDED_FRAME_BOUNDS
 #	define DWMWA_EXTENDED_FRAME_BOUNDS 9
 #endif
 
-static void
-get_actualWindowRect(HWND hwnd, RECT *winR)
-{
-	GetWindowRect(hwnd, winR);
-
-	if (dwmapi_module == NULL) {
-		dwmapi_module = GetModuleHandleW(L"dwmapi.dll");
-		if (dwmapi_module != NULL) {
-			DwmIsCompositionEnabled = (DwmIsCompositionEnabledFunction) GetProcAddress(dwmapi_module, "DwmIsCompositionEnabled");
-			DwmGetWindowAttribute = (DwmGetWindowAttributeFunction) GetProcAddress(dwmapi_module, "DwmGetWindowAttribute");
-		}
-	}
-
-	if (DwmIsCompositionEnabled != NULL && DwmGetWindowAttribute != NULL) {
-		BOOL pfEnabled;
-		if (SUCCEEDED(DwmIsCompositionEnabled(&pfEnabled))) {
-			RECT tempR;
-			if (SUCCEEDED(DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &tempR, sizeof(tempR)))) {
-				*winR = tempR;
-			}
-		}
-	}
-}
-
-void winpidgin_ensure_onscreen(GtkWidget *win) {
-	RECT winR, wAR, intR;
-	HWND hwnd = GDK_WINDOW_HWND(gtk_widget_get_window(win));
-
-	g_return_if_fail(hwnd != NULL);
-	get_actualWindowRect(hwnd, &winR);
-
-	purple_debug_info("win32placement",
-			"Window RECT: L:%ld R:%ld T:%ld B:%ld\n",
-			winR.left, winR.right,
-			winR.top, winR.bottom);
-
-	if(!get_WorkingAreaRectForWindow(hwnd, &wAR)) {
-		purple_debug_info("win32placement",
-				"Couldn't get multimonitor working area\n");
-		if(!SystemParametersInfo(SPI_GETWORKAREA, 0, &wAR, FALSE)) {
-			/* I don't think this will ever happen */
-			wAR.left = 0;
-			wAR.top = 0;
-			wAR.bottom = GetSystemMetrics(SM_CYSCREEN);
-			wAR.right = GetSystemMetrics(SM_CXSCREEN);
-		}
-	}
-
-	purple_debug_info("win32placement",
-			"Working Area RECT: L:%ld R:%ld T:%ld B:%ld\n",
-			wAR.left, wAR.right,
-			wAR.top, wAR.bottom);
-
-	/** If the conversation window doesn't intersect perfectly, move it to do so */
-	if(!(IntersectRect(&intR, &winR, &wAR)
-				&& EqualRect(&intR, &winR))) {
-		purple_debug_info("win32placement",
-				"conversation window out of working area, relocating\n");
-
-		/* Make sure the working area is big enough. */
-		if ((winR.right - winR.left) <= (wAR.right - wAR.left)
-				&& (winR.bottom - winR.top) <= (wAR.bottom - wAR.top)) {
-			/* Is it off the bottom? */
-			if (winR.bottom > wAR.bottom) {
-				winR.top = wAR.bottom - (winR.bottom - winR.top);
-				winR.bottom = wAR.bottom;
-			}
-			/* Is it off the top? */
-			else if (winR.top < wAR.top) {
-				winR.bottom = wAR.top + (winR.bottom - winR.top);
-				winR.top = wAR.top;
-			}
-
-			/* Is it off the left? */
-			if (winR.left < wAR.left) {
-				winR.right = wAR.left + (winR.right - winR.left);
-				winR.left = wAR.left;
-			}
-			/* Is it off the right? */
-			else  if (winR.right > wAR.right) {
-				winR.left = wAR.right - (winR.right - winR.left);
-				winR.right = wAR.right;
-			}
-
-		} else {
- 			/* We couldn't salvage it; move it to the top left corner of the working area */
- 			winR.right = wAR.left + (winR.right - winR.left);
- 			winR.bottom = wAR.top + (winR.bottom - winR.top);
- 			winR.left = wAR.left;
- 			winR.top = wAR.top;
-		}
-
-		purple_debug_info("win32placement",
-			"Relocation RECT: L:%ld R:%ld T:%ld B:%ld\n",
-			winR.left, winR.right,
-			winR.top, winR.bottom);
-
-		MoveWindow(hwnd, winR.left, winR.top,
-				   (winR.right - winR.left),
-				   (winR.bottom - winR.top), TRUE);
-	}
-
-}
-
 DWORD winpidgin_get_lastactive() {
 	DWORD result = 0;
 
--- a/pidgin/win32/gtkwin32dep.h	Tue Aug 23 01:09:33 2022 -0500
+++ b/pidgin/win32/gtkwin32dep.h	Sun Aug 28 22:18:46 2022 -0500
@@ -36,8 +36,6 @@
 int winpidgin_gz_untar(const char* filename, const char* destdir);
 
 /* Misc */
-void winpidgin_shell_execute(const char *target, const char *verb, const char *clazz);
-void winpidgin_ensure_onscreen(GtkWidget *win);
 DWORD winpidgin_get_lastactive(void);
 
 /* init / cleanup */
--- a/po/POTFILES.in	Tue Aug 23 01:09:33 2022 -0500
+++ b/po/POTFILES.in	Sun Aug 28 22:18:46 2022 -0500
@@ -373,7 +373,6 @@
 pidgin/pidginstatusmanager.c
 pidgin/pidginstatusprimitivechooser.c
 pidgin/pidginstatusprimitivestore.c
-pidgin/pidginstylecontext.c
 pidgin/pidgintalkatu.c
 pidgin/plugins/disco/gtkdisco.c
 pidgin/plugins/disco/resources/disco.ui
@@ -407,14 +406,11 @@
 pidgin/resources/Conversations/invite_dialog.ui
 pidgin/resources/Conversations/window.ui
 pidgin/resources/Debug/debug.ui
-pidgin/resources/Debug/plugininfo.ui
 pidgin/resources/Dialogs/addbuddy.ui
 pidgin/resources/Dialogs/addchat.ui
 pidgin/resources/Keypad/keypad.ui
-pidgin/resources/Log/log-viewer.ui
 pidgin/resources/Media/window.ui
 pidgin/resources/Plugins/dialog.ui
-pidgin/resources/Plugins/menu.ui
 pidgin/resources/Prefs/away.ui
 pidgin/resources/Prefs/credentialprovider.ui
 pidgin/resources/Prefs/credentials.ui
--- a/subprojects/talkatu.wrap	Tue Aug 23 01:09:33 2022 -0500
+++ b/subprojects/talkatu.wrap	Sun Aug 28 22:18:46 2022 -0500
@@ -1,4 +1,4 @@
 [wrap-hg]
 directory = talkatu
 url = https://keep.imfreedom.org/talkatu/talkatu
-revision = default
+revision = gtk4

mercurial