Commit cc3b9aea authored by Marwan Tanager's avatar Marwan Tanager Committed by Sebastian Ramacher

More Vim-like search behavior

This patch activates the last aborted search when pressing the search shortcuts
('n' or 'N').

To avoid confusion, and to make things more predictable, I've chosen to always
reactivate an aborted search starting from the beginning (or end, in case of
'N' or '?') of the current page, as opposed to Vim which continues from the
next search term each time the search is reactivated.

Searching using '/' or '?' doesn't center the view at the current search term
like when using 'n' or 'N', so we fix this here.

Also, I managed to work around the issue of the thin rectangular margins that
show around the previously-highlighted search terms after the search is aborted
(either explicitly or as a result of following links), by redrawing the page
widget (only if it's visible) instead of redrawing the rectangles covering the
highlighted search terms.
Signed-off-by: Sebastian Ramacher's avatarSebastian Ramacher <sebastian+dev@ramacher.at>
parent 463545c3
...@@ -106,6 +106,13 @@ cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpoi ...@@ -106,6 +106,13 @@ cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpoi
} }
} else { } else {
zathura_page_set_visibility(page, false); zathura_page_set_visibility(page, false);
girara_list_t* results = NULL;
g_object_get(page_widget, "search-results", &results, NULL);
if (results != NULL) {
g_object_set(page_widget, "search-current", 0, NULL);
}
} }
} }
......
...@@ -339,7 +339,6 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu ...@@ -339,7 +339,6 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu
return false; return false;
} }
bool firsthit = true;
zathura_error_t error = ZATHURA_ERROR_OK; zathura_error_t error = ZATHURA_ERROR_OK;
/* set search direction */ /* set search direction */
...@@ -352,10 +351,6 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu ...@@ -352,10 +351,6 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu
bool nohlsearch = false; bool nohlsearch = false;
girara_setting_get(session, "nohlsearch", &nohlsearch); girara_setting_get(session, "nohlsearch", &nohlsearch);
if (nohlsearch == false) {
document_draw_search_results(zathura, true);
}
/* search pages */ /* search pages */
for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) { for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) {
unsigned int index = (page_id + current_page_number) % number_of_pages; unsigned int index = (page_id + current_page_number) % number_of_pages;
...@@ -383,20 +378,21 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu ...@@ -383,20 +378,21 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu
} }
g_object_set(page_widget, "search-results", result, NULL); g_object_set(page_widget, "search-results", result, NULL);
if (firsthit == true) {
if (page_id != 0) { if (argument->n == BACKWARD) {
page_set_delayed(zathura, zathura_page_get_index(page)); /* start at bottom hit in page */
} g_object_set(page_widget, "search-current", girara_list_size(result) - 1, NULL);
if (argument->n == BACKWARD) { } else {
/* start at bottom hit in page */ g_object_set(page_widget, "search-current", 0, NULL);
g_object_set(page_widget, "search-current", girara_list_size(result) - 1, NULL);
} else {
g_object_set(page_widget, "search-current", 0, NULL);
}
firsthit = false;
} }
} }
girara_argument_t* arg = g_malloc0(sizeof(girara_argument_t));
arg->n = FORWARD;
sc_search(session, arg, NULL, 0);
g_free(arg);
return true; return true;
} }
......
...@@ -86,7 +86,7 @@ enum properties_e { ...@@ -86,7 +86,7 @@ enum properties_e {
PROP_SEARCH_RESULTS, PROP_SEARCH_RESULTS,
PROP_SEARCH_RESULTS_LENGTH, PROP_SEARCH_RESULTS_LENGTH,
PROP_SEARCH_RESULTS_CURRENT, PROP_SEARCH_RESULTS_CURRENT,
PROP_DRAW_SEACH_RESULTS, PROP_DRAW_SEARCH_RESULTS,
PROP_LAST_VIEW, PROP_LAST_VIEW,
}; };
...@@ -131,8 +131,8 @@ zathura_page_widget_class_init(ZathuraPageClass* class) ...@@ -131,8 +131,8 @@ zathura_page_widget_class_init(ZathuraPageClass* class)
g_param_spec_int("search-current", "search-current", "The current search result", -1, INT_MAX, 0, G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_param_spec_int("search-current", "search-current", "The current search result", -1, INT_MAX, 0, G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class, PROP_SEARCH_RESULTS_LENGTH, g_object_class_install_property(object_class, PROP_SEARCH_RESULTS_LENGTH,
g_param_spec_int("search-length", "search-length", "The number of search results", -1, INT_MAX, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_param_spec_int("search-length", "search-length", "The number of search results", -1, INT_MAX, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class, PROP_DRAW_SEACH_RESULTS, g_object_class_install_property(object_class, PROP_DRAW_SEARCH_RESULTS,
g_param_spec_boolean("draw-search-results", "draw-search-results", "Set to true if search results should be drawn", FALSE, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); g_param_spec_boolean("draw-search-results", "draw-search-results", "Set to true if search results should be drawn", FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class, PROP_LAST_VIEW, g_object_class_install_property(object_class, PROP_LAST_VIEW,
g_param_spec_int64("last-view", "last-view", "Last time the page has been viewed", -1, G_MAXINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_param_spec_int64("last-view", "last-view", "Last time the page has been viewed", -1, G_MAXINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
} }
...@@ -154,7 +154,7 @@ zathura_page_widget_init(ZathuraPage* widget) ...@@ -154,7 +154,7 @@ zathura_page_widget_init(ZathuraPage* widget)
priv->search.list = NULL; priv->search.list = NULL;
priv->search.current = INT_MAX; priv->search.current = INT_MAX;
priv->search.draw = true; priv->search.draw = false;
priv->images.list = NULL; priv->images.list = NULL;
priv->images.retrieved = false; priv->images.retrieved = false;
...@@ -269,8 +269,19 @@ zathura_page_widget_set_property(GObject* object, guint prop_id, const GValue* v ...@@ -269,8 +269,19 @@ zathura_page_widget_set_property(GObject* object, guint prop_id, const GValue* v
} }
break; break;
} }
case PROP_DRAW_SEACH_RESULTS: case PROP_DRAW_SEARCH_RESULTS:
priv->search.draw = g_value_get_boolean(value); priv->search.draw = g_value_get_boolean(value);
/*
* we do the following instead of only redrawing the rectangles of the
* search results in order to avoid the rectangular margins that appear
* around the search terms after their highlighted rectangular areas are
* redrawn without highlighting.
*/
if (priv->search.list != NULL && zathura_page_get_visibility(priv->page)) {
gtk_widget_queue_draw(GTK_WIDGET(object));
}
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
...@@ -299,6 +310,9 @@ zathura_page_widget_get_property(GObject* object, guint prop_id, GValue* value, ...@@ -299,6 +310,9 @@ zathura_page_widget_get_property(GObject* object, guint prop_id, GValue* value,
case PROP_LAST_VIEW: case PROP_LAST_VIEW:
g_value_set_int64(value, priv->last_view); g_value_set_int64(value, priv->last_view);
break; break;
case PROP_DRAW_SEARCH_RESULTS:
g_value_set_boolean(value, priv->search.draw);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
} }
......
...@@ -34,7 +34,7 @@ draw_links(zathura_t* zathura) ...@@ -34,7 +34,7 @@ draw_links(zathura_t* zathura)
} }
GtkWidget* page_widget = zathura_page_get_widget(zathura, page); GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
g_object_set(page_widget, "search-results", NULL, NULL); g_object_set(page_widget, "draw-search-results", FALSE, NULL);
if (zathura_page_get_visibility(page) == true) { if (zathura_page_get_visibility(page) == true) {
g_object_set(page_widget, "draw-links", TRUE, NULL); g_object_set(page_widget, "draw-links", TRUE, NULL);
...@@ -71,9 +71,10 @@ sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument), ...@@ -71,9 +71,10 @@ sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument),
continue; continue;
} }
g_object_set(zathura_page_get_widget(zathura, page), "draw-links", FALSE, NULL); GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
g_object_set(page_widget, "draw-links", FALSE, NULL);
if (clear_search == true) { if (clear_search == true) {
g_object_set(zathura_page_get_widget(zathura, page), "search-results", NULL, NULL); g_object_set(page_widget, "draw-search-results", FALSE, NULL);
} }
} }
} }
...@@ -890,8 +891,23 @@ sc_search(girara_session_t* session, girara_argument_t* argument, ...@@ -890,8 +891,23 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
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);
const int num_pages = zathura_document_get_number_of_pages(zathura->document); const unsigned int num_pages = zathura_document_get_number_of_pages(zathura->document);
const int cur_page = zathura_document_get_current_page_number(zathura->document); const unsigned int cur_page = zathura_document_get_current_page_number(zathura->document);
GtkWidget *cur_page_widget = zathura_page_get_widget(zathura, zathura_document_get_page(zathura->document, cur_page));
bool nohlsearch, first_time_after_abort, draw;
nohlsearch = first_time_after_abort = draw = false;
girara_setting_get(session, "nohlsearch", &nohlsearch);
if (nohlsearch == false) {
g_object_get(cur_page_widget, "draw-search-results", &draw, NULL);
if (draw == false) {
first_time_after_abort = true;
}
document_draw_search_results(zathura, true);
}
int diff = argument->n == FORWARD ? 1 : -1; int diff = argument->n == FORWARD ? 1 : -1;
if (zathura->global.search_direction == BACKWARD) if (zathura->global.search_direction == BACKWARD)
...@@ -900,7 +916,7 @@ sc_search(girara_session_t* session, girara_argument_t* argument, ...@@ -900,7 +916,7 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
zathura_page_t* target_page = NULL; zathura_page_t* target_page = NULL;
int target_idx = 0; int target_idx = 0;
for (int page_id = 0; page_id < num_pages; ++page_id) { for (unsigned int page_id = 0; page_id < num_pages; ++page_id) {
int tmp = cur_page + diff * page_id; int tmp = cur_page + diff * page_id;
zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages); zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages);
if (page == NULL) { if (page == NULL) {
...@@ -916,6 +932,12 @@ sc_search(girara_session_t* session, girara_argument_t* argument, ...@@ -916,6 +932,12 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
continue; continue;
} }
if (first_time_after_abort == true && num_search_results > 0) {
target_page = page;
target_idx = diff == 1 ? 0 : num_search_results - 1;
break;
}
if (diff == 1 && current < num_search_results - 1) { if (diff == 1 && current < num_search_results - 1) {
/* the next result is on the same page */ /* the next result is on the same page */
target_page = page; target_page = page;
...@@ -932,7 +954,6 @@ sc_search(girara_session_t* session, girara_argument_t* argument, ...@@ -932,7 +954,6 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
for (int npage_id = 1; page_id < num_pages; ++npage_id) { for (int npage_id = 1; page_id < num_pages; ++npage_id) {
int ntmp = cur_page + diff * (page_id + npage_id); int ntmp = cur_page + diff * (page_id + npage_id);
zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages); zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages);
zathura_document_set_current_page_number(zathura->document, zathura_page_get_index(npage));
GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage); GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage);
g_object_get(npage_page_widget, "search-length", &num_search_results, NULL); g_object_get(npage_page_widget, "search-length", &num_search_results, NULL);
if (num_search_results != 0) { if (num_search_results != 0) {
...@@ -959,6 +980,10 @@ sc_search(girara_session_t* session, girara_argument_t* argument, ...@@ -959,6 +980,10 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
page_offset_t offset; page_offset_t offset;
page_calculate_offset(zathura, target_page, &offset); page_calculate_offset(zathura, target_page, &offset);
if (zathura_page_get_index(target_page) != cur_page) {
page_set(zathura, zathura_page_get_index(target_page));
}
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1; int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1;
zathura_adjustment_set_value(view_vadjustment, y); zathura_adjustment_set_value(view_vadjustment, y);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment