After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 702068 - Caret cursor moves automatically when current page changes
Caret cursor moves automatically when current page changes
Status: RESOLVED FIXED
Product: evince
Classification: Core
Component: general
2.91.x
Other Linux
: Normal normal
: ---
Assigned To: Evince Maintainers
Evince Maintainers
Depends on:
Blocks: 677348
 
 
Reported: 2013-06-12 10:13 UTC by Carlos Garcia Campos
Modified: 2013-06-13 18:41 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Keep the caret cursor page (5.66 KB, patch)
2013-06-12 16:33 UTC, Antía Puentes
needs-work Details | Review
Keep the caret cursor page (8.14 KB, patch)
2013-06-13 09:36 UTC, Antía Puentes
none Details | Review
Keep the caret cursor page (8.19 KB, patch)
2013-06-13 17:37 UTC, Antía Puentes
committed Details | Review
Don't update the page and don't scroll if the caret was not updated (5.54 KB, patch)
2013-06-13 17:53 UTC, Antía Puentes
committed Details | Review

Description Carlos Garcia Campos 2013-06-12 10:13:05 UTC
The caret cursor should only be moved when requested by the user. Currently we only save the cursor position as an offset inside a page, assuming always the current page. We should also keep the page where the caret cursor is.
Comment 1 Antía Puentes 2013-06-12 16:33:27 UTC
Created attachment 246657 [details] [review]
Keep the caret cursor page
Comment 2 Carlos Garcia Campos 2013-06-12 18:08:35 UTC
Review of attachment 246657 [details] [review]:

Since ev_view_next/previous_page can be called for other methods not related to caret, I prefer to do the caret page and offset actualizations explicit in the caret move methods. So, I would remove the calls to cursor_go_to_page_start/end from ev_view_next/previous_page. Also remove the cursor page update from cursor_go_to_page_start/end , and updated explictly in the other methods, for example, in cursor_backward_char you would do:

	if (view->cursor_offset == 0) {
                if (ev_view_previous_page (view)) {
		        view->cursor_page = ev_document_model_get_page (view->model);
	                return cursor_go_to_page_end (view);
                }
                return FALSE;
        }

and similar in cursor_forward_char

        if (view->cursor_offset >= n_attrs) {
                if (ev_view_next_page (view)) {
                        view->cursor_page = ev_document_model_get_page (view->model);
		        return cursor_go_to_page_start (view);
	        }
	        return FALSE;
	}

and the same in all other methods. It's a bit more code but it's also more explicit and easy to follow.

::: libview/ev-view.c
@@ +4674,3 @@
 		return FALSE;
 
+	ev_page_cache_get_text_log_attrs (view->page_cache, view->cursor_page, &log_attrs, &n_attrs);

Here you are using the previous cursor page when called from ev_view_previous_page.

@@ +4680,2 @@
 	view->cursor_offset = n_attrs;
+	view->cursor_page = ev_document_model_get_page (view->model);

Because it's updated here.
Comment 3 Antía Puentes 2013-06-13 09:36:35 UTC
Created attachment 246696 [details] [review]
Keep the caret cursor page

Modified patch according to the review.

I've realized another problem in the patch: ev_view_next/previous_page move to the next/previous page relative to the current_page, not the cursor_page.

I have fixed this issue by calling to ev_document_model_set_page (view->cursor_page) before moving to the next/previous page. As the code repetition was getting bigger I have refactored the next/previous page logic in two functions: cursor_go_to_next/previous_page.

Another possibility that comes to my mind, it would be to create helper functions to, given a certain page, go to the previous/next page of that certain page. In that case, ev_view_next/previous_page would call to that helper function passing view->current_page as parameter, and the caret cursor navigation functions would pass to the helper function the view->cursor_page. Let me know what you prefer.
Comment 4 Carlos Garcia Campos 2013-06-13 10:57:52 UTC
(In reply to comment #3)
> Created an attachment (id=246696) [details] [review]
> Keep the caret cursor page
> 
> Modified patch according to the review.
> 
> I've realized another problem in the patch: ev_view_next/previous_page move to
> the next/previous page relative to the current_page, not the cursor_page.
> 
> I have fixed this issue by calling to ev_document_model_set_page
> (view->cursor_page) before moving to the next/previous page. As the code
> repetition was getting bigger I have refactored the next/previous page logic in
> two functions: cursor_go_to_next/previous_page.
> 
> Another possibility that comes to my mind, it would be to create helper
> functions to, given a certain page, go to the previous/next page of that
> certain page. In that case, ev_view_next/previous_page would call to that
> helper function passing view->current_page as parameter, and the caret cursor
> navigation functions would pass to the helper function the view->cursor_page.
> Let me know what you prefer.

Yes, I think this would be a better solution. with the current patch, if the caret cursor is at the beginning of the first page, and current page is not the first page, trying to move the caret backwards would set the first page as current one even if the caret cursor hasn't been moved.
Comment 5 Antía Puentes 2013-06-13 17:37:26 UTC
Created attachment 246751 [details] [review]
Keep the caret cursor page

Same as attachment 246696 [details] [review] but rebased. The comments in comment 4 will be addressed in the next patch to ease the review.
Comment 6 Antía Puentes 2013-06-13 17:53:32 UTC
Created attachment 246761 [details] [review]
Don't update the page and don't scroll if the caret was not updated

Avoid to update the page and to scroll to the cursor position if the caret was not updated.

Notice that the helper functions to go_to_next/previous_page are not enough to fix the issue in comment 4, we need to check if the rest of the operations over the cursor were successful or not. We only checked the return value of cursor_key_press_event to update the page and scroll to the cursor position to make it visible, that value means that we have managed the event (don't want to propagate it), but doesn't say if the cursor was updated or not. 

In the patch I checked if the cursor was updated by comparing the previous and new values of the cursor offset and page, but I could very well have checked the return values of the cursor operations like cursor_backward_char. I can change it if you prefer it like that.
Comment 7 Carlos Garcia Campos 2013-06-13 18:41:13 UTC
Review of attachment 246761 [details] [review]:

I've squashed both patches, fixed some minor style issues, and pushed to git master. Thanks!

::: libview/ev-view.c
@@ +4962,3 @@
+			return TRUE;
+
+		ev_document_model_set_page (view->model, view->cursor_page);

I think we don't need this, since in case of a page change ev_document_model_set_page has already been called.