# HG changeset patch
# Node ID 32245f3910b9
# Parent  58859eada745
diff --git a/pidgin/meson.build b/pidgin/meson.build
--- a/pidgin/meson.build
+++ b/pidgin/meson.build
@@ -64,6 +64,7 @@ libpidgin_SOURCES = [
 	'prefs/pidgincredentialproviderrow.c',
 	'prefs/pidgincredentialspage.c',
 	'prefs/pidginnetworkpage.c',
+	'prefs/pidginproxyprefs.c',
 ]
 
 libpidgin_headers = [
@@ -134,6 +135,7 @@ libpidgin_prefs_headers = [
 	'prefs/pidgincredentialproviderrow.h',
 	'prefs/pidgincredentialspage.h',
 	'prefs/pidginnetworkpage.h',
+	'prefs/pidginproxyprefs.h',
 ]
 
 libpidgin_enum_headers = [
diff --git a/pidgin/prefs/pidginprefs.c b/pidgin/prefs/pidginprefs.c
--- a/pidgin/prefs/pidginprefs.c
+++ b/pidgin/prefs/pidginprefs.c
@@ -752,124 +752,6 @@ bind_conv_page(PidginPrefsWindow *win)
 	                       G_CALLBACK(formatting_toggle_cb), NULL);
 }
 
-static void
-proxy_changed_cb(const char *name, PurplePrefType type,
-				 gconstpointer value, gpointer data)
-{
-	PidginPrefsWindow *win = data;
-	const char *proxy = value;
-
-	if (!purple_strequal(proxy, "none") && !purple_strequal(proxy, "envvar"))
-		gtk_widget_show_all(win->proxy.options);
-	else
-		gtk_widget_hide(win->proxy.options);
-}
-
-static void
-proxy_print_option(GtkWidget *entry, PidginPrefsWindow *win)
-{
-	if (entry == win->proxy.host) {
-		purple_prefs_set_string("/purple/proxy/host",
-				gtk_entry_get_text(GTK_ENTRY(entry)));
-	} else if (entry == win->proxy.port) {
-		purple_prefs_set_int("/purple/proxy/port",
-				gtk_spin_button_get_value_as_int(
-					GTK_SPIN_BUTTON(entry)));
-	} else if (entry == win->proxy.username) {
-		purple_prefs_set_string("/purple/proxy/username",
-				gtk_entry_get_text(GTK_ENTRY(entry)));
-	} else if (entry == win->proxy.password) {
-		purple_prefs_set_string("/purple/proxy/password",
-				gtk_entry_get_text(GTK_ENTRY(entry)));
-	}
-}
-
-static void
-proxy_button_clicked_cb(GtkWidget *button, PidginPrefsWindow *win)
-{
-	GError *err = NULL;
-
-	if (g_spawn_command_line_async(win->proxy.gnome_program_path, &err))
-		return;
-
-	purple_notify_error(NULL, NULL, _("Cannot start proxy configuration program."), err->message, NULL);
-	g_error_free(err);
-}
-
-static void
-bind_proxy_page(PidginPrefsWindow *win)
-{
-	PurpleProxyInfo *proxy_info;
-
-	if(purple_running_gnome()) {
-		gchar *path = NULL;
-
-		gtk_stack_set_visible_child_name(GTK_STACK(win->proxy.stack),
-				"gnome");
-
-		path = g_find_program_in_path("gnome-network-properties");
-		if (path == NULL)
-			path = g_find_program_in_path("gnome-network-preferences");
-		if (path == NULL) {
-			path = g_find_program_in_path("gnome-control-center");
-			if (path != NULL) {
-				char *tmp = g_strdup_printf("%s network", path);
-				g_free(path);
-				path = tmp;
-			}
-		}
-
-		win->proxy.gnome_program_path = path;
-		gtk_widget_set_visible(win->proxy.gnome_not_found,
-				path == NULL);
-		gtk_widget_set_visible(win->proxy.gnome_program,
-				path != NULL);
-	} else {
-		gtk_stack_set_visible_child_name(GTK_STACK(win->proxy.stack),
-				"nongnome");
-
-		/* This is a global option that affects SOCKS4 usage even with
-		 * account-specific proxy settings */
-		pidgin_prefs_bind_checkbox("/purple/proxy/socks4_remotedns",
-				win->proxy.socks4_remotedns);
-
-		win->proxy.type.type = PURPLE_PREF_STRING;
-		win->proxy.type.key = "/purple/proxy/type";
-		pidgin_prefs_bind_dropdown(&win->proxy.type);
-		proxy_info = purple_global_proxy_get_info();
-
-		purple_prefs_connect_callback(prefs, "/purple/proxy/type",
-				proxy_changed_cb, win);
-
-		if (proxy_info != NULL) {
-			if (purple_proxy_info_get_hostname(proxy_info)) {
-				gtk_entry_set_text(GTK_ENTRY(win->proxy.host),
-						purple_proxy_info_get_hostname(proxy_info));
-			}
-
-			if (purple_proxy_info_get_port(proxy_info) != 0) {
-				gtk_spin_button_set_value(
-						GTK_SPIN_BUTTON(win->proxy.port),
-						purple_proxy_info_get_port(proxy_info));
-			}
-
-			if (purple_proxy_info_get_username(proxy_info) != NULL) {
-				gtk_entry_set_text(GTK_ENTRY(win->proxy.username),
-						purple_proxy_info_get_username(proxy_info));
-			}
-
-			if (purple_proxy_info_get_password(proxy_info) != NULL) {
-				gtk_entry_set_text(GTK_ENTRY(win->proxy.password),
-						purple_proxy_info_get_password(proxy_info));
-			}
-		}
-
-		proxy_changed_cb("/purple/proxy/type", PURPLE_PREF_STRING,
-			purple_prefs_get_string("/purple/proxy/type"),
-			win);
-	}
-}
-
 #ifdef USE_VV
 static GList *
 get_vv_device_menuitems(PurpleMediaElementType type)
@@ -1386,7 +1268,6 @@ prefs_stack_init(PidginPrefsWindow *win)
 #endif
 
 	bind_conv_page(win);
-	bind_proxy_page(win);
 #ifdef USE_VV
 	vv = vv_page(win);
 	gtk_container_add_with_properties(GTK_CONTAINER(stack), vv, "name",
@@ -1433,33 +1314,6 @@ pidgin_prefs_window_class_init(PidginPre
 	gtk_widget_class_bind_template_child(
 			widget_class, PidginPrefsWindow,
 			conversations.format_view);
-
-	/* Proxy page */
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.stack);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.gnome_not_found);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.gnome_program);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			proxy.socks4_remotedns);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.type.combo);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.options);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.host);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.port);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.username);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, proxy.password);
-	gtk_widget_class_bind_template_callback(widget_class,
-			proxy_button_clicked_cb);
-	gtk_widget_class_bind_template_callback(widget_class,
-			proxy_print_option);
 }
 
 static void
diff --git a/pidgin/prefs/pidginproxyprefs.h b/pidgin/prefs/pidginproxyprefs.h
new file mode 100644
--- /dev/null
+++ b/pidgin/prefs/pidginproxyprefs.h
@@ -0,0 +1,62 @@
+/*
+ * 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 program; 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_PROXY_PREFS_H
+#define PIDGIN_PROXY_PREFS_H
+
+#include <glib.h>
+
+#include <gtk/gtk.h>
+#include <handy.h>
+
+G_BEGIN_DECLS
+
+/**
+ * PidginProxyPrefs:
+ *
+ * #PidginProxyPrefs is a widget for the preferences window to let users
+ * choose and configure their proxy settings.
+ *
+ * Since: 3.0.0
+ */
+#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_new:
+ *
+ * Creates a new #PidginProxyPrefs instance.
+ *
+ * Returns: (transfer full): The new #PidginProxyPrefs instance.
+ *
+ * Since: 3.0.0
+ */
+GtkWidget *pidgin_proxy_prefs_new(void);
+
+G_END_DECLS
+
+#endif /* PIDGIN_PROXY_PREFS_H */
diff --git a/pidgin/prefs/pidginproxyprefs.c b/pidgin/prefs/pidginproxyprefs.c
new file mode 100644
--- /dev/null
+++ b/pidgin/prefs/pidginproxyprefs.c
@@ -0,0 +1,235 @@
+/*
+ * 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 program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n-lib.h>
+
+#include <purple.h>
+
+#include <handy.h>
+
+#include "pidginproxyprefs.h"
+#include "pidginprefsinternal.h"
+
+struct _PidginProxyPrefs {
+	HdyPreferencesPage parent;
+
+	GtkWidget *stack;
+	/* GNOME version */
+	GtkWidget *gnome_not_found;
+	GtkWidget *gnome_program;
+	gchar *gnome_program_path;
+	/* Non-GNOME version */
+	GtkWidget *socks4_remotedns;
+	PidginPrefCombo type;
+	GtkWidget *options;
+	GtkWidget *host;
+	GtkWidget *port;
+	GtkWidget *username;
+	GtkWidget *password;
+};
+
+G_DEFINE_TYPE(PidginProxyPrefs, pidgin_proxy_prefs, HDY_TYPE_PREFERENCES_PAGE)
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+proxy_changed_cb(const gchar *name, PurplePrefType type, gconstpointer value,
+                 gpointer data)
+{
+	PidginProxyPrefs *page = data;
+	const char *proxy = value;
+
+	if (!purple_strequal(proxy, "none") && !purple_strequal(proxy, "envvar")) {
+		gtk_widget_show_all(page->options);
+	} else {
+		gtk_widget_hide(page->options);
+	}
+}
+
+static void
+proxy_print_option(GtkWidget *entry, gpointer data)
+{
+	PidginProxyPrefs *page = data;
+
+	if (entry == page->host) {
+		purple_prefs_set_string("/purple/proxy/host",
+				gtk_entry_get_text(GTK_ENTRY(entry)));
+	} else if (entry == page->port) {
+		purple_prefs_set_int("/purple/proxy/port",
+				gtk_spin_button_get_value_as_int(
+					GTK_SPIN_BUTTON(entry)));
+	} else if (entry == page->username) {
+		purple_prefs_set_string("/purple/proxy/username",
+				gtk_entry_get_text(GTK_ENTRY(entry)));
+	} else if (entry == page->password) {
+		purple_prefs_set_string("/purple/proxy/password",
+				gtk_entry_get_text(GTK_ENTRY(entry)));
+	}
+}
+
+static void
+proxy_button_clicked_cb(GtkWidget *button, gpointer data)
+{
+	PidginProxyPrefs *page = data;
+	GError *err = NULL;
+
+	if (g_spawn_command_line_async(page->gnome_program_path, &err)) {
+		return;
+	}
+
+	purple_notify_error(NULL, NULL, _("Cannot start proxy configuration program."), err->message, NULL);
+	g_error_free(err);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+static void
+pidgin_proxy_prefs_finalize(GObject *obj)
+{
+	purple_prefs_disconnect_by_handle(obj);
+
+	G_OBJECT_CLASS(pidgin_proxy_prefs_parent_class)->finalize(obj);
+}
+
+static void
+pidgin_proxy_prefs_class_init(PidginProxyPrefsClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+	obj_class->finalize = pidgin_proxy_prefs_finalize;
+
+	gtk_widget_class_set_template_from_resource(
+		widget_class,
+		"/im/pidgin/Pidgin3/Prefs/proxy.ui"
+	);
+
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginProxyPrefs, stack);
+	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, socks4_remotedns);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginProxyPrefs, type.combo);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginProxyPrefs, options);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginProxyPrefs, host);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginProxyPrefs, port);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginProxyPrefs, username);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginProxyPrefs, password);
+	gtk_widget_class_bind_template_callback(widget_class,
+			proxy_button_clicked_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+			proxy_print_option);
+}
+
+static void
+pidgin_proxy_prefs_init(PidginProxyPrefs *page)
+{
+	PurpleProxyInfo *proxy_info;
+
+	gtk_widget_init_template(GTK_WIDGET(page));
+
+	if(purple_running_gnome()) {
+		gchar *path = NULL;
+
+		gtk_stack_set_visible_child_name(GTK_STACK(page->stack),
+				"gnome");
+
+		path = g_find_program_in_path("gnome-network-properties");
+		if (path == NULL) {
+			path = g_find_program_in_path("gnome-network-preferences");
+		}
+		if (path == NULL) {
+			path = g_find_program_in_path("gnome-control-center");
+			if (path != NULL) {
+				char *tmp = g_strdup_printf("%s network", path);
+				g_free(path);
+				path = tmp;
+			}
+		}
+
+		page->gnome_program_path = path;
+		gtk_widget_set_visible(page->gnome_not_found, path == NULL);
+		gtk_widget_set_visible(page->gnome_program, path != NULL);
+	} else {
+		gtk_stack_set_visible_child_name(GTK_STACK(page->stack),
+				"nongnome");
+
+		/* This is a global option that affects SOCKS4 usage even with
+		 * account-specific proxy settings */
+		pidgin_prefs_bind_checkbox("/purple/proxy/socks4_remotedns",
+				page->socks4_remotedns);
+
+		page->type.type = PURPLE_PREF_STRING;
+		page->type.key = "/purple/proxy/type";
+		pidgin_prefs_bind_dropdown(&page->type);
+		proxy_info = purple_global_proxy_get_info();
+
+		purple_prefs_connect_callback(page, "/purple/proxy/type",
+				proxy_changed_cb, page);
+
+		if (proxy_info != NULL) {
+			if (purple_proxy_info_get_hostname(proxy_info)) {
+				gtk_entry_set_text(GTK_ENTRY(page->host),
+						purple_proxy_info_get_hostname(proxy_info));
+			}
+
+			if (purple_proxy_info_get_port(proxy_info) != 0) {
+				gtk_spin_button_set_value(
+						GTK_SPIN_BUTTON(page->port),
+						purple_proxy_info_get_port(proxy_info));
+			}
+
+			if (purple_proxy_info_get_username(proxy_info) != NULL) {
+				gtk_entry_set_text(GTK_ENTRY(page->username),
+						purple_proxy_info_get_username(proxy_info));
+			}
+
+			if (purple_proxy_info_get_password(proxy_info) != NULL) {
+				gtk_entry_set_text(GTK_ENTRY(page->password),
+						purple_proxy_info_get_password(proxy_info));
+			}
+		}
+
+		proxy_changed_cb("/purple/proxy/type", PURPLE_PREF_STRING,
+			purple_prefs_get_string("/purple/proxy/type"),
+			page);
+	}
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GtkWidget *
+pidgin_proxy_prefs_new(void) {
+	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_PROXY_PREFS, NULL));
+}
diff --git a/pidgin/resources/Prefs/prefs.ui b/pidgin/resources/Prefs/prefs.ui
--- a/pidgin/resources/Prefs/prefs.ui
+++ b/pidgin/resources/Prefs/prefs.ui
@@ -384,327 +384,9 @@ Foundation, Inc., 51 Franklin Street, Fi
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkBox" id="proxy.page">
+                  <object class="PidginProxyPrefs">
                     <property name="visible">True</property>
                     <property name="can-focus">False</property>
-                    <property name="border-width">12</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">18</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>
-                          <object class="GtkAlignment">
-                            <property name="visible">True</property>
-                            <property name="can-focus">False</property>
-                            <property name="left-padding">12</property>
-                            <child>
-                              <object class="GtkStack" id="proxy.stack">
-                                <property name="visible">True</property>
-                                <property name="can-focus">False</property>
-                                <property name="hhomogeneous">False</property>
-                                <property name="vhomogeneous">False</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="proxy.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="proxy.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="PidginPrefsWindow" 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>
-                                  <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="proxy.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>
-                                      <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">proxy.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="proxy.type.combo">
-                                            <property name="visible">True</property>
-                                            <property name="can-focus">False</property>
-                                            <property name="model">proxy.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="proxy.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">proxy.host</property>
-                                            <property name="xalign">1</property>
-                                            <accessibility>
-                                              <relation type="label-for" target="proxy.host"/>
-                                            </accessibility>
-                                          </object>
-                                          <packing>
-                                            <property name="left-attach">0</property>
-                                            <property name="top-attach">0</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkEntry" id="proxy.host">
-                                            <property name="visible">True</property>
-                                            <property name="can-focus">True</property>
-                                            <signal name="changed" handler="proxy_print_option" object="PidginPrefsWindow" 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="proxy.port"/>
-                                            </accessibility>
-                                          </object>
-                                          <packing>
-                                            <property name="left-attach">2</property>
-                                            <property name="top-attach">0</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkSpinButton" id="proxy.port">
-                                            <property name="visible">True</property>
-                                            <property name="can-focus">True</property>
-                                            <property name="text" translatable="yes">0</property>
-                                            <property name="adjustment">proxy.port.adjustment</property>
-                                            <property name="numeric">True</property>
-                                            <signal name="changed" handler="proxy_print_option" object="PidginPrefsWindow" 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">proxy.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="proxy.username">
-                                            <property name="visible">True</property>
-                                            <property name="can-focus">True</property>
-                                            <signal name="changed" handler="proxy_print_option" object="PidginPrefsWindow" 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">proxy.password</property>
-                                            <property name="xalign">1</property>
-                                            <accessibility>
-                                              <relation type="label-for" target="proxy.password"/>
-                                            </accessibility>
-                                          </object>
-                                          <packing>
-                                            <property name="left-attach">2</property>
-                                            <property name="top-attach">1</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkEntry" id="proxy.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="PidginPrefsWindow" 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>
-                                      <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>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">True</property>
-                            <property name="can-focus">False</property>
-                            <property name="label" translatable="yes">Proxy Server</property>
-                            <attributes>
-                              <attribute name="weight" value="bold"/>
-                            </attributes>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
                   </object>
                   <packing>
                     <property name="name">proxy</property>
diff --git a/pidgin/resources/Prefs/proxy.ui b/pidgin/resources/Prefs/proxy.ui
new file mode 100644
--- /dev/null
+++ b/pidgin/resources/Prefs/proxy.ui
@@ -0,0 +1,374 @@
+<?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, see <https://www.gnu.org/licenses/>.
+
+-->
+<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> -->
+  <object class="GtkAdjustment" id="port.adjustment">
+    <property name="upper">65535</property>
+    <property name="step-increment">1</property>
+    <property name="page-increment">10</property>
+  </object>
+  <object class="GtkListStore" id="type.store">
+    <columns>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name value -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">No proxy</col>
+        <col id="1">none</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">SOCKS 4</col>
+        <col id="1">socks4</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">SOCKS 5</col>
+        <col id="1">socks5</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Tor/Privacy (SOCKS 5)</col>
+        <col id="1">tor</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">HTTP</col>
+        <col id="1">http</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Use Environmental Settings</col>
+        <col id="1">envvar</col>
+      </row>
+    </data>
+  </object>
+  <template class="PidginProxyPrefs" parent="HdyPreferencesPage">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <child>
+      <object class="HdyPreferencesGroup">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="title" translatable="yes">Proxy Server</property>
+        <child>
+          <object class="GtkAlignment">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="left-padding">12</property>
+            <child>
+              <object class="GtkStack" id="stack">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="hhomogeneous">False</property>
+                <property name="vhomogeneous">False</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>
+                  <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>
+                      <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>
+                      <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>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </template>
+</interface>
diff --git a/pidgin/resources/pidgin.gresource.xml b/pidgin/resources/pidgin.gresource.xml
--- a/pidgin/resources/pidgin.gresource.xml
+++ b/pidgin/resources/pidgin.gresource.xml
@@ -29,6 +29,7 @@
     <file compressed="true">Prefs/ip.css</file>
     <file compressed="true">Prefs/network.ui</file>
     <file compressed="true">Prefs/prefs.ui</file>
+    <file compressed="true">Prefs/proxy.ui</file>
     <file compressed="true">Prefs/vv.ui</file>
     <file compressed="true">Privacy/dialog.ui</file>
     <file compressed="true">Protocols/chooser.ui</file>
diff --git a/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -393,6 +393,7 @@ pidgin/prefs/pidgincredentialproviderrow
 pidgin/prefs/pidgincredentialspage.c
 pidgin/prefs/pidginnetworkpage.c
 pidgin/prefs/pidginprefs.c
+pidgin/prefs/pidginproxypage.c
 pidgin/resources/About/about.ui
 pidgin/resources/Accounts/actionsmenu.ui
 pidgin/resources/Accounts/chooser.ui
@@ -415,6 +416,7 @@ pidgin/resources/Prefs/credentialprovide
 pidgin/resources/Prefs/credentials.ui
 pidgin/resources/Prefs/network.ui
 pidgin/resources/Prefs/prefs.ui
+pidgin/resources/Prefs/proxy.ui
 pidgin/resources/Prefs/vv.ui
 pidgin/resources/Privacy/dialog.ui
 pidgin/resources/Protocols/chooser.ui
