nsxiv34d4295
read win-title in non-blocking manner (#314)
+42 −33
1 file changed
- M main.c +42 −33
| @@ -78,17 +78,13 @@ static struct { | |||
| 78 | 78 | extcmd_t f, ft; | |
| 79 | 79 | int fd; | |
| 80 | 80 | pid_t pid; | |
| 81 | − | } info; | |
| 81 | + | } info, wintitle; | |
| 82 | 82 | ||
| 83 | 83 | static struct { | |
| 84 | 84 | extcmd_t f; | |
| 85 | 85 | bool warned; | |
| 86 | 86 | } keyhandler; | |
| 87 | 87 | ||
| 88 | − | static struct { | |
| 89 | − | extcmd_t f; | |
| 90 | − | } wintitle; | |
| 91 | − | ||
| 92 | 88 | static struct { | |
| 93 | 89 | timeout_f handler; | |
| 94 | 90 | struct timeval when; | |
| @@ -274,16 +270,41 @@ static bool check_timeouts(int *t) | |||
| 274 | 270 | return tmin > 0; | |
| 275 | 271 | } | |
| 276 | 272 | ||
| 277 | − | static size_t get_win_title(char *buf, size_t len) | |
| 273 | + | static void kill_close(pid_t pid, int *fd) | |
| 274 | + | { | |
| 275 | + | if (fd != NULL && *fd != -1) { | |
| 276 | + | kill(pid, SIGTERM); | |
| 277 | + | close(*fd); | |
| 278 | + | *fd = -1; | |
| 279 | + | } | |
| 280 | + | } | |
| 281 | + | ||
| 282 | + | static void close_title(void) | |
| 283 | + | { | |
| 284 | + | kill_close(wintitle.pid, &wintitle.fd); | |
| 285 | + | } | |
| 286 | + | ||
| 287 | + | static void read_title(void) | |
| 288 | + | { | |
| 289 | + | ssize_t n; | |
| 290 | + | char buf[512]; | |
| 291 | + | ||
| 292 | + | if ((n = read(wintitle.fd, buf, sizeof(buf)-1)) > 0) { | |
| 293 | + | buf[n] = '\0'; | |
| 294 | + | win_set_title(&win, buf, n); | |
| 295 | + | } | |
| 296 | + | close_title(); | |
| 297 | + | } | |
| 298 | + | ||
| 299 | + | static void open_title(void) | |
| 278 | 300 | { | |
| 279 | 301 | char *argv[8]; | |
| 280 | 302 | char w[12] = "", h[12] = "", z[12] = "", fidx[12], fcnt[12]; | |
| 281 | − | ssize_t n = -1; | |
| 282 | − | int readfd; | |
| 283 | 303 | ||
| 284 | − | if (wintitle.f.err || buf == NULL || len == 0) | |
| 285 | − | return 0; | |
| 304 | + | if (wintitle.f.err || !title_dirty) | |
| 305 | + | return; | |
| 286 | 306 | ||
| 307 | + | close_title(); | |
| 287 | 308 | if (mode == MODE_IMAGE) { | |
| 288 | 309 | snprintf(w, ARRLEN(w), "%d", img.w); | |
| 289 | 310 | snprintf(h, ARRLEN(h), "%d", img.h); | |
| @@ -293,22 +314,14 @@ static size_t get_win_title(char *buf, size_t len) | |||
| 293 | 314 | snprintf(fcnt, ARRLEN(fcnt), "%d", filecnt); | |
| 294 | 315 | construct_argv(argv, ARRLEN(argv), wintitle.f.cmd, files[fileidx].path, | |
| 295 | 316 | fidx, fcnt, w, h, z, NULL); | |
| 296 | − | if (spawn(&readfd, NULL, argv) > 0) { | |
| 297 | − | if ((n = read(readfd, buf, len-1)) > 0) | |
| 298 | − | buf[n] = '\0'; | |
| 299 | − | close(readfd); | |
| 300 | − | } | |
| 301 | − | ||
| 302 | − | return MAX(0, n); | |
| 317 | + | if ((wintitle.pid = spawn(&wintitle.fd, NULL, argv)) > 0) | |
| 318 | + | fcntl(wintitle.fd, F_SETFL, O_NONBLOCK); | |
| 319 | + | title_dirty = false; | |
| 303 | 320 | } | |
| 304 | 321 | ||
| 305 | 322 | void close_info(void) | |
| 306 | 323 | { | |
| 307 | − | if (info.fd != -1) { | |
| 308 | − | kill(info.pid, SIGTERM); | |
| 309 | − | close(info.fd); | |
| 310 | − | info.fd = -1; | |
| 311 | − | } | |
| 324 | + | kill_close(info.pid, &info.fd); | |
| 312 | 325 | } | |
| 313 | 326 | ||
| 314 | 327 | void open_info(void) | |
| @@ -487,14 +500,7 @@ void redraw(void) | |||
| 487 | 500 | tns_render(&tns); | |
| 488 | 501 | } | |
| 489 | 502 | update_info(); | |
| 490 | − | if (title_dirty) { | |
| 491 | − | size_t n; | |
| 492 | − | char buf[512]; | |
| 493 | − | ||
| 494 | − | if ((n = get_win_title(buf, sizeof(buf))) > 0) | |
| 495 | − | win_set_title(&win, buf, n); | |
| 496 | − | title_dirty = false; | |
| 497 | − | } | |
| 503 | + | open_title(); | |
| 498 | 504 | win_draw(&win); | |
| 499 | 505 | reset_timeout(redraw); | |
| 500 | 506 | reset_cursor(); | |
| @@ -722,7 +728,7 @@ static void on_buttonpress(const XButtonEvent *bev) | |||
| 722 | 728 | ||
| 723 | 729 | static void run(void) | |
| 724 | 730 | { | |
| 725 | − | enum { FD_X, FD_INFO, FD_ARL, FD_CNT }; | |
| 731 | + | enum { FD_X, FD_INFO, FD_TITLE, FD_ARL, FD_CNT }; | |
| 726 | 732 | struct pollfd pfd[FD_CNT]; | |
| 727 | 733 | int timeout = 0; | |
| 728 | 734 | const struct timespec ten_ms = {0, 10000000}; | |
| @@ -755,13 +761,16 @@ static void run(void) | |||
| 755 | 761 | } else { | |
| 756 | 762 | pfd[FD_X].fd = ConnectionNumber(win.env.dpy); | |
| 757 | 763 | pfd[FD_INFO].fd = info.fd; | |
| 764 | + | pfd[FD_TITLE].fd = wintitle.fd; | |
| 758 | 765 | pfd[FD_ARL].fd = arl.fd; | |
| 759 | − | pfd[FD_X].events = pfd[FD_INFO].events = pfd[FD_ARL].events = POLLIN; | |
| 766 | + | pfd[FD_X].events = pfd[FD_INFO].events = pfd[FD_TITLE].events = pfd[FD_ARL].events = POLLIN; | |
| 760 | 767 | ||
| 761 | 768 | if (poll(pfd, ARRLEN(pfd), to_set ? timeout : -1) < 0) | |
| 762 | 769 | continue; | |
| 763 | 770 | if (pfd[FD_INFO].revents & POLLIN) | |
| 764 | 771 | read_info(); | |
| 772 | + | if (pfd[FD_TITLE].revents & POLLIN) | |
| 773 | + | read_title(); | |
| 765 | 774 | if (pfd[FD_ARL].revents & POLLIN) { | |
| 766 | 775 | if (arl_handle(&arl)) { | |
| 767 | 776 | /* when too fast, imlib2 can't load the image */ | |
| @@ -922,7 +931,7 @@ int main(int argc, char *argv[]) | |||
| 922 | 931 | } else { | |
| 923 | 932 | error(0, 0, "Exec directory not found"); | |
| 924 | 933 | } | |
| 925 | − | info.fd = -1; | |
| 934 | + | wintitle.fd = info.fd = -1; | |
| 926 | 935 | ||
| 927 | 936 | if (options->thumb_mode) { | |
| 928 | 937 | mode = MODE_THUMB; | |