diff options
-rw-r--r-- | calmwm.c | 9 | ||||
-rw-r--r-- | calmwm.h | 7 | ||||
-rw-r--r-- | conf.c | 20 | ||||
-rw-r--r-- | cwmrc.5 | 16 | ||||
-rw-r--r-- | kbfunc.c | 50 | ||||
-rw-r--r-- | search.c | 188 |
6 files changed, 192 insertions, 98 deletions
diff --git a/calmwm.c b/calmwm.c index 7988273..c3943c4 100644 --- a/calmwm.c +++ b/calmwm.c @@ -42,7 +42,6 @@ Atom cwmh[CWMH_NITEMS]; Atom ewmh[EWMH_NITEMS]; struct screen_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq); struct conf Conf; -const char *homedir; volatile sig_atomic_t cwm_status; static void sighdlr(int); @@ -82,16 +81,16 @@ main(int argc, char **argv) if (signal(SIGCHLD, sighdlr) == SIG_ERR) err(1, "signal"); - if ((homedir = getenv("HOME")) == NULL || *homedir == '\0') { + if ((Conf.homedir = getenv("HOME")) == NULL || Conf.homedir[0] == '\0') { pw = getpwuid(getuid()); if (pw != NULL && pw->pw_dir != NULL && *pw->pw_dir != '\0') - homedir = pw->pw_dir; + Conf.homedir = pw->pw_dir; else - homedir = "/"; + Conf.homedir = "/"; } if (conf_file == NULL) - xasprintf(&conf_path, "%s/%s", homedir, CONFFILE); + xasprintf(&conf_path, "%s/%s", Conf.homedir, CONFFILE); else conf_path = xstrdup(conf_file); diff --git a/calmwm.h b/calmwm.h index 9ac69a4..26d8189 100644 --- a/calmwm.h +++ b/calmwm.h @@ -314,6 +314,7 @@ struct conf { Cursor cursor[CF_NITEMS]; int xrandr; int xrandr_event_base; + char *homedir; char *wm_argv; }; @@ -395,7 +396,6 @@ extern Atom cwmh[CWMH_NITEMS]; extern Atom ewmh[EWMH_NITEMS]; extern struct screen_q Screenq; extern struct conf Conf; -extern const char *homedir; void usage(void); @@ -465,6 +465,10 @@ void search_match_path(struct menu_q *, struct menu_q *, char *); void search_match_text(struct menu_q *, struct menu_q *, char *); +void search_match_cmd(struct menu_q *, struct menu_q *, + char *); +void search_match_group(struct menu_q *, struct menu_q *, + char *); void search_print_client(struct menu *, int); void search_print_cmd(struct menu *, int); void search_print_group(struct menu *, int); @@ -482,6 +486,7 @@ void screen_assert_clients_within(struct screen_ctx *); void kbfunc_cwm_status(void *, struct cargs *); void kbfunc_ptrmove(void *, struct cargs *); +void kbfunc_client_snap(void *, struct cargs *); void kbfunc_client_move(void *, struct cargs *); void kbfunc_client_resize(void *, struct cargs *); void kbfunc_client_delete(void *, struct cargs *); diff --git a/conf.c b/conf.c index d750c42..0234f48 100644 --- a/conf.c +++ b/conf.c @@ -92,6 +92,24 @@ static const struct { { "window-movetogroup-8", kbfunc_client_movetogroup, CWM_CONTEXT_CC, 8 }, { "window-movetogroup-9", kbfunc_client_movetogroup, CWM_CONTEXT_CC, 9 }, + { "window-snap-up", kbfunc_client_snap, CWM_CONTEXT_CC, + (CWM_UP) }, + { "window-snap-down", kbfunc_client_snap, CWM_CONTEXT_CC, + (CWM_DOWN) }, + { "window-snap-left", kbfunc_client_snap, CWM_CONTEXT_CC, + (CWM_LEFT) }, + { "window-snap-right", kbfunc_client_snap, CWM_CONTEXT_CC, + (CWM_RIGHT) }, + + { "window-snap-up-right", kbfunc_client_snap, CWM_CONTEXT_CC, + (CWM_UP|CWM_RIGHT) }, + { "window-snap-up-left", kbfunc_client_snap, CWM_CONTEXT_CC, + (CWM_UP|CWM_LEFT) }, + { "window-snap-down-right", kbfunc_client_snap, CWM_CONTEXT_CC, + (CWM_DOWN|CWM_RIGHT) }, + { "window-snap-down-left", kbfunc_client_snap, CWM_CONTEXT_CC, + (CWM_DOWN|CWM_LEFT) }, + { "window-move", kbfunc_client_move, CWM_CONTEXT_CC, 0 }, { "window-move-up", kbfunc_client_move, CWM_CONTEXT_CC, (CWM_UP) }, @@ -297,7 +315,7 @@ conf_init(struct conf *c) conf_cmd_add(c, "term", "xterm"); (void)snprintf(c->known_hosts, sizeof(c->known_hosts), "%s/%s", - homedir, ".ssh/known_hosts"); + c->homedir, ".ssh/known_hosts"); c->font = xstrdup("sans-serif:pixelsize=14:bold"); c->wmname = xstrdup("CWM"); diff --git a/cwmrc.5 b/cwmrc.5 index a29fd12..6851faa 100644 --- a/cwmrc.5 +++ b/cwmrc.5 @@ -398,6 +398,22 @@ pixels right. Resize window 10 times .Ar moveamount pixels left. +.It window-snap-up +Snap window to top edge. +.It window-snap-down +Snap window to bottom edge. +.It window-snap-right +Snap window to right edge. +.It window-snap-left +Snap window to left edge. +.It window-snap-up-right +Snap window to top-right corner. +.It window-snap-up-left +Snap window to top-left corner. +.It window-snap-down-right +Snap window to bottom-right corner. +.It window-snap-down-left +Snap window to bottom-left corner. .It pointer-move-up Move pointer .Ar moveamount diff --git a/kbfunc.c b/kbfunc.c index 01d45b0..e2a125b 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -290,6 +290,42 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs) } void +kbfunc_client_snap(void *ctx, struct cargs *cargs) +{ + struct client_ctx *cc = ctx; + struct screen_ctx *sc = cc->sc; + struct geom area; + int flags; + + area = screen_area(sc, + cc->geom.x + cc->geom.w / 2, + cc->geom.y + cc->geom.h / 2, CWM_GAP); + + flags = cargs->flag; + while (flags) { + if (flags & CWM_UP) { + cc->geom.y = area.y; + flags &= ~CWM_UP; + } + if (flags & CWM_LEFT) { + cc->geom.x = area.x; + flags &= ~CWM_LEFT; + } + if (flags & CWM_RIGHT) { + cc->geom.x = area.x + area.w - cc->geom.w - + (cc->bwidth * 2); + flags &= ~CWM_RIGHT; + } + if (flags & CWM_DOWN) { + cc->geom.y = area.y + area.h - cc->geom.h - + (cc->bwidth * 2); + flags &= ~CWM_DOWN; + } + } + client_move(cc); +} + +void kbfunc_client_delete(void *ctx, struct cargs *cargs) { client_send_delete(ctx); @@ -463,14 +499,13 @@ kbfunc_menu_cmd(void *ctx, struct cargs *cargs) if ((strcmp(cmd->name, "lock") == 0) || (strcmp(cmd->name, "term") == 0)) continue; - /* search_match_text() needs mi->text */ - menuq_add(&menuq, cmd, "%s", cmd->name); + menuq_add(&menuq, cmd, NULL); } if ((mi = menu_filter(sc, &menuq, (m) ? NULL : "application", NULL, ((m) ? CWM_MENU_LIST : 0), - search_match_text, search_print_cmd)) != NULL) { + search_match_cmd, search_print_cmd)) != NULL) { cmd = (struct cmd_ctx *)mi->ctx; u_spawn(cmd->path); } @@ -491,12 +526,12 @@ kbfunc_menu_group(void *ctx, struct cargs *cargs) TAILQ_FOREACH(gc, &sc->groupq, entry) { if (group_holds_only_sticky(gc)) continue; - menuq_add(&menuq, gc, "%d %s", gc->num, gc->name); + menuq_add(&menuq, gc, NULL); } if ((mi = menu_filter(sc, &menuq, (m) ? NULL : "group", NULL, (CWM_MENU_LIST), - search_match_text, search_print_group)) != NULL) { + search_match_group, search_print_group)) != NULL) { gc = (struct group_ctx *)mi->ctx; (group_holds_only_hidden(gc)) ? group_show(gc) : group_hide(gc); @@ -631,9 +666,8 @@ kbfunc_menu_ssh(void *ctx, struct cargs *cargs) /* skip hashed hosts */ if (strncmp(buf, HASH_MARKER, strlen(HASH_MARKER)) == 0) continue; - for (p = buf; *p != ',' && *p != ' ' && p != buf + slen; p++) { - /* do nothing */ - } + for (p = buf; *p != ',' && *p != ' ' && p != buf + slen; p++) + ; /* ignore badness */ if (p - buf + 1 > sizeof(hostbuf)) continue; diff --git a/search.c b/search.c index 7d32291..68c064e 100644 --- a/search.c +++ b/search.c @@ -36,9 +36,35 @@ #define PATH_ANY 0x0001 #define PATH_EXEC 0x0002 -static void search_match_path_type(struct menu_q *, struct menu_q *, - char *, int); -static int strsubmatch(char *, char *, int); +static void match_path_type(struct menu_q *, char *, int); +static int match_substr(char *, char *, int); + +static int +match_substr(char *sub, char *str, int zeroidx) +{ + size_t len, sublen; + unsigned int n, flen; + + if (sub == NULL || str == NULL) + return(0); + + len = strlen(str); + sublen = strlen(sub); + + if (sublen > len) + return(0); + + if (zeroidx) + flen = 0; + else + flen = len - sublen; + + for (n = 0; n <= flen; n++) + if (strncasecmp(sub, str + n, sublen) == 0) + return(1); + + return(0); +} void search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search) @@ -46,29 +72,28 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search) struct winname *wn; struct menu *mi, *tierp[4], *before = NULL; - TAILQ_INIT(resultq); - (void)memset(tierp, 0, sizeof(tierp)); + TAILQ_INIT(resultq); TAILQ_FOREACH(mi, menuq, entry) { int tier = -1, t; struct client_ctx *cc = (struct client_ctx *)mi->ctx; /* Match on label. */ - if (strsubmatch(search, cc->label, 0)) + if (match_substr(search, cc->label, 0)) tier = 0; /* Match on window name history, from present to past. */ if (tier < 0) { TAILQ_FOREACH_REVERSE(wn, &cc->nameq, name_q, entry) - if (strsubmatch(search, wn->name, 0)) { + if (match_substr(search, wn->name, 0)) { tier = 2; break; } } /* Match on window resource class. */ - if ((tier < 0) && strsubmatch(search, cc->ch.res_class, 0)) + if ((tier < 0) && match_substr(search, cc->ch.res_class, 0)) tier = 3; if (tier < 0) @@ -105,48 +130,36 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search) } void -search_print_text(struct menu *mi, int listing) -{ - (void)snprintf(mi->print, sizeof(mi->print), "%s", mi->text); -} - -void -search_print_cmd(struct menu *mi, int listing) -{ - struct cmd_ctx *cmd = (struct cmd_ctx *)mi->ctx; - - (void)snprintf(mi->print, sizeof(mi->print), "%s", cmd->name); -} - -void -search_print_group(struct menu *mi, int listing) +search_match_cmd(struct menu_q *menuq, struct menu_q *resultq, char *search) { - struct group_ctx *gc = (struct group_ctx *)mi->ctx; + struct menu *mi; - (void)snprintf(mi->print, sizeof(mi->print), - (group_holds_only_hidden(gc)) ? "%d: [%s]" : "%d: %s", - gc->num, gc->name); + TAILQ_INIT(resultq); + TAILQ_FOREACH(mi, menuq, entry) { + struct cmd_ctx *cmd = (struct cmd_ctx *)mi->ctx; + if (match_substr(search, cmd->name, 0)) + TAILQ_INSERT_TAIL(resultq, mi, resultentry); + } } void -search_print_client(struct menu *mi, int listing) +search_match_group(struct menu_q *menuq, struct menu_q *resultq, char *search) { - struct client_ctx *cc = (struct client_ctx *)mi->ctx; - char flag = ' '; - - if (cc->flags & CLIENT_ACTIVE) - flag = '!'; - else if (cc->flags & CLIENT_HIDDEN) - flag = '&'; + struct menu *mi; + char *s; - (void)snprintf(mi->print, sizeof(mi->print), "(%d) %c[%s] %s", - (cc->gc) ? cc->gc->num : 0, flag, - (cc->label) ? cc->label : "", cc->name); + TAILQ_INIT(resultq); + TAILQ_FOREACH(mi, menuq, entry) { + struct group_ctx *gc = (struct group_ctx *)mi->ctx; + xasprintf(&s, "%d %s", gc->num, gc->name); + if (match_substr(search, s, 0)) + TAILQ_INSERT_TAIL(resultq, mi, resultentry); + free(s); + } } static void -search_match_path_type(struct menu_q *menuq, struct menu_q *resultq, - char *search, int flag) +match_path_type(struct menu_q *resultq, char *search, int flag) { struct menu *mi; char pattern[PATH_MAX]; @@ -155,7 +168,6 @@ search_match_path_type(struct menu_q *menuq, struct menu_q *resultq, (void)strlcpy(pattern, search, sizeof(pattern)); (void)strlcat(pattern, "*", sizeof(pattern)); - if (glob(pattern, GLOB_MARK, NULL, &g) != 0) return; for (i = 0; i < g.gl_pathc; i++) { @@ -169,35 +181,14 @@ search_match_path_type(struct menu_q *menuq, struct menu_q *resultq, } void -search_match_path(struct menu_q *menuq, struct menu_q *resultq, char *search) -{ - TAILQ_INIT(resultq); - - search_match_path_type(menuq, resultq, search, PATH_ANY); -} - -void -search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search) -{ - struct menu *mi; - - TAILQ_INIT(resultq); - - TAILQ_FOREACH(mi, menuq, entry) - if (strsubmatch(search, mi->text, 0)) - TAILQ_INSERT_TAIL(resultq, mi, resultentry); -} - -void search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search) { struct menu *mi, *mj; int r; TAILQ_INIT(resultq); - TAILQ_FOREACH(mi, menuq, entry) { - if (strsubmatch(search, mi->text, 1) == 0 && + if (match_substr(search, mi->text, 1) == 0 && fnmatch(search, mi->text, 0) == FNM_NOMATCH) continue; TAILQ_FOREACH(mj, resultq, resultentry) { @@ -210,34 +201,65 @@ search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search) if (mj == NULL) TAILQ_INSERT_TAIL(resultq, mi, resultentry); } - if (TAILQ_EMPTY(resultq)) - search_match_path_type(menuq, resultq, search, PATH_EXEC); + match_path_type(resultq, search, PATH_EXEC); } -static int -strsubmatch(char *sub, char *str, int zeroidx) +void +search_match_path(struct menu_q *menuq, struct menu_q *resultq, char *search) { - size_t len, sublen; - unsigned int n, flen; + TAILQ_INIT(resultq); + match_path_type(resultq, search, PATH_ANY); +} - if (sub == NULL || str == NULL) - return(0); +void +search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search) +{ + struct menu *mi; - len = strlen(str); - sublen = strlen(sub); + TAILQ_INIT(resultq); + TAILQ_FOREACH(mi, menuq, entry) { + if (match_substr(search, mi->text, 0)) + TAILQ_INSERT_TAIL(resultq, mi, resultentry); + } +} - if (sublen > len) - return(0); +void +search_print_client(struct menu *mi, int listing) +{ + struct client_ctx *cc = (struct client_ctx *)mi->ctx; + char flag = ' '; - if (!zeroidx) - flen = len - sublen; - else - flen = 0; + if (cc->flags & CLIENT_ACTIVE) + flag = '!'; + else if (cc->flags & CLIENT_HIDDEN) + flag = '&'; - for (n = 0; n <= flen; n++) - if (strncasecmp(sub, str + n, sublen) == 0) - return(1); + (void)snprintf(mi->print, sizeof(mi->print), "(%d) %c[%s] %s", + (cc->gc) ? cc->gc->num : 0, flag, + (cc->label) ? cc->label : "", cc->name); +} - return(0); +void +search_print_cmd(struct menu *mi, int listing) +{ + struct cmd_ctx *cmd = (struct cmd_ctx *)mi->ctx; + + (void)snprintf(mi->print, sizeof(mi->print), "%s", cmd->name); +} + +void +search_print_group(struct menu *mi, int listing) +{ + struct group_ctx *gc = (struct group_ctx *)mi->ctx; + + (void)snprintf(mi->print, sizeof(mi->print), + (group_holds_only_hidden(gc)) ? "%d: [%s]" : "%d: %s", + gc->num, gc->name); +} + +void +search_print_text(struct menu *mi, int listing) +{ + (void)snprintf(mi->print, sizeof(mi->print), "%s", mi->text); } |