Make sure to allocate all children in allocate vfuncs

Clutter expects actors overriding the allocate vfunc to allocate all
mapped children of the actor, otherwise bad things happen.

So make sure we actually allocate all our visible children in our custom
allocation functions, and since we don't want to give them a real
allocation, just pass them an empty ClutterActorBox.

It would be nice if we had a way to hide children during the allocation
process where no relayout is queued like gtk allows with
gtk_widget_set_child_visible(), then we could avoid those weird empty
ClutterActorBoxes.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3098

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1481>
This commit is contained in:
Jonas Dreßler 2020-10-24 20:25:49 +02:00 committed by Marge Bot
parent e8893f4fa4
commit 3fb0284358
4 changed files with 26 additions and 10 deletions

View File

@ -422,10 +422,11 @@ var GridSearchResultsLayout = GObject.registerClass({
const [childWidth] = child.get_preferred_width(-1); const [childWidth] = child.get_preferred_width(-1);
const [childHeight] = child.get_preferred_height(-1); const [childHeight] = child.get_preferred_height(-1);
childBox.set_size(childWidth, childHeight);
if (childBox.x1 + childWidth > width) if (childBox.x1 + childWidth <= width)
return; childBox.set_size(childWidth, childHeight);
else
childBox.set_size(0, 0);
child.allocate(childBox); child.allocate(childBox);

View File

@ -152,17 +152,21 @@ class UserWidgetLabel extends St.Widget {
let [, , natRealNameWidth] = this._realNameLabel.get_preferred_size(); let [, , natRealNameWidth] = this._realNameLabel.get_preferred_size();
if (natRealNameWidth <= availWidth) let childBox = new Clutter.ActorBox();
let hiddenLabel;
if (natRealNameWidth <= availWidth) {
this._currentLabel = this._realNameLabel; this._currentLabel = this._realNameLabel;
else hiddenLabel = this._userNameLabel;
} else {
this._currentLabel = this._userNameLabel; this._currentLabel = this._userNameLabel;
hiddenLabel = this._realNameLabel;
}
this.label_actor = this._currentLabel; this.label_actor = this._currentLabel;
let childBox = new Clutter.ActorBox(); hiddenLabel.allocate(childBox);
childBox.x1 = 0;
childBox.y1 = 0; childBox.set_size(availWidth, availHeight);
childBox.x2 = availWidth;
childBox.y2 = availHeight;
this._currentLabel.allocate(childBox); this._currentLabel.allocate(childBox);
} }

View File

@ -630,6 +630,14 @@ var WorkspaceLayout = GObject.registerClass({
if (windowInfo.currentTransition) { if (windowInfo.currentTransition) {
windowInfo.currentTransition.get_interval().set_final(childBox); windowInfo.currentTransition.get_interval().set_final(childBox);
// The timeline of the transition might not have been updated
// before this allocation cycle, so make sure the child
// still updates needs_allocation to FALSE.
// Unfortunately, this relies on the fast paths in
// clutter_actor_allocate(), otherwise we'd start a new
// transition on the child, replacing the current one.
child.allocate(child.allocation);
continue; continue;
} }

View File

@ -1270,6 +1270,9 @@ var ThumbnailsBox = GObject.registerClass({
let y = box.y1; let y = box.y1;
if (this._dropPlaceholderPos == -1) { if (this._dropPlaceholderPos == -1) {
this._dropPlaceholder.allocate_preferred_size(
...this._dropPlaceholder.get_position());
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._dropPlaceholder.hide(); this._dropPlaceholder.hide();
}); });