summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorProsperousPotato <114923153+ProsperousPotato@users.noreply.github.com>2025-07-14 17:09:29 +0100
committerGitHub <noreply@github.com>2025-07-14 17:09:29 +0100
commitd72a512a6ec77306618ffcec52953e5034534a34 (patch)
treec8157ef2a2c380e1ecef738a22a5ef565392b5b6
parent9f7359ebcb0b4bf93ee0682a8c23be016b88e40e (diff)
add quicksearch
-rw-r--r--config.h5
-rw-r--r--dwm.c8
-rw-r--r--quicksearch.c110
3 files changed, 118 insertions, 5 deletions
diff --git a/config.h b/config.h
index 6c6945e..666520a 100644
--- a/config.h
+++ b/config.h
@@ -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 */
diff --git a/dwm.c b/dwm.c
index 43adc34..1f30a6b 100644
--- a/dwm.c
+++ b/dwm.c
@@ -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);
+}