diff options
Diffstat (limited to 'src/winwidget.c')
-rw-r--r-- | src/winwidget.c | 92 |
1 files changed, 91 insertions, 1 deletions
diff --git a/src/winwidget.c b/src/winwidget.c index f3ecc84..70a65e0 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "options.h" #include "events.h" +#ifdef HAVE_INOTIFY +#include <sys/inotify.h> +#endif + static void winwidget_unregister(winwidget win); static void winwidget_register(winwidget win); static winwidget winwidget_allocate(void); @@ -78,6 +82,10 @@ static winwidget winwidget_allocate(void) ret->click_offset_y = 0; ret->has_rotated = 0; +#ifdef HAVE_INOTIFY + ret->inotify_wd = -1; +#endif + return(ret); } @@ -662,6 +670,9 @@ void winwidget_destroy_xwin(winwidget winwid) void winwidget_destroy(winwidget winwid) { +#ifdef HAVE_INOTIFY + winwidget_inotify_remove(winwid); +#endif winwidget_destroy_xwin(winwid); if (winwid->name) free(winwid->name); @@ -673,6 +684,76 @@ void winwidget_destroy(winwidget winwid) return; } +#ifdef HAVE_INOTIFY +void winwidget_inotify_remove(winwidget winwid) +{ + if (winwid->inotify_wd >= 0) { + D(("Removing inotify watch\n")); + if (inotify_rm_watch(opt.inotify_fd, winwid->inotify_wd)) + weprintf("inotify_rm_watch failed:"); + winwid->inotify_wd = -1; + } +} +#endif + +#ifdef HAVE_INOTIFY +void winwidget_inotify_add(winwidget winwid, feh_file * file) +{ + if (opt.auto_reload) { + D(("Adding inotify watch for %s\n", file->filename)); + char dir[PATH_MAX]; + feh_file_dirname(dir, file, PATH_MAX); + + /* + * Handle files without directory part, e.g. "feh somefile.jpg". + * These always reside in the current directory. + */ + if (dir[0] == '\0') { + dir[0] = '.'; + dir[1] = '\0'; + } + winwid->inotify_wd = inotify_add_watch(opt.inotify_fd, dir, IN_CLOSE_WRITE | IN_MOVED_TO); + if (winwid->inotify_wd < 0) + weprintf("inotify_add_watch failed:"); + } +} +#endif + +#ifdef HAVE_INOTIFY +#define INOTIFY_BUFFER_LEN (1024 * (sizeof (struct inotify_event)) + 16) +void feh_event_handle_inotify(void) +{ + D(("Received inotify events\n")); + char buf[INOTIFY_BUFFER_LEN]; + int i = 0; + int len = read (opt.inotify_fd, buf, INOTIFY_BUFFER_LEN); + if (len < 0) { + if (errno != EINTR) + eprintf("inotify event read failed"); + } else if (!len) + eprintf("inotify event read failed"); + while (i < len) { + struct inotify_event *event; + event = (struct inotify_event *) &buf[i]; + for (int j = 0; j < window_num; j++) { + if(windows[j]->inotify_wd == event->wd) { + if (event->mask & IN_IGNORED) { + D(("inotify watch was implicitely removed\n")); + windows[j]->inotify_wd = -1; + } else if (event->mask & (IN_CLOSE_WRITE | IN_MOVED_TO)) { + if (strcmp(event->name, FEH_FILE(windows[j]->file->data)->name) == 0) { + D(("inotify says file changed\n")); + feh_reload_image(windows[j], 0, 0); + } + } + break; + } + } + i += sizeof(struct inotify_event) + event->len; + } +} +#endif + void winwidget_destroy_all(void) { int i; @@ -706,7 +787,16 @@ winwidget winwidget_get_first_window_of_type(unsigned int type) int winwidget_loadimage(winwidget winwid, feh_file * file) { D(("filename %s\n", file->filename)); - return(feh_load_image(&(winwid->im), file)); +#ifdef HAVE_INOTIFY + winwidget_inotify_remove(winwid); +#endif + int res = feh_load_image(&(winwid->im), file); +#ifdef HAVE_INOTIFY + if (res) { + winwidget_inotify_add(winwid, file); + } +#endif + return(res); } void winwidget_show(winwidget winwid) |