fix(bar): 修复颜色缓存造成的颜色野指针从而导致无法正确渲染 cell 的 bug
This commit is contained in:
@@ -42,6 +42,8 @@ static void bar_item_cleanup(zdwm_bar_item_t *item) {
|
|||||||
for (size_t i = 0; i < item->count; ++i) {
|
for (size_t i = 0; i < item->count; ++i) {
|
||||||
auto cell = &item->cells[i];
|
auto cell = &item->cells[i];
|
||||||
p_delete(&cell->text);
|
p_delete(&cell->text);
|
||||||
|
p_delete(&cell->fg_text);
|
||||||
|
p_delete(&cell->bg_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_delete(&item->cells);
|
p_delete(&item->cells);
|
||||||
@@ -141,8 +143,6 @@ void bar_cleanup(bar_t *bar) {
|
|||||||
}
|
}
|
||||||
p_delete(&bar->bars);
|
p_delete(&bar->bars);
|
||||||
bar->count = 0;
|
bar->count = 0;
|
||||||
|
|
||||||
bar_cell_clean_color_cache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bar_item_update(zdwm_bar_item_t *item) {
|
static inline void bar_item_update(zdwm_bar_item_t *item) {
|
||||||
@@ -258,7 +258,7 @@ static void bar_item_draw(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_background(cr, cell->bg, cell_area);
|
draw_background(cr, &cell->bg, cell_area);
|
||||||
|
|
||||||
if (cell->show_indicator) {
|
if (cell->show_indicator) {
|
||||||
auto size = MIN(item->indicator_width, cell_area.width);
|
auto size = MIN(item->indicator_width, cell_area.width);
|
||||||
@@ -271,7 +271,7 @@ static void bar_item_draw(
|
|||||||
.width = size,
|
.width = size,
|
||||||
.height = size,
|
.height = size,
|
||||||
};
|
};
|
||||||
draw_background(cr, cell->fg, indicator_area);
|
draw_background(cr, &cell->fg, indicator_area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ static void bar_item_draw(
|
|||||||
.height = height,
|
.height = height,
|
||||||
};
|
};
|
||||||
if (text_area.width > 0) {
|
if (text_area.width > 0) {
|
||||||
draw_text(cr, ctx, cell->text, cell->fg, text_area);
|
draw_text(cr, ctx, cell->text, &cell->fg, text_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->dirty = false;
|
cell->dirty = false;
|
||||||
|
|||||||
@@ -2,63 +2,25 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <zdwm/types.h>
|
#include <zdwm/types.h>
|
||||||
|
|
||||||
#include "bar/types.h"
|
#include "bar/types.h"
|
||||||
#include "base/array.h"
|
|
||||||
#include "base/color.h"
|
#include "base/color.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
|
|
||||||
typedef struct color_cache_item_t {
|
|
||||||
const char *text;
|
|
||||||
color_t color;
|
|
||||||
} color_cache_item_t;
|
|
||||||
|
|
||||||
typedef struct color_cache_t {
|
|
||||||
color_cache_item_t *items;
|
|
||||||
size_t count;
|
|
||||||
size_t capacity;
|
|
||||||
} color_cache_t;
|
|
||||||
|
|
||||||
static color_cache_t cache = {};
|
|
||||||
|
|
||||||
static color_t *find_or_insert_color(const char *text) {
|
|
||||||
assert(text);
|
|
||||||
for (size_t i = 0; i < cache.count; ++i) {
|
|
||||||
auto item = &cache.items[i];
|
|
||||||
if (text == item->text || strcasecmp(text, item->text) == 0) {
|
|
||||||
return &item->color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto slot = array_push(cache.items, cache.count, cache.capacity);
|
|
||||||
slot->text = p_strdup(text);
|
|
||||||
color_parse(text, &slot->color);
|
|
||||||
return &slot->color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bar_cell_reset_color_cache(void) {
|
|
||||||
for (size_t i = 0; i < cache.count; ++i) {
|
|
||||||
auto item = &cache.items[i];
|
|
||||||
p_delete(&item->text);
|
|
||||||
}
|
|
||||||
p_clear(cache.items, cache.count);
|
|
||||||
cache.count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bar_cell_clean_color_cache(void) {
|
|
||||||
bar_cell_reset_color_cache();
|
|
||||||
p_delete(&cache.items);
|
|
||||||
cache.capacity = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t bar_cell_get_count(zdwm_bar_item_t *item) { return item->count; }
|
static size_t bar_cell_get_count(zdwm_bar_item_t *item) { return item->count; }
|
||||||
|
|
||||||
static void bar_cell_set_count(zdwm_bar_item_t *item, size_t count) {
|
static void bar_cell_set_count(zdwm_bar_item_t *item, size_t count) {
|
||||||
if (item->count == count) return;
|
if (item->count == count) return;
|
||||||
|
|
||||||
for (size_t i = 0; i < item->count; ++i) p_delete(&item->cells[i].text);
|
for (size_t i = 0; i < item->count; ++i) {
|
||||||
|
auto cell = &item->cells[i];
|
||||||
|
p_delete(cell->text);
|
||||||
|
p_delete(&cell->fg_text);
|
||||||
|
p_delete(&cell->bg_text);
|
||||||
|
}
|
||||||
|
|
||||||
item->count = count;
|
item->count = count;
|
||||||
p_realloc(&item->cells, count);
|
p_realloc(&item->cells, count);
|
||||||
@@ -85,11 +47,12 @@ static void
|
|||||||
bar_cell_set_bg(zdwm_bar_item_t *item, size_t index, const char *color) {
|
bar_cell_set_bg(zdwm_bar_item_t *item, size_t index, const char *color) {
|
||||||
if (index >= item->count) return;
|
if (index >= item->count) return;
|
||||||
|
|
||||||
auto cell = &item->cells[index];
|
auto cell = &item->cells[index];
|
||||||
auto cached_color = find_or_insert_color(color);
|
|
||||||
if (cell->bg == cached_color) return;
|
|
||||||
|
|
||||||
cell->bg = cached_color;
|
if (cell->bg_text && strcmp(color, cell->bg_text) == 0) return;
|
||||||
|
|
||||||
|
cell->bg_text = p_strdup(color);
|
||||||
|
color_parse(color, &cell->bg);
|
||||||
|
|
||||||
cell->dirty = true;
|
cell->dirty = true;
|
||||||
item->dirty = true;
|
item->dirty = true;
|
||||||
@@ -99,11 +62,11 @@ static void
|
|||||||
bar_cell_set_fg(zdwm_bar_item_t *item, size_t index, const char *color) {
|
bar_cell_set_fg(zdwm_bar_item_t *item, size_t index, const char *color) {
|
||||||
if (index >= item->count) return;
|
if (index >= item->count) return;
|
||||||
|
|
||||||
auto cell = &item->cells[index];
|
auto cell = &item->cells[index];
|
||||||
auto cached_color = find_or_insert_color(color);
|
if (cell->fg_text && strcmp(color, cell->fg_text) == 0) return;
|
||||||
if (cell->fg == cached_color) return;
|
|
||||||
|
|
||||||
cell->fg = cached_color;
|
cell->fg_text = p_strdup(color);
|
||||||
|
color_parse(color, &cell->fg);
|
||||||
|
|
||||||
cell->dirty = true;
|
cell->dirty = true;
|
||||||
item->dirty = true;
|
item->dirty = true;
|
||||||
|
|||||||
@@ -6,9 +6,6 @@
|
|||||||
|
|
||||||
#include "bar/types.h"
|
#include "bar/types.h"
|
||||||
|
|
||||||
void bar_cell_reset_color_cache(void);
|
|
||||||
void bar_cell_clean_color_cache(void);
|
|
||||||
|
|
||||||
void bar_cell_set_region(
|
void bar_cell_set_region(
|
||||||
zdwm_bar_item_t *item,
|
zdwm_bar_item_t *item,
|
||||||
size_t index,
|
size_t index,
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ typedef struct bar_x_region_t {
|
|||||||
typedef struct bar_cell_t {
|
typedef struct bar_cell_t {
|
||||||
zdwm_icon_t icon;
|
zdwm_icon_t icon;
|
||||||
char *text; /* 持有内存,避免野指针问题 */
|
char *text; /* 持有内存,避免野指针问题 */
|
||||||
const color_t *fg;
|
char *fg_text;
|
||||||
const color_t *bg;
|
char *bg_text;
|
||||||
|
color_t fg;
|
||||||
|
color_t bg;
|
||||||
bar_x_region_t region;
|
bar_x_region_t region;
|
||||||
bool show_indicator;
|
bool show_indicator;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
|
|||||||
Reference in New Issue
Block a user