Skip to content

Commit 20b712d

Browse files
committed
window choosing using dmenu
1 parent ea914c3 commit 20b712d

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

dwm.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ static void showhide(Client *c);
212212
static void sigchld(int unused);
213213
static void spawn(const Arg *arg);
214214
static void gather(const Arg *arg);
215+
static void choose(const Arg *arg);
215216

216217
static void ignore(const Arg *arg) {}
217218

@@ -1780,6 +1781,19 @@ spawn(const Arg *arg)
17801781
}
17811782
}
17821783

1784+
void
1785+
newterm(const Arg* arg) {
1786+
for(Client *c = selmon->clients; c; c = c->next) {
1787+
if(strstr(c->name,arg->s))
1788+
c->tags |= 1 << TMPTAG;
1789+
else
1790+
c->tags &= ~(1<<TMPTAG);
1791+
}
1792+
1793+
view(&(const Arg){.ui = 1 << TMPTAG});
1794+
setlayout(&(const Arg){.v = &layouts[0]});
1795+
}
1796+
17831797
void
17841798
gather(const Arg* arg) {
17851799
for(Client *c = selmon->clients; c; c = c->next) {
@@ -1791,6 +1805,95 @@ gather(const Arg* arg) {
17911805

17921806
view(&(const Arg){.ui = 1 << TMPTAG});
17931807
setlayout(&(const Arg){.v = &layouts[0]});
1808+
1809+
choose(NULL);
1810+
}
1811+
1812+
typedef struct {
1813+
FILE *in, *out, *err;
1814+
pid_t pid;
1815+
} StreamSet;
1816+
1817+
static StreamSet meanwhile(void (*f)(void*), void *ctx) {
1818+
int input_pipe[2];
1819+
if(pipe(input_pipe) != 0)
1820+
return (StreamSet){0};
1821+
1822+
int output_pipe[2];
1823+
if(pipe(output_pipe) != 0)
1824+
return (StreamSet){0};
1825+
1826+
int error_pipe[2];
1827+
if(pipe(error_pipe) != 0)
1828+
return (StreamSet){0};
1829+
1830+
pid_t prog_pid = fork();
1831+
if(prog_pid < 0)
1832+
return (StreamSet){0};
1833+
1834+
else if(prog_pid == 0) {
1835+
close(input_pipe[1]);
1836+
close(output_pipe[0]);
1837+
close(error_pipe[0]);
1838+
dup2(input_pipe[0], STDIN_FILENO);
1839+
dup2(output_pipe[1], STDOUT_FILENO);
1840+
dup2(error_pipe[1], STDERR_FILENO);
1841+
1842+
f(ctx);
1843+
exit(0);
1844+
}
1845+
1846+
close(input_pipe[0]);
1847+
close(output_pipe[1]);
1848+
close(error_pipe[1]);
1849+
1850+
return (StreamSet){
1851+
.in = fdopen(input_pipe[1], "w"),
1852+
.out = fdopen(output_pipe[0], "r"),
1853+
.err = fdopen(error_pipe[0], "r"),
1854+
.pid = prog_pid
1855+
};
1856+
}
1857+
1858+
static void execute(void *_args) {
1859+
char **args = (char**) _args;
1860+
1861+
execvp(args[0], args);
1862+
fprintf(stderr, "box: cannot run %s\n", args[0]);
1863+
exit(1);
1864+
}
1865+
1866+
static void
1867+
choose(const Arg *arg) {
1868+
(void) arg;
1869+
//don't do it if there are no windows to choose
1870+
if(!selmon->sel) return;
1871+
1872+
StreamSet streams = meanwhile(&execute, (char*[]){"dmenu", NULL});
1873+
if(streams.in == NULL)
1874+
fprintf(stderr, "error running dmenu");
1875+
1876+
int tags = selmon->seltags;
1877+
for (Client *c = selmon->clients; c; c = c->next) {
1878+
if((c->tags & tags) == tags) {
1879+
fprintf(streams.in, "%p %s\n", (void*)c, c->name);
1880+
}
1881+
}
1882+
1883+
fclose(streams.in);
1884+
1885+
Client *c;
1886+
if(fscanf(streams.out, "%p", (void**)&c) == 1) {
1887+
if(c) {
1888+
focus(c);
1889+
arrange(selmon);
1890+
}
1891+
} else {
1892+
fprintf(stderr, "couldn't read from dmenu");
1893+
}
1894+
1895+
fclose(streams.out);
1896+
fclose(streams.err);
17941897
}
17951898

17961899
void

0 commit comments

Comments
 (0)