diff --git a/page-widget.c b/page-widget.c index 0dae4dd..c02ec8d 100644 --- a/page-widget.c +++ b/page-widget.c @@ -13,6 +13,7 @@ #include "render.h" #include "utils.h" #include "shortcuts.h" +#include "synctex.h" G_DEFINE_TYPE(ZathuraPage, zathura_page_widget, GTK_TYPE_DRAWING_AREA) @@ -611,29 +612,38 @@ cb_zathura_page_widget_button_release_event(GtkWidget* widget, GdkEventButton* b } } else { redraw_rect(ZATHURA_PAGE(widget), &priv->mouse.selection); - zathura_rectangle_t tmp = priv->mouse.selection; - double scale = zathura_document_get_scale(document); - tmp.x1 /= scale; - tmp.x2 /= scale; - tmp.y1 /= scale; - tmp.y2 /= scale; + if (priv->zathura->synctex.enabled && button->state & GDK_CONTROL_MASK) { + /* synctex backwards sync */ + double scale = zathura_document_get_scale(document); + int x = button->x / scale, y = button->y / scale; - char* text = zathura_page_get_text(priv->page, tmp, NULL); - if (text != NULL) { - if (strlen(text) > 0) { - /* copy to clipboard */ - gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), text, -1); + synctex_edit(priv->zathura, priv->page, x, y); + } else { + zathura_rectangle_t tmp = priv->mouse.selection; + + double scale = zathura_document_get_scale(document); + tmp.x1 /= scale; + tmp.x2 /= scale; + tmp.y1 /= scale; + tmp.y2 /= scale; + + char* text = zathura_page_get_text(priv->page, tmp, NULL); + if (text != NULL) { + if (strlen(text) > 0) { + /* copy to clipboard */ + gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), text, -1); - if (priv->page != NULL && document != NULL && priv->zathura != NULL) { - char* stripped_text = g_strdelimit(g_strdup(text), "\n\t\r\n", ' '); - girara_notify(priv->zathura->ui.session, GIRARA_INFO, _("Copied selected text to clipboard: %s"), stripped_text); - g_free(stripped_text); + if (priv->page != NULL && document != NULL && priv->zathura != NULL) { + char* stripped_text = g_strdelimit(g_strdup(text), "\n\t\r\n", ' '); + girara_notify(priv->zathura->ui.session, GIRARA_INFO, _("Copied selected text to clipboard: %s"), stripped_text); + g_free(stripped_text); + } } - } - g_free(text); + g_free(text); + } } } diff --git a/synctex.c b/synctex.c new file mode 100644 index 0000000..9a9c91f --- /dev/null +++ b/synctex.c @@ -0,0 +1,31 @@ +/* See LICENSE file for license and copyright information */ + +#include "synctex.h" + +#include "zathura.h" +#include "page.h" +#include "document.h" + +#include + +void +synctex_edit(zathura_t* zathura, zathura_page_t* page, int x, int y) +{ + zathura_document_t* doc = zathura_page_get_document(page); + const char *filename = zathura_document_get_path(doc); + int pageIdx = zathura_page_get_index(page); + + char *buffer = g_strdup_printf("%d:%d:%d:%s", pageIdx+1, x, y, filename); + if (buffer == NULL) + return; + + if (zathura->synctex.editor) { + char* argv[] = {"synctex", "edit", "-o", buffer, "-x", zathura->synctex.editor, NULL}; + g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); + } else { + char* argv[] = {"synctex", "edit", "-o", buffer, NULL}; + g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); + } + + g_free(buffer); +} diff --git a/synctex.h b/synctex.h new file mode 100644 index 0000000..1514117 --- /dev/null +++ b/synctex.h @@ -0,0 +1,10 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef SYNCTEX_H +#define SYNCTEX_H + +#include "types.h" + +void synctex_edit(zathura_t* zathura, zathura_page_t* page, int x, int y); + +#endif diff --git a/zathura.c b/zathura.c index 4146dc4..6cf4860 100644 --- a/zathura.c +++ b/zathura.c @@ -66,8 +66,8 @@ zathura_init(int argc, char* argv[]) Window embed = 0; #endif - gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL, *loglevel = NULL, *password = NULL; - bool forkback = false, print_version = false; + gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL, *loglevel = NULL, *password = NULL, *synctex_editor = NULL; + bool forkback = false, print_version = false, synctex = false; GOptionEntry entries[] = { { "reparent", 'e', 0, G_OPTION_ARG_INT, &embed, _("Reparents to window specified by xid"), "xid" }, @@ -78,6 +78,8 @@ zathura_init(int argc, char* argv[]) { "password", 'w', 0, G_OPTION_ARG_STRING, &password, _("Document password"), "password" }, { "debug", 'l', 0, G_OPTION_ARG_STRING, &loglevel, _("Log level (debug, info, warning, error)"), "level" }, { "version", 'v', 0, G_OPTION_ARG_NONE, &print_version, _("Print version information"), NULL }, + { "synctex", 's', 0, G_OPTION_ARG_NONE, &synctex, _("Enable synctex support"), NULL }, + { "editor-command", 'x', 0, G_OPTION_ARG_STRING, &synctex_editor, _("Synctex editor (this flag is forwarded to the synctex command)"), "cmd" }, { NULL, '\0', 0, 0, NULL, NULL, NULL } }; @@ -144,6 +146,12 @@ zathura_init(int argc, char* argv[]) g_free(path); } + /* synctex */ + zathura->synctex.enabled = synctex; + if (synctex_editor) { + zathura->synctex.editor = g_strdup(synctex_editor); + } + /* create zathura (config/data) directory */ g_mkdir_with_parents(zathura->config.config_dir, 0771); g_mkdir_with_parents(zathura->config.data_dir, 0771); diff --git a/zathura.h b/zathura.h index 1233af9..f133c1f 100644 --- a/zathura.h +++ b/zathura.h @@ -66,6 +66,12 @@ struct zathura_s gchar* data_dir; /**< Path to the data directory */ } config; + struct + { + bool enabled; + gchar* editor; + } synctex; + struct { GtkPrintSettings* settings; /**< Print settings */