trayIconsManager.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // This file is part of the AppIndicator/KStatusNotifierItem GNOME Shell extension
  2. //
  3. // This program is free software; you can redistribute it and/or
  4. // modify it under the terms of the GNU General Public License
  5. // as published by the Free Software Foundation; either version 2
  6. // of the License, or (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. import Shell from 'gi://Shell';
  17. import * as Main from 'resource:///org/gnome/shell/ui/main.js';
  18. import * as Signals from 'resource:///org/gnome/shell/misc/signals.js';
  19. import * as IndicatorStatusIcon from './indicatorStatusIcon.js';
  20. import * as Util from './util.js';
  21. import * as SettingsManager from './settingsManager.js';
  22. let trayIconsManager;
  23. export class TrayIconsManager extends Signals.EventEmitter {
  24. static initialize() {
  25. if (!trayIconsManager)
  26. trayIconsManager = new TrayIconsManager();
  27. return trayIconsManager;
  28. }
  29. static destroy() {
  30. trayIconsManager.destroy();
  31. }
  32. constructor() {
  33. super();
  34. if (trayIconsManager)
  35. throw new Error('TrayIconsManager is already constructed');
  36. this._changedId = SettingsManager.getDefaultGSettings().connect(
  37. 'changed::legacy-tray-enabled', () => this._toggle());
  38. this._toggle();
  39. }
  40. _toggle() {
  41. if (SettingsManager.getDefaultGSettings().get_boolean('legacy-tray-enabled'))
  42. this._enable();
  43. else
  44. this._disable();
  45. }
  46. _enable() {
  47. if (this._tray)
  48. return;
  49. this._tray = new Shell.TrayManager();
  50. Util.connectSmart(this._tray, 'tray-icon-added', this, this.onTrayIconAdded);
  51. Util.connectSmart(this._tray, 'tray-icon-removed', this, this.onTrayIconRemoved);
  52. this._tray.manage_screen(Main.panel);
  53. }
  54. _disable() {
  55. if (!this._tray)
  56. return;
  57. IndicatorStatusIcon.getTrayIcons().forEach(i => i.destroy());
  58. if (this._tray.unmanage_screen) {
  59. this._tray.unmanage_screen();
  60. this._tray = null;
  61. } else {
  62. // FIXME: This is very ugly, but it's needed by old shell versions
  63. this._tray = null;
  64. imports.system.gc(); // force finalizing tray to unmanage screen
  65. }
  66. }
  67. onTrayIconAdded(_tray, icon) {
  68. const trayIcon = new IndicatorStatusIcon.IndicatorStatusTrayIcon(icon);
  69. IndicatorStatusIcon.addIconToPanel(trayIcon);
  70. }
  71. onTrayIconRemoved(_tray, icon) {
  72. try {
  73. const [trayIcon] = IndicatorStatusIcon.getTrayIcons().filter(i => i.icon === icon);
  74. trayIcon.destroy();
  75. } catch (e) {
  76. Util.Logger.warning(`No icon container found for ${icon.title} (${icon})`);
  77. }
  78. }
  79. destroy() {
  80. this.emit('destroy');
  81. SettingsManager.getDefaultGSettings().disconnect(this._changedId);
  82. this._disable();
  83. trayIconsManager = null;
  84. }
  85. }