Fix background to animate with thumbnails
When we animating the scale for the thumbnails, the border and background should wrap around the current size of the thumbails. The technique that we are using to animate the scale breaks that since we don't animate the overall size of the thumbnails box - we just animate our child actors within the allocation. To fix this, switch from drawing the background by packing in another container to drawing the background with a separate actor that is under the other actors and allocated by our custom logic. https://bugzilla.gnome.org/show_bug.cgi?id=641881
This commit is contained in:
parent
7598fd4581
commit
649ed3332f
@ -261,19 +261,19 @@ StTooltip StLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.workspace-controls {
|
.workspace-controls {
|
||||||
font-size: 32px;
|
visible-width: 32px; /* Amount visible before hovering */
|
||||||
font-weight: bold;
|
}
|
||||||
color: #ffffff;
|
|
||||||
|
.workspace-thumbnails-background {
|
||||||
border: 1px solid #424242;
|
border: 1px solid #424242;
|
||||||
border-right: 0px;
|
border-right: 0px;
|
||||||
border-radius: 9px 0px 0px 9px;
|
border-radius: 9px 0px 0px 9px;
|
||||||
background: #071524;
|
background: #071524;
|
||||||
visible-width: 32px; /* Amount visible before hovering */
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspace-thumbnails {
|
.workspace-thumbnails {
|
||||||
spacing: 7px;
|
spacing: 7px;
|
||||||
padding: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspace-thumbnail-indicator {
|
.workspace-thumbnail-indicator {
|
||||||
|
@ -370,6 +370,19 @@ ThumbnailsBox.prototype = {
|
|||||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
|
|
||||||
|
// When we animate the scale, we don't animate the requested size of the thumbnails, rather
|
||||||
|
// we ask for our final size and then animate within that size. This slightly simplifies the
|
||||||
|
// interaction with the main workspace windows (instead of constantly reallocating them
|
||||||
|
// to a new size, they get a new size once, then use the standard window animation code
|
||||||
|
// allocate the windows to their new positions), however it causes problems for drawing
|
||||||
|
// the background and border wrapped around the thumbnail as we animate - we can't just pack
|
||||||
|
// the container into a box and set style properties on the box since that box would wrap
|
||||||
|
// around the final size not the animating size. So instead we fake the background with
|
||||||
|
// an actor underneath the content and adjust the allocation of our children to leave space
|
||||||
|
// for the border and padding of the background actor.
|
||||||
|
this._background = new St.Bin({ style_class: 'workspace-thumbnails-background' });
|
||||||
|
this.actor.add_actor(this._background);
|
||||||
|
|
||||||
let indicator = new St.Bin({ style_class: 'workspace-thumbnail-indicator',
|
let indicator = new St.Bin({ style_class: 'workspace-thumbnail-indicator',
|
||||||
fixed_position_set: true });
|
fixed_position_set: true });
|
||||||
|
|
||||||
@ -596,6 +609,11 @@ ThumbnailsBox.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||||
|
// See comment about this._background in _init()
|
||||||
|
let themeNode = this._background.get_theme_node();
|
||||||
|
|
||||||
|
forWidth = themeNode.adjust_for_width(forWidth);
|
||||||
|
|
||||||
// Note that for getPreferredWidth/Height we cheat a bit and skip propagating
|
// Note that for getPreferredWidth/Height we cheat a bit and skip propagating
|
||||||
// the size request to our children because we know how big they are and know
|
// the size request to our children because we know how big they are and know
|
||||||
// that the actors aren't depending on the virtual functions being called.
|
// that the actors aren't depending on the virtual functions being called.
|
||||||
@ -607,11 +625,15 @@ ThumbnailsBox.prototype = {
|
|||||||
let nWorkspaces = global.screen.n_workspaces;
|
let nWorkspaces = global.screen.n_workspaces;
|
||||||
let totalSpacing = (nWorkspaces - 1) * spacing;
|
let totalSpacing = (nWorkspaces - 1) * spacing;
|
||||||
|
|
||||||
alloc.min_size = totalSpacing;
|
[alloc.min_size, alloc.natural_size] =
|
||||||
alloc.natural_size = totalSpacing + nWorkspaces * global.screen_height * MAX_THUMBNAIL_SCALE;
|
themeNode.adjust_preferred_height(totalSpacing,
|
||||||
|
totalSpacing + nWorkspaces * global.screen_height * MAX_THUMBNAIL_SCALE);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||||
|
// See comment about this._background in _init()
|
||||||
|
let themeNode = this._background.get_theme_node();
|
||||||
|
|
||||||
if (this._thumbnails.length == 0)
|
if (this._thumbnails.length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -627,10 +649,16 @@ ThumbnailsBox.prototype = {
|
|||||||
let scale = (avail / nWorkspaces) / global.screen_height;
|
let scale = (avail / nWorkspaces) / global.screen_height;
|
||||||
scale = Math.min(scale, MAX_THUMBNAIL_SCALE);
|
scale = Math.min(scale, MAX_THUMBNAIL_SCALE);
|
||||||
|
|
||||||
alloc.min_size = alloc.natural_size = Math.round(global.screen_width * scale);
|
let width = Math.round(global.screen_width * scale);
|
||||||
|
[alloc.min_size, alloc.natural_size] =
|
||||||
|
themeNode.adjust_preferred_width(width, width);
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
_allocate: function(actor, box, flags) {
|
||||||
|
// See comment about this._background in _init()
|
||||||
|
let themeNode = this._background.get_theme_node();
|
||||||
|
let contentBox = themeNode.get_content_box(box);
|
||||||
|
|
||||||
if (this._thumbnails.length == 0) // not visible
|
if (this._thumbnails.length == 0) // not visible
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -641,7 +669,7 @@ ThumbnailsBox.prototype = {
|
|||||||
// Compute the scale we'll need once everything is updated
|
// Compute the scale we'll need once everything is updated
|
||||||
let nWorkspaces = global.screen.n_workspaces;
|
let nWorkspaces = global.screen.n_workspaces;
|
||||||
let totalSpacing = (nWorkspaces - 1) * spacing;
|
let totalSpacing = (nWorkspaces - 1) * spacing;
|
||||||
let avail = (box.y2 - box.y1) - totalSpacing;
|
let avail = (contentBox.y2 - contentBox.y1) - totalSpacing;
|
||||||
|
|
||||||
let newScale = (avail / nWorkspaces) / screenHeight;
|
let newScale = (avail / nWorkspaces) / screenHeight;
|
||||||
newScale = Math.min(newScale, MAX_THUMBNAIL_SCALE);
|
newScale = Math.min(newScale, MAX_THUMBNAIL_SCALE);
|
||||||
@ -662,15 +690,23 @@ ThumbnailsBox.prototype = {
|
|||||||
|
|
||||||
let thumbnailHeight = screenHeight * this._scale;
|
let thumbnailHeight = screenHeight * this._scale;
|
||||||
let thumbnailWidth = Math.round(screenWidth * this._scale);
|
let thumbnailWidth = Math.round(screenWidth * this._scale);
|
||||||
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
let rightPadding = themeNode.get_padding(St.Side.RIGHT);
|
||||||
let slideWidth = thumbnailWidth + rightPadding; // Amount to slide a thumbnail off to right
|
let slideWidth = thumbnailWidth + rightPadding; // Amount to slide a thumbnail off to right
|
||||||
|
|
||||||
let childBox = new Clutter.ActorBox();
|
let childBox = new Clutter.ActorBox();
|
||||||
|
|
||||||
|
// The background is horizontally restricted to correspond to the current thumbnail size
|
||||||
|
// but otherwise covers the entire allocation
|
||||||
|
childBox.x1 = box.x1 + ((contentBox.x2 - contentBox.x1) - thumbnailWidth);
|
||||||
|
childBox.x2 = box.x2;
|
||||||
|
childBox.y1 = box.y1;
|
||||||
|
childBox.y2 = box.y2;
|
||||||
|
this._background.allocate(childBox, flags);
|
||||||
|
|
||||||
let indicatorWorkspace = this._indicatorConstrained ? global.screen.get_active_workspace() : null;
|
let indicatorWorkspace = this._indicatorConstrained ? global.screen.get_active_workspace() : null;
|
||||||
let indicatorBox;
|
let indicatorBox;
|
||||||
|
|
||||||
let y = box.y1;
|
let y = contentBox.y1;
|
||||||
|
|
||||||
for (let i = 0; i < this._thumbnails.length; i++) {
|
for (let i = 0; i < this._thumbnails.length; i++) {
|
||||||
let thumbnail = this._thumbnails[i];
|
let thumbnail = this._thumbnails[i];
|
||||||
@ -686,7 +722,7 @@ ThumbnailsBox.prototype = {
|
|||||||
let y2 = Math.round(y + thumbnailHeight);
|
let y2 = Math.round(y + thumbnailHeight);
|
||||||
let roundedScale = (y2 - y1) / screenHeight;
|
let roundedScale = (y2 - y1) / screenHeight;
|
||||||
|
|
||||||
let x1 = box.x2 - thumbnailWidth + slideWidth * thumbnail.slidePosition;
|
let x1 = contentBox.x2 - thumbnailWidth + slideWidth * thumbnail.slidePosition;
|
||||||
let x2 = x1 + thumbnailWidth;
|
let x2 = x1 + thumbnailWidth;
|
||||||
|
|
||||||
if (thumbnail.metaWorkspace == indicatorWorkspace) {
|
if (thumbnail.metaWorkspace == indicatorWorkspace) {
|
||||||
|
@ -621,7 +621,8 @@ WorkspacesDisplay.prototype = {
|
|||||||
|
|
||||||
let controls = new St.Bin({ style_class: 'workspace-controls',
|
let controls = new St.Bin({ style_class: 'workspace-controls',
|
||||||
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT,
|
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT,
|
||||||
y_align: St.Align.START });
|
y_align: St.Align.START,
|
||||||
|
y_fill: true });
|
||||||
this._controls = controls;
|
this._controls = controls;
|
||||||
this.actor.add_actor(controls);
|
this.actor.add_actor(controls);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user