1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
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;
int mode = arg->i;
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 += snprintf(tag_str + tag_len, sizeof(tag_str) - tag_len, ",");
tag_len += snprintf(tag_str + tag_len, sizeof(tag_str) - tag_len, "%d", i + 1);
first = 0;
}
}
tag_len += snprintf(tag_str + tag_len, sizeof(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");
}
strlcpy(names + names_len, tag_str, names_size - names_len);
names_len += tag_len;
strlcpy(names + names_len, c->name, names_size - names_len);
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 'Find 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 (mode == 1) {
selected_client->tags = selmon->tagset[selmon->seltags];
if (selected_client->mon != selmon) {
detach(selected_client);
detachstack(selected_client);
selected_client->mon = selmon;
attach(selected_client);
attachstack(selected_client);
}
focus(selected_client);
arrange(selmon);
} else {
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);
}
|