diff --git a/CMakeLists.txt b/CMakeLists.txt index 79e688837ccbf644b2bc2182c47d16d6396b59ba..6323f01e41086d288b5205c9084f4c5baa19bbc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,7 @@ include_directories( ${PROJECT_BINARY_DIR} src src/battery src/clock + src/graphs src/systray src/taskbar src/launcher @@ -136,6 +137,7 @@ set( SOURCES src/config.c src/drag_and_drop.c src/default_icon.c src/clock/clock.c + src/graphs/graphs.c src/systray/systraybar.c src/launcher/launcher.c src/launcher/apps-common.c diff --git a/src/config.c b/src/config.c index b23857c1dfe48049e3c22e3257e022360e73d368..dd527f3128a38d75322a436d78c57c1d7f22ec5b 100644 --- a/src/config.c +++ b/src/config.c @@ -1,60 +1,60 @@ /************************************************************************** -* -* Tint2 : read/write config file -* -* Copyright (C) 2007 Pål Staurland (staura@gmail.com) -* Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr) from Omega distribution -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License version 2 -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -**************************************************************************/ + * + * Tint2 : read/write config file + * + * Copyright (C) 2007 Pål Staurland (staura@gmail.com) + * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr) from Omega distribution + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **************************************************************************/ -#include -#include -#include -#include -#include +#include +#include #include #include -#include -#include -#include -#include +#include +#include #include #include #include -#include +#include +#include +#include +#include +#include +#include #include "config.h" #ifndef TINT2CONF -#include "tint2rc.h" +#include "clock.h" #include "common.h" +#include "execplugin.h" +#include "graphs.h" +#include "launcher.h" +#include "panel.h" +#include "separator.h" #include "server.h" #include "strnatcmp.h" -#include "panel.h" +#include "systraybar.h" #include "task.h" #include "taskbar.h" #include "taskbarname.h" -#include "systraybar.h" -#include "launcher.h" -#include "clock.h" -#include "window.h" -#include "tooltip.h" #include "timer.h" -#include "separator.h" -#include "execplugin.h" - +#include "tint2rc.h" +#include "tooltip.h" +#include "window.h" #ifdef ENABLE_BATTERY #include "battery.h" #endif @@ -453,6 +453,8 @@ void add_entry(char *key, char *value) } if (panel_items_order[j] == 'C') clock_enabled = 1; + if (panel_items_order[j] == 'G') + graphs_enabled = 1; } } else if (strcmp(key, "panel_margin") == 0) { extract_values(value, &value1, &value2, &value3); @@ -943,6 +945,70 @@ void add_entry(char *key, char *value) clock_dwheel_command = strdup(value); } + /* Graphs */ + else if (strcmp(key, "graphs_items") == 0) { + int j; + for (j = 0; j < strlen(value); j++) { + if (value[j] == 'C' && graphs_cpu_pos == -1) { + graphs_cpu_pos = graphs_ncurves; + graphs_curves_per_pos[graphs_ngraphs] = 2; + graphs_ngraphs++; + graphs_ncurves += 2; + } else if (value[j] == 'M' && graphs_mem_pos == -1) { + graphs_mem_pos = graphs_ncurves; + graphs_curves_per_pos[graphs_ngraphs] = 2; + graphs_ngraphs++; + graphs_ncurves += 2; + } else if (value[j] == 'N' && graphs_net_pos == -1) { + graphs_net_pos = graphs_ncurves; + graphs_curves_per_pos[graphs_ngraphs] = 2; + graphs_ngraphs++; + graphs_ncurves += 2; + } + } + } else if (strcmp(key, "graphs_use_bars") == 0) { + graphs_use_bars = atoi(value); + } else if (strcmp(key, "graphs_graph_width") == 0) { + int w = atoi(value); + graphs_graph_width = (w <= 200 && w >= 10) ? w : 50; + } else if (strcmp(key, "graphs_netiface") == 0) { + if (strlen(value) > 0) + graphs_netiface = strdup(value); + } else if (strcmp(key, "graphs_netmaxup") == 0) { + int s = atoi(value); + graphs_netmaxup = s; + } else if (strcmp(key, "graphs_netmaxdown") == 0) { + int s = atoi(value); + graphs_netmaxdown = s; + } else if (strncmp(key, "graphs_color", 12) == 0) { + int idx = key[12] - 48; + if (idx >= 0 && idx < MAXCURVES) { + extract_values(value, &value1, &value2, &value3); + get_color(value1, panel_config.graphs.g[idx].rgb); + if (value2) + panel_config.graphs.g[idx].alpha = (atoi(value2) / 100.0); + else + panel_config.graphs.g[idx].alpha = 0.5; + } + } else if (strcmp(key, "graphs_padding") == 0) { + extract_values(value, &value1, &value2, &value3); + panel_config.graphs.area.paddingxlr = panel_config.graphs.area.paddingx = atoi(value1); + if (value2) + panel_config.graphs.area.paddingy = atoi(value2); + if (value3) + panel_config.graphs.area.paddingx = atoi(value3); + } else if (strcmp(key, "graphs_background_id") == 0) { + int id = atoi(value); + id = (id < backgrounds->len && id >= 0) ? id : 0; + panel_config.graphs.area.bg = &g_array_index(backgrounds, Background, id); + } else if (strcmp(key, "graphs_lclick_command") == 0) { + if (strlen(value) > 0) + graphs_lclick_command = strdup(value); + } else if (strcmp(key, "graphs_rclick_command") == 0) { + if (strlen(value) > 0) + graphs_rclick_command = strdup(value); + } + /* Taskbar */ else if (strcmp(key, "taskbar_mode") == 0) { if (strcmp(value, "multi_desktop") == 0) @@ -1155,8 +1221,9 @@ void add_entry(char *key, char *value) systray_monitor = MAX(0, config_get_monitor(value)); } else if (strcmp(key, "systray_name_filter") == 0) { if (systray_hide_name_filter) { - fprintf(stderr, "tint2: Error: duplicate option 'systray_name_filter'. Please use it only once. See " - "https://gitlab.com/o9000/tint2/issues/652\n"); + fprintf(stderr, + "tint2: Error: duplicate option 'systray_name_filter'. Please use it only once. See " + "https://gitlab.com/o9000/tint2/issues/652\n"); free(systray_hide_name_filter); } systray_hide_name_filter = strdup(value); diff --git a/src/graphs/graphs.c b/src/graphs/graphs.c new file mode 100644 index 0000000000000000000000000000000000000000..e89d84969fe9b61b0a49a092044533b1ec237ef5 --- /dev/null +++ b/src/graphs/graphs.c @@ -0,0 +1,439 @@ +/************************************************************************** + * + * Tint2 : graphs + * + * Copyright (C) 2011 Francisco J. Vazquez (fjvazquezaraujo@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "graphs.h" +#include "panel.h" +#include "server.h" +#include "timer.h" +#include "window.h" + +#define CPU_SAMPLE_COUNT 5 +#define NET_SAMPLE_COUNT 5 + +int graphs_enabled; +int graphs_ngraphs; +int graphs_ncurves; +int graphs_cpu_pos; +int graphs_mem_pos; +int graphs_net_pos; +int graphs_curves_per_pos[MAXGRAPHS]; +int graphs_use_bars; +int graphs_graph_width; +int graphs_cpu_nsamples_avg; +int graphs_net_nsamples_avg; +char *graphs_netiface; +int graphs_netmaxup; +int graphs_netmaxdown; +char *graphs_lclick_command; +char *graphs_rclick_command; + +float **graph_values; // circular array list +static int pos_x = 0; // current position in graph_values +// static timeout* graphs_timeout; +static Timer graphs_timer; + +void default_graphs() +{ + graphs_enabled = 0; + graphs_ngraphs = 0; + graphs_ncurves = 0; + graphs_cpu_pos = -1; + graphs_mem_pos = -1; + graphs_net_pos = -1; + graphs_use_bars = 0; + graphs_graph_width = 50; + graphs_cpu_nsamples_avg = 1; + graphs_net_nsamples_avg = 2; + graphs_netiface = 0; + graphs_netmaxup = 0; + graphs_netmaxdown = 0; + // graphs_timeout = 0; + INIT_TIMER(graphs_timer); + graphs_lclick_command = 0; + graphs_rclick_command = 0; +} + +void cleanup_graphs() +{ + if (graphs_netiface) + g_free(graphs_netiface); + if (graphs_lclick_command) + g_free(graphs_lclick_command); + if (graphs_rclick_command) + g_free(graphs_rclick_command); + // if (graphs_timeout) stop_timeout(graphs_timeout); + destroy_timer(&graphs_timer); + int i; + for (i = 0; i < graphs_ncurves; i++) { + free(graph_values[i]); + } + free(graph_values); +} + +int update_cpugraph() +{ + if (graphs_cpu_pos == -1) + return 0; + + struct cpu_info { + unsigned long long last_total; + unsigned long long last_active_total, last_wait_total; + int cur_idx; + double active[CPU_SAMPLE_COUNT], wait[CPU_SAMPLE_COUNT]; + float active_perc, wait_perc; + }; + static struct cpu_info cpu = {.cur_idx = 0}; + + FILE *fp; + if ((fp = fopen("/proc/stat", "r")) == NULL) { + return 0; + } + char buf[256]; + while (!feof(fp)) { + if (fgets(buf, 255, fp) == NULL) { + break; + } + if (strncmp(buf, "cpu", 3) == 0) { + unsigned long long cpu_user; + unsigned long long cpu_system; + unsigned long long cpu_nice; + unsigned long long cpu_idle; + unsigned long long cpu_iowait; + unsigned long long cpu_irq; + unsigned long long cpu_softirq; + unsigned long long cpu_steal; + unsigned long long cpu_total; + unsigned long long cpu_active_total; + unsigned long long cpu_wait_total; + sscanf(buf, + "%*s %llu %llu %llu %llu %llu %llu %llu %llu", + &cpu_user, + &cpu_nice, + &cpu_system, + &cpu_idle, + &cpu_iowait, + &cpu_irq, + &cpu_softirq, + &cpu_steal); + cpu_total = cpu_user + cpu_nice + cpu_system + cpu_idle + cpu_iowait + cpu_irq + cpu_softirq + cpu_steal; + cpu_active_total = cpu_user + cpu_nice + cpu_system + cpu_steal; + cpu_wait_total = cpu_total - cpu_active_total - cpu_idle; + double time = (cpu_total - cpu.last_total); + cpu.active[cpu.cur_idx] = (cpu_active_total - cpu.last_active_total) / time; + cpu.wait[cpu.cur_idx] = (cpu_wait_total - cpu.last_wait_total) / time; + cpu.last_total = cpu_total; + cpu.last_active_total = cpu_active_total; + cpu.last_wait_total = cpu_wait_total; + double curtmp1 = 0; + double curtmp2 = 0; + int i; + // Average the samples + for (i = 0; i < graphs_cpu_nsamples_avg; i++) { + int idx2 = (cpu.cur_idx + CPU_SAMPLE_COUNT - i) % CPU_SAMPLE_COUNT; + curtmp1 += cpu.active[idx2]; + curtmp2 += cpu.wait[idx2]; + } + cpu.active_perc = curtmp1 / (float)graphs_cpu_nsamples_avg; + cpu.wait_perc = curtmp2 / (float)graphs_cpu_nsamples_avg; + cpu.cur_idx = (cpu.cur_idx + 1) % CPU_SAMPLE_COUNT; + break; // Ignore the rest + } + } + fclose(fp); + + graph_values[graphs_cpu_pos][pos_x] = cpu.active_perc; + graph_values[graphs_cpu_pos + 1][pos_x] = cpu.active_perc + cpu.wait_perc; + + return 0; +} + +int update_memgraph() +{ + if (graphs_mem_pos == -1) + return 0; + + long long unsigned int memtotal = 0, memfree = 0, buffers = 0, cached = 0; + + FILE *fp; + if ((fp = fopen("/proc/meminfo", "r")) == NULL) { + return 0; + } + char buf[256]; + while (!feof(fp)) { + if (fgets(buf, 255, fp) == NULL) { + break; + } + if (strncmp(buf, "MemTotal:", 9) == 0) { + sscanf(buf, "%*s %llu", &memtotal); + } else if (strncmp(buf, "MemFree:", 8) == 0) { + sscanf(buf, "%*s %llu", &memfree); + } else if (strncmp(buf, "Buffers:", 8) == 0) { + sscanf(buf, "%*s %llu", &buffers); + } else if (strncmp(buf, "Cached:", 7) == 0) { + sscanf(buf, "%*s %llu", &cached); + } + } + fclose(fp); + + long long unsigned int used = memtotal - memfree; + long long unsigned int bufcach = buffers + cached; + + graph_values[graphs_mem_pos][pos_x] = (used - bufcach) / (float)memtotal; + graph_values[graphs_mem_pos + 1][pos_x] = used / (float)memtotal; + + return 0; +} + +int update_netgraph() +{ + if (graphs_net_pos == -1 || graphs_netiface == NULL) + return 0; + + struct net_stat { + long long last_down, last_up; + int cur_idx; + long long down[NET_SAMPLE_COUNT], up[NET_SAMPLE_COUNT]; + double down_rate, up_rate; + double max_down, max_up; + }; + static struct net_stat net = {.cur_idx = 0, .max_down = 0, .max_up = 0}; + + double max(double v1, double v2) + { + return v1 > v2 ? v1 : v2; + } + double min(double v1, double v2) + { + return v1 < v2 ? v1 : v2; + } + + FILE *fp; + if (!(fp = fopen("/proc/net/dev", "r"))) { + return 0; + } + char buf[256]; + // Ignore first two lines + fgets(buf, 255, fp); + fgets(buf, 255, fp); + static int first_run = 1; + while (!feof(fp)) { + if (fgets(buf, 255, fp) == NULL) { + break; + } + char *p = buf; + while (isspace((int)*p)) + p++; + char *curdev = p; + while (*p && *p != ':') + p++; + if (*p == '\0') + continue; + *p = '\0'; + + if (strcmp(curdev, graphs_netiface)) + continue; + + long long down, up; + sscanf(p + 1, "%lld %*d %*d %*d %*d %*d %*d %*d %lld", &down, &up); + if (down < net.last_down) + net.last_down = 0; // Overflow + if (up < net.last_up) + net.last_up = 0; // Overflow + net.down[net.cur_idx] = (down - net.last_down); + net.up[net.cur_idx] = (up - net.last_up); + net.last_down = down; + net.last_up = up; + if (first_run) { + first_run = 0; + break; + } + + unsigned int curtmp1 = 0; + unsigned int curtmp2 = 0; + // Average the samples + int i; + for (i = 0; i < graphs_net_nsamples_avg; i++) { + curtmp1 += net.down[(net.cur_idx + NET_SAMPLE_COUNT - i) % NET_SAMPLE_COUNT]; + curtmp2 += net.up[(net.cur_idx + NET_SAMPLE_COUNT - i) % NET_SAMPLE_COUNT]; + } + net.down_rate = curtmp1 / (double)graphs_net_nsamples_avg; + net.up_rate = curtmp2 / (double)graphs_net_nsamples_avg; + if (graphs_netmaxdown > 0) { + net.down_rate /= (float)graphs_netmaxdown; + net.down_rate = min(1.0, net.down_rate); + } else { + // Normalize by maximum speed (a priori unknown, + // so we must do this all the time). + if (net.max_down < net.down_rate) { + for (i = 0; i < graphs_graph_width; i++) { + graph_values[graphs_net_pos][i] *= (net.max_down / net.down_rate); + } + net.max_down = net.down_rate; + net.down_rate = 1.0; + } else if (net.max_down != 0) + net.down_rate /= net.max_down; + } + if (graphs_netmaxup > 0) { + net.up_rate /= (float)graphs_netmaxup; + net.up_rate = min(1.0, net.up_rate); + } else { + if (net.max_up < net.up_rate) { + for (i = 0; i < graphs_graph_width; i++) { + graph_values[graphs_net_pos + 1][i] *= (net.max_up / net.up_rate); + } + net.max_up = net.up_rate; + net.up_rate = 1.0; + } else if (net.max_up != 0) + net.up_rate /= net.max_up; + } + net.cur_idx = (net.cur_idx + 1) % NET_SAMPLE_COUNT; + break; // Ignore the rest + } + fclose(fp); + + graph_values[graphs_net_pos][pos_x] = net.down_rate; + graph_values[graphs_net_pos + 1][pos_x] = net.up_rate; + + return 0; +} + +void update_graphs(void *arg) +{ + update_cpugraph(); + update_memgraph(); + update_netgraph(); + int i; + for (i = 0; i < num_panels; i++) + panels[i].graphs.area._redraw_needed = TRUE; + + // panel1[i].graphs.area.redraw = 1; + // schedule_redraw(& + panel_refresh = 1; +} + +void init_graphs() +{ + if (!graphs_enabled || !graphs_ngraphs) + return; + + if (!graphs_timer.enabled_) { + change_timer(&graphs_timer, true, 10, 1000, update_graphs, &graphs_timer); + } + int i; + graph_values = (float **)malloc(graphs_ncurves * sizeof(float *)); + for (i = 0; i < graphs_ncurves; i++) { + unsigned int gsize = graphs_graph_width * sizeof(float); + graph_values[i] = malloc(gsize); + memset(graph_values[i], 0, gsize); + } +} + +void init_graphs_panel(void *p) +{ + if (!graphs_enabled || !graphs_ngraphs) + return; + + Panel *panel = (Panel *)p; + Graphs *graphs = &panel->graphs; + + if (graphs->area.bg == 0) + graphs->area.bg = &g_array_index(backgrounds, Background, 0); + graphs->area.parent = p; + graphs->area.panel = p; + graphs->area._draw_foreground = draw_graphs; + graphs->area.size_mode = LAYOUT_FIXED; + + graphs->area._resize = resize_graphs; + + graphs->area.resize_needed = 1; + graphs->area.on_screen = 1; +} + +void draw_graphs(void *obj, cairo_t *c) +{ + Graphs *graphs = obj; + + cairo_set_line_width(c, 1.0); + int i, i2, g, cv; + int x = graphs->area.paddingxlr + graphs->area.bg->border.width + 1; + int y1 = graphs->area.height - graphs->area.bg->border.width - graphs->area.paddingy; + for (g = 0, cv = 0; g < graphs_ngraphs; g++) { + for (i2 = 0; i2 < graphs_curves_per_pos[g]; i2++, cv++) { + cairo_set_source_rgba(c, + graphs->g[cv].rgb[0], + graphs->g[cv].rgb[1], + graphs->g[cv].rgb[2], + graphs->g[cv].alpha); + for (i = 0; i < graphs_graph_width; i++) { + int idx = (pos_x + 1 + i + graphs_graph_width) % graphs_graph_width; + int y2 = y1 - graph_values[cv][idx] * (y1 - graphs->area.bg->border.width - graphs->area.paddingy); + if (graphs_use_bars) + cairo_move_to(c, x + i, y1); + cairo_line_to(c, x + i, y2); + } + cairo_stroke(c); + } + x += graphs->area.paddingx + graphs_graph_width; + } + pos_x = (pos_x + 1) % graphs_graph_width; +} + +int resize_graphs(void *obj) +{ + Graphs *graphs = obj; + int ret = 0; + + graphs->area._redraw_needed = TRUE; + + if (panel_horizontal) { + int new_size = (2 * graphs->area.paddingxlr) + (2 * graphs->area.bg->border.width) + + graphs_ngraphs * (graphs_graph_width) + (graphs_ngraphs - 1) * (graphs->area.paddingx); + if (new_size != graphs->area.width) { + graphs->area.width = new_size + 1; + ret = 1; + } + } + + return ret; +} + +void graphs_action(void *obj, int button, int x, int y, Time time) +{ + + char *command = NULL; + switch (button) { + case 1: + command = graphs_lclick_command; + break; + case 3: + command = graphs_rclick_command; + break; + } + + tint_exec(command, NULL, NULL, time, obj, x, y, FALSE, TRUE); +} diff --git a/src/graphs/graphs.h b/src/graphs/graphs.h new file mode 100644 index 0000000000000000000000000000000000000000..8ab203daf553153d3267b5905149381bb3a0825f --- /dev/null +++ b/src/graphs/graphs.h @@ -0,0 +1,52 @@ +/************************************************************************** + * Copyright (C) 2011 Francisco J. Vazquez (fjvazquezaraujo@gmail.com) + * + **************************************************************************/ + +#ifndef GRAPHS_H +#define GRAPHS_H + +#include "area.h" +#include "common.h" +#include + +#define MAXGRAPHS 3 +#define MAXCURVES 6 + +typedef struct Graphs { + // always start with area + Area area; + + char *netdev; + Color g[MAXCURVES]; +} Graphs; + +extern int graphs_enabled; +extern int graphs_ngraphs; +extern int graphs_ncurves; +extern int graphs_cpu_pos; +extern int graphs_mem_pos; +extern int graphs_net_pos; +extern int graphs_curves_per_pos[MAXGRAPHS]; +extern int graphs_use_bars; +extern int graphs_graph_width; +extern char *graphs_netiface; +extern int graphs_netmaxup; +extern int graphs_netmaxdown; +extern char *graphs_lclick_command; +extern char *graphs_rclick_command; + +void default_graphs(); + +void cleanup_graphs(); + +void init_graphs(); +void init_graphs_panel(void *panel); + +void draw_graphs(void *obj, cairo_t *c); + +int resize_graphs(void *obj); + +void graphs_action(void *obj, int button, int x, int y, Time time); + +#endif diff --git a/src/init.c b/src/init.c index 772997a2fef67c8a14d0ae1594f47ae318051529..7f660edab3f10f1b1e6d9040f7f089abf0f27959 100644 --- a/src/init.c +++ b/src/init.c @@ -5,16 +5,18 @@ #include #include #include +#include +#include #include #include -#include #include #include "config.h" #include "default_icon.h" #include "drag_and_drop.h" #include "fps_distribution.h" +#include "graphs.h" #include "panel.h" #include "server.h" #include "signals.h" @@ -57,7 +59,7 @@ void handle_cli_arguments(int argc, char **argv) run_all_tests(true); exit(0); } else if (strcmp(argv[i], "--dump-image-data") == 0) { - dump_image_data(argv[i+1], argv[i+2]); + dump_image_data(argv[i + 1], argv[i + 2]); exit(0); } else if (strcmp(argv[i], "-c") == 0) { if (i + 1 < argc) { @@ -164,6 +166,7 @@ void create_default_elements() default_battery(); #endif default_clock(); + default_graphs(); default_launcher(); default_taskbar(); default_tooltip(); @@ -182,9 +185,7 @@ void load_default_task_icon() g_free(path); } if (!default_icon) { - default_icon = imlib_create_image_using_data(default_icon_width, - default_icon_height, - default_icon_data); + default_icon = imlib_create_image_using_data(default_icon_width, default_icon_height, default_icon_data); } } @@ -273,6 +274,7 @@ void cleanup() cleanup_systray(); cleanup_tooltip(); cleanup_clock(); + cleanup_graphs(); cleanup_launcher(); #ifdef ENABLE_BATTERY cleanup_battery(); diff --git a/src/mouse_actions.c b/src/mouse_actions.c index 2f791fd8c70f720c12a815364a47fd3101947028..108df173ec6f3e16d03370fad20ac81190771208 100644 --- a/src/mouse_actions.c +++ b/src/mouse_actions.c @@ -1,18 +1,18 @@ /************************************************************************** -* Copyright (C) 2017 tint2 authors -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License version 2 -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -**************************************************************************/ + * Copyright (C) 2017 tint2 authors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **************************************************************************/ #include #include @@ -195,7 +195,24 @@ void handle_mouse_release_event(XEvent *e) Clock *clock = click_clock(panel, e->xbutton.x, e->xbutton.y); if (clock) { - clock_action(clock, e->xbutton.button, e->xbutton.x - clock->area.posx, e->xbutton.y - clock->area.posy, e->xbutton.time); + clock_action(clock, + e->xbutton.button, + e->xbutton.x - clock->area.posx, + e->xbutton.y - clock->area.posy, + e->xbutton.time); + if (panel_layer == BOTTOM_LAYER) + XLowerWindow(server.display, panel->main_win); + task_drag = 0; + return; + } + + Graphs *graphs = click_graphs(panel, e->xbutton.x, e->xbutton.y); + if (graphs) { + graphs_action(graphs, + e->xbutton.button, + e->xbutton.x - graphs->area.posx, + e->xbutton.y - graphs->area.posy, + e->xbutton.time); if (panel_layer == BOTTOM_LAYER) XLowerWindow(server.display, panel->main_win); task_drag = 0; @@ -205,7 +222,11 @@ void handle_mouse_release_event(XEvent *e) #ifdef ENABLE_BATTERY Battery *battery = click_battery(panel, e->xbutton.x, e->xbutton.y); if (battery) { - battery_action(battery, e->xbutton.button, e->xbutton.x - battery->area.posx, e->xbutton.y - battery->area.posy, e->xbutton.time); + battery_action(battery, + e->xbutton.button, + e->xbutton.x - battery->area.posx, + e->xbutton.y - battery->area.posy, + e->xbutton.time); if (panel_layer == BOTTOM_LAYER) XLowerWindow(server.display, panel->main_win); task_drag = 0; @@ -215,7 +236,11 @@ void handle_mouse_release_event(XEvent *e) Execp *execp = click_execp(panel, e->xbutton.x, e->xbutton.y); if (execp) { - execp_action(execp, e->xbutton.button, e->xbutton.x - execp->area.posx, e->xbutton.y - execp->area.posy, e->xbutton.time); + execp_action(execp, + e->xbutton.button, + e->xbutton.x - execp->area.posx, + e->xbutton.y - execp->area.posy, + e->xbutton.time); if (panel_layer == BOTTOM_LAYER) XLowerWindow(server.display, panel->main_win); task_drag = 0; @@ -224,7 +249,11 @@ void handle_mouse_release_event(XEvent *e) Button *button = click_button(panel, e->xbutton.x, e->xbutton.y); if (button) { - button_action(button, e->xbutton.button, e->xbutton.x - button->area.posx, e->xbutton.y - button->area.posy, e->xbutton.time); + button_action(button, + e->xbutton.button, + e->xbutton.x - button->area.posx, + e->xbutton.y - button->area.posy, + e->xbutton.time); if (panel_layer == BOTTOM_LAYER) XLowerWindow(server.display, panel->main_win); task_drag = 0; diff --git a/src/panel.c b/src/panel.c index 542c08797459c9b766454aab0b203d78d04a0a34..9dc1165f7ce41a84c47912e209f9cbb77356165b 100644 --- a/src/panel.c +++ b/src/panel.c @@ -1,40 +1,40 @@ /************************************************************************** -* -* Copyright (C) 2008 Pål Staurland (staura@gmail.com) -* Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr) from Omega distribution -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License version 2 -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -**************************************************************************/ + * + * Copyright (C) 2008 Pål Staurland (staura@gmail.com) + * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr) from Omega distribution + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **************************************************************************/ +#include +#include +#include +#include +#include #include +#include #include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include "server.h" #include "config.h" -#include "window.h" -#include "task.h" #include "panel.h" +#include "server.h" +#include "task.h" #include "tooltip.h" +#include "window.h" void panel_clear_background(void *obj); @@ -103,7 +103,7 @@ void default_panel() panel_autohide_height = 5; // for vertical panels this is of course the width panel_shrink = FALSE; panel_strut_policy = STRUT_FOLLOW_SIZE; - panel_dock = FALSE; // default not in the dock + panel_dock = FALSE; // default not in the dock panel_pivot_struts = FALSE; panel_layer = BOTTOM_LAYER; // default is bottom layer panel_window_name = strdup("tint2"); @@ -195,6 +195,7 @@ void init_panel() init_systray(); init_launcher(); init_clock(); + init_graphs(); #ifdef ENABLE_BATTERY init_battery(); #endif @@ -231,8 +232,11 @@ void init_panel() p->scale = 1; if (ui_scale_monitor_size_ref > 0) p->scale *= server.monitors[p->monitor].height / ui_scale_monitor_size_ref; - if (p->scale > 8 || p->scale < 1./8) { - fprintf(stderr, RED "tint2: panel %d having scale %g outside bounds, resetting to 1.0" RESET "\n", i + 1, p->scale); + if (p->scale > 8 || p->scale < 1. / 8) { + fprintf(stderr, + RED "tint2: panel %d having scale %g outside bounds, resetting to 1.0" RESET "\n", + i + 1, + p->scale); p->scale = 1; } fprintf(stderr, BLUE "tint2: panel %d uses scale %g " RESET "\n", i + 1, p->scale); @@ -255,6 +259,8 @@ void init_panel() init_launcher_panel(p); if (panel_items_order[k] == 'T') init_taskbar_panel(p); + if (panel_items_order[k] == 'G') + init_graphs_panel(p); #ifdef ENABLE_BATTERY if (panel_items_order[k] == 'B') init_battery_panel(p); @@ -432,8 +438,8 @@ void panel_compute_position(Panel *panel) panel->hidden_width = panel->area.width - diff; panel->hidden_height = panel->area.height; } - // fprintf(stderr, "tint2: panel : posx %d, posy %d, width %d, height %d\n", panel->posx, panel->posy, panel->area.width, - // panel->area.height); + // fprintf(stderr, "tint2: panel : posx %d, posy %d, width %d, height %d\n", panel->posx, panel->posy, + // panel->area.width, panel->area.height); } void init_panel_size_and_position(Panel *panel) @@ -528,7 +534,9 @@ gboolean resize_panel(void *obj) if (num_tasks > 0) { int task_size = total_size / num_tasks; if (taskbar_alignment != ALIGN_LEFT) - task_size = MIN(task_size, panel_horizontal ? panel_config.g_task.maximum_width : panel_config.g_task.maximum_height); + task_size = + MIN(task_size, + panel_horizontal ? panel_config.g_task.maximum_width : panel_config.g_task.maximum_height); for (int i = 0; i < panel->num_desktops; i++) { Taskbar *taskbar = &panel->taskbar[i]; if (!taskbar->area.on_screen) @@ -612,19 +620,19 @@ gboolean resize_panel(void *obj) return FALSE; } -#define STRUT_LEFT 0 -#define STRUT_RIGHT 1 -#define STRUT_TOP 2 -#define STRUT_BOTTOM 3 -#define STRUT_LEFT_Y1 4 -#define STRUT_LEFT_Y2 5 -#define STRUT_RIGHT_Y1 6 -#define STRUT_RIGHT_Y2 7 -#define STRUT_TOP_X1 8 -#define STRUT_TOP_X2 9 +#define STRUT_LEFT 0 +#define STRUT_RIGHT 1 +#define STRUT_TOP 2 +#define STRUT_BOTTOM 3 +#define STRUT_LEFT_Y1 4 +#define STRUT_LEFT_Y2 5 +#define STRUT_RIGHT_Y1 6 +#define STRUT_RIGHT_Y2 7 +#define STRUT_TOP_X1 8 +#define STRUT_TOP_X2 9 #define STRUT_BOTTOM_X1 10 #define STRUT_BOTTOM_X2 11 -#define STRUT_COUNT 12 +#define STRUT_COUNT 12 #define STRUT_COUNT_OLD 4 void update_strut(Panel *p) @@ -644,7 +652,8 @@ void update_strut(Panel *p) long struts[STRUT_COUNT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; if (panel_horizontal ^ panel_pivot_struts) { int height = p->area.height + p->marginy; - if (panel_strut_policy == STRUT_MINIMUM || (panel_strut_policy == STRUT_FOLLOW_SIZE && panel_autohide && p->is_hidden)) + if (panel_strut_policy == STRUT_MINIMUM || + (panel_strut_policy == STRUT_FOLLOW_SIZE && panel_autohide && p->is_hidden)) height = p->hidden_height; if (panel_position & TOP) { struts[STRUT_TOP] = height + monitor.y; @@ -659,7 +668,8 @@ void update_strut(Panel *p) } } else { int width = p->area.width + p->marginx; - if (panel_strut_policy == STRUT_MINIMUM || (panel_strut_policy == STRUT_FOLLOW_SIZE && panel_autohide && p->is_hidden)) + if (panel_strut_policy == STRUT_MINIMUM || + (panel_strut_policy == STRUT_FOLLOW_SIZE && panel_autohide && p->is_hidden)) width = p->hidden_width; if (panel_position & LEFT) { struts[STRUT_LEFT] = width + monitor.x; @@ -712,6 +722,10 @@ void set_panel_items_order(Panel *p) for (int j = 0; j < p->num_desktops; j++) p->area.children = g_list_append(p->area.children, &p->taskbar[j]); } + + if (panel_items_order[k] == 'G') + p->area.children = g_list_append(p->area.children, &p->graphs); + #ifdef ENABLE_BATTERY if (panel_items_order[k] == 'B') p->area.children = g_list_append(p->area.children, &p->battery); @@ -1073,6 +1087,14 @@ LauncherIcon *click_launcher_icon(Panel *panel, int x, int y) return NULL; } +Graphs *click_graphs(Panel *panel, int x, int y) +{ + Graphs *gr = &panel->graphs; + if (area_is_under_mouse(gr, x, y)) + return gr; + return NULL; +} + Clock *click_clock(Panel *panel, int x, int y) { Clock *clock = &panel->clock; diff --git a/src/panel.h b/src/panel.h index cf1373c897a45a736020cf4eaf3901c5e59d162a..0217144501d0396e3b9f7b4eb0a0e8e4fa3a6511 100644 --- a/src/panel.h +++ b/src/panel.h @@ -1,12 +1,12 @@ /************************************************************************** -* Copyright (C) 2008 Pål Staurland (staura@gmail.com) -* Modified (C) 2008/2009 thierry lorthiois (lorthiois@bbsoft.fr) -* -* panel : -* - draw panel and all objects according to panel_layout -* -* -**************************************************************************/ + * Copyright (C) 2008 Pål Staurland (staura@gmail.com) + * Modified (C) 2008/2009 thierry lorthiois (lorthiois@bbsoft.fr) + * + * panel : + * - draw panel and all objects according to panel_layout + * + * + **************************************************************************/ #ifndef PANEL_H #define PANEL_H @@ -14,16 +14,17 @@ #include #include -#include "common.h" +#include "button.h" #include "clock.h" -#include "task.h" -#include "taskbar.h" -#include "systraybar.h" -#include "launcher.h" -#include "freespace.h" +#include "common.h" #include "execplugin.h" +#include "freespace.h" +#include "graphs.h" +#include "launcher.h" #include "separator.h" -#include "button.h" +#include "systraybar.h" +#include "task.h" +#include "taskbar.h" #ifdef ENABLE_BATTERY #include "battery.h" @@ -136,6 +137,8 @@ typedef struct Panel { Clock clock; + Graphs graphs; + #ifdef ENABLE_BATTERY Battery battery; #endif @@ -192,6 +195,7 @@ Task *click_task(Panel *panel, int x, int y); Launcher *click_launcher(Panel *panel, int x, int y); LauncherIcon *click_launcher_icon(Panel *panel, int x, int y); Clock *click_clock(Panel *panel, int x, int y); +Graphs *click_graphs(Panel *panel, int x, int y); #ifdef ENABLE_BATTERY Battery *click_battery(Panel *panel, int x, int y);