Add module "menu"
This commit is contained in:
parent
7c717ee221
commit
29536e5ebf
4
Makefile
4
Makefile
|
@ -3,7 +3,7 @@
|
|||
|
||||
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}
|
||||
|
||||
DWM_SRC = dwm/handlers.c dwm/layouts.c dwm/swallow.c dwm/systray.c
|
||||
|
@ -21,7 +21,7 @@ options:
|
|||
${CC} -c $< -o $@ ${CFLAGS}
|
||||
|
||||
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}
|
||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||
|
|
22
dwm.c
22
dwm.c
|
@ -20,7 +20,6 @@
|
|||
*
|
||||
* To understand everything else, start reading main().
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -50,6 +49,7 @@
|
|||
#include "drw.h"
|
||||
#include "helpers.h"
|
||||
#include "layouts.h"
|
||||
#include "menu.h"
|
||||
#include "settings.h"
|
||||
#include "spawn.h"
|
||||
#include "tags.h"
|
||||
|
@ -1243,25 +1243,11 @@ movemouse(const Arg *arg)
|
|||
// TODO: this function really needs to be refactored
|
||||
void
|
||||
nametag(const Arg *arg) {
|
||||
char *p, name[TAGS_CUSTOM_NAME_SIZE];
|
||||
FILE *f;
|
||||
int i;
|
||||
char name[TAGS_CUSTOM_NAME_SIZE];
|
||||
|
||||
errno = 0; // popen(3p) says on failure it "may" set errno
|
||||
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';
|
||||
if (!menu_run(name, TAGS_CUSTOM_NAME_SIZE, "Tag name")) return;
|
||||
|
||||
for (i = 0; i < TAGS_COUNT; ++i) {
|
||||
for (int i = 0; i < TAGS_COUNT; ++i) {
|
||||
if (selmon->tagset[selmon->seltags] & (1 << i)) {
|
||||
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