rework popups to conform with the new drawing logic

This commit is contained in:
Felix Kratz 2022-06-14 00:15:28 +02:00
parent 53d0e09df4
commit 1061558427
8 changed files with 157 additions and 90 deletions

View file

@ -12,17 +12,24 @@ void bar_draw_graph(struct bar* bar, struct bar_item* bar_item, uint32_t x, bool
bool bar_draws_item(struct bar* bar, struct bar_item* bar_item) {
if (!bar_item->drawing || !bar->shown || bar->hidden) return false;
if (bar_item->associated_display > 0
&& (!(bar_item->associated_display & (1 << bar->adid)))
&& !bar_item->ignore_association)
return false;
if (bar_item->associated_space > 0
&& (!(bar_item->associated_space & (1 << bar->sid))
&& !bar_item->ignore_association)
&& (bar_item->type != BAR_COMPONENT_SPACE) )
return false;
if (bar_item->position == POSITION_POPUP)
if (bar_item->position == POSITION_POPUP
&& (!bar_item->parent
|| !bar_item->parent->popup.drawing
|| (bar->adid != g_bar_manager.active_adid)))
return false;
return true;
}
@ -32,7 +39,6 @@ void bar_calculate_popup_anchor_for_bar_item(struct bar* bar, struct bar_item* b
if (!bar_item->popup.overrides_cell_size)
bar_item->popup.cell_size = window->frame.size.height;
bool needs_recalculation = bar_item->popup.adid != bar->adid;
popup_calculate_bounds(&bar_item->popup);
CGPoint anchor = window->origin;
@ -50,9 +56,7 @@ void bar_calculate_popup_anchor_for_bar_item(struct bar* bar, struct bar_item* b
: window->frame.size.height);
popup_set_anchor(&bar_item->popup, anchor, bar->adid);
if (needs_recalculation) {
popup_calculate_bounds(&bar_item->popup);
}
popup_calculate_bounds(&bar_item->popup);
}
void bar_order_item_windows(struct bar* bar, int mode) {
@ -61,9 +65,11 @@ void bar_order_item_windows(struct bar* bar, int mode) {
struct window* previous_window = NULL;
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->position == POSITION_POPUP) continue;
struct window* window = bar_item_get_window(bar_item, bar->adid);
SLSRemoveFromOrderingGroup(g_connection, window->id);
window_set_level(window, g_bar_manager.window_level);
if (bar_item->type == BAR_COMPONENT_GROUP) {
@ -112,11 +118,6 @@ void bar_draw(struct bar* bar) {
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->position == POSITION_POPUP) {
continue;
}
struct window* window = bar_item_get_window(bar_item, bar->adid);
bar_item_remove_associated_bar(bar_item, bar->adid);
@ -186,7 +187,8 @@ void bar_calculate_bounds(struct bar* bar) {
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->type == BAR_COMPONENT_GROUP
|| bar_item->position == POSITION_POPUP ) {
continue;
}
@ -203,8 +205,7 @@ void bar_calculate_bounds(struct bar* bar) {
next_position = &bar_center_right_first_item_x;
else if (bar_item->position == POSITION_CENTER_LEFT)
next_position = &bar_center_left_first_item_x, rtl = true;
else
continue;
else continue;
if (bar_item->position == POSITION_RIGHT
|| bar_item->position == POSITION_CENTER_LEFT) {

View file

@ -15,6 +15,7 @@ void bar_item_clear_pointers(struct bar_item* bar_item) {
bar_item->signal_args.env_vars.vars = NULL;
bar_item->signal_args.env_vars.count = 0;
bar_item->windows = NULL;
bar_item->popup.host = bar_item;
bar_item->num_windows = 0;
text_clear_pointers(&bar_item->icon);
text_clear_pointers(&bar_item->label);
@ -93,8 +94,6 @@ void bar_item_init(struct bar_item* bar_item, struct bar_item* default_item) {
bar_item->custom_width = 0;
bar_item->y_offset = 0;
bar_item->group = NULL;
bar_item->has_alias = false;
bar_item->has_graph = false;
@ -103,11 +102,14 @@ void bar_item_init(struct bar_item* bar_item, struct bar_item* default_item) {
bar_item->script = NULL;
bar_item->click_script = NULL;
bar_item->group = NULL;
bar_item->parent = NULL;
text_init(&bar_item->icon);
text_init(&bar_item->label);
background_init(&bar_item->background);
env_vars_init(&bar_item->signal_args.env_vars);
popup_init(&bar_item->popup);
popup_init(&bar_item->popup, bar_item);
graph_init(&bar_item->graph);
alias_init(&bar_item->alias);
@ -450,15 +452,6 @@ CGRect bar_item_construct_bounding_rect(struct bar_item* bar_item) {
return bounding_rect;
}
void bar_item_set_bounding_rect_for_display(struct bar_item* bar_item, uint32_t adid, CGPoint bar_origin, uint32_t height) {
if (adid <= 0) return;
CGRect rect = CGRectInset(bar_item_construct_bounding_rect(bar_item), -1,-1);
struct window* window = bar_item_get_window(bar_item, adid);
window->origin.x = rect.origin.x + bar_origin.x;
window->origin.y = -rect.origin.y - rect.size.height + bar_origin.y + height;
window->frame.size = rect.size;
}
uint32_t bar_item_calculate_bounds(struct bar_item* bar_item, uint32_t bar_height, uint32_t x, uint32_t y) {
uint32_t content_x = x;
uint32_t content_y = y;
@ -776,7 +769,9 @@ void bar_item_parse_set_message(struct bar_item* bar_item, char* message, FILE*
}
struct bar_item* target_item = g_bar_manager.bar_items[item_index_for_name];
popup_add_item(&target_item->popup, bar_item);
}
} else {
bar_item->parent = NULL;
}
}
needs_refresh = true;
} else if (token_equals(property, PROPERTY_ALIGN)) {

View file

@ -72,6 +72,7 @@ struct bar_item {
// Popup
struct popup popup;
struct bar_item* parent;
};
struct bar_item* bar_item_create();
@ -108,7 +109,6 @@ void bar_item_mouse_exited(struct bar_item* bar_item);
struct window* bar_item_get_window(struct bar_item* bar_item, uint32_t adid);
void bar_item_remove_window(struct bar_item* bar_item, uint32_t adid);
CGRect bar_item_construct_bounding_rect(struct bar_item* bar_item);
void bar_item_set_bounding_rect_for_display(struct bar_item* bar_item, uint32_t adid, CGPoint bar_origin, uint32_t height);
uint32_t bar_item_calculate_bounds(struct bar_item* bar_item, uint32_t bar_height, uint32_t x, uint32_t y);
void bar_item_draw(struct bar_item* bar_item, CGContextRef context);

View file

@ -293,13 +293,8 @@ bool bar_manager_bar_needs_redraw(struct bar_manager* bar_manager, struct bar* b
for (int i = 0; i < bar_manager->bar_item_count; i++) {
struct bar_item* bar_item = bar_manager->bar_items[i];
bool is_associated_space_shown = (bar_item->associated_space & (1 << bar->sid))
|| bar_item->associated_space == 0;
bool is_associated_display_shown = (bar_item->associated_display & (1 << bar->adid));
if ((bar_item->drawing || (!bar_item->drawing
&& bar_item->associated_bar != 0))
&& bar_item->needs_update && (is_associated_space_shown
|| is_associated_display_shown)) {
if ((bar_item->needs_update && bar_draws_item(bar, bar_item))
|| (!bar_item->drawing && bar_item->associated_bar != 0) ) {
return true;
}
}

View file

@ -149,6 +149,23 @@ static void handle_domain_add(FILE* rsp, struct token domain, char* message) {
}
else if (bar_item->type == BAR_COMPONENT_GROUP) {
struct token member = position;
int index = bar_manager_get_item_index_for_name(&g_bar_manager,
member.text );
if (index > 0
&& g_bar_manager.bar_items[index]->position == POSITION_POPUP) {
popup_add_item(&g_bar_manager.bar_items[index]->parent->popup,
bar_item );
bar_item->position = POSITION_POPUP;
}
if (index >= 0)
group_add_member(bar_item->group, g_bar_manager.bar_items[index]);
else {
respond(rsp, "[?] Add (Group) %s: Failed to add member '%s', item not found\n", bar_item->name, member.text);
}
member = get_token(&message);
while (member.text && member.length > 0) {
int index = bar_manager_get_item_index_for_name(&g_bar_manager,

View file

@ -2,11 +2,12 @@
#include "bar_item.h"
#include "bar_manager.h"
void popup_init(struct popup* popup) {
void popup_init(struct popup* popup, struct bar_item* host) {
popup->drawing = false;
popup->horizontal = false;
popup->mouse_over = false;
popup->overrides_cell_size = false;
popup->needs_ordering = false;
popup->anchor = (CGPoint){0, 0};
popup->y_offset = 0;
popup->adid = 0;
@ -15,6 +16,7 @@ void popup_init(struct popup* popup) {
popup->num_items = 0;
popup->cell_size = 30;
popup->items = NULL;
popup->host = host;
background_init(&popup->background);
popup->background.border_color = rgba_color_from_hex(0xffff0000);
popup->background.color = rgba_color_from_hex(0x44000000);
@ -26,6 +28,46 @@ CGRect popup_get_frame(struct popup* popup) {
popup->background.bounds.size.height}};
}
void popup_order_windows(struct popup* popup, int mode) {
window_set_level(&popup->window, kCGScreenSaverWindowLevel);
SLSOrderWindow(g_connection, popup->window.id, 1, 0);
struct window* previous_window = NULL;
for (int i = 0; i < popup->num_items; i++) {
struct bar_item* bar_item = popup->items[i];
struct window* window = bar_item_get_window(bar_item, popup->adid);
SLSRemoveFromOrderingGroup(g_connection, window->id);
window_set_level(window, kCGScreenSaverWindowLevel);
if (bar_item->type == BAR_COMPONENT_GROUP) {
SLSOrderWindow(g_connection, window->id, mode, popup->window.id);
SLSAddWindowToWindowOrderingGroup(g_connection,
popup->window.id,
window->id,
1 );
continue;
}
if (previous_window) {
SLSOrderWindow(g_connection, window->id, mode, previous_window->id);
SLSAddWindowToWindowOrderingGroup(g_connection,
previous_window->id,
window->id,
1 );
}
else {
SLSOrderWindow(g_connection, window->id, mode, popup->window.id);
SLSAddWindowToWindowOrderingGroup(g_connection,
popup->window.id,
window->id,
1 );
}
previous_window = window;
}
}
void popup_calculate_bounds(struct popup* popup) {
uint32_t y = popup->background.border_width;
uint32_t x = 0;
@ -43,6 +85,7 @@ void popup_calculate_bounds(struct popup* popup) {
for (int j = 0; j < popup->num_items; j++) {
struct bar_item* bar_item = popup->items[j];
if (!bar_item->drawing) continue;
if (bar_item->type == BAR_COMPONENT_GROUP) continue;
uint32_t cell_height = max(bar_item_get_height(bar_item),
popup->cell_size );
@ -64,24 +107,48 @@ void popup_calculate_bounds(struct popup* popup) {
for (int j = 0; j < popup->num_items; j++) {
struct bar_item* bar_item = NULL;
if (popup->horizontal) bar_item = popup->items[j];
else bar_item = popup->items[popup->num_items - 1 - j];
bar_item = popup->items[j];
if (!bar_item->drawing) continue;
if (bar_item->type == BAR_COMPONENT_GROUP) continue;
uint32_t cell_height = max(bar_item_get_height(bar_item),
popup->cell_size );
uint32_t item_x = max((int)x + bar_item->background.padding_left, 0);
uint32_t item_y = y + (popup->horizontal ? height : cell_height) / 2;
uint32_t item_height = popup->horizontal ? height : cell_height;
uint32_t item_y = item_height / 2;
uint32_t item_width = bar_item->background.padding_right
+ bar_item->background.padding_left
+ bar_item_calculate_bounds(bar_item,
item_height,
item_x,
0,
item_y );
uint32_t bar_item_display_length = bar_item_get_length(bar_item, true);
if (popup->adid > 0) {
CGRect frame = {{popup->anchor.x + item_x,
popup->anchor.y + y},
{bar_item_display_length,
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)) {
uint32_t group_length = group_get_length(bar_item->group);
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 (item_width > width && !popup->horizontal) width = item_width;
if (popup->horizontal) x += item_width;
else y += cell_height;
@ -102,19 +169,24 @@ void popup_calculate_bounds(struct popup* popup) {
popup->background.bounds.size.height = y;
popup->background.image.bounds.origin.x = popup->background.border_width;
popup->background.image.bounds.origin.y = popup->background.border_width;
if (popup->adid > 0)
window_set_frame(&popup->window, popup_get_frame(popup));
}
void popup_create_window(struct popup* popup) {
window_create(&popup->window, (CGRect){{popup->anchor.x, popup->anchor.y},
{popup->background.bounds.size.width,
popup->background.bounds.size.height}});
window_create(&popup->window,(CGRect){{popup->anchor.x, popup->anchor.y},
{popup->background.bounds.size.width,
popup->background.bounds.size.height}});
if (!popup->background.shadow.enabled)
window_disable_shadow(&popup->window);
window_set_level(&popup->window, kCGScreenSaverWindowLevelKey);
CGContextSetInterpolationQuality(popup->window.context, kCGInterpolationNone);
context_set_font_smoothing(popup->window.context, g_bar_manager.font_smoothing);
CGContextSetInterpolationQuality(popup->window.context,
kCGInterpolationNone);
context_set_font_smoothing(popup->window.context,
g_bar_manager.font_smoothing);
popup->drawing = true;
}
@ -129,6 +201,7 @@ void popup_add_item(struct popup* popup, struct bar_item* bar_item) {
popup->items = realloc(popup->items,
sizeof(struct bar_item*)*popup->num_items);
popup->items[popup->num_items - 1] = bar_item;
bar_item->parent = popup->host;
}
bool popup_contains_item(struct popup* popup, struct bar_item* bar_item) {
@ -161,61 +234,45 @@ void popup_remove_item(struct popup* popup, struct bar_item* bar_item) {
}
void popup_set_anchor(struct popup* popup, CGPoint anchor, uint32_t adid) {
if (popup->anchor.x != anchor.x
|| popup->anchor.y != anchor.y + popup->y_offset) {
popup->anchor = anchor;
popup->anchor.y += popup->y_offset;
SLSMoveWindow(g_connection, popup->window.id, &popup->anchor);
popup->anchor = anchor;
popup->anchor.y += popup->y_offset;
if (adid > 0 && (popup->adid != adid)) {
popup->needs_ordering = true;
}
popup->adid = adid;
}
void popup_set_drawing(struct popup* popup, bool drawing) {
bool popup_set_drawing(struct popup* popup, bool drawing) {
if (popup->drawing == drawing) return false;
if (!drawing && popup->drawing) popup_close_window(popup);
else if (drawing && !popup->drawing) popup_create_window(popup);
popup->adid = 0;
return true;
}
void popup_draw(struct popup* popup) {
if (!popup->drawing || popup->adid <= 0) return;
SLSOrderWindow(g_connection, popup->window.id, -1, 0);
window_set_frame(&popup->window, popup_get_frame(popup));
if (popup->needs_ordering) {
popup_order_windows(popup, 1);
popup->needs_ordering = false;
}
window_apply_frame(&popup->window);
SLSRemoveAllTrackingAreas(g_connection, popup->window.id);
SLSAddTrackingRect(g_connection, popup->window.id, popup->window.frame);
CGContextClearRect(popup->window.context, popup->background.bounds);
SLSRemoveAllTrackingAreas(g_connection, popup->window.id);
SLSAddTrackingRect(g_connection, popup->window.id, popup->window.frame);
bool shadow = popup->background.shadow.enabled;
popup->background.shadow.enabled = false;
background_draw(&popup->background, popup->window.context);
popup->background.shadow.enabled = shadow;
for (int i = 0; i < popup->num_items; i++) {
struct bar_item* bar_item = popup->items[i];
if (!bar_item->drawing) continue;
if (bar_item->update_mask & UPDATE_MOUSE_ENTERED
|| bar_item->update_mask & UPDATE_MOUSE_EXITED) {
CGRect tracking_rect = cgrect_mirror_y(bar_item_construct_bounding_rect(bar_item),
popup->background.bounds.size.height / 2. );
tracking_rect.origin.y -= tracking_rect.size.height;
// TODO: Fix tracking rects in popups
// SLSAddTrackingRect(g_connection, popup->window.id, tracking_rect);
}
bar_item_set_bounding_rect_for_display(bar_item,
popup->adid,
popup->anchor,
popup->background.bounds.size.height);
bool state = bar_item->popup.drawing;
bar_item->popup.drawing = false;
bar_item_draw(bar_item, popup->window.context);
bar_item->popup.drawing = state;
}
CGContextFlush(popup->window.context);
SLSOrderWindow(g_connection, popup->window.id, 1, popup->window.id);
}
void popup_destroy(struct popup* popup) {
@ -231,10 +288,9 @@ bool popup_parse_sub_domain(struct popup* popup, FILE* rsp, struct token propert
popup->y_offset = token_to_int(get_token(&message));
return true;
} else if (token_equals(property, PROPERTY_DRAWING)) {
popup_set_drawing(popup,
evaluate_boolean_state(get_token(&message),
popup->drawing) );
return true;
return popup_set_drawing(popup,
evaluate_boolean_state(get_token(&message),
popup->drawing) );
} else if (token_equals(property, PROPERTY_HORIZONTAL)) {
popup->horizontal = evaluate_boolean_state(get_token(&message),
popup->horizontal );

View file

@ -10,6 +10,7 @@ struct popup {
bool horizontal;
bool overrides_cell_size;
bool mouse_over;
bool needs_ordering;
char align;
@ -20,17 +21,17 @@ struct popup {
CGPoint anchor;
struct window window;
struct bar_item* host;
struct bar_item** items;
uint32_t num_items;
struct background background;
};
void popup_init(struct popup* popup);
void popup_init(struct popup* popup, struct bar_item* host);
void popup_set_anchor(struct popup* popup, CGPoint anchor, uint32_t adid);
void popup_add_item(struct popup* popup, struct bar_item* item);
void popup_set_drawing(struct popup* popup, bool drawing);
bool popup_set_drawing(struct popup* popup, bool drawing);
void popup_remove_item(struct popup* popup, struct bar_item* bar_item);
uint32_t popup_get_width(struct popup* popup);

View file

@ -56,12 +56,16 @@ void windows_unfreeze() {
}
void window_set_frame(struct window* window, CGRect frame) {
if (!CGPointEqualToPoint(window->origin, frame.origin)) {
if (window->needs_move
|| !CGPointEqualToPoint(window->origin, frame.origin)) {
window->needs_move = true;
window->origin = frame.origin;
}
if (!CGSizeEqualToSize(window->frame.size, frame.size)) {
if (window->needs_resize
|| !CGSizeEqualToSize(window->frame.size, frame.size)) {
window->needs_resize = true;
window->frame.size = frame.size;
}
@ -76,8 +80,6 @@ bool window_apply_frame(struct window* window) {
window->origin.y,
frame_region );
SLSRemoveAllTrackingAreas(g_connection, window->id);
CFRelease(frame_region);
window->needs_move = false;
window->needs_resize = false;