summaryrefslogtreecommitdiff
path: root/src/winwidget.c
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2019-04-12 16:34:12 +0200
committerDaniel Friesel <derf@finalrewind.org>2019-04-12 16:34:12 +0200
commitf8270763d6eb37e944999aa30fb648e564353a46 (patch)
tree3f59564728c1ea7933f0a24f662920110da6c18c /src/winwidget.c
parente6dd09e65e22cc13692e09b0018960e878b965c7 (diff)
parenta9ffd5d2234433bc3f3829713b0968a1d6c13b94 (diff)
Merge branch 'master' of https://github.com/swillner/feh into swillner-master
Diffstat (limited to 'src/winwidget.c')
-rw-r--r--src/winwidget.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/src/winwidget.c b/src/winwidget.c
index bb4fdae..020ee5b 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,67 @@ 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))
+ eprintf("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);
+ winwid->inotify_wd = inotify_add_watch(opt.inotify_fd, dir, IN_CLOSE_WRITE | IN_MOVED_TO);
+ if (winwid->inotify_wd < 0)
+ eprintf("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, 1);
+ }
+ }
+ break;
+ }
+ }
+ i += sizeof(struct inotify_event) + event->len;
+ }
+}
+#endif
+
void winwidget_destroy_all(void)
{
int i;
@@ -706,7 +778,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)