diff --git a/src/command/command.c b/src/command/command.c index b68ce3d2..7495506f 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -124,6 +124,7 @@ static char* _close_autocomplete(ProfWin *window, const char *const input); static char* _plugins_autocomplete(ProfWin *window, const char *const input); static char* _sendfile_autocomplete(ProfWin *window, const char *const input); static char* _blocked_autocomplete(ProfWin *window, const char *const input); +static char *_tray_autocomplete(ProfWin *window, const char *const input); GHashTable *commands = NULL; @@ -1412,17 +1413,21 @@ static struct cmd_t command_defs[] = }, { "/tray", - parse_args, 1, 1, &cons_tray_setting, + parse_args, 1, 2, &cons_tray_setting, CMD_NOSUBFUNCS CMD_MAINFUNC(cmd_tray) CMD_TAGS( CMD_TAG_UI) CMD_SYN( - "/tray on|off") + "/tray on|off", + "/tray read on|off", + "/tray timer ") CMD_DESC( "Display an icon in the tray that will indicate new messages.") CMD_ARGS( - { "on|off", "Enable or disable tray icon." }) + { "on|off", "Show tray icon." }, + { "read on|off", "Show tray icon when no unread messages." }, + { "timer ", "Set tray icon timer, seconds must be between 1-10" }) CMD_NOEXAMPLES }, @@ -2299,6 +2304,7 @@ static Autocomplete plugins_ac; static Autocomplete plugins_load_ac; static Autocomplete sendfile_ac; static Autocomplete blocked_ac; +static Autocomplete tray_ac; /* * Initialise command autocompleter and history @@ -2859,6 +2865,12 @@ cmd_init(void) blocked_ac = autocomplete_new(); autocomplete_add(blocked_ac, "add"); autocomplete_add(blocked_ac, "remove"); + + tray_ac = autocomplete_new(); + autocomplete_add(tray_ac, "on"); + autocomplete_add(tray_ac, "off"); + autocomplete_add(tray_ac, "read"); + autocomplete_add(tray_ac, "timer"); } void @@ -2950,6 +2962,7 @@ cmd_uninit(void) autocomplete_free(plugins_load_ac); autocomplete_free(sendfile_ac); autocomplete_free(blocked_ac); + autocomplete_free(tray_ac); } gboolean @@ -3180,6 +3193,7 @@ cmd_reset_autocomplete(ProfWin *window) autocomplete_reset(autoping_ac); autocomplete_reset(plugins_ac); autocomplete_reset(blocked_ac); + autocomplete_reset(tray_ac); autocomplete_reset(script_ac); if (script_show_ac) { autocomplete_free(script_show_ac); @@ -3358,7 +3372,7 @@ _cmd_complete_parameters(ProfWin *window, const char *const input) // autocomplete boolean settings gchar *boolean_choices[] = { "/beep", "/intype", "/states", "/outtype", "/flash", "/splash", "/chlog", "/grlog", "/history", "/vercheck", "/privileges", "/presence", "/wrap", "/winstidy", "/carbons", "/encwarn", - "/lastactivity", "/tray" }; + "/lastactivity" }; for (i = 0; i < ARRAY_SIZE(boolean_choices); i++) { result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice); @@ -3475,6 +3489,7 @@ _cmd_complete_parameters(ProfWin *window, const char *const input) g_hash_table_insert(ac_funcs, "/plugins", _plugins_autocomplete); g_hash_table_insert(ac_funcs, "/sendfile", _sendfile_autocomplete); g_hash_table_insert(ac_funcs, "/blocked", _blocked_autocomplete); + g_hash_table_insert(ac_funcs, "/tray", _tray_autocomplete); int len = strlen(input); char parsed[len+1]; @@ -3534,6 +3549,23 @@ _sub_autocomplete(ProfWin *window, const char *const input) return NULL; } +static char* +_tray_autocomplete(ProfWin *window, const char *const input) +{ + char *result = NULL; + result = autocomplete_param_with_func(input, "/tray read", prefs_autocomplete_boolean_choice); + if (result) { + return result; + } + + result = autocomplete_param_with_ac(input, "/tray", tray_ac, FALSE); + if (result) { + return result; + } + + return NULL; +} + static char* _who_autocomplete(ProfWin *window, const char *const input) { diff --git a/src/command/commands.c b/src/command/commands.c index f64c16e6..3060cf49 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -5865,17 +5865,60 @@ gboolean cmd_tray(ProfWin *window, const char *const command, gchar **args) { #ifdef HAVE_GTK - gboolean old = prefs_get_boolean(PREF_TRAY); - _cmd_set_boolean_preference(args[0], command, "Tray icon", PREF_TRAY); - gboolean new = prefs_get_boolean(PREF_TRAY); - if (old != new) { - if (new) { - tray_enable(); - } else { - tray_disable(); + if (g_strcmp0(args[0], "timer") == 0) { + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + return TRUE; } + + if (prefs_get_boolean(PREF_TRAY) == FALSE) { + cons_show("Tray icon not currently enabled, see /help tray"); + return TRUE; + } + + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(args[1], &intval, 1, 10, &err_msg); + if (res) { + cons_show("Tray timer set to %d seconds.", intval); + prefs_set_tray_timer(intval); + if (prefs_get_boolean(PREF_TRAY)) { + tray_set_timer(intval); + } + } else { + cons_show(err_msg); + free(err_msg); + } + + return TRUE; + } else if (g_strcmp0(args[0], "read") == 0) { + if (prefs_get_boolean(PREF_TRAY) == FALSE) { + cons_show("Tray icon not currently enabled, see /help tray"); + } else if (g_strcmp0(args[1], "on") == 0) { + prefs_set_boolean(PREF_TRAY_READ, TRUE); + cons_show("Tray icon enabled when no unread messages."); + } else if (g_strcmp0(args[1], "off") == 0) { + prefs_set_boolean(PREF_TRAY_READ, FALSE); + cons_show("Tray icon disabled when no unread messages."); + } else { + cons_bad_cmd_usage(command); + } + + return TRUE; + } else { + gboolean old = prefs_get_boolean(PREF_TRAY); + _cmd_set_boolean_preference(args[0], command, "Tray icon", PREF_TRAY); + gboolean new = prefs_get_boolean(PREF_TRAY); + if (old != new) { + if (new) { + tray_enable(); + } else { + tray_disable(); + } + } + + return TRUE; } - return TRUE; #else cons_show("This version of Profanity has not been built with GTK Tray Icon support enabled"); return TRUE; diff --git a/src/config/preferences.c b/src/config/preferences.c index 72cf0400..5d3d0512 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -591,6 +591,25 @@ prefs_set_autoxa_time(gint value) _save_prefs(); } +void +prefs_set_tray_timer(gint value) +{ + g_key_file_set_integer(prefs, PREF_GROUP_NOTIFICATIONS, "tray.timer", value); + _save_prefs(); +} + +gint +prefs_get_tray_timer(void) +{ + gint result = g_key_file_get_integer(prefs, PREF_GROUP_NOTIFICATIONS, "tray.timer", NULL); + + if (result == 0) { + return 5; + } else { + return result; + } +} + gchar** prefs_get_plugins(void) { @@ -1242,6 +1261,7 @@ _get_group(preference_t pref) case PREF_NOTIFY_MENTION_CASE_SENSITIVE: case PREF_NOTIFY_MENTION_WHOLE_WORD: case PREF_TRAY: + case PREF_TRAY_READ: return PREF_GROUP_NOTIFICATIONS; case PREF_CHLOG: case PREF_GRLOG: @@ -1294,6 +1314,8 @@ _get_key(preference_t pref) return "flash"; case PREF_TRAY: return "tray"; + case PREF_TRAY_READ: + return "tray.read"; case PREF_INTYPE: return "intype"; case PREF_HISTORY: @@ -1507,6 +1529,7 @@ _get_default_boolean(preference_t pref) case PREF_TLS_SHOW: case PREF_LASTACTIVITY: case PREF_NOTIFY_MENTION_WHOLE_WORD: + case PREF_TRAY_READ: return TRUE; default: return FALSE; diff --git a/src/config/preferences.h b/src/config/preferences.h index e4968521..5e4b28ef 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -53,6 +53,7 @@ typedef enum { PREF_TITLEBAR_GOODBYE, PREF_FLASH, PREF_TRAY, + PREF_TRAY_READ, PREF_INTYPE, PREF_HISTORY, PREF_CARBONS, @@ -223,6 +224,9 @@ void prefs_set_roster_presence_indent(gint value); void prefs_add_login(const char *jid); +void prefs_set_tray_timer(gint value); +gint prefs_get_tray_timer(void); + gboolean prefs_add_alias(const char *const name, const char *const value); gboolean prefs_remove_alias(const char *const name); char* prefs_get_alias(const char *const name); diff --git a/src/tray.c b/src/tray.c index ff9593c3..c16557a3 100644 --- a/src/tray.c +++ b/src/tray.c @@ -131,9 +131,22 @@ _tray_change_icon(gpointer data) unread_messages = wins_get_total_unread(); if (unread_messages) { - gtk_status_icon_set_from_file(prof_tray, icon_msg_filename->str); + if (!prof_tray) { + prof_tray = gtk_status_icon_new_from_file(icon_msg_filename->str); + } else { + gtk_status_icon_set_from_file(prof_tray, icon_msg_filename->str); + } } else { - gtk_status_icon_set_from_file(prof_tray, icon_filename->str); + if (prefs_get_boolean(PREF_TRAY_READ)) { + if (!prof_tray) { + prof_tray = gtk_status_icon_new_from_file(icon_filename->str); + } else { + gtk_status_icon_set_from_file(prof_tray, icon_filename->str); + } + } else { + g_clear_object(&prof_tray); + prof_tray = NULL; + } } return TRUE; @@ -179,13 +192,22 @@ tray_shutdown(void) g_string_free(icon_msg_filename, TRUE); } +void +tray_set_timer(int interval) +{ + g_source_remove(timer); + _tray_change_icon(NULL); + timer = g_timeout_add(interval * 1000, _tray_change_icon, NULL); +} + void tray_enable(void) { prof_tray = gtk_status_icon_new_from_file(icon_filename->str); shutting_down = FALSE; _tray_change_icon(NULL); - timer = g_timeout_add(5000, _tray_change_icon, NULL); + int interval = prefs_get_tray_timer() * 1000; + timer = g_timeout_add(interval, _tray_change_icon, NULL); } void diff --git a/src/tray.h b/src/tray.h index 81ddd20f..751af07c 100644 --- a/src/tray.h +++ b/src/tray.h @@ -51,4 +51,6 @@ void tray_enable(void); */ void tray_disable(void); +void tray_set_timer(int interval); + #endif diff --git a/src/ui/console.c b/src/ui/console.c index 7adc0147..3f44f133 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1188,6 +1188,14 @@ cons_tray_setting(void) cons_show("Tray icon (/tray) : ON"); else cons_show("Tray icon (/tray) : OFF"); + + if (prefs_get_boolean(PREF_TRAY_READ)) + cons_show("Tray icon read (/tray) : ON"); + else + cons_show("Tray icon read (/tray) : OFF"); + + int seconds = prefs_get_tray_timer(); + cons_show("Tray timer (/tray) : %d seconds", seconds); } void