fix bounding rects for popup menus

This commit is contained in:
Felix Kratz 2021-12-18 23:11:03 +01:00
parent cde65125be
commit 48140bb8f8
6 changed files with 28 additions and 17 deletions

View file

@ -35,7 +35,7 @@ void bar_draw_bar_items(struct bar* bar) {
for (int i = 0; i < g_bar_manager.bar_item_count; i++) { for (int i = 0; i < g_bar_manager.bar_item_count; i++) {
struct bar_item* bar_item = g_bar_manager.bar_items[i]; struct bar_item* bar_item = g_bar_manager.bar_items[i];
bar_item_remove_associated_bar(bar_item, bar->adid); if (!(bar_item->position == POSITION_POPUP)) bar_item_remove_associated_bar(bar_item, bar->adid);
if (!bar_draws_item(bar, bar_item)) continue; if (!bar_draws_item(bar, bar_item)) continue;
bar_item_append_associated_bar(bar_item, bar->adid); bar_item_append_associated_bar(bar_item, bar->adid);
@ -43,7 +43,7 @@ void bar_draw_bar_items(struct bar* bar) {
if (bar_item->update_mask & UPDATE_MOUSE_ENTERED || bar_item->update_mask & UPDATE_MOUSE_EXITED) 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)); SLSAddTrackingRect(g_connection, bar->id, CGRectInset(bar_item_construct_bounding_rect(bar_item), 1, 1));
bar_item_set_bounding_rect_for_display(bar_item, bar->adid, bar->origin); bar_item_set_bounding_rect_for_display(bar_item, bar->adid, bar->origin, bar->frame.size.height);
bar_item_draw(bar_item, bar->context); bar_item_draw(bar_item, bar->context);
} }
@ -89,7 +89,7 @@ void bar_redraw(struct bar* bar) {
CGPoint anchor = bar->origin; CGPoint anchor = bar->origin;
anchor.x += bar_item->icon.bounds.origin.x - bar_item->background.padding_left; anchor.x += bar_item->icon.bounds.origin.x - bar_item->background.padding_left;
anchor.y += bar_item->icon.bounds.origin.y + bar->frame.size.height / 2; anchor.y += bar_item->icon.bounds.origin.y + bar->frame.size.height / 2;
popup_set_anchor(&bar_item->popup, anchor); popup_set_anchor(&bar_item->popup, anchor, bar->adid);
if (bar_item->position == POSITION_RIGHT || bar_item->position == POSITION_CENTER_LEFT) { if (bar_item->position == POSITION_RIGHT || bar_item->position == POSITION_CENTER_LEFT) {
*next_position += bar_item->has_const_width ? bar_item_display_length *next_position += bar_item->has_const_width ? bar_item_display_length

View file

@ -303,7 +303,7 @@ CGRect bar_item_construct_bounding_rect(struct bar_item* bar_item) {
return bounding_rect; return bounding_rect;
} }
void bar_item_set_bounding_rect_for_display(struct bar_item* bar_item, uint32_t adid, CGPoint bar_origin) { void bar_item_set_bounding_rect_for_display(struct bar_item* bar_item, uint32_t adid, CGPoint bar_origin, uint32_t height) {
if (bar_item->num_rects < adid) { if (bar_item->num_rects < adid) {
bar_item->bounding_rects = (CGRect**) realloc(bar_item->bounding_rects, sizeof(CGRect*) * adid); bar_item->bounding_rects = (CGRect**) realloc(bar_item->bounding_rects, sizeof(CGRect*) * adid);
memset(bar_item->bounding_rects + bar_item->num_rects, 0, sizeof(CGRect*) * (adid - bar_item->num_rects)); memset(bar_item->bounding_rects + bar_item->num_rects, 0, sizeof(CGRect*) * (adid - bar_item->num_rects));
@ -315,7 +315,7 @@ void bar_item_set_bounding_rect_for_display(struct bar_item* bar_item, uint32_t
} }
CGRect rect = bar_item_construct_bounding_rect(bar_item); CGRect rect = bar_item_construct_bounding_rect(bar_item);
bar_item->bounding_rects[adid - 1]->origin.x = rect.origin.x + bar_origin.x; bar_item->bounding_rects[adid - 1]->origin.x = rect.origin.x + bar_origin.x;
bar_item->bounding_rects[adid - 1]->origin.y = rect.origin.y + bar_origin.y; bar_item->bounding_rects[adid - 1]->origin.y = -rect.origin.y - rect.size.height + bar_origin.y + height;
bar_item->bounding_rects[adid - 1]->size = rect.size; bar_item->bounding_rects[adid - 1]->size = rect.size;
} }
@ -366,6 +366,8 @@ void bar_item_draw(struct bar_item* bar_item, CGContextRef context) {
alias_draw(&bar_item->alias, context); alias_draw(&bar_item->alias, context);
if (bar_item->has_graph) if (bar_item->has_graph)
graph_draw(&bar_item->graph, context); graph_draw(&bar_item->graph, context);
if (bar_item->popup.drawing)
popup_draw(&bar_item->popup);
} }
void bar_item_destroy(struct bar_item* bar_item) { void bar_item_destroy(struct bar_item* bar_item) {

View file

@ -101,7 +101,7 @@ void bar_item_mouse_exited(struct bar_item* bar_item);
void bar_item_remove_bounding_rect_for_display(struct bar_item* bar_item, uint32_t adid); void bar_item_remove_bounding_rect_for_display(struct bar_item* bar_item, uint32_t adid);
CGRect bar_item_construct_bounding_rect(struct bar_item* bar_item); 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); 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); 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); void bar_item_draw(struct bar_item* bar_item, CGContextRef context);

View file

@ -110,13 +110,14 @@ static EVENT_CALLBACK(EVENT_HANDLER_DAEMON_MESSAGE) {
static EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP) { static EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP) {
debug("%s\n", __FUNCTION__); debug("%s\n", __FUNCTION__);
printf("Clicked\n");
CGPoint point = CGEventGetLocation(context); CGPoint point = CGEventGetLocation(context);
CGEventType type = CGEventGetType(context); CGEventType type = CGEventGetType(context);
uint32_t modifier_keys = CGEventGetFlags(context); uint32_t modifier_keys = CGEventGetFlags(context);
uint32_t adid = display_arrangement(display_active_display_id()); uint32_t adid = display_arrangement(display_active_display_id());
debug("EVENT_HANDLER_MOUSE_UP: D#%d (x: %.0f, y: %.0f) -> ", adid, point.x, point.y); printf("EVENT_HANDLER_MOUSE_UP: D#%d (x: %.0f, y: %.0f) -> ", adid, point.x, point.y);
struct bar_item* bar_item = bar_manager_get_item_by_point(&g_bar_manager, point, adid); struct bar_item* bar_item = bar_manager_get_item_by_point(&g_bar_manager, point, adid);
debug("item: %s\n", bar_item ? bar_item->name : "NULL"); printf("item: %s\n", bar_item ? bar_item->name : "NULL");
bar_item_on_click(bar_item, type, modifier_keys); bar_item_on_click(bar_item, type, modifier_keys);
CFRelease(context); CFRelease(context);
return EVENT_SUCCESS; return EVENT_SUCCESS;

View file

@ -23,7 +23,7 @@ void popup_init(struct popup* popup) {
void popup_calculate_bounds(struct popup* popup) { void popup_calculate_bounds(struct popup* popup) {
uint32_t y = popup->cell_size / 2; uint32_t y = popup->cell_size / 2;
uint32_t width = 0; uint32_t width = 0;
for (int i = 0; i < popup->num_items; i++) { for (int i = popup->num_items - 1; i >= 0; i--) {
uint32_t item_width = popup->items[i]->background.padding_right + popup->items[i]->background.padding_left + bar_item_calculate_bounds(popup->items[i], popup->cell_size, 0, y); uint32_t item_width = popup->items[i]->background.padding_right + popup->items[i]->background.padding_left + bar_item_calculate_bounds(popup->items[i], popup->cell_size, 0, y);
if (item_width > width) width = item_width; if (item_width > width) width = item_width;
y += popup->cell_size; y += popup->cell_size;
@ -62,7 +62,9 @@ void popup_create_window(struct popup* popup) {
context_set_font_smoothing(popup->context, g_bar_manager.font_smoothing); context_set_font_smoothing(popup->context, g_bar_manager.font_smoothing);
popup->drawing = true; popup->drawing = true;
SLSDisableUpdate(g_connection);
popup_draw(popup); popup_draw(popup);
SLSReenableUpdate(g_connection);
} }
void popup_close_window(struct popup* popup) { void popup_close_window(struct popup* popup) {
@ -80,9 +82,10 @@ void popup_add_item(struct popup* popup, struct bar_item* bar_item) {
popup->items[popup->num_items - 1] = bar_item; popup->items[popup->num_items - 1] = bar_item;
} }
void popup_set_anchor(struct popup* popup, CGPoint anchor) { void popup_set_anchor(struct popup* popup, CGPoint anchor, uint32_t adid) {
popup->anchor = anchor; popup->anchor = anchor;
popup->anchor.y += popup->y_offset; popup->anchor.y += popup->y_offset;
popup->adid = adid;
if (popup->drawing) { if (popup->drawing) {
//popup_close_window(popup); //popup_close_window(popup);
@ -99,19 +102,23 @@ void popup_draw(struct popup* popup) {
if (!popup->drawing) return; if (!popup->drawing) return;
popup_calculate_bounds(popup); popup_calculate_bounds(popup);
SLSDisableUpdate(g_connection);
SLSOrderWindow(g_connection, popup->id, -1, 0); SLSOrderWindow(g_connection, popup->id, -1, 0);
draw_rect(popup->context, popup->frame, &popup->background.color, popup->background.corner_radius, popup->background.border_width, &popup->background.border_color, true); draw_rect(popup->context, popup->frame, &popup->background.color, popup->background.corner_radius, popup->background.border_width, &popup->background.border_color, true);
for (int i = 0; i < popup->num_items; i++) { for (int i = 0; i < popup->num_items; i++) {
bool state = popup->items[i]->popup.drawing; struct bar_item* bar_item = popup->items[i];
popup->items[i]->popup.drawing = false; if (bar_item->update_mask & UPDATE_MOUSE_ENTERED || bar_item->update_mask & UPDATE_MOUSE_EXITED)
bar_item_draw(popup->items[i], popup->context); SLSAddTrackingRect(g_connection, popup->id, CGRectInset(bar_item_construct_bounding_rect(bar_item), 1, 1));
popup->items[i]->popup.drawing = state;
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->context);
bar_item->popup.drawing = state;
} }
CGContextFlush(popup->context); CGContextFlush(popup->context);
SLSOrderWindow(g_connection, popup->id, 1, popup->id); SLSOrderWindow(g_connection, popup->id, 1, popup->id);
SLSReenableUpdate(g_connection);
} }
void popup_destroy(struct popup* popup) { void popup_destroy(struct popup* popup) {

View file

@ -4,6 +4,7 @@
#include <_types/_uint32_t.h> #include <_types/_uint32_t.h>
struct popup { struct popup {
uint32_t id; uint32_t id;
uint32_t adid;
bool drawing; bool drawing;
bool horizontal; bool horizontal;
int y_offset; int y_offset;
@ -18,7 +19,7 @@ struct popup {
}; };
void popup_init(struct popup* popup); void popup_init(struct popup* popup);
void popup_set_anchor(struct popup* popup, CGPoint anchor); 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_add_item(struct popup* popup, struct bar_item* item);
void popup_set_drawing(struct popup* popup, bool drawing); void popup_set_drawing(struct popup* popup, bool drawing);
void popup_draw(struct popup* popup); void popup_draw(struct popup* popup);