From 3fe4c77b001e1a4f613c26f01ea68c0f09327f3a Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Mon, 7 Dec 2020 00:43:09 +0100 Subject: [PATCH] #109 try to workaround weird resizing issues that occur for some applications --- src/application.c | 2 -- src/application.h | 3 --- src/event.c | 11 +--------- src/misc/helpers.h | 32 ++++++++++++++++++++++++++++ src/window_manager.c | 50 ++++++++++++++++++++++++++++---------------- src/window_manager.h | 1 + 6 files changed, 66 insertions(+), 33 deletions(-) diff --git a/src/application.c b/src/application.c index 57f6e99e..09958ab0 100644 --- a/src/application.c +++ b/src/application.c @@ -135,8 +135,6 @@ struct application *application_create(struct process *process) struct application *application = malloc(sizeof(struct application)); memset(application, 0, sizeof(struct application)); application->ref = AXUIElementCreateApplication(process->pid); - AXUIElementSetAttributeValue(application->ref, kAXEnhancedUserInterface, kCFBooleanFalse); - AXUIElementSetAttributeValue(application->ref, kAXManualAccessibility, kCFBooleanTrue); application->psn = process->psn; application->pid = process->pid; application->name = process->name; diff --git a/src/application.h b/src/application.h index 2ead09af..01d258bf 100644 --- a/src/application.h +++ b/src/application.h @@ -1,9 +1,6 @@ #ifndef APPLICATION_H #define APPLICATION_H -const CFStringRef kAXEnhancedUserInterface = CFSTR("AXEnhancedUserInterface"); -const CFStringRef kAXManualAccessibility = CFSTR("AXManualAccessibility"); - #define OBSERVER_CALLBACK(name) void name(AXObserverRef observer, AXUIElementRef element, CFStringRef notification, void *context) typedef OBSERVER_CALLBACK(observer_callback); diff --git a/src/event.c b/src/event.c index d8974048..72d23062 100644 --- a/src/event.c +++ b/src/event.c @@ -747,16 +747,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_MOUSE_DRAGGED) if (point.x > frame_mid.x) direction |= HANDLE_RIGHT; if (point.y > frame_mid.y) direction |= HANDLE_BOTTOM; - int x_mod = (direction & HANDLE_LEFT) ? -1 : (direction & HANDLE_RIGHT) ? 1 : 0; - int y_mod = (direction & HANDLE_TOP) ? -1 : (direction & HANDLE_BOTTOM) ? 1 : 0; - - float fw = max(1, frame.size.width + dx * x_mod); - float fh = max(1, frame.size.height + dy * y_mod); - float fx = (direction & HANDLE_LEFT) ? frame.origin.x + frame.size.width - fw : frame.origin.x; - float fy = (direction & HANDLE_TOP) ? frame.origin.y + frame.size.height - fh : frame.origin.y; - - if (fx != 0.0f || fy != 0.0f) window_manager_move_window(g_mouse_state.window, fx, fy); - if (fw != 0.0f || fh != 0.0f) window_manager_resize_window(g_mouse_state.window, fw, fh); + _window_manager_resize_window_relative(g_mouse_state.window, frame, direction, dx, dy); g_mouse_state.last_moved_time = event_time; g_mouse_state.down_location = point; diff --git a/src/misc/helpers.h b/src/misc/helpers.h index 805ba11d..876bab66 100644 --- a/src/misc/helpers.h +++ b/src/misc/helpers.h @@ -1,6 +1,8 @@ #ifndef HELPERS_H #define HELPERS_H +const CFStringRef kAXEnhancedUserInterface = CFSTR("AXEnhancedUserInterface"); + static const char *bool_str[] = { "off", "on" }; static const char *layer_str[] = @@ -264,6 +266,36 @@ static inline pid_t ax_window_pid(AXUIElementRef ref) return *(pid_t *)((void *) ref + 0x10); } +static inline bool ax_enhanced_userinterface(AXUIElementRef ref) +{ + Boolean result = 0; + CFTypeRef value; + + if (AXUIElementCopyAttributeValue(ref, kAXEnhancedUserInterface, &value) == kAXErrorSuccess) { + result = CFBooleanGetValue(value); + CFRelease(value); + } + + return result; +} + +static inline void set_ax_enhanced_userinterface(AXUIElementRef ref, bool value) +{ + if (value) { + AXUIElementSetAttributeValue(ref, kAXEnhancedUserInterface, kCFBooleanTrue); + } else { + AXUIElementSetAttributeValue(ref, kAXEnhancedUserInterface, kCFBooleanFalse); + } +} + +#define AX_ENHANCED_UI_WORKAROUND(r, c) \ +{\ + bool eui = ax_enhanced_userinterface(r); \ + if (eui) set_ax_enhanced_userinterface(r, false); \ + c \ + if (eui) set_ax_enhanced_userinterface(r, true); \ +} + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" static inline bool psn_equals(ProcessSerialNumber *a, ProcessSerialNumber *b) diff --git a/src/window_manager.c b/src/window_manager.c index df14505e..3c9cf695 100644 --- a/src/window_manager.c +++ b/src/window_manager.c @@ -348,11 +348,29 @@ enum window_op_error window_manager_move_window_relative(struct window_manager * dy += frame.origin.y; } - window_manager_move_window(window, dx, dy); + AX_ENHANCED_UI_WORKAROUND(window->application->ref, { + window_manager_move_window(window, dx, dy); + }); return WINDOW_OP_ERROR_SUCCESS; } +void _window_manager_resize_window_relative(struct window *window, CGRect frame, int direction, float dx, float dy) +{ + int x_mod = (direction & HANDLE_LEFT) ? -1 : (direction & HANDLE_RIGHT) ? 1 : 0; + int y_mod = (direction & HANDLE_TOP) ? -1 : (direction & HANDLE_BOTTOM) ? 1 : 0; + + float fw = max(1, frame.size.width + dx * x_mod); + float fh = max(1, frame.size.height + dy * y_mod); + float fx = (direction & HANDLE_LEFT) ? frame.origin.x + frame.size.width - fw : frame.origin.x; + float fy = (direction & HANDLE_TOP) ? frame.origin.y + frame.size.height - fh : frame.origin.y; + + AX_ENHANCED_UI_WORKAROUND(window->application->ref, { + window_manager_move_window(window, fx, fy); + window_manager_resize_window(window, fw, fh); + }); +} + enum window_op_error window_manager_resize_window_relative(struct window_manager *wm, struct window *window, int direction, float dx, float dy) { struct view *view = window_manager_find_managed_window(wm, window); @@ -385,19 +403,11 @@ enum window_op_error window_manager_resize_window_relative(struct window_manager view_flush(view); } else { if (direction == HANDLE_ABS) { - window_manager_resize_window(window, dx, dy); + AX_ENHANCED_UI_WORKAROUND(window->application->ref, { + window_manager_resize_window(window, dx, dy); + }); } else { - int x_mod = (direction & HANDLE_LEFT) ? -1 : (direction & HANDLE_RIGHT) ? 1 : 0; - int y_mod = (direction & HANDLE_TOP) ? -1 : (direction & HANDLE_BOTTOM) ? 1 : 0; - - CGRect frame = window_frame(window); - float fw = max(1, frame.size.width + dx * x_mod); - float fh = max(1, frame.size.height + dy * y_mod); - float fx = (direction & HANDLE_LEFT) ? frame.origin.x + frame.size.width - fw : frame.origin.x; - float fy = (direction & HANDLE_TOP) ? frame.origin.y + frame.size.height - fh : frame.origin.y; - - window_manager_move_window(window, fx, fy); - window_manager_resize_window(window, fw, fh); + _window_manager_resize_window_relative(window, window_frame(window), direction, dx, dy); } } @@ -429,9 +439,11 @@ void window_manager_resize_window(struct window *window, float width, float heig void window_manager_set_window_frame(struct window *window, float x, float y, float width, float height) { - window_manager_resize_window(window, width, height); - window_manager_move_window(window, x, y); - window_manager_resize_window(window, width, height); + AX_ENHANCED_UI_WORKAROUND(window->application->ref, { + window_manager_resize_window(window, width, height); + window_manager_move_window(window, x, y); + window_manager_resize_window(window, width, height); + }); } void window_manager_set_purify_mode(struct window_manager *wm, enum purify_mode mode) @@ -1303,8 +1315,10 @@ enum window_op_error window_manager_apply_grid(struct space_manager *sm, struct float fw = cw * w; float fh = ch * h; - window_manager_move_window(window, fx, fy); - window_manager_resize_window(window, fw, fh); + AX_ENHANCED_UI_WORKAROUND(window->application->ref, { + window_manager_move_window(window, fx, fy); + window_manager_resize_window(window, fw, fh); + }); return WINDOW_OP_ERROR_SUCCESS; } diff --git a/src/window_manager.h b/src/window_manager.h index 39a9e24d..9ca7ba99 100644 --- a/src/window_manager.h +++ b/src/window_manager.h @@ -130,6 +130,7 @@ void window_manager_remove_application(struct window_manager *wm, pid_t pid); void window_manager_add_application(struct window_manager *wm, struct application *application); struct window **window_manager_find_application_windows(struct window_manager *wm, struct application *application, int *window_count); enum window_op_error window_manager_move_window_relative(struct window_manager *wm, struct window *window, int type, float dx, float dy); +void _window_manager_resize_window_relative(struct window *window, CGRect frame, int direction, float dx, float dy); enum window_op_error window_manager_resize_window_relative(struct window_manager *wm, struct window *window, int direction, float dx, float dy); void window_manager_set_purify_mode(struct window_manager *wm, enum purify_mode mode); void window_manager_set_active_window_opacity(struct window_manager *wm, float opacity);