Skip to content

Commit

Permalink
refactoring, properly handle minimized windows and native-fullscreen …
Browse files Browse the repository at this point in the history
…windows
  • Loading branch information
FelixKratz committed Nov 6, 2023
1 parent ea5a80f commit 1701aee
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 137 deletions.
28 changes: 16 additions & 12 deletions src/border.c
Expand Up @@ -15,19 +15,19 @@ void border_destroy(struct border* border) {

void border_move(struct border* border) {
int cid = SLSMainConnectionID();
CFTypeRef transaction = SLSTransactionCreate(cid);

CGRect window_frame;
SLSGetWindowBounds(cid, border->target_wid, &window_frame);
CGRect frame = CGRectInset(window_frame,
-g_settings.border_width,
-g_settings.border_width );
SLSTransactionMoveWindowWithGroup(transaction, border->wid, frame.origin);

CFTypeRef transaction = SLSTransactionCreate(cid);
SLSTransactionMoveWindowWithGroup(transaction, border->wid, frame.origin);
SLSTransactionCommit(transaction, true);
border->origin = window_frame.origin;

CFRelease(transaction);

border->origin = window_frame.origin;
}

void border_draw(struct border* border) {
Expand All @@ -38,13 +38,10 @@ void border_draw(struct border* border) {

bool shown = false;
SLSWindowIsOrderedIn(cid, border->target_wid, &shown);
if (!shown && border->wid) {
SLSReleaseWindow(cid, border->wid);
border->wid = 0;
CGContextRelease(border->context);
border->context = NULL;
}
if (!shown) return;
if (!shown) {
if (border->wid) SLSOrderWindow(cid, border->wid, 0, border->target_wid);
return;
}

int level = window_level(cid, border->target_wid);
int sub_level = 0;
Expand All @@ -56,6 +53,11 @@ void border_draw(struct border* border) {
-g_settings.border_width,
-g_settings.border_width );

if (frame.size.width < 2.f * border_radius
|| frame.size.height < 2.f * border_radius) {
return;
}

CGPoint origin = frame.origin;
frame.origin = CGPointZero;

Expand Down Expand Up @@ -177,5 +179,7 @@ void border_hide(struct border* border) {
}

void border_unhide(struct border* border) {
border_draw(border);
int cid = SLSMainConnectionID();
if (border->wid) SLSOrderWindow(cid, border->wid, -1, border->target_wid);
else border_draw(border);
}
82 changes: 36 additions & 46 deletions src/events.c
Expand Up @@ -18,58 +18,33 @@ static void event_watcher(uint32_t event, void* data, size_t data_length, void*
dump_event(data, data_length);
}

static void window_spawn_handler(uint32_t event, void* data, size_t data_length, void* context) {
struct window_spawn_data {
uint64_t sid;
uint32_t wid;
};

static void window_spawn_handler(uint32_t event, struct window_spawn_data* data, size_t _, int cid) {
struct table* windows = &g_windows;
int cid = (intptr_t)context;
uint32_t wid = *(uint32_t *)(data + 0x8);
uint64_t sid = *(uint64_t *)data;
uint32_t wid = data->wid;
uint64_t sid = data->sid;

if (!wid || !sid) return;

int wid_cid = 0;
SLSGetWindowOwner(cid, wid, &wid_cid);

if (event == EVENT_WINDOW_CREATE) {
pid_t pid = 0;
SLSConnectionGetPID(wid_cid, &pid);
if (pid == g_pid) return;

CFArrayRef target_ref = cfarray_of_cfnumbers(&wid,
sizeof(uint32_t),
1,
kCFNumberSInt32Type);

if (!target_ref) return;

CFTypeRef query = SLSWindowQueryWindows(cid, target_ref, 1);
if (query) {
CFTypeRef iterator = SLSWindowQueryResultCopyWindows(query);
if (iterator && SLSWindowIteratorGetCount(iterator) > 0) {
if (SLSWindowIteratorAdvance(iterator)) {
ITERATOR_WINDOW_SUITABLE(iterator, {
debug("Window Created: %d %d\n", wid, sid);
windows_window_create(windows, wid, sid);
windows_update_notifications(windows);
});
}
}
if (iterator) CFRelease(iterator);
CFRelease(query);
if (windows_window_create(windows, wid, sid)) {
debug("Window Created: %d %d\n", wid, sid);
windows_window_focus(windows, get_front_window());
}
CFRelease(target_ref);
} else if (event == EVENT_WINDOW_DESTROY) {
debug("Window Destroyed: %d %d\n", wid, sid);
if (windows_window_destroy(windows, wid, sid)) {
windows_update_notifications(windows);
debug("Window Destroyed: %d %d\n", wid, sid);
windows_window_focus(windows, get_front_window());
}

windows_window_focus(windows, get_front_window());
}
}

static void window_modify_handler(uint32_t event, void* data, size_t data_length, void* context) {
int cid = (intptr_t)context;
uint32_t wid = *(uint32_t *)(data);
static void window_modify_handler(uint32_t event, uint32_t* window_id, size_t _, int cid) {
uint32_t wid = *window_id;
struct table* windows = &g_windows;

if (event == EVENT_WINDOW_MOVE) {
Expand All @@ -83,15 +58,31 @@ static void window_modify_handler(uint32_t event, void* data, size_t data_length
// The update of the front window might not have taken place yet...
usleep(10000);

windows_window_focus(windows, get_front_window());
uint32_t front_wid = get_front_window();
if (!windows_window_focus(windows, front_wid)) {
debug("Taking slow window focus path: %d\n", front_wid);
if (windows_window_create(windows,
front_wid,
window_space_id(cid, front_wid))) {
windows_window_focus(windows, front_wid);
}
}
windows_window_update(windows, wid);
} else if (event == EVENT_WINDOW_LEVEL) {
debug("Window Level: %d\n", wid);
windows_window_update(windows, wid);
} else if (event == EVENT_WINDOW_TITLE || event == EVENT_WINDOW_UPDATE) {
wid = get_front_window();
debug("Window Focus: %d\n", wid);
windows_window_focus(windows, wid);
uint32_t front_wid = get_front_window();
debug("Window Focus: %d\n", front_wid);
if (!windows_window_focus(windows, front_wid)) {
debug("Taking slow window focus path: %d\n", front_wid);
if (windows_window_create(windows,
front_wid,
window_space_id(cid, front_wid))) {

windows_window_focus(windows, front_wid);
}
}
} else if (event == EVENT_WINDOW_UNHIDE) {
debug("Window Unhide: %d\n", wid);
windows_window_unhide(windows, wid);
Expand All @@ -105,8 +96,7 @@ static void space_handler(uint32_t event, void* data, size_t data_length, void*
windows_draw_borders_on_current_spaces(&g_windows);
}

void events_register() {
int cid = SLSMainConnectionID();
void events_register(int cid) {
void* cid_ctx = (void*)(intptr_t)cid;

SLSRegisterNotifyProc(window_modify_handler, EVENT_WINDOW_MOVE, cid_ctx);
Expand Down
2 changes: 1 addition & 1 deletion src/events.h
Expand Up @@ -16,4 +16,4 @@

#define EVENT_SPACE_CHANGE 1401

void events_register();
void events_register(int cid);
2 changes: 1 addition & 1 deletion src/mach.c
Expand Up @@ -94,7 +94,7 @@ bool mach_server_begin(struct mach_server* mach_server, mach_handler handler) {
}

if (bootstrap_register(mach_server->bs_port,
"git.felix.borders",
BS_NAME,
mach_server->port ) != KERN_SUCCESS) {
return false;
}
Expand Down
7 changes: 2 additions & 5 deletions src/mach.h
@@ -1,17 +1,14 @@
#pragma once
#include <mach/mach.h>

#define BS_NAME "git.felix.borders"

struct mach_message {
mach_msg_header_t header;
mach_msg_size_t msgh_descriptor_count;
mach_msg_ool_descriptor_t descriptor;
};

struct mach_buffer {
struct mach_message message;
mach_msg_trailer_t trailer;
};

#define MACH_HANDLER(name) void name(void* message, uint32_t len)
typedef MACH_HANDLER(mach_handler);

Expand Down
66 changes: 19 additions & 47 deletions src/main.c
Expand Up @@ -22,34 +22,7 @@ static TABLE_COMPARE_FUNC(cmp_windows)
return *(uint32_t *) key_a == *(uint32_t *) key_b;
}

static void acquire_lockfile(void) {
char *user = getenv("USER");
if (!user) {
error("JankyBorders: 'env USER' not set! abort..\n");
}

char lock_file[4096] = {};
snprintf(lock_file, sizeof(lock_file), "/tmp/JankyBorders_%s.lock", user);

int handle = open(lock_file, O_CREAT | O_WRONLY, 0600);
if (handle == -1) {
error("JankyBorders: could not create lock-file! abort..\n");
}

struct flock lockfd = {
.l_start = 0,
.l_len = 0,
.l_pid = g_pid,
.l_type = F_WRLCK,
.l_whence = SEEK_SET
};

if (fcntl(handle, F_SETLK, &lockfd) == -1) {
error("JankyBorders: could not acquire lock-file! already running?\n");
}
}

void event_callback(CFMachPortRef port, void* message, CFIndex size, void* context) {
static void event_callback(CFMachPortRef port, void* message, CFIndex size, void* context) {
int cid = SLSMainConnectionID();
CGEventRef event = SLEventCreateNextEvent(cid);
if (!event) return;
Expand Down Expand Up @@ -96,12 +69,13 @@ static void message_handler(void* data, uint32_t len) {
update_mask |= parse_settings(&g_settings, 1, &message);
message += strlen(message) + 1;
}

if (update_mask & BORDER_UPDATE_MASK_ALL) {
windows_window_update_all(&g_windows);
windows_update_all(&g_windows);
} else if (update_mask & BORDER_UPDATE_MASK_ACTIVE) {
windows_window_update_active(&g_windows);
windows_update_active(&g_windows);
} else if (update_mask & BORDER_UPDATE_MASK_INACTIVE) {
windows_window_update_inactive(&g_windows);
windows_update_inactive(&g_windows);
}
}

Expand All @@ -128,27 +102,27 @@ static void send_args_to_server(mach_port_t port, int argc, char** argv) {
}

int main(int argc, char** argv) {
uint32_t update_mask = 0;
if (argc > 1) {
update_mask = parse_settings(&g_settings, argc - 1, argv + 1);
}

if (update_mask) {
mach_port_t port = mach_get_bs_port("git.felix.borders");
if (port) {
send_args_to_server(port, argc, argv);
return 0;
}
uint32_t update_mask = parse_settings(&g_settings, argc - 1, argv + 1);

mach_port_t server_port = mach_get_bs_port(BS_NAME);
if (server_port && update_mask) {
send_args_to_server(server_port, argc, argv);
return 0;
} else if (server_port) {
error("A borders instance is already running and no valid arguments"
" where provided. To modify properties of the running instance"
" provide them as arguments.\n");
}

pid_for_task(mach_task_self(), &g_pid);
acquire_lockfile();
table_init(&g_windows, 1024, hash_windows, cmp_windows);
events_register();

int cid = SLSMainConnectionID();
events_register(cid);
SLSWindowManagementBridgeSetDelegate(NULL);

mach_port_t port;
CGError error = SLSGetEventPort(SLSMainConnectionID(), &port);
CGError error = SLSGetEventPort(cid, &port);
CFMachPortRef cf_mach_port = NULL;
CFRunLoopSourceRef source = NULL;
if (error == kCGErrorSuccess) {
Expand All @@ -171,7 +145,5 @@ int main(int argc, char** argv) {
windows_add_existing_windows(&g_windows);
mach_server_begin(&g_mach_server, message_handler);
CFRunLoopRun();

return 0;
}

0 comments on commit 1701aee

Please sign in to comment.