mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-28 04:16:02 +01:00
Keyboard navigation for the index
This patch provides the functionality to browse through the index via the keyboard hence the mouse is not needed anymore. The original author of this patch is int3 <jezreel@gmail.com>, in addition there has been introduced a fix solving problems with named destinations.
This commit is contained in:
parent
273ba0c642
commit
e4f80b864b
2 changed files with 143 additions and 43 deletions
|
@ -68,6 +68,7 @@ Shortcut shortcuts[] = {
|
|||
{GDK_SHIFT_MASK, GDK_slash, sc_focus_inputbar, NORMAL, { .data = "/" } },
|
||||
{GDK_SHIFT_MASK, GDK_question, sc_focus_inputbar, NORMAL, { .data = "?" } },
|
||||
{0, GDK_Tab, sc_toggle_index, NORMAL, {0} },
|
||||
{0, GDK_Tab, sc_toggle_index, INDEX, {0} },
|
||||
{0, GDK_J, sc_navigate, NORMAL, { NEXT } },
|
||||
{0, GDK_K, sc_navigate, NORMAL, { PREVIOUS } },
|
||||
{GDK_MOD1_MASK, GDK_Right, sc_navigate, NORMAL, { NEXT } },
|
||||
|
@ -95,6 +96,12 @@ Shortcut shortcuts[] = {
|
|||
{0, GDK_a, sc_adjust_window, NORMAL, { ADJUST_BESTFIT } },
|
||||
{0, GDK_s, sc_adjust_window, NORMAL, { ADJUST_WIDTH } },
|
||||
{0, GDK_BackSpace, sc_change_buffer, -1, { DELETE_LAST } },
|
||||
{0, GDK_k, sc_navigate_index, INDEX, { UP } },
|
||||
{0, GDK_j, sc_navigate_index, INDEX, { DOWN } },
|
||||
{0, GDK_h, sc_navigate_index, INDEX, { COLLAPSE } },
|
||||
{0, GDK_l, sc_navigate_index, INDEX, { EXPAND } },
|
||||
{0, GDK_space, sc_navigate_index, INDEX, { SELECT } },
|
||||
{0, GDK_Return, sc_navigate_index, INDEX, { SELECT } },
|
||||
};
|
||||
|
||||
/* inputbar shortcuts */
|
||||
|
|
179
zathura.c
179
zathura.c
|
@ -27,7 +27,7 @@ enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN,
|
|||
ZOOM_IN, ZOOM_OUT, ZOOM_ORIGINAL, ZOOM_SPECIFIC,
|
||||
FORWARD, BACKWARD, ADJUST_BESTFIT, ADJUST_WIDTH,
|
||||
ADJUST_NONE, CONTINUOUS, DELETE_LAST, ADD_MARKER,
|
||||
EVAL_MARKER };
|
||||
EVAL_MARKER, INDEX, EXPAND, COLLAPSE, SELECT };
|
||||
|
||||
/* typedefs */
|
||||
struct CElement
|
||||
|
@ -288,6 +288,7 @@ void sc_recolor(Argument*);
|
|||
void sc_rotate(Argument*);
|
||||
void sc_scroll(Argument*);
|
||||
void sc_search(Argument*);
|
||||
void sc_navigate_index(Argument*);
|
||||
void sc_toggle_index(Argument*);
|
||||
void sc_toggle_inputbar(Argument*);
|
||||
void sc_toggle_statusbar(Argument*);
|
||||
|
@ -333,7 +334,7 @@ gboolean scmd_search(char*, Argument*);
|
|||
/* callback declarations */
|
||||
gboolean cb_destroy(GtkWidget*, gpointer);
|
||||
gboolean cb_draw(GtkWidget*, GdkEventExpose*, gpointer);
|
||||
gboolean cb_index_selection_changed(GtkTreeSelection*, GtkWidget*);
|
||||
gboolean cb_index_row_activated(GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, gpointer);
|
||||
gboolean cb_inputbar_kb_pressed(GtkWidget*, GdkEventKey*, gpointer);
|
||||
gboolean cb_inputbar_activate(GtkEntry*, gpointer);
|
||||
gboolean cb_inputbar_form_activate(GtkEntry*, gpointer);
|
||||
|
@ -1089,10 +1090,10 @@ search(void* parameter)
|
|||
g_static_mutex_lock(&(Zathura.Lock.document_lock));
|
||||
if(!Zathura.PDF.document || !search_item || !strlen(search_item))
|
||||
{
|
||||
g_static_mutex_lock(&(Zathura.Lock.document_lock));
|
||||
g_static_mutex_lock(&(Zathura.Lock.search_lock));
|
||||
Zathura.Thread.search_thread_running = FALSE;
|
||||
g_static_mutex_unlock(&(Zathura.Lock.search_lock));
|
||||
g_static_mutex_lock(&(Zathura.Lock.document_lock));
|
||||
g_thread_exit(NULL);
|
||||
}
|
||||
g_static_mutex_unlock(&(Zathura.Lock.document_lock));
|
||||
|
@ -1101,6 +1102,9 @@ search(void* parameter)
|
|||
if(argument->n)
|
||||
direction = (argument->n == BACKWARD) ? -1 : 1;
|
||||
|
||||
int number_of_pages = Zathura.PDF.number_of_pages;
|
||||
int page_number = Zathura.PDF.page_number;
|
||||
|
||||
for(page_counter = 1; page_counter <= Zathura.PDF.number_of_pages; page_counter++)
|
||||
{
|
||||
g_static_mutex_lock(&(Zathura.Lock.search_lock));
|
||||
|
@ -1111,9 +1115,8 @@ search(void* parameter)
|
|||
}
|
||||
g_static_mutex_unlock(&(Zathura.Lock.search_lock));
|
||||
|
||||
// probably should wrap this in a mutex, but I'm lazy
|
||||
next_page = (Zathura.PDF.number_of_pages + Zathura.PDF.page_number +
|
||||
page_counter * direction) % Zathura.PDF.number_of_pages;
|
||||
next_page = (number_of_pages + page_number +
|
||||
page_counter * direction) % number_of_pages;
|
||||
|
||||
g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
|
||||
PopplerPage* page = poppler_document_get_page(Zathura.PDF.document, next_page);
|
||||
|
@ -1152,7 +1155,7 @@ search(void* parameter)
|
|||
g_static_mutex_unlock(&(Zathura.Lock.search_lock));
|
||||
|
||||
g_thread_exit(NULL);
|
||||
return NULL; // suppress GCC warnings about return value
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void*
|
||||
|
@ -1431,6 +1434,124 @@ sc_search(Argument* argument)
|
|||
g_static_mutex_unlock(&(Zathura.Lock.search_lock));
|
||||
}
|
||||
|
||||
gboolean cb_index_row_activated(GtkTreeView* treeview, GtkTreePath* path,
|
||||
GtkTreeViewColumn* column, gpointer user_data)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
g_object_get(treeview, "model", &model, NULL);
|
||||
|
||||
if(gtk_tree_model_get_iter(model, &iter, path))
|
||||
{
|
||||
PopplerAction* action;
|
||||
PopplerDest* destination;
|
||||
|
||||
gtk_tree_model_get(model, &iter, 1, &action, -1);
|
||||
if(!action)
|
||||
return TRUE;
|
||||
|
||||
if(action->type == POPPLER_ACTION_GOTO_DEST)
|
||||
{
|
||||
destination = action->goto_dest.dest;
|
||||
int page_number = destination->page_num;
|
||||
|
||||
if(action->goto_dest.dest->type == POPPLER_DEST_NAMED)
|
||||
{
|
||||
PopplerDest* d = poppler_document_find_dest(Zathura.PDF.document, action->goto_dest.dest->named_dest);
|
||||
if(d)
|
||||
{
|
||||
page_number = d->page_num;
|
||||
poppler_dest_free(d);
|
||||
}
|
||||
}
|
||||
|
||||
set_page(page_number - 1);
|
||||
update_status();
|
||||
gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.view));
|
||||
}
|
||||
}
|
||||
|
||||
Zathura.Global.mode = NORMAL;
|
||||
g_object_unref(model);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
sc_navigate_index(Argument* argument)
|
||||
{
|
||||
GtkTreeView *treeview = gtk_container_get_children(GTK_CONTAINER(Zathura.UI.index))->data;
|
||||
GtkTreePath *path;
|
||||
|
||||
gtk_tree_view_get_cursor(treeview, &path, NULL);
|
||||
if(!path)
|
||||
return;
|
||||
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(treeview);
|
||||
GtkTreeIter iter;
|
||||
GtkTreeIter child_iter;
|
||||
|
||||
gboolean is_valid_path = TRUE;
|
||||
|
||||
switch(argument->n)
|
||||
{
|
||||
case UP:
|
||||
if(!gtk_tree_path_prev(path))
|
||||
is_valid_path = gtk_tree_path_up(path);
|
||||
else /* row above */
|
||||
{
|
||||
while(gtk_tree_view_row_expanded(treeview, path)) {
|
||||
gtk_tree_model_get_iter(model, &iter, path);
|
||||
/* select last child */
|
||||
gtk_tree_model_iter_nth_child(model, &child_iter, &iter,
|
||||
gtk_tree_model_iter_n_children(model, &iter)-1);
|
||||
gtk_tree_path_free(path);
|
||||
path = gtk_tree_model_get_path(model, &child_iter);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case COLLAPSE:
|
||||
if(!gtk_tree_view_collapse_row(treeview, path)
|
||||
&& gtk_tree_path_get_depth(path) > 1)
|
||||
{
|
||||
gtk_tree_path_up(path);
|
||||
gtk_tree_view_collapse_row(treeview, path);
|
||||
}
|
||||
break;
|
||||
case DOWN:
|
||||
if(gtk_tree_view_row_expanded(treeview, path))
|
||||
gtk_tree_path_down(path);
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
gtk_tree_model_get_iter(model, &iter, path);
|
||||
if (gtk_tree_model_iter_next(model, &iter))
|
||||
{
|
||||
path = gtk_tree_model_get_path(model, &iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while((is_valid_path = (gtk_tree_path_get_depth(path) > 1))
|
||||
&& gtk_tree_path_up(path));
|
||||
}
|
||||
break;
|
||||
case EXPAND:
|
||||
if(gtk_tree_view_expand_row(treeview, path, FALSE))
|
||||
gtk_tree_path_down(path);
|
||||
break;
|
||||
case SELECT:
|
||||
cb_index_row_activated(treeview, path, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_valid_path)
|
||||
gtk_tree_view_set_cursor(treeview, path, NULL, FALSE);
|
||||
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
|
||||
void
|
||||
sc_toggle_index(Argument* argument)
|
||||
{
|
||||
|
@ -1440,7 +1561,6 @@ sc_toggle_index(Argument* argument)
|
|||
GtkWidget *treeview;
|
||||
GtkTreeModel *model;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeSelection *selection;
|
||||
PopplerIndexIter *iter;
|
||||
|
||||
if(!Zathura.UI.index)
|
||||
|
@ -1473,9 +1593,8 @@ sc_toggle_index(Argument* argument)
|
|||
g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
|
||||
g_object_set(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0)), "expand", TRUE, NULL);
|
||||
|
||||
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
|
||||
gtk_tree_selection_select_path(selection, gtk_tree_path_new_first());
|
||||
g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(cb_index_selection_changed), NULL);
|
||||
gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), gtk_tree_path_new_first(), NULL, FALSE);
|
||||
g_signal_connect(G_OBJECT(treeview), "row-activated", G_CALLBACK(cb_index_row_activated), NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (Zathura.UI.index), treeview);
|
||||
gtk_widget_show (treeview);
|
||||
|
@ -1484,9 +1603,15 @@ sc_toggle_index(Argument* argument)
|
|||
|
||||
static gboolean show = FALSE;
|
||||
if(!show)
|
||||
{
|
||||
switch_view(Zathura.UI.index);
|
||||
Zathura.Global.mode = INDEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch_view(Zathura.UI.drawing_area);
|
||||
Zathura.Global.mode = NORMAL;
|
||||
}
|
||||
|
||||
show = !show;
|
||||
}
|
||||
|
@ -2783,38 +2908,6 @@ gboolean cb_draw(GtkWidget* widget, GdkEventExpose* expose, gpointer data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cb_index_selection_changed(GtkTreeSelection* treeselection, GtkWidget* action_view)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
if(gtk_tree_selection_get_selected(treeselection, &model, &iter))
|
||||
{
|
||||
PopplerAction* action;
|
||||
PopplerDest* destination;
|
||||
|
||||
gtk_tree_model_get(model, &iter, 1, &action, -1);
|
||||
if(!action)
|
||||
return TRUE;
|
||||
|
||||
if(action->type == POPPLER_ACTION_GOTO_DEST)
|
||||
{
|
||||
destination = action->goto_dest.dest;
|
||||
int page_number = destination->page_num;
|
||||
|
||||
if(page_number >= 0 && page_number <= Zathura.PDF.number_of_pages)
|
||||
{
|
||||
set_page(page_number - 1);
|
||||
update_status();
|
||||
gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.view));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cb_inputbar_kb_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue