commit 54d1087c23729ab4bcd1cea032a89df653f342e6 from: Brett Fisher date: Wed May 20 17:38:39 2026 UTC bxwm.c: Reorder functions to match order in forward declarations. commit - f273930fd417e44463c7284c61a622e349f04641 commit + 54d1087c23729ab4bcd1cea032a89df653f342e6 blob - 70264fcc1cdba5e22c8beebc33b759d304e062ef blob + af96ba99594aa29f77b7dc183e992a683c88beca --- bxwm.c +++ bxwm.c @@ -67,6 +67,7 @@ static void cleanup(int status); /* State Updates */ static void update_client_list(void); static void update_workarea(void); +static void arrange(void); /* Window Management */ static void manage(Window w); static void unmanage(Window w); @@ -158,6 +159,20 @@ logmsg(const char *fmt, ...) { static void logmsg(const char *fmt, ...) { (void)fmt; } #endif +static void +spawn(const char *cmd) { + if (fork() == 0) + execl("/bin/sh", "sh", "-c", cmd, (char *)NULL); +} + +static int +xerror(Display *dpy, XErrorEvent *ee) { + char buf[1024]; + XGetErrorText(dpy, ee->error_code, buf, sizeof(buf)); + logmsg("X error: %s", buf); + return 0; +} + int socket_init(void) { struct sockaddr_un addr; @@ -291,7 +306,110 @@ setup(void) { spawn(STATUSBAR); } +static void +cleanup(int status) { + if (dpy) { + if (clients) + free(clients); + XCloseDisplay(dpy); + } + unlink(socket_path); + close(server_fd); + exit(status); +} + static void +update_client_list(void) { + Window *wins = NULL; + unsigned int i; + + if (num_clients > 0) { + wins = malloc(num_clients * sizeof(Window)); + for (i = 0; i < num_clients; i++) + wins[i] = clients[i].win; + } + XChangeProperty(dpy, root, net_client_list, XA_WINDOW, 32, + PropModeReplace, (unsigned char *)wins, num_clients); + if (wins) + free(wins); +} + +static void +update_workarea(void) { + unsigned long left = 0, right = 0, top = 0, bottom = 0; + unsigned int i; + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + unsigned char *data = NULL; + + for (i = 0; i < num_clients; i++) { + if (XGetWindowProperty(dpy, clients[i].win, net_wm_strut_partial, + 0, 12, False, XA_CARDINAL, &actual_type, &actual_format, + &nitems, &bytes_after, &data) == Success && data) { + if (actual_type == XA_CARDINAL && nitems >= 4) { + unsigned long *s = (unsigned long *)data; + if (s[0] > left) left = s[0]; + if (s[1] > right) right = s[1]; + if (s[2] > top) top = s[2]; + if (s[3] > bottom) bottom = s[3]; + } + XFree(data); + data = NULL; + continue; + } + + if (XGetWindowProperty(dpy, clients[i].win, net_wm_strut, + 0, 4, False, XA_CARDINAL, &actual_type, &actual_format, + &nitems, &bytes_after, &data) == Success && data) { + if (actual_type == XA_CARDINAL && nitems >= 4) { + unsigned long *s = (unsigned long *)data; + if (s[0] > left) left = s[0]; + if (s[1] > right) right = s[1]; + if (s[2] > top) top = s[2]; + if (s[3] > bottom) bottom = s[3]; + } + XFree(data); + } + } + + wa_x = left; + wa_y = top; + wa_w = screen_w - left - right; + wa_h = screen_h - top - bottom; + + long *workareas = calloc(NUM_WORKSPACES * 4, sizeof(long)); + for (i = 0; i < NUM_WORKSPACES; i++) { + workareas[i * 4 + 0] = wa_x; + workareas[i * 4 + 1] = wa_y; + workareas[i * 4 + 2] = wa_w; + workareas[i * 4 + 3] = wa_h; + } + XChangeProperty(dpy, root, net_workarea, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)workareas, + NUM_WORKSPACES * 4); + free(workareas); + + arrange(); +} + +static void +arrange(void) { + unsigned int i; + for (i = 0; i < num_clients; i++) { + if (clients[i].ws == curws && !clients[i].is_dock) { + switch (clients[i].layout) { + case CENTER: center_window(&clients[i]); break; + case LEFT_HALF: left_half_window(&clients[i]); break; + case RIGHT_HALF: right_half_window(&clients[i]); break; + case SMALL: small_window(&clients[i]); break; + case MAXIMIZE: maximize_window(&clients[i]); break; + } + } + } +} + +static void manage(Window w) { XWindowAttributes wa; XSetWindowAttributes attrs; @@ -370,6 +488,59 @@ manage(Window w) { } static void +unmanage(Window w) { + unsigned int i; + Client *c = NULL; + + logmsg("unmanage 0x%lx", w); + + for (i = 0; i < num_clients; i++) { + if (clients[i].win == w) { + c = &clients[i]; + break; + } + } + + if (i == num_clients) return; + + if (focused_client == c) + focused_client = NULL; + + int destroyed_idx = i; + + for (int ws = 0; ws < NUM_WORKSPACES; ws++) { + if (ws_focus_idx[ws] == destroyed_idx) { + ws_focus_idx[ws] = -1; + } else if (ws_focus_idx[ws] > destroyed_idx) { + ws_focus_idx[ws]--; + } + } + + for (; i < num_clients - 1; i++) + clients[i] = clients[i + 1]; + num_clients--; + if (num_clients) + clients = realloc(clients, num_clients * sizeof(Client)); + else { + free(clients); + clients = NULL; + } + + if (!focused_client && num_clients) + focus_client(&clients[num_clients - 1]); + + update_workarea(); + + update_client_list(); + + if (!focused_client) { + long active = None; + XChangeProperty(dpy, root, net_active_window, XA_WINDOW, 32, + PropModeReplace, (unsigned char *)&active, 1); + } +} + +static void focus_client(Client *c) { Client *prev = focused_client; @@ -683,164 +854,6 @@ movetows(int ws) { } } -static void -unmanage(Window w) { - unsigned int i; - Client *c = NULL; - - logmsg("unmanage 0x%lx", w); - - for (i = 0; i < num_clients; i++) { - if (clients[i].win == w) { - c = &clients[i]; - break; - } - } - - if (i == num_clients) return; - - if (focused_client == c) - focused_client = NULL; - - int destroyed_idx = i; - - for (int ws = 0; ws < NUM_WORKSPACES; ws++) { - if (ws_focus_idx[ws] == destroyed_idx) { - ws_focus_idx[ws] = -1; - } else if (ws_focus_idx[ws] > destroyed_idx) { - ws_focus_idx[ws]--; - } - } - - for (; i < num_clients - 1; i++) - clients[i] = clients[i + 1]; - num_clients--; - if (num_clients) - clients = realloc(clients, num_clients * sizeof(Client)); - else { - free(clients); - clients = NULL; - } - - if (!focused_client && num_clients) - focus_client(&clients[num_clients - 1]); - - update_workarea(); - - update_client_list(); - - if (!focused_client) { - long active = None; - XChangeProperty(dpy, root, net_active_window, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&active, 1); - } -} - -static void -spawn(const char *cmd) { - if (fork() == 0) - execl("/bin/sh", "sh", "-c", cmd, (char *)NULL); -} - -static int -xerror(Display *dpy, XErrorEvent *ee) { - char buf[1024]; - XGetErrorText(dpy, ee->error_code, buf, sizeof(buf)); - logmsg("X error: %s", buf); - return 0; -} - -static void -update_client_list(void) { - Window *wins = NULL; - unsigned int i; - - if (num_clients > 0) { - wins = malloc(num_clients * sizeof(Window)); - for (i = 0; i < num_clients; i++) - wins[i] = clients[i].win; - } - XChangeProperty(dpy, root, net_client_list, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)wins, num_clients); - if (wins) - free(wins); -} - -static void -arrange(void) { - unsigned int i; - for (i = 0; i < num_clients; i++) { - if (clients[i].ws == curws && !clients[i].is_dock) { - switch (clients[i].layout) { - case CENTER: center_window(&clients[i]); break; - case LEFT_HALF: left_half_window(&clients[i]); break; - case RIGHT_HALF: right_half_window(&clients[i]); break; - case SMALL: small_window(&clients[i]); break; - case MAXIMIZE: maximize_window(&clients[i]); break; - } - } - } -} - -static void -update_workarea(void) { - unsigned long left = 0, right = 0, top = 0, bottom = 0; - unsigned int i; - Atom actual_type; - int actual_format; - unsigned long nitems, bytes_after; - unsigned char *data = NULL; - - for (i = 0; i < num_clients; i++) { - if (XGetWindowProperty(dpy, clients[i].win, net_wm_strut_partial, - 0, 12, False, XA_CARDINAL, &actual_type, &actual_format, - &nitems, &bytes_after, &data) == Success && data) { - if (actual_type == XA_CARDINAL && nitems >= 4) { - unsigned long *s = (unsigned long *)data; - if (s[0] > left) left = s[0]; - if (s[1] > right) right = s[1]; - if (s[2] > top) top = s[2]; - if (s[3] > bottom) bottom = s[3]; - } - XFree(data); - data = NULL; - continue; - } - - if (XGetWindowProperty(dpy, clients[i].win, net_wm_strut, - 0, 4, False, XA_CARDINAL, &actual_type, &actual_format, - &nitems, &bytes_after, &data) == Success && data) { - if (actual_type == XA_CARDINAL && nitems >= 4) { - unsigned long *s = (unsigned long *)data; - if (s[0] > left) left = s[0]; - if (s[1] > right) right = s[1]; - if (s[2] > top) top = s[2]; - if (s[3] > bottom) bottom = s[3]; - } - XFree(data); - } - } - - wa_x = left; - wa_y = top; - wa_w = screen_w - left - right; - wa_h = screen_h - top - bottom; - - long *workareas = calloc(NUM_WORKSPACES * 4, sizeof(long)); - for (i = 0; i < NUM_WORKSPACES; i++) { - workareas[i * 4 + 0] = wa_x; - workareas[i * 4 + 1] = wa_y; - workareas[i * 4 + 2] = wa_w; - workareas[i * 4 + 3] = wa_h; - } - XChangeProperty(dpy, root, net_workarea, XA_CARDINAL, 32, - PropModeReplace, (unsigned char *)workareas, - NUM_WORKSPACES * 4); - free(workareas); - - arrange(); -} - static void handle_socket_command(int server_fd) { @@ -886,15 +899,3 @@ handle_socket_command(int server_fd) close(client_fd); } -static void -cleanup(int status) { - if (dpy) { - if (clients) - free(clients); - XCloseDisplay(dpy); - } - unlink(socket_path); - close(server_fd); - exit(status); -} -