From de13dbca8d62a8a453d15455c7f3adeb527a8e09 Mon Sep 17 00:00:00 2001 From: Felix Kratz Date: Sat, 24 Dec 2022 18:04:52 +0100 Subject: [PATCH] animation fade --- src/misc/extern.h | 1 + src/osax/payload.m | 36 +++++++++++++++++++++++++++++++++++- src/sa.h | 1 + src/sa.m | 22 ++++++++++++++++++++++ src/window_manager.c | 31 +++++++++++++++++++++++++++++-- 5 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/misc/extern.h b/src/misc/extern.h index 3206d466..5371a053 100644 --- a/src/misc/extern.h +++ b/src/misc/extern.h @@ -75,6 +75,7 @@ extern CFTypeRef SLSTransactionCreate(int cid); extern CGError SLSTransactionCommit(CFTypeRef transaction, int unknown); extern CGError SLSTransactionSetWindowTransform(CFTypeRef transaction, uint32_t wid, int unknown, int unknown2, CGAffineTransform t); extern CGError SLSTransactionOrderWindow(CFTypeRef transaction, uint32_t wid, int order, uint32_t rel_wid); +extern CGError SLSTransactionSetWindowAlpha(CFTypeRef transaction, uint32_t wid, float alpha); extern CFArrayRef SLSHWCaptureWindowList(int cid, uint32_t *window_list, int window_count, uint32_t options); #if 0 diff --git a/src/osax/payload.m b/src/osax/payload.m index ccbcbbe5..0e74cc93 100644 --- a/src/osax/payload.m +++ b/src/osax/payload.m @@ -74,6 +74,7 @@ extern CGError SLSTransactionOrderWindow(CFTypeRef transaction, uint32_t wid, int order, uint32_t rel_wid); extern CGError SLSTransactionSetWindowAlpha(CFTypeRef transaction, uint32_t wid, float alpha); extern CGError SLSTransactionSetWindowSystemAlpha(CFTypeRef transaction, uint32_t wid, float alpha); +extern CGError SLSTransactionSetWindowTransform(CFTypeRef transaction, uint32_t wid, int unknown, int unknown2, CGAffineTransform t); struct window_fade_context { @@ -573,6 +574,37 @@ static void do_space_focus(char *message) } } +static void do_window_transform(char *message) +{ + uint32_t count = 0; + unpack(message, count); + if (!count) return; + + float alpha = 1.f; + unpack(message, alpha); + + CFTypeRef transaction = SLSTransactionCreate(_connection); + for (int i = 0; i < count; i++) { + uint32_t wid = 0; + unpack(message, wid); + float x, y, s_w, s_h; + unpack(message, x); + unpack(message, y); + unpack(message, s_w); + unpack(message, s_h); + + if (!wid) continue; + + CGAffineTransform transform = CGAffineTransformMakeTranslation(-x, -y); + CGAffineTransform scale = CGAffineTransformMakeScale(s_w, s_h); + + SLSTransactionSetWindowTransform(transaction, wid, 0, 0, CGAffineTransformConcat(transform, scale)); + SLSTransactionSetWindowSystemAlpha(transaction, wid, alpha); + } + SLSTransactionCommit(transaction, 0); + CFRelease(transaction); +} + static void do_window_scale(char *message) { uint32_t wid; @@ -1038,7 +1070,9 @@ static void handle_message(struct mach_buffer* buffer) case 0x0F: { do_window_order(message); } break; - + case 0x10: { + do_window_transform(message); + } break; } mach_send_message(buffer->message.header.msgh_remote_port, "k", 2); free(buffer); diff --git a/src/sa.h b/src/sa.h index 49abaa59..d6dc3b5c 100644 --- a/src/sa.h +++ b/src/sa.h @@ -25,5 +25,6 @@ bool scripting_addition_focus_window(uint32_t wid); bool scripting_addition_scale_window(uint32_t wid, float x, float y, float w, float h); bool scripting_addition_swap_window_proxy(uint32_t a_wid, uint32_t b_wid, float opacity, int order); bool scripting_addition_order_window(uint32_t a_wid, int order, uint32_t b_wid); +bool scripting_addition_transform_window_list(float alpha, uint32_t* wid, float* x, float* y, float* s_w, float* s_h, uint32_t count); #endif diff --git a/src/sa.m b/src/sa.m index 98f44748..4bcdff1f 100644 --- a/src/sa.m +++ b/src/sa.m @@ -533,6 +533,28 @@ bool scripting_addition_scale_window(uint32_t wid, float x, float y, float w, fl return scripting_addition_send_bytes(bytes, length); } +bool scripting_addition_transform_window_list(float alpha, uint32_t* wid, float* x, float* y, float* s_w, float* s_h, uint32_t count) +{ + char bytes[count * 4 * 5 + 0x100]; + char length = 2; + + pack(bytes, count, length); + pack(bytes, alpha, length); + + for (int i = 0; i < count; i++) { + pack(bytes, *(wid + i), length); + pack(bytes, *(x + i), length); + pack(bytes, *(y + i), length); + pack(bytes, *(s_w + i), length); + pack(bytes, *(s_h + i), length); + } + + bytes[1] = 0x10; + bytes[0] = length-1; + + return scripting_addition_send_bytes(bytes, sizeof(bytes)); +} + bool scripting_addition_swap_window_proxy(uint32_t a_wid, uint32_t b_wid, float opacity, int order) { char bytes[0x100]; diff --git a/src/window_manager.c b/src/window_manager.c index 48888951..ee6ee798 100644 --- a/src/window_manager.c +++ b/src/window_manager.c @@ -575,6 +575,33 @@ void *window_manager_animate_window_list_thread_proc(void *data) CGAffineTransform scale = CGAffineTransformMakeScale(context->animation_list[i].proxy.frame.size.width / context->animation_list[i].proxy.tw, context->animation_list[i].proxy.frame.size.height / context->animation_list[i].proxy.th); SLSTransactionSetWindowTransform(transaction, context->animation_list[i].proxy.id, 0, 0, CGAffineTransformConcat(transform, scale)); } + + float onset = 0.2; + float fin = 0.8; + if (mt > onset) { + float alpha = min((mt - onset) / (fin - onset), 1.f); + float proxy_alpha = mt > fin ? (1.f - (mt - fin)/(1.f - fin)) : 1.f; + uint32_t wids[animation_count]; + float txs[animation_count]; + float tys[animation_count]; + float s_ws[animation_count]; + float s_hs[animation_count]; + + for (int i = 0; i < animation_count; ++i) { + if (context->animation_list[i].skip) { + wids[i] = 0; + continue; + } + wids[i] = context->animation_list[i].wid; + txs[i] = context->animation_list[i].proxy.tx; + tys[i] = context->animation_list[i].proxy.ty; + s_ws[i] = context->animation_list[i].w / context->animation_list[i].proxy.tw; + s_hs[i] = context->animation_list[i].h / context->animation_list[i].proxy.th; + SLSTransactionSetWindowAlpha(transaction, context->animation_list[i].proxy.id, proxy_alpha); + } + + scripting_addition_transform_window_list(alpha, wids, txs, tys, s_ws, s_hs, animation_count); + } }); pthread_mutex_lock(&g_window_manager.window_animations_lock); @@ -648,8 +675,8 @@ void window_manager_animate_window_list_async(struct window_capture *window_list window_manager_create_window_proxy(context->animation_connection, &context->animation_list[i].proxy); + scripting_addition_swap_window_proxy(context->animation_list[i].wid, context->animation_list[i].proxy.id, 0.0f, -1); CFTypeRef transaction = SLSTransactionCreate(context->animation_connection); - SLSTransactionOrderWindow(transaction, context->animation_list[i].proxy.id, 1, context->animation_list[i].wid); SLSTransactionOrderWindow(transaction, existing_animation->proxy.id, 0, 0); SLSTransactionCommit(transaction, 1); CFRelease(transaction); @@ -660,7 +687,7 @@ void window_manager_animate_window_list_async(struct window_capture *window_list SLSGetWindowBounds(context->animation_connection, context->animation_list[i].wid, &context->animation_list[i].proxy.frame); context->animation_list[i].proxy.image = SLSHWCaptureWindowList(context->animation_connection, &context->animation_list[i].wid, 1, (1 << 11) | (1 << 8)); window_manager_create_window_proxy(context->animation_connection, &context->animation_list[i].proxy); - scripting_addition_swap_window_proxy(context->animation_list[i].wid, context->animation_list[i].proxy.id, 0.0f, 1); + scripting_addition_swap_window_proxy(context->animation_list[i].wid, context->animation_list[i].proxy.id, 0.0f, -1); } table_add(&g_window_manager.window_animations_table, &context->animation_list[i].wid, &context->animation_list[i]);