123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- import Shell from 'gi://Shell';
- import Meta from 'gi://Meta';
- import * as Main from 'resource:///org/gnome/shell/ui/main.js';
- import { WorkspaceAnimationController } from 'resource:///org/gnome/shell/ui/workspaceAnimation.js';
- const wac_proto = WorkspaceAnimationController.prototype;
- const OVERVIEW_COMPONENTS_STYLE = [
- "overview-components-light",
- "overview-components-dark",
- "overview-components-transparent"
- ];
- export const OverviewBlur = class OverviewBlur {
- constructor(connections, settings, effects_manager) {
- this.connections = connections;
- this.effects = [];
- this.settings = settings;
- this.effects_manager = effects_manager;
- this._workspace_switch_bg_actors = [];
- this.enabled = false;
- }
- enable() {
- this._log("blurring overview");
- // connect to every background change (even without changing image)
- // FIXME this signal is fired very often, so we should find another one
- // fired only when necessary (but that still catches all cases)
- this.connections.connect(
- Main.layoutManager._backgroundGroup,
- 'notify',
- _ => {
- this._log("updated background");
- this.update_backgrounds();
- }
- );
- // connect to monitors change
- this.connections.connect(
- Main.layoutManager,
- 'monitors-changed',
- _ => {
- if (Main.screenShield && !Main.screenShield.locked) {
- this._log("changed monitors");
- this.update_backgrounds();
- }
- }
- );
- // add css class name for workspace-switch background
- Main.uiGroup.add_style_class_name("blurred-overview");
- // add css class name to make components semi-transparent if wanted
- this.update_components_classname();
- // update backgrounds when the component is enabled
- this.update_backgrounds();
- // part for the workspace animation switch
- // make sure not to do this part if the extension was enabled prior, as
- // the functions would call themselves and cause infinite recursion
- if (!this.enabled) {
- // store original workspace switching methods for restoring them on
- // disable()
- this._original_PrepareSwitch = wac_proto._prepareWorkspaceSwitch;
- this._original_FinishSwitch = wac_proto._finishWorkspaceSwitch;
- const w_m = global.workspace_manager;
- const outer_this = this;
- // create a blurred background actor for each monitor during a
- // workspace switch
- wac_proto._prepareWorkspaceSwitch = function (...params) {
- outer_this._log("prepare workspace switch");
- outer_this._original_PrepareSwitch.apply(this, params);
- // this permits to show the blur behind windows that are on
- // workspaces on the left and right
- if (
- outer_this.settings.applications.BLUR
- ) {
- let ws_index = w_m.get_active_workspace_index();
- [ws_index - 1, ws_index + 1].forEach(
- i => w_m.get_workspace_by_index(i)?.list_windows().forEach(
- window => window.get_compositor_private().show()
- )
- );
- }
- Main.layoutManager.monitors.forEach(monitor => {
- if (
- !(
- Meta.prefs_get_workspaces_only_on_primary() &&
- (monitor !== Main.layoutManager.primaryMonitor)
- )
- ) {
- const bg_actor = outer_this.create_background_actor(
- monitor, true
- );
- Main.uiGroup.insert_child_above(
- bg_actor,
- global.window_group
- );
- // store the actors so that we can delete them later
- outer_this._workspace_switch_bg_actors.push(bg_actor);
- }
- });
- };
- // remove the workspace-switch actors when the switch is done
- wac_proto._finishWorkspaceSwitch = function (...params) {
- outer_this._log("finish workspace switch");
- outer_this._original_FinishSwitch.apply(this, params);
- // this hides windows that are not on the current workspace
- if (
- outer_this.settings.applications.BLUR
- )
- for (let i = 0; i < w_m.get_n_workspaces(); i++) {
- if (i != w_m.get_active_workspace_index())
- w_m.get_workspace_by_index(i)?.list_windows().forEach(
- window => window.get_compositor_private().hide()
- );
- }
- outer_this.effects = outer_this.effects.filter(
- effects_group => !effects_group.is_transition
- );
- outer_this._workspace_switch_bg_actors.forEach(actor => {
- actor.destroy();
- });
- outer_this._workspace_switch_bg_actors = [];
- };
- }
- this.enabled = true;
- }
- update_backgrounds() {
- // remove every old background
- this.remove_background_actors();
- // add new backgrounds
- Main.layoutManager.monitors.forEach(monitor => {
- const bg_actor = this.create_background_actor(monitor, false);
- Main.layoutManager.overviewGroup.insert_child_at_index(
- bg_actor,
- monitor.index
- );
- });
- }
- create_background_actor(monitor, is_transition) {
- let bg_actor = new Meta.BackgroundActor({
- meta_display: global.display,
- monitor: monitor.index
- });
- let background_group = Main.layoutManager._backgroundGroup
- .get_children()
- .filter((child) => child instanceof Meta.BackgroundActor);
- let background =
- background_group[
- Main.layoutManager.monitors.length - monitor.index - 1
- ];
- if (!background) {
- this._warn("could not get background for overview");
- return bg_actor;
- }
- bg_actor.content.set({
- background: background.get_content().background
- });
- let blur_effect = new Shell.BlurEffect({
- brightness: this.settings.overview.CUSTOMIZE
- ? this.settings.overview.BRIGHTNESS
- : this.settings.BRIGHTNESS,
- sigma: this.settings.overview.CUSTOMIZE
- ? this.settings.overview.SIGMA
- : this.settings.SIGMA
- * monitor.geometry_scale,
- mode: Shell.BlurMode.ACTOR
- });
- // store the scale in the effect in order to retrieve it in set_sigma
- blur_effect.scale = monitor.geometry_scale;
- let color_effect = this.effects_manager.new_color_effect({
- color: this.settings.overview.CUSTOMIZE
- ? this.settings.overview.COLOR
- : this.settings.COLOR
- }, this.settings);
- let noise_effect = this.effects_manager.new_noise_effect({
- noise: this.settings.overview.CUSTOMIZE
- ? this.settings.overview.NOISE_AMOUNT
- : this.settings.NOISE_AMOUNT,
- lightness: this.settings.overview.CUSTOMIZE
- ? this.settings.overview.NOISE_LIGHTNESS
- : this.settings.NOISE_LIGHTNESS
- }, this.settings);
- bg_actor.add_effect(color_effect);
- bg_actor.add_effect(noise_effect);
- bg_actor.add_effect(blur_effect);
- this.effects.push({ blur_effect, color_effect, noise_effect, is_transition });
- bg_actor.set_x(monitor.x);
- bg_actor.set_y(monitor.y);
- return bg_actor;
- }
- /// Updates the classname to style overview components with semi-transparent
- /// backgrounds.
- update_components_classname() {
- OVERVIEW_COMPONENTS_STYLE.forEach(
- style => Main.uiGroup.remove_style_class_name(style)
- );
- if (this.settings.overview.STYLE_COMPONENTS > 0)
- Main.uiGroup.add_style_class_name(
- OVERVIEW_COMPONENTS_STYLE[this.settings.overview.STYLE_COMPONENTS - 1]
- );
- }
- set_sigma(s) {
- this.effects.forEach(effect => {
- effect.blur_effect.sigma = s * effect.blur_effect.scale;
- });
- }
- set_brightness(b) {
- this.effects.forEach(effect => {
- effect.blur_effect.brightness = b;
- });
- }
- set_color(c) {
- this.effects.forEach(effect => {
- effect.color_effect.color = c;
- });
- }
- set_noise_amount(n) {
- this.effects.forEach(effect => {
- effect.noise_effect.noise = n;
- });
- }
- set_noise_lightness(l) {
- this.effects.forEach(effect => {
- effect.noise_effect.lightness = l;
- });
- }
- remove_background_actors() {
- Main.layoutManager.overviewGroup.get_children().forEach(actor => {
- if (actor.constructor.name === 'Meta_BackgroundActor') {
- actor.get_effects().forEach(effect => {
- this.effects_manager.remove(effect);
- });
- Main.layoutManager.overviewGroup.remove_child(actor);
- actor.destroy();
- }
- });
- this.effects = [];
- }
- disable() {
- this._log("removing blur from overview");
- this.remove_background_actors();
- Main.uiGroup.remove_style_class_name("blurred-overview");
- OVERVIEW_COMPONENTS_STYLE.forEach(
- style => Main.uiGroup.remove_style_class_name(style)
- );
- // make sure to absolutely not do this if the component was not enabled
- // prior, as this would cause infinite recursion
- if (this.enabled) {
- // restore original behavior
- if (this._original_PrepareSwitch)
- wac_proto._prepareWorkspaceSwitch = this._original_PrepareSwitch;
- if (this._original_FinishSwitch)
- wac_proto._finishWorkspaceSwitch = this._original_FinishSwitch;
- }
- this.connections.disconnect_all();
- this.enabled = false;
- }
- _log(str) {
- if (this.settings.DEBUG)
- console.log(`[Blur my Shell > overview] ${str}`);
- }
- _warn(str) {
- console.warn(`[Blur my Shell > overview] ${str}`);
- }
- };
|