mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-28 05:36:00 +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 <libgen.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#include <poppler/glib/poppler.h>
|
||||
#include <cairo.h>
|
||||
|
@ -193,12 +194,14 @@ struct
|
|||
pthread_mutex_t rotate_lock;
|
||||
pthread_mutex_t search_lock;
|
||||
pthread_mutex_t viewport_lock;
|
||||
pthread_mutex_t document_lock;
|
||||
} Lock;
|
||||
|
||||
struct
|
||||
{
|
||||
pthread_t search_thread;
|
||||
gboolean search_thread_running;
|
||||
pthread_t search_thread;
|
||||
gboolean search_thread_running;
|
||||
pthread_t inotify_thread;
|
||||
} Thread;
|
||||
|
||||
struct
|
||||
|
@ -215,6 +218,12 @@ struct
|
|||
int last;
|
||||
} Marker;
|
||||
|
||||
struct
|
||||
{
|
||||
int wd;
|
||||
int fd;
|
||||
} Inotify;
|
||||
|
||||
struct
|
||||
{
|
||||
GKeyFile *data;
|
||||
|
@ -258,6 +267,7 @@ GtkEventBox* createCompletionRow(GtkBox*, char*, char*, gboolean);
|
|||
|
||||
/* thread declaration */
|
||||
void* search(void*);
|
||||
void* watch_file(void*);
|
||||
|
||||
/* shortcut declarations */
|
||||
void sc_abort(Argument*);
|
||||
|
@ -361,6 +371,7 @@ init_zathura()
|
|||
pthread_mutex_init(&(Zathura.Lock.rotate_lock), NULL);
|
||||
pthread_mutex_init(&(Zathura.Lock.search_lock), NULL);
|
||||
pthread_mutex_init(&(Zathura.Lock.viewport_lock), NULL);
|
||||
pthread_mutex_init(&(Zathura.Lock.document_lock), NULL);
|
||||
|
||||
/* look */
|
||||
gdk_color_parse(default_fgcolor, &(Zathura.Style.default_fg));
|
||||
|
@ -395,6 +406,8 @@ init_zathura()
|
|||
Zathura.Marker.number_of_markers = 0;
|
||||
Zathura.Marker.last = -1;
|
||||
|
||||
Zathura.Inotify.fd = inotify_init();
|
||||
|
||||
/* UI */
|
||||
Zathura.UI.window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
Zathura.UI.box = GTK_BOX(gtk_vbox_new(FALSE, 0));
|
||||
|
@ -752,8 +765,10 @@ open_file(char* path, char* password)
|
|||
|
||||
/* open file */
|
||||
GError* error = NULL;
|
||||
pthread_mutex_lock(&(Zathura.Lock.document_lock));
|
||||
Zathura.PDF.document = poppler_document_new_from_file(g_strdup_printf("file://%s", file),
|
||||
password ? password : NULL, &error);
|
||||
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||
|
||||
if(!Zathura.PDF.document)
|
||||
{
|
||||
|
@ -765,7 +780,16 @@ open_file(char* path, char* password)
|
|||
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);
|
||||
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||
Zathura.PDF.file = file;
|
||||
pthread_mutex_lock(&(Zathura.Lock.scale_lock));
|
||||
Zathura.PDF.scale = 100;
|
||||
|
@ -781,7 +805,9 @@ open_file(char* path, char* password)
|
|||
for(i = 0; i < Zathura.PDF.number_of_pages; i++)
|
||||
{
|
||||
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);
|
||||
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||
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 +
|
||||
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);
|
||||
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||
if(!page)
|
||||
pthread_exit(NULL);
|
||||
results = poppler_page_find_text(page, search_item);
|
||||
|
@ -1061,6 +1089,43 @@ search(void* parameter)
|
|||
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 */
|
||||
void
|
||||
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_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
|
||||
pthread_mutex_lock(&(Zathura.Lock.document_lock));
|
||||
index_iter = poppler_index_iter_new(Zathura.PDF.document);
|
||||
pthread_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||
|
||||
if(index_iter)
|
||||
{
|
||||
|
@ -1756,12 +1823,20 @@ cmd_close(int argc, char** argv)
|
|||
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 */
|
||||
free(Zathura.PDF.pages);
|
||||
g_object_unref(Zathura.PDF.document);
|
||||
|
||||
Zathura.State.pages = "";
|
||||
Zathura.State.filename = (char*) DEFAULT_TEXT;
|
||||
|
||||
Zathura.PDF.document = NULL;
|
||||
Zathura.PDF.file = "";
|
||||
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.search_lock));
|
||||
pthread_mutex_destroy(&(Zathura.Lock.viewport_lock));
|
||||
pthread_mutex_destroy(&(Zathura.Lock.document_lock));
|
||||
|
||||
/* clean up other variables */
|
||||
g_free(Zathura.Bookmarks.file);
|
||||
|
||||
/* inotify */
|
||||
if(Zathura.Inotify.fd != -1)
|
||||
close(Zathura.Inotify.fd);
|
||||
|
||||
gtk_main_quit();
|
||||
|
||||
return TRUE;
|
||||
|
@ -2517,8 +2597,7 @@ cb_destroy(GtkWidget* widget, 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) t; */
|
||||
int page_id = Zathura.PDF.page_number;
|
||||
|
||||
if(page_id < 0 || page_id > Zathura.PDF.number_of_pages)
|
||||
return FALSE;
|
||||
|
|
Loading…
Reference in a new issue