From d6a475e4b1c0d5025806c4a6e47c68e46a3c31d9 Mon Sep 17 00:00:00 2001 From: muennich Date: Mon, 7 Jan 2013 14:30:42 +0100 Subject: [PATCH 1/4] Simplified status bar, filled by user script --- main.c | 149 ++++++++++++++++++++++++++++++++++--------------------- window.c | 143 ++++++++++++++++++++++++++-------------------------- window.h | 16 +++--- 3 files changed, 173 insertions(+), 135 deletions(-) diff --git a/main.c b/main.c index 3b5f9b9..936be3e 100644 --- a/main.c +++ b/main.c @@ -39,8 +39,10 @@ #include "config.h" enum { - INFO_STR_LEN = 256, - FILENAME_CNT = 1024 + BAR_L_LEN = 512, + BAR_R_LEN = 64, + FILENAME_CNT = 1024, + TITLE_LEN = 256 }; typedef struct { @@ -63,15 +65,18 @@ win_t win; fileinfo_t *files; int filecnt, fileidx; int alternate; -size_t filesize; int prefix; bool resized = false; -char win_bar_l[INFO_STR_LEN]; -char win_bar_r[INFO_STR_LEN]; -char win_title[INFO_STR_LEN]; +const char * const INFO_SCRIPT = ".sxiv/exec/image-info"; +char *info_script; + +struct { + char l[BAR_L_LEN]; + char r[BAR_R_LEN]; +} bar; timeout_t timeouts[] = { { { 0, 0 }, false, redraw }, @@ -202,9 +207,37 @@ bool check_timeouts(struct timeval *t) { return tmin > 0; } -void load_image(int new) { - struct stat fstats; +void read_info(void) { + char cmd[4096]; + FILE *outp; + int c, i = 0, n = sizeof(bar.l) - 1; + bool lastsep = false; + + if (info_script != NULL) { + snprintf(cmd, sizeof(cmd), "%s \"%s\"", info_script, files[fileidx].name); + outp = popen(cmd, "r"); + if (outp == NULL) + goto end; + while (i < n && (c = fgetc(outp)) != EOF) { + if (c == '\n') { + if (!lastsep) { + bar.l[i++] = ' '; + lastsep = true; + } + } else { + bar.l[i++] = c; + lastsep = false; + } + } + pclose(outp); + } +end: + if (lastsep) + i--; + bar.l[i] = '\0'; +} +void load_image(int new) { if (new < 0 || new >= filecnt) return; @@ -220,10 +253,8 @@ void load_image(int new) { files[new].loaded = true; alternate = fileidx; fileidx = new; - if (stat(files[new].path, &fstats) == 0) - filesize = fstats.st_size; - else - filesize = 0; + + read_info(); if (img.multi.cnt > 0 && img.multi.animate) set_timeout(animate, img.multi.frames[img.multi.sel].delay, true); @@ -232,60 +263,51 @@ void load_image(int new) { } void update_info(void) { - int i, fw, pw, fi, ln, rn; - char frame_info[16]; - const char *size_unit; - float size = filesize; + unsigned int i, fn, fw, n, len = sizeof(bar.r); + int sel; + char *t = bar.r, title[TITLE_LEN]; + bool ow_info; - pw = 0; - for (i = filecnt; i > 0; i /= 10) - pw++; + for (fw = 0, i = filecnt; i > 0; fw++, i /= 10); + sel = mode == MODE_IMAGE ? fileidx : tns.sel; if (mode == MODE_THUMB) { - if (tns.cnt != filecnt) { - snprintf(win_bar_l, sizeof win_bar_l, "Loading... %0*d/%d", - pw, tns.cnt, filecnt); - } else { - fi = snprintf(win_bar_l, sizeof win_bar_l, "%0*d/%d%s", - pw, tns.sel + 1, filecnt, BAR_SEPARATOR); - ln = snprintf(win_bar_l + fi, sizeof win_bar_l - fi, "%s", - files[tns.sel].name) + fi; - if (win_textwidth(win_bar_l, ln, true) > win.w) - snprintf(win_bar_l + fi, sizeof win_bar_l - fi, "%s", - files[tns.sel].base); - } win_set_title(&win, "sxiv"); - win_set_bar_info(&win, win_bar_l, NULL); - } else { - size_readable(&size, &size_unit); - if (img.multi.cnt > 0) { - fw = 0; - for (i = img.multi.cnt; i > 0; i /= 10) - fw++; - snprintf(frame_info, sizeof frame_info, "%s%0*d/%d", - BAR_SEPARATOR, fw, img.multi.sel+1, img.multi.cnt); + + if (tns.cnt == filecnt) { + n = snprintf(t, len, "%0*d/%d", fw, sel + 1, filecnt); + ow_info = true; } else { - frame_info[0] = '\0'; + snprintf(bar.l, sizeof(bar.l), "Loading... %0*d/%d", + fw, tns.cnt, filecnt); + bar.r[0] = '\0'; + ow_info = false; } - fi = snprintf(win_bar_l, sizeof win_bar_l, "%0*d/%d%s", - pw, fileidx + 1, filecnt, BAR_SEPARATOR); - ln = snprintf(win_bar_l + fi, sizeof win_bar_l - fi, "%s", - files[fileidx].name) + fi; - rn = snprintf(win_bar_r, sizeof win_bar_r, "%.2f%s%s%dx%d%s%3d%%%s", - size, size_unit, BAR_SEPARATOR, img.w, img.h, BAR_SEPARATOR, - (int) (img.zoom * 100.0), frame_info); + } else { + snprintf(title, sizeof(title), "sxiv - %s", files[sel].name); + win_set_title(&win, title); - if (win_textwidth(win_bar_l, ln, true) + - win_textwidth(win_bar_r, rn, true) > win.w) - { - snprintf(win_bar_l + fi, sizeof win_bar_l - fi, "%s", - files[fileidx].base); + n = snprintf(t, len, "%3d%% ", (int) (img.zoom * 100.0)); + if (img.multi.cnt > 0) { + for (fn = 0, i = img.multi.cnt; i > 0; fn++, i /= 10); + n += snprintf(t + n, len - n, "(%0*d/%d) ", + fn, img.multi.sel + 1, img.multi.cnt); } - win_set_bar_info(&win, win_bar_l, win_bar_r); - - snprintf(win_title, sizeof win_title, "sxiv - %s", files[fileidx].name); - win_set_title(&win, win_title); + n += snprintf(t + n, len - n, "%0*d/%d", fw, sel + 1, filecnt); + ow_info = bar.l[0] == '\0'; } + if (ow_info) { + fn = strlen(files[sel].name); + if (fn < sizeof(bar.l) && + win_textwidth(files[sel].name, fn, true) + + win_textwidth(bar.r, n, true) < win.w) + { + strncpy(bar.l, files[sel].name, sizeof(bar.l)); + } else { + strncpy(bar.l, files[sel].base, sizeof(bar.l)); + } + } + win_set_bar_info(&win, bar.l, bar.r); } void redraw(void) { @@ -519,6 +541,7 @@ int main(int argc, char **argv) { size_t n; ssize_t len; char *filename; + const char *homedir; struct stat fstats; r_dir_t dir; @@ -595,6 +618,18 @@ int main(int argc, char **argv) { win_init(&win); img_init(&img, &win); + if ((homedir = getenv("HOME")) == NULL) { + warn("could not locate home directory"); + } else { + len = strlen(homedir) + strlen(INFO_SCRIPT) + 2; + info_script = (char*) s_malloc(len); + snprintf(info_script, len, "%s/%s", homedir, INFO_SCRIPT); + if (access(info_script, X_OK) != 0) { + free(info_script); + info_script = NULL; + } + } + if (options->thumb_mode) { mode = MODE_THUMB; tns_init(&tns, filecnt, &win); diff --git a/window.c b/window.c index 179e9c6..216cfc1 100644 --- a/window.c +++ b/window.c @@ -42,13 +42,16 @@ static GC gc; Atom wm_delete_win; -struct { +static struct { int ascent; int descent; XFontStruct *xfont; XFontSet set; } font; +static int fontheight; +static int barheight; + void win_init_font(Display *dpy, const char *fontstr) { int n; char *def, **missing; @@ -77,6 +80,8 @@ void win_init_font(Display *dpy, const char *fontstr) { font.ascent = font.xfont->ascent; font.descent = font.xfont->descent; } + fontheight = font.ascent + font.descent; + barheight = fontheight + 2 * V_TEXT_PAD; } unsigned long win_alloc_color(win_t *win, const char *name) { @@ -85,8 +90,8 @@ unsigned long win_alloc_color(win_t *win, const char *name) { if (win == NULL) return 0UL; if (XAllocNamedColor(win->env.dpy, - DefaultColormap(win->env.dpy, win->env.scr), - name, &col, &col) == 0) + DefaultColormap(win->env.dpy, win->env.scr), + name, &col, &col) == 0) { die("could not allocate color: %s", name); } @@ -99,6 +104,8 @@ void win_init(win_t *win) { if (win == NULL) return; + memset(win, 0, sizeof(win_t)); + e = &win->env; if ((e->dpy = XOpenDisplay(NULL)) == NULL) die("could not open display"); @@ -110,19 +117,12 @@ void win_init(win_t *win) { e->cmap = DefaultColormap(e->dpy, e->scr); e->depth = DefaultDepth(e->dpy, e->scr); - win->white = WhitePixel(e->dpy, e->scr); - win->bgcol = win_alloc_color(win, WIN_BG_COLOR); - win->fscol = win_alloc_color(win, WIN_FS_COLOR); - win->selcol = win_alloc_color(win, SEL_COLOR); - win->barbgcol = win_alloc_color(win, BAR_BG_COLOR); - win->barfgcol = win_alloc_color(win, BAR_FG_COLOR); - - win->xwin = 0; - win->pm = 0; - win->fullscreen = false; - win->barh = 0; - win->lbar = NULL; - win->rbar = NULL; + win->white = WhitePixel(e->dpy, e->scr); + win->bgcol = win_alloc_color(win, WIN_BG_COLOR); + win->fscol = win_alloc_color(win, WIN_FS_COLOR); + win->selcol = win_alloc_color(win, SEL_COLOR); + win->bar.bgcol = win_alloc_color(win, BAR_BG_COLOR); + win->bar.fgcol = win_alloc_color(win, BAR_FG_COLOR); if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0) warn("no locale support"); @@ -141,8 +141,8 @@ void win_set_sizehints(win_t *win) { sizehints.flags = PMinSize | PMaxSize; sizehints.min_width = win->w; sizehints.max_width = win->w; - sizehints.min_height = win->h + win->barh; - sizehints.max_height = win->h + win->barh; + sizehints.min_height = win->h + win->bar.h; + sizehints.max_height = win->h + win->bar.h; XSetWMNormalHints(win->env.dpy, win->xwin, &sizehints); } @@ -215,8 +215,8 @@ void win_open(win_t *win) { XSetWMProtocols(e->dpy, win->xwin, &wm_delete_win, 1); if (!options->hide_bar) { - win->barh = font.ascent + font.descent + 2 * V_TEXT_PAD; - win->h -= win->barh; + win->bar.h = barheight; + win->h -= win->bar.h; } if (options->fixed_win) @@ -249,8 +249,8 @@ bool win_configure(win_t *win, XConfigureEvent *c) { if (win == NULL || c == NULL) return false; - - if ((changed = win->w != c->width || win->h + win->barh != c->height)) { + + if ((changed = win->w != c->width || win->h + win->bar.h != c->height)) { if (win->pm != None) { XFreePixmap(win->env.dpy, win->pm); win->pm = None; @@ -260,7 +260,7 @@ bool win_configure(win_t *win, XConfigureEvent *c) { win->x = c->x; win->y = c->y; win->w = c->width; - win->h = c->height - win->barh; + win->h = c->height - win->bar.h; win->bw = c->border_width; return changed; @@ -283,13 +283,13 @@ bool win_moveresize(win_t *win, int x, int y, unsigned int w, unsigned int h) { w = MIN(w, win->env.scrw - 2 * win->bw); h = MIN(h, win->env.scrh - 2 * win->bw); - if (win->x == x && win->y == y && win->w == w && win->h + win->barh == h) + if (win->x == x && win->y == y && win->w == w && win->h + win->bar.h == h) return false; win->x = x; win->y = y; win->w = w; - win->h = h - win->barh; + win->h = h - win->bar.h; if (options->fixed_win) win_set_sizehints(win); @@ -327,12 +327,12 @@ void win_toggle_bar(win_t *win) { if (win == NULL || win->xwin == None) return; - if (win->barh != 0) { - win->h += win->barh; - win->barh = 0; + if (win->bar.h != 0) { + win->h += win->bar.h; + win->bar.h = 0; } else { - win->barh = font.ascent + font.descent + 2 * V_TEXT_PAD; - win->h -= win->barh; + win->bar.h = barheight; + win->h -= win->bar.h; } } @@ -343,7 +343,7 @@ void win_clear(win_t *win) { if (win == NULL || win->xwin == None) return; - h = win->h + win->barh; + h = win->h + win->bar.h; e = &win->env; if (win->pm == None) @@ -354,53 +354,56 @@ void win_clear(win_t *win) { } void win_draw_bar(win_t *win) { + int len, olen, x, y, w, tw; + char rest[3]; + const char *dots = "..."; win_env_t *e; - int len, x, y, w, tw = 0, seplen; - const char *rt; if (win == NULL || win->xwin == None || win->pm == None) return; e = &win->env; - x = H_TEXT_PAD; y = win->h + font.ascent + V_TEXT_PAD; - w = win->w - 2 * H_TEXT_PAD; + w = win->w; - XSetForeground(e->dpy, gc, win->barbgcol); - XFillRectangle(e->dpy, win->pm, gc, 0, win->h, win->w, win->barh); + XSetForeground(e->dpy, gc, win->bar.bgcol); + XFillRectangle(e->dpy, win->pm, gc, 0, win->h, win->w, win->bar.h); - XSetForeground(e->dpy, gc, win->barfgcol); - XSetBackground(e->dpy, gc, win->barbgcol); + XSetForeground(e->dpy, gc, win->bar.fgcol); + XSetBackground(e->dpy, gc, win->bar.bgcol); - if (win->lbar != NULL) { - len = strlen(win->lbar); - while (len > 0 && (tw = win_textwidth(win->lbar, len, false)) > w) - len--; - w -= tw + 2 * H_TEXT_PAD; - if (font.set) - XmbDrawString(e->dpy, win->pm, font.set, gc, x, y, win->lbar, len); - else - XDrawString(e->dpy, win->pm, gc, x, y, win->lbar, len); - } - if (win->rbar != NULL) { - len = strlen(win->rbar); - seplen = strlen(BAR_SEPARATOR); - rt = win->rbar; - while (len > 0 && (tw = win_textwidth(rt, len, false)) > w) { - rt = strstr(rt, BAR_SEPARATOR); - if (rt != NULL) { - rt += seplen; - len = strlen(rt); - } else { - len = 0; - } - } + if (win->bar.r != NULL) { + len = strlen(win->bar.r); if (len > 0) { - x = win->w - tw - H_TEXT_PAD; + if ((tw = win_textwidth(win->bar.r, len, true)) > w) + return; + x = win->w - tw + H_TEXT_PAD; + w -= tw; if (font.set) - XmbDrawString(e->dpy, win->pm, font.set, gc, x, y, rt, len); + XmbDrawString(e->dpy, win->pm, font.set, gc, x, y, win->bar.r, len); else - XDrawString(e->dpy, win->pm, gc, x, y, rt, len); + XDrawString(e->dpy, win->pm, gc, x, y, win->bar.r, len); + } + } + if (win->bar.l != NULL) { + olen = len = strlen(win->bar.l); + while (len > 0 && (tw = win_textwidth(win->bar.l, len, true)) > w) + len--; + if (len > 0) { + if (len != olen) { + w = strlen(dots); + if (len <= w) + return; + memcpy(rest, win->bar.l + len - w, w); + memcpy(win->bar.l + len - w, dots, w); + } + x = H_TEXT_PAD; + if (font.set) + XmbDrawString(e->dpy, win->pm, font.set, gc, x, y, win->bar.l, len); + else + XDrawString(e->dpy, win->pm, gc, x, y, win->bar.l, len); + if (len != olen) + memcpy(win->bar.l + len - w, rest, w); } } } @@ -409,11 +412,11 @@ void win_draw(win_t *win) { if (win == NULL || win->xwin == None || win->pm == None) return; - if (win->barh > 0) + if (win->bar.h > 0) win_draw_bar(win); XCopyArea(win->env.dpy, win->pm, win->xwin, gc, - 0, 0, win->w, win->h + win->barh, 0, 0); + 0, 0, win->w, win->h + win->bar.h, 0, 0); } void win_draw_rect(win_t *win, Pixmap pm, int x, int y, int w, int h, @@ -466,10 +469,10 @@ void win_set_title(win_t *win, const char *title) { PropModeReplace, (unsigned char *) title, strlen(title)); } -void win_set_bar_info(win_t *win, const char *li, const char *ri) { +void win_set_bar_info(win_t *win, char *linfo, char *rinfo) { if (win != NULL) { - win->lbar = li; - win->rbar = ri; + win->bar.l = linfo; + win->bar.r = rinfo; } } diff --git a/window.h b/window.h index 5e033e3..6bc6595 100644 --- a/window.h +++ b/window.h @@ -23,8 +23,6 @@ #include "types.h" -#define BAR_SEPARATOR " | " - typedef struct { Display *dpy; int scr; @@ -42,21 +40,23 @@ typedef struct { unsigned long bgcol; unsigned long fscol; unsigned long selcol; - unsigned long barbgcol; - unsigned long barfgcol; Pixmap pm; int x; int y; unsigned int w; unsigned int h; /* = win height - bar height */ - unsigned int barh; unsigned int bw; bool fullscreen; - const char *lbar; - const char *rbar; + struct { + unsigned int h; + char *l; + char *r; + unsigned long bgcol; + unsigned long fgcol; + } bar; } win_t; extern Atom wm_delete_win; @@ -80,7 +80,7 @@ void win_draw_rect(win_t*, Pixmap, int, int, int, int, bool, int, int win_textwidth(const char*, unsigned int, bool); void win_set_title(win_t*, const char*); -void win_set_bar_info(win_t*, const char*, const char*); +void win_set_bar_info(win_t*, char*, char*); void win_set_cursor(win_t*, cursor_t); #endif /* WINDOW_H */ From b6a6c260e1876172c764c6eca3aae004026cd8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bert=20M=C3=BCnnich?= Date: Tue, 8 Jan 2013 20:55:02 +0100 Subject: [PATCH 2/4] Moved thumbnail cache to ~/.sxiv/cache/ --- sxiv.1 | 11 +---------- thumbs.c | 12 +++++++----- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/sxiv.1 b/sxiv.1 index 2058190..b963a17 100644 --- a/sxiv.1 +++ b/sxiv.1 @@ -308,7 +308,7 @@ Pan image left. Pan image right. .SH THUMBNAIL CACHING To enable thumbnail caching, please make sure to create the directory -.I ~/.sxiv/ +.I ~/.sxiv/cache/ with write permissions. sxiv will then store all thumbnails inside this directory, but it will not create this directory by itself. It rather uses the existance of this directory as an affirmation, that the user wants thumbnails @@ -321,15 +321,6 @@ Additionally, run the following command afterwards inside the cache directory to remove empty subdirectories: .P .RS -find \-type d \-empty \-delete -.RE -.P -If the version of -.I find -installed on your local system does not support the \-delete option, then you -can also try the following command: -.P -.RS find . \-depth \-type d \-empty ! \-name '.' \-exec rmdir {} \\; .RE .SH AUTHOR diff --git a/thumbs.c b/thumbs.c index 5dec4a5..5453815 100644 --- a/thumbs.c +++ b/thumbs.c @@ -31,8 +31,10 @@ #include "util.h" #include "config.h" -const int thumb_dim = THUMB_SIZE + 10; -char *cache_dir = NULL; +static const int thumb_dim = THUMB_SIZE + 10; + +static const char * const CACHE_DIR = ".sxiv/cache"; +static char *cache_dir = NULL; bool tns_cache_enabled(void) { struct stat stats; @@ -175,9 +177,9 @@ void tns_init(tns_t *tns, int cnt, win_t *win) { if ((homedir = getenv("HOME")) != NULL) { if (cache_dir != NULL) free(cache_dir); - len = strlen(homedir) + 10; - cache_dir = (char*) s_malloc(len * sizeof(char)); - snprintf(cache_dir, len, "%s/.sxiv", homedir); + len = strlen(homedir) + strlen(CACHE_DIR) + 2; + cache_dir = (char*) s_malloc(len); + snprintf(cache_dir, len, "%s/%s", homedir, CACHE_DIR); } else { warn("could not locate thumbnail cache directory"); } From cae5358234ecfe6a3fd3c5bad29a0a9f032888a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bert=20M=C3=BCnnich?= Date: Thu, 10 Jan 2013 19:25:49 +0100 Subject: [PATCH 3/4] Added skeleton for image-info user script --- image-info | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 image-info diff --git a/image-info b/image-info new file mode 100755 index 0000000..e65e06a --- /dev/null +++ b/image-info @@ -0,0 +1,10 @@ +#!/bin/sh + +#filename=$1 +#filesize=$(du -h "$1") + +#geometry=$(identify -format '%wx%h' "$1") + +#tags=$(exiv2 -q pr -pi "$1" | awk '$1~"Keywords" {print $4","}') +#tags=${tags%,} + From 9c0a53bc34c53424613ee203253fee526ba9f049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bert=20M=C3=BCnnich?= Date: Sun, 27 Jan 2013 18:03:01 +0100 Subject: [PATCH 4/4] Added documentation for image-info script --- Makefile | 8 ++++++-- README.md | 4 ++-- image-info | 17 ++++++++++++----- sxiv.1 | 19 +++++++++++++++---- 4 files changed, 35 insertions(+), 13 deletions(-) mode change 100755 => 100644 image-info diff --git a/Makefile b/Makefile index 9d3afd3..d542281 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION = git-20130112 +VERSION = git-20130127 PREFIX = /usr/local MANPREFIX = $(PREFIX)/share/man @@ -32,9 +32,13 @@ install: all cp sxiv $(DESTDIR)$(PREFIX)/bin/ chmod 755 $(DESTDIR)$(PREFIX)/bin/sxiv mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - sed "s/VERSION/$(VERSION)/g" sxiv.1 > $(DESTDIR)$(MANPREFIX)/man1/sxiv.1 + sed "s!PREFIX!$(PREFIX)!g; s!VERSION!$(VERSION)!g" sxiv.1 > $(DESTDIR)$(MANPREFIX)/man1/sxiv.1 chmod 644 $(DESTDIR)$(MANPREFIX)/man1/sxiv.1 + mkdir -p $(DESTDIR)$(PREFIX)/share/sxiv/exec + cp image-info $(DESTDIR)$(PREFIX)/share/sxiv/exec/image-info + chmod 755 $(DESTDIR)$(PREFIX)/share/sxiv/exec/image-info uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/sxiv rm -f $(DESTDIR)$(MANPREFIX)/man1/sxiv.1 + rm -rf $(DESTDIR)$(PREFIX)/share/sxiv diff --git a/README.md b/README.md index a564bb4..d8c1c7a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ sxiv ==== -**Simple (or small or suckless) X Image Viewer** +**Simple X Image Viewer** sxiv is an alternative to feh and qiv. Its only dependencies besides xlib are imlib2 and giflib. The primary goal for writing sxiv is to create an image @@ -20,7 +20,7 @@ Features * Ability to cache thumbnails for fast re-loading * Basic support for multi-frame images * Load all frames from GIF files and play GIF animations -* Display image information in window title +* Display image information in status bar Screenshots diff --git a/image-info b/image-info old mode 100755 new mode 100644 index e65e06a..3c03a3f --- a/image-info +++ b/image-info @@ -1,10 +1,17 @@ #!/bin/sh -#filename=$1 -#filesize=$(du -h "$1") +# Example for ~/.sxiv/exec/image-info +# Called by sxiv(1) whenever an image gets loaded, +# with the name of the image file as its first argument. +# The output is displayed in sxiv's status bar. -#geometry=$(identify -format '%wx%h' "$1") +filename=$(basename "$1") +filesize=$(du -h "$1" | cut -f 1) -#tags=$(exiv2 -q pr -pi "$1" | awk '$1~"Keywords" {print $4","}') -#tags=${tags%,} +geometry=$(identify -format '%wx%h' "$1") + +tags=$(exiv2 -q pr -pi "$1" | awk '$1~"Keywords" { printf("%s,", $4); }') +tags=${tags:+|}${tags%,} + +echo "[$filesize|$geometry$tags] $filename" diff --git a/sxiv.1 b/sxiv.1 index b963a17..6f61561 100644 --- a/sxiv.1 +++ b/sxiv.1 @@ -1,6 +1,6 @@ .TH SXIV 1 sxiv\-VERSION .SH NAME -sxiv \- Simple (or small or suckless) X Image Viewer +sxiv \- Simple X Image Viewer .SH SYNOPSIS .B sxiv .RB [ \-bcdFfhpqrstvZ ] @@ -306,6 +306,15 @@ Pan image left. .TP .B Shift+ScrollDown Pan image right. +.SH STATUS BAR +The information displayed on the left side of the status bar can be replaced +with the output of a user-provided script, which is called by sxiv whenever an +image gets loaded. The path of this script is +.I ~/.sxiv/exec/image-info +and the first argument to this script is the path of the loaded image. +.P +There is also an example script installed together with sxiv as +.IR PREFIX/share/sxiv/exec/image-info . .SH THUMBNAIL CACHING To enable thumbnail caching, please make sure to create the directory .I ~/.sxiv/cache/ @@ -325,17 +334,19 @@ find . \-depth \-type d \-empty ! \-name '.' \-exec rmdir {} \\; .RE .SH AUTHOR .EX -Bert Muennich +Bert Muennich .EE .SH CONTRIBUTORS .EX Bastien Dejean Dave Reisner Fung SzeTat -.EX +.EE .SH HOMEPAGE -.TP +.EX +http://muennich.github.com/sxiv https://github.com/muennich/sxiv +.EE .SH SEE ALSO .BR feh (1), .BR qiv (1)