search: Fix calculation of max number of displayed results for grid

The calculation of how many results can be shown in GridSearchResults is
broken: The width of the parent container (resultsView.actor) we're
using as the maximum width right now is the width of the scrollView of
SearchResults (which always expands to the whole screen size). This
width will only be correct if the scrollView (ie. the whole screen) is
smaller than the max width of searchResultsContent, which only is the
case for screens smaller than 1000px.

To fix the calculation, use the width of our own actor and don't get it
using clutter_actor_get_width(), but using the last allocation of the
actor. This way we don't get the preferred width if the actor is not
allocated at this point (it's hidden by _ensureProviderDisplay() when
starting a new search).

Then, when the allocation of the actor changes, rebuild the grid search
results by calling updateSearch() with the old arguments to ensure the
number of visible results is correct. The fact that we're only listening
for allocation changes here is the reason why we never want to use the
preferred width of the actor inside _getMaxDisplayedResults(): While
the actor is hidden clutter_actor_get_width() would return the preferred
width, which we'd then use the as the maximum width. But if the actor
had a correct allocation before, no notify::allocation signal will be
emitted when the actor is shown again because the allocation is still
the same, and we'll end up using the preferred width as maximium width
forever.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/110
This commit is contained in:
Jonas Dreßler 2018-11-25 00:57:00 +01:00 committed by Florian Müllner
parent 3f2cffc2e6
commit 1a27ff6130

View File

@ -329,12 +329,6 @@ Signals.addSignalMethods(ListSearchResults.prototype);
var GridSearchResults = class extends SearchResultsBase {
constructor(provider, resultsView) {
super(provider, resultsView);
// We need to use the parent container to know how much results we can show.
// None of the actors in this class can be used for that, since the main actor
// goes hidden when no results are displayed, and then it lost its allocation.
// Then on the next use of _getMaxDisplayedResults allocation is 0, en therefore
// it doesn't show any result although we have some.
this._parentContainer = resultsView.actor;
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
xAlign: St.Align.START });
@ -345,10 +339,23 @@ var GridSearchResults = class extends SearchResultsBase {
this._resultDisplayBin.set_child(this._bin);
}
updateSearch(...args) {
if (this._notifyAllocationId)
this.actor.disconnect(this._notifyAllocationId);
// Make sure the maximum number of results calculated by
// _getMaxDisplayedResults() is updated after width changes.
this._notifyAllocationId = this.actor.connect('notify::allocation', () => {
super.updateSearch(...args);
});
super.updateSearch(...args);
}
_getMaxDisplayedResults() {
let parentThemeNode = this._parentContainer.get_theme_node();
let availableWidth = parentThemeNode.adjust_for_width(this._parentContainer.width);
return this._grid.columnsForWidth(availableWidth) * this._grid.getRowLimit();
let allocation = this.actor.allocation;
let nCols = this._grid.columnsForWidth(allocation.x2 - allocation.x1);
return nCols * this._grid.getRowLimit();
}
_clearResultDisplay() {