Add module "menu"
This commit is contained in:
parent
7c717ee221
commit
29536e5ebf
4
Makefile
4
Makefile
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
SRC = atoms.c drw.c dwm.c helpers.c layouts.c settings.c spawn.c tags.c util.c
|
SRC = atoms.c drw.c dwm.c helpers.c layouts.c menu.c settings.c spawn.c tags.c util.c
|
||||||
OBJ = ${SRC:.c=.o}
|
OBJ = ${SRC:.c=.o}
|
||||||
|
|
||||||
DWM_SRC = dwm/handlers.c dwm/layouts.c dwm/swallow.c dwm/systray.c
|
DWM_SRC = dwm/handlers.c dwm/layouts.c dwm/swallow.c dwm/systray.c
|
||||||
|
@ -21,7 +21,7 @@ options:
|
||||||
${CC} -c $< -o $@ ${CFLAGS}
|
${CC} -c $< -o $@ ${CFLAGS}
|
||||||
|
|
||||||
dwm.o: ${DWM_SRC} ${DWM_HDR}
|
dwm.o: ${DWM_SRC} ${DWM_HDR}
|
||||||
${OBJ}: atoms.h drw.h config.def.h config.mk helpers.h layouts.h settings.h spawn.h tags.h util.h
|
${OBJ}: atoms.h drw.h config.def.h config.mk helpers.h layouts.h menu.h settings.h spawn.h tags.h util.h
|
||||||
|
|
||||||
polytreewm: ${OBJ}
|
polytreewm: ${OBJ}
|
||||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||||
|
|
22
dwm.c
22
dwm.c
|
@ -20,7 +20,6 @@
|
||||||
*
|
*
|
||||||
* To understand everything else, start reading main().
|
* To understand everything else, start reading main().
|
||||||
*/
|
*/
|
||||||
#include <errno.h>
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -50,6 +49,7 @@
|
||||||
#include "drw.h"
|
#include "drw.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "layouts.h"
|
#include "layouts.h"
|
||||||
|
#include "menu.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "spawn.h"
|
#include "spawn.h"
|
||||||
#include "tags.h"
|
#include "tags.h"
|
||||||
|
@ -1243,25 +1243,11 @@ movemouse(const Arg *arg)
|
||||||
// TODO: this function really needs to be refactored
|
// TODO: this function really needs to be refactored
|
||||||
void
|
void
|
||||||
nametag(const Arg *arg) {
|
nametag(const Arg *arg) {
|
||||||
char *p, name[TAGS_CUSTOM_NAME_SIZE];
|
char name[TAGS_CUSTOM_NAME_SIZE];
|
||||||
FILE *f;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
errno = 0; // popen(3p) says on failure it "may" set errno
|
if (!menu_run(name, TAGS_CUSTOM_NAME_SIZE, "Tag name")) return;
|
||||||
if(!(f = popen("rofi -dmenu -p \"Tag name\"", "r"))) {
|
|
||||||
fprintf(stderr, "polytreewm: popen 'rofi -dmenu -p \"Tag name\"' failed%s%s\n", errno ? ": " : "", errno ? strerror(errno) : "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(p = fgets(name, TAGS_CUSTOM_NAME_SIZE, f)) && (i = errno) && ferror(f))
|
|
||||||
fprintf(stderr, "polytreewm: fgets failed: %s\n", strerror(i));
|
|
||||||
if (pclose(f) < 0)
|
|
||||||
fprintf(stderr, "polytreewm: pclose failed: %s\n", strerror(errno));
|
|
||||||
if(!p)
|
|
||||||
return;
|
|
||||||
if((p = strchr(name, '\n')))
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
for (i = 0; i < TAGS_COUNT; ++i) {
|
for (int i = 0; i < TAGS_COUNT; ++i) {
|
||||||
if (selmon->tagset[selmon->seltags] & (1 << i)) {
|
if (selmon->tagset[selmon->seltags] & (1 << i)) {
|
||||||
tags_rename(i, name);
|
tags_rename(i, name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "menu.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define COMMAND_SIZE 256
|
||||||
|
|
||||||
|
bool menu_run(
|
||||||
|
char *const buffer,
|
||||||
|
const size_t buffer_size,
|
||||||
|
const char *prompt
|
||||||
|
) {
|
||||||
|
// TODO: maybe we should assert here
|
||||||
|
if (buffer == NULL || buffer_size < 2) return false;
|
||||||
|
|
||||||
|
if (prompt == NULL) {
|
||||||
|
prompt = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const char *s = prompt; *s; ++s) {
|
||||||
|
// Simple check to ensure that the prompt
|
||||||
|
// string doesn't need to be escaped.
|
||||||
|
// TODO: maybe we should assert here
|
||||||
|
if (*s == '"') return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char command[COMMAND_SIZE];
|
||||||
|
const int command_slen =
|
||||||
|
snprintf(command, COMMAND_SIZE, "rofi -dmenu -p \"%s\"", prompt);
|
||||||
|
|
||||||
|
// Simple check to ensure that the prompt string is not too long.
|
||||||
|
// TODO: maybe we should assert here
|
||||||
|
if (command_slen >= COMMAND_SIZE) return false;
|
||||||
|
|
||||||
|
errno = 0; // popen(3p) says on failure it "may" set errno
|
||||||
|
FILE *f = popen(command, "r");
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
perror("polytreewm: menu: popen failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *const buffer_result = fgets(buffer, buffer_size, f);
|
||||||
|
|
||||||
|
// Just to ensure that string is null-terminated.
|
||||||
|
// The man page fgets(3) is not very clear about that.
|
||||||
|
buffer[buffer_size - 1] = '\0';
|
||||||
|
|
||||||
|
if (!buffer_result) {
|
||||||
|
perror("polytreewm: menu: fgets failed");
|
||||||
|
pclose(f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail on both pipe error and not successfull exit status.
|
||||||
|
if (pclose(f) != EXIT_SUCCESS) {
|
||||||
|
perror("polytreewm: menu: pclose failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (char *s = buffer; *s; ++s) {
|
||||||
|
if (*s == '\n') {
|
||||||
|
if (*(s + 1) == '\0') {
|
||||||
|
*s = '\0';
|
||||||
|
} else {
|
||||||
|
*s = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
Loading…
Reference in New Issue