Page MenuHome

UI: Show recently selected items at the top of searches.
AcceptedPublic

Authored by Jacques Lucke (JacquesLucke) on Jan 5 2022, 1:47 PM.

Details

Summary

This is a quality of live improvement. It's quite common that when something is searched for, it will be searched for again soonish. Therefore it makes sense to rank the recently selected items higher.
This also removes the behavior that the old search string remains in the search box, which is not really helpful anymore and can be annoying.

The implementation uses a global list of recent search items that is stored in the Global struct. It doesn't seem necessary to store this per search. The list of recent searches does not impact which search items will show when opening a new search, only their order.

Future improvements:

  • Store recent searches in a file like recent-files.txt so that they persist when Blender closes.
  • Have max number of recent searches or the ability to clear the recent searches.

Diff Detail

Repository
rB Blender
Branch
search-lru-cache (branched from master)
Build Status
Buildable 19827
Build 19827: arc lint + arc unit

Event Timeline

Jacques Lucke (JacquesLucke) requested review of this revision.Jan 5 2022, 1:47 PM
Jacques Lucke (JacquesLucke) created this revision.
Jacques Lucke (JacquesLucke) edited the summary of this revision. (Show Details)
  • free recent searches when blender exists
Jacques Lucke (JacquesLucke) retitled this revision from UI: Show recently selected items at the top of searches (WIP). to UI: Show recently selected items at the top of searches..Jan 5 2022, 3:45 PM
Jacques Lucke (JacquesLucke) edited the summary of this revision. (Show Details)

I mentioned this idea a long time ago, and now it’s finally implemented, thank you very much.
https://blender.community/c/rightclickselect/fjbbbc/?sorting=hot

Love this feature. I couldn't think of anything that breaks it. Seems to poll nicely depending on the editor types.

This seems really useful-- the search list is actually useful before you type now!

I'm accepting this, but I left an idea for a potential refactor in an inline comment.

source/blender/editors/interface/interface_handlers.c
1238–1252

I think it would make sense to make this a separate function like BLI_string_search_add_recent_item. (Or maybe BKE_global_add_recent_search, though I don't see any similarly named functions).

That would have three benefits:

  • Avoid making the interface_handlers code even longer
  • Allow returning early in the loop.
  • Make expanding this to save the data in a file later on simpler.
This revision is now accepted and ready to land.Jan 6 2022, 9:33 PM

Could there be a preference not to do this? Re-ordering items each execution can makes key-strokes less predictable.

The current undo tests use menu search to run actions too - which could behave in unexpectedly if the order items are shown changes at run-time.

source/blender/blenkernel/intern/blender.c
178–194 ↗(On Diff #46642)

This changes the API to make BKE_blender_globals_clear do something fairly obscure, which also begs the question why recent searches are freed here and not recent files.

I'd prefer to leave BKE_blender_globals_clear as is and free recent searches in WM_exit_ex (see free_openrecent).

We could refactor freeing recent files/searches separately since they're quite similar.

source/blender/editors/interface/interface_handlers.c
1240–1241

BLI_findstring_ptr can be used instead of an inline loop.

1241

This includes the shortcut which should probably be avoided, e.g.

View (`) ▶ Front|Numpad 1 2

(see UI_BUT_HAS_SEP_CHAR usage).

source/blender/windowmanager/intern/wm_operators.c
1713–1716

Since the static memory is no longer used for storing the value for re-use - this field could be moved into allocated memory (this can be done as a separate refactor though).

Campbell Barton (campbellbarton) requested changes to this revision.Jan 7 2022, 1:15 PM
This revision now requires changes to proceed.Jan 7 2022, 1:15 PM
  • Merge branch 'master' into search-lru-cache
  • cleanup

Could there be a preference not to do this? Re-ordering items each execution can makes key-strokes less predictable.

I'm not convinced that this should be a preference. It could be of course, but I don't see significant benefits to disabling this behavior.

The current undo tests use menu search to run actions too - which could behave in unexpectedly if the order items are shown changes at run-time.

How and why do undo tests use menu search? Feels wrong to depend on that.

source/blender/editors/interface/interface_handlers.c
1241

I think it's fine if more text is in the string, as long as it's consistent. Don't see any benefit in adding complexity to change these strings right now.

Predictability

Replying on more of a UI/UX level - would be good to get feedback from @Julian Eisel (Severin) & studio artists to see if they have a preference regarding this behavior.

Personally I find predictability important when running actions, if a series of key-strokes can be repeated to perform an action, it can be done quickly without having to double-check the action selected is the one you expected.

For example, currently selecting the camera can be done: F3, a, Return (these can be thought of as a chained key bindings).
With reusing last searches this means you can't reliably predict which item will show up.

It's possible I am not such a typical user in that I like key sequences to be predictable. Sometimes I memorize them for reuse, without having to be concerned they might arbitrarily activate something unexpected (this applies more to my development environment these days, when using Blender I took advantage of this).
This use case is disputable, there are times I think I wouldn't necessarily expect repeatable actions (online search for example).

Interested what others in the UI team think.

Automation

As for automation I think it's reasonable we keep some ability to use the search menu predictably, this is already used by undo tests and bl_run_operators_event_simulate.py.

A trivial solution is to skip storing searches when G_FLAG_EVENT_SIMULATE is set, although I'm not keen on diverging code paths for event-simulation unless it's absolutely necessary.

How and why do undo tests use menu search? Feels wrong to depend on that.

Undo tests use simulated events because reliably testing undo behavior depends on the main event loop running between actions, as well as the method of calling operators matching user interactions.

Simulating events to open menus / sub-menus is possible but would require allowing Python to inspect the locations of UI layouts which is inconvenient compared to using menu search.

If supporting automation is too much of a constraint, we could always have a separate operator/API to support automated actions.

Search Preferences

This goes outside the scope of this patch a little, noting since the topic of search preferences came up.

We could support some preferences (of course - always aim for good defaults), some behavior that could be optional:

  • Fuzzy searching (where spelling mistakes allow matches).
  • Matching initials (where AB matches Alpha Beta).
  • Store search order (this patch).

Popular command line search tool fzf has options to tweak how search is performed, I turn some of the fuzzy options off as I find they get in the way, so I don't see preferences for searching as something we should necessarily avoid.

Thanks for the more detailed feedback.

Predictability

I can't really argue against predictability in general. It's more that we probably predict different things. For example, I am quite used to this recently-used behavior in searches because I use it all the time.
It can even offer more "stable" predictability for operations that are often done, because adding new operators to the search will not break what is at the top as easily (which is even more true when we store the recent searches between Blender sessions).

I'd argue that long term, chained key bindings like F3, A, Return are not stable (actually, it seems like this specific keybinding key combination does not select the active camera for me). Matching initials is a bit more stable over time.
Maybe the solution is just to have customizable chained key bindings. E.g. the "quick favorite" system could be extended/improved to support custom keys for each item. Then you could e.g. press Q, A, Return to select the active camera.

Automation

Depending on the order of search items seems unreliable for tests, even without the behavior implemented by this patch. Adding a new completely unrelated operator could break such tests, not sure if that ever happened in practice.
So from my perspective, using another api to support automated actions is preferable. I don't have a strong opinion on that though. If we decide to disable some search features during testing, that's fine with me.

Search Preferences

I think I never customized search settings in any software I used. Technically, adding these preferences should be simple, and I expect the maintenance burden to be relatively low as well.
So my only argument against adding preference settings for the search is that we should not add options which, from my perspective, provide so little gain. Especially in light of possibly better alternatives for the cases you brought up.

I generally agree on the point about predictability, but to me this doesn't apply here.

I think. relying on chained key bindings that involve a search operation exposes a flaw in that there should be a better way to define them. A list of search results cannot be expected to be static between blender versions.
Indeed, leveraging and improving the quick favorite system for this kind of chained key bindings would be a good idea imo.

But I personally don't have anything against exposing search preferences.

I'll poke the others from the Blender Studio if they have an opinion on this to get some more feedback :)

One thing I was thinking about is the fact that recent results are stored globally. That means that the results of a search in one menu could influence the results of another menu, possibly in a completely different context. One may be showing operations, the other a list of objects. Maybe that wouldn't be a problem in practice (at least if we exactly match the selected item, as opposed to fuzzy matching, or only matching the typed in string). It may even be nice, since if names of operators match, that (hopefully) means they represent the same operation, just with different implementations (e.g. undo in 3D View vs. undo over asset catalogs, which have their own undo operators).
This is just something non-obvious to think about and test.

Predictability

I think. relying on chained key bindings that involve a search operation exposes a flaw in that there should be a better way to define them. A list of search results cannot be expected to be static between blender versions.

It's worse even, since the operator/menu search is context sensitive, items may be appear and disappear based on context. Maybe we should disable accelerator keys there entirely.

I'm wondering, @Campbell Barton (campbellbarton), are you actually doing this in practice or is this just a possible problem case you saw with this patch? Because I would expect it to be an existing problem already, although maybe it's not so bad.

I often see programs or apps where search isn't very predictable, and I hate that. So I'm definitely sensitive to the problem. Usually it's more because of too fuzzy searching, or trying to be otherwise smart.
All things considered though, I don't think we'd hurt predictability much here. I'd even argue that you improve it, since showing recently used items first is a quite predictable pattern.


One thing I think we should do is show something like a "Recently Used" hint. We could also draw a separator between recently used and regularly matched items.
Without such indicators the sorting can seem arbitrary.

Have max number of recent searches or the ability to clear the recent searches.

We should probably limit the recently used items shown to the user at least. Otherwise when using search a lot, you may end up with a long list of recently used items, before you get to the other ones, that may actually match the search criteria much more (I guess this first sorts by recently used, and then by fuzzy matching?).

Haven't tested but seems like a good idea to me. I usually search for entire words so no opinion on the "key sequence" style use case. I think it would bring a tiny bit of visual aid to pop a little extra spacing between the recent items and the alphabetical items.

This is just something non-obvious to think about and test.

Well, it's fairly obvious with a global list. I did not find a single cases where this is a problem yet. Personally, I'd rather not complicate this patch without having a concrete problem. The recent search list is only used when search item strings match exactly.

Otherwise when using search a lot, you may end up with a long list of recently used items, before you get to the other ones, that may actually match the search criteria much more (I guess this first sorts by recently used, and then by fuzzy matching?).

No. First a matching score is computed for every search item. Items with the highest matching score are always at the top. If there are multiple items with the same score, they will be sorted by other criteria (like if they have been searched for recently, or length).

One thing I think we should do is show something like a "Recently Used" hint. We could also draw a separator between recently used and regularly matched items.
Without such indicators the sorting can seem arbitrary.

Wouldn't be opposed to that, but I also don't think it's absolutely necessary or confusing without it, given what I said above.

I think it would bring a tiny bit of visual aid to pop a little extra spacing between the recent items and the alphabetical items.

Same as above. Just wanted to mention that items are not generally sorted alphabetically.

No. First a matching score is computed for every search item. Items with the highest matching score are always at the top. If there are multiple items with the same score, they will be sorted by other criteria (like if they have been searched for recently, or length).

So you can have a mixed list of recently used and non recently used? That seems odd to me and would indeed reduce predictability I think. I'd expect recently used items to always be on top, isn't that how other apps work?

So you can have a mixed list of recently used and non recently used?

No. Recently used items are always at the top when they match the current search string as good as the best other search items. If you search for something that matches a non-recently-used item better, then that other item should be at the top of course.

Can someone please explain to me the usability concerns here?

I assumed what this change does is to populate the search list only when the text input field is empty, not when the user already starts typing something into it. If that is really the case, then the usability concern does not make much sense, because the ordering would not change when you actually start typing the desired operation to search for it.

Right now, when the text field is empty, the list is populated by all the existing operators alphabetically:


I am having extremely hard time believing anyone's workflow relies on the muscle memory of orders of these few very specific operators, which are related only by their alphabetical order in this given UI element.

Or am I wrong, and will this change also reorder the items when there is something typed in the search field?

Or am I wrong, and will this change also reorder the items when there is something typed in the search field?

It also changes the order of results when something has been typed in, but only for results that match the search string equally well.

Or am I wrong, and will this change also reorder the items when there is something typed in the search field?

It also changes the order of results when something has been typed in, but only for results that match the search string equally well.

Hmm, in that case I don't see an issue. I mean the I am still having a hard time imagining someone relying on typing the exact same subsection of the string and then moving the selection exact amount of times to get reliable result. For example typing exactly "add ca" and then pressing down key exactly twice. That doesn't really sound feasible. Or rather, in that case it would make more sense to create actual keyboard shortcut for than than to rely on exact sequence of many keys in order to get to that result.

Jacques Lucke (JacquesLucke) planned changes to this revision.Jan 20 2022, 11:09 AM

Talked to @Campbell Barton (campbellbarton) in chat. I'll add a hidden operator option for the menu search.

  • Helps not potentially breaking existing tests as part of this patch. Would still be good to separate tests from menu search eventually.
  • Don't add it as a user preference setting yet, because that would need a deeper discussion about what we should have preference settings for.
  • Merge branch 'master' into search-lru-cache
  • add hidden operator option to ignore recent searches

Had to change quite a few places to pass this option down to the actual search.
Note, this doesn't change tests yet. I'm not entirely sure how the tests should be updated.
They don't seem to be broken right now anyway.

Predictability

I think. relying on chained key bindings that involve a search operation exposes a flaw in that there should be a better way to define them. A list of search results cannot be expected to be static between blender versions.

Comparing with shortcuts is not quite accurate, as you say - this changes between versions, which you couldn't expect with shortcuts.

The kinds of tasks I'm referring to are repeated tasks I'm thinking of are closer to menu accelerators.

For example, if you're adding many hooks you may memorize Ctrl+V, H, H ... this is useful to memorize if you happen to be doing a task where it's preformed more than a few times. If it changes in a future version, you'll memorize whatever new bindings that are auto assigned.

The order of accessing items doesn't change while Blender is open, so it's somewhat predictable.

It's worse even, since the operator/menu search is context sensitive, items may be appear and disappear based on context. Maybe we should disable accelerator keys there entirely.

Not sure what you mean by this, menu search will show items even whey they're greyed out (operator search isn't enabled by default, it's more for developers, I don't think these need to be considered in the design).

Within a context - edit-mesh with face select for example, the menus are predictable.
There might be some difference if you have UV's or not (potentially), but overall menu items are not showing or not between searches of similar context.

Some effort has gone into keeping menus predictable as well "Open Recent" and "Undo History" are excluded for this reason.

I'm wondering, @Campbell Barton (campbellbarton), are you actually doing this in practice or is this just a possible problem case you saw with this patch? Because I would expect it to be an existing problem already, although maybe it's not so bad.

As mentioned I don't use Blender so much anymore, these kinds of actions I use more for editing code these days, and yes - I do memorize sequences of keys to repeat actions, sometimes (although not often) binding them to keyboard macros.

I often see programs or apps where search isn't very predictable, and I hate that. So I'm definitely sensitive to the problem. Usually it's more because of too fuzzy searching, or trying to be otherwise smart.

I also run into this & think we should have an option to disable fuzzy search in Blender, but that's getting into a separate topic.

All things considered though, I don't think we'd hurt predictability much here. I'd even argue that you improve it, since showing recently used items first is a quite predictable pattern.

The predictability for literal phrases is fairly good still, the situation where it's more likely to fail is when relying on the initials of words, where using the first letter of each word, which is more likely to get a different result based on reordering.

There is a possible compromise that I don't think was mentioned, allowing predictable search + recent items.

  • Show recent items first.
  • Searching for text always gives the same output (no change to search weighting).

This means users would have to select recent items with the arrow keys / mouse.

This would be my personal preference (as a user).


One thing I think we should do is show something like a "Recently Used" hint. We could also draw a separator between recently used and regularly matched items.
Without such indicators the sorting can seem arbitrary.

+1

Have max number of recent searches or the ability to clear the recent searches.

We should probably limit the recently used items shown to the user at least. Otherwise when using search a lot, you may end up with a long list of recently used items, before you get to the other ones, that may actually match the search criteria much more (I guess this first sorts by recently used, and then by fuzzy matching?).

This revision is now accepted and ready to land.Jan 21 2022, 7:04 AM