connections.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. infos.destroy_id = destroy_id;
  51. }
  52. this.buffer.push(infos);
  53. }
  54. /// Disconnects every connection found for an actor.
  55. disconnect_all_for(actor) {
  56. // get every connection stored for the actor
  57. let actor_connections = this.buffer.filter(
  58. infos => infos.actor === actor
  59. );
  60. // remove each of them
  61. actor_connections.forEach(connection => {
  62. // disconnect
  63. try {
  64. connection.actor.disconnect(connection.id);
  65. if ('destroy_id' in connection)
  66. connection.actor.disconnect(connection.destroy_id);
  67. } catch (e) {
  68. this._warn(`error removing connection: ${e}; continuing`);
  69. }
  70. // remove from buffer
  71. let index = this.buffer.indexOf(connection);
  72. this.buffer.splice(index, 1);
  73. });
  74. }
  75. /// Disconnect every connection for each actor.
  76. disconnect_all() {
  77. this.buffer.forEach(connection => {
  78. // disconnect
  79. try {
  80. connection.actor.disconnect(connection.id);
  81. if ('destroy_id' in connection)
  82. connection.actor.disconnect(connection.destroy_id);
  83. } catch (e) {
  84. this._warn(`error removing connection: ${e}; continuing`);
  85. }
  86. });
  87. // reset buffer
  88. this.buffer = [];
  89. }
  90. _warn(str) {
  91. console.warn(`[Blur my Shell > connections] ${str}`);
  92. }
  93. };