From b727eee8b0e12a49e0ff21d1a8cbb82091208952 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Thu, 22 Sep 2022 15:43:36 +0200 Subject: [PATCH] #148 fix stuff --- src/osax/common.h | 2 +- src/osax/payload.m | 38 +++++++++++++++++++++++++++++--------- src/sa.h | 1 + src/sa.m | 4 +++- src/view.h | 2 ++ src/window_manager.c | 34 ++++++++++++++++++++++++++-------- 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/osax/common.h b/src/osax/common.h index 70968254..d51c0230 100644 --- a/src/osax/common.h +++ b/src/osax/common.h @@ -1,7 +1,7 @@ #ifndef SA_COMMON_H #define SA_COMMON_H -#define OSAX_VERSION "2.0.10" +#define OSAX_VERSION "2.0.11" #define OSAX_ATTRIB_DOCK_SPACES 0x01 #define OSAX_ATTRIB_DPPM 0x02 diff --git a/src/osax/payload.m b/src/osax/payload.m index 4133eb0f..b2ef308e 100644 --- a/src/osax/payload.m +++ b/src/osax/payload.m @@ -1,4 +1,5 @@ #include + #include #include #include @@ -70,6 +71,7 @@ extern CFTypeRef SLSTransactionCreate(int cid); extern CGError SLSTransactionCommit(CFTypeRef transaction, int unknown); extern CGError SLSTransactionOrderWindow(CFTypeRef transaction, uint32_t wid, int order, uint32_t rel_wid); +extern CGError SLSTransactionSetWindowAlpha(CFTypeRef transaction, uint32_t wid, float alpha); struct window_fade_context { @@ -78,6 +80,7 @@ volatile float alpha; volatile float duration; volatile bool skip; + volatile bool abort; }; pthread_mutex_t window_fade_lock; @@ -633,7 +636,8 @@ static void do_window_opacity(char *message) { entry:; struct window_fade_context *context = (struct window_fade_context *) data; - context->skip = false; + context->abort = false; + context->skip = false; float start_alpha; float end_alpha = context->alpha; @@ -644,7 +648,8 @@ static void do_window_opacity(char *message) int frame_count = (int)(((float) total_duration / (float) frame_duration) + 1.0f); for (int frame_index = 1; frame_index <= frame_count; ++frame_index) { - if (context->skip) goto entry; + if (context->abort) goto abort; + if (context->skip) goto entry; float t = (float) frame_index / (float) frame_count; if (t < 0.0f) t = 0.0f; @@ -656,15 +661,14 @@ static void do_window_opacity(char *message) usleep(frame_duration*1000); } +abort: pthread_mutex_lock(&window_fade_lock); - - if (!context->skip) { + if (context->abort || !context->skip) { table_remove(&window_fade_table, &context->wid); pthread_mutex_unlock(&window_fade_lock); free(context); return NULL; } - pthread_mutex_unlock(&window_fade_lock); goto entry; @@ -695,6 +699,7 @@ static void do_window_opacity_fade(char *message) context->wid = wid; context->alpha = alpha; context->duration = duration; + context->abort = false; context->skip = false; __asm__ __volatile__ ("" ::: "memory"); @@ -768,7 +773,7 @@ static void do_window_shadow(char *message) } } -static void do_window_order_swap(char *message) +static void do_window_swap_proxy(char *message) { uint32_t a_wid; unpack(message, a_wid); @@ -778,9 +783,24 @@ static void do_window_order_swap(char *message) unpack(message, b_wid); if (!b_wid) return; + float alpha; + unpack(message, alpha); + + int order; + unpack(message, order); + + pthread_mutex_lock(&window_fade_lock); + struct window_fade_context *context = table_find(&window_fade_table, &a_wid); + if (context) { + context->abort = true; + __asm__ __volatile__ ("" ::: "memory"); + usleep(8 * 1000); + } + pthread_mutex_unlock(&window_fade_lock); + CFTypeRef transaction = SLSTransactionCreate(_connection); - SLSTransactionOrderWindow(transaction, a_wid, -1, b_wid); - SLSTransactionOrderWindow(transaction, b_wid, 0, 0); + SLSTransactionOrderWindow(transaction, b_wid, order, a_wid); + SLSTransactionSetWindowAlpha(transaction, a_wid, alpha); SLSTransactionCommit(transaction, 0); CFRelease(transaction); } @@ -853,7 +873,7 @@ static void handle_message(int sockfd, char *message) do_window_opacity(message); } break; case 0x0E: { - do_window_order_swap(message); + do_window_swap_proxy(message); } break; } diff --git a/src/sa.h b/src/sa.h index 204efe39..dcc12577 100644 --- a/src/sa.h +++ b/src/sa.h @@ -24,5 +24,6 @@ bool scripting_addition_set_shadow(uint32_t wid, bool shadow); 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_order(uint32_t a_wid, uint32_t b_wid); +bool scripting_addition_swap_window_proxy(uint32_t a_wid, uint32_t b_wid, float opacity, int order); #endif diff --git a/src/sa.m b/src/sa.m index 5e0cec2d..d088b0bc 100644 --- a/src/sa.m +++ b/src/sa.m @@ -525,13 +525,15 @@ 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_swap_window_order(uint32_t a_wid, uint32_t b_wid) +bool scripting_addition_swap_window_proxy(uint32_t a_wid, uint32_t b_wid, float opacity, int order) { char bytes[0x100]; char length = 2; pack(bytes, a_wid, length); pack(bytes, b_wid, length); + pack(bytes, opacity, length); + pack(bytes, order, length); bytes[1] = 0x0E; bytes[0] = length-1; diff --git a/src/view.h b/src/view.h index 2ee804d5..08f56aa2 100644 --- a/src/view.h +++ b/src/view.h @@ -22,7 +22,9 @@ struct window_proxy uint32_t id; CGContextRef context; float tx, ty, tw, th; + float alpha; CGRect frame; + CFArrayRef image; }; struct window_animation diff --git a/src/window_manager.c b/src/window_manager.c index acd335c4..ed3e6b8b 100644 --- a/src/window_manager.c +++ b/src/window_manager.c @@ -513,8 +513,7 @@ void window_manager_resize_window(struct window *window, float width, float heig static void window_manager_create_window_proxy(int animation_connection, uint32_t wid, struct window_proxy *proxy) { - CFArrayRef image = SLSHWCaptureWindowList(animation_connection, &wid, 1, (1 << 11) | (1 << 8)); - if (!image) return; + if (!proxy->image) return; CFTypeRef frame_region; CGSNewRegionWithRect(&proxy->frame, &frame_region); @@ -535,15 +534,19 @@ static void window_manager_create_window_proxy(int animation_connection, uint32_ CGRect frame = { {0, 0}, proxy->frame.size }; CGContextClearRect(proxy->context, frame); - CGContextDrawImage(proxy->context, frame, (CGImageRef) CFArrayGetValueAtIndex(image, 0)); + CGContextDrawImage(proxy->context, frame, (CGImageRef) CFArrayGetValueAtIndex(proxy->image, 0)); CGContextFlush(proxy->context); CFRelease(frame_region); - CFRelease(image); } static void window_manager_destroy_window_proxy(int animation_connection, struct window_proxy *proxy) { + if (proxy->image) { + CFRelease(proxy->image); + proxy->image = NULL; + } + if (proxy->context) { CGContextRelease(proxy->context); proxy->context = NULL; @@ -581,7 +584,7 @@ void *window_manager_animate_window_list_thread_proc(void *data) if (context->animation_list[i].skip) continue; table_remove(&g_window_manager.window_animations_table, &context->animation_list[i].wid); - scripting_addition_swap_window_order(context->animation_list[i].wid, context->animation_list[i].proxy.id); + scripting_addition_swap_window_proxy(context->animation_list[i].wid, context->animation_list[i].proxy.id, context->animation_list[i].proxy.alpha, 0); window_manager_destroy_window_proxy(context->animation_connection, &context->animation_list[i].proxy); } SLSReenableUpdate(context->animation_connection); @@ -640,12 +643,14 @@ void window_manager_animate_window_list_async(struct window_capture *window_list context->animation_list[i].proxy.frame.origin.y = (int)(existing_animation->proxy.ty); context->animation_list[i].proxy.frame.size.width = (int)(existing_animation->proxy.tw); context->animation_list[i].proxy.frame.size.height = (int)(existing_animation->proxy.th); + context->animation_list[i].proxy.alpha = existing_animation->proxy.alpha; + context->animation_list[i].proxy.image = CFRetain(existing_animation->proxy.image); __asm__ __volatile__ ("" ::: "memory"); window_manager_create_window_proxy(context->animation_connection, context->animation_list[i].wid, &context->animation_list[i].proxy); CFTypeRef transaction = SLSTransactionCreate(context->animation_connection); - SLSTransactionOrderWindow(transaction, context->animation_list[i].proxy.id, -1, existing_animation->proxy.id); + SLSTransactionOrderWindow(transaction, context->animation_list[i].proxy.id, 1, context->animation_list[i].wid); SLSTransactionOrderWindow(transaction, existing_animation->proxy.id, 0, 0); SLSTransactionCommit(transaction, 0); CFRelease(transaction); @@ -653,8 +658,10 @@ void window_manager_animate_window_list_async(struct window_capture *window_list window_manager_destroy_window_proxy(context->animation_connection, &existing_animation->proxy); } else { SLSGetWindowBounds(context->animation_connection, context->animation_list[i].wid, &context->animation_list[i].proxy.frame); + SLSGetWindowAlpha(context->animation_connection, context->animation_list[i].wid, &context->animation_list[i].proxy.alpha); + 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].wid, &context->animation_list[i].proxy); - scripting_addition_swap_window_order(context->animation_list[i].proxy.id, context->animation_list[i].wid); + 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]); @@ -740,7 +747,18 @@ bool window_manager_set_opacity(struct window_manager *wm, struct window *window } } - return scripting_addition_set_opacity(window->id, opacity, wm->window_opacity_duration); + bool result = true; + pthread_mutex_lock(&g_window_manager.window_animations_lock); + struct window_animation *existing_animation = table_find(&g_window_manager.window_animations_table, &window->id); + if (existing_animation) { + existing_animation->proxy.alpha = opacity; + __asm__ __volatile__ ("" ::: "memory"); + } else { + result = scripting_addition_set_opacity(window->id, opacity, wm->window_opacity_duration); + } + pthread_mutex_unlock(&g_window_manager.window_animations_lock); + + return result; } void window_manager_set_window_opacity(struct window_manager *wm, struct window *window, float opacity)