JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Convert XGetWMNormalHints to XCB. Also fix a bug masking to the wrong value (I think)
[spectrwm.git] / spectrwm.c
index 0e76488..53aaba2 100644 (file)
@@ -136,7 +136,7 @@ static const char   *buildstr = SPECTRWM_VERSION;
 #define xcb_icccm_get_wm_transient_for_reply   xcb_get_wm_transient_for_reply
 #endif
 
-/*#define SWM_DEBUG*/
+#define SWM_DEBUG
 #ifdef SWM_DEBUG
 #define DPRINTF(x...)          do { if (swm_debug) fprintf(stderr, x); } while (0)
 #define DNPRINTF(n,x...)       do { if (swm_debug & n) fprintf(stderr, x); } while (0)
@@ -194,13 +194,13 @@ u_int32_t         swm_debug = 0
 #define BORDER(w)              (w->bordered ? border_width : 0)
 #define MAX_X(r)               ((r)->g.x + (r)->g.w)
 #define MAX_Y(r)               ((r)->g.y + (r)->g.h)
-#define SH_MIN(w)              (w)->sh_mask & PMinSize
+#define SH_MIN(w)              (w)->sh.flags & XCB_SIZE_HINT_P_MIN_SIZE
 #define SH_MIN_W(w)            (w)->sh.min_width
 #define SH_MIN_H(w)            (w)->sh.min_height
-#define SH_MAX(w)              (w)->sh_mask & PMaxSize
+#define SH_MAX(w)              (w)->sh.flags & XCB_SIZE_HINT_P_MAX_SIZE
 #define SH_MAX_W(w)            (w)->sh.max_width
 #define SH_MAX_H(w)            (w)->sh.max_height
-#define SH_INC(w)              (w)->sh_mask & PResizeInc
+#define SH_INC(w)              (w)->sh.flags & XCB_SIZE_HINT_P_RESIZE_INC
 #define SH_INC_W(w)            (w)->sh.width_inc
 #define SH_INC_H(w)            (w)->sh.height_inc
 #define SWM_MAX_FONT_STEPS     (3)
@@ -387,10 +387,9 @@ struct ws_win {
        unsigned long           quirks;
        struct workspace        *ws;    /* always valid */
        struct swm_screen       *s;     /* always valid, never changes */
-       XWindowAttributes       wa;
-       XSizeHints              sh;
-       long                    sh_mask;
-       XClassHint              ch;
+       xcb_get_geometry_reply_t        *wa;
+       xcb_size_hints_t        sh;
+       xcb_get_wm_class_reply_t        ch;
        xcb_wm_hints_t          hints;
 };
 TAILQ_HEAD(ws_win_list, ws_win);
@@ -1518,8 +1517,8 @@ bar_class_name(char *s, size_t sz, struct swm_region *r)
 {
        if (r == NULL || r->ws == NULL || r->ws->focus == NULL)
                return;
-       if (r->ws->focus->ch.res_class != NULL)
-               strlcat(s, r->ws->focus->ch.res_class, sz);
+       if (r->ws->focus->ch.class_name != NULL)
+               strlcat(s, r->ws->focus->ch.class_name, sz);
 }
 
 void
@@ -1527,8 +1526,8 @@ bar_title_name(char *s, size_t sz, struct swm_region *r)
 {
        if (r == NULL || r->ws == NULL || r->ws->focus == NULL)
                return;
-       if (r->ws->focus->ch.res_name != NULL)
-               strlcat(s, r->ws->focus->ch.res_name, sz);
+       if (r->ws->focus->ch.instance_name != NULL)
+               strlcat(s, r->ws->focus->ch.instance_name, sz);
 }
 
 void
@@ -2147,10 +2146,10 @@ config_win(struct ws_win *win, XConfigureRequestEvent  *ev)
                ce.window = ev->window;
 
                /* make response appear more WM_SIZE_HINTS-compliant */
-               if (win->sh_mask)
+               if (win->sh.flags)
                        DNPRINTF(SWM_D_MISC, "config_win: hints: window: 0x%x,"
-                           " sh_mask: %ld, min: %d x %d, max: %d x %d, inc: "
-                           "%d x %d\n", win->id, win->sh_mask, SH_MIN_W(win),
+                           " sh.flags: %u, min: %d x %d, max: %d x %d, inc: "
+                           "%d x %d\n", win->id, win->sh.flags, SH_MIN_W(win),
                            SH_MIN_H(win), SH_MAX_W(win), SH_MAX_H(win),
                            SH_INC_W(win), SH_INC_H(win));
 
@@ -3778,14 +3777,15 @@ get_win_name(xcb_window_t win)
 
        c = xcb_icccm_get_wm_name(conn, win);
        if (xcb_icccm_get_wm_name_reply(conn, c, &r, NULL)) {
-               name = malloc(r.name_len + 1);
-               if (!name) {
-                       xcb_get_text_property_reply_wipe(&r);
-                       return (NULL);
+               if (r.name_len > 0) {
+                       name = malloc(r.name_len + 1);
+                       if (!name) {
+                               xcb_get_text_property_reply_wipe(&r);
+                               return (NULL);
+                       }
+                       memcpy(name, r.name, r.name_len);
+                       name[r.name_len] = '\0';
                }
-               memcpy(name, r.name, r.name_len);
-               name[r.name_len] = '\0';
-               
                xcb_get_text_property_reply_wipe(&r);
        }
 
@@ -6320,7 +6320,7 @@ set_child_transient(struct ws_win *win, xcb_window_t *trans)
                DNPRINTF(SWM_D_MISC, "set_child_transient: parent doesn't exist"
                    " for 0x%x trans 0x%x\n", win->id, win->transient);
 
-               r = root_to_region(win->wa.root);
+               r = root_to_region(win->wa->root);
                ws = r->ws;
                /* parent doen't exist in our window list */
                TAILQ_FOREACH(w, &ws->winlist, entry) {
@@ -6394,6 +6394,7 @@ manage_window(xcb_window_t id)
        int                     i, ws_idx, border_me = 0;
        xcb_atom_t              ws_idx_atom = XCB_ATOM_NONE;
        char                    ws_idx_str[SWM_PROPLEN], *prop = NULL;
+       size_t                  proplen;
        struct swm_region       *r;
        const char              *errstr;
        struct pid_e            *p;
@@ -6449,24 +6450,32 @@ manage_window(xcb_window_t id)
 
        /* Get all the window data in one shot */
        ws_idx_atom = get_atom_from_string("_SWM_WS");
+       fprintf(stderr, "ws_idx_atom: %d\n", ws_idx_atom);
        if (ws_idx_atom) {
                gpr = xcb_get_property_reply(conn,
                        xcb_get_property(conn, False, id, ws_idx_atom,
                                XCB_ATOM_STRING, 0, SWM_PROPLEN),
                        NULL);
                if (gpr) {
-                       prop = malloc(xcb_get_property_value_length(gpr) + 1);
-                       if (prop) {
-                               memcpy(prop, xcb_get_property_value(gpr),
-                                       xcb_get_property_value_length(gpr));
-                               prop[xcb_get_property_value_length(gpr)] = '\0';
+                       proplen = xcb_get_property_value_length(gpr);
+                       if (proplen > 0) {
+                               prop = malloc(proplen + 1);
+                               if (prop) {
+                                       memcpy(prop,
+                                           xcb_get_property_value(gpr),
+                                           proplen);   
+                                       prop[proplen] = '\0';
+                               }
                        }
                        free(gpr);
                }
-               
        }
-       XGetWindowAttributes(display, id, &win->wa);
-       XGetWMNormalHints(display, id, &win->sh, &win->sh_mask);
+       win->wa = xcb_get_geometry_reply(conn,
+               xcb_get_geometry(conn, id),
+               NULL);  
+       xcb_get_wm_normal_hints_reply(conn,
+               xcb_get_wm_normal_hints(conn, id),
+               &win->sh, NULL);
        xcb_icccm_get_wm_hints_reply(conn,
                xcb_icccm_get_wm_hints(conn, id),
                &win->hints, NULL);
@@ -6504,7 +6513,7 @@ manage_window(xcb_window_t id)
         * a workspace (either by spawn() or manually moving), and isn't
         * transient, * put it in the same workspace
         */
-       r = root_to_region(win->wa.root);
+       r = root_to_region(win->wa->root);
        if (p) {
                ws = &r->s->ws[p->ws];
                TAILQ_REMOVE(&pidlist, p, entry);
@@ -6558,10 +6567,10 @@ manage_window(xcb_window_t id)
        }
 
        /* ignore window border if there is one. */
-       WIDTH(win) = win->wa.width;
-       HEIGHT(win) = win->wa.height;
-       X(win) = win->wa.x + win->wa.border_width;
-       Y(win) = win->wa.y + win->wa.border_width;
+       WIDTH(win) = win->wa->width;
+       HEIGHT(win) = win->wa->height;
+       X(win) = win->wa->x + win->wa->border_width;
+       Y(win) = win->wa->y + win->wa->border_width;
        win->bordered = 0;
        win->g_floatvalid = 0;
        win->floatmaxed = 0;
@@ -6588,22 +6597,24 @@ manage_window(xcb_window_t id)
 
        ewmh_autoquirk(win);
 
-       if (XGetClassHint(display, win->id, &win->ch)) {
+       if (xcb_get_wm_class_reply(conn,
+                       xcb_get_wm_class(conn, win->id),
+                       &win->ch, NULL)) {
                DNPRINTF(SWM_D_CLASS, "manage_window: class: %s, name: %s\n",
-                   win->ch.res_class, win->ch.res_name);
+                   win->ch.class_name, win->ch.instance_name);
 
                /* java is retarded so treat it special */
-               if (strstr(win->ch.res_name, "sun-awt")) {
+               if (strstr(win->ch.instance_name, "sun-awt")) {
                        win->java = 1;
                        border_me = 1;
                }
 
                TAILQ_FOREACH(qp, &quirks, entry) {
-                       if (!strcmp(win->ch.res_class, qp->class) &&
-                           !strcmp(win->ch.res_name, qp->name)) {
+                       if (!strcmp(win->ch.class_name, qp->class) &&
+                           !strcmp(win->ch.instance_name, qp->name)) {
                                DNPRINTF(SWM_D_CLASS, "manage_window: found: "
-                                   "class: %s, name: %s\n", win->ch.res_class,
-                                   win->ch.res_name);
+                                   "class: %s, name: %s\n", win->ch.class_name,
+                                   win->ch.instance_name);
                                if (qp->quirk & SWM_Q_FLOAT) {
                                        win->floating = 1;
                                        border_me = 1;
@@ -6669,10 +6680,10 @@ free_window(struct ws_win *win)
 
        TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry);
 
-       if (win->ch.res_class)
-               XFree(win->ch.res_class);
-       if (win->ch.res_name)
-               XFree(win->ch.res_name);
+       if (win->wa)
+               free(win->wa);
+       
+       xcb_get_wm_class_reply_wipe(&win->ch);
 
        kill_refs(win);
 
@@ -6823,7 +6834,7 @@ configurerequest(XEvent *e)
 
                XConfigureWindow(display, ev->window, ev->value_mask, &wc);
        } else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) &&
-           !(win->sh_mask & EWMH_F_FULLSCREEN)) {
+           !(win->ewmh_flags & EWMH_F_FULLSCREEN)) {
                win->g_float.x = ev->x - X(win->ws->r);
                win->g_float.y = ev->y - Y(win->ws->r);
                win->g_float.w = ev->width;
@@ -6853,7 +6864,9 @@ configurenotify(XEvent *e)
 
        win = find_window(e->xconfigure.window);
        if (win) {
-               XGetWMNormalHints(display, win->id, &win->sh, &win->sh_mask);
+               xcb_get_wm_normal_hints_reply(conn,
+                       xcb_get_wm_normal_hints(conn, win->id),
+                       &win->sh, NULL);
                adjust_font(win);
                if (font_adjusted)
                        stack();
@@ -7111,7 +7124,7 @@ maprequest(XEvent *e)
        stack();
 
        /* make new win focused */
-       r = root_to_region(win->wa.root);
+       r = root_to_region(win->wa->root);
        if (win->ws == r->ws)
                focus_magic(win);
 }
@@ -7122,11 +7135,30 @@ propertynotify(XEvent *e)
        struct ws_win           *win;
        XPropertyEvent          *ev = &e->xproperty;
 #ifdef SWM_DEBUG
-       char                    *name;
-       name = XGetAtomName(display, ev->atom);
-       DNPRINTF(SWM_D_EVENT, "propertynotify: window: 0x%lx, atom: %s\n",
-           ev->window, name);
-       XFree(name);
+       char                            *name;
+       size_t                          len;
+       xcb_get_atom_name_reply_t       *r;
+
+       r = xcb_get_atom_name_reply(conn,
+               xcb_get_atom_name(conn, ev->atom),
+               NULL);
+       if (r) {
+               len = xcb_get_atom_name_name_length(r);
+               if (len > 0) {
+                       name = malloc(len + 1);
+                       if (name) {
+                               memcpy(name, xcb_get_atom_name_name(r), len);
+                               name[len] = '\0';
+                               
+                               DNPRINTF(SWM_D_EVENT,
+                                       "propertynotify: window: 0x%lx, "
+                                       "atom: %s\n",
+                                       ev->window, name);
+                               free(name);
+                       }
+               }
+               free(r);
+       }
 #endif
 
        win = find_window(ev->window);
@@ -7147,7 +7179,7 @@ propertynotify(XEvent *e)
                long            mask;
                XGetWMNormalHints(display, win->id, &win->sh, &mask);
                warnx("normal hints: flag 0x%x", win->sh.flags);
-               if (win->sh.flags & PMinSize) {
+               if (win->sh.flags & XCB_SIZE_HINT_P_MIN_SIZE) {
                        WIDTH(win) = win->sh.min_width;
                        HEIGHT(win) = win->sh.min_height;
                        warnx("min %d %d", WIDTH(win), HEIGHT(win));