diff --git a/src/background.c b/src/background.c index 5302b87..0cee896 100644 --- a/src/background.c +++ b/src/background.c @@ -3,8 +3,10 @@ void background_init(struct background* background) { background->enabled = false; + background->overrides_height = false; background->height = 0; + background->width = 0; background->border_width = 0; background->padding_left = 0; background->padding_right = 0; @@ -44,6 +46,7 @@ bool background_set_enabled(struct background* background, bool enabled) { bool background_set_height(struct background* background, uint32_t height) { if (background->height == height) return false; background->height = height; + background->overrides_height = height != 0; return true; } @@ -71,6 +74,12 @@ bool background_set_padding_right(struct background* background, uint32_t pad) { return true; } +void background_draw(struct background* background, CGPoint origin, CGContextRef context) { + if (!background->enabled) return; + CGRect draw_region = {{origin.x, origin.y}, {background->width, background->height}}; + draw_rect(context, draw_region, &background->color, background->corner_radius, background->border_width, &background->border_color, false); +} + static bool background_parse_sub_domain(struct background* background, FILE* rsp, struct token property, char* message) { if (token_equals(property, PROPERTY_DRAWING)) return background_set_enabled(background, evaluate_boolean_state(get_token(&message), background->enabled)); diff --git a/src/background.h b/src/background.h index 59edd08..14df446 100644 --- a/src/background.h +++ b/src/background.h @@ -1,9 +1,12 @@ #ifndef BACKGROUND_H #define BACKGROUND_H +#include struct background { bool enabled; + bool overrides_height; uint32_t height; + uint32_t width; uint32_t corner_radius; uint32_t border_width; int padding_left; @@ -22,6 +25,8 @@ bool background_set_corner_radius(struct background* background, uint32_t corner bool background_set_padding_left(struct background* background, uint32_t pad); bool background_set_padding_right(struct background* background, uint32_t pad); +void background_draw(struct background* background, CGPoint origin, CGContextRef context); + static bool background_parse_sub_domain(struct background* background, FILE* rsp, struct token property, char* message); #endif // !BACKGROUND_H diff --git a/src/bar.c b/src/bar.c index 8324601..a3b3fa3 100644 --- a/src/bar.c +++ b/src/bar.c @@ -2,7 +2,9 @@ #include "alias.h" #include "bar_item.h" #include "display.h" +#include "graph.h" #include "misc/helpers.h" +#include "text.h" #include <_types/_uint32_t.h> #include @@ -34,12 +36,6 @@ static CGPoint bar_align_line(struct bar *bar, struct text_line* line, int align return (CGPoint) { x, y }; } -static void bar_draw_line(struct bar *bar, struct text_line* line, float x, float y) { - CGContextSetRGBFillColor(bar->context, line->color.r, line->color.g, line->color.b, line->color.a); - CGContextSetTextPosition(bar->context, x, y); - CTLineDraw(line->line, bar->context); -} - void bar_draw_graph_line(struct bar *bar, struct graph* graph, uint32_t x, uint32_t y, uint32_t height, bool right_to_left) { y-= height / 2; uint32_t sample_width = 1; @@ -121,30 +117,11 @@ bool bar_draws_item(struct bar* bar, struct bar_item* bar_item) { } void bar_draw_bar_items(struct bar* bar) { - bool atomic_redraw = true; SLSDisableUpdate(g_connection); SLSOrderWindow(g_connection, bar->id, -1, 0); SLSRemoveAllTrackingAreas(g_connection, bar->id); - if (g_bar_manager.picky_redraw) { - for (int i = 0; i < g_bar_manager.bar_item_count; i++) { - struct bar_item* bar_item = g_bar_manager.bar_items[i]; - - if (!bar_item->queued_for_redraw || !bar_draws_item(bar, bar_item)) continue; - if (atomic_redraw && bar_item->num_rects >= bar->adid && bar_item->bounding_rects[bar->adid - 1]) { - CGRect draw_region = {{bar_item->bounding_rects[bar->adid - 1]->origin.x - bar->origin.x, 0}, - {bar_item->bounding_rects[bar->adid - 1]->size.width, bar->frame.size.height}}; - draw_rect(bar->context, CGRectInset(draw_region, g_bar_manager.background.border_width, 0), &g_bar_manager.background.color, 0, 0, &g_bar_manager.background.border_color, true); - } - atomic_redraw &= bar_item->redraw_in_place; - } - } else - atomic_redraw = false; - - if (!bar->background_exists || !atomic_redraw) { - draw_rect(bar->context, bar->frame, &g_bar_manager.background.color, g_bar_manager.background.corner_radius, g_bar_manager.background.border_width, &g_bar_manager.background.border_color, true); - bar->background_exists = true; - } + draw_rect(bar->context, bar->frame, &g_bar_manager.background.color, g_bar_manager.background.corner_radius, g_bar_manager.background.border_width, &g_bar_manager.background.border_color, true); for (int i = 0; i < g_bar_manager.bar_item_count; i++) { struct bar_item* bar_item = g_bar_manager.bar_items[i]; @@ -153,20 +130,18 @@ void bar_draw_bar_items(struct bar* bar) { if (!bar_draws_item(bar, bar_item)) continue; bar_item_append_associated_bar(bar_item, bar->adid); - if (!bar_item->queued_for_redraw && atomic_redraw) continue; if (bar_item->update_mask & UPDATE_MOUSE_ENTERED || bar_item->update_mask & UPDATE_MOUSE_EXITED) SLSAddTrackingRect(g_connection, bar->id, CGRectInset(bar_item_construct_bounding_rect(bar_item), 1, 1)); - struct text_line* label = &bar_item->label.line; - struct text_line* icon = &bar_item->icon.line; - bar_item_set_bounding_rect_for_display(bar_item, bar->adid, bar->origin); bar_draw_group(bar, bar_item, bar->adid); bar_draw_item_background(bar, bar_item, bar->adid); - bar_draw_line(bar, icon, icon->bounds.origin.x, icon->bounds.origin.y + bar_item->y_offset); - bar_draw_line(bar, label, label->bounds.origin.x, label->bounds.origin.y + bar_item->y_offset); + + text_draw(&bar_item->icon, bar_item->icon.line.bounds.origin, bar->context); + text_draw(&bar_item->label, bar_item->label.line.bounds.origin, bar->context); + bar_draw_alias(bar, bar_item, bar_item->sandwich_position); bar_draw_graph(bar, bar_item, bar_item->sandwich_position, bar_item->graph.rtl); } @@ -191,93 +166,83 @@ void bar_redraw(struct bar* bar) { struct text_line* label = &bar_item->label.line; struct text_line* icon = &bar_item->icon.line; + CGPoint icon_position = bar_align_line(bar, icon, ALIGN_CENTER, ALIGN_CENTER); + icon_position.y += bar_item->y_offset; + CGPoint label_position = bar_align_line(bar, label, ALIGN_CENTER, ALIGN_CENTER); + label_position.y += bar_item->y_offset; + uint32_t sandwich_position = 0; - bool graph_rtl = false; + bool rtl = false; if (bar_item->position == POSITION_LEFT) { - icon_position.x = bar_left_final_item_x + bar_item->icon.padding_left + bar_item->background.padding_left + 1; - label_position.x = icon_position.x + icon->bounds.size.width + bar_item->icon.padding_right + bar_item->label.padding_left; + icon_position.x = bar_left_final_item_x + bar_item->background.padding_left + 1; + label_position.x = icon_position.x + text_get_length(&bar_item->icon); if (!bar_item->has_const_width) - bar_left_final_item_x = label_position.x + label->bounds.size.width + bar_item->label.padding_right + bar_item->background.padding_right; + bar_left_final_item_x = label_position.x + text_get_length(&bar_item->label) + bar_item->background.padding_right; else bar_left_final_item_x += bar_item->custom_width; + sandwich_position = label_position.x; if (bar_item->has_graph) { if (!bar_item->has_const_width) - bar_left_final_item_x += bar_item->graph.width; - sandwich_position = label_position.x - bar_item->label.padding_left; - label_position.x += bar_item->graph.width; + bar_left_final_item_x += graph_get_length(&bar_item->graph); + label_position.x += graph_get_length(&bar_item->graph); } else if (bar_item->has_alias) { if (!bar_item->has_const_width) - bar_left_final_item_x += bar_item->alias.bounds.size.width; - sandwich_position = label_position.x - bar_item->label.padding_left; - label_position.x += bar_item->alias.bounds.size.width; + bar_left_final_item_x += alias_get_length(&bar_item->alias); + label_position.x += alias_get_length(&bar_item->alias); } } else if (bar_item->position == POSITION_RIGHT) { - label_position.x = bar_right_first_item_x - label->bounds.size.width - bar_item->label.padding_right - bar_item->background.padding_right; - icon_position.x = label_position.x - icon->bounds.size.width - bar_item->icon.padding_right - bar_item->label.padding_left - 1; + rtl = true; + label_position.x = bar_right_first_item_x - text_get_length(&bar_item->label) - bar_item->background.padding_right; + icon_position.x = label_position.x - text_get_length(&bar_item->icon) - 1; if (!bar_item->has_const_width) - bar_right_first_item_x = icon_position.x - bar_item->icon.padding_left - bar_item->background.padding_left; + bar_right_first_item_x = icon_position.x - bar_item->background.padding_left; else bar_right_first_item_x -= bar_item->custom_width; if (bar_item->has_graph) { - graph_rtl = true; if (!bar_item->has_const_width) - bar_right_first_item_x -= bar_item->graph.width; - sandwich_position = icon_position.x + bar_item->icon.padding_right + icon->bounds.size.width; - icon_position.x -= bar_item->graph.width; + bar_right_first_item_x -= graph_get_length(&bar_item->graph); + sandwich_position = icon_position.x + text_get_length(&bar_item->icon); + icon_position.x -= graph_get_length(&bar_item->graph); } else if (bar_item->has_alias) { if (!bar_item->has_const_width) - icon_position.x -= bar_item->alias.bounds.size.width; - sandwich_position = icon_position.x + bar_item->icon.padding_right + icon->bounds.size.width; - bar_right_first_item_x -= bar_item->alias.bounds.size.width; + icon_position.x -= alias_get_length(&bar_item->alias); + bar_right_first_item_x -= alias_get_length(&bar_item->alias); + sandwich_position = icon_position.x + text_get_length(&bar_item->icon); } } else if (bar_item->position == POSITION_CENTER) { - icon_position.x = bar_center_first_item_x + bar_item->icon.padding_left + bar_item->background.padding_left + 1; - label_position.x = icon_position.x + icon->bounds.size.width + bar_item->icon.padding_right + bar_item->label.padding_left; + icon_position.x = bar_center_first_item_x + bar_item->background.padding_left + 1; + label_position.x = icon_position.x + text_get_length(&bar_item->icon); if (!bar_item->has_const_width) - bar_center_first_item_x = label_position.x + label->bounds.size.width + bar_item->label.padding_right + bar_item->background.padding_right; + bar_center_first_item_x = label_position.x + text_get_length(&bar_item->label) + bar_item->background.padding_right; else bar_center_first_item_x += bar_item->custom_width; + sandwich_position = label_position.x; if (bar_item->has_graph) { if (!bar_item->has_const_width) - bar_center_first_item_x += bar_item->graph.width; - sandwich_position = label_position.x - bar_item->label.padding_left; - label_position.x += bar_item->graph.width; + bar_center_first_item_x += graph_get_length(&bar_item->graph); + label_position.x += graph_get_length(&bar_item->graph); } else if (bar_item->has_alias) { if (!bar_item->has_const_width) - bar_center_first_item_x += bar_item->alias.bounds.size.width; - sandwich_position = label_position.x - bar_item->label.padding_left; - label_position.x += bar_item->alias.bounds.size.width; + bar_center_first_item_x += alias_get_length(&bar_item->alias); + label_position.x += alias_get_length(&bar_item->alias); } } - bar_item->queued_for_redraw = true; - bar_item->redraw_in_place = false; - if (g_bar_manager.picky_redraw) { - if (bar_item->num_rects >= bar->adid && bar_item->bounding_rects[bar->adid - 1]) { - if ((bar_item->bounding_rects[bar->adid - 1]->origin.x == icon_position.x - bar_item->icon.padding_left + bar->origin.x) && !bar_item->needs_update) { - bar_item->queued_for_redraw = false; - } - else if (bar_item->bounding_rects[bar->adid - 1]->origin.x == icon_position.x - bar_item->icon.padding_left + bar->origin.x - && bar_item->needs_update - && bar_item->bounding_rects[bar->adid - 1]->size.width >= bar_item_construct_bounding_rect(bar_item).size.width) - bar_item->redraw_in_place = true; - } - } + bar_item->icon.line.bounds.origin = icon_position; + bar_item->label.line.bounds.origin = label_position; - label->bounds.origin = label_position; - icon->bounds.origin = icon_position; - bar_item->graph.rtl = graph_rtl; + bar_item->graph.rtl = rtl; bar_item->sandwich_position = sandwich_position; } diff --git a/src/bar.h b/src/bar.h index 570e73f..b9e87ec 100644 --- a/src/bar.h +++ b/src/bar.h @@ -37,7 +37,6 @@ extern CGError SLSWindowSetShadowProperties(uint32_t wid, CFDictionaryRef proper struct bar { bool hidden; - bool background_exists; uint32_t id; uint32_t did; uint32_t sid; diff --git a/src/bar_item.c b/src/bar_item.c index 510cfac..acd62ef 100644 --- a/src/bar_item.c +++ b/src/bar_item.c @@ -295,7 +295,6 @@ void bar_item_remove_bounding_rect_for_display(struct bar_item* bar_item, uint32 CGRect bar_item_construct_bounding_rect(struct bar_item* bar_item) { CGRect bounding_rect; bounding_rect.origin = bar_item->icon.line.bounds.origin; - bounding_rect.origin.x -= bar_item->icon.padding_left; bounding_rect.origin.y = bar_item->icon.line.bounds.origin.y < bar_item->label.line.bounds.origin.y ? bar_item->icon.line.bounds.origin.y : bar_item->label.line.bounds.origin.y + bar_item->y_offset; bounding_rect.size.width = bar_item_get_length(bar_item); bounding_rect.size.height = bar_item_get_height(bar_item); diff --git a/src/bar_item.h b/src/bar_item.h index 01ae135..a366c12 100644 --- a/src/bar_item.h +++ b/src/bar_item.h @@ -20,8 +20,6 @@ struct bar_item { bool drawing; bool has_const_width; uint32_t custom_width; - bool queued_for_redraw; - bool redraw_in_place; // These are 32bit masks where the ith bit represents the ith screen/display/bar association uint32_t associated_bar; diff --git a/src/misc/helpers.h b/src/misc/helpers.h index ae0b5f6..c2833d0 100644 --- a/src/misc/helpers.h +++ b/src/misc/helpers.h @@ -5,7 +5,7 @@ #include #define array_count(a) (sizeof((a)) / sizeof(*(a))) #define MAXLEN 512 -#define FORK_TIMEOUT 10 +#define FORK_TIMEOUT 60 #include extern CFArrayRef SLSCopyManagedDisplaySpaces(int cid); diff --git a/src/text.c b/src/text.c index d9a29a9..6c89432 100644 --- a/src/text.c +++ b/src/text.c @@ -26,9 +26,13 @@ static CTFontRef text_create_font(char *cstring) { } void text_init(struct text* text) { + text->drawing = true; text->highlight = false; + text->has_const_width = false; + text->custom_width = 0; text->padding_left = 0; text->padding_right = 0; + text->y_offset = 0; text->color = rgba_color_from_hex(0xffffffff); @@ -105,6 +109,8 @@ void text_clear_pointers(struct text* text) { } uint32_t text_get_length(struct text* text) { + if (!text->drawing) return 0; + if (text->has_const_width) return text->custom_width; return (text->line.bounds.size.width + text->padding_left + text->padding_right) > 0 ? (text->line.bounds.size.width + text->padding_left + text->padding_right) : 0; } @@ -125,25 +131,45 @@ void text_destroy(struct text* text) { text_clear_pointers(text); } +void text_draw(struct text* text, CGPoint origin, CGContextRef context) { + if (!text->drawing) return; + CGContextSetRGBFillColor(context, text->line.color.r, text->line.color.g, text->line.color.b, text->line.color.a); + CGContextSetTextPosition(context, origin.x + text->padding_left, origin.y + text->y_offset); + CTLineDraw(text->line.line, context); +} + static bool text_parse_sub_domain(struct text* text, FILE* rsp, struct token property, char* message) { if (token_equals(property, PROPERTY_COLOR)) return text_set_color(text, token_to_uint32t(get_token(&message))); else if (token_equals(property, PROPERTY_HIGHLIGHT)) { text->highlight = evaluate_boolean_state(get_token(&message), text->highlight); return text_update_color(text); - } - else if (token_equals(property, PROPERTY_FONT)) + } else if (token_equals(property, PROPERTY_FONT)) return text_set_font(text, string_copy(message), false); else if (token_equals(property, PROPERTY_HIGHLIGHT_COLOR)) { text->highlight_color = rgba_color_from_hex(token_to_uint32t(get_token(&message))); return text_update_color(text); - } - else if (token_equals(property, PROPERTY_PADDING_LEFT)) { + } else if (token_equals(property, PROPERTY_PADDING_LEFT)) { text->padding_left = token_to_int(get_token(&message)); return true; } else if (token_equals(property, PROPERTY_PADDING_RIGHT)) { text->padding_right = token_to_int(get_token(&message)); return true; + } else if (token_equals(property, PROPERTY_YOFFSET)) { + text->y_offset = token_to_int(get_token(&message)); + return true; + } else if (token_equals(property, PROPERTY_WIDTH)) { + struct token token = get_token(&message); + if (token_equals(token, "dynamic")) + text->has_const_width = false; + else { + text->has_const_width = true; + text->custom_width = token_to_uint32t(token); + } + return true; + } else if (token_equals(property, PROPERTY_DRAWING)) { + text->drawing = evaluate_boolean_state(get_token(&message), text->drawing); + return true; } else { fprintf(rsp, "Unknown property: %s \n", property.text); diff --git a/src/text.h b/src/text.h index c26e26a..3e1b360 100644 --- a/src/text.h +++ b/src/text.h @@ -10,15 +10,21 @@ struct text_line { }; struct text { + int y_offset; bool highlight; - struct text_line line; + bool drawing; + bool has_const_width; + uint32_t custom_width; char* string; char* font_name; CTFontRef font; int padding_left; int padding_right; + struct text_line line; struct rgba_color color; struct rgba_color highlight_color; + + struct background background; }; void text_init(struct text* text); @@ -32,6 +38,8 @@ uint32_t text_get_length(struct text* text); uint32_t text_get_height(struct text* text); bool text_update_color(struct text* text); +void text_draw(struct text* text, CGPoint origin, CGContextRef context); + static bool text_parse_sub_domain(struct text* text, FILE* rsp, struct token property, char* message); #endif // !TEXT_H_