diff --git a/src/bar.c b/src/bar.c index 7075c9e..02807dc 100644 --- a/src/bar.c +++ b/src/bar.c @@ -118,9 +118,7 @@ static void bar_check_for_clip_updates(struct bar* bar) { struct window* window = bar_item_get_window(bar_item, bar->adid); bool clips_bar = bar_item_clips_bar(bar_item); - if (!clips_bar || (!bar_draws_item(bar, bar_item) - || (bar_item->type == BAR_COMPONENT_GROUP - && !bar_draws_item(bar, group_get_first_member(bar_item->group))))) { + if (!clips_bar || (!bar_draws_item(bar, bar_item))) { if (clips_bar && !CGPointEqualToPoint(window->origin, g_nirvana)) { g_bar_manager.bar_needs_update = true; @@ -164,10 +162,7 @@ void bar_draw(struct bar* bar) { struct bar_item* bar_item = g_bar_manager.bar_items[i]; struct window* window = bar_item_get_window(bar_item, bar->adid); - if (!bar_draws_item(bar, bar_item) - || (bar_item->type == BAR_COMPONENT_GROUP - && !bar_draws_item(bar, group_get_first_member(bar_item->group)))){ - + if (!bar_draws_item(bar, bar_item)){ if (!CGPointEqualToPoint(window->origin, g_nirvana)) { window_move(window, g_nirvana); } @@ -287,37 +282,6 @@ static void bar_calculate_bounds_top_bottom(struct bar* bar) { window_set_frame(bar_item_get_window(bar_item, bar->adid), frame); - if (bar_item->group && group_is_first_member(bar_item->group, bar_item)) { - group_calculate_bounds(bar_item->group, - bar, - max(shadow_offsets.x, 0), - y, - bar_item->position == POSITION_RIGHT - || bar_item->position == POSITION_CENTER_LEFT); - - CGPoint shadow_offsets = - bar_item_calculate_shadow_offsets(bar_item->group->members[0]); - - uint32_t group_length = group_get_length(bar_item->group, bar); - int group_offset = (bar_item->position == POSITION_RIGHT - || bar_item->position == POSITION_CENTER_LEFT) - ? group_length - - bar_item_get_length(bar_item, false) - - bar_item->background.padding_right - : bar_item->background.padding_left; - - CGRect group_frame = {{frame.origin.x - group_offset, - frame.origin.y}, - {group_length - + shadow_offsets.x - + shadow_offsets.y, - frame.size.height} }; - - window_set_frame(bar_item_get_window(bar_item->group->members[0], - bar->adid ), - group_frame ); - } - if (bar_item->popup.drawing) bar_calculate_popup_anchor_for_bar_item(bar, bar_item); @@ -336,6 +300,21 @@ static void bar_calculate_bounds_top_bottom(struct bar* bar) { + bar_item->background.padding_right); } } + + 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_draws_item(bar, bar_item) + || bar_item->type != BAR_COMPONENT_GROUP + || bar_item->position == POSITION_POPUP ) { + continue; + } + + group_calculate_bounds(bar_item->group, bar, y); + window_set_frame(bar_item_get_window(bar_item->group->members[0], + bar->adid ), + bar_item->group->bounds ); + } } static void bar_calculate_bounds_left_right(struct bar* bar) { diff --git a/src/bar_item.c b/src/bar_item.c index 150b6b1..3a0e5cd 100644 --- a/src/bar_item.c +++ b/src/bar_item.c @@ -166,10 +166,8 @@ bool bar_item_update(struct bar_item* bar_item, char* sender, bool forced, struc } void bar_item_needs_update(struct bar_item* bar_item) { - if (bar_item->group) { - struct bar_item* first_member = group_get_first_member(bar_item->group); - if (first_member && first_member != bar_item) - bar_item_needs_update(first_member); + if (bar_item->group && bar_item != bar_item->group->members[0]) { + bar_item_needs_update(bar_item->group->members[0]); } bar_item->needs_update = true; @@ -384,7 +382,7 @@ uint32_t bar_item_get_height(struct bar_item* bar_item) { } struct window* bar_item_get_window(struct bar_item* bar_item, uint32_t adid) { - if (adid < 1) return NULL; + if (adid < 1 || !bar_item) return NULL; if (bar_item->num_windows < adid) { bar_item->windows = (struct window**) realloc(bar_item->windows, sizeof(struct window*)*adid); diff --git a/src/group.c b/src/group.c index f7c324e..1810a94 100644 --- a/src/group.c +++ b/src/group.c @@ -34,43 +34,54 @@ void group_add_member(struct group* group, struct bar_item* item) { } } -struct bar_item* group_get_first_member(struct group* group) { - if (group->num_members > 1) return group->members[1]; - return NULL; +static struct bar_item* group_get_first_member(struct group* group, struct bar* bar) { + if (group->num_members == 1) return NULL; + + int min = INT32_MAX; + struct bar_item* first_item = NULL; + + for (int i = 1; i < group->num_members; i++) { + struct bar_item* member = group->members[i]; + if (bar_draws_item(bar, member)) { + struct window* window = bar_item_get_window(member, bar->adid); + if (window->origin.x < min) { + min = window->origin.x; + first_item = member; + } + } + } + + return first_item; } -bool group_is_first_member(struct group* group, struct bar_item* item) { - if (!group_is_item_member(group, item)) return false; - if (group->num_members > 1) {return group->members[1] == item; } - return false; +static struct bar_item* group_get_last_member(struct group* group, struct bar* bar) { + if (group->num_members == 1) return NULL; + + int max = INT32_MIN; + struct bar_item* last_item = NULL; + + for (int i = 1; i < group->num_members; i++) { + struct bar_item* member = group->members[i]; + if (bar_draws_item(bar, member)) { + struct window* window = bar_item_get_window(member, bar->adid); + if (window->origin.x + window->frame.size.width > max) { + max = window->origin.x + window->frame.size.width; + last_item = member; + } + } + } + + return last_item; } uint32_t group_get_length(struct group* group, struct bar* bar) { - uint32_t length = 0; - for (int i = 1; i < group->num_members; i++) { - if (bar_draws_item(bar, group->members[i])) { - if (!group->members[i]->has_const_width) - length += group->members[i]->background.padding_left - + group->members[i]->background.padding_right; + int len = group->last_window->origin.x + + group->last_window->frame.size.width + + group->last_item->background.padding_right + + group->first_item->background.padding_left + - group->first_window->origin.x; - length += bar_item_get_length(group->members[i], false); - } - } - return length; -} - -uint32_t group_get_height(struct group* group, struct bar* bar) { - uint32_t height = 0; - for (int i = 1; i < group->num_members; i++) { - if (bar_draws_item(bar, group->members[i])) { - if (!group->members[i]->has_const_width) - height += group->members[i]->background.padding_left - + group->members[i]->background.padding_right; - - height += bar_item_get_height(group->members[i]); - } - } - return height; + return max(len, 0); } void group_remove_member(struct group* group, struct bar_item* bar_item) { @@ -95,9 +106,31 @@ void group_destroy(struct group* group) { free(group); } -void group_calculate_bounds(struct group* group, struct bar* bar, uint32_t x, uint32_t y, bool rtl) { +void group_calculate_bounds(struct group* group, struct bar* bar, uint32_t y) { + group->first_item = group_get_first_member(group, bar); + group->first_window = bar_item_get_window(group->first_item, bar->adid); + + group->last_item = group_get_last_member(group, bar); + group->last_window = bar_item_get_window(group->last_item, bar->adid); + + if (!group->first_window || !group->last_window) { + return; + } + + uint32_t group_length = group_get_length(group, bar); + CGPoint shadow_offsets = bar_item_calculate_shadow_offsets(group->members[0]); + + + group->bounds = (CGRect){{group->first_window->origin.x + - group->first_item->background.padding_left, + group->first_window->origin.y}, + {group_length + + shadow_offsets.x + + shadow_offsets.y, + group->first_window->frame.size.height}}; + background_calculate_bounds(&group->members[0]->background, - x, + max(shadow_offsets.x, 0), y + group->members[0]->y_offset, group_get_length(group, bar), group->members[0]->background.bounds.size.height); diff --git a/src/group.h b/src/group.h index 7aa23a9..00f686e 100644 --- a/src/group.h +++ b/src/group.h @@ -5,6 +5,13 @@ struct bar; struct group { CGRect bounds; + + struct window* first_window; + struct window* last_window; + + struct bar_item* first_item; + struct bar_item* last_item; + uint32_t num_members; struct bar_item** members; }; @@ -15,11 +22,8 @@ void group_set_name(struct group* group, char* _name); void group_add_member(struct group* group, struct bar_item* item); void group_remove_member(struct group* group, struct bar_item* bar_item); uint32_t group_get_length(struct group* group, struct bar* bar); -uint32_t group_get_height(struct group* group, struct bar* bar); -bool group_is_first_member(struct group* group, struct bar_item* item); -struct bar_item* group_get_first_member(struct group* group); -void group_calculate_bounds(struct group* group, struct bar* bar, uint32_t x, uint32_t y, bool rtl); +void group_calculate_bounds(struct group* group, struct bar* bar, uint32_t y); void group_draw(struct group* group, CGContextRef context); void group_destroy(struct group* group); diff --git a/src/popup.c b/src/popup.c index cc3b3b2..1cdaa3a 100644 --- a/src/popup.c +++ b/src/popup.c @@ -145,7 +145,7 @@ void popup_calculate_bounds(struct popup* popup, struct bar* bar) { struct bar_item* bar_item = NULL; bar_item = popup->items[j]; if (!bar_item->drawing) continue; - if (bar_item->type == BAR_COMPONENT_GROUP) continue; + if (bar_item->type == BAR_COMPONENT_GROUP) continue; uint32_t cell_height = max(bar_item_get_height(bar_item), popup->cell_size ); @@ -169,22 +169,6 @@ void popup_calculate_bounds(struct popup* popup, struct bar* bar) { item_height } }; window_set_frame(bar_item_get_window(bar_item, popup->adid), frame); - - if (bar_item->group - && group_is_first_member(bar_item->group, bar_item)) { - - group_calculate_bounds(bar_item->group, bar, 0, item_y, false); - - uint32_t group_length = group_get_length(bar_item->group, bar); - CGRect group_frame = {{frame.origin.x, - frame.origin.y }, - {group_length, - frame.size.height} }; - - window_set_frame(bar_item_get_window(bar_item->group->members[0], - popup->adid ), - group_frame ); - } } if (bar_item->popup.drawing) @@ -195,6 +179,30 @@ void popup_calculate_bounds(struct popup* popup, struct bar* bar) { else y += cell_height; } + for (int j = 0; j < popup->num_items; j++) { + if (popup->adid <= 0) break; + struct bar_item* bar_item = NULL; + bar_item = popup->items[j]; + if (!bar_item->drawing) continue; + if (bar_item->type != BAR_COMPONENT_GROUP) continue; + + uint32_t cell_height = popup->cell_size; + if (bar_item->group->num_members > 2) { + cell_height = max(bar_item_get_height(bar_item->group->members[1]), + popup->cell_size ); + } + + uint32_t item_height = popup->horizontal ? height : cell_height; + uint32_t item_y = item_height / 2; + + group_calculate_bounds(bar_item->group, bar, item_y); + + window_set_frame(bar_item_get_window(bar_item->group->members[0], + popup->adid ), + bar_item->group->bounds ); + } + + if (popup->horizontal) { if (!popup->background.enabled || !popup->background.image.enabled) { width = x + popup->background.border_width;