From 477e87ac1a1a99cd4d7a9ee7bb789975e9fc1fbf Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 28 Sep 2020 22:28:08 -0400
Subject: [PATCH 10/13] userWidget: Disconnect signal connections on destroy
At the moment an Avatar (and StIcon) are getting leaked
every time the screen is locked.
This is because the Avatar class sets up a global signal
connection that prevents the object from getting garbage
collected when its actor is destroyed.
This commit adds a destroy handler to disconnect the
signal connection.
---
js/ui/userWidget.js | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/js/ui/userWidget.js b/js/ui/userWidget.js
index 4e1ce25e9..0a80fa672 100644
--- a/js/ui/userWidget.js
+++ b/js/ui/userWidget.js
@@ -9,63 +9,73 @@ const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const St = imports.gi.St;
const Params = imports.misc.params;
var AVATAR_ICON_SIZE = 64;
// Adapted from gdm/gui/user-switch-applet/applet.c
//
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
// Copyright (C) 2008,2009 Red Hat, Inc.
var Avatar = new Lang.Class({
Name: 'Avatar',
_init(user, params) {
this._user = user;
params = Params.parse(params, { reactive: false,
iconSize: AVATAR_ICON_SIZE,
styleClass: 'framed-user-icon' });
this._iconSize = params.iconSize;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this.actor = new St.Bin({ style_class: params.styleClass,
track_hover: params.reactive,
reactive: params.reactive,
width: this._iconSize * scaleFactor,
height: this._iconSize * scaleFactor });
+ this.actor.connect('destroy', this._onDestroy.bind(this));
+
// Monitor the scaling factor to make sure we recreate the avatar when needed.
let themeContext = St.ThemeContext.get_for_stage(global.stage);
- themeContext.connect('notify::scale-factor', this.update.bind(this));
+ this._scaleFactorChangedId = themeContext.connect('notify::scale-factor', this.update.bind(this));
+ },
+
+ _onDestroy() {
+ if (this._scaleFactorChangedId != 0) {
+ let themeContext = St.ThemeContext.get_for_stage(global.stage);
+ themeContext.disconnect(this._scaleFactorChangedId);
+ this._scaleFactorChangedId = 0;
+ }
},
setSensitive(sensitive) {
this.actor.can_focus = sensitive;
this.actor.reactive = sensitive;
},
update() {
let iconFile = this._user.get_icon_file();
if (iconFile && !GLib.file_test(iconFile, GLib.FileTest.EXISTS))
iconFile = null;
if (iconFile) {
let file = Gio.File.new_for_path(iconFile);
this.actor.child = null;
this.actor.style = 'background-image: url("%s");'.format(iconFile);
} else {
this.actor.style = null;
this.actor.child = new St.Icon({ icon_name: 'avatar-default-symbolic',
icon_size: this._iconSize });
}
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this.actor.set_size(this._iconSize * scaleFactor, this._iconSize * scaleFactor);
}
});
var UserWidgetLabel = new Lang.Class({
Name: 'UserWidgetLabel',
Extends: St.Widget,
--
2.25.1