diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index b7425710..9f9438b3 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -189,7 +189,8 @@ FORMAT_REC fecommon_core_formats[] = { { "theme_saved", "Theme saved to $0", 1, { 0 } }, { "theme_save_failed", "Error saving theme to $0: $1", 2, { 0, 0 } }, { "theme_not_found", "Theme {hilight $0} not found", 1, { 0 } }, - { "window_theme_changed", "Using theme {hilight $0} in this window", 1, { 0 } }, + { "theme_changed", "Using now theme {hilight $0} ($1)", 2, { 0, 0 } }, + { "window_theme_changed", "Using theme {hilight $0} ($1) in this window", 2, { 0, 0 } }, { "format_title", "%:[{hilight $0}] - [{hilight $1}]%:", 2, { 0, 0 } }, { "format_subtitle", "[{hilight $0}]", 1, { 0 } }, { "format_item", "$0 = $1", 2, { 0, 0 } }, diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h index edb9e6cb..068ab027 100644 --- a/src/fe-common/core/module-formats.h +++ b/src/fe-common/core/module-formats.h @@ -157,6 +157,7 @@ enum { TXT_THEME_SAVED, TXT_THEME_SAVE_FAILED, TXT_THEME_NOT_FOUND, + TXT_THEME_CHANGED, TXT_WINDOW_THEME_CHANGED, TXT_FORMAT_TITLE, TXT_FORMAT_SUBTITLE, diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index 63d38ab2..cf91e95a 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -617,11 +617,24 @@ static THEME_REC *theme_find(const char *name) return NULL; } +static void window_themes_update(void) +{ + GSList *tmp; + + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + if (rec->theme_name != NULL) + rec->theme = theme_load(rec->theme_name); + } +} + THEME_REC *theme_load(const char *setname) { THEME_REC *theme; struct stat statbuf; char *fname, *name, *p; + int modified; name = g_strdup(setname); p = strrchr(name, '.'); @@ -631,10 +644,6 @@ THEME_REC *theme_load(const char *setname) } theme = theme_find(name); - if (theme != NULL) { - g_free(name); - return theme; - } /* check home dir */ fname = g_strdup_printf("%s/.irssi/%s.theme", g_get_home_dir(), name); @@ -646,13 +655,31 @@ THEME_REC *theme_load(const char *setname) /* theme not found */ g_free(fname); g_free(name); - return NULL; + return theme; /* use the one in memory if possible */ } } + modified = theme != NULL; + if (theme != NULL) { + if (theme->last_modify == statbuf.st_mtime) { + /* theme not modified, use the one already in memory */ + g_free(fname); + g_free(name); + return theme; + } + + theme_destroy(theme); + } + theme = theme_create(fname, name); + theme->last_modify = statbuf.st_mtime; theme_read(theme, theme->path, NULL); + if (modified) { + /* make sure no windows use the theme we just destroyed */ + window_themes_update(); + } + g_free(fname); g_free(name); return theme; @@ -1007,26 +1034,35 @@ static void sig_complete_format(GList **list, WINDOW_REC *window, if (*list != NULL) signal_stop(); } -static void read_settings(void) +static void change_theme(const char *name, int verbose) { THEME_REC *rec; + + rec = theme_load(name); + if (rec != NULL) { + current_theme = rec; + if (verbose) { + printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, + TXT_THEME_CHANGED, + rec->name, rec->path); + } + } else if (verbose) { + printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, + TXT_THEME_NOT_FOUND, name); + } +} + +static void read_settings(void) +{ const char *theme; theme = settings_get_str("theme"); - if (strcmp(current_theme->name, theme) != 0) { - rec = theme_load(theme); - if (rec != NULL) - current_theme = rec; - else { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_THEME_NOT_FOUND, theme); - } - } + if (strcmp(current_theme->name, theme) != 0) + change_theme(theme, TRUE); } static void themes_read(void) { - GSList *tmp; char *fname; while (themes != NULL) @@ -1044,15 +1080,8 @@ static void themes_read(void) g_free(fname); } - /* update window theme structures */ - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; - - if (rec->theme_name != NULL) - rec->theme = theme_load(rec->theme_name); - } - - read_settings(); + window_themes_update(); + change_theme(settings_get_str("theme"), FALSE); } void themes_init(void) diff --git a/src/fe-common/core/themes.h b/src/fe-common/core/themes.h index c5be2400..3305c7bb 100644 --- a/src/fe-common/core/themes.h +++ b/src/fe-common/core/themes.h @@ -13,6 +13,7 @@ typedef struct { typedef struct { char *path; char *name; + time_t last_modify; int default_color, default_bold_color; GHashTable *modules; diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index fe92f187..e2e43039 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -432,13 +432,16 @@ static void cmd_window_list(void) /* SYNTAX: WINDOW THEME */ static void cmd_window_theme(const char *data) { + THEME_REC *theme; + g_free_not_null(active_win->theme_name); active_win->theme_name = g_strdup(data); - active_win->theme = theme_load(data); - if (active_win->theme != NULL) { + active_win->theme = theme = theme_load(data); + if (theme != NULL) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, - TXT_WINDOW_THEME_CHANGED, data); + TXT_WINDOW_THEME_CHANGED, + theme->name, theme->path); } else { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_THEME_NOT_FOUND, data);