connections.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import GObject from 'gi://GObject';
  2. /// An object to easily manage signals.
  3. export const Connections = class Connections {
  4. constructor() {
  5. this.buffer = [];
  6. }
  7. /// Adds a connection.
  8. ///
  9. /// Takes as arguments:
  10. /// - an actor, which fires the signal
  11. /// - signal(s) (string or array of strings), which are watched for
  12. /// - a callback, which is called when the signal is fired
  13. connect(actor, signals, handler) {
  14. if (signals instanceof Array) {
  15. signals.forEach(signal => {
  16. let id = actor.connect(signal, handler);
  17. this.process_connection(actor, id);
  18. });
  19. } else {
  20. let id = actor.connect(signals, handler);
  21. this.process_connection(actor, id);
  22. }
  23. }
  24. /// Process the given actor and id.
  25. ///
  26. /// This makes sure that the signal is disconnected when the actor is
  27. /// destroyed, and that the signal can be managed through other Connections
  28. /// methods.
  29. process_connection(actor, id) {
  30. let infos = {
  31. actor: actor,
  32. id: id
  33. };
  34. // remove the signal when the actor is destroyed
  35. if (
  36. actor.connect &&
  37. (
  38. !(actor instanceof GObject.Object) ||
  39. GObject.signal_lookup('destroy', actor)
  40. )
  41. ) {
  42. let destroy_id = actor.connect('destroy', () => {
  43. actor.disconnect(id);
  44. actor.disconnect(destroy_id);
  45. let index = this.buffer.indexOf(infos);
  46. if (index >= 0) {
  47. this.buffer.splice(index, 1);
  48. }
  49. });
  50. }
  51. this.buffer.push(infos);
  52. }
  53. /// Disconnects every connection found for an actor.
  54. disconnect_all_for(actor) {
  55. // get every connection stored for the actor
  56. let actor_connections = this.buffer.filter(
  57. infos => infos.actor === actor
  58. );
  59. // remove each of them
  60. actor_connections.forEach((connection) => {
  61. // disconnect
  62. try {
  63. connection.actor.disconnect(connection.id);
  64. } catch (e) {
  65. this._warn(`error removing connection: ${e}; continuing`);
  66. }
  67. // remove from buffer
  68. let index = this.buffer.indexOf(connection);
  69. this.buffer.splice(index, 1);
  70. });
  71. }
  72. /// Disconnect every connection for each actor.
  73. disconnect_all() {
  74. this.buffer.forEach((connection) => {
  75. // disconnect
  76. try {
  77. connection.actor.disconnect(connection.id);
  78. } catch (e) {
  79. this._warn(`error removing connection: ${e}; continuing`);
  80. }
  81. });
  82. // reset buffer
  83. this.buffer = [];
  84. }
  85. _warn(str) {
  86. console.warn(`[Blur my Shell > connections] ${str}`);
  87. }
  88. };