perf: debounce GUI config saves; flush pending write on close

This commit is contained in:
2026-03-16 21:57:21 -06:00
parent 96af9bdde6
commit 896a761e24

View File

@@ -173,6 +173,55 @@ enum
static void mg_apply_emoji_fallback_widget (GtkWidget *widget); static void mg_apply_emoji_fallback_widget (GtkWidget *widget);
#define MG_CONFIG_SAVE_DEBOUNCE_MS 250
static guint mg_config_save_source_id = 0;
static gboolean mg_config_prefs_dirty = FALSE;
static gboolean
mg_config_save_timeout_cb (gpointer userdata)
{
mg_config_save_source_id = 0;
if (!mg_config_prefs_dirty)
return G_SOURCE_REMOVE;
save_config ();
mg_config_prefs_dirty = FALSE;
return G_SOURCE_REMOVE;
}
static void
mg_schedule_config_save (void)
{
if (!mg_config_prefs_dirty)
return;
if (mg_config_save_source_id != 0)
g_source_remove (mg_config_save_source_id);
mg_config_save_source_id = g_timeout_add (MG_CONFIG_SAVE_DEBOUNCE_MS,
mg_config_save_timeout_cb,
NULL);
}
static void
mg_flush_config_save (void)
{
if (mg_config_save_source_id != 0)
{
g_source_remove (mg_config_save_source_id);
mg_config_save_source_id = 0;
}
if (mg_config_prefs_dirty)
{
save_config ();
mg_config_prefs_dirty = FALSE;
}
}
static inline void static inline void
mg_set_source_color (cairo_t *cr, const XTextColor *color) mg_set_source_color (cairo_t *cr, const XTextColor *color)
{ {
@@ -761,6 +810,10 @@ fe_set_title (session *sess)
static gboolean static gboolean
mg_windowstate_cb (GtkWindow *wid, GdkEventWindowState *event, gpointer userdata) mg_windowstate_cb (GtkWindow *wid, GdkEventWindowState *event, gpointer userdata)
{ {
guint win_state;
guint win_fullscreen;
gboolean changed = FALSE;
if ((event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) && if ((event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) &&
(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) && (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) &&
prefs.hex_gui_tray_minimize && prefs.hex_gui_tray && prefs.hex_gui_tray_minimize && prefs.hex_gui_tray &&
@@ -769,13 +822,31 @@ mg_windowstate_cb (GtkWindow *wid, GdkEventWindowState *event, gpointer userdata
tray_toggle_visibility (TRUE); tray_toggle_visibility (TRUE);
} }
prefs.hex_gui_win_state = 0; win_state = 0;
if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
prefs.hex_gui_win_state = 1; win_state = 1;
prefs.hex_gui_win_fullscreen = 0; win_fullscreen = 0;
if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
prefs.hex_gui_win_fullscreen = 1; win_fullscreen = 1;
if (prefs.hex_gui_win_state != win_state)
{
prefs.hex_gui_win_state = win_state;
changed = TRUE;
}
if (prefs.hex_gui_win_fullscreen != win_fullscreen)
{
prefs.hex_gui_win_fullscreen = win_fullscreen;
changed = TRUE;
}
if (changed)
{
mg_config_prefs_dirty = TRUE;
mg_schedule_config_save ();
}
menu_set_fullscreen (current_sess->gui, prefs.hex_gui_win_fullscreen); menu_set_fullscreen (current_sess->gui, prefs.hex_gui_win_fullscreen);
@@ -789,17 +860,46 @@ mg_windowstate_cb (GtkWindow *wid, GdkEventWindowState *event, gpointer userdata
static gboolean static gboolean
mg_configure_cb (GtkWidget *wid, GdkEventConfigure *event, session *sess) mg_configure_cb (GtkWidget *wid, GdkEventConfigure *event, session *sess)
{ {
gboolean changed = FALSE;
if (sess == NULL) /* for the main_window */ if (sess == NULL) /* for the main_window */
{ {
if (mg_gui) if (mg_gui)
{ {
if (prefs.hex_gui_win_save && !prefs.hex_gui_win_state && !prefs.hex_gui_win_fullscreen) if (prefs.hex_gui_win_save && !prefs.hex_gui_win_state && !prefs.hex_gui_win_fullscreen)
{ {
int win_left;
int win_top;
int win_width;
int win_height;
sess = current_sess; sess = current_sess;
gtk_window_get_position (GTK_WINDOW (wid), &prefs.hex_gui_win_left, gtk_window_get_position (GTK_WINDOW (wid), &win_left, &win_top);
&prefs.hex_gui_win_top); gtk_window_get_size (GTK_WINDOW (wid), &win_width, &win_height);
gtk_window_get_size (GTK_WINDOW (wid), &prefs.hex_gui_win_width,
&prefs.hex_gui_win_height); if (prefs.hex_gui_win_left != win_left)
{
prefs.hex_gui_win_left = win_left;
changed = TRUE;
}
if (prefs.hex_gui_win_top != win_top)
{
prefs.hex_gui_win_top = win_top;
changed = TRUE;
}
if (prefs.hex_gui_win_width != win_width)
{
prefs.hex_gui_win_width = win_width;
changed = TRUE;
}
if (prefs.hex_gui_win_height != win_height)
{
prefs.hex_gui_win_height = win_height;
changed = TRUE;
}
} }
} }
} }
@@ -808,13 +908,46 @@ mg_configure_cb (GtkWidget *wid, GdkEventConfigure *event, session *sess)
{ {
if (sess->type == SESS_DIALOG && prefs.hex_gui_win_save) if (sess->type == SESS_DIALOG && prefs.hex_gui_win_save)
{ {
gtk_window_get_position (GTK_WINDOW (wid), &prefs.hex_gui_dialog_left, int dialog_left;
&prefs.hex_gui_dialog_top); int dialog_top;
gtk_window_get_size (GTK_WINDOW (wid), &prefs.hex_gui_dialog_width, int dialog_width;
&prefs.hex_gui_dialog_height); int dialog_height;
gtk_window_get_position (GTK_WINDOW (wid), &dialog_left, &dialog_top);
gtk_window_get_size (GTK_WINDOW (wid), &dialog_width, &dialog_height);
if (prefs.hex_gui_dialog_left != dialog_left)
{
prefs.hex_gui_dialog_left = dialog_left;
changed = TRUE;
}
if (prefs.hex_gui_dialog_top != dialog_top)
{
prefs.hex_gui_dialog_top = dialog_top;
changed = TRUE;
}
if (prefs.hex_gui_dialog_width != dialog_width)
{
prefs.hex_gui_dialog_width = dialog_width;
changed = TRUE;
}
if (prefs.hex_gui_dialog_height != dialog_height)
{
prefs.hex_gui_dialog_height = dialog_height;
changed = TRUE;
}
} }
} }
if (changed)
{
mg_config_prefs_dirty = TRUE;
mg_schedule_config_save ();
}
return FALSE; return FALSE;
} }
@@ -2339,6 +2472,8 @@ mg_tabwindow_kill_cb (GtkWidget *win, gpointer userdata)
GSList *list, *next; GSList *list, *next;
session *sess; session *sess;
mg_flush_config_save ();
zoitechat_is_quitting = TRUE; zoitechat_is_quitting = TRUE;
/* see if there's any non-tab windows left */ /* see if there's any non-tab windows left */