feat: implement fixed-width toggling top process display for CPU and memory

This commit is contained in:
retoor 2026-01-27 12:18:45 +01:00
parent 2017a9b666
commit b0b1a854cf
3 changed files with 44 additions and 100 deletions

BIN
bin/dwn

Binary file not shown.

Binary file not shown.

View File

@ -30,6 +30,7 @@
#define WORKSPACE_WIDTH 36
#define TASKBAR_ITEM_WIDTH 180
#define TOP_PROCESS_NAME_MAX_LEN 12
#define TOP_PROCESS_WIDGET_WIDTH 150
#define CLOCK_FORMAT "%H:%M:%S"
#define DATE_FORMAT "%Y-%m-%d"
@ -94,6 +95,8 @@ typedef struct {
int process_display_index;
int process_category;
long process_last_cycle;
bool process_show_cpu;
long process_toggle_time;
} SystemStats;
static ProcCpuState proc_cpu_history[PROC_CPU_HISTORY_SIZE];
@ -105,7 +108,6 @@ static SystemStats sys_stats = {0};
static void panel_render_system_stats(Panel *panel, int x, int *width);
static int panel_calculate_stats_width(void);
static void panel_render_top_process(Panel *panel, int x, int *width);
static int panel_calculate_top_process_width(void);
static void panel_render_key_counter(Panel *panel, int x, int *width);
static void panel_render_mouse_distance(Panel *panel, int x, int *width);
static void panel_render_disk_space(Panel *panel, int x, int *width);
@ -411,8 +413,12 @@ void panel_render(Panel *panel)
date_width = panel_text_width(date_buffer, strlen(date_buffer));
}
int top_proc_width = 0;
int top_proc_x = PANEL_PADDING + date_width + WIDGET_SPACING;
panel_render_top_process(panel, top_proc_x, &top_proc_width);
int key_counter_width = 0;
int key_counter_x = PANEL_PADDING + date_width + WIDGET_SPACING;
int key_counter_x = top_proc_x + top_proc_width + WIDGET_SPACING;
panel_render_key_counter(panel, key_counter_x, &key_counter_width);
int mouse_dist_width = 0;
@ -425,7 +431,6 @@ void panel_render(Panel *panel)
int clock_width = panel_text_width(clock_buffer, strlen(clock_buffer));
int stats_width = panel_calculate_stats_width();
int top_proc_width = panel_calculate_top_process_width();
int clock_x = panel->width - clock_width - PANEL_PADDING;
panel_render_clock(panel, clock_x, &width);
@ -433,12 +438,8 @@ void panel_render(Panel *panel)
int stats_x = clock_x - stats_width - WIDGET_SPACING;
panel_render_system_stats(panel, stats_x, &width);
int top_proc_x = stats_x - top_proc_width - WIDGET_SPACING;
int actual_top_proc_width = 0;
panel_render_top_process(panel, top_proc_x, &actual_top_proc_width);
int news_start = disk_space_x + disk_space_width + WIDGET_SPACING;
int news_max_width = top_proc_x - news_start - WIDGET_SPACING;
int news_max_width = stats_x - news_start - WIDGET_SPACING;
if (news_max_width > 100) {
panel_set_news_region(news_start, news_max_width);
int news_width = 0;
@ -1424,54 +1425,6 @@ static void panel_render_disk_space(Panel *panel, int x, int *width)
*width = panel_text_width(buf, len);
}
static int panel_calculate_top_process_width(void)
{
if (dwn->xft_font == NULL && dwn->font == NULL) return 0;
int mem_count = sys_stats.top_mem_count;
int cpu_count = sys_stats.top_cpu_count;
if (mem_count == 0 && cpu_count == 0) return 0;
int idx = sys_stats.process_display_index;
char buf[128];
char name_buf[TOP_PROCESS_NAME_MAX_LEN + 1];
const char *proc_name;
size_t name_len;
int len;
int total = 0;
if (mem_count > 0) {
int mem_idx = (idx >= mem_count) ? 0 : idx;
proc_name = sys_stats.top_mem_processes[mem_idx];
name_len = strlen(proc_name);
if (name_len > TOP_PROCESS_NAME_MAX_LEN) {
strncpy(name_buf, proc_name, TOP_PROCESS_NAME_MAX_LEN - 2);
name_buf[TOP_PROCESS_NAME_MAX_LEN - 2] = '\0';
strncat(name_buf, "..", 3);
proc_name = name_buf;
}
len = snprintf(buf, sizeof(buf), "M:%s %d%%", proc_name, sys_stats.top_mem_percents[mem_idx]);
total += panel_text_width(buf, len);
}
if (cpu_count > 0) {
if (total > 0) total += WIDGET_SPACING;
int cpu_idx = (idx >= cpu_count) ? 0 : idx;
proc_name = sys_stats.top_cpu_processes[cpu_idx];
name_len = strlen(proc_name);
if (name_len > TOP_PROCESS_NAME_MAX_LEN) {
strncpy(name_buf, proc_name, TOP_PROCESS_NAME_MAX_LEN - 2);
name_buf[TOP_PROCESS_NAME_MAX_LEN - 2] = '\0';
strncat(name_buf, "..", 3);
proc_name = name_buf;
}
len = snprintf(buf, sizeof(buf), "C:%s %d%%", proc_name, sys_stats.top_cpu_percents[cpu_idx]);
total += panel_text_width(buf, len);
}
return total;
}
static void panel_render_top_process(Panel *panel, int x, int *width)
{
if (panel == NULL || width == NULL) {
@ -1491,33 +1444,30 @@ static void panel_render_top_process(Panel *panel, int x, int *width)
}
long now = get_time_ms();
if (now - sys_stats.process_last_cycle >= 3000) {
sys_stats.process_display_index++;
if (sys_stats.process_display_index >= 3) {
sys_stats.process_display_index = 0;
}
sys_stats.process_last_cycle = now;
if (now - sys_stats.process_toggle_time >= 3000) {
sys_stats.process_show_cpu = !sys_stats.process_show_cpu;
sys_stats.process_toggle_time = now;
}
const ColorScheme *colors = config_get_colors();
int text_y = panel_text_y(panel->height);
int idx = sys_stats.process_display_index;
char buf[128];
char name_buf[TOP_PROCESS_NAME_MAX_LEN + 1];
int len;
unsigned long color;
const char *proc_name;
size_t name_len;
int text_width;
int total_width = panel_calculate_top_process_width();
int right_edge = x + total_width;
int current_right = right_edge;
int prefix_width = panel_text_width("M:", 2);
int suffix_width = panel_text_width(" 100%", 5);
int available_for_name = TOP_PROCESS_WIDGET_WIDTH - prefix_width - suffix_width;
if (cpu_count > 0) {
int cpu_idx = (idx >= cpu_count) ? 0 : idx;
int percent = sys_stats.top_cpu_percents[cpu_idx];
bool show_cpu = sys_stats.process_show_cpu;
if (show_cpu && cpu_count == 0) show_cpu = false;
if (!show_cpu && mem_count == 0) show_cpu = true;
if (show_cpu && cpu_count > 0) {
int percent = sys_stats.top_cpu_percents[0];
color = colors->panel_fg;
if (percent >= 50) {
color = 0x4169E1;
@ -1525,24 +1475,17 @@ static void panel_render_top_process(Panel *panel, int x, int *width)
color = 0x00CED1;
}
color = ambient_glow_bg(color, dwn->ambient_phase + PHASE_OFFSET_TOP_CPU);
proc_name = sys_stats.top_cpu_processes[cpu_idx];
name_len = strlen(proc_name);
if (name_len > TOP_PROCESS_NAME_MAX_LEN) {
strncpy(name_buf, proc_name, TOP_PROCESS_NAME_MAX_LEN - 2);
name_buf[TOP_PROCESS_NAME_MAX_LEN - 2] = '\0';
strncat(name_buf, "..", 3);
proc_name = name_buf;
}
len = snprintf(buf, sizeof(buf), "C:%s %d%%", proc_name, percent);
text_width = panel_text_width(buf, len);
int text_x = current_right - text_width;
panel_draw_text(panel->buffer, text_x, text_y, buf, len, color);
current_right = text_x - WIDGET_SPACING;
}
if (mem_count > 0) {
int mem_idx = (idx >= mem_count) ? 0 : idx;
int percent = sys_stats.top_mem_percents[mem_idx];
proc_name = sys_stats.top_cpu_processes[0];
strncpy(name_buf, proc_name, TOP_PROCESS_NAME_MAX_LEN);
name_buf[TOP_PROCESS_NAME_MAX_LEN] = '\0';
while (strlen(name_buf) > 2 && panel_text_width(name_buf, (int)strlen(name_buf)) > available_for_name) {
name_buf[strlen(name_buf) - 1] = '\0';
}
len = snprintf(buf, sizeof(buf), "C:%s %d%%", name_buf, percent);
} else if (mem_count > 0) {
int percent = sys_stats.top_mem_percents[0];
color = colors->panel_fg;
if (percent >= 50) {
color = colors->workspace_urgent;
@ -1550,21 +1493,22 @@ static void panel_render_top_process(Panel *panel, int x, int *width)
color = 0xFFA500;
}
color = ambient_glow_bg(color, dwn->ambient_phase + PHASE_OFFSET_TOP_MEM);
proc_name = sys_stats.top_mem_processes[mem_idx];
name_len = strlen(proc_name);
if (name_len > TOP_PROCESS_NAME_MAX_LEN) {
strncpy(name_buf, proc_name, TOP_PROCESS_NAME_MAX_LEN - 2);
name_buf[TOP_PROCESS_NAME_MAX_LEN - 2] = '\0';
strncat(name_buf, "..", 3);
proc_name = name_buf;
proc_name = sys_stats.top_mem_processes[0];
strncpy(name_buf, proc_name, TOP_PROCESS_NAME_MAX_LEN);
name_buf[TOP_PROCESS_NAME_MAX_LEN] = '\0';
while (strlen(name_buf) > 2 && panel_text_width(name_buf, (int)strlen(name_buf)) > available_for_name) {
name_buf[strlen(name_buf) - 1] = '\0';
}
len = snprintf(buf, sizeof(buf), "M:%s %d%%", proc_name, percent);
text_width = panel_text_width(buf, len);
int text_x = current_right - text_width;
panel_draw_text(panel->buffer, text_x, text_y, buf, len, color);
len = snprintf(buf, sizeof(buf), "M:%s %d%%", name_buf, percent);
} else {
*width = 0;
return;
}
*width = total_width;
panel_draw_text(panel->buffer, x, text_y, buf, len, color);
*width = TOP_PROCESS_WIDGET_WIDTH;
}