mirror of
https://github.com/FelixKratz/SketchyBar
synced 2024-11-26 13:20:24 +00:00
Merge pull request #191 from FelixKratz/picky_redraw
Major Performance Optimizations
This commit is contained in:
commit
9e02b7e067
31 changed files with 690 additions and 407 deletions
|
@ -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:
|
||||
|
|
27
src/alias.c
27
src/alias.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.,
|
||||
|
|
|
@ -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
214
src/bar.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
159
src/bar_item.c
159
src/bar_item.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
78
src/event.c
78
src/event.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
25
src/group.c
25
src/group.c
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
159
src/message.c
159
src/message.c
|
@ -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(®ex, 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, ®ex, 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(®ex, 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, ®ex, buf, sizeof(buf));
|
||||
fprintf(rsp, "Regex match failed: %s\n", buf);
|
||||
printf("Regex match failed: %s\n", buf);
|
||||
char buf[1024];
|
||||
regerror(reti, ®ex, 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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
45
src/popup.c
45
src/popup.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
94
src/window.c
94
src/window.c
|
@ -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,
|
||||
|
|
23
src/window.h
23
src/window.h
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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])) {
|
||||
|
|
Loading…
Reference in a new issue