Krolyxon
Commit e26c81f

Branches

Refs →

nsxive26c81f

use win-title script for customizing window title (#213)

this removes the cli flag `-T` as well as related config.h options.
Author
N-R-K
Date
2022-02-23 09:23 +0000
Committer
GitHub · 2022-02-23 09:23 +0000
Parent
ad95012
Commit
e26c81fe9ab43ef0148f51464dbae0f7a0e2b91e

+103 −69

8 files changed

  1. M config.def.h +0 −13
  2. A examples/win-title +27 −0
  3. M main.c +34 −4
  4. M nsxiv.1 +18 −15
  5. M nsxiv.h +1 −9
  6. M options.c +15 −13
  7. M thumbs.c +0 −2
  8. M window.c +8 −13
M config.def.h View
@@ -16,19 +16,6 @@ static const char *DEFAULT_BAR_FG = NULL; /* NULL means it will default to
1616 static const char *DEFAULT_FONT = "monospace-8";
1717 #endif
1818
19−#endif
20−#ifdef _TITLE_CONFIG
21−
22−/* default title prefix */
23−static const char *TITLE_PREFIX = "nsxiv - ";
24−
25−/* default title suffixmode, available options are:
26− * SUFFIX_EMPTY
27− * SUFFIX_BASENAME
28− * SUFFIX_FULLPATH
29− */
30−static const suffixmode_t TITLE_SUFFIXMODE = SUFFIX_BASENAME;
31−
3219 #endif
3320 #ifdef _IMAGE_CONFIG
3421
A examples/win-title View
@@ -0,0 +1,27 @@
1+#!/bin/sh
2+
3+# Example for $XDG_CONFIG_HOME/nsxiv/exec/win-title
4+# Called by nsxiv(1) on each redraw.
5+# The output is set as nsxiv's window title.
6+#
7+# Arguments, "Optional" arguments might be empty:
8+# $1: resolved absolute path of the current file
9+# $2: current file number
10+# $3: total file number
11+# $4: image width (Optional: Disabled on thumbnails mode)
12+# $5: image height (Optional: Disabled on thumbnails mode)
13+# $6: current zoom (Optional: Disabled on thumbnails mode)
14+#
15+# The term file is used rather than image as nsxiv does not
16+# precheck that the input files are valid images. Total file
17+# count may be different from the actual count of valid images.
18+
19+exec 2>/dev/null
20+
21+filename="${1##*/}"
22+
23+if [ -n "$4" ]; then # image mode
24+ printf "%s" "nsxiv - ${filename} | ${4}x${5} ${6}% [${2}/${3}]"
25+else
26+ printf "%s" "nsxiv - ${filename} [${2}/${3}]"
27+fi
M main.c View
@@ -87,6 +87,10 @@ static struct {
8787 bool warned;
8888 } keyhandler;
8989
90+static struct {
91+ extcmd_t f;
92+} wintitle;
93+
9094 static timeout_t timeouts[] = {
9195 { { 0, 0 }, false, redraw },
9296 { { 0, 0 }, false, reset_cursor },
@@ -229,6 +233,33 @@ static bool check_timeouts(struct timeval *t)
229233 return tmin > 0;
230234 }
231235
236+size_t get_win_title(char *buf, int len)
237+{
238+ char *argv[8];
239+ spawn_t pfd;
240+ char w[12] = "", h[12] = "", z[12] = "", fidx[12], fcnt[12];
241+ ssize_t n = -1;
242+
243+ if (wintitle.f.err || buf == NULL || len <= 0)
244+ return 0;
245+
246+ if (mode == MODE_IMAGE) {
247+ snprintf(w, ARRLEN(w), "%d", img.w);
248+ snprintf(h, ARRLEN(h), "%d", img.h);
249+ snprintf(z, ARRLEN(z), "%d", (int)(img.zoom * 100));
250+ }
251+ snprintf(fidx, ARRLEN(fidx), "%d", fileidx+1);
252+ snprintf(fcnt, ARRLEN(fcnt), "%d", filecnt);
253+ construct_argv(argv, ARRLEN(argv), wintitle.f.cmd, files[fileidx].path,
254+ fidx, fcnt, w, h, z, NULL);
255+ pfd = spawn(wintitle.f.cmd, argv, X_READ);
256+ if (pfd.readfd >= 0) {
257+ if ((n = read(pfd.readfd, buf, len-1)) > 0)
258+ buf[n] = '\0';
259+ }
260+ return MAX(0, n);
261+}
262+
232263 void close_info(void)
233264 {
234265 if (info.fd != -1) {
@@ -320,7 +351,6 @@ void load_image(int new)
320351 close_info();
321352 open_info();
322353 arl_setup(&arl, files[fileidx].path);
323− win_set_title(&win, files[fileidx].path);
324354
325355 if (img.multi.cnt > 0 && img.multi.animate)
326356 set_timeout(animate, img.multi.frames[img.multi.sel].delay, true);
@@ -429,6 +459,7 @@ void redraw(void)
429459 tns_render(&tns);
430460 }
431461 update_info();
462+ win_set_title(&win);
432463 win_draw(&win);
433464 reset_timeout(redraw);
434465 reset_cursor();
@@ -879,8 +910,8 @@ int main(int argc, char *argv[])
879910 dsuffix = "/.config";
880911 }
881912 if (homedir != NULL) {
882− extcmd_t *cmd[] = { &info.f, &keyhandler.f };
883− const char *name[] = { "image-info", "key-handler" };
913+ extcmd_t *cmd[] = { &info.f, &keyhandler.f, &wintitle.f };
914+ const char *name[] = { "image-info", "key-handler", "win-title" };
884915 const char *s = "/nsxiv/exec/";
885916
886917 for (i = 0; i < ARRLEN(cmd); i++) {
@@ -906,7 +937,6 @@ int main(int argc, char *argv[])
906937 load_image(fileidx);
907938 }
908939 win_open(&win);
909− win_set_title(&win, files[fileidx].path);
910940 win_set_cursor(&win, CURSOR_WATCH);
911941
912942 atexit(cleanup);
M nsxiv.1 View
@@ -20,8 +20,6 @@ nsxiv \- Neo Simple X Image Viewer
2020 .IR DELAY ]
2121 .RB [ \-s
2222 .IR MODE ]
23−.RB [ \-T
24−.IR TITLE ]
2523 .RB [ \-z
2624 .IR ZOOM ]
2725 .IR FILE ...
@@ -101,19 +99,6 @@ may be a floating point number.
10199 Set scale mode according to MODE character. Supported modes are: [d]own,
102100 [f]it, [F]ill, [w]idth, [h]eight.
103101 .TP
104−.BI "\-T " TITLE
105−Set the window title to TITLE. Use the format `prefix:suffixmode'. Any string
106−literal is accepted for prefix, and the format of suffixmode is:
107−
108−.EX
109− Value Format
110− 0 Empty
111− 1 Basename of file
112− 2 Full path to file
113−.EE
114−
115−By default, prefix is set to "nsxiv - " and suffixmode is set to 1 (basename).
116−.TP
117102 .B \-t
118103 Start in thumbnail mode.
119104 .TP
@@ -439,6 +424,24 @@ Color of the bar foreground. Defaults to window.foreground
439424 Color of the mark foreground. Defaults to window.foreground
440425 .TP
441426 Please see xrdb(1) on how to change them.
427+.SH WINDOW TITLE
428+The window title can be replaced with the output of a user-provided script,
429+which is called by nsxiv whenever there's a redraw. The path of this script is
430+.I $XDG_CONFIG_HOME/nsxiv/exec/win-title
431+and the arguments given to it (where "Optional" arguments might be empty) are:
432+1) resolved absolute path of the current file,
433+2) current file number,
434+3) total file count,
435+4) image width (Optional: Disabled on thumbnails mode),
436+5) image height (Optional: Disabled on thumbnails mode),
437+6) current zoom (Optional: Disabled on thumbnails mode).
438+.P
439+The term file is used rather than image as nsxiv does not precheck that the
440+input files are valid images. Total file count may be different from the actual
441+count of valid images.
442+.P
443+There is also an example script installed together with nsxiv as
444+.IR EGPREFIX/win-title .
442445 .SH STATUS BAR
443446 The information displayed on the left side of the status bar can be replaced
444447 with the output of a user-provided script, which is called by nsxiv whenever an
M nsxiv.h View
@@ -111,12 +111,6 @@ typedef enum {
111111 FF_TN_INIT = 4
112112 } fileflags_t;
113113
114−typedef enum {
115− SUFFIX_EMPTY,
116− SUFFIX_BASENAME,
117− SUFFIX_FULLPATH
118−} suffixmode_t;
119−
120114 typedef struct {
121115 const char *name; /* as given by user */
122116 const char *path; /* always absolute */
@@ -265,8 +259,6 @@ struct opt {
265259 Window embed; /* unsigned long */
266260 char *geometry;
267261 char *res_name;
268− const char *title_prefix;
269− suffixmode_t title_suffixmode;
270262
271263 /* misc flags: */
272264 bool quiet;
@@ -448,7 +440,7 @@ void win_toggle_bar(win_t*);
448440 void win_clear(win_t*);
449441 void win_draw(win_t*);
450442 void win_draw_rect(win_t*, int, int, int, int, bool, int, unsigned long);
451−void win_set_title(win_t*, const char*);
443+void win_set_title(win_t*);
452444 void win_set_cursor(win_t*, cursor_t);
453445 void win_cursor_pos(win_t*, int*, int*);
454446
M options.c View
@@ -18,8 +18,6 @@
1818 */
1919
2020 #include "nsxiv.h"
21−#define _TITLE_CONFIG
22−#include "config.h"
2321 #include "version.h"
2422
2523 #include <stdlib.h>
@@ -31,10 +29,23 @@ const opt_t *options;
3129 void print_usage(void)
3230 {
3331 printf("usage: nsxiv [-abcfhiopqrtvZ0] [-A FRAMERATE] [-e WID] [-G GAMMA] "
34− "[-g GEOMETRY] [-N NAME] [-T TITLE] [-n NUM] [-S DELAY] [-s MODE] "
32+ "[-g GEOMETRY] [-N NAME] [-n NUM] [-S DELAY] [-s MODE] "
3533 "[-z ZOOM] FILES...\n");
3634 }
3735
36+static void title_deprecation_notice(void)
37+{
38+ error(EXIT_FAILURE, 0, "\n"
39+ "################################################################\n"
40+ "# DEPRECATION NOTICE #\n"
41+ "################################################################\n"
42+ "# `-T` option has been deprecated in favour of `win-title`. #\n"
43+ "# Please read the `WINDOW TITLE` section of the manpage for #\n"
44+ "# more info. #\n"
45+ "################################################################"
46+ );
47+}
48+
3849 static void print_version(void)
3950 {
4051 puts("nsxiv " VERSION);
@@ -69,8 +80,6 @@ void parse_options(int argc, char **argv)
6980 _options.hide_bar = false;
7081 _options.geometry = NULL;
7182 _options.res_name = NULL;
72− _options.title_prefix = TITLE_PREFIX;
73− _options.title_suffixmode = TITLE_SUFFIXMODE;
7483
7584 _options.quiet = false;
7685 _options.thumb_mode = false;
@@ -155,14 +164,7 @@ void parse_options(int argc, char **argv)
155164 _options.scalemode = s - scalemodes;
156165 break;
157166 case 'T':
158− if ((s = strrchr(optarg, ':')) != NULL) {
159− *s = '\0';
160− n = strtol(++s, &end, 0);
161− if (*end != '\0' || n < SUFFIX_EMPTY || n > SUFFIX_FULLPATH)
162− error(EXIT_FAILURE, 0, "Invalid argument for option -T suffixmode: %s", s);
163− _options.title_suffixmode = n;
164− }
165− _options.title_prefix = optarg;
167+ title_deprecation_notice(); /* TODO(v30): remove this option */
166168 break;
167169 case 't':
168170 _options.thumb_mode = true;
M thumbs.c View
@@ -36,7 +36,6 @@ void exif_auto_orientate(const fileinfo_t*);
3636 Imlib_Image img_open(const fileinfo_t*);
3737
3838 static char *cache_dir;
39−extern const int fileidx;
4039
4140 static char* tns_cache_filepath(const char *filepath)
4241 {
@@ -530,7 +529,6 @@ bool tns_move_selection(tns_t *tns, direction_t dir, int cnt)
530529 if (!tns->dirty)
531530 tns_highlight(tns, *tns->sel, true);
532531 }
533− win_set_title(tns->win, tns->files[fileidx].path);
534532 return *tns->sel != old;
535533 }
536534
M window.c View
@@ -30,6 +30,8 @@
3030 #include <X11/Xatom.h>
3131 #include <X11/Xresource.h>
3232
33+extern size_t get_win_title(char *, int);
34+
3335 #if HAVE_LIBFONTS
3436 #include "utf8.h"
3537 static XftFont *font;
@@ -499,27 +501,20 @@ void win_draw_rect(win_t *win, int x, int y, int w, int h, bool fill, int lw,
499501 XDrawRectangle(win->env.dpy, win->buf.pm, gc, x, y, w, h);
500502 }
501503
502−void win_set_title(win_t *win, const char *path)
504+void win_set_title(win_t *win)
503505 {
504− enum { title_max = 512 };
505− char title[title_max];
506− const char *basename = strrchr(path, '/') + 1;
506+ char title[512];
507+ size_t len;
507508
508− /* Return if window is not ready yet */
509− if (win->xwin == None)
509+ if ((len = get_win_title(title, ARRLEN(title))) <= 0)
510510 return;
511511
512− snprintf(title, title_max, "%s%s", options->title_prefix,
513− options->title_suffixmode == SUFFIX_BASENAME ? basename : path);
514− if (options->title_suffixmode == SUFFIX_EMPTY)
515− *(title+strlen(options->title_prefix)) = '\0';
516−
517512 XChangeProperty(win->env.dpy, win->xwin, atoms[ATOM__NET_WM_NAME],
518513 XInternAtom(win->env.dpy, "UTF8_STRING", False), 8,
519− PropModeReplace, (unsigned char *) title, strlen(title));
514+ PropModeReplace, (unsigned char *) title, len);
520515 XChangeProperty(win->env.dpy, win->xwin, atoms[ATOM__NET_WM_ICON_NAME],
521516 XInternAtom(win->env.dpy, "UTF8_STRING", False), 8,
522− PropModeReplace, (unsigned char *) title, strlen(title));
517+ PropModeReplace, (unsigned char *) title, len);
523518 }
524519
525520 void win_set_cursor(win_t *win, cursor_t cursor)