Oreon-Lime-R2/blur-my-shell/blur-my-shell-29/panel.js

245 lines
8.8 KiB
JavaScript

'use strict';
const { St, Shell, Meta, Gio, GLib } = imports.gi;
const Main = imports.ui.main;
const Config = imports.misc.config;
const backgroundSettings = new Gio.Settings({ schema: 'org.gnome.desktop.background' })
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Settings = Me.imports.settings;
const Utils = Me.imports.utilities;
const PaintSignals = Me.imports.paint_signals;
const [GS_MAJOR, GS_MINOR] = Config.PACKAGE_VERSION.split('.');
var PanelBlur = class PanelBlur {
constructor(connections, prefs) {
this.connections = connections;
this.paint_signals = new PaintSignals.PaintSignals(connections);
this.prefs = prefs;
this.effect = new Shell.BlurEffect({
brightness: prefs.BRIGHTNESS.get(),
sigma: prefs.SIGMA.get(),
mode: prefs.STATIC_BLUR.get() ? 0 : 1
});
this.background_parent = new St.Widget({
name: 'topbar-blurred-background-parent',
style_class: 'topbar-blurred-background-parent',
x: this.monitor.x,
y: this.monitor.y,
width: this.monitor.width,
height: 0,
});
this.background = prefs.STATIC_BLUR.get() ? new Meta.BackgroundActor : new St.Widget({
style_class: 'topbar-blurred-background',
x: 0,
y: 0,
width: this.monitor.width,
height: Main.panel.height,
});
this.background_parent.add_child(this.background);
}
enable() {
this._log("blurring top panel");
if (GS_MAJOR < 42) {
// hide corners, can't style them
Main.panel._leftCorner.hide();
Main.panel._rightCorner.hide();
this.connections.connect(Main.panel._leftCorner, 'show', () => { Main.panel._leftCorner.hide(); });
this.connections.connect(Main.panel._rightCorner, 'show', () => { Main.panel._rightCorner.hide(); });
}
// insert background parent
let children = Main.layoutManager.panelBox.get_children();
for (let i = 0; i < children.length; ++i)
if (children[i].name == 'topbar-blurred-background-parent')
Main.layoutManager.panelBox.remove_child(children[i]);
Main.layoutManager.panelBox.insert_child_at_index(this.background_parent, 0);
// remove background
Main.panel.add_style_class_name('transparent-panel');
// perform updates
this.change_blur_type();
Utils.setTimeout(() => { this.change_blur_type() }, 500);
// connect to panel size change
this.connections.connect(Main.panel, 'notify::height', () => {
this.update_size(this.prefs.STATIC_BLUR.get());
});
// connect to every background change (even without changing image)
this.connections.connect(Main.layoutManager._backgroundGroup, 'notify', () => {
this.update_wallpaper(this.prefs.STATIC_BLUR.get());
})
// connect to monitors change
this.connections.connect(Main.layoutManager, 'monitors-changed', () => {
if (Main.screenShield && !Main.screenShield.locked) {
this.update_wallpaper(this.prefs.STATIC_BLUR.get());
this.update_size(this.prefs.STATIC_BLUR.get());
}
});
this.connect_to_overview();
}
change_blur_type() {
let is_static = this.prefs.STATIC_BLUR.get();
// reset widgets to right state
this.background_parent.remove_child(this.background);
this.background.remove_effect(this.effect);
this.background = is_static ? new Meta.BackgroundActor : new St.Widget({
style_class: 'topbar-blurred-background',
x: 0,
y: 0,
width: this.monitor.width,
height: Main.panel.height,
});
this.effect.set_mode(is_static ? 0 : 1);
this.background.add_effect(this.effect);
this.background_parent.add_child(this.background);
// perform updates
this.update_wallpaper(is_static);
this.update_size(is_static);
// HACK
if (!is_static) {
// ! DIRTY PART: hack because `Shell.BlurEffect` does not repaint when shadows are under it
// ! this does not entirely fix this bug (shadows caused by windows still cause artefacts)
// ! but it prevents the shadows of the panel buttons to cause artefacts on the panel itself
// ! note: issue opened at https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857
if (this.prefs.HACKS_LEVEL.get() == 1) {
this._log("panel hack level 1");
this.paint_signals.disconnect_all();
let rp = () => { this.effect.queue_repaint() };
this.connections.connect(Main.panel, 'enter-event', rp);
this.connections.connect(Main.panel, 'leave-event', rp);
this.connections.connect(Main.panel, 'button-press-event', rp);
Main.panel.get_children().forEach(child => {
this.connections.connect(child, 'enter-event', rp);
this.connections.connect(child, 'leave-event', rp);
this.connections.connect(child, 'button-press-event', rp);
});
} else if (this.prefs.HACKS_LEVEL.get() == 2) {
this._log("panel hack level 2");
this.paint_signals.disconnect_all();
this.paint_signals.connect(this.background, this.effect);
} else {
this.paint_signals.disconnect_all();
}
// ! END OF DIRTY PART
}
}
update_wallpaper(is_static) {
// if static blur, get right wallpaper and update blur with it
if (is_static) {
// the try/catch behaviour is used to prevent bugs like #136 and #137
try {
let bg = Main.layoutManager._backgroundGroup.get_child_at_index(Main.layoutManager.monitors.length - this.monitor.index - 1);
this.background.set_content(bg.get_content());
} catch (error) { this._log(`could not blur panel: ${error}`) }
}
}
update_size(is_static) {
this.background_parent.width = Main.panel.width;
this.background.width = Main.panel.width;
let panel_box = Main.layoutManager.panelBox;
this.background.height = panel_box.height;
let clip_box = panel_box.get_parent();
if (is_static) {
this.background.set_clip(
clip_box.x,
clip_box.y,
panel_box.width,
panel_box.height
);
this.background.x = -clip_box.x;
this.background.y = -clip_box.y;
}
}
// returns either the primary monitor, or a dummy one if none is connected
get monitor() {
if (Main.layoutManager.primaryMonitor != null) {
return Main.layoutManager.primaryMonitor
} else {
return { x: 0, y: 0, width: 0, index: 0 }
}
}
// connect when overview if opened/closed to hide/show the blur in consequence
// if HIDETOPBAR set, we need just to hide the blur when showing appgrid (so no shadow is cropped)
connect_to_overview() {
this.connections.disconnect_all_for(Main.overview._overview._controls._appDisplay);
this.connections.disconnect_all_for(Main.overview);
if (!this.prefs.HIDETOPBAR.get()) {
this.connections.connect(Main.overview, 'showing', () => {
this.hide();
});
this.connections.connect(Main.overview, 'hidden', () => {
this.show();
});
} else {
this.connections.connect(Main.overview._overview._controls._appDisplay, 'show', () => {
this.hide();
});
this.connections.connect(Main.overview._overview._controls._appDisplay, 'hide', () => {
this.show();
});
this.connections.connect(Main.overview, 'hidden', () => {
this.show();
});
}
}
set_sigma(s) {
this.effect.sigma = s;
}
set_brightness(b) {
this.effect.brightness = b;
}
disable() {
this._log("removing blur from top panel");
Main.panel.remove_style_class_name('transparent-panel');
if (GS_MAJOR < 42) {
Main.panel._leftCorner.show();
Main.panel._rightCorner.show();
}
try {
Main.layoutManager.panelBox.remove_child(this.background_parent);
} catch (e) { }
this.connections.disconnect_all();
}
show() {
this.background_parent.show();
}
hide() {
this.background_parent.hide();
}
_log(str) {
if (this.prefs.DEBUG.get())
log(`[Blur my Shell] ${str}`)
}
}