X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=5c791a179ada934903abf5107a028b7c3cf49d21;hb=fe71db40e007b2fcd53261c3a8b998cdea85da7b;hp=e54a743c59e953d4c11942512f132962b245ec3a;hpb=a28e0d1b2fcfbc6f93c0888c0f5781d0cb5417bd;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index e54a743..5c791a1 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -89,20 +89,17 @@ #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 +179,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 +197,7 @@ u_int32_t swm_debug = 0 | SWM_D_EVENTQ | SWM_D_CONF | SWM_D_BAR + | SWM_D_INIT ; #else #define DPRINTF(x...) @@ -359,12 +358,6 @@ XFontSetExtents *bar_fs_extents; 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; @@ -1281,12 +1274,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,15 +1319,15 @@ 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; len = strlen(s); /* FIXME fix bar font position calculations */ #if 0 + int x = 0; + XRectangle ibox, lbox; XmbTextExtents(bar_fs, s, len, &ibox, &lbox); switch (bar_justify) { @@ -1553,7 +1546,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, " "); } @@ -1576,7 +1569,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) */ @@ -1632,7 +1625,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) @@ -3987,7 +3980,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); @@ -4016,7 +4009,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); @@ -5001,7 +4994,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"); @@ -5484,8 +5477,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 }; @@ -6185,7 +6178,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; } @@ -6329,7 +6322,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); @@ -6341,7 +6334,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; @@ -6349,7 +6342,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; @@ -6468,7 +6461,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", @@ -6746,7 +6739,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); @@ -6766,6 +6760,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) { @@ -6777,42 +6789,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); @@ -6976,17 +6998,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); @@ -6996,14 +7018,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); @@ -7061,15 +7096,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); @@ -7116,33 +7163,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); -} - -void -active_wm(void) +enable_wm(void) { 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 */ num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) { sc = get_screen(i); - xcb_change_window_attributes(conn, sc->root, + 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; + } } + + return 0; } void @@ -7308,6 +7353,7 @@ screenchange(xcb_randr_screen_change_notify_event_t *e) else xcb_randr_set_screen_size(conn, e->root, e->width, e->height, e->mwidth, e->mheight); + xcb_flush(conn); num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); /* silly event doesn't include the screen index */ @@ -7625,13 +7671,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"); - /* handle some signals */ bzero(&sact, sizeof(sact)); sigemptyset(&sact.sa_mask); @@ -7650,6 +7692,7 @@ main(int argc, char *argv[]) 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); /* look for local and global conf file */ @@ -7667,12 +7710,11 @@ main(int argc, char *argv[]) free(evt); } - active_wm(); - xcb_aux_sync(conn); - - if (xcb_poll_for_event(conn) != NULL) + if (enable_wm() != 0) errx(1, "another window manager is currently running"); + xcb_aux_sync(conn); + setup_globals(); setup_screens(); setup_keys(); @@ -7802,6 +7844,7 @@ done: XFreeFontSet(display, bar_fs); #endif xcb_key_symbols_free(syms); + xcb_flush(conn); xcb_disconnect(conn); return (0);