X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=ef20ce07bc6d93cd1a89fd811f1c45e8897b7e2f;hb=a261181f039ffb676413787097afee615f371099;hp=83d1bfac9966812199c7b883b43da0ca145facc3;hpb=e33b66766fa2abe825742dc891385468d7f3ab37;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 83d1bfa..ef20ce0 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -91,6 +91,8 @@ #include #include #include +#include +#include #include #include #include @@ -201,15 +203,15 @@ u_int32_t swm_debug = 0 #endif char **start_argv; -Atom astate; -Atom aprot; -Atom adelete; -Atom takefocus; -Atom a_wmname; -Atom a_netwmname; -Atom a_utf8_string; -Atom a_string; -Atom a_swm_iconic; +xcb_atom_t astate; +xcb_atom_t aprot; +xcb_atom_t adelete; +xcb_atom_t takefocus; +xcb_atom_t a_wmname; +xcb_atom_t a_netwmname; +xcb_atom_t a_utf8_string; +xcb_atom_t a_string; +xcb_atom_t a_swm_iconic; volatile sig_atomic_t running = 1; volatile sig_atomic_t restart_wm = 0; int outputs = 0; @@ -242,7 +244,7 @@ struct search_window { int idx; struct ws_win *win; GC gc; - Window indicator; + xcb_window_t indicator; }; TAILQ_HEAD(search_winlist, search_window); struct search_winlist search_wl; @@ -404,12 +406,12 @@ void fancy_stacker(struct workspace *); struct ws_win *find_window(xcb_window_t); -void grabbuttons(struct ws_win *, int); -void new_region(struct swm_screen *, int, int, int, int); -void unmanage_window(struct ws_win *); -long getstate(xcb_window_t); +void grabbuttons(struct ws_win *, int); +void new_region(struct swm_screen *, int, int, int, int); +void unmanage_window(struct ws_win *); +uint16_t getstate(xcb_window_t); -int conf_load(char *, int); +int conf_load(char *, int); struct layout { void (*l_stack)(struct workspace *, struct swm_geometry *); @@ -484,7 +486,7 @@ struct swm_screen { /* colors */ struct { - unsigned long color; + uint32_t color; char *name; } c[SWM_S_COLOR_MAX]; @@ -623,6 +625,39 @@ void constrain_window(struct ws_win *, struct swm_region *, int); void update_window(struct ws_win *); void spawn_select(struct swm_region *, union arg *, char *, int *); unsigned char *get_win_name(xcb_window_t); +xcb_atom_t get_atom_from_string(const char *); +void map_window_raised(xcb_window_t); + +void +map_window_raised(xcb_window_t win) +{ + uint32_t val = XCB_STACK_MODE_ABOVE; + + xcb_configure_window(conn, win, + XCB_CONFIG_WINDOW_STACK_MODE, &val); + + xcb_map_window(conn, win); + xcb_flush(conn); +} + +xcb_atom_t +get_atom_from_string(const char *str) +{ + xcb_intern_atom_cookie_t c; + xcb_intern_atom_reply_t *r; + xcb_atom_t atom; + + c = xcb_intern_atom(conn, False, strlen(str), str); + r = xcb_intern_atom_reply(conn, c, NULL); + if (r) { + atom = r->atom; + free(r); + + return (atom); + } + + return (XCB_ATOM_NONE); +} int get_property(Window id, Atom atom, long count, Atom type, unsigned long *nitems, @@ -652,17 +687,11 @@ update_iconic(struct ws_win *win, int newv) { int32_t v = newv; xcb_atom_t iprop; - xcb_intern_atom_cookie_t c; - xcb_intern_atom_reply_t *r; win->iconic = newv; - c = xcb_intern_atom(conn, False, strlen("_SWM_ICONIC"), "_SWM_ICONIC"); - r = xcb_intern_atom_reply(conn, c, NULL); - if (r) { - iprop = r->atom; - free(r); - } else + iprop = get_atom_from_string("_SWM_ICONIC"); + if (iprop == XCB_ATOM_NONE) return; if (newv) @@ -677,17 +706,11 @@ get_iconic(struct ws_win *win) { int32_t v = 0, *vtmp; xcb_atom_t iprop; - xcb_intern_atom_cookie_t c; - xcb_intern_atom_reply_t *r; xcb_get_property_cookie_t pc; xcb_get_property_reply_t *pr; - c = xcb_intern_atom(conn, False, strlen("_SWM_ICONIC"), "_SWM_ICONIC"); - r = xcb_intern_atom_reply(conn, c, NULL); - if (r) { - iprop = r->atom; - free(r); - } else + iprop = get_atom_from_string("_SWM_ICONIC"); + if (iprop == XCB_ATOM_NONE) goto out; pc = xcb_get_property(conn, False, win->id, iprop, XCB_ATOM_INTEGER, @@ -709,27 +732,12 @@ void setup_ewmh(void) { xcb_atom_t sup_list; - xcb_intern_atom_cookie_t c; - xcb_intern_atom_reply_t *r; int i, j, num_screens; - c = xcb_intern_atom(conn, False, strlen("_NET_SUPPORTED"), - "_NET_SUPPORTED"); - r = xcb_intern_atom_reply(conn, c, NULL); - if (r) { - sup_list = r->atom; - free(r); - } + sup_list = get_atom_from_string("_NET_SUPPORTED"); - for (i = 0; i < LENGTH(ewmh); i++) { - c = xcb_intern_atom(conn, False, strlen(ewmh[i].name), - ewmh[i].name); - r = xcb_intern_atom_reply(conn, c, NULL); - if (r) { - ewmh[i].atom = r->atom; - free(r); - } - } + for (i = 0; i < LENGTH(ewmh); i++) + ewmh[i].atom = get_atom_from_string(ewmh[i].name); num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) { @@ -747,31 +755,16 @@ setup_ewmh(void) void teardown_ewmh(void) { - int i, num_screens; - xcb_atom_t sup_check, sup_list; - xcb_window_t id; - - xcb_intern_atom_cookie_t c; - xcb_intern_atom_reply_t *r; + int i, num_screens; + xcb_atom_t sup_check, sup_list; + xcb_window_t id; xcb_get_property_cookie_t pc; xcb_get_property_reply_t *pr; - c = xcb_intern_atom(conn, False, strlen("_NET_SUPPORTING_WM_CHECK"), - "_NET_SUPPORTING_WM_CHECK"); - r = xcb_intern_atom_reply(conn, c, NULL); - if (r) { - sup_check = r->atom; - free(r); - } - c = xcb_intern_atom(conn, False, strlen("_NET_SUPPORTED"), - "_NET_SUPPORTED"); - r = xcb_intern_atom_reply(conn, c, NULL); - if (r) { - sup_list = r->atom; - free(r); - } - + sup_check = get_atom_from_string("_NET_SUPPORTING_WM_CHECK"); + sup_list = get_atom_from_string("_NET_SUPPORTED"); num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); + for (i = 0; i < num_screens; i++) { /* Get the support check window and destroy it */ pc = xcb_get_property(conn, False, screens[i].root, sup_check, @@ -792,20 +785,22 @@ teardown_ewmh(void) void ewmh_autoquirk(struct ws_win *win) { - int success, i; - unsigned long *data = NULL, n; - Atom type; + int i; + unsigned long n; + xcb_atom_t type; - success = get_property(win->id, ewmh[_NET_WM_WINDOW_TYPE].atom, (~0L), - XA_ATOM, &n, NULL, (void *)&data); + xcb_get_property_cookie_t c; + xcb_get_property_reply_t *r; - if (!success) { - XFree(data); + c = xcb_get_property(conn, False, win->id, + ewmh[_NET_WM_WINDOW_TYPE].atom, XCB_ATOM_ATOM, 0, (~0L)); + r = xcb_get_property_reply(conn, c, NULL); + if (!r) return; - } + n = xcb_get_property_value_length(r); for (i = 0; i < n; i++) { - type = data[i]; + type = *((xcb_atom_t *)xcb_get_property_value(r)); if (type == ewmh[_NET_WM_WINDOW_TYPE_NORMAL].atom) break; if (type == ewmh[_NET_WM_WINDOW_TYPE_DOCK].atom || @@ -822,8 +817,7 @@ ewmh_autoquirk(struct ws_win *win) break; } } - - XFree(data); + free(r); } #define SWM_EWMH_ACTION_COUNT_MAX (6) @@ -1129,9 +1123,10 @@ xrandr_geteventname(XEvent *e) void dumpwins(struct swm_region *r, union arg *args) { - struct ws_win *win; - unsigned int state; - XWindowAttributes wa; + struct ws_win *win; + uint16_t state; + xcb_get_window_attributes_cookie_t c; + xcb_get_window_attributes_reply_t *r; if (r->ws == NULL) { warnx("dumpwins: invalid workspace"); @@ -1139,26 +1134,33 @@ dumpwins(struct swm_region *r, union arg *args) } warnx("=== managed window list ws %02d ===", r->ws->idx); - TAILQ_FOREACH(win, &r->ws->winlist, entry) { state = getstate(win->id); - if (!XGetWindowAttributes(display, win->id, &wa)) - warnx("window: 0x%lx, failed XGetWindowAttributes", + c = xcb_get_window_attributes(conn, win->id); + r = xcb_get_window_attributes_reply(conn, c, NULL); + if (r) { + warnx("window: 0x%x, map_state: %d, state: %u, " + "transient: 0x%x", win->id, wa.map_state, + state, win->transient); + free(r); + } else + warnx("window: 0x%x, failed xcb_get_window_attributes", win->id); - warnx("window: 0x%lx, map_state: %d, state: %d, " - "transient: 0x%lx", win->id, wa.map_state, state, - win->transient); } warnx("===== unmanaged window list ====="); TAILQ_FOREACH(win, &r->ws->unmanagedlist, entry) { state = getstate(win->id); - if (!XGetWindowAttributes(display, win->id, &wa)) + c = xcb_get_window_attributes(conn, win->id); + r xcb_get_window_attributes_reply(conn, c, NULL); + if (r) { + warnx("window: 0x%lx, map_state: %d, state: %u, " + "transient: 0x%lx", win->id, wa.map_state, + state, win->transient); + free(r); + } else warnx("window: 0x%lx, failed XGetWindowAttributes", win->id); - warnx("window: 0x%lx, map_state: %d, state: %d, " - "transient: 0x%lx", win->id, wa.map_state, state, - win->transient); } warnx("================================="); @@ -1430,8 +1432,8 @@ bar_print(struct swm_region *r, const char *s) XSetForeground(display, r->s->bar_gc, r->s->c[SWM_S_COLOR_BAR_FONT].color); DRAWSTRING(display, r->bar->buffer, bar_fs, r->s->bar_gc, - x, (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - - lbox.y, s, len); + x, (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - + lbox.y, s, len); /* blt */ XCopyArea(display, r->bar->buffer, r->bar->id, r->s->bar_gc, 0, 0, @@ -1509,10 +1511,11 @@ int urgent[SWM_WS_MAX]; void bar_urgent(char *s, size_t sz) { - XWMHints *wmh = NULL; struct ws_win *win; int i, j, num_screens; char b[8]; + xcb_get_property_cookie_t c; + xcb_wm_hints_t hints; for (i = 0; i < workspace_limit; i++) urgent[i] = 0; @@ -1521,13 +1524,12 @@ bar_urgent(char *s, size_t sz) for (i = 0; i < num_screens; i++) for (j = 0; j < workspace_limit; j++) TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry) { - wmh = XGetWMHints(display, win->id); - if (wmh == NULL) + c = xcb_get_wm_hints(conn, win->id); + if (xcb_get_wm_hints_reply(conn, c, + &hints, NULL) == 0) continue; - - if (wmh->flags & XUrgencyHint) + if (hints.flags & XCB_WM_HINT_X_URGENCY) urgent[j] = 1; - XFree(wmh); } for (i = 0; i < workspace_limit; i++) { @@ -1824,12 +1826,12 @@ bar_toggle(struct swm_region *r, union arg *args) for (i = 0; i < num_screens; i++) TAILQ_FOREACH(tmpr, &screens[i].rl, entry) if (tmpr->bar) - XUnmapWindow(display, tmpr->bar->id); + xcb_unmap_window(conn, tmpr->bar->id); } else { for (i = 0; i < num_screens; i++) TAILQ_FOREACH(tmpr, &screens[i].rl, entry) if (tmpr->bar) - XMapRaised(display, tmpr->bar->id); + map_window_raised(tmpr->bar->id); } bar_enabled = !bar_enabled; @@ -1948,10 +1950,11 @@ bar_setup(struct swm_region *r) r->bar->buffer = XCreatePixmap(display, r->bar->id, WIDTH(r->bar), HEIGHT(r->bar), DefaultDepth(display, r->s->idx)); - XSelectInput(display, r->bar->id, VisibilityChangeMask); - + xcb_randr_select_input(conn, r->bar->id, + XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE); + if (bar_enabled) - XMapRaised(display, r->bar->id); + map_window_raised(r->bar->id); DNPRINTF(SWM_D_BAR, "bar_setup: window: 0x%lx, (x,y) w x h: (%d,%d) " "%d x %d\n", WINID(r->bar), X(r->bar), Y(r->bar), WIDTH(r->bar), @@ -1977,20 +1980,19 @@ void drain_enter_notify(void) { int i = 0; - XEvent cne; - while (XCheckMaskEvent(display, EnterWindowMask, &cne)) + while (xcb_poll_for_event(conn)) i++; DNPRINTF(SWM_D_EVENT, "drain_enter_notify: drained: %d\n", i); } void -set_win_state(struct ws_win *win, long state) +set_win_state(struct ws_win *win, uint16_t state) { - long data[] = {state, XCB_ATOM_NONE}; + uint16_t data[2] = { state, XCB_ATOM_NONE }; - DNPRINTF(SWM_D_EVENT, "set_win_state: window: 0x%lx\n", win->id); + DNPRINTF(SWM_D_EVENT, "set_win_state: window: 0x%x\n", win->id); if (win == NULL) return; @@ -1999,10 +2001,10 @@ set_win_state(struct ws_win *win, long state) astate, 32, 2, data); } -long +uint16_t getstate(xcb_window_t w) { - long result = -1; + uint16_t result = 0; xcb_get_property_cookie_t c; xcb_get_property_reply_t *r; @@ -2010,7 +2012,7 @@ getstate(xcb_window_t w) r = xcb_get_property_reply(conn, c, NULL); if (r) { - result = *((long *)xcb_get_property_value(r)); + result = *((uint16_t *)xcb_get_property_value(r)); free(r); } @@ -2030,21 +2032,23 @@ version(struct swm_region *r, union arg *args) } void -client_msg(struct ws_win *win, Atom a) +client_msg(struct ws_win *win, xcb_atom_t a) { - XClientMessageEvent cm; + xcb_client_message_event_t ev; if (win == NULL) return; - bzero(&cm, sizeof cm); - cm.type = ClientMessage; - cm.window = win->id; - cm.message_type = aprot; - cm.format = 32; - cm.data.l[0] = a; - cm.data.l[1] = CurrentTime; - XSendEvent(display, win->id, False, 0L, (XEvent *)&cm); + bzero(&ev, sizeof ev); + ev.response_type = XCB_CLIENT_MESSAGE; + ev.window = win->id; + ev.type = aprot; + ev.format = 32; + ev.data.data32[0] = a; + ev.data.data32[1] = XCB_CURRENT_TIME; + + xcb_send_event(conn, False, win->id, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); } /* synthetic response to a ConfigureRequest when not making a change */ @@ -2161,14 +2165,14 @@ unmap_window(struct ws_win *win) return; /* don't unmap again */ - if (getstate(win->id) == IconicState) + if (getstate(win->id) == XCB_WM_STATE_ICONIC) return; - set_win_state(win, IconicState); + set_win_state(win, XCB_WM_STATE_ICONIC); - XUnmapWindow(display, win->id); - XSetWindowBorder(display, win->id, - win->s->c[SWM_S_COLOR_UNFOCUS].color); + xcb_unmap_window(conn, win->id); + xcb_change_window_attributes(conn, win->id, + XCB_CW_BORDER_PIXEL, &win->s->c[SWM_S_COLOR_UNFOCUS].color); } void @@ -2234,29 +2238,32 @@ restart(struct swm_region *r, union arg *args) } struct swm_region * -root_to_region(Window root) +root_to_region(xcb_window_t root) { struct swm_region *r = NULL; - Window rr, cr; - int i, x, y, wx, wy, num_screens; - unsigned int mask; + int i, num_screens; + xcb_query_pointer_cookie_t qpc; + xcb_query_pointer_reply_t *qpr; - DNPRINTF(SWM_D_MISC, "root_to_region: window: 0x%lx\n", root); + DNPRINTF(SWM_D_MISC, "root_to_region: window: 0x%x\n", root); num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) if (screens[i].root == root) break; - if (XQueryPointer(display, screens[i].root, - &rr, &cr, &x, &y, &wx, &wy, &mask) != False) { + qpc = xcb_query_pointer(conn, screens[i].root); + qpr = xcb_query_pointer_reply(conn, qpc, NULL); + + if (qpr) { DNPRINTF(SWM_D_MISC, "root_to_region: pointer: (%d,%d)\n", - x, y); + qpr->root_x, qpr->root_y); /* choose a region based on pointer location */ TAILQ_FOREACH(r, &screens[i].rl, entry) - if (X(r) <= x && x < MAX_X(r) && - Y(r) <= y && y < MAX_Y(r)) + if (X(r) <= qpr->root_x && qpr->root_x < MAX_X(r) && + Y(r) <= qpr->root_y && qpr->root_y < MAX_Y(r)) break; + free(qpr); } if (r == NULL) @@ -2266,7 +2273,7 @@ root_to_region(Window root) } struct ws_win * -find_unmanaged_window(Window id) +find_unmanaged_window(xcb_window_t id) { struct ws_win *win; int i, j, num_screens; @@ -2285,9 +2292,9 @@ struct ws_win * find_window(xcb_window_t id) { struct ws_win *win; - Window wrr, wpr, *wcr = NULL; int i, j, num_screens; - unsigned int nc; + xcb_query_tree_cookie_t c; + xcb_query_tree_reply_t *r; num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) @@ -2296,23 +2303,25 @@ find_window(xcb_window_t id) if (id == win->id) return (win); - /* if we were looking for the parent return that window instead */ - if (XQueryTree(display, id, &wrr, &wpr, &wcr, &nc) == 0) + c = xcb_query_tree(conn, id); + r = xcb_query_tree_reply(conn, c, NULL); + if (!r) return (NULL); - if (wcr) - XFree(wcr); - /* ignore not found and root */ - if (wpr == 0 || wrr == wpr) + /* if we were looking for the parent return that window instead */ + if (r->parent == 0 || r->root == r->parent) return (NULL); /* look for parent */ for (i = 0; i < num_screens; i++) for (j = 0; j < workspace_limit; j++) TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry) - if (wpr == win->id) + if (r->parent == win->id) { + free(r); return (win); + } + free(r); return (NULL); } @@ -2325,7 +2334,7 @@ spawn(int ws_idx, union arg *args, int close_fd) DNPRINTF(SWM_D_MISC, "spawn: %s\n", args->argv[0]); if (display) - close(ConnectionNumber(display)); + close(xcb_get_file_descriptor(conn)); setenv("LD_PRELOAD", SWM_LIB, 1); @@ -2479,9 +2488,8 @@ unfocus_win(struct ws_win *win) ; grabbuttons(win, 0); - XSetWindowBorder(display, win->id, - win->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color); - + xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL, + &win->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root, ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, &none); @@ -2506,10 +2514,10 @@ void focus_win(struct ws_win *win) { XEvent cne; - Window cur_focus; - int rr; struct ws_win *cfw = NULL; - + xcb_get_input_focus_cookie_t c; + xcb_get_input_focus_reply_t *r; + xcb_window_t cur_focus = XCB_WINDOW_NONE; DNPRINTF(SWM_D_FOCUS, "focus_win: window: 0x%lx\n", WINID(win)); @@ -2531,15 +2539,21 @@ focus_win(struct ws_win *win) return; } - XGetInputFocus(display, &cur_focus, &rr); + c = xcb_get_input_focus(conn); + r = xcb_get_input_focus_reply(conn, c, NULL); + if (r) { + cur_focus = r->focus; + free(r); + } if ((cfw = find_window(cur_focus)) != NULL) unfocus_win(cfw); else { /* use larger hammer since the window was killed somehow */ TAILQ_FOREACH(cfw, &win->ws->winlist, entry) if (cfw->ws && cfw->ws->r && cfw->ws->r->s) - XSetWindowBorder(display, cfw->id, - cfw->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color); + xcb_change_window_attributes(conn, cfw->id, + XCB_CW_BORDER_PIXEL, + &cfw->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color); } win->ws->focus = win; @@ -2550,18 +2564,19 @@ focus_win(struct ws_win *win) ; if (win->java == 0) - XSetInputFocus(display, win->id, - RevertToParent, CurrentTime); + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, + win->id, XCB_CURRENT_TIME); grabbuttons(win, 1); - XSetWindowBorder(display, win->id, - win->ws->r->s->c[SWM_S_COLOR_FOCUS].color); + xcb_change_window_attributes(conn, win->id, + XCB_CW_BORDER_PIXEL, + &win->ws->r->s->c[SWM_S_COLOR_FOCUS].color); if (win->ws->cur_layout->flags & SWM_L_MAPONFOCUS || win->ws->always_raise) - XMapRaised(display, win->id); + map_window_raised(win->id); - XChangeProperty(display, win->s->root, - ewmh[_NET_ACTIVE_WINDOW].atom, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&win->id, 1); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root, + ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, + &win->id); } bar_update(); @@ -2718,7 +2733,8 @@ cyclescr(struct swm_region *r, union arg *args) /* move mouse to region */ x = X(rr) + 1; y = Y(rr) + 1 + (bar_enabled ? bar_height : 0); - XWarpPointer(display, None, rr->s[i].root, 0, 0, 0, 0, x, y); + xcb_warp_pointer(conn, XCB_WINDOW_NONE, rr->s[i].root, 0, 0, 0, 0, + x, y); a.id = SWM_ARG_ID_FOCUSCUR; focus(rr, &a); @@ -2727,7 +2743,8 @@ cyclescr(struct swm_region *r, union arg *args) /* move to focus window */ x = X(rr->ws->focus) + 1; y = Y(rr->ws->focus) + 1; - XWarpPointer(display, None, rr->s[i].root, 0, 0, 0, 0, x, y); + xcb_warp_pointer(conn, XCB_WINDOW_NONE, rr->s[i].root, 0, 0, 0, + 0, x, y); } } @@ -3388,7 +3405,7 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) if (XGetWindowAttributes(display, win->id, &wa)) if (wa.map_state == IsUnmapped) - XMapRaised(display, win->id); + map_window_raised(win->id); last_h = win_g.h; i++; @@ -3408,12 +3425,12 @@ notiles: } stack_floater(win, ws->r); - XMapRaised(display, win->id); + map_window_raised(win->id); } if (fs_win) { stack_floater(fs_win, ws->r); - XMapRaised(display, fs_win->id); + map_window_raised(fs_win->id); } } @@ -3575,7 +3592,7 @@ max_stack(struct workspace *ws, struct swm_geometry *g) /* put the last transient on top */ if (wintrans) { if (parent) - XMapRaised(display, parent->id); + map_window_raised(parent->id); stack_floater(wintrans, ws->r); focus_magic(wintrans); } @@ -3587,8 +3604,8 @@ send_to_ws(struct swm_region *r, union arg *args) int wsid = args->id; struct ws_win *win = NULL, *parent; struct workspace *ws, *nws; - Atom ws_idx_atom = 0; - unsigned char ws_idx_str[SWM_PROPLEN]; + xcb_atom_t ws_idx_atom = XCB_ATOM_NONE; + char ws_idx_str[SWM_PROPLEN]; union arg a; if (wsid >= workspace_limit) @@ -3627,14 +3644,15 @@ send_to_ws(struct swm_region *r, union arg *args) win->ws = nws; /* Try to update the window's workspace property */ - ws_idx_atom = XInternAtom(display, "_SWM_WS", False); + ws_idx_atom = get_atom_from_string("_SWM_WS"); if (ws_idx_atom && - snprintf((char *)ws_idx_str, SWM_PROPLEN, "%d", nws->idx) < + snprintf(ws_idx_str, SWM_PROPLEN, "%d", nws->idx) < SWM_PROPLEN) { DNPRINTF(SWM_D_PROP, "send_to_ws: set property: _SWM_WS: %s\n", ws_idx_str); - XChangeProperty(display, win->id, ws_idx_atom, XA_STRING, 8, - PropModeReplace, ws_idx_str, strlen((char *)ws_idx_str)); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, + ws_idx_atom, XCB_ATOM_STRING, 8, strlen(ws_idx_str), + ws_idx_str); } stack(); @@ -3810,7 +3828,7 @@ search_win_cleanup(void) struct search_window *sw = NULL; while ((sw = TAILQ_FIRST(&search_wl)) != NULL) { - XDestroyWindow(display, sw->indicator); + xcb_destroy_window(conn, sw->indicator); XFreeGC(display, sw->gc); TAILQ_REMOVE(&search_wl, sw, entry); free(sw); @@ -3822,8 +3840,8 @@ search_win(struct swm_region *r, union arg *args) { struct ws_win *win = NULL; struct search_window *sw = NULL; - Window w; - XGCValues gcv; + xcb_window_t w; + XGCValues gcv; int i; char s[8]; FILE *lfile; @@ -3872,9 +3890,9 @@ search_win(struct swm_region *r, union arg *args) TAILQ_INSERT_TAIL(&search_wl, sw, entry); sw->gc = XCreateGC(display, w, 0, &gcv); - XMapRaised(display, w); + map_window_raised(w); XSetForeground(display, sw->gc, r->s->c[SWM_S_COLOR_BAR].color); - + DRAWSTRING(display, w, bar_fs, sw->gc, 2, (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - lbox.y, s, len); @@ -4072,7 +4090,7 @@ wkill(struct swm_region *r, union arg *args) return; if (args->id == SWM_ARG_ID_KILLWINDOW) - XKillClient(display, r->ws->focus->id); + xcb_kill_client(conn, r->ws->focus->id); else if (r->ws->focus->can_delete) client_msg(r->ws->focus, adelete); @@ -4371,7 +4389,7 @@ resize(struct ws_win *win, union arg *args) } store_float_geom(win,r); - XUngrabPointer(display, CurrentTime); + xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); XFreeCursor(display, cursor); /* drain events */ @@ -4496,7 +4514,7 @@ move(struct ws_win *win, union arg *args) update_window(win); } store_float_geom(win, r); - XUngrabPointer(display, CurrentTime); + xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); /* drain events */ drain_enter_notify(); @@ -6223,22 +6241,16 @@ set_child_transient(struct ws_win *win, Window *trans) } long -window_get_pid(Window win) +window_get_pid(xcb_window_t win) { long ret = 0; const char *errstr; xcb_atom_t apid; - xcb_intern_atom_cookie_t c; - xcb_intern_atom_reply_t *r; xcb_get_property_cookie_t pc; - xcb_get_property_reply_t *pr; + xcb_get_property_reply_t *pr; - c = xcb_intern_atom(conn, False, strlen("_NET_WM_PID"), "_NET_WM_PID"); - r = xcb_intern_atom_reply(conn, c, NULL); - if (r) { - apid = r->atom; - free(r); - } else + apid = get_atom_from_string("_NET_WM_PID"); + if (apid == XCB_ATOM_NONE) goto tryharder; pc = xcb_get_property(conn, False, win, apid, XCB_ATOM_CARDINAL, 0, 1); @@ -6254,12 +6266,7 @@ window_get_pid(Window win) return (ret); tryharder: - c = xcb_intern_atom(conn, False, strlen("_SWM_PID"), "_SWM_PID"); - r = xcb_intern_atom_reply(conn, c, NULL); - if (r) { - apid = r->atom; - free(r); - } + apid = get_atom_from_string("_SWM_PID"); pc = xcb_get_property(conn, False, win, apid, XCB_ATOM_STRING, 0, SWM_PROPLEN); pr = xcb_get_property_reply(conn, pc, NULL); @@ -6275,7 +6282,7 @@ tryharder: } struct ws_win * -manage_window(Window id) +manage_window(xcb_window_t id) { Window trans = 0; struct workspace *ws; @@ -6289,7 +6296,8 @@ manage_window(Window id) const char *errstr; struct pid_e *p; struct quirk *qp; - + uint32_t event_mask; + if ((win = find_window(id)) != NULL) return (win); /* already being managed */ @@ -6508,12 +6516,15 @@ manage_window(Window id) update_window(win); } - XSelectInput(display, id, EnterWindowMask | FocusChangeMask | - PropertyChangeMask | StructureNotifyMask); + event_mask = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY; + xcb_change_window_attributes(conn, id, XCB_CW_EVENT_MASK, &event_mask); + /* floaters need to be mapped if they are in the current workspace */ if ((win->floating || win->transient) && (ws->idx == r->ws->idx)) - XMapRaised(display, win->id); + map_window_raised(win->id); return (win); } @@ -6527,7 +6538,7 @@ free_window(struct ws_win *win) return; /* needed for restart wm */ - set_win_state(win, WithdrawnState); + set_win_state(win, XCB_WM_STATE_WITHDRAWN); TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry); @@ -6548,6 +6559,7 @@ void unmanage_window(struct ws_win *win) { struct ws_win *parent; + xcb_screen_t *screen; if (win == NULL) return; @@ -6561,8 +6573,10 @@ unmanage_window(struct ws_win *win) } /* focus on root just in case */ - XSetInputFocus(display, PointerRoot, PointerRoot, CurrentTime); - + screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, + screen->root, XCB_CURRENT_TIME); + focus_prev(win); if (win->hints) { @@ -6925,7 +6939,7 @@ mapnotify(XEvent *e) win = manage_window(ev->window); if (win) - set_win_state(win, NormalState); + set_win_state(win, XCB_WM_STATE_NORMAL); /* * focus_win can only set input focus on a mapped window. @@ -6992,7 +7006,7 @@ propertynotify(XEvent *e) if (ev->state == PropertyDelete && ev->atom == a_swm_iconic) { update_iconic(win, 0); - XMapRaised(display, win->id); + map_window_raised(win->id); stack(); focus_win(win); return; @@ -7033,7 +7047,7 @@ unmapnotify(XEvent *e) if (win == NULL) return; - if (getstate(e->xunmap.window) == NormalState) { + if (getstate(e->xunmap.window) == XCB_WM_STATE_NORMAL) { unmanage_window(win); stack(); @@ -7106,7 +7120,7 @@ clientmessage(XEvent *e) if (win->can_delete) client_msg(win, adelete); else - XKillClient(display, win->id); + xcb_kill_client(conn, win->id); } if (ev->message_type == ewmh[_NET_MOVERESIZE_WINDOW].atom) { DNPRINTF(SWM_D_EVENT, @@ -7251,13 +7265,16 @@ void scan_xrandr(int i) { #ifdef SWM_XRR_HAS_CRTC - XRRCrtcInfo *ci; - XRRScreenResources *sr; int c; int ncrtc = 0; #endif /* SWM_XRR_HAS_CRTC */ struct swm_region *r; int num_screens; + xcb_randr_get_screen_resources_cookie_t src; + xcb_randr_get_screen_resources_reply_t *srr; + xcb_randr_get_crtc_info_cookie_t cic; + xcb_randr_get_crtc_info_reply_t *cir; + xcb_randr_crtc_t *crtc; num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); if (i >= num_screens) @@ -7275,30 +7292,34 @@ scan_xrandr(int i) /* map virtual screens onto physical screens */ #ifdef SWM_XRR_HAS_CRTC if (xrandr_support) { - sr = XRRGetScreenResourcesCurrent(display, screens[i].root); - if (sr == NULL) + src = xcb_randr_get_screen_resources(conn, screens[i].root); + srr = xcb_randr_get_screen_resources_reply(conn, src, NULL); + if (srr == NULL) new_region(&screens[i], 0, 0, DisplayWidth(display, i), DisplayHeight(display, i)); else - ncrtc = sr->ncrtc; - - for (c = 0, ci = NULL; c < ncrtc; c++) { - ci = XRRGetCrtcInfo(display, sr, sr->crtcs[c]); - if (ci->noutput == 0) + ncrtc = srr->num_crtcs; + for (c = 0; c < ncrtc; c++) { + crtc = xcb_randr_get_screen_resources_crtcs(srr); + cic = xcb_randr_get_crtc_info(conn, crtc[c], + XCB_CURRENT_TIME); + cir = xcb_randr_get_crtc_info_reply(conn, cic, NULL); + if (cir && cir->num_outputs == 0) continue; - if (ci != NULL && ci->mode == None) + if (cir == NULL || cir->mode == 0) new_region(&screens[i], 0, 0, DisplayWidth(display, i), DisplayHeight(display, i)); else new_region(&screens[i], - ci->x, ci->y, ci->width, ci->height); + cir->x, cir->y, cir->width, cir->height); } - if (ci) - XRRFreeCrtcInfo(ci); - XRRFreeScreenResources(sr); + if (srr) + free(srr); + if (cir) + free(cir); } else #endif /* SWM_XRR_HAS_CRTC */ { @@ -7308,7 +7329,8 @@ scan_xrandr(int i) } void -screenchange(XEvent *e) { +screenchange(XEvent *e) +{ XRRScreenChangeNotifyEvent *xe = (XRRScreenChangeNotifyEvent *)e; struct swm_region *r; int i, num_screens; @@ -7341,46 +7363,70 @@ screenchange(XEvent *e) { void grab_windows(void) { - Window d1, d2, *wins = NULL; - XWindowAttributes wa; - unsigned int no; + xcb_window_t *wins = NULL; + int no; int i, j, num_screens; - long state, manage; + uint16_t state, manage; + + xcb_query_tree_cookie_t qtc; + xcb_query_tree_reply_t *qtr; + xcb_get_window_attributes_cookie_t c; + xcb_get_window_attributes_reply_t *r; + xcb_get_property_cookie_t pc; num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) { - if (!XQueryTree(display, screens[i].root, &d1, &d2, &wins, &no)) + qtc = xcb_query_tree(conn, screens[i].root); + qtr = xcb_query_tree_reply(conn, qtc, NULL); + if (!qtr) continue; - + wins = xcb_query_tree_children(qtr); + no = xcb_query_tree_children_length(qtr); /* attach windows to a region */ - /* normal windows */ + /* normal windows */ for (j = 0; j < no; j++) { - if (!XGetWindowAttributes(display, wins[j], &wa) || - wa.override_redirect || - XGetTransientForHint(display, wins[j], &d1)) + c = xcb_get_window_attributes(conn, wins[j]); + r = xcb_get_window_attributes_reply(conn, c, NULL); + if (!r) continue; + if (r->override_redirect) { + free(r); + continue; + } + + pc = xcb_get_wm_transient_for(conn, wins[j]); + if (xcb_get_wm_transient_for_reply(conn, pc, &wins[j], + NULL)) { + free(r); + continue; + } state = getstate(wins[j]); - manage = state == IconicState; - if (wa.map_state == IsViewable || manage) + manage = state == XCB_WM_STATE_ICONIC; + if (r->map_state == XCB_MAP_STATE_VIEWABLE || manage) manage_window(wins[j]); + free(r); } /* transient windows */ for (j = 0; j < no; j++) { - if (!XGetWindowAttributes(display, wins[j], &wa) || - wa.override_redirect) + c = xcb_get_window_attributes(conn, wins[j]); + r = xcb_get_window_attributes_reply(conn, c, NULL); + if (!r) continue; - + if (r->override_redirect) { + free(r); + continue; + } + free(r); + state = getstate(wins[j]); - manage = state == IconicState; - if (XGetTransientForHint(display, wins[j], &d1) && - manage) + manage = state == XCB_WM_STATE_ICONIC; + pc = xcb_get_wm_transient_for(conn, wins[j]); + if (xcb_get_wm_transient_for_reply(conn, pc, &wins[j], + NULL) && manage) manage_window(wins[j]); } - if (wins) { - XFree(wins); - wins = NULL; - } + free(qtr); } } @@ -7388,9 +7434,11 @@ void setup_screens(void) { int i, j, k, num_screens; - int errorbase, major, minor; struct workspace *ws; XGCValues gcv; + const xcb_query_extension_reply_t *qep; + xcb_randr_query_version_cookie_t c; + xcb_randr_query_version_reply_t *r; num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); if ((screens = calloc(num_screens, @@ -7399,11 +7447,16 @@ setup_screens(void) "screens"); /* initial Xrandr setup */ - xrandr_support = XRRQueryExtension(display, - &xrandr_eventbase, &errorbase); - if (xrandr_support) - if (XRRQueryVersion(display, &major, &minor) && major < 1) - xrandr_support = 0; + xrandr_support = False; + c = xcb_randr_query_version(conn, True, True); + r = xcb_randr_query_version_reply(conn, c, NULL); + if (r) { + if (r->major_version >= 1) + xrandr_support = True; + free(r); + } + qep = xcb_get_extension_data(conn, &xcb_randr_id); + xrandr_eventbase = qep->first_event; /* map physical screens */ for (i = 0; i < num_screens; i++) { @@ -7423,7 +7476,7 @@ setup_screens(void) /* create graphics context on screen */ gcv.graphics_exposures = 0; screens[i].bar_gc = XCreateGC(display, screens[i].root, - GCGraphicsExposures, &gcv); + GCGraphicsExposures, &gcv); /* set default cursor */ XDefineCursor(display, screens[i].root, @@ -7452,8 +7505,8 @@ setup_screens(void) scan_xrandr(i); if (xrandr_support) - XRRSelectInput(display, screens[i].root, - RRScreenChangeNotifyMask); + xcb_randr_select_input(conn, screens[i].root, + XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE); } } @@ -7471,13 +7524,13 @@ void workaround(void) { int i, num_screens; - Atom netwmcheck, netwmname, utf8_string; - Window root, win; + xcb_atom_t netwmcheck, netwmname, utf8_string; + xcb_window_t root, win; /* work around sun jdk bugs, code from wmname */ - netwmcheck = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False); - netwmname = XInternAtom(display, "_NET_WM_NAME", False); - utf8_string = XInternAtom(display, "UTF8_STRING", False); + netwmcheck = get_atom_from_string("_NET_SUPPORTING_WM_CHECK"); + netwmname = get_atom_from_string("_NET_WM_NAME"); + utf8_string = get_atom_from_string("UTF8_STRING"); num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) { @@ -7486,12 +7539,12 @@ workaround(void) screens[i].c[SWM_S_COLOR_UNFOCUS].color, screens[i].c[SWM_S_COLOR_UNFOCUS].color); - XChangeProperty(display, root, netwmcheck, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&win, 1); - XChangeProperty(display, win, netwmcheck, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&win, 1); - XChangeProperty(display, win, netwmname, utf8_string, 8, - PropModeReplace, (unsigned char*)"LG3D", strlen("LG3D")); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, + netwmcheck, XCB_ATOM_WINDOW, 32, 1, &win); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, + netwmcheck, XCB_ATOM_WINDOW, 32, 1, &win); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, + netwmcheck, utf8_string, 8, strlen("LG3D"), "LG3D"); } } @@ -7508,7 +7561,7 @@ main(int argc, char *argv[]) int xfd, i, num_screens; fd_set rd; struct sigaction sact; - + start_argv = argv; warnx("Welcome to spectrwm V%s Build: %s", SPECTRWM_VERSION, buildstr); if (!setlocale(LC_CTYPE, "") || !setlocale(LC_TIME, "") || @@ -7541,15 +7594,15 @@ main(int argc, char *argv[]) sact.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &sact, NULL); - astate = XInternAtom(display, "WM_STATE", False); - aprot = XInternAtom(display, "WM_PROTOCOLS", False); - adelete = XInternAtom(display, "WM_DELETE_WINDOW", False); - takefocus = XInternAtom(display, "WM_TAKE_FOCUS", False); - a_wmname = XInternAtom(display, "WM_NAME", False); - a_netwmname = XInternAtom(display, "_NET_WM_NAME", False); - a_utf8_string = XInternAtom(display, "UTF8_STRING", False); - a_string = XInternAtom(display, "STRING", False); - a_swm_iconic = XInternAtom(display, "_SWM_ICONIC", False); + astate = get_atom_from_string("WM_STATE"); + aprot = get_atom_from_string("WM_PROTOCOLS"); + adelete = get_atom_from_string("WM_DELETE_WINDOW"); + takefocus = get_atom_from_string("WM_TAKE_FOCUS"); + a_wmname = get_atom_from_string("WM_NAME"); + a_netwmname = get_atom_from_string("_NET_WM_NAME"); + a_utf8_string = get_atom_from_string("UTF8_STRING"); + a_string = get_atom_from_string("STRING"); + a_swm_iconic = get_atom_from_string("_SWM_ICONIC"); /* look for local and global conf file */ pwd = getpwuid(getuid()); @@ -7627,7 +7680,7 @@ noconfig: if (focus_mode == SWM_FOCUS_DEFAULT) drain_enter_notify(); - xfd = ConnectionNumber(display); + xfd = xcb_get_file_descriptor(conn); while (running) { while (XPending(display)) { XNextEvent(display, &e); @@ -7667,9 +7720,9 @@ noconfig: } /* move pointer to first screen if multi screen */ if (num_screens > 1 || outputs > 1) - XWarpPointer(display, None, rr->s[0].root, - 0, 0, 0, 0, X(rr), - Y(rr) + (bar_enabled ? bar_height : 0)); + xcb_warp_pointer(conn, XCB_WINDOW_NONE, + rr->s[0].root, 0, 0, 0, 0, X(rr), + Y(rr) + (bar_enabled ? bar_height : 0)); a.id = SWM_ARG_ID_FOCUSCUR; focus(rr, &a); @@ -7702,7 +7755,6 @@ done: for (i = 0; i < num_screens; ++i) if (screens[i].bar_gc != NULL) XFreeGC(display, screens[i].bar_gc); - XFreeFontSet(display, bar_fs); xcb_disconnect(conn); XCloseDisplay(display);