Commit Diff


commit - 35aad0741352b1d223abe9dca6d9d4120db65631
commit + f7cc10d779f671cfc3ac8d06a30c6f44daf41265
blob - cd57322cda2169668c5ee8d16806e396151c9287
blob + a6b088a6ca740ad6618e2faadc3302e9bf0aa1c0
--- bxwm.c
+++ bxwm.c
@@ -1,6 +1,6 @@
 /*
  * bxwm
- * A very basic X window manager, a.k.a. Brett's X window manager.
+ * A very basic X window manager.
  * See LICENSE.md and README.md for details.
  */
 
@@ -54,6 +54,8 @@ static Atom net_client_list, net_active_window, net_wm
 static Atom net_wm_strut_partial, net_wm_strut, net_workarea;
 static Atom net_wm_window_type, net_wm_window_type_dock;
 static Atom wm_protocols, wm_delete_window;
+static Window *or_wins = NULL;
+static unsigned int num_or = 0;
 
 /* Forward Declarations */
 /* Utilities */
@@ -72,6 +74,9 @@ static void arrange(void);
 static void manage(Window w);
 static void unmanage(Window w);
 static void focus_client(Client *c);
+static void restack_overrides(void);
+static void or_add(Window w);
+static void or_remove(Window w);
 static void center_window(Client *c);
 static void left_half_window(Client *c);
 static void right_half_window(Client *c);
@@ -121,7 +126,11 @@ main(int argc, char *argv[])
                 XNextEvent(dpy, &ev);
                 if (ev.type == MapRequest) {
                     manage(ev.xmaprequest.window);
+                } else if (ev.type == CreateNotify) {
+                if (ev.xcreatewindow.override_redirect)
+                or_add(ev.xcreatewindow.window);
                 } else if (ev.type == DestroyNotify) {
+                    or_remove(ev.xdestroywindow.window);
                     unmanage(ev.xdestroywindow.window);
                 } else if (ev.type == PropertyNotify) {
                     if (ev.xproperty.atom == net_wm_strut_partial) {
@@ -407,6 +416,7 @@ arrange(void) {
             }
         }
     }
+    restack_overrides();
 }
 
 static void 
@@ -422,6 +432,11 @@ manage(Window w) {
     if (!XGetWindowAttributes(dpy, w, &wa))
         return;
 
+    if (wa.override_redirect) {
+        XMapWindow(dpy, w);
+        return;
+    }
+
     int is_dock = 0;
     Atom actual_type;
     int actual_format;
@@ -555,6 +570,7 @@ focus_client(Client *c) {
         XSetWindowBorder(dpy, c->win, focus_pixel);
         XSetInputFocus(dpy, c->win, RevertToParent, CurrentTime);
         XRaiseWindow(dpy, c->win);
+        restack_overrides();
         long active = c->win;
         XChangeProperty(dpy, root, net_active_window, XA_WINDOW, 32,
                         PropModeReplace, (unsigned char *)&active, 1);
@@ -563,6 +579,45 @@ focus_client(Client *c) {
     }
 }
 
+static void
+restack_overrides(void)
+{
+    for (unsigned int i = 0; i < num_or; i++)
+        XRaiseWindow(dpy, or_wins[i]);
+}
+
+static void
+or_add(Window w)
+{
+    or_wins = realloc(or_wins, (num_or + 1) * sizeof(Window));
+    if (!or_wins) {
+        fprintf(stderr, "bxwm: realloc failed\n");
+        return;
+    }
+    or_wins[num_or++] = w;
+}
+
+static void
+or_remove(Window w)
+{
+    unsigned int i;
+
+    for (i = 0; i < num_or; i++) {
+        if (or_wins[i] == w) {
+            for (; i < num_or - 1; i++)
+                or_wins[i] = or_wins[i + 1];
+            num_or--;
+            if (num_or)
+                or_wins = realloc(or_wins, num_or * sizeof(Window));
+            else {
+                free(or_wins);
+                or_wins = NULL;
+            }
+            return;
+        }
+    }
+}
+
 static void 
 center_window(Client *c) {
     unsigned int win_w = (wa_w / 2) - (2 * BORDER_WIDTH);