Move tag naming code into separate module

This commit is contained in:
Alex Kotov 2021-11-14 05:10:13 +05:00
parent 5c195a31ee
commit 30e1efff67
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
5 changed files with 117 additions and 35 deletions

View File

@ -3,7 +3,7 @@
include config.mk
SRC = atoms.c datetime.c drw.c dwm.c settings.c status.c util.c
SRC = atoms.c datetime.c drw.c dwm.c settings.c status.c tags.c util.c
OBJ = ${SRC:.c=.o}
all: options dwm
@ -17,7 +17,7 @@ options:
%.o: %.c
${CC} -c $< -o $@ ${CFLAGS}
${OBJ}: atoms.h datetime.h drw.h config.def.h config.mk settings.h status.h util.h
${OBJ}: atoms.h datetime.h drw.h config.def.h config.mk settings.h status.h tags.h util.h
dwm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}

View File

@ -23,12 +23,6 @@ static const unsigned int systrayspacing = 2; /* systray spacing */
static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
static const int showsystray = 1; /* 0 means no systray */
/* tagging */
#define MAX_TAGNAME_LEN 14 /* excludes TAG_PREPEND */
#define TAG_PREPEND "%1i:" /* formatted as 2 chars */
#define MAX_TAGLEN 16 /* altogether */
static char tags[][MAX_TAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class

47
dwm.c
View File

@ -46,6 +46,7 @@
#include "drw.h"
#include "settings.h"
#include "status.h"
#include "tags.h"
#include "util.h"
/* macros */
@ -58,7 +59,7 @@
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TAGMASK ((1 << TAGS_COUNT) - 1)
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
#define SYSTEM_TRAY_REQUEST_DOCK 0
@ -310,16 +311,13 @@ static Window root, wmcheckwin;
struct Pertag {
unsigned int curtag, prevtag; /* current and previous tag */
int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
int nmasters[TAGS_COUNT + 1]; /* number of windows in master area */
float mfacts[TAGS_COUNT + 1]; /* mfacts per tag */
unsigned int sellts[TAGS_COUNT + 1]; /* selected layouts */
const Layout *ltidxs[TAGS_COUNT + 1][2]; /* matrix of tags and layouts indexes */
int showbars[TAGS_COUNT + 1]; /* display bar for the current tag */
};
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
/* function implementations */
void
applyrules(Client *c)
@ -497,11 +495,11 @@ buttonpress(XEvent *e)
occ |= c->tags == 255 ? 0 : c->tags;
do {
/* do not reserve space for vacant tags */
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i || tags[i][1] != '\0'))
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i || tags_get(i)->has_custom_name))
continue;
x += TEXTW(tags[i]);
} while (ev->x >= x && ++i < LENGTH(tags));
if (i < LENGTH(tags)) {
x += TEXTW(tags_get(i)->name.cstr);
} while (ev->x >= x && ++i < TAGS_COUNT);
if (i < TAGS_COUNT) {
click = ClkTagBar;
arg.ui = 1 << i;
} else if (ev->x < x + blw)
@ -836,7 +834,7 @@ createmon(void)
m->pertag = ecalloc(1, sizeof(Pertag));
m->pertag->curtag = m->pertag->prevtag = 1;
for (i = 0; i <= LENGTH(tags); i++) {
for (i = 0; i <= TAGS_COUNT; i++) {
m->pertag->nmasters[i] = m->nmaster;
m->pertag->mfacts[i] = m->mfact;
@ -929,14 +927,14 @@ drawbar(Monitor *m)
urg |= c->tags;
}
x = 0;
for (i = 0; i < LENGTH(tags); i++) {
for (i = 0; i < TAGS_COUNT; i++) {
/* do not draw vacant tags */
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i || tags[i][1] != '\0'))
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i || tags_get(i)->has_custom_name))
continue;
w = TEXTW(tags[i]);
w = TEXTW(tags_get(i)->name.cstr);
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
drw_text(drw, x, 0, w, bh, lrpad / 2, tags_get(i)->name.cstr, urg & 1 << i);
x += w;
}
w = blw = TEXTW(m->ltsymbol);
@ -1485,7 +1483,7 @@ movemouse(const Arg *arg)
// TODO: this function really needs to be refactored
void
nametag(const Arg *arg) {
char *p, name[MAX_TAGNAME_LEN];
char *p, name[TAGS_CUSTOM_NAME_SIZE];
FILE *f;
int i;
@ -1494,7 +1492,7 @@ nametag(const Arg *arg) {
fprintf(stderr, "dwm: popen 'dmenu < /dev/null' failed%s%s\n", errno ? ": " : "", errno ? strerror(errno) : "");
return;
}
if (!(p = fgets(name, MAX_TAGNAME_LEN, f)) && (i = errno) && ferror(f))
if (!(p = fgets(name, TAGS_CUSTOM_NAME_SIZE, f)) && (i = errno) && ferror(f))
fprintf(stderr, "dwm: fgets failed: %s\n", strerror(i));
if (pclose(f) < 0)
fprintf(stderr, "dwm: pclose failed: %s\n", strerror(errno));
@ -1503,14 +1501,9 @@ nametag(const Arg *arg) {
if((p = strchr(name, '\n')))
*p = '\0';
for (i = 0; i < LENGTH(tags); ++i) {
for (i = 0; i < TAGS_COUNT; ++i) {
if (selmon->tagset[selmon->seltags] & (1 << i)) {
if (name[0] == '\0') {
sprintf(tags[i], "%d", i + 1);
} else {
sprintf(tags[i], TAG_PREPEND, i + 1);
strcat(tags[i], name);
}
tags_rename(i, name);
}
}

65
tags.c Normal file
View File

@ -0,0 +1,65 @@
#include "tags.h"
#include <stddef.h>
#include <string.h>
static struct Tag tags[TAGS_COUNT] = {
[0] = {
.has_custom_name = false,
.name = { .structured = { .number = '1', .colon_or_eol = '\0' } },
},
[1] = {
.has_custom_name = false,
.name = { .structured = { .number = '2', .colon_or_eol = '\0' } },
},
[2] = {
.has_custom_name = false,
.name = { .structured = { .number = '3', .colon_or_eol = '\0' } },
},
[3] = {
.has_custom_name = false,
.name = { .structured = { .number = '4', .colon_or_eol = '\0' } },
},
[4] = {
.has_custom_name = false,
.name = { .structured = { .number = '5', .colon_or_eol = '\0' } },
},
[5] = {
.has_custom_name = false,
.name = { .structured = { .number = '6', .colon_or_eol = '\0' } },
},
[6] = {
.has_custom_name = false,
.name = { .structured = { .number = '7', .colon_or_eol = '\0' } },
},
[7] = {
.has_custom_name = false,
.name = { .structured = { .number = '8', .colon_or_eol = '\0' } },
},
[8] = {
.has_custom_name = false,
.name = { .structured = { .number = '9', .colon_or_eol = '\0' } },
},
};
const struct Tag *tags_get(const unsigned int index)
{
if (index >= TAGS_COUNT) return NULL;
return &tags[index];
}
void tags_rename(const unsigned int index, const char *const new_custom_name)
{
if (index >= TAGS_COUNT) return;
if (new_custom_name == NULL || new_custom_name[0] == '\0') {
tags[index].has_custom_name = false;
tags[index].name.structured.colon_or_eol = '\0';
} else {
tags[index].has_custom_name = true;
tags[index].name.structured.colon_or_eol = ':';
strncpy(tags[index].name.structured.custom_name, new_custom_name, TAGS_CUSTOM_NAME_SIZE);
tags[index].name.structured.custom_name[TAGS_CUSTOM_NAME_SIZE - 1] = '\0';
}
}

30
tags.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _TAGS_H
#define _TAGS_H
#include <stdbool.h>
#define TAGS_COUNT (9)
#define TAGS_CUSTOM_NAME_SLEN (13)
#define TAGS_CUSTOM_NAME_SIZE ((TAGS_CUSTOM_NAME_SLEN) + 1)
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[TAGS_COUNT > 31 ? -1 : 1]; };
struct __attribute__((packed)) TagName {
char number;
char colon_or_eol;
char custom_name[TAGS_CUSTOM_NAME_SIZE];
};
struct Tag {
bool has_custom_name;
union {
char cstr[sizeof(struct TagName) / sizeof(char)];
struct TagName structured;
} name;
};
const struct Tag *tags_get(unsigned int index);
void tags_rename(unsigned int index, const char *new_custom_name);
#endif // _TAGS_H