From 6c0c7916d221faa740dac68b26df02082726e1fe Mon Sep 17 00:00:00 2001 From: Florian Müllner Date: Mar 06 2019 20:54:24 +0000 Subject: [PATCH 1/3] Adjust to TextureCache API change We need to include the newly-added resource-scale now. --- diff --git a/extension.js b/extension.js index e61b882..ab1ef2a 100644 --- a/extension.js +++ b/extension.js @@ -92,16 +92,21 @@ class BackgroundLogo { _updateLogoTexture() { if (this._icon) this._icon.destroy(); + this._icon = null; + + let [valid, resourceScale] = this._bin.get_resource_scale(); + if (!valid) + return; let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; - this._icon = this._textureCache.load_file_async(this._logoFile, -1, -1, scaleFactor); + this._icon = this._textureCache.load_file_async(this._logoFile, -1, -1, scaleFactor, resourceScale); this._icon.connect('allocation-changed', this._updateScale.bind(this)); this._bin.add_actor(this._icon); } _updateScale() { - if (this._icon.width == 0) + if (this._icon == null || this._icon.width == 0) return; let size = this._settings.get_double('logo-size'); From 23cb75e9bf739d6187fc87a37dcbdf2eb266b9be Mon Sep 17 00:00:00 2001 From: Florian Müllner Date: Mar 09 2019 11:16:08 +0000 Subject: [PATCH 2/3] Fix logo size The texture cache now returns an actor with an appropriate ClutterContent rather than a ClutterTexture. That actor uses the CONTENT_SIZE request mode, which means that it will unconditionally request the preferred size of the content. That is, setting an explicit size no longer has an effect, but we can scale the actor instead. --- diff --git a/extension.js b/extension.js index ab1ef2a..24e0785 100644 --- a/extension.js +++ b/extension.js @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ -const { Clutter, Gio, St } = imports.gi; +const { Clutter, Gio, GObject, St } = imports.gi; const Background = imports.ui.background; const ExtensionUtils = imports.misc.extensionUtils; @@ -22,6 +22,30 @@ const Layout = imports.ui.layout; const Main = imports.ui.main; const Tweener = imports.ui.tweener; +var IconContainer = GObject.registerClass( +class IconContainer extends St.Widget { + _init(params) { + super._init(params); + + this.connect('notify::scale-x', () => { + this.queue_relayout(); + }); + this.connect('notify::scale-y', () => { + this.queue_relayout(); + }); + } + + vfunc_get_preferred_width(forHeight) { + let width = super.vfunc_get_preferred_width(forHeight); + return width.map(w => w * this.scale_x); + } + + vfunc_get_preferred_height(forWidth) { + let height = super.vfunc_get_preferred_height(forWidth); + return height.map(h => h * this.scale_y); + } +}); + class BackgroundLogo { constructor(bgManager) { this._bgManager = bgManager; @@ -59,8 +83,10 @@ class BackgroundLogo { work_area: true }); this.actor.add_constraint(constraint); - this._bin = new St.Widget({ x_expand: true, y_expand: true }); + this._bin = new IconContainer({ x_expand: true, y_expand: true }); this.actor.add_actor(this._bin); + this._bin.connect('notify::resource-scale', + this._updateLogoTexture.bind(this)); this._settings.bind('logo-opacity', this._bin, 'opacity', Gio.SettingsBindFlags.DEFAULT); @@ -100,8 +126,8 @@ class BackgroundLogo { let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; this._icon = this._textureCache.load_file_async(this._logoFile, -1, -1, scaleFactor, resourceScale); - this._icon.connect('allocation-changed', - this._updateScale.bind(this)); + this._icon.connect('notify::content', + this._updateScale.bind(this)); this._bin.add_actor(this._icon); } @@ -109,18 +135,15 @@ class BackgroundLogo { if (this._icon == null || this._icon.width == 0) return; + let monitorIndex = this._bgManager._monitorIndex; + let { + width: monitorWidth + } = Main.layoutManager.getWorkAreaForMonitor(monitorIndex); + let size = this._settings.get_double('logo-size'); - let width = this.actor.width * size / 100; - let height = this._icon.height * width / this._icon.width; - if (Math.abs(this._icon.height - height) < 1.0 && - Math.abs(this._icon.width - width) < 1.0) { - // size of icon would not significantly change, so don't - // update the size to avoid recursion in case the - // manually set size differs just minimal from the eventually - // allocated size - return; - } - this._icon.set_size(width, height); + let width = monitorWidth * size / 100; + let scale = width / this._icon.width; + this._bin.set_scale(scale, scale); } _updatePosition() { From 4b9ced203fad5a0391bd4a36732d8cbe980c70f9 Mon Sep 17 00:00:00 2001 From: Florian Müllner Date: Mar 09 2019 11:17:12 +0000 Subject: [PATCH 3/3] Do not load unnecessarily large image The size of the logo is limited by the work area size and the maximum value of the logo-size setting. There's no reason for ever loading the texture at a larger size than that, just use that size so we don't have to adjust the scale too much later. --- diff --git a/extension.js b/extension.js index 24e0785..0f90e8e 100644 --- a/extension.js +++ b/extension.js @@ -49,6 +49,7 @@ class IconContainer extends St.Widget { class BackgroundLogo { constructor(bgManager) { this._bgManager = bgManager; + this._monitorIndex = bgManager._monitorIndex; this._logoFile = null; @@ -78,9 +79,10 @@ class BackgroundLogo { this.actor.connect('destroy', this._onDestroy.bind(this)); - let monitorIndex = bgManager._monitorIndex; - let constraint = new Layout.MonitorConstraint({ index: monitorIndex, - work_area: true }); + let constraint = new Layout.MonitorConstraint({ + index: this._monitorIndex, + work_area: true + }); this.actor.add_constraint(constraint); this._bin = new IconContainer({ x_expand: true, y_expand: true }); @@ -115,6 +117,15 @@ class BackgroundLogo { this._updateLogoTexture(); } + _getWorkArea() { + return Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex); + } + + _getWidthForRelativeSize(size) { + let { width } = this._getWorkArea(); + return width * size / 100; + } + _updateLogoTexture() { if (this._icon) this._icon.destroy(); @@ -124,8 +135,13 @@ class BackgroundLogo { if (!valid) return; + let key = this._settings.settings_schema.get_key('logo-size'); + let [, range] = key.get_range().deep_unpack(); + let [, max] = range.deep_unpack(); + let width = this._getWidthForRelativeSize(max); + let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; - this._icon = this._textureCache.load_file_async(this._logoFile, -1, -1, scaleFactor, resourceScale); + this._icon = this._textureCache.load_file_async(this._logoFile, width, -1, scaleFactor, resourceScale); this._icon.connect('notify::content', this._updateScale.bind(this)); this._bin.add_actor(this._icon); @@ -135,13 +151,8 @@ class BackgroundLogo { if (this._icon == null || this._icon.width == 0) return; - let monitorIndex = this._bgManager._monitorIndex; - let { - width: monitorWidth - } = Main.layoutManager.getWorkAreaForMonitor(monitorIndex); - let size = this._settings.get_double('logo-size'); - let width = monitorWidth * size / 100; + let width = this._getWidthForRelativeSize(size); let scale = width / this._icon.width; this._bin.set_scale(scale, scale); }