Discussion:
[zathura] [Zathura PATCH v5 FINAL] More Vim-like search behavior
Marwan Tanager
2013-06-08 00:46:58 UTC
Permalink
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.

---
callbacks.c | 7 +++++++
commands.c | 28 ++++++++++++----------------
page-widget.c | 24 +++++++++++++++++++-----
shortcuts.c | 39 ++++++++++++++++++++++++++++++++-------
4 files changed, 70 insertions(+), 28 deletions(-)

diff --git a/callbacks.c b/callbacks.c
index 124837c..87e2100 100644
--- a/callbacks.c
+++ b/callbacks.c
@@ -106,6 +106,13 @@ cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpoi
}
} else {
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);
+ }
}
}

diff --git a/commands.c b/commands.c
index 38f7470..713963b 100644
--- a/commands.c
+++ b/commands.c
@@ -339,7 +339,6 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu
return false;
}

- bool firsthit = true;
zathura_error_t error = ZATHURA_ERROR_OK;

/* set search direction */
@@ -352,10 +351,6 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu
bool nohlsearch = false;
girara_setting_get(session, "nohlsearch", &nohlsearch);

- if (nohlsearch == false) {
- document_draw_search_results(zathura, true);
- }
-
/* search pages */
for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) {
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
}

g_object_set(page_widget, "search-results", result, NULL);
- if (firsthit == true) {
- if (page_id != 0) {
- page_set_delayed(zathura, zathura_page_get_index(page));
- }
- if (argument->n == BACKWARD) {
- /* start at bottom hit in page */
- 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;
+
+ if (argument->n == BACKWARD) {
+ /* start at bottom hit in page */
+ g_object_set(page_widget, "search-current", girara_list_size(result) - 1, NULL);
+ } else {
+ g_object_set(page_widget, "search-current", 0, NULL);
}
}

+ girara_argument_t* arg = g_malloc0(sizeof(girara_argument_t));
+
+ arg->n = FORWARD;
+ sc_search(session, arg, NULL, 0);
+ g_free(arg);
+
return true;
}

diff --git a/page-widget.c b/page-widget.c
index 7bcb186..0c95624 100644
--- a/page-widget.c
+++ b/page-widget.c
@@ -86,7 +86,7 @@ enum properties_e {
PROP_SEARCH_RESULTS,
PROP_SEARCH_RESULTS_LENGTH,
PROP_SEARCH_RESULTS_CURRENT,
- PROP_DRAW_SEACH_RESULTS,
+ PROP_DRAW_SEARCH_RESULTS,
PROP_LAST_VIEW,
};

@@ -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_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_object_class_install_property(object_class, PROP_DRAW_SEACH_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_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_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
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));
}
@@ -154,7 +154,7 @@ zathura_page_widget_init(ZathuraPage* widget)

priv->search.list = NULL;
priv->search.current = INT_MAX;
- priv->search.draw = true;
+ priv->search.draw = false;

priv->images.list = NULL;
priv->images.retrieved = false;
@@ -269,8 +269,19 @@ zathura_page_widget_set_property(GObject* object, guint prop_id, const GValue* v
}
break;
}
- case PROP_DRAW_SEACH_RESULTS:
+ case PROP_DRAW_SEARCH_RESULTS:
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;
default:
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,
case PROP_LAST_VIEW:
g_value_set_int64(value, priv->last_view);
break;
+ case PROP_DRAW_SEARCH_RESULTS:
+ g_value_set_boolean(value, priv->search.draw);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
diff --git a/shortcuts.c b/shortcuts.c
index 0174598..f6cd733 100644
--- a/shortcuts.c
+++ b/shortcuts.c
@@ -34,7 +34,7 @@ draw_links(zathura_t* zathura)
}

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) {
g_object_set(page_widget, "draw-links", TRUE, NULL);

@@ -71,9 +71,10 @@ sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument),
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) {
- 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,
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);

- const 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 num_pages = zathura_document_get_number_of_pages(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;
if (zathura->global.search_direction == BACKWARD)
@@ -900,7 +916,7 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
zathura_page_t* target_page = NULL;
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;
zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages);
if (page == NULL) {
@@ -916,6 +932,12 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
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) {
/* the next result is on the same page */
target_page = page;
@@ -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) {
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_document_set_current_page_number(zathura->document, zathura_page_get_index(npage));
GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage);
g_object_get(npage_page_widget, "search-length", &num_search_results, NULL);
if (num_search_results != 0) {
@@ -959,6 +980,10 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
page_offset_t 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));
int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1;
zathura_adjustment_set_value(view_vadjustment, y);
--
1.7.10.4
Loading...