Commit Diff


commit - 9c8821a84e92c4ceb948bd14259d6519f7c2a307
commit + 08f4348e34813e6491f12260ef98c315649f58e5
blob - c6dd9c0f940cc061ecf8614a248f3ef9765d2f68
blob + 70264fcc1cdba5e22c8beebc33b759d304e062ef
--- bxwm.c
+++ bxwm.c
@@ -24,54 +24,52 @@
 
 #define SOCKET_SUFFIX "/.local/tmp/bxwm.sock"
 
-/* Layout types */
 enum { FLOAT, CENTER, LEFT_HALF, RIGHT_HALF, SMALL, MAXIMIZE };
 
-/* Types */
 typedef struct {
     Window win;
     int focused;
     int ws;
-    int is_dock; /* dock/bar window: no border, no positioning,  no focus */
-    int layout; /* Remember window geometry type */
+    int is_dock;
+    int layout;
 } Client;
 
-/* Globals */
 static Display *dpy;
 static Window root;
 static int screen;
 static unsigned long screen_w, screen_h;
-static unsigned long wa_x, wa_y, wa_w, wa_h;  /* work area (screen minus struts) */
+static unsigned long wa_x, wa_y, wa_w, wa_h;
 static Client *clients = NULL;
 static unsigned int num_clients = 0;
 static Client *focused_client = NULL;
 static unsigned long focus_pixel;
 static unsigned long unfocus_pixel;
 static int curws = INITIAL_WORKSPACE;
-static int ws_focus_idx[NUM_WORKSPACES] = {-1}; /* Index of last focused per WS */
+static int ws_focus_idx[NUM_WORKSPACES] = {-1};
 static int server_fd;
 static char socket_path[256];
 static int running;
-
-/* EWMH atoms */
 static Atom net_supported, net_number_of_desktops, net_current_desktop;
 static Atom net_client_list, net_active_window, net_wm_desktop;
 static Atom net_wm_strut_partial, net_wm_strut, net_workarea;
 static Atom net_wm_window_type, net_wm_window_type_dock;
-
-/* ICCCM atoms */
 static Atom wm_protocols, wm_delete_window;
 
-/* Forward function declarations */
+/* Forward Declarations */
+/* Utilities */
 static void logmsg(const char *fmt, ...);
+static void spawn(const char *cmd);
+static int xerror(Display *dpy, XErrorEvent *ee);
+/* Lifecycle */
 int socket_init(void);
 static void setup(void);
-static void handle_socket_command(int fd);
 static void cleanup(int status);
-static int xerror(Display *dpy, XErrorEvent *ee);
+/* State Updates */
+static void update_client_list(void);
 static void update_workarea(void);
+/* Window Management */
 static void manage(Window w);
-static void spawn(const char *cmd);
+static void unmanage(Window w);
 static void focus_client(Client *c);
 static void center_window(Client *c);
 static void left_half_window(Client *c);
@@ -83,8 +81,8 @@ static void focus_next(void);
 static void focus_prev(void);
 static void view(int ws);
 static void movetows(int ws);
-static void unmanage(Window w);
-static void update_client_list(void);
+/* Inter-Process Communication */
+static void handle_socket_command(int fd);
 
 int
 main(int argc, char *argv[])
@@ -94,33 +92,29 @@ main(int argc, char *argv[])
 
     XEvent ev;
 
-    // 1. Initial setup
     if (!(dpy = XOpenDisplay(NULL))) exit(1);
     root = DefaultRootWindow(dpy);
-    
-    // 2. Initialize Socket and Poll
+
     server_fd = socket_init();
     int x_fd = ConnectionNumber(dpy);
-    
+
     struct pollfd fds[2];
     fds[0].fd = x_fd;
     fds[0].events = POLLIN;
     fds[1].fd = server_fd;
     fds[1].events = POLLIN;
 
-    // 3. User configuration/setup
     setup();
 
     running = 1;
 
-    // 4. Main Loop
+    /* Event loop: poll(2) on both X connection and IPC socket */
     while (running) {
         if (poll(fds, 2, -1) < 0) {
             if (errno == EINTR) continue;
             break;
         }
 
-        // Handle X11 events
         if (fds[0].revents & POLLIN) {
             while (XPending(dpy)) {
                 XNextEvent(dpy, &ev);
@@ -136,13 +130,11 @@ main(int argc, char *argv[])
             }
         }
 
-        // Handle socket commands
         if (fds[1].revents & POLLIN) {
             handle_socket_command(server_fd);
         }
     }
 
-    // 5. Final Cleanup
     cleanup(0);
     close(server_fd);
     XCloseDisplay(dpy);
@@ -166,12 +158,12 @@ logmsg(const char *fmt, ...) {
 static void logmsg(const char *fmt, ...) { (void)fmt; }
 #endif
 
-int socket_init(void) {
+int
+socket_init(void) {
     struct sockaddr_un addr;
     int server_fd;
     char socket_path[256];
 
-    // Build the socket path
     char *home = getenv("HOME");
     if (home == NULL) {
         fprintf(stderr, "bxwm: HOME not set\n");
@@ -179,17 +171,14 @@ int socket_init(void) {
     }
     snprintf(socket_path, sizeof(socket_path), "%s%s", home, SOCKET_SUFFIX);
 
-    // Remove stale socket from previous session
-    unlink(socket_path);
+    unlink(socket_path); /* clear stale socket from prior run */
 
-    // Create the socket
     server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
     if (server_fd < 0) {
         perror("bxwm: socket");
         exit(1);
     }
 
-    // Bind the socket to the path
     memset(&addr, 0, sizeof(addr));
     addr.sun_family = AF_UNIX;
     strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
@@ -200,8 +189,7 @@ int socket_init(void) {
         exit(1);
     }
 
-    // Listen for incoming connections
-    if (listen(server_fd, 5) < 0) {
+    if (listen(server_fd, SOMAXCONN) < 0) {
         perror("bxwm: listen");
         close(server_fd);
         unlink(socket_path);
@@ -233,7 +221,6 @@ setup(void) {
         cleanup(1);
     }
 
-    /* Allocate border colors */
     if (!XParseColor(dpy, cmap, BORDER_FOCUSED, &color) ||
         !XAllocColor(dpy, cmap, &color)) {
         fprintf(stderr, "bxwm: cannot allocate focus color '%s'\n", BORDER_FOCUSED);
@@ -248,14 +235,12 @@ setup(void) {
     }
     unfocus_pixel = color.pixel;
 
-    /* Root window event mask */
     wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |
                     ButtonPressMask | PointerMotionMask | EnterWindowMask |
                     LeaveWindowMask | KeyPressMask | KeyReleaseMask |
                     PropertyChangeMask;
     XChangeWindowAttributes(dpy, root, CWEventMask, &wa);
 
-    /* Set root cursor */
     Cursor cursor = XCreateFontCursor(dpy, XC_left_ptr);
     XDefineCursor(dpy, root, cursor);
     XFreeCursor(dpy, cursor);
@@ -275,7 +260,6 @@ setup(void) {
     net_wm_window_type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
     net_wm_window_type_dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
 
-    /* Set EWMH properties on root window */
     Atom supported[] = {
         net_supported, net_number_of_desktops, net_current_desktop,
         net_client_list, net_active_window, net_wm_desktop,
@@ -320,7 +304,6 @@ manage(Window w) {
     if (!XGetWindowAttributes(dpy, w, &wa))
         return;
 
-    /* Check if window is a dock/bar */
     int is_dock = 0;
     Atom actual_type;
     int actual_format;
@@ -335,7 +318,6 @@ manage(Window w) {
         XFree(data);
     }
 
-    /* Events only (border pixel set via Configure later) */
     attrs.event_mask = StructureNotifyMask | EnterWindowMask | PropertyChangeMask;
     XChangeWindowAttributes(dpy, w, CWEventMask, &attrs);
 
@@ -487,24 +469,17 @@ small_window(Client *c) {
     if (!c) return;
     c->layout = SMALL;
  
-    /* Step 1: Calculate height first (50% of screen, minus borders) */
     win_h = (wa_h * INITIAL_HEIGHT) - (2 * BORDER_WIDTH);
     
-    /* Step 2: Calculate width using golden ratio (width = height * PHI) */
     win_w = (win_h * PHI) - (2 * BORDER_WIDTH);
     
-    /* Step 3: Safety check - if too wide (>80% of screen), cap it */
     if (win_w > (wa_w * 0.8) - (2 * BORDER_WIDTH)) {
         win_w = (wa_w * 0.8) - (2 * BORDER_WIDTH);
         win_h = (win_w / PHI) - (2 * BORDER_WIDTH);
     }
     
-    /* Step 4: Center the window horizontally 
-       (screen width - total window width including borders) / 2 */
     win_x = wa_x + (wa_w - (win_w + 2 * BORDER_WIDTH)) / 2;
     
-    /* Step 5: Center the window vertically 
-       (screen height - total window height including borders) / 2 */
     win_y = wa_y + (wa_h - (win_h + 2 * BORDER_WIDTH)) / 2;
 
     {
@@ -579,7 +554,6 @@ focus_next(void) {
     if (num_clients == 0)
         return;
     
-    /* Find current index */
     if (focused_client) {
         for (i = 0; i < num_clients; i++) {
             if (&clients[i] == focused_client) {
@@ -590,9 +564,8 @@ focus_next(void) {
         }
     }
     if (!found)
-        start = num_clients - 1;  /* So first check is index 0 */
+        start = num_clients - 1;
     
-    /* Search for next visible window */
     for (i = 1; i <= num_clients; i++) {
         idx = (start + i) % num_clients;
         if (clients[idx].ws == curws) {
@@ -602,7 +575,6 @@ focus_next(void) {
         }
     }
     
-    /* No visible windows on this workspace - clear focus */
     if (focused_client) {
         XSetWindowBorder(dpy, focused_client->win, unfocus_pixel);
         focused_client->focused = 0;
@@ -631,7 +603,6 @@ focus_prev(void) {
     if (!found)
         start = 0;
     
-    /* Search backward for visible window */
     for (i = 1; i <= num_clients; i++) {
         idx = (start + num_clients - i) % num_clients;
         if (clients[idx].ws == curws) {
@@ -641,7 +612,6 @@ focus_prev(void) {
         }
     }
     
-    /* No visible windows */
     if (focused_client) {
         XSetWindowBorder(dpy, focused_client->win, unfocus_pixel);
         focused_client->focused = 0;
@@ -657,10 +627,8 @@ view(int ws) {
     if (ws < 0 || ws >= NUM_WORKSPACES || ws == curws)
         return;
 
-    /* Save current focus index */
     ws_focus_idx[curws] = (focused_client ? (focused_client - clients) : -1);
 
-    /* Unmap current workspace windows */
     for (i = 0; i < num_clients; i++) {
         if (clients[i].ws == curws)
             XUnmapWindow(dpy, clients[i].win);
@@ -673,13 +641,11 @@ view(int ws) {
                     PropModeReplace, (unsigned char *)&current_desktop, 1);
 
 
-    /* Map new workspace windows */
     for (i = 0; i < num_clients; i++) {
         if (clients[i].ws == curws)
             XMapWindow(dpy, clients[i].win);
     }
 
-    /* Restore focus or find first visible */
     int idx = ws_focus_idx[curws];
     if (idx >= 0 && idx < (int)num_clients && clients[idx].ws == curws)
         focus_client(&clients[idx]);
@@ -703,17 +669,15 @@ movetows(int ws) {
                     PropModeReplace, (unsigned char *)&new_ws, 1);
 
     if (old_ws == curws) {
-        /* Moving away from visible workspace */
         XUnmapWindow(dpy, c->win);
         
         int c_idx = (c - clients);
         if (ws_focus_idx[old_ws] == c_idx)
         ws_focus_idx[old_ws] = -1;
-        focus_next();  /* Find new focus on current workspace */
+        focus_next();
     }
     
     if (ws == curws) {
-        /* Moving to visible workspace */
         XMapWindow(dpy, c->win);
         focus_client(c);
     }
@@ -740,16 +704,14 @@ unmanage(Window w) {
 
     int destroyed_idx = i;
     
-    /* Update workspace focus indices */
     for (int ws = 0; ws < NUM_WORKSPACES; ws++) {
         if (ws_focus_idx[ws] == destroyed_idx) {
-            ws_focus_idx[ws] = -1;  /* Focused window destroyed */
+            ws_focus_idx[ws] = -1;
         } else if (ws_focus_idx[ws] > destroyed_idx) {
-            ws_focus_idx[ws]--;     /* Array shifted down by one */
+            ws_focus_idx[ws]--;
         }
     }
 
-    /* Shift and realloc */
     for (; i < num_clients - 1; i++)
         clients[i] = clients[i + 1];
     num_clients--;
@@ -784,7 +746,7 @@ static int 
 xerror(Display *dpy, XErrorEvent *ee) {
     char buf[1024];
     XGetErrorText(dpy, ee->error_code, buf, sizeof(buf));
-    fprintf(stderr, "bxwm: X error: %s\n", buf);
+    logmsg("X error: %s", buf);
     return 0;
 }
 
@@ -830,7 +792,6 @@ update_workarea(void) {
     unsigned char *data = NULL;
 
     for (i = 0; i < num_clients; i++) {
-        /* Try _NET_WM_STRUT_PARTIAL (12 CARDINALs) */
         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) {
@@ -845,7 +806,7 @@ update_workarea(void) {
             data = NULL;
             continue;
         }
-        /* Fall back to _NET_WM_STRUT (4 CARDINALs) */
+
         if (XGetWindowProperty(dpy, clients[i].win, net_wm_strut,
                 0, 4, False, XA_CARDINAL, &actual_type, &actual_format,
                 &nitems, &bytes_after, &data) == Success && data) {
@@ -865,7 +826,6 @@ update_workarea(void) {
     wa_w = screen_w - left - right;
     wa_h = screen_h - top - bottom;
 
-    /* Set _NET_WORKAREA (4 values per desktop) */
     long *workareas = calloc(NUM_WORKSPACES * 4, sizeof(long));
     for (i = 0; i < NUM_WORKSPACES; i++) {
         workareas[i * 4 + 0] = wa_x;
@@ -892,9 +852,8 @@ handle_socket_command(int server_fd)
     
     if (read(client_fd, buffer, sizeof(buffer) - 1) > 0) {
         buffer[strcspn(buffer, "\n")] = '\0';
-        fprintf(stderr, "bxwm: socket received '%s'\n", buffer);
+        logmsg("socket received '%s'", buffer);
 
-        // Map command strings to functions
         if (strcmp(buffer, "center_window") == 0) {
             center_window(focused_client);
         } else if (strcmp(buffer, "left_half") == 0) {
@@ -936,7 +895,6 @@ cleanup(int status) {
     }
     unlink(socket_path);
     close(server_fd);
-    fprintf(stderr, "bxwm: exit\n");
     exit(status);
 }