i3 - improved tiling WM


Colorized output for disk usage (revised).

Patch status: needinfo

Patch by Kevin Pulo

Long description:

Revised to address the issues in http://cr.i3wm.org/patch/292, and also
updated against a recent master branch.

Fixes #912.

To apply this patch, use:
curl http://cr.i3wm.org/patch/414/raw.patch | git am

b/i3status.c

20
@@ -290,6 +290,9 @@ int main(int argc, char *argv[]) {
21
         cfg_opt_t disk_opts[] = {
22
                 CFG_STR("format", "%free", CFGF_NONE),
23
                 CFG_STR("prefix_type", "binary", CFGF_NONE),
24
+                CFG_INT("low_threshold", 10 * 1024, CFGF_NONE), // 10 GiB
25
+                CFG_STR("threshold_type", "mibibytes", CFGF_NONE),
26
+                CFG_CUSTOM_COLOR_OPTS,
27
                 CFG_END()
28
         };
29
 
30
@@ -499,7 +502,7 @@ int main(int argc, char *argv[]) {
31
 
32
                         CASE_SEC_TITLE("disk") {
33
                                 SEC_OPEN_MAP("disk_info");
34
-                                print_disk_info(json_gen, buffer, title, cfg_getstr(sec, "format"), cfg_getstr(sec, "prefix_type"));
35
+                                print_disk_info(json_gen, buffer, title, cfg_getstr(sec, "format"), cfg_getstr(sec, "prefix_type"), cfg_getint(sec, "low_threshold"), cfg_getstr(sec, "threshold_type"));
36
                                 SEC_CLOSE_MAP;
37
                         }
38
 

b/include/i3status.h

43
@@ -145,7 +145,7 @@ char *auto_detect_format();
44
 void set_timezone(const char *tz);
45
 
46
 void print_ipv6_info(yajl_gen json_gen, char *buffer, const char *format_up, const char *format_down);
47
-void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *prefix_type);
48
+void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *prefix_type, const int low_threshold, const char *threshold_type);
49
 void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity, bool hide_seconds);
50
 void print_time(yajl_gen json_gen, char *buffer, const char *format, const char *tz, time_t t);
51
 void print_ddate(yajl_gen json_gen, char *buffer, const char *format, time_t t);

b/man/i3status.man

56
@@ -196,6 +196,12 @@ SI prefixes (k, M, G, T) represent multiples of powers of 1000.
57
 custom::
58
 The custom prefixes (K, M, G, T) represent multiples of powers of 1024.
59
 
60
+It is possible to define a low_threshold that causes the disk text to be
61
+colored red if the free space is unter a certain amount. The low_threshold
62
+type can be of threshold_type "mibibytes", "megabytes" or "percentage".
63
+So, if you configure low_threshold to 10 and threshold_type to "percentage",
64
+and your disk is 91 percent full, it will be colored red.
65
+
66
 *Example order*: +disk /mnt/usbstick+
67
 
68
 *Example format*: +%free (%avail)/ %total+
69
@@ -204,6 +210,11 @@ The custom prefixes (K, M, G, T) represent multiples of powers of 1024.
70
 
71
 *Example prefix_type*: +custom+
72
 
73
+*Example low_threshold*: +10240+
74
+
75
+*Example threshold_type*: +mibibytes+
76
+
77
+
78
 === Run-watch
79
 
80
 Expands the given path to a pidfile and checks if the process ID found inside

b/src/print_disk_info.c

85
@@ -53,13 +53,22 @@ static int print_bytes_human(char *outwalk, uint64_t bytes, const char *prefix_t
86
 }
87
 
88
 /*
89
+ * Returns true if the given type matches the target type, and the
90
+ * given value is under the threshold.
91
+ */
92
+static bool check_value_under_threshold(const char *type, const char *target_type, const uint64_t value, const uint64_t threshold_value) {
93
+    return strcasecmp(type, target_type) == 0 && (value < threshold_value);
94
+}
95
+
96
+/*
97
  * Does a statvfs and prints either free, used or total amounts of bytes in a
98
  * human readable manner.
99
  *
100
  */
101
-void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *prefix_type) {
102
+void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *prefix_type, const int low_threshold, const char *threshold_type) {
103
         const char *walk;
104
         char *outwalk = buffer;
105
+        bool colorful_output = false;
106
 
107
         INSTANCE(path);
108
 
109
@@ -75,6 +84,18 @@ void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const ch
110
                 return;
111
 #endif
112
 
113
+        const int percentage_free = ((float)buf.f_bfree / (float)buf.f_blocks) * 100;
114
+        const uint64_t mibibytes_free = ((uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail)/(1024*1024);
115
+        const uint64_t megabytes_free = ((uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail)/(1000*1000);
116
+        if (check_value_under_threshold(threshold_type, "percentage", percentage_free, low_threshold) ||
117
+            check_value_under_threshold(threshold_type, "mibibytes", mibibytes_free, low_threshold) ||
118
+            check_value_under_threshold(threshold_type, "megabytes", megabytes_free, low_threshold)) {
119
+                START_COLOR("color_bad");
120
+                colorful_output = true;
121
+        } else {
122
+                colorful_output = false;
123
+        }
124
+
125
         for (walk = format; *walk != '\0'; walk++) {
126
                 if (*walk != '%') {
127
                         *(outwalk++) = *walk;
128
@@ -121,6 +142,8 @@ void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const ch
129
                         walk += strlen("percentage_avail");
130
                 }
131
         }
132
+        if (colorful_output)
133
+                END_COLOR;
134
 
135
         *outwalk = '\0';
136
         OUTPUT_FULL_TEXT(buffer);