mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2025-01-16 05:25:51 +01:00
Reload modified PDF document
This commits add the functionality that when the PDF file has been rewritten in the background (e.g.: from another program), zathura reloads the document to refresh the page.
This commit is contained in:
parent
e250cbc5d5
commit
7b1bc17b1e
1 changed files with 83 additions and 4 deletions
87
zathura.c
87
zathura.c
|
@ -9,6 +9,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
|
||||||
#include <poppler/glib/poppler.h>
|
#include <poppler/glib/poppler.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
|
@ -193,12 +194,14 @@ struct
|
||||||
pthread_mutex_t rotate_lock;
|
pthread_mutex_t rotate_lock;
|
||||||
pthread_mutex_t search_lock;
|
pthread_mutex_t search_lock;
|
||||||
pthread_mutex_t viewport_lock;
|
pthread_mutex_t viewport_lock;
|
||||||
|
pthread_mutex_t document_lock;
|
||||||
} Lock;
|
} Lock;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
pthread_t search_thread;
|
pthread_t search_thread;
|
||||||
gboolean search_thread_running;
|
gboolean search_thread_running;
|
||||||
|
pthread_t inotify_thread;
|
||||||
} Thread;
|
} Thread;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
@ -215,6 +218,12 @@ struct
|
||||||
int last;
|
int last;
|
||||||
} Marker;
|
} Marker;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int wd;
|
||||||
|
int fd;
|
||||||
|
} Inotify;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
GKeyFile *data;
|
GKeyFile *data;
|
||||||
|
@ -258,6 +267,7 @@ GtkEventBox* createCompletionRow(GtkBox*, char*, char*, gboolean);
|
||||||
|
|
||||||
/* thread declaration */
|
/* thread declaration */
|
||||||
void* search(void*);
|
void* search(void*);
|
||||||
|
void* watch_file(void*);
|
||||||
|
|
||||||
/* shortcut declarations */
|
/* shortcut declarations */
|
||||||
void sc_abort(Argument*);
|
void sc_abort(Argument*);
|
||||||
|
@ -361,6 +371,7 @@ init_zathura()
|
||||||
pthread_mutex_init(&(Zathura.Lock.rotate_lock), NULL);
|
pthread_mutex_init(&(Zathura.Lock.rotate_lock), NULL);
|
||||||
pthread_mutex_init(&(Zathura.Lock.search_lock), NULL);
|
pthread_mutex_init(&(Zathura.Lock.search_lock), NULL);
|
||||||
pthread_mutex_init(&(Zathura.Lock.viewport_lock), NULL);
|
pthread_mutex_init(&(Zathura.Lock.viewport_lock), NULL);
|
||||||
|
pthread_mutex_init(&(Zathura.Lock.document_lock), NULL);
|
||||||
|
|
||||||
/* look */
|
/* look */
|
||||||
gdk_color_parse(default_fgcolor, &(Zathura.Style.default_fg));
|
gdk_color_parse(default_fgcolor, &(Zathura.Style.default_fg));
|
||||||
|
@ -395,6 +406,8 @@ init_zathura()
|
||||||
Zathura.Marker.number_of_markers = 0;
|
Zathura.Marker.number_of_markers = 0;
|
||||||
Zathura.Marker.last = -1;
|
Zathura.Marker.last = -1;
|
||||||
|
|
||||||
|
Zathura.Inotify.fd = inotify_init();
|
||||||
|
|
||||||
/* UI */
|
/* UI */
|
||||||
Zathura.UI.window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
Zathura.UI.window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||||
Zathura.UI.box = GTK_BOX(gtk_vbox_new(FALSE, 0));
|
Zathura.UI.box = GTK_BOX(gtk_vbox_new(FALSE, 0));
|
||||||
|
@ -752,8 +765,10 @@ open_file(char* path, char* password)
|
||||||
|
|
||||||
/* open file */
|
/* open file */
|
||||||
GError* error = NULL;
|
GError* error = NULL;
|
||||||
|
pthread_mutex_lock(&(Zathura.Lock.document_lock));
|
||||||
Zathura.PDF.document = poppler_document_new_from_file(g_strdup_printf("file://%s", file),
|
Zathura.PDF.document = poppler_document_new_from_file(g_strdup_printf("file://%s", file),
|
||||||
password ? password : NULL, &error);
|
password ? password : NULL, &error);
|
||||||
|
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||||
|
|
||||||
if(!Zathura.PDF.document)
|
if(!Zathura.PDF.document)
|
||||||
{
|
{
|
||||||
|
@ -765,7 +780,16 @@ open_file(char* path, char* password)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* inotify */
|
||||||
|
if(Zathura.Inotify.fd != -1)
|
||||||
|
{
|
||||||
|
if((Zathura.Inotify.wd = inotify_add_watch(Zathura.Inotify.fd, file, IN_CLOSE_WRITE)) != -1)
|
||||||
|
pthread_create(&(Zathura.Thread.inotify_thread), NULL, watch_file, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(Zathura.Lock.document_lock));
|
||||||
Zathura.PDF.number_of_pages = poppler_document_get_n_pages(Zathura.PDF.document);
|
Zathura.PDF.number_of_pages = poppler_document_get_n_pages(Zathura.PDF.document);
|
||||||
|
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||||
Zathura.PDF.file = file;
|
Zathura.PDF.file = file;
|
||||||
pthread_mutex_lock(&(Zathura.Lock.scale_lock));
|
pthread_mutex_lock(&(Zathura.Lock.scale_lock));
|
||||||
Zathura.PDF.scale = 100;
|
Zathura.PDF.scale = 100;
|
||||||
|
@ -781,7 +805,9 @@ open_file(char* path, char* password)
|
||||||
for(i = 0; i < Zathura.PDF.number_of_pages; i++)
|
for(i = 0; i < Zathura.PDF.number_of_pages; i++)
|
||||||
{
|
{
|
||||||
Zathura.PDF.pages[i] = malloc(sizeof(Page));
|
Zathura.PDF.pages[i] = malloc(sizeof(Page));
|
||||||
|
pthread_mutex_lock(&(Zathura.Lock.document_lock));
|
||||||
Zathura.PDF.pages[i]->page = poppler_document_get_page(Zathura.PDF.document, i);
|
Zathura.PDF.pages[i]->page = poppler_document_get_page(Zathura.PDF.document, i);
|
||||||
|
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||||
pthread_mutex_init(&(Zathura.PDF.pages[i]->lock), NULL);
|
pthread_mutex_init(&(Zathura.PDF.pages[i]->lock), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,7 +1061,9 @@ search(void* parameter)
|
||||||
next_page = (Zathura.PDF.number_of_pages + Zathura.PDF.page_number +
|
next_page = (Zathura.PDF.number_of_pages + Zathura.PDF.page_number +
|
||||||
page_counter * direction) % Zathura.PDF.number_of_pages;
|
page_counter * direction) % Zathura.PDF.number_of_pages;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(Zathura.Lock.document_lock));
|
||||||
PopplerPage* page = poppler_document_get_page(Zathura.PDF.document, next_page);
|
PopplerPage* page = poppler_document_get_page(Zathura.PDF.document, next_page);
|
||||||
|
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||||
if(!page)
|
if(!page)
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
results = poppler_page_find_text(page, search_item);
|
results = poppler_page_find_text(page, search_item);
|
||||||
|
@ -1061,6 +1089,43 @@ search(void* parameter)
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
watch_file(void* parameter)
|
||||||
|
{
|
||||||
|
int blen = sizeof(struct inotify_event);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
/* wait for event */
|
||||||
|
char buf[blen];
|
||||||
|
if(read(Zathura.Inotify.fd, buf, blen) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* process event */
|
||||||
|
struct inotify_event *event = (struct inotify_event*) buf;
|
||||||
|
if(event->mask & IN_CLOSE_WRITE)
|
||||||
|
{
|
||||||
|
/* save old information */
|
||||||
|
char* path = Zathura.PDF.file ? strdup(Zathura.PDF.file) : NULL;
|
||||||
|
char* password = Zathura.PDF.password ? strdup(Zathura.PDF.password) : NULL;
|
||||||
|
int scale = Zathura.PDF.scale;
|
||||||
|
int page = Zathura.PDF.page_number;
|
||||||
|
|
||||||
|
/* reopen and restore settings */
|
||||||
|
cmd_close(0, NULL);
|
||||||
|
open_file(path, password);
|
||||||
|
|
||||||
|
Zathura.PDF.scale = scale;
|
||||||
|
draw(page);
|
||||||
|
gtk_widget_queue_draw(Zathura.UI.drawing_area);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* shortcut implementation */
|
/* shortcut implementation */
|
||||||
void
|
void
|
||||||
sc_abort(Argument* argument)
|
sc_abort(Argument* argument)
|
||||||
|
@ -1260,7 +1325,9 @@ sc_toggle_index(Argument* argument)
|
||||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.UI.index),
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.UI.index),
|
||||||
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(Zathura.Lock.document_lock));
|
||||||
index_iter = poppler_index_iter_new(Zathura.PDF.document);
|
index_iter = poppler_index_iter_new(Zathura.PDF.document);
|
||||||
|
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||||
|
|
||||||
if(index_iter)
|
if(index_iter)
|
||||||
{
|
{
|
||||||
|
@ -1756,12 +1823,20 @@ cmd_close(int argc, char** argv)
|
||||||
g_free(bookmarks);
|
g_free(bookmarks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* inotify */
|
||||||
|
if(Zathura.Inotify.fd != -1 && Zathura.Inotify.wd != -1)
|
||||||
|
inotify_rm_watch(Zathura.Inotify.fd, Zathura.Inotify.wd);
|
||||||
|
|
||||||
|
Zathura.Inotify.wd = -1;
|
||||||
|
/*pthread_cancel(Zathura.Thread.inotify_thread);*/
|
||||||
|
|
||||||
/* reset values */
|
/* reset values */
|
||||||
free(Zathura.PDF.pages);
|
free(Zathura.PDF.pages);
|
||||||
g_object_unref(Zathura.PDF.document);
|
g_object_unref(Zathura.PDF.document);
|
||||||
|
|
||||||
Zathura.State.pages = "";
|
Zathura.State.pages = "";
|
||||||
Zathura.State.filename = (char*) DEFAULT_TEXT;
|
Zathura.State.filename = (char*) DEFAULT_TEXT;
|
||||||
|
|
||||||
Zathura.PDF.document = NULL;
|
Zathura.PDF.document = NULL;
|
||||||
Zathura.PDF.file = "";
|
Zathura.PDF.file = "";
|
||||||
Zathura.PDF.password = "";
|
Zathura.PDF.password = "";
|
||||||
|
@ -2506,10 +2581,15 @@ cb_destroy(GtkWidget* widget, gpointer data)
|
||||||
pthread_mutex_destroy(&(Zathura.Lock.rotate_lock));
|
pthread_mutex_destroy(&(Zathura.Lock.rotate_lock));
|
||||||
pthread_mutex_destroy(&(Zathura.Lock.search_lock));
|
pthread_mutex_destroy(&(Zathura.Lock.search_lock));
|
||||||
pthread_mutex_destroy(&(Zathura.Lock.viewport_lock));
|
pthread_mutex_destroy(&(Zathura.Lock.viewport_lock));
|
||||||
|
pthread_mutex_destroy(&(Zathura.Lock.document_lock));
|
||||||
|
|
||||||
/* clean up other variables */
|
/* clean up other variables */
|
||||||
g_free(Zathura.Bookmarks.file);
|
g_free(Zathura.Bookmarks.file);
|
||||||
|
|
||||||
|
/* inotify */
|
||||||
|
if(Zathura.Inotify.fd != -1)
|
||||||
|
close(Zathura.Inotify.fd);
|
||||||
|
|
||||||
gtk_main_quit();
|
gtk_main_quit();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -2517,8 +2597,7 @@ cb_destroy(GtkWidget* widget, gpointer data)
|
||||||
|
|
||||||
gboolean cb_draw(GtkWidget* widget, GdkEventExpose* expose, gpointer data)
|
gboolean cb_draw(GtkWidget* widget, GdkEventExpose* expose, gpointer data)
|
||||||
{
|
{
|
||||||
/*intptr_t t = (intptr_t) data;*/
|
int page_id = Zathura.PDF.page_number;
|
||||||
int page_id = Zathura.PDF.page_number; /* (int) t; */
|
|
||||||
|
|
||||||
if(page_id < 0 || page_id > Zathura.PDF.number_of_pages)
|
if(page_id < 0 || page_id > Zathura.PDF.number_of_pages)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in a new issue