diff options
| -rw-r--r-- | config.h | 5 | ||||
| -rw-r--r-- | dwm.c | 8 | ||||
| -rw-r--r-- | quicksearch.c | 110 |
3 files changed, 118 insertions, 5 deletions
@@ -74,6 +74,7 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray1, NULL }; static const char *termcmd[] = { "st", NULL }; +#include "quicksearch.c" #include <X11/XF86keysym.h> static const Key keys[] = { /* modifier key function argument */ @@ -113,7 +114,7 @@ static const Key keys[] = { { Mod1Mask, XK_e, spawn, SHCMD(TERMINAL" -c stfloat -e mc --nosubshell") }, { MODKEY|ShiftMask, XK_m, spawn, SHCMD(TERMINAL" -c stfloat -e neomutt") }, { MODKEY, XK_n, spawn, SHCMD(TERMINAL" -c stfloat -e newsboat") }, - { MODKEY, XK_p, spawn, SHCMD(TERMINAL" -c stfloat -e pulsemixer") }, + { Mod1Mask|ShiftMask, XK_p, spawn, SHCMD(TERMINAL" -c stfloat -e pulsemixer") }, { MODKEY, XK_Escape, spawn, SHCMD(TERMINAL" -e htop") }, { Mod1Mask, XK_Escape, spawn, SHCMD(TERMINAL" -c stfloat -e htop") }, { Mod1Mask, XK_n, spawn, SHCMD(TERMINAL" -c stfloat -e nvtop") }, @@ -132,6 +133,8 @@ static const Key keys[] = { { ControlMask, XK_F1, spawn, SHCMD("amixer sset Master toggle") }, { ControlMask, XK_F2, spawn, SHCMD("amixer sset Master 5%-") }, { ControlMask, XK_F3, spawn, SHCMD("amixer sset Master 5%+") }, + + { MODKEY, XK_p, quicksearch, {0} }, }; /* button definitions */ @@ -567,8 +567,8 @@ clientmessage(XEvent *e) setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); } else if (cme->message_type == netatom[NetActiveWindow]) { - if (c != selmon->sel && !c->isurgent) - seturgent(c, 1); + if (c != selmon->sel && !c->isurgent) + seturgent(c, 1); } } @@ -1128,7 +1128,7 @@ movemouse(const Arg *arg) if (!(c = selmon->sel)) return; - if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ + if (c->isfullscreen) return; restack(selmon); ocx = c->x; @@ -1282,7 +1282,7 @@ resizemouse(const Arg *arg) if (!(c = selmon->sel)) return; - if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ + if (c->isfullscreen) return; restack(selmon); ocx = c->x; diff --git a/quicksearch.c b/quicksearch.c new file mode 100644 index 0000000..9cc517c --- /dev/null +++ b/quicksearch.c @@ -0,0 +1,110 @@ +void +quicksearch(const Arg *arg) +{ + Client *c; + Monitor *m; + char *names = NULL; + size_t names_size = 0; + size_t names_len = 0; + int client_count = 0; + Client **clients = NULL; + size_t clients_size = 0; + + for (m = mons; m; m = m->next) { + for (c = m->clients; c; c = c->next) { + if (!ISVISIBLE(c)) { + client_count++; + + char tag_str[64] = "["; + int tag_len = 1; + int first = 1; + for (int i = 0; i < LENGTH(tags); i++) { + if (c->tags & (1 << i)) { + if (!first) tag_len += sprintf(tag_str + tag_len, ","); + tag_len += sprintf(tag_str + tag_len, "%d", i + 1); + first = 0; + } + } + tag_len += sprintf(tag_str + tag_len, "] "); + + size_t name_len = strlen(c->name); + size_t needed = names_len + tag_len + name_len + 1; + + if (needed > names_size) { + names_size = needed * 2; + names = realloc(names, names_size); + if (!names) + die("quicksearch: realloc failed"); + } + + if (client_count > clients_size) { + clients_size = client_count * 2; + clients = realloc(clients, clients_size * sizeof(Client *)); + if (!clients) + die("quicksearch: realloc failed"); + } + + strcpy(names + names_len, tag_str); + names_len += tag_len; + strcpy(names + names_len, c->name); + names_len += name_len; + names[names_len] = '\n'; + names_len++; + + clients[client_count - 1] = c; + } + } + } + + if (client_count == 0) + return; + + names[names_len - 1] = '\0'; + + char dmenu_cmd[256]; + snprintf(dmenu_cmd, sizeof(dmenu_cmd), "echo '%s' | dmenu -l 10 -i -p 'Switch to client:'", names); + + FILE *fp = popen(dmenu_cmd, "r"); + if (!fp) { + free(names); + free(clients); + return; + } + + char selected_name[256]; + if (fgets(selected_name, sizeof(selected_name), fp) != NULL) { + size_t len = strlen(selected_name); + if (len > 0 && selected_name[len - 1] == '\n') + selected_name[len - 1] = '\0'; + + char *client_name = strchr(selected_name, ']'); + if (client_name) { + client_name += 2; + + for (int i = 0; i < client_count; i++) { + if (strcmp(clients[i]->name, client_name) == 0) { + Client *selected_client = clients[i]; + + if (selected_client->mon != selmon) + selmon = selected_client->mon; + + Arg view_arg; + view_arg.ui = selected_client->tags; + view(&view_arg); + + focus(selected_client); + + if (selected_client != nexttiled(selmon->clients)) { + zoom(0); + } + + break; + } + } + } + } + + pclose(fp); + free(names); + free(clients); +} |
