Enhancements/Cleanups for the jumplist mechansim

- Don't delete the elements on the right of the current one, when
	  appending a new jump to the jumplist, because this makes no sense at
	  all; the point of the jumplist in the first place is to remember
	  previously jumped-to positions in the document, so there is no need
	  to delete anythings except to trim the oldest entries from the
	  beginning to maintain the maximum size. This also makes us compatible
	  with the Vim way of doing things.

	- Make the jumplist mechanism functional on the same page; if we
	  followed a link to a target on the same page, remember the
	  adjustments before and after following the link. The same holds for
	  navigating search results on the same page.

	- Implement position_set and use it instead of position_set_delayed
	  when following links in order to give zathura_jumplist_save a chance
	  to record the exact adjustments of the link target. Otherwise, it
	  will always record the adjustments after going to the target page,
	  but before going to the exact position within it.

	- Don't consider movements with ^i and ^o as jumps :)

	- Don't use page_set followed by setting the adjustments in
	  sc_jumplist, because this is redundant and causes clutter when using
	  ^i and ^o, as the adjustments is set twice this way (once in page_set
	  and again in position_set_delayed).  It's enough to only update the
	  page number on the statusbar and then set the adjustments.

	- Hide implementation details (zathura_jumplist_save and
	  zathura_jumplist_append), and make things more consistent by
	  exporting and using only zathura_jumplist_add for adding new entries.

The end result: A more slick jumping experience :-)

Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
Marwan Tanager 2013-06-09 05:53:31 +02:00 committed by Sebastian Ramacher
parent 88bff5dfd2
commit afd008f466
6 changed files with 94 additions and 61 deletions

View file

@ -333,7 +333,7 @@ handle_link(GtkEntry* entry, girara_session_t* session,
invalid_index = false; invalid_index = false;
switch (action) { switch (action) {
case ZATHURA_LINK_ACTION_FOLLOW: case ZATHURA_LINK_ACTION_FOLLOW:
zathura_jumplist_save(zathura); zathura_jumplist_add(zathura);
zathura_link_evaluate(zathura, link); zathura_link_evaluate(zathura, link);
zathura_jumplist_add(zathura); zathura_jumplist_add(zathura);
break; break;
@ -534,7 +534,7 @@ cb_unknown_command(girara_session_t* session, const char* input)
} }
} }
zathura_jumplist_save(zathura); zathura_jumplist_add(zathura);
page_set(zathura, atoi(input) - 1); page_set(zathura, atoi(input) - 1);
zathura_jumplist_add(zathura); zathura_jumplist_add(zathura);

View file

@ -157,7 +157,7 @@ config_load_default(zathura_t* zathura)
girara_setting_add(gsession, "zoom-max", &int_value, INT, false, _("Zoom maximum"), NULL, NULL); girara_setting_add(gsession, "zoom-max", &int_value, INT, false, _("Zoom maximum"), NULL, NULL);
int_value = ZATHURA_PAGE_CACHE_DEFAULT_SIZE; int_value = ZATHURA_PAGE_CACHE_DEFAULT_SIZE;
girara_setting_add(gsession, "page-cache-size", &int_value, INT, true, _("Maximum number of pages to keep in the cache"), NULL, NULL); girara_setting_add(gsession, "page-cache-size", &int_value, INT, true, _("Maximum number of pages to keep in the cache"), NULL, NULL);
int_value = 20; int_value = 2000;
girara_setting_add(gsession, "jumplist-size", &int_value, INT, false, _("Number of positions to remember in the jumplist"), cb_jumplist_change, NULL); girara_setting_add(gsession, "jumplist-size", &int_value, INT, false, _("Number of positions to remember in the jumplist"), cb_jumplist_change, NULL);
girara_setting_add(gsession, "recolor-darkcolor", NULL, STRING, false, _("Recoloring (dark color)"), cb_color_change, NULL); girara_setting_add(gsession, "recolor-darkcolor", NULL, STRING, false, _("Recoloring (dark color)"), cb_color_change, NULL);

View file

@ -157,9 +157,9 @@ zathura_link_evaluate(zathura_t* zathura, zathura_link_t* link)
girara_setting_get(zathura->ui.session, "link-hadjust", &link_hadjust); girara_setting_get(zathura->ui.session, "link-hadjust", &link_hadjust);
if (link_hadjust == true) { if (link_hadjust == true) {
position_set_delayed(zathura, offset.x, offset.y); position_set(zathura, offset.x, offset.y);
} else { } else {
position_set_delayed(zathura, -1, offset.y); position_set(zathura, -1, offset.y);
} }
} }
break; break;

View file

@ -313,7 +313,7 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t*
g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false); g_return_val_if_fail(zathura->document != NULL, false);
zathura_jumplist_save(zathura); zathura_jumplist_add(zathura);
if (t != 0) { if (t != 0) {
/* add offset */ /* add offset */
t += zathura_document_get_page_offset(zathura->document); t += zathura_document_get_page_offset(zathura->document);
@ -328,7 +328,6 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t*
/* adjust horizontal position */ /* adjust horizontal position */
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
cb_view_hadjustment_changed(hadjustment, zathura); cb_view_hadjustment_changed(hadjustment, zathura);
zathura_jumplist_add(zathura); zathura_jumplist_add(zathura);
return false; return false;
@ -726,20 +725,19 @@ sc_jumplist(girara_session_t* session, girara_argument_t* argument,
zathura_jump_t* jump = NULL; zathura_jump_t* jump = NULL;
switch(argument->n) { switch(argument->n) {
case FORWARD: case FORWARD:
zathura_jumplist_save(zathura);
zathura_jumplist_forward(zathura); zathura_jumplist_forward(zathura);
jump = zathura_jumplist_current(zathura); jump = zathura_jumplist_current(zathura);
break; break;
case BACKWARD: case BACKWARD:
zathura_jumplist_save(zathura);
zathura_jumplist_backward(zathura); zathura_jumplist_backward(zathura);
jump = zathura_jumplist_current(zathura); jump = zathura_jumplist_current(zathura);
break; break;
} }
if (jump != NULL) { if (jump != NULL) {
page_set(zathura, jump->page); zathura_document_set_current_page_number(zathura->document, jump->page);
statusbar_page_number_update(zathura);
const double s = zathura_document_get_scale(zathura->document); const double s = zathura_document_get_scale(zathura->document);
position_set_delayed(zathura, jump->x * s, jump->y * s); position_set_delayed(zathura, jump->x * s, jump->y * s);
} }
@ -770,13 +768,11 @@ sc_bisect(girara_session_t* session, girara_argument_t* argument,
prev_page = prev2_page = 0; prev_page = prev2_page = 0;
have_prev = have_prev2 = false; have_prev = have_prev2 = false;
/* save position at current jump point */
zathura_jumplist_save(zathura);
/* process arguments */ /* process arguments */
int direction; int direction;
if (t > 0 && t <= number_of_pages) { if (t > 0 && t <= number_of_pages) {
/* jump to page t, and bisect between cur_page and t */ /* jump to page t, and bisect between cur_page and t */
zathura_jumplist_add(zathura);
page_set(zathura, t-1); page_set(zathura, t-1);
zathura_jumplist_add(zathura); zathura_jumplist_add(zathura);
if (t-1 > cur_page) { if (t-1 > cur_page) {
@ -825,6 +821,7 @@ sc_bisect(girara_session_t* session, girara_argument_t* argument,
if (have_prev && cur_page <= prev_page) { if (have_prev && cur_page <= prev_page) {
/* add a new jump point */ /* add a new jump point */
if (cur_page < prev_page) { if (cur_page < prev_page) {
zathura_jumplist_add(zathura);
page_set(zathura, (cur_page + prev_page)/2); page_set(zathura, (cur_page + prev_page)/2);
zathura_jumplist_add(zathura); zathura_jumplist_add(zathura);
} }
@ -833,14 +830,15 @@ sc_bisect(girara_session_t* session, girara_argument_t* argument,
/* save current position at previous jump point */ /* save current position at previous jump point */
if (cur_page < prev2_page) { if (cur_page < prev2_page) {
zathura_jumplist_backward(zathura); zathura_jumplist_backward(zathura);
zathura_jumplist_save(zathura); zathura_jumplist_add(zathura);
zathura_jumplist_forward(zathura); zathura_jumplist_forward(zathura);
page_set(zathura, (cur_page + prev2_page)/2); page_set(zathura, (cur_page + prev2_page)/2);
zathura_jumplist_save(zathura); zathura_jumplist_add(zathura);
} }
} else { } else {
/* none of prev_page or prev2_page comes after cur_page */ /* none of prev_page or prev2_page comes after cur_page */
zathura_jumplist_add(zathura);
page_set(zathura, (cur_page + number_of_pages - 1)/2); page_set(zathura, (cur_page + number_of_pages - 1)/2);
zathura_jumplist_add(zathura); zathura_jumplist_add(zathura);
} }
@ -850,6 +848,7 @@ sc_bisect(girara_session_t* session, girara_argument_t* argument,
if (have_prev && prev_page <= cur_page) { if (have_prev && prev_page <= cur_page) {
/* add a new jump point */ /* add a new jump point */
if (prev_page < cur_page) { if (prev_page < cur_page) {
zathura_jumplist_add(zathura);
page_set(zathura, (cur_page + prev_page)/2); page_set(zathura, (cur_page + prev_page)/2);
zathura_jumplist_add(zathura); zathura_jumplist_add(zathura);
} }
@ -858,15 +857,16 @@ sc_bisect(girara_session_t* session, girara_argument_t* argument,
/* save current position at previous jump point */ /* save current position at previous jump point */
if (prev2_page < cur_page) { if (prev2_page < cur_page) {
zathura_jumplist_backward(zathura); zathura_jumplist_backward(zathura);
zathura_jumplist_save(zathura); zathura_jumplist_add(zathura);
zathura_jumplist_forward(zathura); zathura_jumplist_forward(zathura);
page_set(zathura, (cur_page + prev2_page)/2); page_set(zathura, (cur_page + prev2_page)/2);
zathura_jumplist_save(zathura); zathura_jumplist_add(zathura);
} }
} else { } else {
/* none of prev_page or prev2_page comes before cur_page */ /* none of prev_page or prev2_page comes before cur_page */
zathura_jumplist_add(zathura);
page_set(zathura, cur_page/2); page_set(zathura, cur_page/2);
zathura_jumplist_add(zathura); zathura_jumplist_add(zathura);
} }
@ -947,8 +947,6 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
target_idx = current - 1; target_idx = current - 1;
} else { } else {
/* the next result is on a different page */ /* the next result is on a different page */
zathura_jumplist_save(zathura);
g_object_set(page_widget, "search-current", -1, NULL); g_object_set(page_widget, "search-current", -1, NULL);
for (int npage_id = 1; page_id < num_pages; ++npage_id) { for (int npage_id = 1; page_id < num_pages; ++npage_id) {
@ -962,8 +960,6 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
break; break;
} }
} }
zathura_jumplist_add(zathura);
} }
break; break;
@ -979,6 +975,7 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect); zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect);
page_offset_t offset; page_offset_t offset;
page_calculate_offset(zathura, target_page, &offset); page_calculate_offset(zathura, target_page, &offset);
zathura_jumplist_add(zathura);
if (zathura_page_get_index(target_page) != cur_page) { if (zathura_page_get_index(target_page) != cur_page) {
page_set(zathura, zathura_page_get_index(target_page)); page_set(zathura, zathura_page_get_index(target_page));
@ -995,6 +992,8 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
int x = offset.x - gtk_adjustment_get_page_size(view_hadjustment) / 2 + rectangle.x1; int x = offset.x - gtk_adjustment_get_page_size(view_hadjustment) / 2 + rectangle.x1;
zathura_adjustment_set_value(view_hadjustment, x); zathura_adjustment_set_value(view_hadjustment, x);
} }
zathura_jumplist_add(zathura);
} }
return false; return false;
@ -1190,7 +1189,7 @@ sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(argument),
hvalue = gtk_adjustment_get_value(hadjustment); hvalue = gtk_adjustment_get_value(hadjustment);
/* save current position to the jumplist */ /* save current position to the jumplist */
zathura_jumplist_save(zathura); zathura_jumplist_add(zathura);
girara_set_view(session, zathura->ui.index); girara_set_view(session, zathura->ui.index);
gtk_widget_show(GTK_WIDGET(zathura->ui.index)); gtk_widget_show(GTK_WIDGET(zathura->ui.index));

View file

@ -57,6 +57,9 @@ static bool zathura_page_cache_is_cached(zathura_t* zathura, unsigned int page_i
static ssize_t zathura_page_cache_lru_invalidate(zathura_t* zathura); static ssize_t zathura_page_cache_lru_invalidate(zathura_t* zathura);
static void zathura_page_cache_invalidate_all(zathura_t* zathura); static void zathura_page_cache_invalidate_all(zathura_t* zathura);
static bool zathura_page_cache_is_full(zathura_t* zathura, bool* result); static bool zathura_page_cache_is_full(zathura_t* zathura, bool* result);
static void zathura_jumplist_reset_current(zathura_t* zathura);
static void zathura_jumplist_append_jump(zathura_t* zathura);
static void zathura_jumplist_save(zathura_t* zathura);
/* function implementation */ /* function implementation */
zathura_t* zathura_t*
@ -275,8 +278,6 @@ zathura_init(zathura_t* zathura)
zathura->jumplist.list = girara_list_new2(g_free); zathura->jumplist.list = girara_list_new2(g_free);
zathura->jumplist.size = 0; zathura->jumplist.size = 0;
zathura->jumplist.cur = NULL; zathura->jumplist.cur = NULL;
zathura_jumplist_append_jump(zathura);
zathura->jumplist.cur = girara_list_iterator(zathura->jumplist.list);
/* page cache */ /* page cache */
@ -1111,9 +1112,11 @@ position_set_delayed_impl(gpointer data)
return FALSE; return FALSE;
} }
bool void
position_set_delayed(zathura_t* zathura, double position_x, double position_y) position_set_delayed(zathura_t* zathura, double position_x, double position_y)
{ {
g_return_if_fail(zathura != NULL);
position_set_delayed_t* p = g_malloc0(sizeof(position_set_delayed_t)); position_set_delayed_t* p = g_malloc0(sizeof(position_set_delayed_t));
p->zathura = zathura; p->zathura = zathura;
@ -1121,10 +1124,26 @@ position_set_delayed(zathura_t* zathura, double position_x, double position_y)
p->position_y = position_y; p->position_y = position_y;
gdk_threads_add_idle(position_set_delayed_impl, p); gdk_threads_add_idle(position_set_delayed_impl, p);
return FALSE;
} }
void
position_set(zathura_t* zathura, double position_x, double position_y)
{
g_return_if_fail(zathura != NULL);
GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view);
GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window);
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window);
/* negative values mean: don't set the position */
if (position_x >= 0) {
zathura_adjustment_set_value(hadjustment, position_x);
}
if (position_y >= 0) {
zathura_adjustment_set_value(vadjustment, position_y);
}
}
bool bool
zathura_jumplist_has_previous(zathura_t* zathura) zathura_jumplist_has_previous(zathura_t* zathura)
@ -1133,7 +1152,7 @@ zathura_jumplist_has_previous(zathura_t* zathura)
} }
bool bool
zathura_jumplist_has_has_next(zathura_t* zathura) zathura_jumplist_has_next(zathura_t* zathura)
{ {
return girara_list_iterator_has_next(zathura->jumplist.cur); return girara_list_iterator_has_next(zathura->jumplist.cur);
} }
@ -1164,7 +1183,25 @@ zathura_jumplist_backward(zathura_t* zathura)
} }
} }
void static void
zathura_jumplist_reset_current(zathura_t* zathura)
{
g_return_if_fail(zathura != NULL || zathura->jumplist.cur != NULL);
if (girara_list_iterator_has_next(zathura->jumplist.cur) == false) {
return;
}
while (true) {
girara_list_iterator_next(zathura->jumplist.cur);
if (girara_list_iterator_has_next(zathura->jumplist.cur) == false) {
return;
}
}
}
static void
zathura_jumplist_append_jump(zathura_t* zathura) zathura_jumplist_append_jump(zathura_t* zathura)
{ {
zathura_jump_t *jump = g_malloc(sizeof(zathura_jump_t)); zathura_jump_t *jump = g_malloc(sizeof(zathura_jump_t));
@ -1173,17 +1210,6 @@ zathura_jumplist_append_jump(zathura_t* zathura)
jump->x = 0; jump->x = 0;
jump->y = 0; jump->y = 0;
/* remove right tail after current */
if (zathura->jumplist.cur != NULL) {
girara_list_iterator_t *it = girara_list_iterator_copy(zathura->jumplist.cur);
girara_list_iterator_next(it);
while (girara_list_iterator_is_valid(it)) {
girara_list_iterator_remove(it);
zathura->jumplist.size = zathura->jumplist.size - 1;
}
g_free(it);
}
/* trim from beginning until max_size */ /* trim from beginning until max_size */
girara_list_iterator_t *it = girara_list_iterator(zathura->jumplist.list); girara_list_iterator_t *it = girara_list_iterator(zathura->jumplist.list);
while (zathura->jumplist.size >= zathura->jumplist.max_size && girara_list_iterator_is_valid(it)) { while (zathura->jumplist.size >= zathura->jumplist.max_size && girara_list_iterator_is_valid(it)) {
@ -1193,6 +1219,11 @@ zathura_jumplist_append_jump(zathura_t* zathura)
g_free(it); g_free(it);
girara_list_append(zathura->jumplist.list, jump); girara_list_append(zathura->jumplist.list, jump);
if (zathura->jumplist.size == 0) {
zathura->jumplist.cur = girara_list_iterator(zathura->jumplist.list);
}
zathura->jumplist.size = zathura->jumplist.size + 1; zathura->jumplist.size = zathura->jumplist.size + 1;
} }
} }
@ -1201,20 +1232,29 @@ void
zathura_jumplist_add(zathura_t* zathura) zathura_jumplist_add(zathura_t* zathura)
{ {
if (zathura->jumplist.list != NULL) { if (zathura->jumplist.list != NULL) {
unsigned int pagenum = zathura_document_get_current_page_number(zathura->document); unsigned int pagenum = zathura_document_get_current_page_number(zathura->document);
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
double x, y;
x = gtk_adjustment_get_value(view_hadjustment) / zathura_document_get_scale(zathura->document);
y = gtk_adjustment_get_value(view_vadjustment) / zathura_document_get_scale(zathura->document);
zathura_jumplist_reset_current(zathura);
zathura_jump_t* cur = zathura_jumplist_current(zathura); zathura_jump_t* cur = zathura_jumplist_current(zathura);
if (cur && cur->page == pagenum) {
if (cur && cur->page == pagenum && cur->x == x && cur->y == y) {
return; return;
} }
zathura_jumplist_append_jump(zathura); zathura_jumplist_append_jump(zathura);
girara_list_iterator_next(zathura->jumplist.cur); zathura_jumplist_reset_current(zathura);
zathura_jumplist_save(zathura); zathura_jumplist_save(zathura);
} }
} }
static void
void
zathura_jumplist_save(zathura_t* zathura) zathura_jumplist_save(zathura_t* zathura)
{ {
zathura_jump_t* cur = zathura_jumplist_current(zathura); zathura_jump_t* cur = zathura_jumplist_current(zathura);
@ -1228,7 +1268,7 @@ zathura_jumplist_save(zathura_t* zathura)
cur->page = pagenum; cur->page = pagenum;
cur->x = gtk_adjustment_get_value(view_hadjustment) / zathura_document_get_scale(zathura->document); cur->x = gtk_adjustment_get_value(view_hadjustment) / zathura_document_get_scale(zathura->document);
cur->y = gtk_adjustment_get_value(view_vadjustment) / zathura_document_get_scale(zathura->document);; cur->y = gtk_adjustment_get_value(view_vadjustment) / zathura_document_get_scale(zathura->document);
} }
} }

View file

@ -313,9 +313,17 @@ bool page_set_delayed(zathura_t* zathura, unsigned int page_id);
* @param zathura Zathura session * @param zathura Zathura session
* @param position_x X coordinate * @param position_x X coordinate
* @param position_y Y coordinate * @param position_y Y coordinate
* @return If no error occured true, otherwise false, is returned.
*/ */
bool position_set_delayed(zathura_t* zathura, double position_x, double position_y); void position_set_delayed(zathura_t* zathura, double position_x, double position_y);
/**
* Moves to the given position
*
* @param zathura Zathura session
* @param position_x X coordinate
* @param position_y Y coordinate
*/
void position_set(zathura_t* zathura, double position_x, double position_y);
/** /**
* Builds the box structure to show the rendered pages * Builds the box structure to show the rendered pages
@ -372,13 +380,6 @@ void zathura_jumplist_forward(zathura_t* zathura);
*/ */
void zathura_jumplist_backward(zathura_t* zathura); void zathura_jumplist_backward(zathura_t* zathura);
/**
* Save current page to the jumplist at current position
*
* @param zathura The zathura session
*/
void zathura_jumplist_save(zathura_t* zathura);
/** /**
* Add current page as a new item to the jumplist after current position * Add current page as a new item to the jumplist after current position
* *
@ -386,13 +387,6 @@ void zathura_jumplist_save(zathura_t* zathura);
*/ */
void zathura_jumplist_add(zathura_t* zathura); void zathura_jumplist_add(zathura_t* zathura);
/**
* Add a page to the jumplist after current position
*
* @param zathura The zathura session
*/
void zathura_jumplist_append_jump(zathura_t* zathura);
/** /**
* Add a page to the page cache * Add a page to the page cache
* *