Mon, 14 Oct 2024 23:41:43 -0500
Port Debug Window to GSettings
Testing Done:
Opened debug window, set filter string, toggled invert/highlight, and confirmed the window changed, along with stuff ending up in the `.ini`.
Reviewed at https://reviews.imfreedom.org/r/3572/
--- a/libpurple/debug.c Mon Oct 14 23:32:57 2024 -0500 +++ b/libpurple/debug.c Mon Oct 14 23:41:43 2024 -0500 @@ -169,6 +169,4 @@ if(g_getenv("PURPLE_VERBOSE_DEBUG")) { purple_debug_set_verbose(TRUE); } - - purple_prefs_add_none("/purple/debug"); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/data/gschema/im.pidgin.Pidgin3.Debug.gschema.xml Mon Oct 14 23:41:43 2024 -0500 @@ -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>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/data/gschema/meson.build Mon Oct 14 23:41:43 2024 -0500 @@ -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())
--- a/pidgin/data/meson.build Mon Oct 14 23:32:57 2024 -0500 +++ b/pidgin/data/meson.build Mon Oct 14 23:41:43 2024 -0500 @@ -1,3 +1,4 @@ +subdir('gschema') subdir('icons') devenv.prepend('XDG_DATA_DIRS', meson.current_source_dir())
--- a/pidgin/pidginapplication.c Mon Oct 14 23:32:57 2024 -0500 +++ b/pidgin/pidginapplication.c Mon Oct 14 23:41:43 2024 -0500 @@ -348,8 +348,12 @@ 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 @@ 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 @@ 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(); }
--- a/pidgin/pidgindebug.c Mon Oct 14 23:32:57 2024 -0500 +++ b/pidgin/pidgindebug.c Mon Oct 14 23:41:43 2024 -0500 @@ -59,8 +59,6 @@ GtkWidget *popover; GtkWidget *popover_invert; GtkWidget *popover_highlight; - gboolean invert; - gboolean highlight; GRegex *regex; }; @@ -72,27 +70,13 @@ } 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 @@ 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 @@ 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 @@ &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 @@ 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 @@ } 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 @@ } 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 @@ } 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 @@ } 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 @@ } 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 @@ { 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } +GSettings * +pidgin_debug_get_settings(void) +{ + return settings; +} + void pidgin_debug_init_handler(void) { @@ -879,45 +769,15 @@ 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; -} -
--- a/pidgin/pidgindebug.h Mon Oct 14 23:32:57 2024 -0500 +++ b/pidgin/pidgindebug.h Mon Oct 14 23:41:43 2024 -0500 @@ -59,6 +59,19 @@ 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 @@ 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.
--- a/pidgin/resources/Debug/debug.ui Mon Oct 14 23:32:57 2024 -0500 +++ b/pidgin/resources/Debug/debug.ui Mon Oct 14 23:41:43 2024 -0500 @@ -183,7 +183,6 @@ <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 @@ <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>