appIndicator: Free the cached pixmaps variants when not needed
We used to keep the pixmaps variants saved as cached properties of the proxy
but these are just a waste of memory usage once the icon is set, given that
we're not going to re-use them as they are in any case until the icon is
invalidated which happens only in rare cases.
So, once a pixmap is set, unset the cached property and mark it as invalid,
in this way next time an icon is requested we can refresh it if that's
required
Marco Trevisan (TreviƱo) authored 1 year, 2 months ago
Marco Trevisan committed 1 year, 2 months ago
60 | 60 | NORMAL: 0, |
61 | 61 | ATTENTION: 1, |
62 | 62 | OVERLAY: 2, |
63 | ||
64 | toPropertyName: (iconType, params = { isPixbuf: false }) => { | |
65 | let propertyName = 'Icon'; | |
66 | ||
67 | if (iconType === SNIconType.OVERLAY) | |
68 | propertyName = 'OverlayIcon'; | |
69 | else if (iconType === SNIconType.ATTENTION) | |
70 | propertyName = 'AttentionIcon'; | |
71 | ||
72 | return `${propertyName}${params.isPixbuf ? 'Pixmap' : 'Name'}`; | |
73 | }, | |
63 | 74 | }); |
64 | 75 | |
65 | 76 | var AppIndicatorProxy = GObject.registerClass({ |
460 | 471 | |
461 | 472 | this._cancellable = new Gio.Cancellable(); |
462 | 473 | this._proxy = new AppIndicatorProxy(busName, object); |
474 | this._invalidatedPixmapsIcons = new Set(); | |
463 | 475 | |
464 | 476 | this._setupProxy().catch(logError); |
465 | 477 | Util.connectSmart(this._proxy, 'g-properties-changed', this, this._onPropertiesChanged); |
604 | 616 | return { |
605 | 617 | theme: this._proxy.IconThemePath, |
606 | 618 | name: this._proxy.AttentionIconName, |
607 | pixmap: this._proxy.get_cached_property('AttentionIconPixmap'), | |
619 | pixmap: this._getPixmapProperty(SNIconType.ATTENTION), | |
608 | 620 | }; |
609 | 621 | } |
610 | 622 | |
612 | 624 | return { |
613 | 625 | theme: this._proxy.IconThemePath, |
614 | 626 | name: this._proxy.IconName, |
615 | pixmap: this._proxy.get_cached_property('IconPixmap'), | |
627 | pixmap: this._getPixmapProperty(SNIconType.NORMAL), | |
616 | 628 | }; |
617 | 629 | } |
618 | 630 | |
620 | 632 | return { |
621 | 633 | theme: this._proxy.IconThemePath, |
622 | 634 | name: this._proxy.OverlayIconName, |
623 | pixmap: this._proxy.get_cached_property('OverlayIconPixmap'), | |
635 | pixmap: this._getPixmapProperty(SNIconType.OVERLAY), | |
624 | 636 | }; |
625 | 637 | } |
626 | 638 | |
745 | 757 | this.disconnectAll(); |
746 | 758 | this._proxy.destroy(); |
747 | 759 | this._cancellable.cancel(); |
760 | this._invalidatedPixmapsIcons.clear(); | |
748 | 761 | |
749 | 762 | if (this._nameWatcher) |
750 | 763 | this._nameWatcher.destroy(); |
751 | 764 | delete this._cancellable; |
752 | 765 | delete this._proxy; |
753 | 766 | delete this._nameWatcher; |
767 | } | |
768 | ||
769 | _getPixmapProperty(iconType) { | |
770 | const propertyName = SNIconType.toPropertyName(iconType, | |
771 | { isPixbuf: true }); | |
772 | const pixmap = this._proxy.get_cached_property(propertyName); | |
773 | const wasInvalidated = this._invalidatedPixmapsIcons.delete(iconType); | |
774 | ||
775 | if (!pixmap && wasInvalidated) { | |
776 | this._proxy.refreshProperty(propertyName, { | |
777 | skipEqualityCheck: true, | |
778 | }).catch(e => { | |
779 | if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) | |
780 | logError(e); | |
781 | }); | |
782 | } | |
783 | ||
784 | return pixmap; | |
785 | } | |
786 | ||
787 | invalidatePixmapProperty(iconType) { | |
788 | this._invalidatedPixmapsIcons.add(iconType); | |
789 | this._proxy.set_cached_property( | |
790 | SNIconType.toPropertyName(iconType, { isPixbuf: true }), null); | |
754 | 791 | } |
755 | 792 | |
756 | 793 | _getActivationToken(timestamp) { |
1311 | 1348 | |
1312 | 1349 | try { |
1313 | 1350 | this._setGicon(iconType, gicon, iconSize); |
1351 | ||
1352 | if (pixmap && this.gicon) { | |
1353 | // The pixmap has been saved, we can free the variants memory | |
1354 | this._indicator.invalidatePixmapProperty(iconType); | |
1355 | } | |
1356 | ||
1314 | 1357 | return gicon; |
1315 | 1358 | } catch (e) { |
1316 | 1359 | logError(e, 'Setting GIcon failed'); |