Skip to content

Commit

Permalink
only access global settings from main thread and make border settings…
Browse files Browse the repository at this point in the history
… overridable on a per border basis (preparation for #57)
  • Loading branch information
FelixKratz committed Mar 5, 2024
1 parent 2c7f048 commit 49a7b67
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 39 deletions.
90 changes: 57 additions & 33 deletions src/border.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ void border_init(struct border* border) {
pthread_mutex_init(&border->mutex, &mattr);
}

struct settings* border_get_settings(struct border* border) {
assert(pthread_main_np() != 0);
return border->setting_override.enabled
? &border->setting_override
: &g_settings;
}

static void border_destroy_window(struct border* border, int cid) {
if (border->wid) SLSReleaseWindow(cid, border->wid);
if (border->context) CGContextRelease(border->context);
Expand Down Expand Up @@ -55,7 +62,7 @@ static bool border_coalesce_resize_and_move_events(struct border* border, int ci
return true;
}

static bool border_calculate_bounds(struct border* border, int cid, CGRect* frame) {
static bool border_calculate_bounds(struct border* border, int cid, CGRect* frame, struct settings* settings) {
CGRect window_frame;
if (border->is_proxy) window_frame = border->target_bounds;
else if (!border_coalesce_resize_and_move_events(border,
Expand All @@ -71,7 +78,7 @@ static bool border_calculate_bounds(struct border* border, int cid, CGRect* fram
return false;
}

float border_offset = - g_settings.border_width - BORDER_PADDING;
float border_offset = - settings->border_width - BORDER_PADDING;
*frame = CGRectInset(window_frame, border_offset, border_offset);

border->origin = frame->origin;
Expand All @@ -84,12 +91,12 @@ static bool border_calculate_bounds(struct border* border, int cid, CGRect* fram
return true;
}

static void border_draw(struct border* border, CGRect frame) {
static void border_draw(struct border* border, CGRect frame, struct settings* settings) {
CGContextSaveGState(border->context);
border->needs_redraw = false;
struct color_style color_style = border->focused
? g_settings.active_window
: g_settings.inactive_window;
? settings->active_window
: settings->inactive_window;

CGGradientRef gradient = NULL;
CGPoint gradient_direction[2];
Expand Down Expand Up @@ -129,17 +136,17 @@ static void border_draw(struct border* border, CGRect frame) {
}
}

CGContextSetLineWidth(border->context, g_settings.border_width);
CGContextSetLineWidth(border->context, settings->border_width);
CGContextClearRect(border->context, frame);

CGRect path_rect = border->drawing_bounds;
CGMutablePathRef clip_path = CGPathCreateMutable();
CGMutablePathRef inner_clip_path = CGPathCreateMutable();
CGPathAddRect(clip_path, NULL, frame);

if (g_settings.border_style == BORDER_STYLE_SQUARE
&& g_settings.border_order == BORDER_ORDER_ABOVE
&& g_settings.border_width >= BORDER_TSMW) {
if (settings->border_style == BORDER_STYLE_SQUARE
&& settings->border_order == BORDER_ORDER_ABOVE
&& settings->border_width >= BORDER_TSMW) {
// Inset the frame to overlap the rounding of macOS windows to create a
// truly square border
path_rect = CGRectInset(border->drawing_bounds,
Expand All @@ -159,10 +166,10 @@ static void border_draw(struct border* border, CGRect frame) {
CGContextAddPath(border->context, clip_path);
CGContextEOClip(border->context);

if (g_settings.border_style == BORDER_STYLE_SQUARE) {
if (settings->border_style == BORDER_STYLE_SQUARE) {
CGRect square_rect = CGRectInset(path_rect,
-g_settings.border_width / 2.f,
-g_settings.border_width / 2.f );
-settings->border_width / 2.f,
-settings->border_width / 2.f );

CGPathRef square_path = CGPathCreateWithRect(square_rect, NULL);
CGContextAddPath(border->context, square_path);
Expand Down Expand Up @@ -205,10 +212,10 @@ static void border_draw(struct border* border, CGRect frame) {
}
CGGradientRelease(gradient);

if (g_settings.show_background && g_settings.border_order != 1) {
if (settings->show_background && settings->border_order != 1) {
CGContextRestoreGState(border->context);
CGContextSaveGState(border->context);
color_style = g_settings.background;
color_style = settings->background;
if (color_style.stype == COLOR_STYLE_SOLID
|| color_style.stype == COLOR_STYLE_GLOW) {
float a,r,g,b;
Expand All @@ -226,11 +233,11 @@ static void border_draw(struct border* border, CGRect frame) {
CGContextRestoreGState(border->context);
}

static void border_update_internal(struct border* border, int cid) {
void border_update_internal(struct border* border, int cid, struct settings* settings) {
if (border->external_proxy_wid) return;

CGRect frame;
if (!border_calculate_bounds(border, cid, &frame)) return;
if (!border_calculate_bounds(border, cid, &frame, settings)) return;

uint64_t tags = window_tags(cid, border->target_wid);
border->sticky = tags & WINDOW_TAG_STICKY;
Expand All @@ -247,7 +254,13 @@ static void border_update_internal(struct border* border, int cid) {
int level = window_level(cid, border->target_wid);
int sub_level = window_sub_level(border->target_wid);

if (!border->wid) border_create_window(border, cid, frame, border->is_proxy);
if (!border->wid) {
border_create_window(border,
cid,
frame,
border->is_proxy,
settings->hidpi );
}

CFTypeRef transaction = SLSTransactionCreate(cid);
if (!CGRectEqualToRect(frame, border->frame)) {
Expand All @@ -272,7 +285,7 @@ static void border_update_internal(struct border* border, int cid) {
SLSTransactionCommit(transaction, 1);
CFRelease(transaction);

border_draw(border, frame);
border_draw(border, frame, settings);
transaction = SLSTransactionCreate(cid);
}
CGAffineTransform transform = CGAffineTransformIdentity;
Expand All @@ -283,7 +296,7 @@ static void border_update_internal(struct border* border, int cid) {
SLSTransactionSetWindowSubLevel(transaction, border->wid, sub_level);
SLSTransactionOrderWindow(transaction,
border->wid,
g_settings.border_order,
settings->border_order,
border->target_wid );
SLSTransactionCommit(transaction, 1);
CFRelease(transaction);
Expand All @@ -297,26 +310,28 @@ static void border_update_internal(struct border* border, int cid) {

SLSSetWindowTags(cid, border->wid, &set_tags, 0x40);
SLSClearWindowTags(cid, border->wid, &clear_tags, 0x40);
SLSSetWindowBackgroundBlurRadius(cid, border->wid, g_settings.blur_radius);
SLSSetWindowBackgroundBlurRadius(cid, border->wid, settings->blur_radius);

if (disabled_update) SLSReenableUpdate(cid);
}

static void* border_update_async_proc(void* context) {
struct { struct border* border; int cid; }* payload = context;
struct {
struct border* border;
struct settings settings;
int cid;
}* payload = context;

pthread_mutex_lock(&payload->border->mutex);
border_update_internal(payload->border, payload->cid);
border_update_internal(payload->border, payload->cid, &payload->settings);
pthread_mutex_unlock(&payload->border->mutex);
free(payload);
return NULL;
}

void border_create_window(struct border* border, int cid, CGRect frame, bool unmanaged) {
void border_create_window(struct border* border, int cid, CGRect frame, bool unmanaged, bool hidpi) {
pthread_mutex_lock(&border->mutex);
border->wid = window_create(cid,
frame,
g_settings.hidpi,
unmanaged );
border->wid = window_create(cid, frame, hidpi, unmanaged);

border->frame = frame;
border->needs_redraw = true;
Expand Down Expand Up @@ -345,11 +360,12 @@ void border_move(struct border* border, int cid) {
CGRect window_frame;
SLSGetWindowBounds(cid, border->target_wid, &window_frame);

struct settings* settings = border_get_settings(border);
CGPoint origin = { .x = window_frame.origin.x
- g_settings.border_width
- settings->border_width
- BORDER_PADDING,
.y = window_frame.origin.y
- g_settings.border_width
- settings->border_width
- BORDER_PADDING };

CFTypeRef transaction = SLSTransactionCreate(cid);
Expand All @@ -363,16 +379,23 @@ void border_move(struct border* border, int cid) {

void border_update(struct border* border, int cid, bool try_async) {
pthread_mutex_lock(&border->mutex);
struct settings* settings = border_get_settings(border);
if (!border->wid || !try_async) {
border_update_internal(border, cid);
border_update_internal(border, cid, settings);
pthread_mutex_unlock(&border->mutex);
return;
}

struct payload { struct border* border; int cid; }* payload
= malloc(sizeof(struct payload));
struct payload {
struct border* border;
struct settings settings;
int cid;
}* payload = malloc(sizeof(struct payload));

payload->border = border;
payload->cid = cid;
payload->settings = *settings;

pthread_t thread;
pthread_create(&thread, NULL, border_update_async_proc, payload);
pthread_detach(thread);
Expand Down Expand Up @@ -400,10 +423,11 @@ void border_unhide(struct border* border, int cid) {
}

if (border->wid) {
struct settings* settings = border_get_settings(border);
CFTypeRef transaction = SLSTransactionCreate(cid);
SLSTransactionOrderWindow(transaction,
border->wid,
g_settings.border_order,
settings->border_order,
border->target_wid );
SLSTransactionCommit(transaction, 0);
CFRelease(transaction);
Expand Down
8 changes: 7 additions & 1 deletion src/border.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct color_style {
};

struct settings {
bool enabled;

struct color_style active_window;
struct color_style inactive_window;
struct color_style background;
Expand Down Expand Up @@ -72,13 +74,17 @@ struct border {
bool is_proxy;
struct border* proxy;
uint32_t external_proxy_wid;

struct settings setting_override;
};

void border_init(struct border* border);
void border_destroy(struct border* border, int cid);
void border_create_window(struct border* border, int cid, CGRect frame, bool unmanaged);
void border_create_window(struct border* border, int cid, CGRect frame, bool unmanaged, bool hidpi);

void border_move(struct border* border, int cid);
void border_update(struct border* border, int cid, bool try_async);
void border_hide(struct border* border, int cid);
void border_unhide(struct border* border, int cid);

struct settings* border_get_settings(struct border* border);
3 changes: 2 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ pid_t g_pid;
mach_port_t g_server_port;
struct table g_windows;
struct mach_server g_mach_server;
struct settings g_settings = { .active_window = { .stype = COLOR_STYLE_SOLID,
struct settings g_settings = { .enabled = true,
.active_window = { .stype = COLOR_STYLE_SOLID,
.color = 0xffe1e3e4 },
.inactive_window = { .stype = COLOR_STYLE_SOLID,
.color = 0x00000000 },
Expand Down
11 changes: 8 additions & 3 deletions src/misc/yabai.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#define _YABAI_INTEGRATION

void border_update_internal(struct border* border, int cid, struct settings* settings);

struct track_transform_payload {
int cid;
uint32_t border_wid;
Expand All @@ -18,6 +20,7 @@ struct track_transform_payload {

struct yabai_proxy_payload {
union { struct border* proxy; struct border* border; };
struct settings settings;
uint32_t border_wid;
uint32_t real_wid;
uint32_t external_proxy_wid;
Expand Down Expand Up @@ -66,7 +69,7 @@ static void* yabai_proxy_begin_proc(void* context) {

if (!proxy->is_proxy) {
proxy->is_proxy = true;
border_update(proxy, cid, false);
border_update_internal(proxy, cid, &info->settings);

CFTypeRef transaction = SLSTransactionCreate(cid);
SLSTransactionSetWindowAlpha(transaction, info->border_wid, 0.f);
Expand Down Expand Up @@ -108,7 +111,7 @@ static void* yabai_proxy_end_proc(void* context) {
pthread_mutex_lock(&border->mutex);
border->disable_coalescing = true;
border->external_proxy_wid = 0;
border_update(border, cid, false);
border_update_internal(border, cid, &info->settings);
border->disable_coalescing = false;
pthread_mutex_unlock(&border->mutex);
free(context);
Expand All @@ -125,7 +128,7 @@ static inline void yabai_proxy_begin(struct table* windows, int cid, uint32_t wi
if (!border->proxy) {
border->proxy = malloc(sizeof(struct border));
border_init(border->proxy);
border_create_window(border->proxy, cid, CGRectNull, true);
border_create_window(border->proxy, cid, CGRectNull, true, false);
border->proxy->target_bounds = border->target_bounds;
border->proxy->focused = border->focused;
border->proxy->target_wid = border->target_wid;
Expand All @@ -139,6 +142,7 @@ static inline void yabai_proxy_begin(struct table* windows, int cid, uint32_t wi
payload->external_proxy_wid = border->external_proxy_wid;
payload->real_wid = real_wid;
payload->cid = cid;
payload->settings = *border_get_settings(border);

pthread_t thread;
pthread_create(&thread, NULL, yabai_proxy_begin_proc, payload);
Expand Down Expand Up @@ -176,6 +180,7 @@ static inline void yabai_proxy_end(struct table* windows, int cid, uint32_t wid,
payload->border = border;
payload->border_wid = border->wid;
payload->cid = cid;
payload->settings = *border_get_settings(border);

pthread_t thread;
pthread_create(&thread, NULL, yabai_proxy_end_proc, payload);
Expand Down
4 changes: 3 additions & 1 deletion src/windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ void windows_window_hide(struct table* windows, uint32_t wid) {

void windows_window_unhide(struct table* windows, uint32_t wid) {
struct border* border = table_find(windows, &wid);
if (border) border_unhide(border, SLSMainConnectionID());
if (border) {
border_unhide(border, SLSMainConnectionID());
}
}

bool windows_window_destroy(struct table* windows, uint32_t wid, uint32_t sid) {
Expand Down

0 comments on commit 49a7b67

Please sign in to comment.