diff --git a/main.c b/main.c index 593e1c1a..21d69bc3 100644 --- a/main.c +++ b/main.c @@ -314,6 +314,7 @@ void load_image(int new) close_info(); open_info(); arl_setup(&arl, files[fileidx].path); + win_set_title(&win, files[fileidx].path); if (img.multi.cnt > 0 && img.multi.animate) set_timeout(animate, img.multi.frames[img.multi.sel].delay, true); @@ -939,6 +940,7 @@ int main(int argc, char **argv) load_image(fileidx); } win_open(&win); + win_set_title(&win, files[fileidx].path); win_set_cursor(&win, CURSOR_WATCH); atexit(cleanup); diff --git a/sxiv.1 b/sxiv.1 index eff3d666..aec4da5c 100644 --- a/sxiv.1 +++ b/sxiv.1 @@ -387,6 +387,21 @@ Color of the window foreground and bar background .B font Name of Xft bar font .TP +.B titlePrefix +Any string literal to be used as the window title prefix. +.TP +.B titleSuffix +The format of the window title suffix. + +.EX + Value Format + 0 Basename of file + 1 Basename of directory + 2 Full path to file + 3 Full path to directory + 4 Empty string +.EE +.TP Please see xrdb(1) on how to change them. .SH STATUS BAR The information displayed on the left side of the status bar can be replaced diff --git a/sxiv.h b/sxiv.h index 707eba71..1c78f285 100644 --- a/sxiv.h +++ b/sxiv.h @@ -115,6 +115,16 @@ typedef enum { FF_TN_INIT = 4 } fileflags_t; +typedef enum { + BASE_CFILE, + BASE_CDIR, + CFILE, + CDIR, + EMPTY, + + SUFFIXMODE_COUNT, +} suffixmode_t; + typedef struct { const char *name; /* as given by user */ const char *path; /* always absolute */ @@ -410,6 +420,10 @@ struct win { XftColor bg; XftColor fg; + suffixmode_t suffixmode; + const char *prefix; + const char *suffix; + int x; int y; unsigned int w; diff --git a/thumbs.c b/thumbs.c index 36874d63..c1a81560 100644 --- a/thumbs.c +++ b/thumbs.c @@ -35,6 +35,7 @@ void exif_auto_orientate(const fileinfo_t*); Imlib_Image img_open(const fileinfo_t*); static char *cache_dir; +extern const int fileidx; char* tns_cache_filepath(const char *filepath) { @@ -531,6 +532,7 @@ bool tns_move_selection(tns_t *tns, direction_t dir, int cnt) if (!tns->dirty) tns_highlight(tns, *tns->sel, true); } + win_set_title(tns->win, tns->files[fileidx].path); return *tns->sel != old; } diff --git a/window.c b/window.c index 6f9a3906..5d0105fc 100644 --- a/window.c +++ b/window.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -119,6 +120,10 @@ void win_init(win_t *win) f = win_res(db, RES_CLASS ".font", "monospace-8"); win_init_font(e, f); + win->prefix = win_res(db, RES_CLASS ".titlePrefix", "sxiv - "); + win->suffixmode = strtol(win_res(db, RES_CLASS ".titleSuffix", "0"), + NULL, 10) % SUFFIXMODE_COUNT; + bg = win_res(db, RES_CLASS ".background", "white"); fg = win_res(db, RES_CLASS ".foreground", "black"); win_alloc_color(e, bg, &win->bg); @@ -238,8 +243,6 @@ void win_open(win_t *win) } free(icon_data); - win_set_title(win, "sxiv"); - classhint.res_class = RES_CLASS; classhint.res_name = options->res_name != NULL ? options->res_name : "sxiv"; XSetClassHint(e->dpy, win->xwin, &classhint); @@ -443,17 +446,55 @@ void win_draw_rect(win_t *win, int x, int y, int w, int h, bool fill, int lw, XDrawRectangle(win->env.dpy, win->buf.pm, gc, x, y, w, h); } -void win_set_title(win_t *win, const char *title) +void win_set_title(win_t *win, const char *path) { - XStoreName(win->env.dpy, win->xwin, title); - XSetIconName(win->env.dpy, win->xwin, title); + char *title, *suffix=""; + static bool first_time = true; + + /* Return if window is not ready yet, otherwise we get an X fault. */ + if (win->xwin == None) + return; + /* Get title suffix type from X-resources. Default: BASE_CDIR. */ + suffix = estrdup(path); + switch (win->suffixmode) { + case CFILE: + win->suffix = suffix; + break; + case BASE_CFILE: + win->suffix = basename(suffix); + break; + case CDIR: + win->suffix = dirname(suffix); + break; + case BASE_CDIR: + win->suffix = basename(dirname(suffix)); + break; + case SUFFIXMODE_COUNT: // Never happens + case EMPTY: + win->suffix = ""; + break; + } + + /* Set the title. Some WM's that don't comply to EMWH (e.g. mwm) only use + * WM_NAME for the window title, which is set by XStoreName below. */ + title = emalloc(strlen(win->prefix) + strlen(win->suffix) + 1); + (void)sprintf(title, "%s%s", win->prefix, win->suffix); XChangeProperty(win->env.dpy, win->xwin, atoms[ATOM__NET_WM_NAME], XInternAtom(win->env.dpy, "UTF8_STRING", False), 8, PropModeReplace, (unsigned char *) title, strlen(title)); - XChangeProperty(win->env.dpy, win->xwin, atoms[ATOM__NET_WM_ICON_NAME], - XInternAtom(win->env.dpy, "UTF8_STRING", False), 8, - PropModeReplace, (unsigned char *) title, strlen(title)); + free(title); + free(suffix); + + /* These three atoms won't change and thus only need to be set once. */ + if (first_time) { + XStoreName(win->env.dpy, win->xwin, "sxiv"); + XSetIconName(win->env.dpy, win->xwin, "sxiv"); + XChangeProperty(win->env.dpy, win->xwin, atoms[ATOM__NET_WM_ICON_NAME], + XInternAtom(win->env.dpy, "UTF8_STRING", False), 8, + PropModeReplace, (unsigned char *)"sxiv", strlen("sxiv")); + first_time = false; + } } void win_set_cursor(win_t *win, cursor_t cursor)