mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-17 11:10:18 +00:00
refactor: coord prefs/theme saves in one staged path; drop broken manager wrappers
This commit is contained in:
@@ -1009,15 +1009,51 @@ load_config (void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
save_config (void)
|
save_config_write_to_fd (int fh)
|
||||||
{
|
{
|
||||||
int fh, i;
|
int i;
|
||||||
char *config, *new_config;
|
|
||||||
|
if (!cfg_put_str (fh, "version", PACKAGE_VERSION))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
switch (vars[i].type)
|
||||||
|
{
|
||||||
|
case TYPE_STR:
|
||||||
|
if (!cfg_put_str (fh, vars[i].name, (char *) &prefs + vars[i].offset))
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TYPE_INT:
|
||||||
|
case TYPE_BOOL:
|
||||||
|
if (!cfg_put_int (fh, *((int *) &prefs + vars[i].offset), vars[i].name))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vars[i].after_update != NULL)
|
||||||
|
vars[i].after_update();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (vars[i].name);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
save_config_prepare (char **temp_path)
|
||||||
|
{
|
||||||
|
int fh;
|
||||||
|
char *config;
|
||||||
|
char *new_config;
|
||||||
|
|
||||||
if (check_config_dir () != 0)
|
if (check_config_dir () != 0)
|
||||||
make_config_dirs ();
|
make_config_dirs ();
|
||||||
|
|
||||||
|
if (!temp_path)
|
||||||
|
return 0;
|
||||||
|
|
||||||
config = default_file ();
|
config = default_file ();
|
||||||
new_config = g_strconcat (config, ".new", NULL);
|
new_config = g_strconcat (config, ".new", NULL);
|
||||||
|
|
||||||
@@ -1028,63 +1064,67 @@ save_config (void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cfg_put_str (fh, "version", PACKAGE_VERSION))
|
if (!save_config_write_to_fd (fh))
|
||||||
{
|
{
|
||||||
close (fh);
|
close (fh);
|
||||||
g_free (new_config);
|
g_free (new_config);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
switch (vars[i].type)
|
|
||||||
{
|
|
||||||
case TYPE_STR:
|
|
||||||
if (!cfg_put_str (fh, vars[i].name, (char *) &prefs + vars[i].offset))
|
|
||||||
{
|
|
||||||
close (fh);
|
|
||||||
g_free (new_config);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TYPE_INT:
|
|
||||||
case TYPE_BOOL:
|
|
||||||
if (!cfg_put_int (fh, *((int *) &prefs + vars[i].offset), vars[i].name))
|
|
||||||
{
|
|
||||||
close (fh);
|
|
||||||
g_free (new_config);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vars[i].after_update != NULL)
|
|
||||||
{
|
|
||||||
vars[i].after_update();
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while (vars[i].name);
|
|
||||||
|
|
||||||
if (close (fh) == -1)
|
if (close (fh) == -1)
|
||||||
{
|
{
|
||||||
g_free (new_config);
|
g_free (new_config);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
*temp_path = new_config;
|
||||||
g_unlink (config); /* win32 can't rename to an existing file */
|
return 1;
|
||||||
#endif
|
}
|
||||||
if (g_rename (new_config, config) == -1)
|
|
||||||
{
|
int
|
||||||
g_free (new_config);
|
save_config_finalize (const char *temp_path)
|
||||||
|
{
|
||||||
|
char *config;
|
||||||
|
|
||||||
|
if (!temp_path)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
config = default_file ();
|
||||||
|
#ifdef WIN32
|
||||||
|
g_unlink (config);
|
||||||
|
#endif
|
||||||
|
if (g_rename (temp_path, config) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
g_free (new_config);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
save_config_discard (const char *temp_path)
|
||||||
|
{
|
||||||
|
if (!temp_path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_unlink (temp_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
save_config (void)
|
||||||
|
{
|
||||||
|
char *temp_path = NULL;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (!save_config_prepare (&temp_path))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
result = save_config_finalize (temp_path);
|
||||||
|
if (!result)
|
||||||
|
save_config_discard (temp_path);
|
||||||
|
g_free (temp_path);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_showval (session *sess, const struct prefs *var, char *tbuf)
|
set_showval (session *sess, const struct prefs *var, char *tbuf)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ int make_config_dirs (void);
|
|||||||
int make_dcc_dirs (void);
|
int make_dcc_dirs (void);
|
||||||
int load_config (void);
|
int load_config (void);
|
||||||
int save_config (void);
|
int save_config (void);
|
||||||
|
int save_config_prepare (char **temp_path);
|
||||||
|
int save_config_finalize (const char *temp_path);
|
||||||
|
void save_config_discard (const char *temp_path);
|
||||||
void list_free (GSList ** list);
|
void list_free (GSList ** list);
|
||||||
void list_loadconf (char *file, GSList ** list, char *defaultconf);
|
void list_loadconf (char *file, GSList ** list, char *defaultconf);
|
||||||
int list_delentry (GSList ** list, char *name);
|
int list_delentry (GSList ** list, char *name);
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
|
|||||||
<ClInclude Include="icon-resolver.h" />
|
<ClInclude Include="icon-resolver.h" />
|
||||||
<ClInclude Include="joind.h" />
|
<ClInclude Include="joind.h" />
|
||||||
<ClInclude Include="maingui.h" />
|
<ClInclude Include="maingui.h" />
|
||||||
|
<ClInclude Include="preferences-persistence.h" />
|
||||||
<ClInclude Include="menu.h" />
|
<ClInclude Include="menu.h" />
|
||||||
<ClInclude Include="notifications\notification-backend.h" />
|
<ClInclude Include="notifications\notification-backend.h" />
|
||||||
<ClInclude Include="notifygui.h" />
|
<ClInclude Include="notifygui.h" />
|
||||||
@@ -107,6 +108,7 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
|
|||||||
<ClCompile Include="notifications\notification-windows.c" />
|
<ClCompile Include="notifications\notification-windows.c" />
|
||||||
<ClCompile Include="notifygui.c" />
|
<ClCompile Include="notifygui.c" />
|
||||||
<ClCompile Include="pixmaps.c" />
|
<ClCompile Include="pixmaps.c" />
|
||||||
|
<ClCompile Include="preferences-persistence.c" />
|
||||||
<ClCompile Include="plugin-notification.c" />
|
<ClCompile Include="plugin-notification.c" />
|
||||||
<ClCompile Include="plugin-tray.c" />
|
<ClCompile Include="plugin-tray.c" />
|
||||||
<ClCompile Include="plugingui.c" />
|
<ClCompile Include="plugingui.c" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Source Files">
|
<Filter Include="Source Files">
|
||||||
@@ -51,6 +51,9 @@
|
|||||||
<ClInclude Include="maingui.h">
|
<ClInclude Include="maingui.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="preferences-persistence.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="menu.h">
|
<ClInclude Include="menu.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -182,6 +185,9 @@
|
|||||||
<ClCompile Include="pixmaps.c">
|
<ClCompile Include="pixmaps.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="preferences-persistence.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="plugingui.c">
|
<ClCompile Include="plugingui.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#include "theme/theme-palette.h"
|
#include "theme/theme-palette.h"
|
||||||
#include "maingui.h"
|
#include "maingui.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "preferences-persistence.h"
|
||||||
#include "fkeys.h"
|
#include "fkeys.h"
|
||||||
#include "userlistgui.h"
|
#include "userlistgui.h"
|
||||||
#include "chanview.h"
|
#include "chanview.h"
|
||||||
@@ -178,15 +179,37 @@ static void mg_apply_emoji_fallback_widget (GtkWidget *widget);
|
|||||||
static guint mg_config_save_source_id = 0;
|
static guint mg_config_save_source_id = 0;
|
||||||
static gboolean mg_config_prefs_dirty = FALSE;
|
static gboolean mg_config_prefs_dirty = FALSE;
|
||||||
|
|
||||||
|
static void
|
||||||
|
mg_show_save_failure (const PreferencesPersistenceResult *save_result)
|
||||||
|
{
|
||||||
|
char buffer[192];
|
||||||
|
|
||||||
|
if (!save_result || save_result->success)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (save_result->partial_failure)
|
||||||
|
{
|
||||||
|
fe_message (_("Could not fully save preferences. zoitechat.conf was written, but colors.conf failed. Retry is possible."), FE_MSG_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_snprintf (buffer, sizeof (buffer), _("Could not save preferences (%s). Retry is possible."), save_result->failed_file ? save_result->failed_file : _("unknown file"));
|
||||||
|
fe_message (buffer, FE_MSG_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
mg_config_save_timeout_cb (gpointer userdata)
|
mg_config_save_timeout_cb (gpointer userdata)
|
||||||
{
|
{
|
||||||
|
PreferencesPersistenceResult save_result;
|
||||||
|
|
||||||
mg_config_save_source_id = 0;
|
mg_config_save_source_id = 0;
|
||||||
|
|
||||||
if (!mg_config_prefs_dirty)
|
if (!mg_config_prefs_dirty)
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
|
|
||||||
save_config ();
|
save_result = preferences_persistence_save_all ();
|
||||||
|
if (!save_result.success)
|
||||||
|
mg_show_save_failure (&save_result);
|
||||||
mg_config_prefs_dirty = FALSE;
|
mg_config_prefs_dirty = FALSE;
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
@@ -209,6 +232,8 @@ mg_schedule_config_save (void)
|
|||||||
static void
|
static void
|
||||||
mg_flush_config_save (void)
|
mg_flush_config_save (void)
|
||||||
{
|
{
|
||||||
|
PreferencesPersistenceResult save_result;
|
||||||
|
|
||||||
if (mg_config_save_source_id != 0)
|
if (mg_config_save_source_id != 0)
|
||||||
{
|
{
|
||||||
g_source_remove (mg_config_save_source_id);
|
g_source_remove (mg_config_save_source_id);
|
||||||
@@ -217,7 +242,9 @@ mg_flush_config_save (void)
|
|||||||
|
|
||||||
if (mg_config_prefs_dirty)
|
if (mg_config_prefs_dirty)
|
||||||
{
|
{
|
||||||
save_config ();
|
save_result = preferences_persistence_save_all ();
|
||||||
|
if (!save_result.success)
|
||||||
|
mg_show_save_failure (&save_result);
|
||||||
mg_config_prefs_dirty = FALSE;
|
mg_config_prefs_dirty = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ zoitechat_gtk_sources = [
|
|||||||
'maingui.c',
|
'maingui.c',
|
||||||
'notifygui.c',
|
'notifygui.c',
|
||||||
'pixmaps.c',
|
'pixmaps.c',
|
||||||
|
'preferences-persistence.c',
|
||||||
'plugin-tray.c',
|
'plugin-tray.c',
|
||||||
'plugin-notification.c',
|
'plugin-notification.c',
|
||||||
'rawlog.c',
|
'rawlog.c',
|
||||||
|
|||||||
66
src/fe-gtk/preferences-persistence.c
Normal file
66
src/fe-gtk/preferences-persistence.c
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#include "preferences-persistence.h"
|
||||||
|
|
||||||
|
#include "../common/cfgfiles.h"
|
||||||
|
#include "theme/theme-runtime.h"
|
||||||
|
|
||||||
|
PreferencesPersistenceResult
|
||||||
|
preferences_persistence_save_all (void)
|
||||||
|
{
|
||||||
|
PreferencesPersistenceResult result;
|
||||||
|
char *config_temp;
|
||||||
|
char *theme_temp;
|
||||||
|
|
||||||
|
result.success = FALSE;
|
||||||
|
result.retry_possible = TRUE;
|
||||||
|
result.partial_failure = FALSE;
|
||||||
|
result.config_failed = FALSE;
|
||||||
|
result.theme_failed = FALSE;
|
||||||
|
result.failed_file = NULL;
|
||||||
|
config_temp = NULL;
|
||||||
|
theme_temp = NULL;
|
||||||
|
|
||||||
|
if (!save_config_prepare (&config_temp))
|
||||||
|
{
|
||||||
|
result.config_failed = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!theme_runtime_save_prepare (&theme_temp))
|
||||||
|
{
|
||||||
|
result.theme_failed = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!save_config_finalize (config_temp))
|
||||||
|
{
|
||||||
|
result.config_failed = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!theme_runtime_save_finalize (theme_temp))
|
||||||
|
{
|
||||||
|
result.theme_failed = TRUE;
|
||||||
|
result.partial_failure = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.success = TRUE;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (!result.success)
|
||||||
|
{
|
||||||
|
if (result.config_failed && result.theme_failed)
|
||||||
|
result.failed_file = "zoitechat.conf and colors.conf";
|
||||||
|
else if (result.config_failed)
|
||||||
|
result.failed_file = "zoitechat.conf";
|
||||||
|
else if (result.theme_failed)
|
||||||
|
result.failed_file = "colors.conf";
|
||||||
|
}
|
||||||
|
|
||||||
|
save_config_discard (config_temp);
|
||||||
|
theme_runtime_save_discard (theme_temp);
|
||||||
|
g_free (config_temp);
|
||||||
|
g_free (theme_temp);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
18
src/fe-gtk/preferences-persistence.h
Normal file
18
src/fe-gtk/preferences-persistence.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef ZOITECHAT_PREFERENCES_PERSISTENCE_H
|
||||||
|
#define ZOITECHAT_PREFERENCES_PERSISTENCE_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
gboolean success;
|
||||||
|
gboolean retry_possible;
|
||||||
|
gboolean partial_failure;
|
||||||
|
gboolean config_failed;
|
||||||
|
gboolean theme_failed;
|
||||||
|
const char *failed_file;
|
||||||
|
} PreferencesPersistenceResult;
|
||||||
|
|
||||||
|
PreferencesPersistenceResult preferences_persistence_save_all (void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "maingui.h"
|
#include "maingui.h"
|
||||||
#include "pixmaps.h"
|
#include "pixmaps.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "preferences-persistence.h"
|
||||||
#include "plugin-tray.h"
|
#include "plugin-tray.h"
|
||||||
#include "notifications/notification-backend.h"
|
#include "notifications/notification-backend.h"
|
||||||
|
|
||||||
@@ -2191,12 +2192,23 @@ setup_apply (struct zoitechatprefs *pr)
|
|||||||
static void
|
static void
|
||||||
setup_ok_cb (GtkWidget *but, GtkWidget *win)
|
setup_ok_cb (GtkWidget *but, GtkWidget *win)
|
||||||
{
|
{
|
||||||
|
PreferencesPersistenceResult save_result;
|
||||||
|
char buffer[192];
|
||||||
|
|
||||||
gtk_widget_destroy (win);
|
gtk_widget_destroy (win);
|
||||||
setup_apply (&setup_prefs);
|
setup_apply (&setup_prefs);
|
||||||
if (!save_config ())
|
save_result = preferences_persistence_save_all ();
|
||||||
fe_message (_("Could not save zoitechat.conf."), FE_MSG_ERROR);
|
if (save_result.success)
|
||||||
if (!theme_manager_save_preferences ())
|
return;
|
||||||
fe_message (_("Could not save colors.conf."), FE_MSG_ERROR);
|
|
||||||
|
if (save_result.partial_failure)
|
||||||
|
{
|
||||||
|
fe_message (_("Preferences were partially saved. zoitechat.conf succeeded, colors.conf failed. Retry is possible."), FE_MSG_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_snprintf (buffer, sizeof (buffer), _("Could not save preferences (%s). Retry is possible."), save_result.failed_file ? save_result.failed_file : _("unknown file"));
|
||||||
|
fe_message (buffer, FE_MSG_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
|
|||||||
@@ -449,12 +449,11 @@ theme_runtime_load (void)
|
|||||||
user_colors_valid = TRUE;
|
user_colors_valid = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
theme_runtime_save (void)
|
theme_runtime_save_to_fd (int fh)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t j;
|
size_t j;
|
||||||
int fh;
|
|
||||||
ThemePalettePersistenceMode modes[] = {
|
ThemePalettePersistenceMode modes[] = {
|
||||||
{ "light", "color", &light_palette, &user_colors_valid },
|
{ "light", "color", &light_palette, &user_colors_valid },
|
||||||
{ "dark", "dark_color", &dark_palette, &dark_user_colors_valid },
|
{ "dark", "dark_color", &dark_palette, &dark_user_colors_valid },
|
||||||
@@ -485,15 +484,8 @@ theme_runtime_save (void)
|
|||||||
else
|
else
|
||||||
modes[1].palette = &dark_palette;
|
modes[1].palette = &dark_palette;
|
||||||
|
|
||||||
fh = zoitechat_open_file ("colors.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
|
|
||||||
if (fh == -1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!cfg_put_int (fh, THEME_PALETTE_MIGRATION_MARKER_VALUE, (char *) THEME_PALETTE_MIGRATION_MARKER_KEY))
|
if (!cfg_put_int (fh, THEME_PALETTE_MIGRATION_MARKER_VALUE, (char *) THEME_PALETTE_MIGRATION_MARKER_KEY))
|
||||||
{
|
|
||||||
close (fh);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < mode_count; i++)
|
for (i = 0; i < mode_count; i++)
|
||||||
{
|
{
|
||||||
@@ -512,19 +504,131 @@ theme_runtime_save (void)
|
|||||||
continue;
|
continue;
|
||||||
g_assert (theme_palette_get_color (modes[i].palette, def->token, &color));
|
g_assert (theme_palette_get_color (modes[i].palette, def->token, &color));
|
||||||
if (!palette_write_token_color (fh, modes[i].mode_name, def, &color))
|
if (!palette_write_token_color (fh, modes[i].mode_name, def, &color))
|
||||||
{
|
|
||||||
close (fh);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
theme_runtime_save_prepare (char **temp_path)
|
||||||
|
{
|
||||||
|
int fh;
|
||||||
|
const char *temp_name;
|
||||||
|
|
||||||
|
if (!temp_path)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
temp_name = "colors.conf.new";
|
||||||
|
fh = zoitechat_open_file (temp_name, O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
|
||||||
|
if (fh == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!theme_runtime_save_to_fd (fh))
|
||||||
|
{
|
||||||
|
close (fh);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (close (fh) == -1)
|
if (close (fh) == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
*temp_path = g_strdup (temp_name);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
theme_runtime_save_finalize (const char *temp_path)
|
||||||
|
{
|
||||||
|
int src_fh;
|
||||||
|
int dst_fh;
|
||||||
|
char buffer[4096];
|
||||||
|
ssize_t read_len;
|
||||||
|
|
||||||
|
if (!temp_path)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
src_fh = zoitechat_open_file (temp_path, O_RDONLY, 0, XOF_DOMODE);
|
||||||
|
if (src_fh == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
dst_fh = zoitechat_open_file ("colors.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
|
||||||
|
if (dst_fh == -1)
|
||||||
|
{
|
||||||
|
close (src_fh);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((read_len = read (src_fh, buffer, sizeof (buffer))) > 0)
|
||||||
|
{
|
||||||
|
ssize_t offset;
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
|
while (offset < read_len)
|
||||||
|
{
|
||||||
|
ssize_t written;
|
||||||
|
|
||||||
|
written = write (dst_fh, buffer + offset, (size_t) (read_len - offset));
|
||||||
|
if (written <= 0)
|
||||||
|
{
|
||||||
|
close (src_fh);
|
||||||
|
close (dst_fh);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read_len < 0)
|
||||||
|
{
|
||||||
|
close (src_fh);
|
||||||
|
close (dst_fh);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close (src_fh) == -1)
|
||||||
|
{
|
||||||
|
close (dst_fh);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close (dst_fh) == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
theme_runtime_save_discard (const char *temp_path)
|
||||||
|
{
|
||||||
|
int fh;
|
||||||
|
|
||||||
|
if (!temp_path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fh = zoitechat_open_file (temp_path, O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
|
||||||
|
if (fh != -1)
|
||||||
|
close (fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
theme_runtime_save (void)
|
||||||
|
{
|
||||||
|
char *temp_path = NULL;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
if (!theme_runtime_save_prepare (&temp_path))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
result = theme_runtime_save_finalize (temp_path);
|
||||||
|
if (!result)
|
||||||
|
theme_runtime_save_discard (temp_path);
|
||||||
|
g_free (temp_path);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
palette_color_eq (const GdkRGBA *a, const GdkRGBA *b)
|
palette_color_eq (const GdkRGBA *a, const GdkRGBA *b)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ typedef struct
|
|||||||
|
|
||||||
void theme_runtime_load (void);
|
void theme_runtime_load (void);
|
||||||
gboolean theme_runtime_save (void);
|
gboolean theme_runtime_save (void);
|
||||||
|
gboolean theme_runtime_save_prepare (char **temp_path);
|
||||||
|
gboolean theme_runtime_save_finalize (const char *temp_path);
|
||||||
|
void theme_runtime_save_discard (const char *temp_path);
|
||||||
gboolean theme_runtime_apply_mode (unsigned int mode, gboolean *palette_changed);
|
gboolean theme_runtime_apply_mode (unsigned int mode, gboolean *palette_changed);
|
||||||
gboolean theme_runtime_apply_dark_mode (gboolean enable);
|
gboolean theme_runtime_apply_dark_mode (gboolean enable);
|
||||||
void theme_runtime_user_set_color (ThemeSemanticToken token, const GdkRGBA *col);
|
void theme_runtime_user_set_color (ThemeSemanticToken token, const GdkRGBA *col);
|
||||||
|
|||||||
Reference in New Issue
Block a user