cvfosammmm / Setzer

LaTeX editor written in Python with Gtk
https://www.cvfosammmm.org/setzer/
Other
393 stars 36 forks source link

When calling the search bar (Ctrl+F), the existing search query's text should be all selected #273

Closed nekohayo closed 2 years ago

nekohayo commented 2 years ago

I very frequently hit Ctrl+F when I want to bring up / focus the search bar to make a new search, after having dismissed it with Esc. Currently, Setzer preserves the previous search query text but only focuses the search entry, putting the text cursor at the end. The result is that I end up typing (or pasting) what I want to search and it fails everytime because it's actually appended to whatever the previous search was.

Instead, the previous search's text should be all selected, so that anything I type or paste replaces the search query. If I wanted to append, I would use the right arrow key before typing.

The "pre-select-all" behavior would be consistent with other applications such as Firefox (including its PDF reader), Chromium, LibreOffice, etc.

The alternative is not keeping at all the previous search query when re-calling a previously dismissed searchbar, which is what applications such as Evince, Nautilus, Epiphany do. But I would still expect Ctrl+F on a non-dismissed searchbar to not only focus it, but select all.

cvfosammmm commented 2 years ago

Actually, Setzer doesn't keep the previous query. It adds selected text to the search entry, just like gedit does. Difference is on Esc Setzer keeps the text selected. I want to keep it that way, as I find it more consistent. LibreOffice does the same thing.

Pre-selecting removes the selection from the text editor, and I don't want that. I think Gtk does that somehow.

nekohayo commented 2 years ago

Indeed there is an important distinction in Gedit, where if you type something in the search entry and press Esc, (which is a pretty deliberate action, you can't confuse Esc with Enter...) it deselects the text and the next time you use it, the search entry is blank. Setzer doesn't do that, and it annoys me, but not as much as the other part of the problem.

Yes, if you already have preselected text the Setzer search entry will be prefilled with it (as Gedit and LibreOffice do), but in those other apps that pre-fill will be all selected in the search entry, so that you can replace it. 99% of the time I want to replace my query to search for something different; otherwise, if my search-as-you-type query was incomplete, I would have just completed typing it the first time around before hitting Esc or Enter; and if I somehow wanted to append upon calling back the search entry after having dismissed it with Esc (which again is rare, because if that was the case I would not have dismissed the searchbar in the first place), I would use the "right arrow" key to deselect and move the cursor to the end of the string.

Selecting all the contents of the searchbar when calling the searchbar back from the dead (and pressing "right arrow" once if you want to append instead) is the standard behavior of every major app I've been using elsewhere. Gedit, GNOME Builder, LibreOffice Writer/Calc/Impress, Firefox, Thunderbird behave like that for example.

cvfosammmm commented 2 years ago

GEdit behaves like Setzer. As I said above, Gtk seems to remove the selection from the editor once I select text in the search bar, and I don't want that.

nekohayo commented 2 years ago

Not exactly. Here's the behavior in Gedit with multiple matches:

Hope that helps clear up the subtlety I'm referring to :)

cvfosammmm commented 2 years ago

GEdit behaves like Setzer at first: highlight text -> Ctrl+F -> text in entry is not selected. After that it's different. But I think the behaviour of Setzer is more predictable.

That said, I agree with you that it would better if the text in the entry would be pre-selected, while everything else stayed the same. But that doesn't seem to be possible with Gtk.

nekohayo commented 6 months ago

I agree with you that it would better if the text in the entry would be pre-selected, while everything else stayed the same. But that doesn't seem to be possible with Gtk.

I'd like to reopen this ticket for consideration. I think it's still quite possible technically, even with GTK4 and libadwaita; Epiphany's "find in page" searchbar, as well as Nautilus' "search in folder" (not yet its "Search everywhere" second search field) feature, manages to accomplish this.

I had a look at your code and tried fixing it myself, but I ran into issues caused by other parts of the code, if the objective is to preserve your "Enter key goes to the next result while keeping the searchbar focused" wish.

Here's what I tried so far, which made it work for my usecase, but it's just missing your insights to make it work for yours at the same time...

In document/search/search.py, in your search_entry_grab_focus method, instead of this complicated thing:

    def search_entry_grab_focus(self, args=None):
        entry = self.view.entry

        selection = self.document.get_selected_text()
        if selection != None:
            entry.set_text(selection)

        entry.grab_focus()
        entry.set_position(len(entry.get_text()))

        if selection == None:
            entry.select_region(0, len(entry.get_text()))
            self.on_search_entry_changed(entry)

...I simplified it into this:

    def search_entry_grab_focus(self, args=None):
        entry = self.view.entry

        selection = self.document.get_selected_text()
        if selection != None:
            entry.set_text(selection)

        entry.grab_focus()
        entry.select_region(0, -1)

Notice I nuked the whole last part which didn't seem to make sense to me in that method. At that point, it was already starting to work better.

But then, for some reason, something else was still interfering with selection and focus; it turned out to be on_search_entry_activate and on_search_next_match interfering. Here again, I don't see why you would steal focus away from the searchbar on activate (i.e. pressing the Enter key), that seems entirely against your own goals, no?

So this code:

    def on_search_entry_activate(self, entry=None):
        self.on_search_next_match(entry, True)
        self.document_view.source_view.grab_focus()

Becomes:

    def on_search_entry_activate(self, entry=None):
        self.on_search_next_match(entry, True)

At that point, it was working as intended for my usecase, but I wanted to try to address your usecase as well and fix the behavior of the Enter key (which was already broken in current versions anyway).

Now, where I got stuck was your on_search_next_match method, where you're trying to handle the various usecases, and I didn't feel quite comfortable in my understanding to figure out a solution there. But I suspect you would be able to find the better solution there :)

Alternatively, I thought that maybe your search_entry_grab_focus method could have some checks and special casing to handle this, but I'm not sure it's the right place to be adding complexity.

Note/remember: as far as I can tell, my tentative changes shown above do not really break the Enter behavior more than it already was (in fact, they made it partially work!). In vanilla version 65 for example, if you Ctrl+F, type some word and then hit Enter, it focuses the document without even going to the next match, and then if you hit Enter again then you mess up the document's contents.

I hope this pre-investigation helps!