X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=f42432a9fac37071a5d7420139ffb27170be5776;hb=9b55b66ab52e3f8ec45663b07cf6b80095e2c14c;hp=d160c47e5c3bf23d6320bcdedf98e6e4f26c0dbb;hpb=45ef141d5c94019c82cc1ea17b89c081b0037c91;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index d160c47..f42432a 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -62,10 +63,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -85,7 +88,6 @@ #endif #endif -#define SWM_DEBUG /* #define SWM_DEBUG */ #ifdef SWM_DEBUG #define DPRINTF(x...) do { if (swm_debug) fprintf(stderr, x); } while(0) @@ -132,12 +134,14 @@ Display *display; /* dialog windows */ double dialog_ratio = .6; /* status bar */ +#define SWM_BAR_MAX (128) +sig_atomic_t bar_alarm = 0; int bar_enabled = 1; +int bar_verbose = 1; int bar_height = 0; GC bar_gc; XGCValues bar_gcv; XFontStruct *bar_fs; -char bar_text[128]; char *bar_fonts[] = { "-*-terminus-*-*-*-*-*-*-*-*-*-*-*-*", "-*-times-medium-r-*-*-*-*-*-*-*-*-*-*", @@ -241,6 +245,7 @@ struct swm_screen { unsigned long bar_font_color; unsigned long color_focus; /* XXX should this be per ws? */ unsigned long color_unfocus; + char bar_text[SWM_BAR_MAX]; }; struct swm_screen *screens; int num_screens; @@ -385,44 +390,55 @@ bad: } void -bar_print(struct swm_region *r) +bar_print(struct swm_region *r, char *s, int erase) +{ + if (erase) { + XSetForeground(display, bar_gc, r->s->bar_color); + XDrawString(display, r->bar_window, bar_gc, 4, bar_fs->ascent, + r->s->bar_text, strlen(r->s->bar_text)); + } + + strlcpy(r->s->bar_text, s, sizeof r->s->bar_text); + XSetForeground(display, bar_gc, r->s->bar_font_color); + XDrawString(display, r->bar_window, bar_gc, 4, bar_fs->ascent, + r->s->bar_text, strlen(r->s->bar_text)); +} + +void +bar_update(void) { time_t tmt; struct tm tm; - + struct swm_region *r; + int i; + char s[SWM_BAR_MAX]; + if (bar_enabled == 0) return; - /* clear old text */ - XSetForeground(display, bar_gc, r->s->bar_color); - XDrawString(display, r->bar_window, - bar_gc, 4, bar_fs->ascent, bar_text, strlen(bar_text)); - /* draw new text */ time(&tmt); localtime_r(&tmt, &tm); - strftime(bar_text, sizeof bar_text, "%a %b %d %R %Z %Y", &tm); - XSetForeground(display, bar_gc, r->s->bar_font_color); - XDrawString(display, r->bar_window, bar_gc, 4, - bar_fs->ascent, bar_text, strlen(bar_text)); - XSync(display, False); + strftime(s, sizeof s, "%a %b %d %R %Z %Y", &tm); + for (i = 0; i < ScreenCount(display); i++) + TAILQ_FOREACH(r, &screens[i].rl, entry) + bar_print(r, s, 1); + XSync(display, False); alarm(60); } void bar_signal(int sig) { - /* XXX yeah yeah byte me */ - if (cur_focus) - bar_print(cur_focus->ws->r); + bar_alarm = 1; } void bar_toggle(struct swm_region *r, union arg *args) { - struct swm_region *tmpr; - int i, j; + struct swm_region *tmpr; + int i, j; DNPRINTF(SWM_D_MISC, "bar_toggle\n"); @@ -445,7 +461,7 @@ bar_toggle(struct swm_region *r, union arg *args) /* must be after stack */ for (i = 0; i < ScreenCount(display); i++) TAILQ_FOREACH(tmpr, &screens[i].rl, entry) - bar_print(tmpr); + bar_update(); } void @@ -463,7 +479,7 @@ bar_setup(struct swm_region *r) bar_height = bar_fs->ascent + bar_fs->descent + 3; r->bar_window = XCreateSimpleWindow(display, - r->s->root, X(r), Y(r), WIDTH(r), bar_height - 2, + r->s->root, X(r), Y(r), WIDTH(r) - 2, bar_height - 2, 1, r->s->bar_border, r->s->bar_color); bar_gc = XCreateGC(display, r->bar_window, 0, &bar_gcv); XSetFont(display, bar_gc, bar_fs->fid); @@ -474,7 +490,7 @@ bar_setup(struct swm_region *r) if (signal(SIGALRM, bar_signal) == SIG_ERR) err(1, "could not install bar_signal"); - bar_print(r); + bar_update(); } void @@ -528,6 +544,11 @@ restart(struct swm_region *r, union arg *args) { DNPRINTF(SWM_D_MISC, "restart: %s\n", start_argv[0]); + /* disable alarm because the following code may not be interrupted */ + alarm(0); + if (signal(SIGALRM, SIG_IGN) == SIG_ERR) + errx(1, "can't disable alarm"); + XCloseDisplay(display); execvp(start_argv[0], start_argv); fprintf(stderr, "execvp failed\n"); @@ -660,10 +681,8 @@ switchws(struct swm_region *r, union arg *args) return; other_r = new_ws->r; - fprintf(stderr, "switchws: other_r %p\n", other_r); if (!other_r) { /* if the other workspace is hidden, switch windows */ - /* map new window first to prevent ugly blinking */ TAILQ_FOREACH(win, &new_ws->winlist, entry) XMapRaised(display, win->id); @@ -1232,9 +1251,9 @@ grabkeys(void) if (TAILQ_EMPTY(&screens[k].rl)) continue; XUngrabKey(display, AnyKey, AnyModifier, screens[k].root); - for(i = 0; i < LENGTH(keys); i++) { - if((code = XKeysymToKeycode(display, keys[i].keysym))) - for(j = 0; j < LENGTH(modifiers); j++) + for (i = 0; i < LENGTH(keys); i++) { + if ((code = XKeysymToKeycode(display, keys[i].keysym))) + for (j = 0; j < LENGTH(modifiers); j++) XGrabKey(display, code, keys[i].mod | modifiers[j], screens[k].root, True, @@ -1461,7 +1480,6 @@ destroynotify(XEvent *e) set_win_state(win, WithdrawnState); free(win); } - stack(); } @@ -1474,7 +1492,7 @@ enternotify(XEvent *e) DNPRINTF(SWM_D_EVENT, "enternotify: window: %lu\n", ev->window); - if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && + if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != ev->root) return; if (ignore_enter) { @@ -1569,7 +1587,7 @@ visibilitynotify(XEvent *e) for (i = 0; i < ScreenCount(display); i++) TAILQ_FOREACH(r, &screens[i].rl, entry) if (e->xvisibility.window == r->bar_window) - bar_print(r); + bar_update(); } void (*handler[LASTEvent])(XEvent *) = { @@ -1667,16 +1685,16 @@ void setup_screens(void) { #ifdef SWM_XRR_HAS_CRTC - XRRCrtcInfo *crtc_info; - XRRScreenResources *res; + XRRCrtcInfo *ci; + XRRScreenResources *sr; int c; #endif /* SWM_XRR_HAS_CRTC */ Window d1, d2, *wins = NULL; XWindowAttributes wa; struct swm_region *r; - unsigned int num; + unsigned int no; int errorbase, major, minor; - int ncrtc, w = 0; + int ncrtc = 0, w = 0; int i, j, k; struct workspace *ws; @@ -1710,10 +1728,9 @@ setup_screens(void) ws->r = NULL; TAILQ_INIT(&ws->winlist); - for (k = 0; layouts[k].l_stack != NULL; k++) { + for (k = 0; layouts[k].l_stack != NULL; k++) if (layouts[k].l_init != NULL) layouts[k].l_init(ws); - } ws->cur_layout = &layouts[0]; } @@ -1733,41 +1750,37 @@ setup_screens(void) #endif /* grab existing windows (before we build the bars)*/ - if (!XQueryTree(display, screens[i].root, - &d1, &d2, &wins, &num)) { - if (wins) /* not sure if this is necessary */ - XFree(wins); + if (!XQueryTree(display, screens[i].root, &d1, &d2, &wins, &no)) continue; - } #ifdef SWM_XRR_HAS_CRTC - res = XRRGetScreenResources(display, screens[i].root); - if (res == NULL) { - ncrtc = 0; + sr = XRRGetScreenResources(display, screens[i].root); + if (sr == NULL) new_region(&screens[i], &screens[i].ws[w], 0, 0, DisplayWidth(display, i), DisplayHeight(display, i)); - } else - ncrtc = res->ncrtc; + else + ncrtc = sr->ncrtc; for (c = 0; c < ncrtc; c++) { - crtc_info = XRRGetCrtcInfo(display, res, res->crtcs[c]); - if (crtc_info->noutput == 0) + ci = XRRGetCrtcInfo(display, sr, sr->crtcs[c]); + if (ci->noutput == 0) continue; - if (crtc_info != NULL && crtc_info->mode == None) - new_region(&screens[i], &screens[i].ws[w], - 0, 0, DisplayWidth(display, i), + if (ci != NULL && ci->mode == None) + new_region(&screens[i], &screens[i].ws[w], 0, 0, + DisplayWidth(display, i), DisplayHeight(display, i)); else new_region(&screens[i], &screens[i].ws[w], - crtc_info->x, crtc_info->y, - crtc_info->width, crtc_info->height); + ci->x, ci->y, ci->width, ci->height); w++; } + XRRFreeCrtcInfo(ci); + XRRFreeScreenResources(sr); #else - new_region(&screens[i], &screens[i].ws[w], - 0, 0, DisplayWidth(display, i), + new_region(&screens[i], &screens[i].ws[w], 0, 0, + DisplayWidth(display, i), DisplayHeight(display, i)); #endif /* SWM_XRR_HAS_CRTC */ @@ -1776,27 +1789,31 @@ setup_screens(void) if ((r = TAILQ_FIRST(&screens[i].rl)) == NULL) errx(1, "no regions on screen %d", i); - for (i = 0; i < num; i++) { + for (i = 0; i < no; i++) { XGetWindowAttributes(display, wins[i], &wa); if (!XGetWindowAttributes(display, wins[i], &wa) || wa.override_redirect || XGetTransientForHint(display, wins[i], &d1)) continue; + if (wa.map_state == IsViewable || getstate(wins[i]) == NormalState) manage_window(wins[i], r->ws); } /* transient windows */ - for (i = 0; i < num; i++) { + for (i = 0; i < no; i++) { if (!XGetWindowAttributes(display, wins[i], &wa)) continue; + if (XGetTransientForHint(display, wins[i], &d1) && (wa.map_state == IsViewable || getstate(wins[i]) == NormalState)) manage_window(wins[i], r->ws); } - if (wins) + if (wins) { XFree(wins); + wins = NULL; + } } } @@ -1807,6 +1824,8 @@ main(int argc, char *argv[]) char conf[PATH_MAX], *cfile = NULL; struct stat sb; XEvent e; + int xfd; + fd_set rd; start_argv = argv; fprintf(stderr, "Welcome to scrotwm V%s\n", SWM_VERSION); @@ -1842,15 +1861,26 @@ main(int argc, char *argv[]) setup_screens(); - //ws[0].focus = TAILQ_FIRST(&ws[0].winlist); + /* ws[0].focus = TAILQ_FIRST(&ws[0].winlist); */ grabkeys(); stack(); + xfd = ConnectionNumber(display); while (running) { - XNextEvent(display, &e); - if (handler[e.type]) - handler[e.type](&e); + FD_SET(xfd, &rd); + if (select(xfd + 1, &rd, NULL, NULL, NULL) == -1) + if (errno != EINTR) + errx(1, "select failed"); + if (bar_alarm) { + bar_alarm = 0; + bar_update(); + } + while(XPending(display)) { + XNextEvent(display, &e); + if (handler[e.type]) + handler[e.type](&e); + } } XCloseDisplay(display);