diff --git a/calmwm.c b/calmwm.c index ed18a6a..71ee1f6 100644 --- a/calmwm.c +++ b/calmwm.c @@ -35,7 +35,6 @@ #include "calmwm.h" -char **cwm_argv; Display *X_Dpy; Time Last_Event_Time = CurrentTime; Atom cwmh[CWMH_NITEMS]; @@ -47,10 +46,12 @@ struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq); int HasRandr, Randr_ev; struct conf Conf; const char *homedir; +volatile sig_atomic_t cwm_status; static void sigchld_cb(int); static int x_errorhandler(Display *, XErrorEvent *); static void x_init(const char *); +static void x_restart(char **); static void x_teardown(void); static int x_wmerrorhandler(Display *, XErrorEvent *); @@ -59,6 +60,7 @@ main(int argc, char **argv) { const char *conf_file = NULL; char *conf_path, *display_name = NULL; + char **cwm_argv; int ch; struct passwd *pw; @@ -111,8 +113,12 @@ main(int argc, char **argv) free(conf_path); x_init(display_name); - xev_loop(); + cwm_status = CWM_RUNNING; + while (cwm_status == CWM_RUNNING) + xev_process(); x_teardown(); + if (cwm_status == CWM_RESTART) + x_restart(cwm_argv); return (0); } @@ -140,9 +146,35 @@ x_init(const char *dpyname) screen_init(i); } +static void +x_restart(char **args) +{ + (void)setsid(); + (void)execvp(args[0], args); +} + static void x_teardown(void) { + struct screen_ctx *sc; + unsigned int i; + + TAILQ_FOREACH(sc, &Screenq, entry) { + for (i = 0; i < CWM_COLOR_NITEMS; i++) + XftColorFree(X_Dpy, sc->visual, sc->colormap, + &sc->xftcolor[i]); + XftDrawDestroy(sc->xftdraw); + XftFontClose(X_Dpy, sc->xftfont); + XUnmapWindow(X_Dpy, sc->menuwin); + XDestroyWindow(X_Dpy, sc->menuwin); + XUngrabKey(X_Dpy, AnyKey, AnyModifier, sc->rootwin); + } + XUngrabPointer(X_Dpy, CurrentTime); + XUngrabKeyboard(X_Dpy, CurrentTime); + for (i = 0; i < CF_NITEMS; i++) + XFreeCursor(X_Dpy, Conf.cursor[i]); + XSync(X_Dpy, False); + XSetInputFocus(X_Dpy, PointerRoot, RevertToPointerRoot, CurrentTime); XCloseDisplay(X_Dpy); } diff --git a/calmwm.h b/calmwm.h index 0f2bde6..e8042c1 100644 --- a/calmwm.h +++ b/calmwm.h @@ -97,6 +97,10 @@ size_t strlcat(char *, const char *, size_t); #define CWM_WIN 0x0001 +#define CWM_QUIT 0x0000 +#define CWM_RUNNING 0x0001 +#define CWM_RESTART 0x0002 + union arg { char *c; int i; @@ -339,6 +343,7 @@ extern struct client_ctx_q Clientq; extern struct conf Conf; extern const char *homedir; extern int HasRandr, Randr_ev; +extern volatile sig_atomic_t cwm_status; enum { WM_STATE, @@ -485,11 +490,10 @@ void kbfunc_client_search(struct client_ctx *, union arg *); void kbfunc_client_vmaximize(struct client_ctx *, union arg *); void kbfunc_cmdexec(struct client_ctx *, union arg *); +void kbfunc_cwm_status(struct client_ctx *, union arg *); void kbfunc_exec(struct client_ctx *, union arg *); void kbfunc_lock(struct client_ctx *, union arg *); void kbfunc_menu_search(struct client_ctx *, union arg *); -void kbfunc_quit_wm(struct client_ctx *, union arg *); -void kbfunc_restart(struct client_ctx *, union arg *); void kbfunc_ssh(struct client_ctx *, union arg *); void kbfunc_term(struct client_ctx *, union arg *); void kbfunc_tile(struct client_ctx *, union arg *); @@ -539,7 +543,7 @@ void conf_init(struct conf *); void conf_ignore(struct conf *, const char *); void conf_screen(struct screen_ctx *); -void xev_loop(void); +void xev_process(void); void xu_btn_grab(Window, int, unsigned int); void xu_btn_ungrab(Window); diff --git a/conf.c b/conf.c index 142ee40..16faf30 100644 --- a/conf.c +++ b/conf.c @@ -120,7 +120,7 @@ conf_screen(struct screen_ctx *sc) xu_xorcolor(sc->xftcolor[CWM_COLOR_MENU_FONT], xc, &xc); if (!XftColorAllocValue(X_Dpy, sc->visual, sc->colormap, &xc.color, &sc->xftcolor[CWM_COLOR_MENU_FONT_SEL])) - warnx("XftColorAllocValue: '%s'", Conf.color[i]); + warnx("XftColorAllocValue: %s", Conf.color[i]); break; } if (XftColorAllocName(X_Dpy, sc->visual, sc->colormap, @@ -128,7 +128,7 @@ conf_screen(struct screen_ctx *sc) sc->xftcolor[i] = xc; XftColorFree(X_Dpy, sc->visual, sc->colormap, &xc); } else { - warnx("XftColorAllocName: '%s'", Conf.color[i]); + warnx("XftColorAllocName: %s", Conf.color[i]); XftColorAllocName(X_Dpy, sc->visual, sc->colormap, color_binds[i], &sc->xftcolor[i]); } @@ -373,8 +373,8 @@ static const struct { { "vmaximize", kbfunc_client_vmaximize, CWM_WIN, {0} }, { "hmaximize", kbfunc_client_hmaximize, CWM_WIN, {0} }, { "freeze", kbfunc_client_freeze, CWM_WIN, {0} }, - { "restart", kbfunc_restart, 0, {0} }, - { "quit", kbfunc_quit_wm, 0, {0} }, + { "restart", kbfunc_cwm_status, 0, {.i = CWM_RESTART} }, + { "quit", kbfunc_cwm_status, 0, {.i = CWM_QUIT} }, { "exec", kbfunc_exec, 0, {.i = CWM_EXEC_PROGRAM} }, { "exec_wm", kbfunc_exec, 0, {.i = CWM_EXEC_WM} }, { "ssh", kbfunc_ssh, 0, {0} }, diff --git a/group.c b/group.c index fe5eb3a..990b914 100644 --- a/group.c +++ b/group.c @@ -105,7 +105,7 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc) if (cc->stackingorder > gc->highstack) gc->highstack = cc->stackingorder; } - winlist = (Window *) xcalloc(sizeof(*winlist), (gc->highstack + 1)); + winlist = xcalloc((gc->highstack + 1), sizeof(*winlist)); /* * Invert the stacking order as XRestackWindows() expects them diff --git a/kbfunc.c b/kbfunc.c index 26e6d3d..dc3f401 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -35,9 +35,6 @@ #define HASH_MARKER "|1|" -extern char **cwm_argv; -extern sig_atomic_t xev_quit; - void kbfunc_client_lower(struct client_ctx *cc, union arg *arg) { @@ -239,15 +236,15 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg) int l, i, cmd = arg->i; switch (cmd) { - case CWM_EXEC_PROGRAM: - label = "exec"; - break; - case CWM_EXEC_WM: - label = "wm"; - break; - default: - errx(1, "kbfunc_exec: invalid cmd %d", cmd); - /*NOTREACHED*/ + case CWM_EXEC_PROGRAM: + label = "exec"; + break; + case CWM_EXEC_WM: + label = "wm"; + break; + default: + errx(1, "kbfunc_exec: invalid cmd %d", cmd); + /*NOTREACHED*/ } TAILQ_INIT(&menuq); @@ -289,16 +286,16 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg) if (mi->text[0] == '\0') goto out; switch (cmd) { - case CWM_EXEC_PROGRAM: - u_spawn(mi->text); - break; - case CWM_EXEC_WM: - u_exec(mi->text); - warn("%s", mi->text); - break; - default: - errx(1, "kb_func: egad, cmd changed value!"); - break; + case CWM_EXEC_PROGRAM: + u_spawn(mi->text); + break; + case CWM_EXEC_WM: + u_exec(mi->text); + warn("%s", mi->text); + break; + default: + errx(1, "kb_func: egad, cmd changed value!"); + break; } } out: @@ -357,8 +354,8 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg) search_match_exec, NULL)) != NULL) { if (mi->text[0] == '\0') goto out; - l = snprintf(cmd, sizeof(cmd), "%s -e ssh %s", Conf.termpath, - mi->text); + l = snprintf(cmd, sizeof(cmd), "%s -T '[ssh] %s' -e ssh %s", + Conf.termpath, mi->text, mi->text); if (l != -1 && l < sizeof(cmd)) u_spawn(cmd); } @@ -464,27 +461,20 @@ kbfunc_client_freeze(struct client_ctx *cc, union arg *arg) } void -kbfunc_quit_wm(struct client_ctx *cc, union arg *arg) +kbfunc_cwm_status(struct client_ctx *cc, union arg *arg) { - xev_quit = 1; -} - -void -kbfunc_restart(struct client_ctx *cc, union arg *arg) -{ - (void)setsid(); - (void)execvp(cwm_argv[0], cwm_argv); + cwm_status = arg->i; } void kbfunc_tile(struct client_ctx *cc, union arg *arg) { switch (arg->i) { - case CWM_TILE_HORIZ: - client_htile(cc); - break; - case CWM_TILE_VERT: - client_vtile(cc); - break; + case CWM_TILE_HORIZ: + client_htile(cc); + break; + case CWM_TILE_VERT: + client_vtile(cc); + break; } } diff --git a/parse.y b/parse.y index 188c090..6fbeb8d 100644 --- a/parse.y +++ b/parse.y @@ -118,21 +118,21 @@ main : FONTNAME STRING { conf->flags |= CONF_STICKY_GROUPS; } | BORDERWIDTH NUMBER { - if ($2 < 0) { + if ($2 < 0 || $2 > UINT_MAX) { yyerror("invalid borderwidth: %d", $2); YYERROR; } conf->bwidth = $2; } | MOVEAMOUNT NUMBER { - if ($2 < 0) { + if ($2 < 0 || $2 > INT_MAX) { yyerror("invalid movemount: %d", $2); YYERROR; } conf->mamount = $2; } | SNAPDIST NUMBER { - if ($2 < 0) { + if ($2 < 0 || $2 > INT_MAX) { yyerror("invalid snapdist: %d", $2); YYERROR; } @@ -167,7 +167,10 @@ main : FONTNAME STRING { free($3); } | GAP NUMBER NUMBER NUMBER NUMBER { - if ($2 < 0 || $3 < 0 || $4 < 0 || $5 < 0) { + if ($2 < 0 || $2 > INT_MAX || + $3 < 0 || $3 > INT_MAX || + $4 < 0 || $4 > INT_MAX || + $5 < 0 || $5 > INT_MAX) { yyerror("invalid gap: %d %d %d %d", $2, $3, $4, $5); YYERROR; diff --git a/xevents.c b/xevents.c index 55dabab..6844f98 100644 --- a/xevents.c +++ b/xevents.c @@ -400,18 +400,14 @@ xev_handle_expose(XEvent *ee) client_draw_border(cc); } -volatile sig_atomic_t xev_quit = 0; - void -xev_loop(void) +xev_process(void) { XEvent e; - while (xev_quit == 0) { - XNextEvent(X_Dpy, &e); - if (e.type - Randr_ev == RRScreenChangeNotify) - xev_handle_randr(&e); - else if (e.type < LASTEvent && xev_handlers[e.type] != NULL) - (*xev_handlers[e.type])(&e); - } + XNextEvent(X_Dpy, &e); + if (e.type - Randr_ev == RRScreenChangeNotify) + xev_handle_randr(&e); + else if (e.type < LASTEvent && xev_handlers[e.type] != NULL) + (*xev_handlers[e.type])(&e); }