fully transactional window system rewrite for Ventura

This commit is contained in:
Felix Kratz 2022-12-20 10:05:17 +01:00
parent f1c5cd9f48
commit 8e97ffeb63
6 changed files with 72 additions and 39 deletions

View file

@ -282,12 +282,10 @@ bool bar_manager_set_sticky(struct bar_manager *bar_manager, bool sticky) {
void bar_manager_freeze(struct bar_manager *bar_manager) {
bar_manager->frozen = true;
windows_freeze();
}
void bar_manager_unfreeze(struct bar_manager *bar_manager) {
bar_manager->frozen = false;
windows_unfreeze();
}
uint32_t bar_manager_length_for_bar_side(struct bar_manager* bar_manager, struct bar* bar, char side) {
@ -494,7 +492,7 @@ void bar_manager_update_space_components(struct bar_manager* bar_manager, bool f
void bar_manager_animator_refresh(struct bar_manager* bar_manager) {
bar_manager_freeze(bar_manager);
if (animator_update(&bar_manager->animator)) {
bar_manager->frozen = false;
bar_manager_unfreeze(bar_manager);
if (bar_manager->bar_needs_resize) bar_manager_resize(bar_manager);
bar_manager_refresh(bar_manager, false);
@ -512,12 +510,7 @@ void bar_manager_update(struct bar_manager* bar_manager, bool forced) {
NULL );
}
if (needs_refresh) {
bar_manager_freeze(bar_manager);
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, false);
bar_manager_unfreeze(bar_manager);
}
if (needs_refresh) bar_manager_refresh(bar_manager, false);
}
void bar_manager_reset(struct bar_manager* bar_manager) {
@ -698,9 +691,8 @@ void bar_manager_display_changed(struct bar_manager* bar_manager) {
bar_manager_freeze(bar_manager);
bar_manager_reset(bar_manager);
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, true);
bar_manager_unfreeze(bar_manager);
bar_manager_refresh(bar_manager, true);
bar_manager_handle_space_change(bar_manager, true);
}
@ -814,9 +806,8 @@ void bar_manager_handle_space_change(struct bar_manager* bar_manager, bool force
&env_vars );
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, force_refresh);
bar_manager_unfreeze(bar_manager);
bar_manager_refresh(bar_manager, force_refresh);
env_vars_destroy(&env_vars);
}
@ -832,10 +823,7 @@ void bar_manager_handle_display_change(struct bar_manager* bar_manager) {
COMMAND_SUBSCRIBE_DISPLAY_CHANGE,
&env_vars );
bar_manager_freeze(bar_manager);
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, false);
bar_manager_unfreeze(bar_manager);
env_vars_destroy(&env_vars);
}
@ -852,11 +840,7 @@ void bar_manager_handle_system_woke(struct bar_manager* bar_manager) {
COMMAND_SUBSCRIBE_SYSTEM_WOKE,
NULL );
bar_manager_freeze(bar_manager);
bar_manager->frozen = false;
bar_manager_refresh(bar_manager, true);
bar_manager_unfreeze(bar_manager);
bar_manager_handle_space_change(bar_manager, true);
}

View file

@ -64,7 +64,9 @@ static void *event_loop_run(void *context) {
#ifdef STATS
uint64_t begin_cycles = __rdtsc();
#endif
windows_freeze();
uint32_t result = event_handler[event->type](event->context);
windows_unfreeze();
#ifdef STATS
cycle_counter_tick(event_type_str[event->type], &event_counters[event->type], __rdtsc() - begin_cycles);
#endif

View file

@ -512,10 +512,7 @@ static void handle_domain_order(FILE* rsp, struct token domain, char* message) {
}
bar_manager_sort(&g_bar_manager, ordering, count);
bar_manager_freeze(&g_bar_manager);
g_bar_manager.frozen = false;
bar_manager_refresh(&g_bar_manager, false);
bar_manager_unfreeze(&g_bar_manager);
}
void handle_message_mach(struct mach_buffer* buffer) {
@ -666,9 +663,8 @@ void handle_message_mach(struct mach_buffer* buffer) {
}
animator_lock(&g_bar_manager.animator);
g_bar_manager.frozen = false;
bar_manager_refresh(&g_bar_manager, false);
bar_manager_unfreeze(&g_bar_manager);
bar_manager_refresh(&g_bar_manager, false);
if (rsp) fclose(rsp);

View file

@ -24,6 +24,7 @@ extern int SLSMainConnectionID(void);
extern int RunApplicationEventLoop(void);
int g_connection;
CFTypeRef g_transaction;
struct bar_manager g_bar_manager;
struct event_loop g_event_loop;

View file

@ -15,6 +15,7 @@ void window_init(struct window* window) {
window->order_mode = W_ABOVE;
}
static CFTypeRef window_create_region(struct window *window, CGRect frame) {
CFTypeRef frame_region;
CGSNewRegionWithRect(&frame, &frame_region);
@ -69,9 +70,17 @@ void window_create(struct window* window, CGRect frame) {
void windows_freeze() {
SLSDisableUpdate(g_connection);
if (__builtin_available(macOS 13.0, *)) {
g_transaction = SLSTransactionCreate(g_connection);
}
}
void windows_unfreeze() {
if (__builtin_available(macOS 13.0, *)) {
SLSTransactionCommit(g_transaction, 0);
CFRelease(g_transaction);
g_transaction = NULL;
}
SLSReenableUpdate(g_connection);
}
@ -93,10 +102,20 @@ void window_set_frame(struct window* window, CGRect frame) {
void window_move(struct window* window, CGPoint point) {
window->origin = point;
SLSMoveWindow(g_connection, window->id, &point);
if (__builtin_available(macOS 12.0, *)) {
if (__builtin_available(macOS 13.0, *)) {
// Ventura
SLSTransactionMoveWindowWithGroup(g_transaction, window->id,
point );
}
else {
// Monterey
SLSMoveWindow(g_connection, window->id, &point);
}
} else {
// Big Sur and Previous
SLSMoveWindow(g_connection, window->id, &point);
CFNumberRef number = CFNumberCreate(NULL,
kCFNumberSInt32Type,
&window->id );
@ -114,11 +133,18 @@ bool window_apply_frame(struct window* window) {
CFTypeRef frame_region = window_create_region(window, window->frame);
if (__builtin_available(macOS 13.0, *)) {
} else if (window->parent) {
window_order(window, window->parent, W_OUT);
CFTypeRef transaction = SLSTransactionCreate(g_connection);
SLSTransactionSetWindowShape(transaction, window->id,
0,
0,
frame_region);
SLSTransactionCommit(transaction, 1);
CFRelease(transaction);
} else {
if (window->parent) window_order(window, window->parent, W_OUT);
SLSSetWindowShape(g_connection, window->id, 0, 0, frame_region);
}
SLSSetWindowShape(g_connection, window->id, 0, 0, frame_region);
if (window->parent) {
CGContextClearRect(window->context, window->frame);
@ -152,6 +178,7 @@ void window_send_to_space(struct window* window, uint64_t dsid) {
}
void window_close(struct window* window) {
SLSOrderWindow(g_connection, window->id, 0, 0);
CGContextRelease(window->context);
SLSReleaseWindow(g_connection, window->id);
@ -164,22 +191,43 @@ void window_close(struct window* window) {
}
void window_set_level(struct window* window, uint32_t level) {
SLSSetWindowLevel(g_connection, window->id, level);
if (__builtin_available(macOS 13.0, *)) {
SLSTransactionSetWindowLevel(g_transaction, window->id, level);
} else {
SLSSetWindowLevel(g_connection, window->id, level);
}
}
void window_order(struct window* window, struct window* parent, int mode) {
SLSRemoveFromOrderingGroup(g_connection, window->id);
if (__builtin_available(macOS 13.0, *)) {
// SLSTransactionClearWindowOrderingGroup(g_transaction, window->id);
} else {
SLSRemoveFromOrderingGroup(g_connection, window->id);
}
if (parent) {
window->parent = parent;
if (mode != W_OUT) window->order_mode = mode;
SLSOrderWindow(g_connection, window->id, mode, parent->id);
SLSAddWindowToWindowOrderingGroup(g_connection,
parent->id,
window->id,
mode );
if (__builtin_available(macOS 13.0, *)) {
SLSTransactionOrderWindow(g_transaction, window->id,
mode,
parent->id );
// SLSTransactionAddWindowToWindowOrderingGroup(g_transaction, parent->id,
// window->id,
// mode );
} else {
SLSOrderWindow(g_connection, window->id, mode, parent->id);
SLSAddWindowToWindowOrderingGroup(g_connection, parent->id,
window->id,
mode );
}
} else {
window->parent = NULL;
SLSOrderWindow(g_connection, window->id, mode, 0);
if (__builtin_available(macOS 13.0, *)) {
SLSTransactionOrderWindow(g_transaction, window->id, mode, 0);
} else {
SLSOrderWindow(g_connection, window->id, mode, 0);
}
}
}

View file

@ -2,11 +2,10 @@
#include "misc/helpers.h"
CFTypeRef SLSTransactionCreate(int cid);
extern CGError SLSTransactionSetWindowShape(CFTypeRef transaction, uint32_t wid, float x_offset, float y_offset, CFTypeRef region);
extern CGError SLSTransactionOrderWindow(CFTypeRef transaction, uint32_t wid, int mode, uint32_t relativeToWID);
extern CGError SLSTransactionSetWindowLevel(CFTypeRef transaction, uint32_t wid, int level);
extern CGError SLSTransactionSetWindowShape(CFTypeRef transaction, uint32_t wid, float x_offset, float y_offset, CFTypeRef shape);
extern CGError SLSTransactionMoveWindowWithGroup(CFTypeRef transaction, uint32_t wid, CGPoint* point);
extern CGError SLSTransactionMoveWindowWithGroup(CFTypeRef transaction, uint32_t wid, CGPoint point);
extern CGError SLSTransactionAddWindowToWindowOrderingGroup(CFTypeRef transaction, uint32_t parent_wid, uint32_t child_wid, int order);
extern CGError SLSTransactionClearWindowOrderingGroup(CFTypeRef transaction, uint32_t wid);
extern CGError SLSTransactionCommitUsingMethod(CFTypeRef transaction, uint32_t method);
@ -38,6 +37,7 @@ extern CGError SLSAddWindowToWindowOrderingGroup(int cid, uint32_t parent_wid, u
extern CGError SLSRemoveFromOrderingGroup(int cid, uint32_t wid);
extern CGError SLSReassociateWindowsSpacesByGeometry(int cid, CFArrayRef wids);
extern CGError SLSMoveWindowsToManagedSpace(int cid, CFArrayRef window_list, uint64_t sid);
extern CGError SLSMoveWindowWithGroup(int cid, uint32_t wid, CGPoint* point);
extern void SLSCaptureWindowsContentsToRectWithOptions(uint32_t cid, uint64_t* wid, bool meh, CGRect bounds, uint32_t flags, CGImageRef* image);
extern int SLSGetScreenRectForWindow(uint32_t cid, uint32_t wid, CGRect* out);
@ -62,6 +62,8 @@ extern CGError SLSSetSurfaceColorSpace(int cid, uint32_t wid, uint32_t surface,
#define W_OUT 0
#define W_BELOW -1
extern CFTypeRef g_transaction;
struct window {
struct window* parent;
int order_mode;