123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- import Meta from 'gi://Meta';
- import * as Main from 'resource:///org/gnome/shell/ui/main.js';
- import * as Signals from 'resource:///org/gnome/shell/misc/signals.js';
- import { PaintSignals } from '../conveniences/paint_signals.js';
- import { Pipeline } from '../conveniences/pipeline.js';
- import { DummyPipeline } from '../conveniences/dummy_pipeline.js';
- const DASH_STYLES = [
- "transparent-dash",
- "light-dash",
- "dark-dash"
- ];
- /// This type of object is created for every dash found, and talks to the main
- /// DashBlur thanks to signals.
- ///
- /// This allows to dynamically track the created dashes for each screen.
- class DashInfos {
- constructor(
- dash_blur, dash, dash_container, dash_background,
- background, background_group, bg_manager
- ) {
- // the parent DashBlur object, to communicate
- this.dash_blur = dash_blur;
- this.dash = dash;
- this.dash_container = dash_container;
- this.dash_background = dash_background;
- this.background = background;
- this.background_group = background_group;
- this.bg_manager = bg_manager;
- this.settings = dash_blur.settings;
- this.old_style = this.dash._background.style;
- this.dash_destroy_id = dash.connect('destroy', () => this.remove_dash_blur(false));
- this.dash_blur_connections_ids = [];
- this.dash_blur_connections_ids.push(
- this.dash_blur.connect('remove-dashes', () => this.remove_dash_blur()),
- this.dash_blur.connect('override-style', () => this.override_style()),
- this.dash_blur.connect('remove-style', () => this.remove_style()),
- this.dash_blur.connect('show', () => this.background_group.show()),
- this.dash_blur.connect('hide', () => this.background_group.hide()),
- this.dash_blur.connect('update-size', () => this.update_size()),
- this.dash_blur.connect('change-blur-type', () => this.change_blur_type()),
- this.dash_blur.connect('update-pipeline', () => this.update_pipeline())
- );
- }
- // IMPORTANT: do never call this in a mutable `this.dash_blur.forEach`
- remove_dash_blur(dash_not_already_destroyed = true) {
- // remove the style and destroy the effects
- this.remove_style();
- this.destroy_dash(dash_not_already_destroyed);
- // remove the dash infos from their list
- const dash_infos_index = this.dash_blur.dashes.indexOf(this);
- if (dash_infos_index >= 0)
- this.dash_blur.dashes.splice(dash_infos_index, 1);
- // disconnect everything
- this.dash_blur_connections_ids.forEach(id => { if (id) this.dash_blur.disconnect(id); });
- this.dash_blur_connections_ids = [];
- if (this.dash_destroy_id)
- this.dash.disconnect(this.dash_destroy_id);
- this.dash_destroy_id = null;
- }
- override_style() {
- this.remove_style();
- this.dash.set_style_class_name(
- DASH_STYLES[this.settings.dash_to_dock.STYLE_DASH_TO_DOCK]
- );
- }
- remove_style() {
- this.dash._background.style = this.old_style;
- DASH_STYLES.forEach(
- style => this.dash.remove_style_class_name(style)
- );
- }
- destroy_dash(dash_not_already_destroyed = true) {
- if (!dash_not_already_destroyed)
- this.bg_manager.backgroundActor = null;
- this.paint_signals?.disconnect_all();
- this.dash.get_parent().remove_child(this.background_group);
- this.bg_manager._bms_pipeline.destroy();
- this.bg_manager.destroy();
- this.background_group.destroy();
- }
- change_blur_type() {
- this.destroy_dash();
- let [
- background, background_group, bg_manager, paint_signals
- ] = this.dash_blur.add_blur(this.dash);
- this.background = background;
- this.background_group = background_group;
- this.bg_manager = bg_manager;
- this.paint_signals = paint_signals;
- this.dash.get_parent().insert_child_at_index(this.background_group, 0);
- this.update_size();
- }
- update_pipeline() {
- this.bg_manager._bms_pipeline.change_pipeline_to(
- this.settings.dash_to_dock.PIPELINE
- );
- }
- update_size() {
- if (this.dash_blur.is_static) {
- let [x, y] = this.get_dash_position(this.dash_container, this.dash_background);
- this.background.x = -x;
- this.background.y = -y;
- if (this.dash_container.get_style_class_name().includes("top"))
- this.background.set_clip(
- x,
- y + this.dash.y + this.dash_background.y,
- this.dash_background.width,
- this.dash_background.height
- );
- else if (this.dash_container.get_style_class_name().includes("bottom"))
- this.background.set_clip(
- x,
- y + this.dash.y + this.dash_background.y,
- this.dash_background.width,
- this.dash_background.height
- );
- else if (this.dash_container.get_style_class_name().includes("left"))
- this.background.set_clip(
- x + this.dash.x + this.dash_background.x,
- y + this.dash.y + this.dash_background.y,
- this.dash_background.width,
- this.dash_background.height
- );
- else if (this.dash_container.get_style_class_name().includes("right"))
- this.background.set_clip(
- x + this.dash.x + this.dash_background.x,
- y + this.dash.y + this.dash_background.y,
- this.dash_background.width,
- this.dash_background.height
- );
- } else {
- this.background.width = this.dash_background.width;
- this.background.height = this.dash_background.height;
- this.background.x = this.dash_background.x;
- this.background.y = this.dash_background.y + this.dash.y;
- }
- }
- get_dash_position(dash_container, dash_background) {
- var x, y;
- let monitor = Main.layoutManager.findMonitorForActor(dash_container);
- let dash_box = dash_container._slider.get_child();
- if (dash_container.get_style_class_name().includes("top")) {
- x = (monitor.width - dash_background.width) / 2;
- y = dash_box.y;
- } else if (dash_container.get_style_class_name().includes("bottom")) {
- x = (monitor.width - dash_background.width) / 2;
- y = monitor.height - dash_container.height;
- } else if (dash_container.get_style_class_name().includes("left")) {
- x = dash_box.x;
- y = dash_container.y + (dash_container.height - dash_background.height) / 2 - dash_background.y;
- } else if (dash_container.get_style_class_name().includes("right")) {
- x = monitor.width - dash_container.width;
- y = dash_container.y + (dash_container.height - dash_background.height) / 2 - dash_background.y;
- }
- return [x, y];
- }
- _log(str) {
- if (this.settings.DEBUG)
- console.log(`[Blur my Shell > dash] ${str}`);
- }
- _warn(str) {
- console.warn(`[Blur my Shell > dash] ${str}`);
- }
- }
- export const DashBlur = class DashBlur extends Signals.EventEmitter {
- constructor(connections, settings, _) {
- super();
- this.dashes = [];
- this.connections = connections;
- this.settings = settings;
- this.paint_signals = new PaintSignals(connections);
- this.is_static = this.settings.dash_to_dock.STATIC_BLUR;
- this.enabled = false;
- }
- enable() {
- this.connections.connect(Main.uiGroup, 'child-added', (_, actor) => {
- if (
- (actor.get_name() === "dashtodockContainer") &&
- (actor.constructor.name === 'DashToDock')
- )
- this.try_blur(actor);
- });
- this.blur_existing_dashes();
- this.connect_to_overview();
- this.update_size();
- this.enabled = true;
- }
- // Finds all existing dashes on every monitor, and call `try_blur` on them
- // We cannot only blur `Main.overview.dash`, as there could be several
- blur_existing_dashes() {
- this._log("searching for dash");
- // blur every dash found, filtered by name
- Main.uiGroup.get_children().filter((child) => {
- return (child.get_name() === "dashtodockContainer") &&
- (child.constructor.name === 'DashToDock');
- }).forEach(dash_container => this.try_blur(dash_container));
- }
- // Tries to blur the dash contained in the given actor
- try_blur(dash_container) {
- let dash_box = dash_container._slider.get_child();
- // verify that we did not already blur that dash
- if (!dash_box.get_children().some(child =>
- child.get_name() === "bms-dash-backgroundgroup"
- )) {
- this._log("dash to dock found, blurring it");
- // finally blur the dash
- let dash = dash_box.get_children().find(child => {
- return child.get_name() === 'dash';
- });
- this.dashes.push(this.blur_dash_from(dash, dash_container));
- }
- }
- // Blurs the dash and returns a `DashInfos` containing its information
- blur_dash_from(dash, dash_container) {
- let [background, background_group, bg_manager, paint_signals] = this.add_blur(dash);
- // insert the background group to the right element
- dash.get_parent().insert_child_at_index(background_group, 0);
- // updates size and position on change
- this.connections.connect(
- dash,
- ['notify::width', 'notify::height'],
- _ => this.update_size()
- );
- this.connections.connect(
- dash_container,
- ['notify::width', 'notify::height', 'notify::y', 'notify::x'],
- _ => this.update_size()
- );
- const dash_background = dash.get_children().find(child => {
- return child.get_style_class_name() === 'dash-background';
- });
- // create infos
- let infos = new DashInfos(
- this,
- dash,
- dash_container,
- dash_background,
- background,
- background_group,
- bg_manager,
- paint_signals
- );
- this.update_size();
- this.update_background();
- // returns infos
- return infos;
- }
- add_blur(dash) {
- const monitor = Main.layoutManager.findMonitorForActor(dash);
- if (!monitor)
- return;
- const background_group = new Meta.BackgroundGroup({
- name: 'bms-dash-backgroundgroup', width: 0, height: 0
- });
- let background, bg_manager, paint_signals;
- let static_blur = this.settings.dash_to_dock.STATIC_BLUR;
- if (static_blur) {
- let bg_manager_list = [];
- const pipeline = new Pipeline(
- global.blur_my_shell._effects_manager,
- global.blur_my_shell._pipelines_manager,
- this.settings.dash_to_dock.PIPELINE
- );
- background = pipeline.create_background_with_effects(
- monitor.index, bg_manager_list,
- background_group, 'bms-dash-blurred-widget'
- );
- bg_manager = bg_manager_list[0];
- }
- else {
- const pipeline = new DummyPipeline(
- global.blur_my_shell._effects_manager,
- this.settings.dash_to_dock
- );
- [background, bg_manager] = pipeline.create_background_with_effect(
- background_group, 'bms-dash-blurred-widget'
- );
- paint_signals = new PaintSignals(this.connections);
- // HACK
- //
- //`Shell.BlurEffect` does not repaint when shadows are under it. [1]
- //
- // This does not entirely fix this bug (shadows caused by windows
- // still cause artifacts), but it prevents the shadows of the dash
- // buttons to cause artifacts on the dash itself
- //
- // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857
- if (this.settings.HACKS_LEVEL === 1) {
- this._log("hack level 1");
- paint_signals.disconnect_all();
- paint_signals.connect(background, pipeline.effect);
- } else {
- paint_signals.disconnect_all();
- }
- }
- return [background, background_group, bg_manager, paint_signals];
- }
- change_blur_type() {
- this.is_static = this.settings.dash_to_dock.STATIC_BLUR;
- this.emit('change-blur-type');
- this.update_background();
- }
- /// Connect when overview if opened/closed to hide/show the blur accordingly
- connect_to_overview() {
- this.connections.disconnect_all_for(Main.overview);
- if (this.settings.dash_to_dock.UNBLUR_IN_OVERVIEW) {
- this.connections.connect(
- Main.overview, 'showing', _ => this.hide()
- );
- this.connections.connect(
- Main.overview, 'hidden', _ => this.show()
- );
- }
- };
- /// Updates the background to either remove it or not, according to the
- /// user preferences.
- update_background() {
- this._log("updating background");
- if (this.settings.dash_to_dock.OVERRIDE_BACKGROUND)
- this.emit('override-style');
- else
- this.emit('remove-style');
- }
- update_pipeline() {
- this.emit('update-pipeline');
- }
- update_size() {
- this.emit('update-size');
- }
- show() {
- this.emit('show');
- }
- hide() {
- this.emit('hide');
- }
- disable() {
- this._log("removing blur from dashes");
- this.emit('remove-dashes');
- this.dashes = [];
- this.connections.disconnect_all();
- this.enabled = false;
- }
- _log(str) {
- if (this.settings.DEBUG)
- console.log(`[Blur my Shell > dash manager] ${str}`);
- }
- _warn(str) {
- console.warn(`[Blur my Shell > dash manager] ${str}`);
- }
- };
|