mirror of
https://github.com/FelixKratz/SketchyBar
synced 2024-11-10 05:44:16 +00:00
experimental: default item aliasing
This commit is contained in:
parent
87d94d09fd
commit
86da5be578
9 changed files with 133 additions and 3 deletions
21
README.md
21
README.md
|
@ -380,6 +380,27 @@ which you can freely configure to your liking by supplying a different script to
|
|||
For performance reasons the space script is only run on change.
|
||||
I plan on increasing the available environment variables in scripting step by step but if you have a suggestion let me know in the issues.
|
||||
|
||||
## Experimental Features
|
||||
These are highly experimental features that need some work, but are included on HEAD anyways, because they do not interfere with
|
||||
the rest of the bar.
|
||||
### Default Menu Bar Item Alias
|
||||
It is possible to create an alias for default menu bar items (such as MeetingBar, etc.) in sketchybar. This is still a bit janky though and needs some serious work
|
||||
till it will be usable without headache.
|
||||
|
||||
Important: Autohiding of the default menu bar *must* be disabled, such that the bar is shown on screen before starting sketchybar. <br>
|
||||
Sketchybar needs to be configured with *topmost* set to on, such that it draws on top of the default menu bar. <br>
|
||||
I recommend turning off transparency of the bar and setting *margin* and *y_offset* to 0 and the *height* of the bar to at least 24, so that
|
||||
sketchybar completely occludes the default bar. <br>
|
||||
I also highly recommend setting a wallpaper on all spaces that makes the default menu bar items appear in either the light or the dark theme consitently.
|
||||
|
||||
It is now possible to create an alias of a default menu bar item with the following syntax:
|
||||
```bash
|
||||
sketchybar -m add alias <application_name> <position>
|
||||
```
|
||||
this operation requires screen capture permissions, which should be granted in the system preferences.
|
||||
This will put the default item into sketchybar.
|
||||
Aliases currently are not clickable.
|
||||
|
||||
## Credits
|
||||
yabai,
|
||||
spacebar,
|
||||
|
|
2
makefile
2
makefile
|
@ -1,6 +1,6 @@
|
|||
FRAMEWORK_PATH = -F/System/Library/PrivateFrameworks
|
||||
FRAMEWORK = -framework Carbon -framework Cocoa -framework SkyLight
|
||||
BUILD_FLAGS = -std=c99 -Wall -DNDEBUG -O2 -fvisibility=hidden -mmacosx-version-min=10.13
|
||||
BUILD_FLAGS = -std=c99 -Wall -DNDEBUG -Ofast -fvisibility=hidden -mmacosx-version-min=10.13
|
||||
BUILD_PATH = ./bin
|
||||
SKETCHYBAR_SRC = ./src/manifest.m
|
||||
BINS = $(BUILD_PATH)/sketchybar
|
||||
|
|
61
src/alias.c
Normal file
61
src/alias.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include "alias.h"
|
||||
#include "misc/helpers.h"
|
||||
#include <string.h>
|
||||
|
||||
void alias_init(struct alias* alias, char* name) {
|
||||
alias->using_light_colors = true;
|
||||
alias->name = name;
|
||||
alias->wid = 0;
|
||||
alias->image_ref = NULL;
|
||||
alias_update_image(alias);
|
||||
}
|
||||
|
||||
void alias_find_window(struct alias* alias) {
|
||||
CFArrayRef window_list = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
|
||||
int window_count = CFArrayGetCount(window_list);
|
||||
|
||||
for (int i = 0; i < window_count; ++i) {
|
||||
CFDictionaryRef dictionary = CFArrayGetValueAtIndex(window_list, i);
|
||||
if (!dictionary) continue;
|
||||
CFStringRef owner_ref = CFDictionaryGetValue(dictionary, kCGWindowOwnerName);
|
||||
CFStringRef name_ref = CFDictionaryGetValue(dictionary, kCGWindowName);
|
||||
if (!name_ref) continue;
|
||||
if (!owner_ref) continue;
|
||||
|
||||
CFNumberRef layer_ref = CFDictionaryGetValue(dictionary, kCGWindowLayer);
|
||||
if (!layer_ref) continue;
|
||||
|
||||
uint64_t layer = 0;
|
||||
CFNumberGetValue(layer_ref, CFNumberGetType(layer_ref), &layer);
|
||||
if (layer != MENUBAR_LAYER) continue;
|
||||
|
||||
CFNumberRef window_id_ref = CFDictionaryGetValue(dictionary, kCGWindowNumber);
|
||||
if (!window_id_ref) continue;
|
||||
CGWindowID window_id = 0;
|
||||
CFNumberGetValue(window_id_ref, CFNumberGetType(window_id_ref), &window_id);
|
||||
char* owner = cfstring_copy(owner_ref);
|
||||
char* name = cfstring_copy(name_ref);
|
||||
|
||||
if (strcmp(alias->name, owner) != 0) { free(owner); free(name); continue; }
|
||||
alias->wid = window_id;
|
||||
|
||||
free(owner);
|
||||
free(name);
|
||||
CFRelease(window_list);
|
||||
return;
|
||||
}
|
||||
alias->wid = 0;
|
||||
CFRelease(window_list);
|
||||
}
|
||||
|
||||
bool alias_update_image(struct alias* alias) {
|
||||
if (alias->wid == 0) alias_find_window(alias);
|
||||
if (alias->wid == 0) { alias->image_ref = NULL; return false; }
|
||||
if (alias->image_ref) CFRelease(alias->image_ref);
|
||||
alias->image_ref = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow,
|
||||
alias->wid, kCGWindowImageBestResolution);
|
||||
if (!alias->image_ref) return false;
|
||||
alias->size.x = CGImageGetWidth(alias->image_ref);
|
||||
alias->size.y = CGImageGetHeight(alias->image_ref);
|
||||
return true;
|
||||
}
|
18
src/alias.h
Normal file
18
src/alias.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef ALIAS_H
|
||||
#define ALIAS_H
|
||||
|
||||
#define MENUBAR_LAYER 0x19
|
||||
|
||||
struct alias {
|
||||
bool using_light_colors;
|
||||
char* name;
|
||||
uint32_t wid;
|
||||
CGImageRef image_ref;
|
||||
CGPoint size;
|
||||
};
|
||||
|
||||
void alias_init(struct alias* alias, char* name);
|
||||
bool alias_update_image(struct alias* alias);
|
||||
void alias_find_window(struct alias* alias);
|
||||
|
||||
#endif
|
22
src/bar.c
22
src/bar.c
|
@ -154,6 +154,12 @@ void bar_draw_item_background(struct bar* bar, struct bar_item* bar_item, uint32
|
|||
draw_rect(bar->context, draw_region, &bar_item->background_color, bar_item->background_corner_radius, bar_item->background_border_width, &bar_item->background_border_color, false);
|
||||
}
|
||||
|
||||
void bar_draw_alias(struct bar* bar, struct bar_item* bar_item, uint32_t x) {
|
||||
if (!bar_item->has_alias || !bar_item->alias.image_ref) return;
|
||||
CGRect bounds = {{x, (bar->frame.size.height - bar_item->alias.size.y) / 2},{bar_item->alias.size.x, bar_item->alias.size.y}};
|
||||
CGContextDrawImage(bar->context, bounds, bar_item->alias.image_ref);
|
||||
}
|
||||
|
||||
void bar_redraw(struct bar* bar) {
|
||||
uint32_t did = bar->adid;
|
||||
uint32_t sid = bar->sid;
|
||||
|
@ -172,6 +178,7 @@ void bar_redraw(struct bar* bar) {
|
|||
if (!bar_item->drawing) continue;
|
||||
if (bar_item->associated_display > 0 && !(bar_item->associated_display & (1 << did))) continue;
|
||||
if (bar_item->associated_space > 0 && !(bar_item->associated_space & (1 << sid)) && (bar_item->type != BAR_COMPONENT_SPACE)) continue;
|
||||
if (bar_item->has_alias) alias_update_image(&bar_item->alias);
|
||||
struct bar_line* label = &bar_item->label_line;
|
||||
struct bar_line* icon = &bar_item->icon_line;
|
||||
CGPoint icon_position = bar_align_line(bar, icon, ALIGN_CENTER, ALIGN_CENTER);
|
||||
|
@ -190,6 +197,9 @@ void bar_redraw(struct bar* bar) {
|
|||
if (!bar_item->nospace)
|
||||
bar_left_final_item_x += bar_item->graph_data.graph_width;
|
||||
}
|
||||
if (bar_item->has_alias) {
|
||||
bar_left_final_item_x += bar_item->alias.size.x;
|
||||
}
|
||||
}
|
||||
else if (bar_item->position == BAR_POSITION_RIGHT) {
|
||||
label_position.x = bar_right_first_item_x - label->bounds.size.width - bar_item->label_spacing_right;
|
||||
|
@ -202,6 +212,10 @@ void bar_redraw(struct bar* bar) {
|
|||
graph_rtl = true;
|
||||
if (!bar_item->nospace)
|
||||
bar_right_first_item_x -= bar_item->graph_data.graph_width;
|
||||
}
|
||||
if (bar_item->has_alias) {
|
||||
icon_position.x -= bar_item->alias.size.x;
|
||||
bar_right_first_item_x -= bar_item->alias.size.x;
|
||||
}
|
||||
}
|
||||
else if (bar_item->position == BAR_POSITION_CENTER) {
|
||||
|
@ -215,6 +229,9 @@ void bar_redraw(struct bar* bar) {
|
|||
if (!bar_item->nospace)
|
||||
bar_center_first_item_x += bar_item->graph_data.graph_width;
|
||||
}
|
||||
if (bar_item->has_alias) {
|
||||
bar_center_first_item_x += bar_item->alias.size.x;
|
||||
}
|
||||
}
|
||||
bar_item->label_line.bounds.origin = label_position;
|
||||
bar_item->icon_line.bounds.origin = icon_position;
|
||||
|
@ -223,6 +240,7 @@ void bar_redraw(struct bar* bar) {
|
|||
|
||||
bar_draw_item_background(bar, bar_item, sid);
|
||||
bar_draw_line(bar, icon, icon_position.x, icon_position.y);
|
||||
bar_draw_alias(bar, bar_item, icon_position.x);
|
||||
bar_draw_line(bar, label, label_position.x, label_position.y);
|
||||
bar_draw_graph(bar, bar_item, graph_x, graph_rtl);
|
||||
}
|
||||
|
@ -243,8 +261,8 @@ void bar_create_frame(struct bar *bar, CFTypeRef *frame_region) {
|
|||
if (0 == strcmp(g_bar_manager.position, BAR_POSITION_BOTTOM)) {
|
||||
origin.y = CGRectGetMaxY(bounds) - g_bar_manager.height - 2*g_bar_manager.y_offset;
|
||||
} else if (display_menu_bar_visible()) {
|
||||
CGRect menu = display_menu_bar_rect(bar->did);
|
||||
origin.y += menu.size.height;
|
||||
//CGRect menu = display_menu_bar_rect(bar->did);
|
||||
//origin.y += menu.size.height;
|
||||
}
|
||||
|
||||
bar->frame = (CGRect) {{0, 0},{bounds.size.width, g_bar_manager.height}};
|
||||
|
|
|
@ -75,6 +75,7 @@ void bar_item_init(struct bar_item* bar_item, struct bar_item* default_item) {
|
|||
bar_item->background_corner_radius = 0;
|
||||
bar_item->background_border_width = 0;
|
||||
bar_item->bounding_rects = NULL;
|
||||
bar_item->has_alias = false;
|
||||
|
||||
if (default_item) bar_item_inherit_from_item(bar_item, default_item);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#define BAR_ITEM 'i'
|
||||
#define BAR_COMPONENT_GRAPH 'g'
|
||||
#define BAR_COMPONENT_SPACE 's'
|
||||
#define BAR_COMPONENT_ALIAS 'a'
|
||||
#define BAR_PLUGIN 'p'
|
||||
|
||||
#define BAR_POSITION_LEFT 'l'
|
||||
|
@ -78,6 +79,10 @@ struct bar_item {
|
|||
bool has_graph;
|
||||
struct graph_data graph_data;
|
||||
|
||||
// Alias Data
|
||||
bool has_alias;
|
||||
struct alias alias;
|
||||
|
||||
// Update Events
|
||||
uint32_t update_mask;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "display.h"
|
||||
#include "bar.h"
|
||||
#include "graph_data.h"
|
||||
#include "alias.h"
|
||||
#include "bar_item.h"
|
||||
#include "custom_events.h"
|
||||
#include "bar_manager.h"
|
||||
|
@ -38,6 +39,7 @@
|
|||
#include "display.c"
|
||||
#include "bar.c"
|
||||
#include "graph_data.c"
|
||||
#include "alias.c"
|
||||
#include "bar_item.c"
|
||||
#include "custom_events.c"
|
||||
#include "bar_manager.c"
|
||||
|
|
|
@ -314,6 +314,10 @@ static void handle_domain_add(FILE* rsp, struct token domain, char* message) {
|
|||
bar_item_set_script(bar_item, string_copy("if [ \"$SELECTED\" = \"true\" ]; then sketchybar -m set $NAME icon_highlight on; else sketchybar -m set $NAME icon_highlight off; fi"));
|
||||
bar_item->update_mask |= UPDATE_SPACE_CHANGE;
|
||||
}
|
||||
else if (bar_item->type == BAR_COMPONENT_ALIAS) {
|
||||
alias_init(&bar_item->alias, token_to_string(name));
|
||||
bar_item->has_alias = true;
|
||||
}
|
||||
} else if (token_equals(command, COMMAND_ADD_PLUGIN)) {
|
||||
struct token identifier = get_token(&message);
|
||||
name = get_token(&message);
|
||||
|
|
Loading…
Reference in a new issue