From 16ef8709f3040b7ede3e97c8c7f5be3f4d52b1da Mon Sep 17 00:00:00 2001 From: Felix Kratz Date: Sun, 5 Jun 2022 17:14:15 +0200 Subject: [PATCH] fix groups and flickering --- src/bar.c | 82 +++++++++++++++++++++++++++-------------------- src/bar_item.c | 9 ++++-- src/bar_manager.c | 8 +++++ src/group.c | 5 +++ src/group.h | 1 + src/message.c | 2 ++ src/window.c | 12 +++---- 7 files changed, 76 insertions(+), 43 deletions(-) diff --git a/src/bar.c b/src/bar.c index 3960c5e..9136f60 100644 --- a/src/bar.c +++ b/src/bar.c @@ -52,6 +52,26 @@ void bar_calculate_popup_anchor_for_bar_item(struct bar* bar, struct bar_item* b popup_set_anchor(&bar_item->popup, anchor, bar->adid); } +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_draws_item(bar, bar_item)) continue; + + struct window* window = bar_item_get_window(bar_item, bar->adid); + window_set_level(window, g_bar_manager.window_level); + + if (previous_window) { + SLSOrderWindow(g_connection, window->id, mode, previous_window->id); + } + else { + SLSOrderWindow(g_connection, window->id, mode, bar->window.id); + } + previous_window = window; + } +} + void bar_draw(struct bar* bar) { SLSRemoveAllTrackingAreas(g_connection, bar->window.id); @@ -63,7 +83,9 @@ void bar_draw(struct bar* bar) { g_bar_manager.background.border_width, &g_bar_manager.background.border_color, true ); + bar->needs_update = false; + CGContextFlush(bar->window.context); } if (g_bar_manager.background.image.enabled) { @@ -107,6 +129,11 @@ void bar_draw(struct bar* bar) { if (bar_item->needs_update) { + window_resize(window, (CGRect){{window->origin.x, + window->origin.y }, + {window->frame.size.width, + window->frame.size.height}}); + draw_rect(window->context, window->frame, &g_transparent, 0, 0, @@ -115,14 +142,13 @@ void bar_draw(struct bar* bar) { bar_item_draw(bar_item, window->context); CGContextFlush(window->context); - // SLSOrderWindow(g_connection, window->id, 1, bar->window.id); } if (bar_item->popup.drawing && bar->adid == g_bar_manager.active_adid) popup_draw(&bar_item->popup); } - CGContextFlush(bar->window.context); + bar_order_item_windows(bar, 1); } void bar_calculate_bounds(struct bar* bar) { @@ -153,7 +179,6 @@ void bar_calculate_bounds(struct bar* bar) { uint32_t* next_position = NULL; uint32_t y = bar->window.frame.size.height / 2; - 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]; @@ -186,43 +211,31 @@ void bar_calculate_bounds(struct bar* bar) { *next_position += bar_item->background.padding_left; } + uint32_t group_length = 0; + uint32_t group_offset = 0; + if (bar_item->group && group_is_first_member(bar_item->group, bar_item)) { + group_length = group_get_length(bar_item->group); + group_offset = (bar_item->position == POSITION_RIGHT + || bar_item->position == POSITION_CENTER_LEFT) + ? group_length - bar_item_get_length(bar_item, false) + : 0; + } + bar_item->graph.rtl = rtl; uint32_t bar_item_length = bar_item_calculate_bounds(bar_item, bar->window.frame.size.height - (g_bar_manager.background.border_width + 1), - *next_position, + group_offset, y ); struct window* window = bar_item_get_window(bar_item, bar->adid); - window_set_level(window, g_bar_manager.window_level); - // SLSRemoveFromOrderingGroup(g_connection, window->id); - if (previous_window) { - SLSOrderWindow(g_connection, window->id, 1, previous_window->id); - SLSAddWindowToWindowOrderingGroup(g_connection, - previous_window->id, - window->id, - 1 ); - } - else { - SLSOrderWindow(g_connection, window->id, 1, bar->window.id); - SLSAddWindowToWindowOrderingGroup(g_connection, - bar->window.id, - window->id, - 1 ); - } - - uint32_t group_length = 0; - if (bar_item->group && group_is_first_member(bar_item->group, bar_item)) { - group_length = group_get_length(bar_item->group); - } - - window_resize(window, (CGRect){{bar->window.origin.x + *next_position, - bar->window.origin.y }, - {bar_item_display_length - + group_length - + abs(bar_item->background.padding_left) - + abs(bar_item->background.padding_right), - bar->window.frame.size.height}}); + window->origin.x = bar->window.origin.x + *next_position - group_offset; + window->origin.y = bar->window.origin.y; + window->frame.size.width = bar_item_display_length + + group_length + + abs(bar_item->background.padding_left) + + abs(bar_item->background.padding_right); + window->frame.size.height = bar->window.frame.size.height; if (bar_item->popup.drawing) bar_calculate_popup_anchor_for_bar_item(bar, bar_item); @@ -241,7 +254,6 @@ void bar_calculate_bounds(struct bar* bar) { : (bar_item_length + bar_item->background.padding_right); } - previous_window = window; } } @@ -298,7 +310,7 @@ struct bar *bar_create(uint32_t did) { bar->did = did; bar->sid = mission_control_index(display_space_id(did)); bar->shown = true; - bar->needs_update = true; + bar->needs_update = false; bar_create_window(bar); return bar; } diff --git a/src/bar_item.c b/src/bar_item.c index 4f7246a..7660dc1 100644 --- a/src/bar_item.c +++ b/src/bar_item.c @@ -216,6 +216,12 @@ 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); + } + bar_item->needs_update = true; } @@ -495,8 +501,7 @@ void bar_item_set_bounding_rect_for_display(struct bar_item* bar_item, uint32_t } uint32_t bar_item_calculate_bounds(struct bar_item* bar_item, uint32_t bar_height, uint32_t x, uint32_t y) { - x = 0; - uint32_t content_x = 0; + uint32_t content_x = x; uint32_t content_y = y; uint32_t bar_item_length = bar_item_get_length(bar_item, false); diff --git a/src/bar_manager.c b/src/bar_manager.c index 116dfc9..6bef5f0 100644 --- a/src/bar_manager.c +++ b/src/bar_manager.c @@ -414,7 +414,9 @@ void bar_manager_update(struct bar_manager* bar_manager, bool forced) { forced, NULL ); } + bar_manager_freeze(bar_manager); if (needs_refresh) bar_manager_refresh(bar_manager, false); + bar_manager_unfreeze(bar_manager); } void bar_manager_begin(struct bar_manager *bar_manager) { @@ -477,7 +479,9 @@ void bar_manager_display_changed(struct bar_manager* bar_manager) { bar_destroy(bar_manager->bars[i]); bar_manager_begin(bar_manager); + bar_manager_freeze(bar_manager); bar_manager_refresh(bar_manager, true); + bar_manager_unfreeze(bar_manager); } void bar_manager_handle_mouse_entered(struct bar_manager* bar_manager, struct bar_item* bar_item) { @@ -534,7 +538,9 @@ void bar_manager_handle_space_change(struct bar_manager* bar_manager) { &env_vars ); env_vars_destroy(&env_vars); + bar_manager_freeze(bar_manager); bar_manager_refresh(bar_manager, true); + bar_manager_unfreeze(bar_manager); } void bar_manager_handle_display_change(struct bar_manager* bar_manager) { @@ -558,7 +564,9 @@ void bar_manager_handle_system_woke(struct bar_manager* bar_manager) { COMMAND_SUBSCRIBE_SYSTEM_WOKE, NULL ); + bar_manager_freeze(bar_manager); bar_manager_refresh(bar_manager, true); + bar_manager_unfreeze(bar_manager); } void bar_manager_handle_notification(struct bar_manager* bar_manager, struct notification* notification) { diff --git a/src/group.c b/src/group.c index 8d08937..c150094 100644 --- a/src/group.c +++ b/src/group.c @@ -32,6 +32,11 @@ 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; +} + 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; } diff --git a/src/group.h b/src/group.h index 27cee0b..1ff0e25 100644 --- a/src/group.h +++ b/src/group.h @@ -14,6 +14,7 @@ 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); bool group_is_first_member(struct group* group, struct bar_item* item); +struct bar_item* group_get_first_member(struct group* group); uint32_t group_count_members_drawn(struct group* group); void group_calculate_bounds(struct group* group, uint32_t x, uint32_t y, bool rtl); diff --git a/src/message.c b/src/message.c index 84871f5..cf164e1 100644 --- a/src/message.c +++ b/src/message.c @@ -462,7 +462,9 @@ static void handle_domain_order(FILE* rsp, struct token domain, char* message) { } bar_manager_sort(&g_bar_manager, ordering, count); + bar_manager_freeze(&g_bar_manager); bar_manager_refresh(&g_bar_manager, false); + bar_manager_unfreeze(&g_bar_manager); } void handle_message_mach(struct mach_buffer* buffer) { diff --git a/src/window.c b/src/window.c index a2d4507..5449d60 100644 --- a/src/window.c +++ b/src/window.c @@ -1,5 +1,6 @@ #include "window.h" #include "alias.h" +#include "bar_manager.h" static CFTypeRef window_create_region(struct window *window, CGRect frame) { window->frame = (CGRect) {{0, 0},{frame.size.width, frame.size.height}}; @@ -69,14 +70,13 @@ void window_resize(struct window* window, CGRect frame) { CFTypeRef frame_region = window_create_region(window, frame); SLSSetWindowShape(g_connection, window->id, - 0, - 0, + window->origin.x, + window->origin.y, frame_region ); - SLSMoveWindow(g_connection, window->id, &window->origin); - SLSClearActivationRegion(g_connection, window->id); - SLSAddActivationRegion(g_connection, window->id, frame_region); - SLSRemoveAllTrackingAreas(g_connection, window->id); + // SLSClearActivationRegion(g_connection, window->id); + // SLSAddActivationRegion(g_connection, window->id, frame_region); + // SLSRemoveAllTrackingAreas(g_connection, window->id); CFRelease(frame_region); }