diff options
| -rw-r--r-- | README.md | 7 | ||||
| -rwxr-xr-x | colitur-x | bin | 27032 -> 27120 bytes | |||
| -rw-r--r-- | colitur-x.c | 39 | ||||
| -rw-r--r-- | config.h | 31 |
4 files changed, 59 insertions, 18 deletions
@@ -14,8 +14,15 @@ presentation choice and belongs in a viewer: colitur's own kernel is pure and deliberately never asks what day it is, which is what lets it be tested to the year 9999. + colitur-x -g 1200x820 < day.csv # preferred size, if the WM allows CX_DUMP=/tmp/f.ppm colitur-x < day.csv # write one frame, then exit +The grid **fills whatever size it is given**: cell width is the window +divided seven ways, cell height six ways, and the number of lines a feast +name gets is whatever fits. Under a tiling window manager it therefore uses +its whole tile rather than sitting in a corner of one, and resizing reflows +instead of clipping. `config.h` sets minimums, not sizes. + It reads CSV on **stdin** and nothing else, so the shell decides what it shows. One month: diff --git a/colitur-x.c b/colitur-x.c index 5307c24..dffbbe6 100644 --- a/colitur-x.c +++ b/colitur-x.c @@ -198,6 +198,14 @@ static void redraw(void) } fill(col_bg, 0, 0, wa.width, wa.height); + /* Cells are sized from the window, not from a constant, so the grid + fills its tile. Six rows is the most a month can need: 31 days + starting on a Saturday spans six Sunday-started weeks. */ + int CELL_W = (wa.width - 2 * PAD) / 7; + int CELL_H = (wa.height - HEAD_H - DETAIL_H) / 6; + if (CELL_W < CELL_W_MIN) CELL_W = CELL_W_MIN; + if (CELL_H < CELL_H_MIN) CELL_H = CELL_H_MIN; + XftColor head, detail, sel_dark, sel_light, grid; alloc(col_head, &head); alloc(col_detail, &detail); alloc(col_sel_dark, &sel_dark); alloc(col_sel_light, &sel_light); @@ -256,8 +264,11 @@ static void redraw(void) character count, so it is right for any font in config.h. */ const char *nm = rows[i].f[6]; int avail = CELL_W - 12, ty = y + bigh + 8 + fnt->ascent; + int room = (CELL_H - 2 - (bigh + 8)) / lh; /* lines that fit */ + if (room > NAME_LINES_MAX) room = NAME_LINES_MAX; + if (room < 1) room = 1; const char *p = nm; - for (int ln = 0; ln < NAME_LINES && *p; ln++) { + for (int ln = 0; ln < room && *p; ln++) { size_t take = strlen(p), best = 0; XGlyphInfo gi; for (size_t k = 1; k <= take; k++) { @@ -298,8 +309,20 @@ static void redraw(void) } } -int main(void) +static void usage(void) { + fputs("usage: colitur-x [-g WxH] < calendar.csv\n", stderr); + exit(2); +} + +int main(int argc, char **argv) +{ + int w = WIN_W, h = WIN_H; + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-g") && i + 1 < argc) { + if (sscanf(argv[++i], "%dx%d", &w, &h) != 2) usage(); + } else usage(); + } load(); if (!nrows) { fputs("colitur-x: no rows on stdin\n", stderr); return 2; } select_today(); @@ -309,17 +332,19 @@ int main(void) vis = DefaultVisual(dpy, scr); cmap = DefaultColormap(dpy, scr); - int w = PAD*2 + 7*CELL_W, h = HEAD_H + 6*CELL_H + DETAIL_H; win = XCreateSimpleWindow(dpy, RootWindow(dpy, scr), 0, 0, w, h, 0, BlackPixel(dpy, scr), BlackPixel(dpy, scr)); XStoreName(dpy, win, window_title); - { /* Ask the window manager for exactly the grid we drew. Without - this a tiling or maximising WM picks its own size and the grid - floats in a field of background. */ + { /* A PREFERRED size and a MINIMUM, never a fixed one. Pinning the + size was the earlier mistake: it fights a tiling window manager, + which ignores it anyway, and it stops the grid making use of a + larger tile. The layout reflows, so any size above the minimum + is legitimate. */ XSizeHints *sh = XAllocSizeHints(); sh->flags = PSize | PMinSize; sh->width = w; sh->height = h; - sh->min_width = w; sh->min_height = h; + sh->min_width = PAD*2 + 7*CELL_W_MIN; + sh->min_height = HEAD_H + 6*CELL_H_MIN + DETAIL_H; XSetWMNormalHints(dpy, win, sh); XFree(sh); } @@ -39,18 +39,27 @@ static const char *col_sel_light = "#ffd24a"; enum { SEL_RING = 3 }; /* px per ring */ /* --------------------------------------------------------------- geometry */ -/* CELL_W/CELL_H must suit the font: a cell holds the day number plus - NAME_LINES lines of `font`. Line height itself is taken from the font at - runtime, so only these two need revisiting when you change size. - Rough guide: CELL_W >= 10 * (widest name chars you want), CELL_H >= - big-font height + NAME_LINES * font height + 12. */ +/* The grid FILLS the window: cell size is computed from whatever space the + window manager gives us, divided seven across and six down. Under a + tiling WM that means the calendar uses its whole tile instead of sitting + in a corner of it, and resizing reflows rather than clipping. + + These are therefore MINIMUMS, not sizes. If the window is too small to + honour them the grid stops shrinking and simply overflows -- better than + cells too small to read. How many lines a name gets is likewise derived + from the cell height at runtime; NAME_LINES_MAX only caps it. */ enum { - CELL_W = 196, - CELL_H = 116, - PAD = 10, /* margin around the grid */ - HEAD_H = 62, /* title + weekday headings */ - DETAIL_H = 116, /* the pane under the grid */ - NAME_LINES = 3, /* how many lines a feast name gets */ + CELL_W_MIN = 96, + CELL_H_MIN = 52, + PAD = 10, /* margin around the grid */ + HEAD_H = 62, /* title + weekday headings */ + DETAIL_H = 116, /* the pane under the grid */ + NAME_LINES_MAX = 5, + + /* Preferred size when the window manager lets us choose. A tiling WM + will not, and that is fine: the grid reflows to whatever it gets. */ + WIN_W = 1200, + WIN_H = 820, }; /* ------------------------------------------------------------------ labels */ |
