extension.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. Copyright (c) 2017 Fabius <fabio@mereu.info>
  3. Released under the MIT license
  4. Window Corner Preview Gnome Extension
  5. Purpose: It adds a menu to the GNOME main panel from which you can turn the
  6. preview of any desktop window on.
  7. It can help you watch a movie or a video while studying or working.
  8. This is a fork of https://github.com/Exsul/float-youtube-for-gnome
  9. by "Enelar" Kirill Berezin which was originally forked itself
  10. from https://github.com/Shou/float-mpv by "Shou" Benedict Aas.
  11. Contributors:
  12. Scott Ames https://github.com/scottames
  13. Jan Tojnar https://github.com/jtojnar
  14. */
  15. "use strict";
  16. // Global modules
  17. const Lang = imports.lang;
  18. const Main = imports.ui.main;
  19. const Mainloop = imports.mainloop;
  20. // Internal modules
  21. const ExtensionUtils = imports.misc.extensionUtils;
  22. const Me = ExtensionUtils.getCurrentExtension();
  23. const Preview = Me.imports.preview;
  24. const Indicator = Me.imports.indicator;
  25. const Settings = Me.imports.settings;
  26. const Signaling = Me.imports.signaling;
  27. const Bundle = Me.imports.bundle;
  28. const Polygnome = Me.imports.polygnome;
  29. const WindowCornerPreview = Preview.WindowCornerPreview;
  30. const WindowCornerIndicator = Indicator.WindowCornerIndicator;
  31. const WindowCornerSettings = Settings.WindowCornerSettings;
  32. const SignalConnector = Signaling.SignalConnector;
  33. const getWindowSignature = Bundle.getWindowSignature;
  34. const getWindowHash = Bundle.getWindowHash;
  35. const getMetawindows = Polygnome.getMetawindows;
  36. const getWorkspaceWindowsArray = Polygnome.getWorkspaceWindowsArray;
  37. const getWorkspaces = Polygnome.getWorkspaces;
  38. function onZoomChanged() {
  39. settings.initialZoom = this.zoom;
  40. }
  41. function onCropChanged() {
  42. settings.initialLeftCrop = this.leftCrop;
  43. settings.initialRightCrop = this.rightCrop;
  44. settings.initialTopCrop = this.topCrop;
  45. settings.initialBottomCrop = this.bottomCrop;
  46. }
  47. function onCornerChanged() {
  48. settings.initialCorner = this.corner;
  49. }
  50. function onWindowChanged(preview, window) {
  51. settings.lastWindowHash = getWindowHash(preview.visible && window);
  52. }
  53. function onSettingsChanged(settings, property) {
  54. if (["focusHidden"].indexOf(property) > -1) {
  55. // this = preview
  56. this[property] = settings[property];
  57. }
  58. }
  59. function previewLastWindow(preview) {
  60. const lastWindowHash = settings.lastWindowHash;
  61. if (! lastWindowHash) return;
  62. const signals = new SignalConnector();
  63. let done, timer;
  64. function shouldBePreviewed(anyWindow) {
  65. if (!done && lastWindowHash === getWindowHash(anyWindow)) {
  66. done = true;
  67. signals.disconnectAll();
  68. if (timer) {
  69. Mainloop.source_remove(timer);
  70. timer = null;
  71. }
  72. // I don't know exactly the reason, but some windows
  73. // do not get shown properly without putting this on async
  74. // The thumbnail seems not to be ready yet
  75. Mainloop.timeout_add(100, function () {
  76. preview.window = anyWindow;
  77. preview.show();
  78. });
  79. }
  80. }
  81. // If the Extension is firstly activated the window list is empty [] and will
  82. // be filled in shortly, instead if it's enabled later (like via Tweak tool)
  83. // the array is already filled
  84. const windows = getMetawindows();
  85. if (windows.length) {
  86. windows.forEach(function (window) {
  87. shouldBePreviewed(window);
  88. });
  89. }
  90. else {
  91. getWorkspaces().forEach(function (workspace) {
  92. signals.tryConnectAfter(workspace, "window-added", function (workspace, window) {
  93. shouldBePreviewed(window);
  94. });
  95. });
  96. const TIMEOUT = 10000;
  97. timer = Mainloop.timeout_add(TIMEOUT, function () {
  98. // In case the last window previewed could not be found, stop listening
  99. done = true;
  100. signals.disconnectAll();
  101. });
  102. }
  103. }
  104. let preview, menu;
  105. let settings, signals;
  106. function init() {
  107. settings = new WindowCornerSettings();
  108. signals = new SignalConnector();
  109. }
  110. function enable() {
  111. preview = new WindowCornerPreview();
  112. signals.tryConnect(settings, "changed", Lang.bind(preview, onSettingsChanged));
  113. signals.tryConnect(preview, "zoom-changed", Lang.bind(preview, onZoomChanged));
  114. signals.tryConnect(preview, "crop-changed", Lang.bind(preview, onCropChanged));
  115. signals.tryConnect(preview, "corner-changed", Lang.bind(preview, onCornerChanged));
  116. signals.tryConnect(preview, "window-changed", Lang.bind(preview, onWindowChanged));
  117. // Initialize props
  118. preview.zoom = settings.initialZoom;
  119. preview.leftCrop = settings.initialLeftCrop;
  120. preview.rightCrop = settings.initialRightCrop;
  121. preview.topCrop = settings.initialTopCrop;
  122. preview.bottomCrop = settings.initialBottomCrop;
  123. preview.focusHidden = settings.focusHidden;
  124. preview.corner = settings.initialCorner;
  125. menu = new WindowCornerIndicator();
  126. menu.preview = preview;
  127. menu.enable();
  128. Main.panel.addToStatusArea("WindowCornerIndicator", menu);
  129. // The last window being previewed is reactivate
  130. previewLastWindow(preview);
  131. }
  132. function disable() {
  133. signals.disconnectAll();
  134. // Save the last window on (or off)
  135. onWindowChanged.call(null, preview, preview.window);
  136. preview.passAway();
  137. menu.disable();
  138. menu.destroy();
  139. preview = null;
  140. menu = null;
  141. }