# HG changeset patch
# Node ID 46c68d8a7c56
# Parent  5a506dee26d2
diff --git a/libpurple/debug.c b/libpurple/debug.c
--- a/libpurple/debug.c
+++ b/libpurple/debug.c
@@ -169,6 +169,4 @@ purple_debug_init(void) {
 	if(g_getenv("PURPLE_VERBOSE_DEBUG")) {
 		purple_debug_set_verbose(TRUE);
 	}
-
-	purple_prefs_add_none("/purple/debug");
 }
diff --git a/pidgin/data/gschema/im.pidgin.Pidgin3.Debug.gschema.xml b/pidgin/data/gschema/im.pidgin.Pidgin3.Debug.gschema.xml
new file mode 100644
--- /dev/null
+++ b/pidgin/data/gschema/im.pidgin.Pidgin3.Debug.gschema.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schemalist>
+  <enum id="im.pidgin.Pidgin3.Debug.Level">
+    <value nick="all" value="0"/>
+    <value nick="misc" value="1"/>
+    <value nick="info" value="2"/>
+    <value nick="warning" value="3"/>
+    <value nick="error" value="4"/>
+    <value nick="fatal" value="5"/>
+  </enum>
+
+  <schema path="/pidgin3/debug/" id="im.pidgin.Pidgin3.Debug">
+    <key name="visible" type="b">
+      <default>false</default>
+      <summary>Show debug window</summary>
+      <description>
+        Whether to display the debug window at startup.
+      </description>
+    </key>
+
+    <key name="width" type="i">
+      <default>450</default>
+      <summary>Debug window width</summary>
+      <description>
+        The width of the Debug Window.
+      </description>
+    </key>
+
+    <key name="height" type="i">
+      <default>250</default>
+      <summary>Debug window height</summary>
+      <description>
+        The height of the Debug Window.
+      </description>
+    </key>
+
+    <key name="active" type="b">
+      <default>false</default>
+      <summary>Filter messages</summary>
+      <description>
+        Whether to filter message in the debug window.
+      </description>
+    </key>
+
+    <key name="filterlevel" enum="im.pidgin.Pidgin3.Debug.Level">
+      <default>"all"</default>
+      <summary>Message level filter</summary>
+      <description>
+        The minimum debug message level to display.
+      </description>
+    </key>
+
+    <key name="regex" type="s">
+      <default>""</default>
+      <summary>Filter regular expression</summary>
+      <description>
+        The regular expression to use to filter the debug window.
+      </description>
+    </key>
+
+    <key name="invert" type="b">
+      <default>false</default>
+      <summary>Invert filter</summary>
+      <description>
+        Whether to invert the message filter.
+      </description>
+    </key>
+
+    <key name="case-insensitive" type="b">
+      <default>false</default>
+      <summary>Case insensitive filter</summary>
+      <description>
+        Whether to ignore letter case in the message filter.
+      </description>
+    </key>
+
+    <key name="highlight" type="b">
+      <default>false</default>
+      <summary>Highlight matches</summary>
+      <description>
+        Whether to highlight matches from the message filter.
+      </description>
+    </key>
+  </schema>
+</schemalist>
diff --git a/pidgin/data/gschema/meson.build b/pidgin/data/gschema/meson.build
new file mode 100644
--- /dev/null
+++ b/pidgin/data/gschema/meson.build
@@ -0,0 +1,11 @@
+schemas_dir = get_option('datadir') / 'glib-2.0' / 'schemas'
+settings_schemas = [
+    'im.pidgin.Pidgin3.Debug.gschema.xml',
+]
+
+install_data(settings_schemas, install_dir: schemas_dir)
+gnome.post_install(glib_compile_schemas: true)
+
+# Compile the schemas in the current directory; this is only useful for testing
+pidgin_schemas = [gnome.compile_schemas(depend_files: files(settings_schemas))]
+testenv.prepend('GSETTINGS_SCHEMA_DIR', meson.current_build_dir())
diff --git a/pidgin/data/meson.build b/pidgin/data/meson.build
--- a/pidgin/data/meson.build
+++ b/pidgin/data/meson.build
@@ -1,3 +1,4 @@
+subdir('gschema')
 subdir('icons')
 
 devenv.prepend('XDG_DATA_DIRS', meson.current_source_dir())
diff --git a/pidgin/pidginapplication.c b/pidgin/pidginapplication.c
--- a/pidgin/pidginapplication.c
+++ b/pidgin/pidginapplication.c
@@ -348,8 +348,12 @@ pidgin_application_debug(G_GNUC_UNUSED G
                          G_GNUC_UNUSED GVariant *parameter,
                          G_GNUC_UNUSED gpointer data)
 {
-	gboolean old = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/enabled");
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/enabled", !old);
+	GSettings *settings = NULL;
+	gboolean old = FALSE;
+
+	settings = pidgin_debug_get_settings();
+	old = g_settings_get_boolean(settings, "visible");
+	g_settings_set_boolean(settings, "visible", !old);
 }
 
 
@@ -731,6 +735,7 @@ pidgin_application_window_added(GtkAppli
 static void
 pidgin_application_startup(GApplication *application) {
 	PurpleAccountManager *manager = NULL;
+	GSettings *debug_settings = NULL;
 	GError *error = NULL;
 	GList *active_accounts = NULL;
 	gboolean online = FALSE;
@@ -797,7 +802,8 @@ pidgin_application_startup(GApplication 
 
 	g_clear_pointer(&opt_config_dir_arg, g_free);
 
-	if(purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/enabled")) {
+	debug_settings = pidgin_debug_get_settings();
+	if(g_settings_get_boolean(debug_settings, "visible")) {
 		pidgin_debug_window_show();
 	}
 
diff --git a/pidgin/pidgindebug.c b/pidgin/pidgindebug.c
--- a/pidgin/pidgindebug.c
+++ b/pidgin/pidgindebug.c
@@ -59,8 +59,6 @@ struct _PidginDebugWindow {
 	GtkWidget *popover;
 	GtkWidget *popover_invert;
 	GtkWidget *popover_highlight;
-	gboolean invert;
-	gboolean highlight;
 	GRegex *regex;
 };
 
@@ -72,27 +70,13 @@ typedef struct {
 } PidginDebugMessage;
 
 static gboolean debug_print_enabled = FALSE;
+static GSettings *settings = NULL;
 static PidginDebugWindow *debug_win = NULL;
-static guint pref_callback_id = 0;
-static guint debug_enabled_timer = 0;
+static gulong pref_callback_id = 0;
 
 G_DEFINE_FINAL_TYPE(PidginDebugWindow, pidgin_debug_window, GTK_TYPE_WINDOW)
 
 static gboolean
-save_default_size_cb(GObject *gobject, G_GNUC_UNUSED GParamSpec *pspec,
-                     G_GNUC_UNUSED gpointer data)
-{
-	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;
-}
-
-static gboolean
 view_near_bottom(PidginDebugWindow *win)
 {
 	GtkAdjustment *adj = gtk_scrollable_get_vadjustment(
@@ -224,6 +208,7 @@ regex_change_color(GtkWidget *w, gboolea
 static void
 do_regex(PidginDebugWindow *win, GtkTextIter *start, GtkTextIter *end)
 {
+	gboolean highlight, invert;
 	GMatchInfo *match;
 	gint initial_position;
 	gint start_pos, end_pos;
@@ -234,9 +219,12 @@ do_regex(PidginDebugWindow *win, GtkText
 		return;
 	}
 
+	highlight = g_settings_get_boolean(settings, "highlight");
+	invert = g_settings_get_boolean(settings, "invert");
+
 	initial_position = gtk_text_iter_get_offset(start);
 
-	if (!win->invert) {
+	if(!invert) {
 		/* First hide everything. */
 		gtk_text_buffer_apply_tag(win->buffer,
 				win->tags.filtered_invisible, start, end);
@@ -257,7 +245,7 @@ do_regex(PidginDebugWindow *win, GtkText
 				&match_end, end_pos);
 		gtk_text_iter_forward_line(&match_end);
 
-		if (win->invert) {
+		if(invert) {
 			/* Make invisible. */
 			gtk_text_buffer_apply_tag(win->buffer,
 					win->tags.filtered_invisible,
@@ -268,7 +256,7 @@ do_regex(PidginDebugWindow *win, GtkText
 					win->tags.filtered_visible,
 					&match_start, &match_end);
 
-			if (win->highlight) {
+			if(highlight) {
 				gtk_text_buffer_get_iter_at_offset(
 						win->buffer,
 						&match_start,
@@ -309,54 +297,6 @@ regex_toggle_filter(PidginDebugWindow *w
 }
 
 static void
-regex_pref_filter_cb(G_GNUC_UNUSED const gchar *name,
-                     G_GNUC_UNUSED PurplePrefType type,
-					 gconstpointer val, gpointer data)
-{
-	PidginDebugWindow *win = (PidginDebugWindow *)data;
-	gboolean active = GPOINTER_TO_INT(val), current;
-
-	if (!win) {
-		return;
-	}
-
-	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
-regex_pref_invert_cb(G_GNUC_UNUSED const gchar *name,
-                     G_GNUC_UNUSED PurplePrefType type,
-					 gconstpointer val, gpointer data)
-{
-	PidginDebugWindow *win = (PidginDebugWindow *)data;
-	gboolean active = GPOINTER_TO_INT(val);
-
-	win->invert = active;
-
-	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win->filter))) {
-		regex_toggle_filter(win, TRUE);
-	}
-}
-
-static void
-regex_pref_highlight_cb(G_GNUC_UNUSED const gchar *name,
-                        G_GNUC_UNUSED PurplePrefType type,
-						gconstpointer val, gpointer data)
-{
-	PidginDebugWindow *win = (PidginDebugWindow *)data;
-	gboolean active = GPOINTER_TO_INT(val);
-
-	win->highlight = active;
-
-	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win->filter))) {
-		regex_toggle_filter(win, TRUE);
-	}
-}
-
-static void
 regex_changed_cb(G_GNUC_UNUSED GtkWidget *w, PidginDebugWindow *win) {
 	const gchar *text;
 
@@ -365,9 +305,8 @@ regex_changed_cb(G_GNUC_UNUSED GtkWidget
 	}
 
 	text = gtk_editable_get_text(GTK_EDITABLE(win->expression));
-	purple_prefs_set_string(PIDGIN_PREFS_ROOT "/debug/regex", text);
 
-	if (text == NULL || *text == '\0') {
+	if(purple_strempty(text)) {
 		regex_clear_color(win->expression);
 		gtk_widget_set_sensitive(win->filter, FALSE);
 		return;
@@ -409,20 +348,6 @@ regex_key_released_cb(G_GNUC_UNUSED GtkE
 }
 
 static void
-regex_menu_cb(GtkWidget *item, PidginDebugWindow *win)
-{
-	gboolean active;
-
-	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);
-	} else if (item == win->popover_invert) {
-		purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/invert", active);
-	}
-}
-
-static void
 regex_popup_cb(G_GNUC_UNUSED GtkGestureClick* self, G_GNUC_UNUSED gint n_press,
                gdouble x, gdouble y, gpointer data)
 {
@@ -434,18 +359,6 @@ regex_popup_cb(G_GNUC_UNUSED GtkGestureC
 }
 
 static void
-regex_filter_toggled_cb(GtkToggleButton *button, PidginDebugWindow *win)
-{
-	gboolean active;
-
-	active = gtk_toggle_button_get_active(button);
-
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/filter", active);
-
-	regex_toggle_filter(win, active);
-}
-
-static void
 debug_window_set_filter_level(PidginDebugWindow *win, int level)
 {
 	gboolean scroll;
@@ -466,23 +379,35 @@ debug_window_set_filter_level(PidginDebu
 }
 
 static void
-filter_level_pref_changed(G_GNUC_UNUSED const char *name,
-                          G_GNUC_UNUSED PurplePrefType type,
-                          gconstpointer value, gpointer data)
-{
-	PidginDebugWindow *win = data;
-	int level = GPOINTER_TO_INT(value);
-
-	debug_window_set_filter_level(win, level);
-}
-
-static void
 filter_level_changed_cb(GObject *obj, G_GNUC_UNUSED GParamSpec *pspec)
 {
 	GtkDropDown *dropdown = GTK_DROP_DOWN(obj);
 
-	purple_prefs_set_int(PIDGIN_PREFS_ROOT "/debug/filterlevel",
-	                     gtk_drop_down_get_selected(dropdown));
+	g_settings_set_enum(settings, "filterlevel",
+	                    gtk_drop_down_get_selected(dropdown));
+}
+
+static void
+pidgin_debug_settings_changed_cb(GSettings *settings, char *key, gpointer data)
+{
+	PidginDebugWindow *win = data;
+
+	if(purple_strequal(key, "active")) {
+		gboolean active = g_settings_get_boolean(settings, key);
+
+		regex_toggle_filter(win, active);
+
+	} else if(purple_strequal(key, "highlight") ||
+	          purple_strequal(key, "invert")) {
+		if(g_settings_get_boolean(settings, "active")) {
+			regex_toggle_filter(win, TRUE);
+		}
+
+	} else if(purple_strequal(key, "filterlevel")) {
+		int level = g_settings_get_enum(settings, key);
+
+		debug_window_set_filter_level(win, level);
+	}
 }
 
 static void
@@ -500,12 +425,10 @@ pidgin_debug_window_finalize(GObject *ob
 {
 	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_settings_set_boolean(settings, "visible", FALSE);
 
 	G_OBJECT_CLASS(pidgin_debug_window_parent_class)->finalize(object);
 }
@@ -565,11 +488,8 @@ pidgin_debug_window_class_init(PidginDeb
 	gtk_widget_class_bind_template_callback(widget_class, clear_cb);
 	gtk_widget_class_bind_template_callback(widget_class, pause_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
-			regex_filter_toggled_cb);
-	gtk_widget_class_bind_template_callback(widget_class,
 			regex_changed_cb);
 	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_released_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
@@ -579,63 +499,41 @@ pidgin_debug_window_class_init(PidginDeb
 static void
 pidgin_debug_window_init(PidginDebugWindow *win)
 {
-	gint width, height;
-	void *handle;
 	GtkTextIter end;
 
 	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");
-
-	purple_debug_info("pidgindebug", "Setting dimensions to %d, %d\n",
-					width, height);
-
-	gtk_window_set_default_size(GTK_WINDOW(win), width, height);
+	g_settings_bind(settings, "width", win, "default-width",
+	                G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind(settings, "height", win, "default-height",
+	                G_SETTINGS_BIND_DEFAULT);
 
-	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();
-
-	/* we purposely disable the toggle button here in case
-	 * /purple/gtk/debug/expression has an empty string.  If it does not have
-	 * an empty string, the change signal will get called and make the
-	 * toggle button sensitive.
+	/* We purposely disable the toggle button here in case the regex setting
+	 * has an empty string. If it does not have an empty string, the change
+	 * signal will get called and make the toggle button sensitive.
 	 */
 	gtk_widget_set_sensitive(win->filter, FALSE);
-	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 */
-	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");
-	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/invert",
-	                              regex_pref_invert_cb, win);
+	g_settings_bind(settings, "active", win->filter, "active",
+	                G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind(settings, "regex", win->expression, "text",
+	                G_SETTINGS_BIND_DEFAULT);
 
-	win->highlight = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/highlight");
-	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/highlight",
-	                              regex_pref_highlight_cb, win);
-
+	/* This setting doesn't use binding because the uint-typed "selected"
+	 * property, and the enum-typed setting don't have a mapping. Since we have
+	 * to do some processing in these cases, just use manual setting instead.
+	 */
 	gtk_drop_down_set_selected(GTK_DROP_DOWN(win->filterlevel),
-	                           purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"));
+	                           g_settings_get_enum(settings, "filterlevel"));
 
-	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/filterlevel",
-	                              filter_level_pref_changed, win);
+	g_settings_bind(settings, "invert", win->popover_invert, "active",
+	                G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind(settings, "highlight", win->popover_highlight, "active",
+	                G_SETTINGS_BIND_DEFAULT);
 
-	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);
+	g_signal_connect(settings, "changed",
+	                 G_CALLBACK(pidgin_debug_settings_changed_cb), win);
 
 	/* The *start* and *end* marks bound the beginning and end of an
 	   insertion, used for filtering. The *end* mark is also used for
@@ -648,35 +546,23 @@ pidgin_debug_window_init(PidginDebugWind
 
 	/* Set active filter level in textview */
 	debug_window_set_filter_level(win,
-			purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"));
+	                              g_settings_get_enum(settings, "filterlevel"));
 
 	clear_cb(NULL, win);
 }
 
-static gboolean
-debug_enabled_timeout_cb(gpointer data)
+static void
+debug_visible_cb(GSettings *settings, char *key, G_GNUC_UNUSED gpointer data)
 {
-	gboolean enabled = GPOINTER_TO_INT(data);
+	gboolean visible = g_settings_get_boolean(settings, key);
 
-	debug_enabled_timer = 0;
-
-	if (enabled) {
+	g_signal_handler_block(settings, pref_callback_id);
+	if(visible) {
 		pidgin_debug_window_show();
 	} else {
 		pidgin_debug_window_hide();
 	}
-
-	return FALSE;
-}
-
-static void
-debug_enabled_cb(G_GNUC_UNUSED const gchar *name,
-                 G_GNUC_UNUSED PurplePrefType type,
-                 gconstpointer value,
-                 G_GNUC_UNUSED gpointer data)
-{
-	debug_enabled_timer = g_timeout_add(0, debug_enabled_timeout_cb,
-	                                    (gpointer)value);
+	g_signal_handler_unblock(settings, pref_callback_id);
 }
 
 static gboolean
@@ -688,8 +574,7 @@ pidgin_debug_g_log_handler_cb(gpointer d
 	GtkTextIter end;
 	gboolean scroll;
 
-	if (debug_win == NULL ||
-			!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/enabled")) {
+	if(debug_win == NULL || !g_settings_get_boolean(settings, "visible")) {
 		/* The Debug Window may have been closed/disabled after the thread that
 		 * sent this message. */
 		g_date_time_unref(message->timestamp);
@@ -715,7 +600,7 @@ pidgin_debug_g_log_handler_cb(gpointer d
 			debug_win->paused ? debug_win->tags.paused : NULL,
 			NULL);
 
-	if (message->domain != NULL && *message->domain != '\0') {
+	if(!purple_strempty(message->domain)) {
 		gtk_text_buffer_insert_with_tags(
 				debug_win->buffer,
 				&end,
@@ -753,8 +638,7 @@ pidgin_debug_g_log_handler_cb(gpointer d
 			debug_win->paused ? debug_win->tags.paused : NULL,
 			NULL);
 
-	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/filter") &&
-			debug_win->regex) {
+	if(g_settings_get_boolean(settings, "active") && debug_win->regex) {
 		/* Filter out any new messages. */
 		GtkTextIter start;
 
@@ -852,7 +736,7 @@ pidgin_debug_window_show(void)
 
 	gtk_window_present(GTK_WINDOW(debug_win));
 
-	purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/enabled", TRUE);
+	g_settings_set_boolean(settings, "visible", TRUE);
 }
 
 void
@@ -863,6 +747,12 @@ pidgin_debug_window_hide(void)
 	}
 }
 
+GSettings *
+pidgin_debug_get_settings(void)
+{
+	return settings;
+}
+
 void
 pidgin_debug_init_handler(void)
 {
@@ -879,45 +769,15 @@ void
 pidgin_debug_init(void)
 {
 	/* Debug window preferences. */
-	/*
-	 * NOTE: This must be set before prefs are loaded, and the callbacks
-	 *       set after they are loaded, since prefs sets the enabled
-	 *       preference here and that loads the window, which calls the
-	 *       configure event, which overrides the width and height! :P
-	 */
-
-	purple_prefs_add_none(PIDGIN_PREFS_ROOT "/debug");
-
-	/* Controls printing to the debug window */
-	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/enabled", FALSE);
-	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/debug/filterlevel",
-	                     PURPLE_DEBUG_ALL);
-
-	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/debug/width",  450);
-	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/debug/height", 250);
-
-	purple_prefs_add_string(PIDGIN_PREFS_ROOT "/debug/regex", "");
-	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/filter", FALSE);
-	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/invert", FALSE);
-	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/case_insensitive", FALSE);
-	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/highlight", FALSE);
-
-	pref_callback_id = purple_prefs_connect_callback(NULL,
-	                                                 PIDGIN_PREFS_ROOT "/debug/enabled",
-	                                                 debug_enabled_cb, NULL);
+	GSettingsBackend *backend = purple_core_get_settings_backend();
+	settings = g_settings_new_with_backend("im.pidgin.Pidgin3.Debug", backend);
+	pref_callback_id = g_signal_connect(settings, "changed::visible",
+	                                    G_CALLBACK(debug_visible_cb), NULL);
 }
 
 void
 pidgin_debug_uninit(void)
 {
-	g_clear_handle_id(&pref_callback_id, purple_prefs_disconnect_callback);
-	g_clear_handle_id(&debug_enabled_timer, g_source_remove);
+	g_clear_signal_handler(&pref_callback_id, settings);
+	g_clear_object(&settings);
 }
-
-void *
-pidgin_debug_get_handle(void) {
-	static int handle;
-
-	return &handle;
-}
-
diff --git a/pidgin/pidgindebug.h b/pidgin/pidgindebug.h
--- a/pidgin/pidgindebug.h
+++ b/pidgin/pidgindebug.h
@@ -59,6 +59,19 @@ PIDGIN_AVAILABLE_IN_3_0
 void pidgin_debug_init_handler(void);
 
 /**
+ * pidgin_debug_get_settings:
+ *
+ * Gets the [class@Gio.Settings] for debug handling. This value is only valid
+ * after calling [func@debug_init].
+ *
+ * Returns: (transfer none): The settings for the debug window.
+ *
+ * Since: 3.0
+ */
+PIDGIN_AVAILABLE_IN_3_0
+GSettings *pidgin_debug_get_settings(void);
+
+/**
  * pidgin_debug_set_print_enabled:
  * @enable: Whether or not to use the default GLib logging handler.
  *
@@ -93,18 +106,6 @@ PIDGIN_AVAILABLE_IN_ALL
 void pidgin_debug_uninit(void);
 
 /**
- * pidgin_debug_get_handle:
- *
- * Get the handle for the GTK debug system.
- *
- * Returns: the handle to the debug system
- *
- * Since: 2.0
- */
-PIDGIN_AVAILABLE_IN_ALL
-void *pidgin_debug_get_handle(void);
-
-/**
  * pidgin_debug_window_show:
  *
  * Shows the debug window.
diff --git a/pidgin/resources/Debug/debug.ui b/pidgin/resources/Debug/debug.ui
--- a/pidgin/resources/Debug/debug.ui
+++ b/pidgin/resources/Debug/debug.ui
@@ -183,7 +183,6 @@ funky is going on. The raw text is below
                 <property name="label" translatable="1">_Filter</property>
                 <property name="use-underline">1</property>
                 <property name="icon-name">edit-find</property>
-                <signal name="toggled" handler="regex_filter_toggled_cb" object="PidginDebugWindow" swapped="no"/>
                 <child>
                   <object class="GtkGestureClick">
                     <property name="button">3</property>
@@ -263,14 +262,12 @@ funky is going on. The raw text is below
           <object class="GtkCheckButton" id="popover_invert">
             <property name="label" translatable="1">Invert</property>
             <property name="focusable">1</property>
-            <signal name="toggled" handler="regex_menu_cb" object="PidginDebugWindow" swapped="no"/>
           </object>
         </child>
         <child>
           <object class="GtkCheckButton" id="popover_highlight">
             <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>
         </child>
       </object>
