dash_to_dock.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. import St from 'gi://St';
  2. import Shell from 'gi://Shell';
  3. import * as Main from 'resource:///org/gnome/shell/ui/main.js';
  4. const Signals = imports.signals;
  5. import { PaintSignals } from '../effects/paint_signals.js';
  6. const DASH_STYLES = [
  7. "transparent-dash",
  8. "light-dash",
  9. "dark-dash"
  10. ];
  11. /// This type of object is created for every dash found, and talks to the main
  12. /// DashBlur thanks to signals.
  13. ///
  14. /// This allows to dynamically track the created dashes for each screen.
  15. class DashInfos {
  16. constructor(dash_blur, dash, background_parent, effect, settings) {
  17. // the parent DashBlur object, to communicate
  18. this.dash_blur = dash_blur;
  19. // the blurred dash
  20. this.dash = dash;
  21. this.background_parent = background_parent;
  22. this.effect = effect;
  23. this.settings = settings;
  24. this.old_style = this.dash._background.style;
  25. dash_blur.connections.connect(dash_blur, 'remove-dashes', () => {
  26. this._log("removing blur from dash");
  27. this.dash.get_parent().remove_child(this.background_parent);
  28. this.dash._background.style = this.old_style;
  29. DASH_STYLES.forEach(
  30. style => this.dash.remove_style_class_name(style)
  31. );
  32. });
  33. dash_blur.connections.connect(dash_blur, 'update-sigma', () => {
  34. this.effect.sigma = this.dash_blur.sigma;
  35. });
  36. dash_blur.connections.connect(dash_blur, 'update-brightness', () => {
  37. this.effect.brightness = this.dash_blur.brightness;
  38. });
  39. dash_blur.connections.connect(dash_blur, 'override-background', () => {
  40. this.dash._background.style = null;
  41. DASH_STYLES.forEach(
  42. style => this.dash.remove_style_class_name(style)
  43. );
  44. this.dash.set_style_class_name(
  45. DASH_STYLES[this.settings.dash_to_dock.STYLE_DASH_TO_DOCK]
  46. );
  47. });
  48. dash_blur.connections.connect(dash_blur, 'reset-background', () => {
  49. this.dash._background.style = this.old_style;
  50. DASH_STYLES.forEach(
  51. style => this.dash.remove_style_class_name(style)
  52. );
  53. });
  54. dash_blur.connections.connect(dash_blur, 'show', () => {
  55. this.effect.sigma = this.dash_blur.sigma;
  56. });
  57. dash_blur.connections.connect(dash_blur, 'hide', () => {
  58. this.effect.sigma = 0;
  59. });
  60. }
  61. _log(str) {
  62. if (this.settings.DEBUG)
  63. console.log(`[Blur my Shell > dash] ${str}`);
  64. }
  65. }
  66. export const DashBlur = class DashBlur {
  67. constructor(connections, settings, _) {
  68. this.dashes = [];
  69. this.connections = connections;
  70. this.settings = settings;
  71. this.paint_signals = new PaintSignals(connections);
  72. this.sigma = this.settings.dash_to_dock.CUSTOMIZE
  73. ? this.settings.dash_to_dock.SIGMA
  74. : this.settings.SIGMA;
  75. this.brightness = this.settings.dash_to_dock.CUSTOMIZE
  76. ? this.settings.dash_to_dock.BRIGHTNESS
  77. : this.settings.BRIGHTNESS;
  78. this.enabled = false;
  79. }
  80. enable() {
  81. this.connections.connect(Main.uiGroup, 'actor-added', (_, actor) => {
  82. if (
  83. (actor.get_name() === "dashtodockContainer") &&
  84. (actor.constructor.name === 'DashToDock')
  85. )
  86. this.try_blur(actor);
  87. });
  88. this.blur_existing_dashes();
  89. this.connect_to_overview();
  90. this.enabled = true;
  91. }
  92. // Finds all existing dashes on every monitor, and call `try_blur` on them
  93. // We cannot only blur `Main.overview.dash`, as there could be several
  94. blur_existing_dashes() {
  95. this._log("searching for dash");
  96. // blur every dash found, filtered by name
  97. Main.uiGroup.get_children().filter((child) => {
  98. return (child.get_name() === "dashtodockContainer") &&
  99. (child.constructor.name === 'DashToDock');
  100. }).forEach(this.try_blur.bind(this));
  101. }
  102. // Tries to blur the dash contained in the given actor
  103. try_blur(dash_container) {
  104. let dash_box = dash_container._slider.get_child();
  105. // verify that we did not already blur that dash
  106. if (!dash_box.get_children().some((child) => {
  107. return child.get_name() === "dash-blurred-background-parent";
  108. })) {
  109. this._log("dash to dock found, blurring it");
  110. // finally blur the dash
  111. let dash = dash_box.get_children().find(child => {
  112. return child.get_name() === 'dash';
  113. });
  114. this.dashes.push(this.blur_dash_from(dash, dash_container));
  115. }
  116. }
  117. // Blurs the dash and returns a `DashInfos` containing its information
  118. blur_dash_from(dash, dash_container) {
  119. // the effect to be applied
  120. let effect = new Shell.BlurEffect({
  121. brightness: this.brightness,
  122. sigma: this.sigma,
  123. mode: Shell.BlurMode.BACKGROUND
  124. });
  125. // dash background parent, not visible
  126. let background_parent = new St.Widget({
  127. name: 'dash-blurred-background-parent',
  128. style_class: 'dash-blurred-background-parent',
  129. width: 0,
  130. height: 0
  131. });
  132. // dash background widget
  133. let background = new St.Widget({
  134. name: 'dash-blurred-background',
  135. style_class: 'dash-blurred-background',
  136. x: 0,
  137. y: dash_container._slider.y,
  138. width: dash.width,
  139. height: dash.height,
  140. });
  141. // updates size and position on change
  142. this.connections.connect(dash_container._slider, 'notify::y', _ => {
  143. background.y = dash_container._slider.y;
  144. });
  145. this.connections.connect(dash, 'notify::width', _ => {
  146. background.width = dash.width;
  147. });
  148. this.connections.connect(dash, 'notify::height', _ => {
  149. background.height = dash.height;
  150. });
  151. // add the widget to the dash
  152. background.add_effect(effect);
  153. background_parent.add_child(background);
  154. dash.get_parent().insert_child_at_index(background_parent, 0);
  155. // HACK
  156. //
  157. //`Shell.BlurEffect` does not repaint when shadows are under it. [1]
  158. //
  159. // This does not entirely fix this bug (shadows caused by windows
  160. // still cause artifacts), but it prevents the shadows of the panel
  161. // buttons to cause artifacts on the panel itself
  162. //
  163. // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857
  164. if (this.settings.HACKS_LEVEL === 1) {
  165. this._log("dash hack level 1");
  166. this.paint_signals.disconnect_all();
  167. let rp = () => {
  168. effect.queue_repaint();
  169. };
  170. dash._box.get_children().forEach((icon) => {
  171. try {
  172. let zone = icon.get_child_at_index(0);
  173. this.connections.connect(zone, [
  174. 'enter-event', 'leave-event', 'button-press-event'
  175. ], rp);
  176. } catch (e) {
  177. this._warn(`${e}, continuing`);
  178. }
  179. });
  180. this.connections.connect(dash._box, 'actor-added', (_, actor) => {
  181. try {
  182. let zone = actor.get_child_at_index(0);
  183. this.connections.connect(zone, [
  184. 'enter-event', 'leave-event', 'button-press-event'
  185. ], rp);
  186. } catch (e) {
  187. this._warn(`${e}, continuing`);
  188. }
  189. });
  190. let show_apps = dash._showAppsIcon;
  191. this.connections.connect(show_apps, [
  192. 'enter-event', 'leave-event', 'button-press-event'
  193. ], rp);
  194. this.connections.connect(dash, 'leave-event', rp);
  195. } else if (this.settings.HACKS_LEVEL === 2) {
  196. this._log("dash hack level 2");
  197. this.paint_signals.connect(background, effect);
  198. } else {
  199. this.paint_signals.disconnect_all();
  200. }
  201. // create infos
  202. let infos = new DashInfos(
  203. this, dash, background_parent, effect, this.settings
  204. );
  205. // update the background
  206. this.update_background();
  207. // returns infos
  208. return infos;
  209. }
  210. /// Connect when overview if opened/closed to hide/show the blur accordingly
  211. connect_to_overview() {
  212. this.connections.disconnect_all_for(Main.overview);
  213. if (this.settings.dash_to_dock.UNBLUR_IN_OVERVIEW) {
  214. this.connections.connect(
  215. Main.overview, 'showing', this.hide.bind(this)
  216. );
  217. this.connections.connect(
  218. Main.overview, 'hidden', this.show.bind(this)
  219. );
  220. }
  221. };
  222. /// Updates the background to either remove it or not, according to the
  223. /// user preferences.
  224. update_background() {
  225. if (this.settings.dash_to_dock.OVERRIDE_BACKGROUND)
  226. this.emit('override-background', true);
  227. else
  228. this.emit('reset-background', true);
  229. }
  230. set_sigma(sigma) {
  231. this.sigma = sigma;
  232. this.emit('update-sigma', true);
  233. }
  234. set_brightness(brightness) {
  235. this.brightness = brightness;
  236. this.emit('update-brightness', true);
  237. }
  238. // not implemented for dynamic blur
  239. set_color(c) { }
  240. set_noise_amount(n) { }
  241. set_noise_lightness(l) { }
  242. disable() {
  243. this._log("removing blur from dashes");
  244. this.emit('remove-dashes', true);
  245. this.dashes = [];
  246. this.connections.disconnect_all();
  247. this.enabled = false;
  248. }
  249. show() {
  250. this.emit('show', true);
  251. }
  252. hide() {
  253. this.emit('hide', true);
  254. }
  255. _log(str) {
  256. if (this.settings.DEBUG)
  257. console.log(`[Blur my Shell > dash manager] ${str}`);
  258. }
  259. _warn(str) {
  260. console.warn(`[Blur my Shell > dash manager] ${str}`);
  261. }
  262. };
  263. Signals.addSignalMethods(DashBlur.prototype);