X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=4699392923002d439183cd24cf811cab5956e9b7;hb=b1b60af57d5187e8382fc3078b5157b5df9b00ab;hp=2324a486159cf05eba8799fd2589b54bcea61f37;hpb=9a58fa26bae6925b4db8055a9e130139b8ce579d;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 2324a48..4699392 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -88,21 +88,15 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include #include #include #include #include #include #include +#include /* local includes */ #include "version.h" @@ -182,6 +176,7 @@ static const char *buildstr = SPECTRWM_VERSION; #define SWM_D_EVENTQ 0x1000 #define SWM_D_CONF 0x2000 #define SWM_D_BAR 0x4000 +#define SWM_D_INIT 0x8000 u_int32_t swm_debug = 0 | SWM_D_MISC @@ -199,6 +194,7 @@ u_int32_t swm_debug = 0 | SWM_D_EVENTQ | SWM_D_CONF | SWM_D_BAR + | SWM_D_INIT ; #else #define DPRINTF(x...) @@ -246,10 +242,10 @@ u_int32_t swm_debug = 0 #endif char **start_argv; -xcb_atom_t astate; -xcb_atom_t aprot; -xcb_atom_t adelete; -xcb_atom_t takefocus; +xcb_atom_t a_state; +xcb_atom_t a_prot; +xcb_atom_t a_delete; +xcb_atom_t a_takefocus; xcb_atom_t a_wmname; xcb_atom_t a_netwmname; xcb_atom_t a_utf8_string; @@ -259,13 +255,11 @@ volatile sig_atomic_t running = 1; volatile sig_atomic_t restart_wm = 0; int outputs = 0; /*int last_focus_event = FocusOut;*/ -int (*xerrorxlib)(Display *, XErrorEvent *); int other_wm; int ss_enabled = 0; int xrandr_support; int xrandr_eventbase; unsigned int numlockmask = 0; -Display *display; xcb_connection_t *conn; xcb_key_symbols_t *syms; @@ -354,17 +348,11 @@ int border_width = 1; int verbose_layout = 0; time_t time_started; pid_t bar_pid; -XFontSet bar_fs; -XFontSetExtents *bar_fs_extents; +xcb_font_t bar_fs; +int32_t bar_fs_height; char *bar_fonts; struct passwd *pwd; -#define SWM_MENU_FN (2) -#define SWM_MENU_NB (4) -#define SWM_MENU_NF (6) -#define SWM_MENU_SB (8) -#define SWM_MENU_SF (10) - /* layout manager data */ struct swm_geometry { int x; @@ -646,6 +634,7 @@ struct ewmh_hint { }; /* function prototypes */ +xcb_char2b_t *char2b(const char *); int conf_load(char *, int); void constrain_window(struct ws_win *, struct swm_region *, int); void do_sync(void); @@ -668,6 +657,25 @@ void unmanage_window(struct ws_win *); void update_window(struct ws_win *); /* function definitions */ +xcb_char2b_t * +char2b(const char *str) +{ + xcb_char2b_t *s; + size_t i, len; + + len = strlen(str); + s = malloc(len * sizeof(xcb_char2b_t)); + if (!s) + return (NULL); + + for (i = 0; i < len; i++) { + s[i].byte1 = '\0'; + s[i].byte2 = str[i]; + } + + return (s); +} + int parse_rgb(const char *rgb, uint16_t *rr, uint16_t *gg, uint16_t *bb) { @@ -798,7 +806,7 @@ setup_ewmh(void) num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) { /* Support check window will be created by workaround(). */ - + /* Report supported atoms */ xcb_delete_property(conn, screens[i].root, sup_list); for (j = 0; j < LENGTH(ewmh); j++) @@ -1281,12 +1289,12 @@ plain_stacker(struct workspace *ws) void custom_region(char *val) { - unsigned int sidx, x, y, w, h; - int num_screens; + unsigned int x, y, w, h; + int sidx, num_screens; xcb_screen_t *screen; num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); - if (sscanf(val, "screen[%u]:%ux%u+%u+%u", &sidx, &w, &h, &x, &y) != 5) + if (sscanf(val, "screen[%d]:%ux%u+%u+%u", &sidx, &w, &h, &x, &y) != 5) errx(1, "invalid custom region, " "should be 'screen[]:x++"); if (sidx < 1 || sidx > num_screens) @@ -1326,30 +1334,44 @@ socket_setnonblock(int fd) void bar_print(struct swm_region *r, const char *s) { - int x = 0; - size_t len; - xcb_rectangle_t rect; - uint32_t gcv[1]; - XRectangle ibox, lbox; + size_t len; + xcb_rectangle_t rect; + uint32_t gcv[1]; + xcb_char2b_t *c2b; + xcb_query_text_extents_reply_t *ter; + int32_t x, width; len = strlen(s); - XmbTextExtents(bar_fs, s, len, &ibox, &lbox); - + c2b = char2b(s); + if (!c2b) + return; + ter = xcb_query_text_extents_reply(conn, + xcb_query_text_extents(conn, bar_fs, len, c2b), + NULL); + if (!ter) { + free(c2b); + return; + } + width = ter->overall_width; + + free(ter); + free(c2b); + switch (bar_justify) { case SWM_BAR_JUSTIFY_LEFT: x = SWM_BAR_OFFSET; break; case SWM_BAR_JUSTIFY_CENTER: - x = (WIDTH(r) - lbox.width) / 2; + x = (WIDTH(r) - width) / 2; break; case SWM_BAR_JUSTIFY_RIGHT: - x = WIDTH(r) - lbox.width - SWM_BAR_OFFSET; + x = WIDTH(r) - width - SWM_BAR_OFFSET; break; } if (x < SWM_BAR_OFFSET) x = SWM_BAR_OFFSET; - + rect.x = 0; rect.y = 0; rect.width = WIDTH(r->bar); @@ -1366,9 +1388,11 @@ bar_print(struct swm_region *r, const char *s) xcb_change_gc(conn, r->s->bar_gc, XCB_GC_BACKGROUND, gcv); gcv[0] = r->s->c[SWM_S_COLOR_BAR_FONT].color; xcb_change_gc(conn, r->s->bar_gc, XCB_GC_FOREGROUND, gcv); + gcv[0] = bar_fs; + xcb_change_gc(conn, r->s->bar_gc, XCB_GC_FONT, gcv); + xcb_image_text_8(conn, len, r->bar->buffer, r->s->bar_gc, x, - (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - - lbox.y, s); + bar_fs_height, s); /* blt */ xcb_copy_area(conn, r->bar->buffer, r->bar->id, r->s->bar_gc, 0, 0, @@ -1545,7 +1569,7 @@ void bar_replace_pad(char *tmp, int *limit, size_t sz) { /* special case; no limit given, pad one space, instead */ - if (*limit == sz - 1) + if (*limit == (int)sz - 1) *limit = 1; snprintf(tmp, sz, "%*s", *limit, " "); } @@ -1568,7 +1592,7 @@ bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep, size = 0; if (sscanf(fmt, "%d%n", &limit, &size) != 1) limit = sizeof tmp - 1; - if (limit <= 0 || limit >= sizeof tmp) + if (limit <= 0 || limit >= (int)sizeof tmp) limit = sizeof tmp - 1; /* there is nothing to replace (ie EOL) */ @@ -1624,7 +1648,7 @@ bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep, len = strlen(tmp); ptr = tmp; - if (len < limit) + if ((int)len < limit) limit = len; while (limit-- > 0) { if (*offrep >= sz - 1) @@ -1830,48 +1854,54 @@ bar_refresh(void) void bar_setup(struct swm_region *r) { - char *default_string; - char **missing_charsets; - int num_missing_charsets = 0; - int i; + char *bar_font; xcb_screen_t *screen = get_screen(r->s->idx); uint32_t wa[3]; + xcb_generic_error_t *error; + xcb_void_cookie_t voc; + xcb_query_font_reply_t *bar_fs_info; if (bar_fs) { - XFreeFontSet(display, bar_fs); - bar_fs = NULL; + xcb_close_font(conn, bar_fs); + bar_fs = 0; } if ((r->bar = calloc(1, sizeof(struct swm_bar))) == NULL) err(1, "bar_setup: calloc: failed to allocate memory."); - DNPRINTF(SWM_D_BAR, "bar_setup: loading bar_fonts: %s\n", bar_fonts); - - bar_fs = XCreateFontSet(display, bar_fonts, &missing_charsets, - &num_missing_charsets, &default_string); - - if (num_missing_charsets > 0) { - warnx("Unable to load charset(s):"); - - for (i = 0; i < num_missing_charsets; ++i) - warnx("%s", missing_charsets[i]); + bar_fs = xcb_generate_id(conn); + while ((bar_font = strsep(&bar_fonts, " ,")) != NULL) { + if (*bar_font == '\0') + continue; - XFreeStringList(missing_charsets); + DNPRINTF(SWM_D_INIT, "bar_setup: try font %s\n", bar_font); + voc = xcb_open_font_checked(conn, bar_fs, strlen(bar_font), + bar_font); - if (strcmp(default_string, "")) - warnx("Glyphs from those sets will be replaced " - "by '%s'.", default_string); - else - warnx("Glyphs from those sets won't be drawn."); + if ((error = xcb_request_check(conn, voc))) { + DNPRINTF(SWM_D_INIT, + "bar_setup: unable to open font: %s\n", + bar_font); + free(error); + warnx("unable to load font %s", bar_font); + } else { + DNPRINTF(SWM_D_INIT, + "bar_setup: successfully opened font: %s\n", + bar_font); + break; + } } - if (bar_fs == NULL) - errx(1, "Error creating font set structure."); - - bar_fs_extents = XExtentsOfFontSet(bar_fs); + bar_fs_info = xcb_query_font_reply(conn, + xcb_query_font(conn, bar_fs), + NULL); + if (!bar_fs_info) + errx(1, "unable to get font information for font %s\n", + bar_font); + bar_fs_height = bar_fs_info->font_ascent + bar_fs_info->font_descent; + free(bar_fs_info); - bar_height = bar_fs_extents->max_logical_extent.height + - 2 * bar_border_width; + bar_height = bar_fs_height + 4 * bar_border_width; if (bar_height < 1) bar_height = 1; @@ -1885,6 +1915,8 @@ bar_setup(struct swm_region *r) wa[0] = r->s->c[SWM_S_COLOR_BAR].color; wa[1] = r->s->c[SWM_S_COLOR_BAR_BORDER].color; wa[2] = XCB_EVENT_MASK_EXPOSURE; + DNPRINTF(SWM_D_BAR, "bar_setup: create_window: (x,y) w x h: (%d,%d) " + "%d x %d\n", X(r->bar), Y(r->bar), WIDTH(r->bar), HEIGHT(r->bar)); xcb_create_window(conn, XCB_COPY_FROM_PARENT, r->bar->id, r->s->root, X(r->bar), Y(r->bar), WIDTH(r->bar), HEIGHT(r->bar), bar_border_width, XCB_WINDOW_CLASS_INPUT_OUTPUT, @@ -1931,8 +1963,8 @@ set_win_state(struct ws_win *win, uint16_t state) if (win == NULL) return; - xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, astate, - astate, 32, 2, data); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, a_state, + a_state, 32, 2, data); } uint16_t @@ -1942,7 +1974,7 @@ getstate(xcb_window_t w) xcb_get_property_cookie_t c; xcb_get_property_reply_t *r; - c = xcb_get_property(conn, False, w, astate, astate, 0L, 2L); + c = xcb_get_property(conn, False, w, a_state, a_state, 0L, 2L); r = xcb_get_property_reply(conn, c, NULL); if (r) { @@ -1980,7 +2012,7 @@ client_msg(struct ws_win *win, xcb_atom_t a) bzero(&ev, sizeof ev); ev.response_type = XCB_CLIENT_MESSAGE; ev.window = win->id; - ev.type = aprot; + ev.type = a_prot; ev.format = 32; ev.data.data32[0] = a; ev.data.data32[1] = XCB_CURRENT_TIME; @@ -2278,8 +2310,7 @@ spawn(int ws_idx, union arg *args, int close_fd) DNPRINTF(SWM_D_MISC, "spawn: %s\n", args->argv[0]); - if (display) - close(xcb_get_file_descriptor(conn)); + close(xcb_get_file_descriptor(conn)); setenv("LD_PRELOAD", SWM_LIB, 1); @@ -2997,6 +3028,7 @@ cycle_layout(struct swm_region *r, union arg *args) ws->cur_layout = &layouts[0]; stack(); + bar_update(); if (focus_mode == SWM_FOCUS_DEFAULT) event_drain(XCB_ENTER_NOTIFY); @@ -3808,12 +3840,14 @@ search_win(struct swm_region *r, union arg *args) struct ws_win *win = NULL; struct search_window *sw = NULL; xcb_window_t w; - uint32_t gcv[3], wa[2]; - int i; + uint32_t gcv[4], wa[2]; + int i, width; char s[8]; FILE *lfile; size_t len; - XRectangle ibox, lbox; + xcb_char2b_t *c2b; + xcb_query_text_extents_reply_t *ter; + DNPRINTF(SWM_D_MISC, "search_win\n"); search_r = r; @@ -3844,13 +3878,35 @@ search_win(struct swm_region *r, union arg *args) snprintf(s, sizeof s, "%d", i); len = strlen(s); - XmbTextExtents(bar_fs, s, len, &ibox, &lbox); + c2b = char2b(s); + if (!c2b) { + warn("search_win: char2b malloc"); + free(sw); + fclose(lfile); + search_win_cleanup(); + return; + } + ter = xcb_query_text_extents_reply(conn, + xcb_query_text_extents(conn, bar_fs, + len, c2b), + NULL); + if (!ter) { + warn("search_win: query text failed"); + free(c2b); + free(sw); + fclose(lfile); + search_win_cleanup(); + return; + } + width = ter->overall_width; + free(ter); + free(c2b); w = xcb_generate_id(conn); wa[0] = r->s->c[SWM_S_COLOR_FOCUS].color; wa[1] = r->s->c[SWM_S_COLOR_UNFOCUS].color; xcb_create_window(conn, XCB_COPY_FROM_PARENT, w, win->id, 0, 0, - lbox.width + 4, bar_fs_extents->max_logical_extent.height, + width + 4, bar_fs_height + 4, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa); @@ -3860,14 +3916,14 @@ search_win(struct swm_region *r, union arg *args) sw->gc = xcb_generate_id(conn); gcv[0] = r->s->c[SWM_S_COLOR_BAR].color; gcv[1] = r->s->c[SWM_S_COLOR_FOCUS].color; - gcv[2] = 0; + gcv[2] = bar_fs; + gcv[3] = 0; xcb_create_gc(conn, sw->gc, w, XCB_GC_FOREGROUND | - XCB_GC_BACKGROUND | XCB_GC_GRAPHICS_EXPOSURES, gcv); + XCB_GC_BACKGROUND | XCB_GC_FONT | XCB_GC_GRAPHICS_EXPOSURES, + gcv); map_window_raised(w); - xcb_image_text_8(conn, len, w, sw->gc, 2, - (bar_fs_extents->max_logical_extent.height - - lbox.height) / 2 - lbox.y, s); + xcb_image_text_8(conn, len, w, sw->gc, 2, bar_fs_height, s); DNPRINTF(SWM_D_MISC, "search_win: mapped window: 0x%x\n", w); @@ -3955,7 +4011,7 @@ search_resp_search_workspace(char *resp, unsigned long len) p = strchr(q, ':'); if (p != NULL) *p = '\0'; - ws_idx = strtonum(q, 1, workspace_limit, &errstr); + ws_idx = (int)strtonum(q, 1, workspace_limit, &errstr); if (errstr) { DNPRINTF(SWM_D_MISC, "workspace idx is %s: %s", errstr, q); @@ -3984,7 +4040,7 @@ search_resp_search_window(char *resp, unsigned long len) return; } - idx = strtonum(s, 1, INT_MAX, &errstr); + idx = (int)strtonum(s, 1, INT_MAX, &errstr); if (errstr) { DNPRINTF(SWM_D_MISC, "window idx is %s: %s", errstr, s); @@ -4069,7 +4125,7 @@ wkill(struct swm_region *r, union arg *args) xcb_kill_client(conn, r->ws->focus->id); else if (r->ws->focus->can_delete) - client_msg(r->ws->focus, adelete); + client_msg(r->ws->focus, a_delete); xcb_flush(conn); } @@ -4311,10 +4367,6 @@ resize(struct ws_win *win, union arg *args) xcb_flush(conn); resizing = 1; while ((evt = xcb_wait_for_event(conn)) && resizing) { - /* - XMaskEvent(display, MOUSEMASK | ExposureMask | - SubstructureRedirectMask, &ev); - */ switch (XCB_EVENT_RESPONSE_TYPE(evt)) { case XCB_BUTTON_RELEASE: DNPRINTF(SWM_D_EVENT, "resize: BUTTON_RELEASE\n"); @@ -4973,7 +5025,7 @@ spawn_insert(char *name, char *args) DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s\n", name); if ((sp = calloc(1, sizeof *sp)) == NULL) - err(1, "spawn_insert: malloc"); + err(1, "spawn_insert: calloc"); if ((sp->name = strdup(name)) == NULL) err(1, "spawn_insert: strdup"); @@ -5115,7 +5167,7 @@ parsekeys(char *keystr, unsigned int currmod, unsigned int *mod, KeySym *ks) return (1); } cp = keystr; - *ks = NoSymbol; + *ks = XCB_NO_SYMBOL; *mod = 0; while ((name = strsep(&cp, SWM_KEY_WS)) != NULL) { DNPRINTF(SWM_D_KEY, "parsekeys: key [%s]\n", name); @@ -5138,7 +5190,7 @@ parsekeys(char *keystr, unsigned int currmod, unsigned int *mod, KeySym *ks) else { *ks = XStringToKeysym(name); XConvertCase(*ks, ks, &uks); - if (ks == NoSymbol) { + if (ks == XCB_NO_SYMBOL) { DNPRINTF(SWM_D_KEY, "parsekeys: invalid key %s\n", name); @@ -5456,8 +5508,8 @@ updatenumlockmask(void) void grabkeys(void) { - int num_screens; - unsigned int j, k; + int num_screens, k; + unsigned int j; xcb_keycode_t *code; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask | LockMask }; @@ -5740,7 +5792,6 @@ setconfvalue(char *selector, char *value, int flags) if (asprintf(&bar_fonts, "%s,%s", value, bar_fonts) == -1) err(1, "setconfvalue: asprintf: failed to allocate " "memory for bar_fonts."); - free(b); break; case SWM_S_BAR_FORMAT: @@ -6157,7 +6208,7 @@ conf_load(char *filename, int keymapping) for (i = 0; i < LENGTH(configopt); i++) { opt = &configopt[i]; if (!strncasecmp(cp, opt->optname, wordlen) && - strlen(opt->optname) == wordlen) { + (int)strlen(opt->optname) == wordlen) { optind = i; break; } @@ -6301,7 +6352,7 @@ tryharder: return (0); } - ret = strtonum(xcb_get_property_value(pr), 0, INT_MAX, &errstr); + ret = (pid_t)strtonum(xcb_get_property_value(pr), 0, INT_MAX, &errstr); free(pr); return (ret); @@ -6313,7 +6364,7 @@ manage_window(xcb_window_t id) xcb_window_t trans = XCB_WINDOW_NONE; struct workspace *ws; struct ws_win *win, *ww; - int i, ws_idx, border_me = 0; + int 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; @@ -6321,7 +6372,7 @@ manage_window(xcb_window_t id) const char *errstr; struct pid_e *p; struct quirk *qp; - uint32_t event_mask; + uint32_t event_mask, i; xcb_atom_t prot; xcb_get_property_reply_t *gpr; xcb_icccm_get_wm_protocols_reply_t wpr; @@ -6417,9 +6468,9 @@ manage_window(xcb_window_t id) xcb_icccm_get_wm_protocols(conn, id, prot), &wpr, NULL)) { for (i = 0; i < wpr.atoms_len; i++) { - if (wpr.atoms[i] == takefocus) + if (wpr.atoms[i] == a_takefocus) win->take_focus = 1; - if (wpr.atoms[i] == adelete) + if (wpr.atoms[i] == a_delete) win->can_delete = 1; } xcb_icccm_get_wm_protocols_reply_wipe(&wpr); @@ -6440,7 +6491,7 @@ manage_window(xcb_window_t id) p = NULL; } else if (prop && win->transient == 0) { DNPRINTF(SWM_D_PROP, "manage_window: get _SWM_WS: %s\n", prop); - ws_idx = strtonum(prop, 0, workspace_limit - 1, + ws_idx = (int)strtonum(prop, 0, workspace_limit - 1, &errstr); if (errstr) { DNPRINTF(SWM_D_EVENT, "manage_window: window: #%s: %s", @@ -6653,25 +6704,26 @@ focus_magic(struct ws_win *win) if (win->java) { focus_win(win->child_trans); if (win->child_trans->take_focus) - client_msg(win, takefocus); + client_msg(win, a_takefocus); } else { /* make sure transient hasn't disappeared */ if (validate_win(win->child_trans) == 0) { focus_win(win->child_trans); if (win->child_trans->take_focus) - client_msg(win->child_trans, takefocus); + client_msg(win->child_trans, + a_takefocus); } else { win->child_trans = NULL; focus_win(win); if (win->take_focus) - client_msg(win, takefocus); + client_msg(win, a_takefocus); } } } else { /* regular focus */ focus_win(win); if (win->take_focus) - client_msg(win, takefocus); + client_msg(win, a_takefocus); } } @@ -6695,12 +6747,12 @@ expose(xcb_expose_event_t *e) void keypress(xcb_key_press_event_t *e) { - KeySym keysym; + xcb_keysym_t keysym; struct key *kp; - keysym = XkbKeycodeToKeysym(display, (KeyCode)e->detail, 0, 0); + keysym = xcb_key_press_lookup_keysym(syms, e, 0); - DNPRINTF(SWM_D_EVENT, "keypress: %u\n", e->detail); + DNPRINTF(SWM_D_EVENT, "keypress: %u %u\n", e->detail, keysym); if ((kp = key_lookup(CLEANMASK(e->state), keysym)) == NULL) return; @@ -6717,7 +6769,8 @@ void buttonpress(xcb_button_press_event_t *e) { struct ws_win *win; - int i, action; + int i; + unsigned int action; DNPRINTF(SWM_D_EVENT, "buttonpress: window 0x%x, detail: %u\n", e->event, e->detail); @@ -6737,6 +6790,24 @@ buttonpress(xcb_button_press_event_t *e) xcb_flush(conn); } +#ifdef SWM_DEBUG +void +print_win_geom(xcb_window_t w) +{ + xcb_get_geometry_reply_t *wa; + + + wa = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, w), NULL); + + DNPRINTF(SWM_D_MISC, "print_win_geom: window: 0x%x, root: 0x%x, " + "depth: %u, (x,y) w x h: (%d,%d) %d x %d, border: %d\n", + w, wa->root, wa->depth, wa->x, wa->y, wa->width, wa->height, + wa->border_width); + + free(wa); +} +#endif + void configurerequest(xcb_configure_request_event_t *e) { @@ -6748,42 +6819,52 @@ configurerequest(xcb_configure_request_event_t *e) if ((win = find_window(e->window)) == NULL) if ((win = find_unmanaged_window(e->window)) == NULL) new = 1; - +#ifdef SWM_DEBUG + print_win_geom(e->window); +#endif if (new) { + DNPRINTF(SWM_D_EVENT, "configurerequest: new window: 0x%x, " + "value_mask: 0x%x", e->window, e->value_mask); if (e->value_mask & XCB_CONFIG_WINDOW_X) { mask |= XCB_CONFIG_WINDOW_X; wc[i++] = e->x; + DPRINTF(", X: %d", e->x); } if (e->value_mask & XCB_CONFIG_WINDOW_Y) { mask |= XCB_CONFIG_WINDOW_Y; wc[i++] = e->y; + DPRINTF(", Y: %d", e->y); } if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) { mask |= XCB_CONFIG_WINDOW_WIDTH; wc[i++] = e->width; + DPRINTF(", W: %u", e->width); } if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { mask |= XCB_CONFIG_WINDOW_HEIGHT; wc[i++] = e->height; + DPRINTF(", H: %u", e->height); } if (e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) { mask |= XCB_CONFIG_WINDOW_BORDER_WIDTH; wc[i++] = e->border_width; + DPRINTF(", Border: %u", e->border_width); } if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) { mask |= XCB_CONFIG_WINDOW_SIBLING; wc[i++] = e->sibling; + DPRINTF(", Sibling: 0x%x", e->sibling); } if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) { mask |= XCB_CONFIG_WINDOW_STACK_MODE; wc[i++] = e->stack_mode; + DPRINTF(", StackMode: %u", e->stack_mode); } - DNPRINTF(SWM_D_EVENT, "configurerequest: new window: 0x%x, " - "new: %s, (x,y) w x h: (%d,%d) %d x %d\n", e->window, - YESNO(new), wc[0], wc[1], wc[2], wc[3]); + if (mask != 0) + xcb_configure_window(conn, e->window, mask, wc); - xcb_configure_window(conn, e->window, mask, wc); + DPRINTF(", Sent: %s\n", YESNO((mask != 0))); } else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) && !(win->ewmh_flags & EWMH_F_FULLSCREEN)) { win->g_float.x = e->x - X(win->ws->r); @@ -6947,17 +7028,17 @@ maprequest(xcb_map_request_event_t *e) focus_magic(win); } -void -propertynotify(xcb_property_notify_event_t *e) -{ - struct ws_win *win; #ifdef SWM_DEBUG +char * +get_atom_name(xcb_atom_t atom) +{ char *name; size_t len; xcb_get_atom_name_reply_t *r; + xcb_map_request_event_t mre; r = xcb_get_atom_name_reply(conn, - xcb_get_atom_name(conn, e->atom), + xcb_get_atom_name(conn, atom), NULL); if (r) { len = xcb_get_atom_name_name_length(r); @@ -6967,14 +7048,27 @@ propertynotify(xcb_property_notify_event_t *e) memcpy(name, xcb_get_atom_name_name(r), len); name[len] = '\0'; - DNPRINTF(SWM_D_EVENT, - "propertynotify: window: 0x%x, atom: %s\n", - e->window, name); - free(name); + return name; } } free(r); } + + return NULL; +} +#endif + +void +propertynotify(xcb_property_notify_event_t *e) +{ + struct ws_win *win; +#ifdef SWM_DEBUG + char *name; + + name = get_atom_name(e->atom); + DNPRINTF(SWM_D_EVENT, "propertynotify: window: 0x%x, atom: %s(%u)\n", + e->window, name, e->atom); + free(name); #endif win = find_window(e->window); @@ -7032,15 +7126,27 @@ void clientmessage(xcb_client_message_event_t *e) { struct ws_win *win; + xcb_map_request_event_t mre; +#ifdef SWM_DEBUG + char *name; + name = get_atom_name(e->type); + DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%x, atom: %s(%u)\n", + e->window, name, e->type); + free(name); +#endif win = find_window(e->window); - if (win == NULL) + + if (win == NULL) { + if (e->type == ewmh[_NET_ACTIVE_WINDOW].atom) { + DNPRINTF(SWM_D_EVENT, "clientmessage: request focus on " + "unmanaged window.\n"); + mre.window = e->window; + maprequest(&mre); + } return; } - DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%x, type: %u\n", - e->window, e->type); - if (e->type == ewmh[_NET_ACTIVE_WINDOW].atom) { DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_ACTIVE_WINDOW\n"); focus_win(win); @@ -7048,7 +7154,7 @@ clientmessage(xcb_client_message_event_t *e) if (e->type == ewmh[_NET_CLOSE_WINDOW].atom) { DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_CLOSE_WINDOW\n"); if (win->can_delete) - client_msg(win, adelete); + client_msg(win, a_delete); else xcb_kill_client(conn, win->id); } @@ -7087,35 +7193,31 @@ clientmessage(xcb_client_message_event_t *e) } int -xerror_start(Display *d, XErrorEvent *ee) -{ - other_wm = 1; - return (-1); -} - -int -xerror(Display *d, XErrorEvent *ee) -{ - /* warnx("error: %p %p", display, ee); */ - return (-1); -} - -int -active_wm(void) +enable_wm(void) { - other_wm = 0; - xerrorxlib = XSetErrorHandler(xerror_start); + int num_screens, i; + const uint32_t val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; + xcb_screen_t *sc; + xcb_void_cookie_t wac; + xcb_generic_error_t *error; /* this causes an error if some other window manager is running */ - XSelectInput(display, DefaultRootWindow(display), - SubstructureRedirectMask); - do_sync(); - if (other_wm) - return (1); + num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); + for (i = 0; i < num_screens; i++) { + sc = get_screen(i); + DNPRINTF(SWM_D_INIT, "enable_wm: screen %d, root: 0x%x\n", + i, sc->root); + wac = xcb_change_window_attributes_checked(conn, sc->root, + XCB_CW_EVENT_MASK, &val); + if ((error = xcb_request_check(conn, wac))) { + DNPRINTF(SWM_D_INIT, "enable_wm: error_code: %u\n", + error->error_code); + free(error); + return 1; + } + } - XSetErrorHandler(xerror); - do_sync(); - return (0); + return 0; } void @@ -7274,14 +7376,6 @@ screenchange(xcb_randr_screen_change_notify_event_t *e) DNPRINTF(SWM_D_EVENT, "screenchange: root: 0x%x\n", e->root); - if (e->rotation & (XCB_RANDR_ROTATION_ROTATE_90 - | XCB_RANDR_ROTATION_ROTATE_270)) - xcb_randr_set_screen_size(conn, e->root, e->height, - e->width, e->mheight, e->mwidth); - else - xcb_randr_set_screen_size(conn, e->root, e->width, - e->height, e->mwidth, e->mheight); - num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); /* silly event doesn't include the screen index */ for (i = 0; i < num_screens; i++) @@ -7293,6 +7387,9 @@ screenchange(xcb_randr_screen_change_notify_event_t *e) /* brute force for now, just re-enumerate the regions */ scan_xrandr(i); +#ifdef SWM_DEBUG + print_win_geom(e->root); +#endif /* add bars to all regions */ for (i = 0; i < num_screens; i++) TAILQ_FOREACH(r, &screens[i].rl, entry) @@ -7414,7 +7511,7 @@ setup_screens(void) screens[i].idx = i; TAILQ_INIT(&screens[i].rl); TAILQ_INIT(&screens[i].orl); - screens[i].root = RootWindow(display, i); + screens[i].root = get_screen(i)->root; /* set default colors */ setscreencolor("red", i + 1, SWM_S_COLOR_FOCUS); @@ -7471,6 +7568,19 @@ setup_globals(void) if ((clock_format = strdup("%a %b %d %R %Z %Y")) == NULL) err(1, "setup_globals: strdup: failed to allocate memory."); + + if ((syms = xcb_key_symbols_alloc(conn)) == NULL) + errx(1, "unable to allocate key symbols"); + + a_state = get_atom_from_string("WM_STATE"); + a_prot = get_atom_from_string("WM_PROTOCOLS"); + a_delete = get_atom_from_string("WM_DELETE_WINDOW"); + a_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"); } void @@ -7585,16 +7695,9 @@ main(int argc, char *argv[]) start_argv = argv; warnx("Welcome to spectrwm V%s Build: %s", SPECTRWM_VERSION, buildstr); - if (!setlocale(LC_CTYPE, "") || !setlocale(LC_TIME, "") || - !XSupportsLocale()) + if (!setlocale(LC_CTYPE, "") || !setlocale(LC_TIME, "")) warnx("no locale support"); - if (!X_HAVE_UTF8_STRING) - warnx("no UTF-8 support"); - - if (!(display = XOpenDisplay(0))) - errx(1, "can not open display"); - /* handle some signals */ bzero(&sact, sizeof(sact)); sigemptyset(&sact.sa_mask); @@ -7609,24 +7712,12 @@ main(int argc, char *argv[]) sact.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &sact, NULL); - conn = XGetXCBConnection(display); + conn = xcb_connect(NULL, NULL); if (xcb_connection_has_error(conn)) errx(1, "can not get XCB connection"); + xcb_prefetch_extension_data(conn, &xcb_randr_id); xfd = xcb_get_file_descriptor(conn); - syms = xcb_key_symbols_alloc(conn); - if (!syms) - errx(1, "unable to allocate key symbols"); - - 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()); @@ -7643,8 +7734,8 @@ main(int argc, char *argv[]) free(evt); } - if (active_wm()) - errx(1, "other wm running"); + if (enable_wm() != 0) + errx(1, "another window manager is currently running"); xcb_aux_sync(conn); @@ -7773,9 +7864,11 @@ done: for (i = 0; i < num_screens; ++i) if (screens[i].bar_gc != 0) xcb_free_gc(conn, screens[i].bar_gc); +#if 0 XFreeFontSet(display, bar_fs); - +#endif xcb_key_symbols_free(syms); + xcb_flush(conn); xcb_disconnect(conn); return (0);