From 128697d6a775efce46e557d8e6338cb1f0ecc4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 21 Jun 2016 19:46:44 +0200 Subject: [PATCH] osdWindow: Use a constraint to enforce ratio Commit 9b07ce1d0d broke the code that keeps the OSD window square. Use that opportunity to move away from the hack of setting the min-height style property from code and adjusting the width on allocate, and implement a proper constraint instead. https://bugzilla.gnome.org/show_bug.cgi?id=768317 --- js/ui/osdWindow.js | 68 +++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/js/ui/osdWindow.js b/js/ui/osdWindow.js index 4fd0c18f2..4cb0f7b4f 100644 --- a/js/ui/osdWindow.js +++ b/js/ui/osdWindow.js @@ -45,11 +45,42 @@ const LevelBar = new Lang.Class({ } }); +const OsdWindowConstraint = new Lang.Class({ + Name: 'OsdWindowConstraint', + Extends: Clutter.Constraint, + + _init: function(props) { + this._minSize = 0; + this.parent(props); + }, + + set minSize(v) { + this._minSize = v; + if (this.actor) + this.actor.queue_relayout(); + }, + + vfunc_update_allocation: function(actor, actorBox) { + // Clutter will adjust the allocation for margins, + // so add it to our minimum size + let minSize = this._minSize + actor.margin_top + actor.margin_bottom; + let [width, height] = actorBox.get_size(); + + // Enforce a ratio of 1 + let size = Math.ceil(Math.max(minSize, height)); + actorBox.set_size(size, size); + + // Recenter + let [x, y] = actorBox.get_origin(); + actorBox.set_origin(Math.floor(x + width / 2 - size / 2), + Math.floor(y + height / 2 - size / 2)); + } +}); + const OsdWindow = new Lang.Class({ Name: 'OsdWindow', _init: function(monitorIndex) { - this._popupSize = 0; this.actor = new St.Widget({ x_expand: true, y_expand: true, x_align: Clutter.ActorAlign.CENTER, @@ -59,19 +90,12 @@ const OsdWindow = new Lang.Class({ let constraint = new Layout.MonitorConstraint({ index: monitorIndex }); this.actor.add_constraint(constraint); + this._boxConstraint = new OsdWindowConstraint(); this._box = new St.BoxLayout({ style_class: 'osd-window', vertical: true }); + this._box.add_constraint(this._boxConstraint); this.actor.add_actor(this._box); - this._box.connect('style-changed', Lang.bind(this, this._onStyleChanged)); - this._box.connect('notify::height', Lang.bind(this, - function() { - Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, - function() { - this._box.width = this._box.height; - })); - })); - this._icon = new St.Icon(); this._box.add(this._icon, { expand: true }); @@ -173,30 +197,12 @@ const OsdWindow = new Lang.Class({ let scalew = monitor.width / 640.0; let scaleh = monitor.height / 480.0; let scale = Math.min(scalew, scaleh); - this._popupSize = 110 * Math.max(1, scale); + let popupSize = 110 * Math.max(1, scale); let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; - this._icon.icon_size = this._popupSize / (2 * scaleFactor); + this._icon.icon_size = popupSize / (2 * scaleFactor); this._box.translation_y = monitor.height / 4; - this._box.style_changed(); - }, - - _onStyleChanged: function() { - let themeNode = this._box.get_theme_node(); - let horizontalPadding = themeNode.get_horizontal_padding(); - let verticalPadding = themeNode.get_vertical_padding(); - let topBorder = themeNode.get_border_width(St.Side.TOP); - let bottomBorder = themeNode.get_border_width(St.Side.BOTTOM); - let leftBorder = themeNode.get_border_width(St.Side.LEFT); - let rightBorder = themeNode.get_border_width(St.Side.RIGHT); - - let minWidth = this._popupSize - verticalPadding - leftBorder - rightBorder; - let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder; - - // minWidth/minHeight here are in real pixels, - // but the theme takes measures in unscaled dimensions - let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; - this._box.style = 'min-height: %dpx;'.format(Math.max(minWidth, minHeight) / scaleFactor); + this._boxConstraint.minSize = popupSize; } });