Merge pull request #191 from FelixKratz/picky_redraw

Major Performance Optimizations
This commit is contained in:
Felix Kratz 2022-06-09 21:23:13 +02:00 committed by GitHub
commit 9e02b7e067
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 690 additions and 407 deletions

View file

@ -31,7 +31,7 @@ sketchybar --default updates=when_shown \
label.padding_left=4 \
label.padding_right=4 \
icon.padding_left=8 \
label.padding_right=8
icon.padding_right=8
##### Adding Mission Control Space Indicators #####
# Now we add some space components:

View file

@ -8,8 +8,7 @@ void print_all_menu_items(FILE* rsp) {
kCGNullWindowID );
int window_count = CFArrayGetCount(window_list);
printf("[\n");
fprintf(rsp, "[\n");
respond(rsp, "[\n");
int counter = 0;
for (int i = 0; i < window_count; ++i) {
CFDictionaryRef dictionary = CFArrayGetValueAtIndex(window_list, i);
@ -42,17 +41,14 @@ void print_all_menu_items(FILE* rsp) {
if (strcmp(name, "") == 0) continue;
if (counter++ > 0) {
fprintf(rsp, ", \n");
printf(", \n");
respond(rsp, ", \n");
}
fprintf(rsp, "\t\"%s,%s\"", owner, name);
printf("\t\"%s,%s\"", owner, name);
respond(rsp, "\t\"%s,%s\"", owner, name);
free(owner);
free(name);
}
printf("\n]\n");
fprintf(rsp, "\n]\n");
respond(rsp, "\n]\n");
CFRelease(window_list);
}
@ -155,14 +151,12 @@ bool alias_update_image(struct alias* alias) {
if (alias->wid == 0) return false;
CGRect bounds = CGRectNull;
SLSGetScreenRectForWindow(g_connection, alias->wid, &bounds);
bounds.size.width = (uint32_t) (bounds.size.width + 0.5);
CGImageRef tmp_ref = NULL;
SLSCaptureWindowsContentsToRectWithOptions(g_connection,
&alias->wid,
true,
CGRectNull,
bounds,
1 << 8,
&tmp_ref );
@ -171,6 +165,9 @@ bool alias_update_image(struct alias* alias) {
return false;
}
SLSGetScreenRectForWindow(g_connection, alias->wid, &bounds);
bounds.size.width = (uint32_t) (bounds.size.width + 0.5);
return image_set_image(&alias->image, tmp_ref, bounds, false);
}
@ -216,8 +213,7 @@ bool alias_parse_sub_domain(struct alias* alias, FILE* rsp, struct token propert
entry,
message );
else {
fprintf(rsp, "Invalid subdomain: %s \n", subdom.text);
printf("Invalid subdomain: %s \n", subdom.text);
respond(rsp, "[!] Alias: Invalid subdomain '%s'\n", subdom.text);
}
}
else if (token_equals(property, PROPERTY_COLOR)) {
@ -225,8 +221,7 @@ bool alias_parse_sub_domain(struct alias* alias, FILE* rsp, struct token propert
alias->color_override = true;
return true;
} else {
fprintf(rsp, "Unknown property: %s \n", property.text);
printf("Unknown property: %s \n", property.text);
respond(rsp, "[!] Alias: Invalid property '%s' \n", property.text);
}
return false;
}

View file

@ -1,13 +1,11 @@
#pragma once
#include <stdbool.h>
#include "misc/helpers.h"
#include "window.h"
#include "image.h"
#define MENUBAR_LAYER 0x19
extern void SLSCaptureWindowsContentsToRectWithOptions(uint32_t cid, uint64_t* wid, bool meh, CGRect bounds, uint32_t flags, CGImageRef* image);
extern int SLSGetScreenRectForWindow(uint32_t cid, uint32_t wid, CGRect* out);
struct alias {
bool permission;

View file

@ -25,7 +25,8 @@ double function_bounce(double x) {
return alpha*alpha * x * x;
}
else {
return beta * beta * (x - 1./2. + 1./alpha/2.) + 1. - beta*beta*(1./2. + 1./alpha/2.);
return beta * beta * (x - 1./2. + 1./alpha/2.)
+ 1. - beta*beta* (1./2. + 1./alpha/2.);
}
}
@ -95,11 +96,27 @@ bool animation_update(struct animation* animation) {
}
else {
value = (1. - slider) * animation->initial_value
+ slider * animation->final_value;
+ slider * animation->final_value;
}
animation->counter++;
return animation->update_function(animation->target, value);
bool needs_update = animation->update_function(animation->target, value);
bool found_item = false;
for (int i = 0; i < g_bar_manager.bar_item_count; i++) {
if (needs_update
&& (animation->target >= (void*)g_bar_manager.bar_items[i])
&& (animation->target < ((void*)g_bar_manager.bar_items[i]
+ sizeof(struct bar_item) ))) {
bar_item_needs_update(g_bar_manager.bar_items[i]);
found_item = true;
}
}
if (!found_item && needs_update) g_bar_manager.bar_needs_update = true;
return needs_update;
}
void animator_init(struct animator* animator) {
@ -116,7 +133,6 @@ void animator_add(struct animator* animator, struct animation* animation) {
animator->animations[animator->animation_count - 1] = animation;
if (animator->animation_count == 1) {
animator->clock = CFRunLoopTimerCreate(NULL,
CFAbsoluteTimeGetCurrent()+1./60.,
1./60.,

View file

@ -193,10 +193,11 @@ bool background_parse_sub_domain(struct background* background, FILE* rsp, struc
background->y_offset,
token_to_int(token) );
}
else if (token_equals(property, SUB_DOMAIN_IMAGE))
else if (token_equals(property, SUB_DOMAIN_IMAGE)) {
return image_load(&background->image,
token_to_string(get_token(&message)),
rsp );
}
else {
struct key_value_pair key_value_pair = get_key_value_pair(property.text,
'.' );
@ -211,13 +212,11 @@ bool background_parse_sub_domain(struct background* background, FILE* rsp, struc
else if (token_equals(subdom, SUB_DOMAIN_IMAGE))
return image_parse_sub_domain(&background->image, rsp, entry, message);
else {
fprintf(rsp, "Invalid subdomain: %s \n", subdom.text);
printf("Invalid subdomain: %s \n", subdom.text);
respond(rsp, "[!] Background: Invalid subdomain '%s'\n", subdom.text);
}
}
else {
fprintf(rsp, "Unknown property: %s \n", property.text);
printf("Unknown property: %s \n", property.text);
respond(rsp, "[!] Background: Invalid property '%s'\n", property.text);
}
}
return needs_refresh;

214
src/bar.c
View file

@ -3,6 +3,7 @@
#include "event.h"
#include "event_loop.h"
#include "display.h"
#include "misc/helpers.h"
#include "window.h"
void bar_draw_graph(struct bar* bar, struct bar_item* bar_item, uint32_t x, bool right_to_left) {
@ -27,78 +28,131 @@ bool bar_draws_item(struct bar* bar, struct bar_item* bar_item) {
void bar_calculate_popup_anchor_for_bar_item(struct bar* bar, struct bar_item* bar_item) {
if (bar->adid != g_bar_manager.active_adid) return;
struct window* window = bar_item_get_window(bar_item, bar->adid);
if (!bar_item->popup.overrides_cell_size)
bar_item->popup.cell_size = bar->window.frame.size.height;
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 = bar->window.origin;
CGPoint anchor = window->origin;
if (bar_item->popup.align == POSITION_CENTER) {
anchor.x += bar_item->icon.bounds.origin.x
+ bar_item->background.padding_left / 2
+ (bar_item_get_length(bar_item, false)
- bar_item->popup.background.bounds.size.width) / 2;
anchor.x += (window->frame.size.width
- bar_item->popup.background.bounds.size.width) / 2;
} else if (bar_item->popup.align == POSITION_LEFT) {
anchor.x += bar_item->icon.bounds.origin.x
- bar_item->background.padding_left;
anchor.x -= bar_item->background.padding_left;
} else {
anchor.x += bar_item->icon.bounds.origin.x
+ bar_item_get_length(bar_item, false)
anchor.x += window->frame.size.width
- bar_item->popup.background.bounds.size.width;
}
anchor.y += (g_bar_manager.position == POSITION_BOTTOM
? (-bar->window.frame.size.height
- bar_item->popup.background.bounds.size.height)
: bar->window.frame.size.height);
? (- bar_item->popup.background.bounds.size.height)
: window->frame.size.height);
popup_set_anchor(&bar_item->popup, anchor, bar->adid);
if (needs_recalculation) {
popup_calculate_bounds(&bar_item->popup);
}
}
void bar_order_item_windows(struct bar* bar, int mode) {
SLSOrderWindow(g_connection, bar->window.id, 1, 0);
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];
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) {
SLSOrderWindow(g_connection, window->id, mode, bar->window.id);
SLSAddWindowToWindowOrderingGroup(g_connection,
bar->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, bar->window.id);
SLSAddWindowToWindowOrderingGroup(g_connection,
bar->window.id,
window->id,
1 );
}
previous_window = window;
}
}
void bar_draw(struct bar* bar) {
SLSOrderWindow(g_connection, bar->window.id, -1, 0);
SLSRemoveAllTrackingAreas(g_connection, bar->window.id);
if (g_bar_manager.bar_needs_update) {
draw_rect(bar->window.context,
bar->window.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 );
draw_rect(bar->window.context,
bar->window.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 );
if (g_bar_manager.background.image.enabled) {
image_draw(&g_bar_manager.background.image, bar->window.context);
}
if (g_bar_manager.background.image.enabled) {
image_draw(&g_bar_manager.background.image, bar->window.context);
CGContextFlush(bar->window.context);
}
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))
bar_item_remove_associated_bar(bar_item, bar->adid);
if (!bar_draws_item(bar, bar_item)) continue;
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);
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 (!CGPointEqualToPoint(window->origin, g_nirvana)) {
window->origin = g_nirvana;
SLSMoveWindow(g_connection, window->id, &g_nirvana);
}
continue;
}
bar_item_append_associated_bar(bar_item, bar->adid);
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),
bar->window.frame.size.height / 2.);
tracking_rect.origin.y -= tracking_rect.size.height;
SLSAddTrackingRect(g_connection, bar->window.id, tracking_rect);
}
bar_item_set_bounding_rect_for_display(bar_item,
bar->adid,
bar->window.origin,
bar->window.frame.size.height);
bar_item_draw(bar_item, bar->window.context);
if (bar_item->popup.drawing && bar->adid == g_bar_manager.active_adid)
popup_draw(&bar_item->popup);
}
CGContextFlush(bar->window.context);
SLSOrderWindow(g_connection, bar->window.id, 1, bar->window.id);
if (!window_apply_frame(window) && !bar_item->needs_update) continue;
if (bar_item->update_mask & UPDATE_MOUSE_ENTERED
|| bar_item->update_mask & UPDATE_MOUSE_EXITED) {
CGRect tracking_rect = window->frame;
SLSRemoveAllTrackingAreas(g_connection, window->id);
SLSAddTrackingRect(g_connection, window->id, tracking_rect);
}
CGContextClearRect(window->context, window->frame);
bar_item_draw(bar_item, window->context);
CGContextFlush(window->context);
}
}
void bar_calculate_bounds(struct bar* bar) {
@ -132,7 +186,10 @@ void bar_calculate_bounds(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_draws_item(bar, bar_item)) continue;
if (!bar_draws_item(bar, bar_item)
|| bar_item->type == BAR_COMPONENT_GROUP) {
continue;
}
uint32_t bar_item_display_length = bar_item_get_length(bar_item, true);
bool rtl = false;
@ -151,18 +208,47 @@ void bar_calculate_bounds(struct bar* bar) {
continue;
if (bar_item->position == POSITION_RIGHT
|| bar_item->position == POSITION_CENTER_LEFT)
|| bar_item->position == POSITION_CENTER_LEFT) {
*next_position -= bar_item_display_length
+ bar_item->background.padding_left
+ bar_item->background.padding_right;
}
else {
*next_position += bar_item->background.padding_left;
}
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,
0,
y );
CGRect frame = {{bar->window.origin.x + *next_position,
bar->window.origin.y },
{bar_item_display_length,
bar->window.frame.size.height} };
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)) {
uint32_t group_length = group_get_length(bar_item->group);
uint32_t group_offset = (bar_item->position == POSITION_RIGHT
|| bar_item->position == POSITION_CENTER_LEFT)
? group_length
- bar_item_get_length(bar_item, false)
- group_count_members_drawn(bar_item->group)
: 0;
CGRect group_frame = {{frame.origin.x - group_offset,
frame.origin.y },
{group_length,
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);
@ -170,15 +256,16 @@ void bar_calculate_bounds(struct bar* bar) {
|| bar_item->position == POSITION_CENTER_LEFT) {
*next_position += bar_item->has_const_width
? bar_item_display_length
+ bar_item->background.padding_left
+ bar_item->background.padding_right
- bar_item->custom_width
: 0;
} else
: - bar_item->background.padding_left;
} else {
*next_position += bar_item->has_const_width
? bar_item->custom_width
: (bar_item_length + bar_item->background.padding_left
+ bar_item->background.padding_right );
- bar_item->background.padding_left
: (bar_item_length
+ bar_item->background.padding_right);
}
}
}
@ -205,9 +292,12 @@ CGRect bar_get_frame(struct bar *bar) {
void bar_resize(struct bar* bar) {
if (bar->hidden) return;
window_resize(&bar->window, bar_get_frame(bar));
bar_calculate_bounds(bar);
bar_draw(bar);
window_set_frame(&bar->window, bar_get_frame(bar));
if (window_apply_frame(&bar->window)) {
SLSRemoveAllTrackingAreas(g_connection, bar->window.id);
SLSAddTrackingRect(g_connection, bar->window.id, bar->window.frame);
g_bar_manager.bar_needs_update = true;
}
}
void bar_set_hidden(struct bar* bar, bool hidden) {
@ -219,10 +309,12 @@ void bar_set_hidden(struct bar* bar, bool hidden) {
void bar_create_window(struct bar* bar) {
window_create(&bar->window, bar_get_frame(bar));
SLSRemoveAllTrackingAreas(g_connection, bar->window.id);
SLSAddTrackingRect(g_connection, bar->window.id, bar->window.frame);
window_set_level(&bar->window, g_bar_manager.window_level);
window_set_blur_radius(&bar->window, g_bar_manager.blur_radius);
if (!g_bar_manager.shadow) window_disable_shadow(&bar->window);
window_set_level(&bar->window, g_bar_manager.window_level);
context_set_font_smoothing(bar->window.context, g_bar_manager.font_smoothing);
}
@ -230,9 +322,11 @@ struct bar *bar_create(uint32_t did) {
struct bar *bar = malloc(sizeof(struct bar));
memset(bar, 0, sizeof(struct bar));
bar->hidden = false;
bar->mouse_over = false;
bar->did = did;
bar->sid = mission_control_index(display_space_id(did));
bar->shown = true;
g_bar_manager.bar_needs_update = true;
bar_create_window(bar);
return bar;
}

View file

@ -13,6 +13,7 @@
struct bar {
bool shown;
bool hidden;
bool mouse_over;
uint32_t did;
uint32_t sid;
@ -29,6 +30,7 @@ void bar_set_hidden(struct bar* bar, bool hidden);
void bar_calculate_bounds(struct bar* bar);
void bar_resize(struct bar* bar);
void bar_draw(struct bar* bar);
void bar_order_item_windows(struct bar* bar, int mode);
bool bar_draws_item(struct bar* bar, struct bar_item* bar_item);

View file

@ -11,11 +11,11 @@ void bar_item_clear_pointers(struct bar_item* bar_item) {
bar_item->name = NULL;
bar_item->script = NULL;
bar_item->click_script = NULL;
bar_item->bounding_rects = NULL;
bar_item->group = NULL;
bar_item->num_rects = 0;
bar_item->signal_args.env_vars.vars = NULL;
bar_item->signal_args.env_vars.count = 0;
bar_item->windows = NULL;
bar_item->num_windows = 0;
text_clear_pointers(&bar_item->icon);
text_clear_pointers(&bar_item->label);
background_clear_pointers(&bar_item->background);
@ -73,7 +73,7 @@ void bar_item_inherit_from_item(struct bar_item* bar_item, struct bar_item* ance
void bar_item_init(struct bar_item* bar_item, struct bar_item* default_item) {
bar_item->needs_update = true;
bar_item->lazy = false;
bar_item->lazy = true;
bar_item->drawing = true;
bar_item->updates = true;
bar_item->updates_only_when_shown = false;
@ -93,8 +93,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->num_rects = 0;
bar_item->bounding_rects = NULL;
bar_item->group = NULL;
@ -153,13 +151,10 @@ void bar_item_append_associated_bar(struct bar_item* bar_item, uint32_t adid) {
void bar_item_remove_associated_bar(struct bar_item* bar_item, uint32_t adid) {
bar_item->associated_bar &= ~(1 << (adid - 1));
bar_item_remove_bounding_rect_for_display(bar_item, adid);
}
void bar_item_reset_associated_bar(struct bar_item* bar_item) {
bar_item->associated_bar = 0;
for (uint32_t adid = 1; adid <= bar_item->num_rects; adid++)
bar_item_remove_bounding_rect_for_display(bar_item, adid);
}
bool bar_item_update(struct bar_item* bar_item, char* sender, bool forced, struct env_vars* env_vars) {
@ -214,13 +209,15 @@ 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;
}
void bar_item_clear_needs_update(struct bar_item* bar_item) {
bar_item->needs_update = false;
}
void bar_item_set_name(struct bar_item* bar_item, char* name) {
if (!name) return;
@ -268,7 +265,6 @@ void bar_item_set_type(struct bar_item* bar_item, char type) {
bar_item->has_graph = true;
}
else if (type == BAR_COMPONENT_GROUP) {
bar_item->drawing = false;
bar_item->group = group_create();
group_init(bar_item->group);
group_add_member(bar_item->group, bar_item);
@ -368,7 +364,7 @@ uint32_t bar_item_get_content_length(struct bar_item* bar_item) {
+ (bar_item->has_graph ? graph_get_length(&bar_item->graph) : 0)
+ (bar_item->has_alias ? alias_get_length(&bar_item->alias) : 0);
return length > 0 ? length : 0;
return max(length, 0);
}
uint32_t bar_item_get_length(struct bar_item* bar_item, bool ignore_override) {
@ -392,13 +388,9 @@ uint32_t bar_item_get_height(struct bar_item* bar_item) {
uint32_t icon_height = text_get_height(&bar_item->icon);
uint32_t alias_height = alias_get_height(&bar_item->alias);
uint32_t text_height = label_height > icon_height
? label_height
: icon_height;
uint32_t text_height = max(label_height, icon_height);
uint32_t item_height = text_height > alias_height
? text_height
: alias_height;
uint32_t item_height = max(text_height, alias_height);
if (bar_item->background.enabled && bar_item->background.image.enabled
&& bar_item->background.image.bounds.size.height > item_height ) {
@ -408,20 +400,44 @@ uint32_t bar_item_get_height(struct bar_item* bar_item) {
return item_height;
}
void bar_item_remove_bounding_rect_for_display(struct bar_item* bar_item, uint32_t adid) {
if (bar_item->num_rects >= adid && bar_item->bounding_rects[adid - 1]) {
free(bar_item->bounding_rects[adid - 1]);
bar_item->bounding_rects[adid - 1] = NULL;
struct window* bar_item_get_window(struct bar_item* bar_item, uint32_t adid) {
if (adid <= 0) return NULL;
if (bar_item->num_windows < adid) {
bar_item->windows = (struct window**) realloc(bar_item->windows,
sizeof(struct window*)*adid);
memset(bar_item->windows + bar_item->num_windows,
0,
sizeof(struct window*) * (adid - bar_item->num_windows));
bar_item->num_windows = adid;
}
if (!bar_item->windows[adid - 1]) {
bar_item->windows[adid - 1] = malloc(sizeof(struct window));
window_create(bar_item->windows[adid - 1],
(CGRect){{g_nirvana.x,g_nirvana.y}, {1, 1}});
window_disable_shadow(bar_item->windows[adid - 1]);
context_set_font_smoothing(bar_item->windows[adid - 1]->context,
g_bar_manager.font_smoothing );
window_set_level(bar_item->windows[adid - 1],
g_bar_manager.window_level);
}
return bar_item->windows[adid - 1];
}
void bar_item_remove_window(struct bar_item* bar_item, uint32_t adid) {
if (bar_item->num_windows >= adid && bar_item->windows[adid - 1]) {
window_close(bar_item->windows[adid - 1]);
free(bar_item->windows[adid - 1]);
bar_item->windows[adid - 1] = NULL;
}
}
CGRect bar_item_construct_bounding_rect(struct bar_item* bar_item) {
CGRect bounding_rect;
bounding_rect.origin = bar_item->icon.bounds.origin;
bounding_rect.origin.y = bar_item->icon.bounds.origin.y
< bar_item->label.bounds.origin.y
? bar_item->icon.bounds.origin.y
: bar_item->label.bounds.origin.y;
bounding_rect.origin.y = min(bar_item->icon.bounds.origin.y, bar_item->label.bounds.origin.y);
if (bar_item->has_alias
&& bounding_rect.origin.y > bar_item->alias.image.bounds.origin.y) {
@ -436,31 +452,16 @@ 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) {
if (adid <= 0) return;
if (bar_item->num_rects < 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) );
bar_item->num_rects = adid;
}
if (!bar_item->bounding_rects[adid - 1]) {
bar_item->bounding_rects[adid - 1] = malloc(sizeof(CGRect));
memset(bar_item->bounding_rects[adid - 1], 0, sizeof(CGRect));
}
CGRect rect = CGRectInset(bar_item_construct_bounding_rect(bar_item), -1,-1);
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
- rect.size.height
+ bar_origin.y
+ height;
bar_item->bounding_rects[adid - 1]->size = rect.size;
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;
uint32_t bar_item_length = bar_item_get_length(bar_item, false);
uint32_t bar_item_content_length = bar_item_get_content_length(bar_item);
@ -471,7 +472,7 @@ uint32_t bar_item_calculate_bounds(struct bar_item* bar_item, uint32_t bar_heigh
content_x += bar_item_length - bar_item_content_length;
}
uint32_t icon_position = content_x + bar_item->background.padding_left;
uint32_t icon_position = content_x;
uint32_t label_position = icon_position + text_get_length(&bar_item->icon,
false );
@ -484,28 +485,23 @@ uint32_t bar_item_calculate_bounds(struct bar_item* bar_item, uint32_t bar_heigh
if (bar_item->group && group_is_first_member(bar_item->group, bar_item))
group_calculate_bounds(bar_item->group,
(bar_item->position == POSITION_RIGHT
|| bar_item->position == POSITION_CENTER_LEFT)
? (icon_position
- group_get_length(bar_item->group)
+ bar_item_length )
: icon_position,
x,
y,
bar_item->position == POSITION_RIGHT
|| bar_item->position == POSITION_CENTER_LEFT);
text_calculate_bounds(&bar_item->icon,
icon_position,
y + bar_item->y_offset);
content_y + bar_item->y_offset);
text_calculate_bounds(&bar_item->label,
label_position,
y + bar_item->y_offset);
content_y + bar_item->y_offset);
if (bar_item->has_alias)
alias_calculate_bounds(&bar_item->alias,
sandwich_position,
y + bar_item->y_offset);
content_y + bar_item->y_offset);
if (bar_item->has_graph) {
bar_item->graph.bounds.size.height = bar_item->background.enabled
@ -514,7 +510,8 @@ uint32_t bar_item_calculate_bounds(struct bar_item* bar_item, uint32_t bar_heigh
: (bar_height
- (g_bar_manager.background.border_width + 1));
graph_calculate_bounds(&bar_item->graph, sandwich_position, y + bar_item->y_offset);
graph_calculate_bounds(&bar_item->graph, sandwich_position,
content_y + bar_item->y_offset);
}
if (bar_item->background.enabled) {
@ -525,16 +522,14 @@ uint32_t bar_item_calculate_bounds(struct bar_item* bar_item, uint32_t bar_heigh
bar_item->background.bounds.size.width = bar_item_length;
background_calculate_bounds(&bar_item->background,
x + bar_item->background.padding_left,
y + bar_item->y_offset );
x,
content_y + bar_item->y_offset );
}
return bar_item_length;
}
void bar_item_draw(struct bar_item* bar_item, CGContextRef context) {
if (bar_item->group && group_is_first_member(bar_item->group, bar_item))
group_draw(bar_item->group, context);
background_draw(&bar_item->background, context);
text_draw(&bar_item->icon, context);
text_draw(&bar_item->label, context);
@ -553,13 +548,6 @@ void bar_item_destroy(struct bar_item* bar_item) {
text_destroy(&bar_item->icon);
text_destroy(&bar_item->label);
if (bar_item->bounding_rects) {
for (int adid = 1; adid <= bar_item->num_rects; adid++) {
bar_item_remove_bounding_rect_for_display(bar_item, adid);
}
free(bar_item->bounding_rects);
}
if (bar_item->has_graph) {
graph_destroy(&bar_item->graph);
}
@ -577,6 +565,11 @@ void bar_item_destroy(struct bar_item* bar_item) {
popup_destroy(&bar_item->popup);
background_destroy(&bar_item->background);
for (int j = 1; j <= bar_item->num_windows; j++) {
bar_item_remove_window(bar_item, j);
}
if (bar_item->windows) free(bar_item->windows);
free(bar_item);
}
@ -655,17 +648,17 @@ void bar_item_serialize(struct bar_item* bar_item, FILE* rsp) {
bar_item->update_mask);
int counter = 0;
for (int i = 0; i < bar_item->num_rects; i++) {
if (!bar_item->bounding_rects[i]) continue;
for (int i = 0; i < bar_item->num_windows; i++) {
if (!bar_item->windows[i]) continue;
if (counter++ > 0) fprintf(rsp, ",\n");
fprintf(rsp, "\t\t\"display-%d\": {\n"
"\t\t\t\"origin\": [ %f, %f ],\n"
"\t\t\t\"size\": [ %f, %f ]\n\t\t}",
i + 1,
bar_item->bounding_rects[i]->origin.x,
bar_item->bounding_rects[i]->origin.y,
bar_item->bounding_rects[i]->size.width,
bar_item->bounding_rects[i]->size.height);
bar_item->windows[i]->origin.x,
bar_item->windows[i]->origin.y,
bar_item->windows[i]->frame.size.width,
bar_item->windows[i]->frame.size.height);
}
fprintf(rsp, "\n\t}");
@ -722,8 +715,7 @@ void bar_item_parse_set_message(struct bar_item* bar_item, char* message, FILE*
message );
else {
fprintf(rsp, "Invalid subdomain: %s \n", subdom.text);
printf("Invalid subdomain: %s \n", subdom.text);
respond(rsp, "[!] Item (%s): Invalid subdomain '%s'\n", bar_item->name, subdom.text);
}
}
else if (token_equals(property, PROPERTY_ICON)) {
@ -779,8 +771,7 @@ void bar_item_parse_set_message(struct bar_item* bar_item, char* message, FILE*
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager,
key_value_pair.value);
if (item_index_for_name < 0) {
fprintf(rsp, "Name: %s not found in bar items \n", key_value_pair.value);
printf("Name: %s not found in bar items \n", key_value_pair.value);
respond(rsp, "[!] Item Position (%s): Item '%s' is not a valid popup host\n", bar_item->name, key_value_pair.value);
return;
}
struct bar_item* target_item = g_bar_manager.bar_items[item_index_for_name];
@ -830,7 +821,7 @@ void bar_item_parse_set_message(struct bar_item* bar_item, char* message, FILE*
} else if (token_equals(property, PROPERTY_CACHE_SCRIPTS)) {
printf("cache_scripts property is deprecated.\n");
} else if (token_equals(property, PROPERTY_LAZY)) {
bar_item->lazy = evaluate_boolean_state(get_token(&message), bar_item->lazy);
printf("lazy property is deprecated.\n");
} else if (token_equals(property, PROPERTY_IGNORE_ASSOCIATION)) {
bar_item->ignore_association = evaluate_boolean_state(get_token(&message),
bar_item->ignore_association);
@ -838,8 +829,7 @@ void bar_item_parse_set_message(struct bar_item* bar_item, char* message, FILE*
} else if (token_equals(property, COMMAND_DEFAULT_RESET)) {
bar_item_init(&g_bar_manager.default_item, NULL);
} else {
fprintf(rsp, "Invalid propery: %s \n", property.text);
printf("Invalid propery: %s \n", property.text);
respond(rsp, "[!] Item (%s): Invalid property '%s' \n", bar_item->name, property.text);
}
if (needs_refresh) bar_item_needs_update(bar_item);
@ -854,4 +844,3 @@ void bar_item_parse_subscribe_message(struct bar_item* bar_item, char* message)
event = get_token(&message);
}
}

View file

@ -66,9 +66,9 @@ struct bar_item {
// Update Events
uint64_t update_mask;
// Bounding Boxes for click events and background drawing (individual per display)
uint32_t num_rects;
CGRect** bounding_rects;
// Windows
uint32_t num_windows;
struct window** windows;
// Popup
struct popup popup;
@ -100,13 +100,13 @@ uint32_t bar_item_get_length(struct bar_item* bar_item, bool ignore_override);
uint32_t bar_item_get_height(struct bar_item* bar_item);
void bar_item_needs_update(struct bar_item* bar_item);
void bar_item_clear_needs_update(struct bar_item* bar_item);
void bar_item_on_click(struct bar_item* bar_item, uint32_t type, uint32_t modifier);
void bar_item_mouse_entered(struct bar_item* bar_item);
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);
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);

View file

@ -1,4 +1,5 @@
#include "bar_manager.h"
#include "bar_item.h"
#include "event.h"
#include "event_loop.h"
#include "misc/env_vars.h"
@ -14,6 +15,8 @@ static CLOCK_CALLBACK(clock_handler) {
void bar_manager_init(struct bar_manager* bar_manager) {
bar_manager->font_smoothing = false;
bar_manager->any_bar_hidden = false;
bar_manager->needs_ordering = false;
bar_manager->bar_needs_update = false;
bar_manager->bars = NULL;
bar_manager->bar_count = 0;
bar_manager->bar_item_count = 0;
@ -78,6 +81,7 @@ void bar_manager_sort(struct bar_manager* bar_manager, struct bar_item** orderin
}
}
}
bar_manager->needs_ordering = true;
}
int bar_manager_get_item_index_for_name(struct bar_manager* bar_manager, char* name) {
@ -122,6 +126,8 @@ void bar_manager_move_item(struct bar_manager* bar_manager, struct bar_item* ite
memcpy(bar_manager->bar_items,
tmp,
sizeof(struct bar_item*)*bar_manager->bar_item_count);
bar_manager->needs_ordering = true;
}
void bar_manager_remove_item(struct bar_manager* bar_manager, struct bar_item* bar_item) {
@ -193,20 +199,14 @@ bool bar_manager_set_display(struct bar_manager* bar_manager, char display) {
if (bar_manager->display == display) return false;
bar_manager->display = display;
for (int i = 0; i < bar_manager->bar_count; ++i)
bar_destroy(bar_manager->bars[i]);
bar_manager_begin(bar_manager);
bar_manager_reset(bar_manager);
return true;
}
bool bar_manager_set_shadow(struct bar_manager* bar_manager, bool shadow) {
if (bar_manager->shadow == shadow) return false;
bar_manager->shadow = shadow;
for (int i = 0; i < bar_manager->bar_count; ++i)
bar_destroy(bar_manager->bars[i]);
bar_manager_begin(bar_manager);
bar_manager_reset(bar_manager);
return true;
}
@ -247,28 +247,21 @@ bool bar_manager_set_hidden(struct bar_manager *bar_manager, uint32_t adid, bool
}
bool bar_manager_set_topmost(struct bar_manager *bar_manager, bool topmost) {
for (int i = 0; i < bar_manager->bar_count; i++)
bar_destroy(bar_manager->bars[i]);
if (topmost) bar_manager->window_level = kCGScreenSaverWindowLevel;
else bar_manager->window_level = kCGNormalWindowLevel;
bar_manager_begin(bar_manager);
bar_manager_reset(bar_manager);
bar_manager->topmost = topmost;
return true;
}
void bar_manager_freeze(struct bar_manager *bar_manager) {
bar_manager->frozen = true;
for (int i = 0; i < bar_manager->bar_count; i++) {
window_freeze(&bar_manager->bars[i]->window);
}
windows_freeze();
}
void bar_manager_unfreeze(struct bar_manager *bar_manager) {
bar_manager->frozen = false;
for (int i = 0; i < bar_manager->bar_count; i++) {
window_unfreeze(&bar_manager->bars[i]->window);
}
windows_unfreeze();
}
uint32_t bar_manager_length_for_bar_side(struct bar_manager* bar_manager, struct bar* bar, char side) {
@ -286,6 +279,8 @@ uint32_t bar_manager_length_for_bar_side(struct bar_manager* bar_manager, struct
}
bool bar_manager_bar_needs_redraw(struct bar_manager* bar_manager, struct bar* bar) {
if (bar_manager->bar_needs_update) return true;
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))
@ -294,8 +289,7 @@ bool bar_manager_bar_needs_redraw(struct bar_manager* bar_manager, struct bar* b
if ((bar_item->drawing || (!bar_item->drawing
&& bar_item->associated_bar != 0))
&& bar_item->needs_update && (is_associated_space_shown
|| is_associated_display_shown)
&& (!bar_item->lazy || bar_manager->picky_redraw) ) {
|| is_associated_display_shown)) {
return true;
}
}
@ -304,7 +298,10 @@ bool bar_manager_bar_needs_redraw(struct bar_manager* bar_manager, struct bar* b
void bar_manager_clear_needs_update(struct bar_manager* bar_manager) {
for (int i = 0; i < bar_manager->bar_item_count; i++)
bar_item_clear_needs_update(bar_manager->bar_items[i]);
bar_manager->bar_items[i]->needs_update = false;
bar_manager->needs_ordering = false;
bar_manager->bar_needs_update = false;
}
void bar_manager_clear_association_for_bar(struct bar_manager* bar_manager, struct bar* bar) {
@ -319,14 +316,24 @@ void bar_manager_reset_bar_association(struct bar_manager* bar_manager) {
void bar_manager_refresh(struct bar_manager* bar_manager, bool forced) {
if (bar_manager->frozen) return;
if (forced) bar_manager_reset_bar_association(bar_manager);
if (forced) {
bar_manager_reset_bar_association(bar_manager);
for (int j = 0; j < bar_manager->bar_item_count; j++) {
bar_item_needs_update(bar_manager->bar_items[j]);
}
}
for (int i = 0; i < bar_manager->bar_count; ++i) {
if (forced
|| bar_manager_bar_needs_redraw(bar_manager, bar_manager->bars[i])) {
bar_calculate_bounds(bar_manager->bars[i]);
bar_draw(bar_manager->bars[i]);
if (bar_manager->needs_ordering) {
bar_order_item_windows(bar_manager->bars[i], 1);
}
}
}
bar_manager_clear_needs_update(bar_manager);
}
@ -344,6 +351,7 @@ struct bar_item* bar_manager_create_item(struct bar_manager* bar_manager) {
struct bar_item* bar_item = bar_item_create();
bar_item_init(bar_item, &bar_manager->default_item);
bar_manager->bar_items[bar_manager->bar_item_count - 1] = bar_item;
bar_manager->needs_ordering = true;
return bar_item;
}
@ -398,7 +406,8 @@ void bar_manager_animator_refresh(struct bar_manager* bar_manager) {
bar_manager_freeze(bar_manager);
if (animator_update(&bar_manager->animator)) {
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, true);
bar_manager_refresh(bar_manager, false);
}
bar_manager_unfreeze(bar_manager);
}
@ -412,10 +421,28 @@ void bar_manager_update(struct bar_manager* bar_manager, bool forced) {
forced,
NULL );
}
bar_manager_freeze(bar_manager);
bar_manager->frozen = false;
if (needs_refresh) bar_manager_refresh(bar_manager, false);
bar_manager_unfreeze(bar_manager);
}
void bar_manager_begin(struct bar_manager *bar_manager) {
void bar_manager_reset(struct bar_manager* bar_manager) {
for (int i = 0; i < bar_manager->bar_count; i++) {
for (int j = 0; j < bar_manager->bar_item_count; j++) {
struct bar_item* bar_item = bar_manager->bar_items[j];
bar_item_remove_window(bar_item, bar_manager->bars[i]->adid);
}
bar_destroy(bar_manager->bars[i]);
bar_manager->bars[i] = NULL;
}
bar_manager->bar_count = 0;
bar_manager_begin(bar_manager);
}
void bar_manager_begin(struct bar_manager* bar_manager) {
if (bar_manager->display == DISPLAY_MAIN) {
uint32_t did = display_main_display_id();
bar_manager->bar_count = 1;
@ -440,23 +467,54 @@ void bar_manager_begin(struct bar_manager *bar_manager) {
bar_manager->bars[index - 1]->adid = index;
}
}
bar_manager->needs_ordering = true;
}
struct bar_item* bar_manager_get_item_by_point(struct bar_manager* bar_manager, CGPoint point, uint32_t adid) {
for (int i = 0; i < bar_manager->bar_item_count; i++) {
struct bar_item* bar_item = bar_manager->bar_items[i];
if (!bar_item->drawing || bar_item->num_rects < adid
|| bar_item->bounding_rects[adid - 1] == NULL) {
if (!bar_item->drawing || bar_item->num_windows < adid
|| bar_item->windows[adid - 1] == NULL) {
continue;
}
if (cgrect_contains_point(bar_item->bounding_rects[adid - 1], &point)) {
struct window* window = bar_item_get_window(bar_item, adid);
CGRect frame = window->frame;
frame.origin = window->origin;
if (cgrect_contains_point(&frame, &point)) {
return bar_item;
}
}
return NULL;
}
struct bar_item* bar_manager_get_item_by_wid(struct bar_manager* bar_manager, uint32_t wid, uint32_t adid) {
for (int i = 0; i < bar_manager->bar_item_count; i++) {
struct bar_item* bar_item = bar_manager->bar_items[i];
if (!bar_item->drawing || bar_item->num_windows < adid
|| bar_item->windows[adid - 1] == NULL) {
continue;
}
struct window* window = bar_item_get_window(bar_item, adid);
if (window->id == wid) {
return bar_item;
}
}
return NULL;
}
struct bar* bar_manager_get_bar_by_wid(struct bar_manager* bar_manager, uint32_t wid) {
for (int i = 0; i < bar_manager->bar_count; i++) {
if (bar_manager->bars[i]->window.id == wid) {
return bar_manager->bars[i];
}
}
return NULL;
}
void bar_manager_custom_events_trigger(struct bar_manager* bar_manager, char* name, struct env_vars* env_vars) {
uint64_t flag = custom_events_get_flag_for_name(&bar_manager->custom_events,
name );
@ -471,11 +529,23 @@ void bar_manager_custom_events_trigger(struct bar_manager* bar_manager, char* na
void bar_manager_display_changed(struct bar_manager* bar_manager) {
bar_manager->active_adid = display_arrangement(display_active_display_id());
for (int i = 0; i < bar_manager->bar_count; ++i)
bar_destroy(bar_manager->bars[i]);
bar_manager_begin(bar_manager);
bar_manager_reset(bar_manager);
bar_manager_freeze(bar_manager);
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, true);
bar_manager_unfreeze(bar_manager);
}
void bar_manager_handle_mouse_entered_global(struct bar_manager* bar_manager) {
bar_manager_custom_events_trigger(bar_manager,
COMMAND_SUBSCRIBE_MOUSE_ENTERED_GLOBAL,
NULL );
}
void bar_manager_handle_mouse_exited_global(struct bar_manager* bar_manager) {
bar_manager_custom_events_trigger(bar_manager,
COMMAND_SUBSCRIBE_MOUSE_EXITED_GLOBAL,
NULL );
}
void bar_manager_handle_mouse_entered(struct bar_manager* bar_manager, struct bar_item* bar_item) {
@ -486,9 +556,13 @@ void bar_manager_handle_mouse_entered(struct bar_manager* bar_manager, struct ba
bar_item_mouse_entered(bar_item);
}
void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager) {
for (int i = 0; i < bar_manager->bar_item_count; i++)
bar_item_mouse_exited(bar_manager->bar_items[i]);
void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager, struct bar_item* bar_item) {
if (!bar_item) {
for (int i = 0; i < bar_manager->bar_item_count; i++)
bar_item_mouse_exited(bar_manager->bar_items[i]);
} else {
bar_item_mouse_exited(bar_item);
}
}
void bar_manager_handle_front_app_switch(struct bar_manager* bar_manager, char* info) {
@ -522,6 +596,7 @@ void bar_manager_handle_space_change(struct bar_manager* bar_manager) {
bar_manager->bars[i]->sid );
cursor = strlen(info);
}
info[cursor] = '}';
info[cursor + 1] = '\0';
env_vars_set(&env_vars, string_copy("INFO"), string_copy(info));
@ -531,8 +606,12 @@ void bar_manager_handle_space_change(struct bar_manager* bar_manager) {
COMMAND_SUBSCRIBE_SPACE_CHANGE,
&env_vars );
bar_manager_freeze(bar_manager);
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, false);
bar_manager_unfreeze(bar_manager);
env_vars_destroy(&env_vars);
bar_manager_refresh(bar_manager, true);
}
void bar_manager_handle_display_change(struct bar_manager* bar_manager) {
@ -556,7 +635,10 @@ void bar_manager_handle_system_woke(struct bar_manager* bar_manager) {
COMMAND_SUBSCRIBE_SYSTEM_WOKE,
NULL );
bar_manager_freeze(bar_manager);
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, true);
bar_manager_unfreeze(bar_manager);
}
void bar_manager_handle_notification(struct bar_manager* bar_manager, struct notification* notification) {

View file

@ -16,6 +16,8 @@ struct bar_manager {
bool picky_redraw;
bool font_smoothing;
bool any_bar_hidden;
bool needs_ordering;
bool bar_needs_update;
char display;
char position;
@ -43,6 +45,7 @@ struct bar_manager {
struct bar_manager g_bar_manager;
void bar_manager_init(struct bar_manager* bar_manager);
void bar_manager_begin(struct bar_manager* bar_manager);
void bar_manager_reset(struct bar_manager* bar_manager);
struct bar_item* bar_manager_create_item(struct bar_manager* bar_manager);
void bar_manager_remove_item(struct bar_manager* bar_manager, struct bar_item* bar_item);
@ -67,6 +70,8 @@ bool bar_manager_set_notch_width(struct bar_manager* bar_manager, uint32_t width
void bar_manager_sort(struct bar_manager* bar_manager, struct bar_item** ordering, uint32_t count);
struct bar_item* bar_manager_get_item_by_point(struct bar_manager* bar_manager, CGPoint point, uint32_t adid);
struct bar_item* bar_manager_get_item_by_wid(struct bar_manager* bar_manager, uint32_t wid, uint32_t adid);
struct bar* bar_manager_get_bar_by_wid(struct bar_manager* bar_manager, uint32_t wid);
int bar_manager_get_item_index_for_name(struct bar_manager* bar_manager, char* name);
uint32_t bar_manager_length_for_bar_side(struct bar_manager* bar_manager, struct bar* bar, char side);
@ -77,8 +82,10 @@ void bar_manager_display_changed(struct bar_manager* bar_manager);
void bar_manager_refresh(struct bar_manager* bar_manager, bool forced);
void bar_manager_resize(struct bar_manager* bar_manager);
void bar_manager_handle_mouse_entered_global(struct bar_manager* bar_manager);
void bar_manager_handle_mouse_exited_global(struct bar_manager* bar_manager);
void bar_manager_handle_mouse_entered(struct bar_manager* bar_manager, struct bar_item* bar_item);
void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager);
void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager, struct bar_item* bar_item);
void bar_manager_handle_front_app_switch(struct bar_manager* bar_manager, char* info);
void bar_manager_handle_space_change(struct bar_manager* bar_manager);
void bar_manager_handle_display_change(struct bar_manager* bar_manager);

View file

@ -27,6 +27,8 @@ void custom_events_init(struct custom_events* custom_events) {
custom_events_append(custom_events, string_copy(COMMAND_SUBSCRIBE_MOUSE_EXITED), NULL);
custom_events_append(custom_events, string_copy(COMMAND_SUBSCRIBE_MOUSE_CLICKED), NULL);
custom_events_append(custom_events, string_copy(COMMAND_SUBSCRIBE_SYSTEM_WILL_SLEEP), NULL);
custom_events_append(custom_events, string_copy(COMMAND_SUBSCRIBE_MOUSE_ENTERED_GLOBAL), NULL);
custom_events_append(custom_events, string_copy(COMMAND_SUBSCRIBE_MOUSE_EXITED_GLOBAL), NULL);
}
void custom_events_append(struct custom_events* custom_events, char* name, char* notification) {

View file

@ -113,17 +113,21 @@ EVENT_CALLBACK(EVENT_HANDLER_MACH_MESSAGE) {
EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP) {
debug("%s\n", __FUNCTION__);
CGPoint point = CGEventGetLocation(context);
debug("EVENT_HANDLER_MOUSE_UP\n");
uint32_t wid = get_window_id_from_cg_event(context);
CGEventType type = CGEventGetType(context);
uint32_t modifier_keys = CGEventGetFlags(context);
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 );
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_wid(&g_bar_manager,
wid,
adid );
if (!bar_item) {
CGPoint point = CGEventGetLocation(context);
bar_item = bar_manager_get_item_by_point(&g_bar_manager, point, adid);
}
debug("item: %s\n", bar_item ? bar_item->name : "NULL");
bar_item_on_click(bar_item, type, modifier_keys);
@ -133,15 +137,30 @@ EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP) {
EVENT_CALLBACK(EVENT_HANDLER_MOUSE_ENTERED) {
debug("%s\n", __FUNCTION__);
CGPoint point = CGEventGetLocation(context);
debug("EVENT_HANDLER_MOUSE_ENTERED\n");
uint32_t wid = get_window_id_from_cg_event(context);
uint32_t adid = display_arrangement(display_active_display_id());
debug("EVENT_HANDLER_MOUSE_ENTERED: 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* bar = bar_manager_get_bar_by_wid(&g_bar_manager, wid);
if (bar) {
// Handle global mouse entered event
if (!bar->mouse_over) {
bar->mouse_over = true;
bar_manager_handle_mouse_entered_global(&g_bar_manager);
}
CFRelease(context);
return EVENT_SUCCESS;
}
struct bar_item* bar_item = bar_manager_get_item_by_wid(&g_bar_manager,
wid,
adid );
if (!bar_item) {
CGPoint point = CGEventGetLocation(context);
bar_item = bar_manager_get_item_by_point(&g_bar_manager, point, adid);
}
debug("item: %s\n", bar_item ? bar_item->name : "NULL");
bar_manager_handle_mouse_entered(&g_bar_manager, bar_item);
@ -151,8 +170,31 @@ EVENT_CALLBACK(EVENT_HANDLER_MOUSE_ENTERED) {
EVENT_CALLBACK(EVENT_HANDLER_MOUSE_EXITED) {
debug("%s\n", __FUNCTION__);
debug("EVENT_HANDLER_MOUSE_EXITED \n");
bar_manager_handle_mouse_exited(&g_bar_manager);
debug("EVENT_HANDLER_MOUSE_EXITED\n");
uint32_t adid = display_arrangement(display_active_display_id());
uint32_t wid = get_window_id_from_cg_event(context);
struct bar* bar = bar_manager_get_bar_by_wid(&g_bar_manager, wid);
if (bar) {
// Handle global mouse exited event
CGPoint point = CGEventGetLocation(context);
CGRect frame = bar->window.frame;
frame.origin = bar->window.origin;
if (!CGRectContainsPoint(frame, point)) {
bar->mouse_over = false;
bar_manager_handle_mouse_exited_global(&g_bar_manager);
}
CFRelease(context);
return EVENT_SUCCESS;
}
struct bar_item* bar_item = bar_manager_get_item_by_wid(&g_bar_manager,
wid,
adid );
debug("item: %s\n", bar_item ? bar_item->name : "NULL");
bar_manager_handle_mouse_exited(&g_bar_manager, bar_item);
CFRelease(context);
return EVENT_SUCCESS;
}

View file

@ -8,7 +8,7 @@
struct event_loop;
extern OSStatus SLSFindWindowByGeometry(int cid, int zero, int one, int zero_again, CGPoint *screen_point, CGPoint *window_point, uint32_t *wid, int *wcid);
extern uint32_t get_window_id_from_cg_event(CGEventRef cgevent);
#define EVENT_CALLBACK(name) uint32_t name(void *context)
typedef EVENT_CALLBACK(event_callback);

View file

@ -143,8 +143,7 @@ bool graph_parse_sub_domain(struct graph* graph, FILE* rsp, struct token propert
return true;
}
else {
fprintf(rsp, "Unknown property: %s \n", property.text);
printf("Unknown property: %s \n", property.text);
respond(rsp, "[!] Graph: Invalid property '%s'\n", property.text);
}
return false;
}

View file

@ -26,12 +26,18 @@ void group_add_member(struct group* group, struct bar_item* item) {
}
} else {
group->num_members++;
group->members = realloc(group->members, sizeof(struct bar_item*)*group->num_members);
group->members = realloc(group->members,
sizeof(struct bar_item*)*group->num_members);
group->members[group->num_members - 1] = item;
item->group = group;
}
}
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; }
@ -59,7 +65,7 @@ uint32_t group_get_length(struct group* group) {
length += bar_item_get_length(group->members[i], false);
}
}
return length;
return length + group_count_members_drawn(group);
}
uint32_t group_count_members_drawn(struct group* group) {
@ -81,7 +87,8 @@ void group_remove_member(struct group* group, struct bar_item* bar_item) {
tmp[count++] = group->members[i];
}
group->num_members--;
group->members = realloc(group->members, sizeof(struct bar_item*)*group->num_members);
group->members = realloc(group->members,
sizeof(struct bar_item*)*group->num_members);
memcpy(group->members, tmp, sizeof(struct bar_item*)*group->num_members);
}
@ -96,12 +103,14 @@ void group_destroy(struct group* group) {
void group_calculate_bounds(struct group* group, uint32_t x, uint32_t y, bool rtl) {
background_calculate_bounds(&group->members[0]->background, x, y);
group->members[0]->background.bounds.size.width = group_get_length(group)
+ (rtl
? 0
: group_count_members_drawn(group));
- (rtl
? group_count_members_drawn(group)
: 0 );
group->members[0]->background.bounds.origin.x = x;
group->members[0]->background.bounds.origin.y = y - group->members[0]->background.bounds.size.height / 2
+ group->members[0]->y_offset;
group->members[0]->background.bounds.origin.y = y
- group->members[0]->background.bounds.size.height / 2
+ group->members[0]->y_offset;
}
void group_draw(struct group* group, CGContextRef context) {

View file

@ -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);

View file

@ -22,8 +22,7 @@ bool image_set_enabled(struct image* image, bool enabled) {
bool image_load(struct image* image, char* path, FILE* rsp) {
char* res_path = resolve_path(path);
if (!file_exists(res_path)) {
printf("File %s not found!\n", res_path);
fprintf(rsp, "File %s not found!\n", res_path);
respond(rsp, "[!] Image: File '%s' not found\n", res_path);
free(res_path);
return false;
}

View file

@ -5,19 +5,20 @@ extern struct event_loop g_event_loop;
extern struct bar_manager g_bar_manager;
extern bool g_verbose;
// Syntax: sketchybar -m --subscribe <name> <event>
static void handle_domain_subscribe(FILE* rsp, struct token domain, char* message) {
struct token name = get_token(&message);
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager,
name.text );
if (item_index_for_name < 0) return;
if (item_index_for_name < 0) {
respond(rsp, "[!] Subscribe: Item not found '%s'\n", name.text);
return;
}
struct bar_item* bar_item = g_bar_manager.bar_items[item_index_for_name];
bar_item_parse_subscribe_message(bar_item, message);
}
// Syntax: sketchybar -m --trigger <event>
static void handle_domain_trigger(FILE* rsp, struct token domain, char* message) {
struct token event = get_token(&message);
struct env_vars env_vars;
@ -38,20 +39,22 @@ static void handle_domain_trigger(FILE* rsp, struct token domain, char* message)
env_vars_destroy(&env_vars);
}
// Syntax: sketchybar -m --push <name> <y>
static void handle_domain_push(FILE* rsp, struct token domain, char* message) {
struct token name = get_token(&message);
struct token y = get_token(&message);
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager,
name.text );
if (item_index_for_name < 0) return;
if (item_index_for_name < 0) {
respond(rsp, "[!] Push: Item '%s' not found", name.text);
return;
}
struct bar_item* bar_item = g_bar_manager.bar_items[item_index_for_name];
graph_push_back(&bar_item->graph, token_to_float(y));
bar_item_needs_update(bar_item);
}
// Syntax sketchybar -m --rename <old name> <new name>
static void handle_domain_rename(FILE* rsp, struct token domain, char* message) {
struct token old_name = get_token(&message);
struct token new_name = get_token(&message);
@ -60,18 +63,14 @@ static void handle_domain_rename(FILE* rsp, struct token domain, char* message)
int item_index_for_new_name = bar_manager_get_item_index_for_name(&g_bar_manager,
new_name.text);
if (item_index_for_old_name < 0 || item_index_for_new_name >= 0) {
fprintf(rsp, "Could not rename item: %s -> %s \n", old_name.text,
new_name.text);
printf("Could not rename item: %s -> %s \n", old_name.text,
new_name.text);
respond(rsp, "[!] Rename: Failed to rename item: %s -> %s\n", old_name.text,
new_name.text);
return;
}
bar_item_set_name(g_bar_manager.bar_items[item_index_for_old_name],
token_to_string(new_name) );
}
// Syntax: sketchybar -m --clone <name> <parent name>
static void handle_domain_clone(FILE* rsp, struct token domain, char* message) {
struct token name = get_token(&message);
struct token parent = get_token(&message);
@ -84,13 +83,12 @@ static void handle_domain_clone(FILE* rsp, struct token domain, char* message) {
if (parent_index >= 0)
parent_item = g_bar_manager.bar_items[parent_index];
else {
printf("Parent Item: %s does not exist \n", parent.text);
fprintf(rsp, "Parent Item: %s does not exist \n", parent.text);
respond(rsp, "[!] Clone: Parent Item '%s' not found\n", parent.text);
return;
}
if (bar_manager_get_item_index_for_name(&g_bar_manager, name.text) >= 0) {
fprintf(rsp, "Item %s already exists \n", name.text);
respond(rsp, "[?] Clone: Item '%s' already exists\n", name.text);
return;
}
struct bar_item* bar_item = bar_manager_create_item(&g_bar_manager);
@ -103,7 +101,6 @@ static void handle_domain_clone(FILE* rsp, struct token domain, char* message) {
bar_item_needs_update(bar_item);
}
// Syntax: sketchybar -m --add <item|component identifer> <name>[:parent] [<position>]
static void handle_domain_add(FILE* rsp, struct token domain, char* message) {
struct token command = get_token(&message);
@ -123,31 +120,13 @@ static void handle_domain_add(FILE* rsp, struct token domain, char* message) {
struct token position = get_token(&message);
if (bar_manager_get_item_index_for_name(&g_bar_manager, name.text) >= 0) {
fprintf(rsp, "Item %s already exists \n", name.text);
respond(rsp, "[?] Add: Item '%s' already exists\n", name.text);
return;
}
struct bar_item* bar_item = bar_manager_create_item(&g_bar_manager);
bar_item_set_type(bar_item, command.text[0]);
bar_item_set_position(bar_item, position.text[0]);
if (position.text[0] == POSITION_POPUP) {
char* pair = string_copy(position.text);
struct key_value_pair key_value_pair = get_key_value_pair(pair, '.');
if (key_value_pair.key && key_value_pair.value) {
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager,
key_value_pair.value);
if (item_index_for_name < 0) {
fprintf(rsp, "Name: %s not found in bar items \n", key_value_pair.value);
printf("Name: %s not found in bar items \n", key_value_pair.value);
free(pair);
return;
}
struct bar_item* target_item = g_bar_manager.bar_items[item_index_for_name];
popup_add_item(&target_item->popup, bar_item);
}
free(pair);
}
bar_item_set_name(bar_item, token_to_string(name));
if (token_equals(command, COMMAND_ADD_ITEM)) {
@ -177,28 +156,46 @@ static void handle_domain_add(FILE* rsp, struct token domain, char* message) {
if (index >= 0)
group_add_member(bar_item->group, g_bar_manager.bar_items[index]);
else {
printf("Item %s not found! \n", member.text);
fprintf(rsp, "Item %s not found! \n", member.text);
respond(rsp, "[?] Add (Group) %s: Failed to add member '%s', item not found\n", bar_item->name, member.text);
}
member = get_token(&message);
}
}
} else {
printf("Command: %s not found \n", command.text);
fprintf(rsp, "Command: %s not found \n", command.text);
respond(rsp, "[!] Add %s: Invalid item type '%s'\n", bar_item->name, command.text);
return;
}
if (position.text[0] == POSITION_POPUP) {
char* pair = string_copy(position.text);
struct key_value_pair key_value_pair = get_key_value_pair(pair, '.');
if (key_value_pair.key && key_value_pair.value) {
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager,
key_value_pair.value);
if (item_index_for_name < 0) {
respond(rsp,
"[!] Add (Popup) %s: Item '%s' is not a valid popup host\n",
bar_item->name,
key_value_pair.value,
bar_item->name );
free(pair);
bar_item_set_position(bar_item, POSITION_LEFT);
return;
}
struct bar_item* target_item = g_bar_manager.bar_items[item_index_for_name];
popup_add_item(&target_item->popup, bar_item);
}
free(pair);
}
bar_item_needs_update(bar_item);
}
// Syntax: sketchybar -m --set <name> <property>=<value> ... <property>=<value>
// Syntax: sketchybar -m --default <property>=<value> ... <property>=<value>
static void handle_domain_default(FILE* rsp, struct token domain, char* message) {
bar_item_parse_set_message(&g_bar_manager.default_item, message, rsp);
}
// Syntax: sketchybar -m --bar <property>=<value> ... <property>=<value>
static bool handle_domain_bar(FILE *rsp, struct token domain, char *message) {
struct token command = get_token(&message);
bool needs_refresh = false;
@ -267,18 +264,10 @@ static bool handle_domain_bar(FILE *rsp, struct token domain, char *message) {
if (position.length > 0)
needs_refresh = bar_manager_set_display(&g_bar_manager,
position.text[0]);
else {
printf("value for %s must be either 'main' or 'all'.\n", command.text);
fprintf(rsp, "value for %s must be either 'main' or 'all'.\n", command.text);
}
} else if (token_equals(command, PROPERTY_POSITION)) {
struct token position = get_token(&message);
if (position.length > 0)
needs_refresh = bar_manager_set_position(&g_bar_manager, position.text[0]);
else {
printf("value for %s must be either 'top' or 'bottom'.\n", command.text);
fprintf(rsp, "value for %s must be either 'top' or 'bottom'.\n", command.text);
}
}
else
needs_refresh = background_parse_sub_domain(&g_bar_manager.background, rsp, command, message);
@ -320,10 +309,6 @@ static char* get_batch_line(char** message) {
return rbr_msg;
}
// Syntax: sketchybar -m --query bar
// Syntax: sketchybar -m --query item <name>
// Syntax: sketchybar -m --query defaults
// Syntax: sketchybar -m --query events
static void handle_domain_query(FILE* rsp, struct token domain, char* message) {
struct token token = get_token(&message);
@ -334,8 +319,7 @@ static void handle_domain_query(FILE* rsp, struct token domain, char* message) {
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager,
name.text );
if (item_index_for_name < 0) {
fprintf(rsp, "Name: %s not found in bar items \n", name.text);
printf("Name: %s not found in bar items \n", name.text);
respond(rsp, "[!] Query: Item '%s' not found\n", name.text);
return;
}
bar_item_serialize(g_bar_manager.bar_items[item_index_for_name], rsp);
@ -350,15 +334,13 @@ static void handle_domain_query(FILE* rsp, struct token domain, char* message) {
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager,
name.text );
if (item_index_for_name < 0) {
fprintf(rsp, "Not a valid query, or item: %s not found \n", name.text);
printf("Not a valid query, or item: %s not found \n", name.text);
respond(rsp, "[!] Query: Invalid query, or item '%s' not found \n", name.text);
return;
}
bar_item_serialize(g_bar_manager.bar_items[item_index_for_name], rsp);
}
}
// Syntax: sketchybar -m --remove <name>
static void handle_domain_remove(FILE* rsp, struct token domain, char* message) {
struct token name = get_token(&message);
uint32_t count = 0;
@ -374,8 +356,7 @@ static void handle_domain_remove(FILE* rsp, struct token domain, char* message)
reti = regcomp(&regex, regstring, 0);
free(regstring);
if (reti) {
fprintf(rsp, "Could not compile regex: %s \n", name.text);
printf("Could not compile regex: %s \n", name.text);
respond(rsp, "[!] Remove: Could not compile regex '%s'\n", name.text);
return;
}
@ -391,8 +372,7 @@ static void handle_domain_remove(FILE* rsp, struct token domain, char* message)
else if (reti != REG_NOMATCH) {
char buf[100];
regerror(reti, &regex, buf, sizeof(buf));
fprintf(rsp, "Regex match failed: %s\n", buf);
printf("Regex match failed: %s\n", buf);
respond(rsp, "[!] Remove: Regex match failed '%s'\n", buf);
return;
}
}
@ -402,8 +382,7 @@ static void handle_domain_remove(FILE* rsp, struct token domain, char* message)
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager,
name.text );
if (item_index_for_name < 0) {
fprintf(rsp, "Name: %s not found in bar items \n", name.text);
printf("Name: %s not found in bar items \n", name.text);
respond(rsp, "[!] Remove: Item '%s' not found\n", name.text);
return;
}
bar_items = realloc(bar_items, sizeof(struct bar_item*));
@ -419,7 +398,6 @@ static void handle_domain_remove(FILE* rsp, struct token domain, char* message)
if (bar_items) free(bar_items);
}
// Syntax: sketchybar -m --move <name> </> <reference>
static void handle_domain_move(FILE* rsp, struct token domain, char* message) {
struct token name = get_token(&message);
struct token direction = get_token(&message);
@ -428,8 +406,7 @@ static void handle_domain_move(FILE* rsp, struct token domain, char* message) {
int item_index = bar_manager_get_item_index_for_name(&g_bar_manager, name.text);
int reference_item_index = bar_manager_get_item_index_for_name(&g_bar_manager, reference.text);
if (item_index < 0 || reference_item_index < 0) {
fprintf(rsp, "Name: %s or %s not found in bar items \n", name.text, reference.text);
printf("Name: %s or %s not found in bar items \n", name.text, reference.text);
respond(rsp, "[!] Move: Item '%s' or '%s' not found\n", name.text, reference.text);
return;
}
@ -450,8 +427,7 @@ static void handle_domain_order(FILE* rsp, struct token domain, char* message) {
while (name.text && name.length > 0) {
int index = bar_manager_get_item_index_for_name(&g_bar_manager, name.text);
if (index < 0) {
fprintf(rsp, "Item: %s does not exist in bar items.\n", name.text);
printf("Item: %s does not exist in bar items.\n", name.text);
respond(rsp, "[!] Order: Item '%s' not found\n", name.text);
name = get_token(&message);
continue;
}
@ -462,7 +438,10 @@ 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);
g_bar_manager.frozen = false;
bar_manager_refresh(&g_bar_manager, false);
bar_manager_unfreeze(&g_bar_manager);
}
void handle_message_mach(struct mach_buffer* buffer) {
@ -495,8 +474,7 @@ void handle_message_mach(struct mach_buffer* buffer) {
reti = regcomp(&regex, regstring, 0);
free(regstring);
if (reti) {
fprintf(rsp, "Could not compile regex: %s \n", name.text);
printf("Could not compile regex: %s \n", name.text);
respond(rsp, "[!] Set: Could not compile regex '%s'\n", name.text);
break;
}
@ -510,10 +488,9 @@ void handle_message_mach(struct mach_buffer* buffer) {
bar_items[count - 1] = bar_item;
}
else if (reti != REG_NOMATCH) {
char buf[100];
regerror(reti, &regex, buf, sizeof(buf));
fprintf(rsp, "Regex match failed: %s\n", buf);
printf("Regex match failed: %s\n", buf);
char buf[1024];
regerror(reti, &regex, buf, sizeof(char)*1024);
respond(rsp, "[?] Set: No match found for regex '%s'\n", name.text);
break;
}
}
@ -522,8 +499,7 @@ void handle_message_mach(struct mach_buffer* buffer) {
else {
int item_index_for_name = bar_manager_get_item_index_for_name(&g_bar_manager, name.text);
if (item_index_for_name < 0) {
fprintf(rsp, "Name: %s not found in bar items \n", name.text);
printf("Name: %s not found in bar items \n", name.text);
respond(rsp, "[!] Set: Item not found '%s'\n", name.text);
break;
}
bar_items = realloc(bar_items, sizeof(struct bar_item*));
@ -538,7 +514,10 @@ void handle_message_mach(struct mach_buffer* buffer) {
struct token tmp = {string_copy(token.text), token.length};
char* rbr_msg = reformat_batch_key_value_pair(tmp);
free(tmp.text);
if (!rbr_msg) break;
if (!rbr_msg) {
respond(rsp, "[!] Set (%s): Expected <key>=<value> pair, but got: '%s'\n", bar_items[i]->name, token.text);
break;
}
bar_item_parse_set_message(bar_items[i], rbr_msg, rsp);
free(rbr_msg);
}
@ -550,7 +529,10 @@ void handle_message_mach(struct mach_buffer* buffer) {
struct token token = get_token(&message);
while (token.text && token.length > 0) {
char* rbr_msg = reformat_batch_key_value_pair(token);
if (!rbr_msg) break;
if (!rbr_msg) {
respond(rsp, "[!] Set (default): Expected <key>=<value> pair, but got: '%s'\n", token.text);
break;
}
handle_domain_default(rsp, command, rbr_msg);
free(rbr_msg);
if (message && message[0] == '-') break;
@ -563,7 +545,10 @@ void handle_message_mach(struct mach_buffer* buffer) {
struct token token = get_token(&message);
while (token.text && token.length > 0) {
char* rbr_msg = reformat_batch_key_value_pair(token);
if (!rbr_msg) break;
if (!rbr_msg) {
respond(rsp, "[!] Bar: Expected <key>=<value> pair, but got: '%s'\n", token.text);
break;
}
bar_needs_refresh |= handle_domain_bar(rsp, command, rbr_msg);
free(rbr_msg);
if (message && message[0] == '-') break;
@ -619,15 +604,19 @@ void handle_message_mach(struct mach_buffer* buffer) {
exit(0);
} else {
char* rbr_msg = get_batch_line(&message);
fprintf(rsp, "unknown domain %s\n", command.text);
printf("unknown domain %s\n", command.text);
respond(rsp, "[!] Unknown domain '%s'\n", command.text);
free(rbr_msg);
}
command = get_token(&message);
}
if (bar_needs_refresh) bar_manager_resize(&g_bar_manager);
if (bar_needs_refresh) {
bar_manager_resize(&g_bar_manager);
g_bar_manager.bar_needs_update = true;
}
g_bar_manager.frozen = false;
bar_manager_refresh(&g_bar_manager, bar_needs_refresh);
bar_manager_refresh(&g_bar_manager, false);
bar_manager_unfreeze(&g_bar_manager);
if (rsp) fclose(rsp);

View file

@ -93,6 +93,8 @@
#define COMMAND_SUBSCRIBE_MOUSE_ENTERED "mouse.entered"
#define COMMAND_SUBSCRIBE_MOUSE_EXITED "mouse.exited"
#define COMMAND_SUBSCRIBE_MOUSE_CLICKED "mouse.clicked"
#define COMMAND_SUBSCRIBE_MOUSE_ENTERED_GLOBAL "mouse.entered.global"
#define COMMAND_SUBSCRIBE_MOUSE_EXITED_GLOBAL "mouse.exited.global"
#define DOMAIN_QUERY "--query"
#define COMMAND_QUERY_DEFAULT_ITEMS "default_menu_items"

View file

@ -3,10 +3,13 @@
#include <CoreGraphics/CoreGraphics.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <time.h>
#include "env_vars.h"
#include "defines.h"
#define array_count(a) (sizeof((a)) / sizeof(*(a)))
#define max(a, b) a > b ? a : b
#define min(a, b) a < b ? a : b
#define MAXLEN 512
#define FORK_TIMEOUT 60
@ -28,6 +31,7 @@ struct rgba_color {
};
static struct rgba_color g_transparent = { 0 };
static CGPoint g_nirvana = {-9999, -9999};
struct token {
char *text;
@ -51,6 +55,23 @@ static inline void notification_destroy(struct notification* notification) {
free(notification);
}
static inline void respond(FILE* rsp, char* response, ...) {
time_t t = time(NULL);
struct tm ltime = *localtime(&t);
printf("[%d-%02d-%02d %02d:%02d:%02d] ", ltime.tm_year + 1900,
ltime.tm_mon + 1,
ltime.tm_mday,
ltime.tm_hour,
ltime.tm_min,
ltime.tm_sec );
va_list args;
va_start(args, response);
vfprintf(rsp, response, args);
vfprintf(stdout, response, args);
va_end(args);
}
static inline uint32_t hex_from_rgba_color(struct rgba_color rgba_color) {
uint32_t result = 0;
result += ((uint32_t)(rgba_color.a * 255.0)) << 24;

View file

@ -12,13 +12,6 @@ static inline void debug(const char *format, ...) {
va_end(args);
}
static inline void warn(const char *format, ...) {
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
}
static inline void error(const char *format, ...) {
va_list args;
va_start(args, format);

View file

@ -19,6 +19,12 @@ void popup_init(struct popup* popup) {
popup->background.color = rgba_color_from_hex(0x44000000);
}
CGRect popup_get_frame(struct popup* popup) {
return (CGRect){{popup->anchor.x, popup->anchor.y},
{popup->background.bounds.size.width,
popup->background.bounds.size.height}};
}
void popup_calculate_bounds(struct popup* popup) {
uint32_t y = popup->background.border_width;
uint32_t x = 0;
@ -36,9 +42,8 @@ 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;
uint32_t cell_height = bar_item_get_height(bar_item) > popup->cell_size
? bar_item_get_height(bar_item)
: popup->cell_size;
uint32_t cell_height = max(bar_item_get_height(bar_item),
popup->cell_size );
total_item_width += bar_item->background.padding_right
+ bar_item->background.padding_left
@ -54,7 +59,6 @@ void popup_calculate_bounds(struct popup* popup) {
x = (width - total_item_width) / 2;
}
}
for (int j = 0; j < popup->num_items; j++) {
@ -62,20 +66,20 @@ void popup_calculate_bounds(struct popup* popup) {
if (popup->horizontal) bar_item = popup->items[j];
else bar_item = popup->items[popup->num_items - 1 - j];
if (!bar_item->drawing) continue;
uint32_t cell_height = bar_item_get_height(bar_item) > popup->cell_size
? bar_item_get_height(bar_item)
: popup->cell_size;
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_width = bar_item->background.padding_right
+ bar_item->background.padding_left
+ bar_item_calculate_bounds(bar_item,
popup->horizontal
? height
: cell_height,
x,
y + (popup->horizontal
? height
: cell_height) / 2);
item_height,
item_x,
item_y );
if (item_width > width && !popup->horizontal) width = item_width;
if (popup->horizontal) x += item_width;
@ -171,12 +175,11 @@ void popup_set_drawing(struct popup* popup, bool drawing) {
}
void popup_draw(struct popup* popup) {
if (!popup->drawing) return;
if (!popup->drawing || popup->adid <= 0) return;
SLSOrderWindow(g_connection, popup->window.id, -1, 0);
window_resize(&popup->window, (CGRect){{popup->anchor.x, popup->anchor.y},
{popup->background.bounds.size.width,
popup->background.bounds.size.height}});
window_set_frame(&popup->window, popup_get_frame(popup));
window_apply_frame(&popup->window);
CGContextClearRect(popup->window.context, popup->background.bounds);
@ -252,13 +255,11 @@ bool popup_parse_sub_domain(struct popup* popup, FILE* rsp, struct token propert
entry,
message );
else {
fprintf(rsp, "Invalid subdomain: %s \n", subdom.text);
printf("Invalid subdomain: %s \n", subdom.text);
respond(rsp, "[!] Popup: Invalid subdomain '%s'\n", subdom.text);
}
}
else {
fprintf(rsp, "Unknown property: %s \n", property.text);
printf("Unknown property: %s \n", property.text);
respond(rsp, "[!] Popup: Invalid property '%s'\n", property.text);
}
}
return false;

View file

@ -32,6 +32,7 @@ void popup_add_item(struct popup* popup, struct bar_item* item);
void 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);
void popup_calculate_bounds(struct popup* popup);
void popup_draw(struct popup* popup);
void popup_destroy(struct popup* popup);

View file

@ -76,8 +76,7 @@ bool shadow_parse_sub_domain(struct shadow* shadow, FILE* rsp, struct token prop
token_to_int(token) );
}
else {
fprintf(rsp, "Unknown property: %s \n", property.text);
printf("Unknown property: %s \n", property.text);
respond(rsp, "[!] Shadow: Invalid property '%s'\n", property.text);
}
return needs_refresh;

View file

@ -172,7 +172,10 @@ int main(int argc, char **argv) {
mouse_begin();
display_begin();
workspace_event_handler_begin(&g_workspace_context);
windows_freeze();
bar_manager_begin(&g_bar_manager);
windows_unfreeze();
if (!mach_server_begin(&g_mach_server, mach_message_handler))
error("sketchybar: could not initialize daemon! abort..\n");

View file

@ -383,13 +383,11 @@ bool text_parse_sub_domain(struct text* text, FILE* rsp, struct token property,
else if (token_equals(subdom, SUB_DOMAIN_SHADOW))
return shadow_parse_sub_domain(&text->shadow, rsp, entry, message);
else {
fprintf(rsp, "Invalid subdomain: %s \n", subdom.text);
printf("Invalid subdomain: %s \n", subdom.text);
respond(rsp, "[!] Text: Invalid subdomain '%s' \n", subdom.text);
}
}
else {
fprintf(rsp, "Unknown property: %s \n", property.text);
printf("Unknown property: %s \n", property.text);
respond(rsp, "[!] Text: Invalid property '%s'\n", property.text);
}
}

View file

@ -1,11 +1,8 @@
#include "window.h"
static CFTypeRef window_create_region(struct window *window, CGRect frame) {
window->frame = (CGRect) {{0, 0},{frame.size.width, frame.size.height}};
window->origin = frame.origin;
CFTypeRef frame_region;
CGSNewRegionWithRect(&window->frame, &frame_region);
CGSNewRegionWithRect(&frame, &frame_region);
return frame_region;
}
@ -13,12 +10,16 @@ void window_create(struct window* window, CGRect frame) {
uint64_t set_tags = kCGSStickyTagBit | kCGSHighQualityResamplingTagBit;
uint64_t clear_tags = kCGSSuperStickyTagBit;
window->origin = frame.origin;
window->frame.origin = (CGPoint){0, 0};
window->frame.size = frame.size;
frame.origin = (CGPoint){0, 0};
CFTypeRef frame_region = window_create_region(window, frame);
SLSNewWindow(g_connection, 2, window->origin.x, window->origin.y,
frame_region,
&window->id );
SLSAddActivationRegion(g_connection, window->id, frame_region);
CFRelease(frame_region);
SLSSetWindowResolution(g_connection, window->id, 2.0f);
@ -26,49 +27,65 @@ void window_create(struct window* window, CGRect frame) {
SLSClearWindowTags(g_connection, window->id, &clear_tags, 64);
SLSSetWindowOpacity(g_connection, window->id, 0);
// const void* keys[] = { CFSTR("CGWindowContextShouldUseCA") };
// const void* values[] = { kCFBooleanTrue };
// CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// CGContextRef context = SLWindowContextCreate(g_connection, window->id, dict);
window->context = SLWindowContextCreate(g_connection, window->id, 0);
// CFRelease(dict);
const void* keys[] = { CFSTR("CGWindowContextShouldUseCA") };
const void* values[] = { kCFBooleanTrue };
CFDictionaryRef dict = CFDictionaryCreate(NULL,
keys,
values,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
window->context = SLWindowContextCreate(g_connection, window->id, dict);
CFRelease(dict);
CGContextSetInterpolationQuality(window->context, kCGInterpolationNone);
// CGLayerRef layer = CGLayerCreateWithContext(context, window->frame.size, 0);
// window->context = CGLayerGetContext(layer);
// SLSAddSurface(g_connection, window->id, &window->surface_id);
// SLSSetSurfaceBounds(g_connection, window->id, window->surface_id, window->frame);
// SLSBindSurface(g_connection, window->id, window->surface_id, 0, 0, window->context);
// SLSOrderSurface(g_connection, window->id, window->surface_id, 0, 1);
window->needs_move = false;
window->needs_resize = false;
}
void window_freeze(struct window* window) {
void windows_freeze() {
SLSDisableUpdate(g_connection);
}
void window_unfreeze(struct window* window) {
void windows_unfreeze() {
SLSReenableUpdate(g_connection);
}
void window_resize(struct window* window, CGRect frame) {
CFTypeRef frame_region = window_create_region(window, frame);
SLSOrderWindow(g_connection, window->id, -1, 0);
SLSSetWindowShape(g_connection,
window->id,
window->origin.x,
window->origin.y,
frame_region );
void window_set_frame(struct window* window, CGRect frame) {
if (!CGPointEqualToPoint(window->origin, frame.origin)) {
window->needs_move = true;
window->origin = frame.origin;
}
SLSClearActivationRegion(g_connection, window->id);
SLSAddActivationRegion(g_connection, window->id, frame_region);
SLSRemoveAllTrackingAreas(g_connection, window->id);
if (!CGSizeEqualToSize(window->frame.size, frame.size)) {
window->needs_resize = true;
window->frame.size = frame.size;
}
}
SLSOrderWindow(g_connection, window->id, 1, 0);
CFRelease(frame_region);
bool window_apply_frame(struct window* window) {
if (window->needs_resize) {
CFTypeRef frame_region = window_create_region(window, window->frame);
SLSSetWindowShape(g_connection,
window->id,
window->origin.x,
window->origin.y,
frame_region );
SLSRemoveAllTrackingAreas(g_connection, window->id);
CFRelease(frame_region);
window->needs_move = false;
window->needs_resize = false;
return true;
} else if (window->needs_move) {
CGPoint origin = window->origin;
SLSMoveWindow(g_connection, window->id, &origin);
window->needs_move = false;
return false;
}
return false;
}
void window_close(struct window* window) {
@ -77,6 +94,10 @@ void window_close(struct window* window) {
window->context = NULL;
window->id = 0;
window->origin = CGPointZero;
window->frame = CGRectNull;
window->needs_move = false;
window->needs_resize = false;
}
void window_set_level(struct window* window, uint32_t level) {
@ -96,6 +117,7 @@ void window_disable_shadow(struct window* window) {
CFNumberRef shadow_density_cf = CFNumberCreate(kCFAllocatorDefault,
kCFNumberCFIndexType,
&shadow_density );
const void *keys[1] = { CFSTR("com.apple.WindowShadowDensity") };
const void *values[1] = { shadow_density_cf };
CFDictionaryRef shadow_props_cf = CFDictionaryCreate(NULL,

View file

@ -3,13 +3,14 @@
extern CGError SLSDisableUpdate(int cid);
extern CGError SLSReenableUpdate(int cid);
extern CGError SLSNewWindow(int cid, int type, float x, float y, CFTypeRef region, uint32_t *wid);
extern CGError SLSNewWindow(int cid, int type, float x, float y, CFTypeRef region, uint64_t *wid);
extern CGError SLSReleaseWindow(int cid, uint32_t wid);
extern CGError SLSSetWindowTags(int cid, uint32_t wid, uint64_t* tags, int tag_size);
extern CGError SLSClearWindowTags(int cid, uint32_t wid, uint64_t* tags, int tag_size);
extern CGError SLSSetWindowShape(int cid, uint32_t wid, float x_offset, float y_offset, CFTypeRef shape);
extern CGError SLSSetWindowResolution(int cid, uint32_t wid, double res);
extern CGError SLSSetWindowOpacity(int cid, uint32_t wid, bool isOpaque);
extern CGError SLSSetWindowAlpha(int cid, uint32_t wid, float alpha);
extern CGError SLSSetWindowBackgroundBlurRadius(int cid, uint32_t wid, uint32_t radius);
extern CGError SLSOrderWindow(int cid, uint32_t wid, int mode, uint32_t relativeToWID);
extern CGError SLSSetWindowLevel(int cid, uint32_t wid, int level);
@ -21,8 +22,13 @@ extern CGError SLSClearActivationRegion(uint32_t cid, uint32_t wid);
extern CGError SLSRemoveAllTrackingAreas(uint32_t cid, uint32_t wid);
extern CGError SLSMoveWindow(int cid, uint32_t wid, CGPoint *point);
extern CGError SLSWindowSetShadowProperties(uint32_t wid, CFDictionaryRef properties);
extern CGError SLSAddWindowToWindowOrderingGroup(int cid, uint32_t parent_wid, uint32_t child_wid, int order);
extern CGError SLSRemoveFromOrderingGroup(int cid, uint32_t wid);
extern int SLSSpaceGetType(int cid, uint64_t sid);
extern void SLSCaptureWindowsContentsToRectWithOptions(uint32_t cid, uint64_t* wid, bool meh, CGRect bounds, uint32_t flags, CGImageRef* image);
extern int SLSGetScreenRectForWindow(uint32_t cid, uint32_t wid, CGRect* out);
extern CGError SLSAddSurface(int cid, uint32_t wid, uint32_t* outSID);
extern CGError SLSRemoveSurface(int cid, uint32_t wid, uint32_t sid);
extern CGError SLSBindSurface(int cid, uint32_t wid, uint32_t sid, int x, int y, CGContextRef ctx);
@ -37,7 +43,10 @@ extern CGError SLSFlushSurface(int cid, uint32_t wid, uint32_t surface, int para
#define kCGSSuperStickyTagBit (1ULL << 45)
struct window {
uint32_t id;
bool needs_move;
bool needs_resize;
uint64_t id;
uint32_t surface_id;
CGRect frame;
@ -47,12 +56,16 @@ struct window {
void window_create(struct window* window, CGRect frame);
void window_close(struct window* window);
void window_resize(struct window* window, CGRect frame);
void window_freeze(struct window* window);
void window_unfreeze(struct window* window);
void window_set_frame(struct window* window, CGRect frame);
bool window_apply_frame(struct window* window);
void window_set_blur_radius(struct window* window, uint32_t blur_radius);
void window_disable_shadow(struct window* window);
void window_set_level(struct window* window, uint32_t level);
void context_set_font_smoothing(CGContextRef context, bool smoothing);
void windows_freeze();
void windows_unfreeze();

View file

@ -14,3 +14,5 @@ void workspace_create_custom_observer (void **context, char* notification);
void workspace_event_handler_init(void **context);
void workspace_event_handler_begin(void **context);
void workspace_event_handler_end(void *context);
uint32_t get_window_id_from_cg_event(CGEventRef cgevent);

View file

@ -23,6 +23,11 @@ void workspace_create_custom_observer (void **context, char* notification) {
[ws_context addCustomObserver:@(notification)];
}
uint32_t get_window_id_from_cg_event(CGEventRef cgevent) {
NSEvent *nsEvent = [NSEvent eventWithCGEvent:cgevent];
return [nsEvent windowNumber];
}
@implementation workspace_context
- (id)init {
if ((self = [super init])) {