246 lines
8.8 KiB
JavaScript
246 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}`)
|
||
|
}
|
||
|
}
|