summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js
diff options
context:
space:
mode:
authorNippy <nippy@Nippy-Mac-mini.local>2026-10-09 17:23:53 +0200
committerNippy <nippy@Nippy-Mac-mini.local>2026-10-09 17:23:53 +0200
commit9d5be1660d8f74038ebed3d74fdbc809e43787ae (patch)
tree4cb46c3765be87ca4c5219f2f714425d7dfddb56 /raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js
parentdeb4b8a9c407832c35100a643bd7a592589c9679 (diff)
downloadRaveOS-PKGBUILD-9d5be1660d8f74038ebed3d74fdbc809e43787ae.tar.gz
RaveOS-PKGBUILD-9d5be1660d8f74038ebed3d74fdbc809e43787ae.zip
gnome fix
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js')
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js187
1 files changed, 165 insertions, 22 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js
index 84b1d7a..f52e26f 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js
@@ -1,6 +1,9 @@
import St from 'gi://St';
+import Meta from 'gi://Meta';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as Background from 'resource:///org/gnome/shell/ui/background.js';
+import * as uniforms from './shader_uniforms.js';
+import * as utils from './utils.js';
/// A `Pipeline` object is a handy way to manage the effects attached to an actor. It only manages
/// one actor at a time (so blurring multiple widgets will need multiple `Pipeline`), and is
@@ -18,10 +21,11 @@ import * as Background from 'resource:///org/gnome/shell/ui/background.js';
/// - `'pipeline_id'::effect-'id'-key-updated`, handing the key that was changed and its new value
/// - `'pipeline_id'::effect-'id'-key-added`, handing the key that was added and its value
export const Pipeline = class Pipeline {
- constructor(effects_manager, pipelines_manager, pipeline_id, actor = null) {
+ constructor(effects_manager, pipelines_manager, pipeline_id, actor = null, options = {}) {
this.effects_manager = effects_manager;
this.pipelines_manager = pipelines_manager;
this.effects = [];
+ this.effect_overrides = options.effect_overrides ?? {};
this.set_pipeline_id(pipeline_id);
this.attach_pipeline_to_actor(actor);
}
@@ -41,19 +45,18 @@ export const Pipeline = class Pipeline {
) {
let monitor = Main.layoutManager.monitors[monitor_index];
+ this.remove_pipeline_from_actor();
+
// create the new actor
this.actor = new St.Widget({
name: widget_name,
x: use_absolute_position ? monitor.x : 0,
- y: .5 + (use_absolute_position ? monitor.y : 0), // add 1 to correct z-position
+ y: utils.subpixel_stage_offset() + (use_absolute_position ? monitor.y : 0),
z_position: 1, // seems to fix the multi-monitor glitch
width: monitor.width,
height: monitor.height
});
- // remove the effects, wether or not we attach the pipeline to the actor: if they are fired
- // while the actor has changed, this could go bad
- this.remove_all_effects();
if (this.pipeline_id)
this.attach_pipeline_to_actor(this.actor);
@@ -64,6 +67,17 @@ export const Pipeline = class Pipeline {
});
bg_manager._bms_pipeline = this;
+ // 'controlPosition: false' skips BackgroundManager's default layout pass, which also diables
+ // sibling re-ordering.
+ // Without it, new actors render on top while loading, causing a solid color flash through
+ // on the surface.
+ this.child_added_id = this.actor.connect(
+ 'child-added', (container, child) => {
+ if (child instanceof Meta.BackgroundActor)
+ container.set_child_below_sibling(child, null);
+ }
+ );
+
background_managers.push(bg_manager);
background_group.insert_child_at_index(this.actor, 0);
@@ -104,14 +118,14 @@ export const Pipeline = class Pipeline {
/// Attach a Pipeline object with `pipeline_id` already set to an actor.
attach_pipeline_to_actor(actor) {
- // set the actor
- if (actor)
- this.actor = actor;
- else {
+ if (!actor) {
this.remove_pipeline_from_actor();
return;
}
+ this.disconnect_actor_destroy();
+ this.actor = actor;
+
// attach the pipeline
let pipeline = this.pipelines_manager.pipelines[this.pipeline_id];
if (!pipeline) {
@@ -134,10 +148,23 @@ export const Pipeline = class Pipeline {
remove_pipeline_from_actor() {
this.remove_all_effects();
- if (this.actor && this.actor_destroy_id)
+ this.disconnect_actor_destroy();
+ this.disconnect_child_added();
+ this.actor = null;
+ }
+
+ disconnect_actor_destroy() {
+ if (this.actor && this.actor_destroy_id) {
this.actor.disconnect(this.actor_destroy_id);
+ }
this.actor_destroy_id = null;
- this.actor = null;
+ }
+
+ disconnect_child_added() {
+ if (this.actor && this.child_added_id) {
+ this.actor.disconnect(this.child_added_id);
+ }
+ this.child_added_id = null;
}
/// Update the effects from the given pipeline object, the hard way.
@@ -147,7 +174,9 @@ export const Pipeline = class Pipeline {
// build the new effects to be added
pipeline.effects.forEach(effect => {
- if ('new_' + effect.type + '_effect' in this.effects_manager)
+ if (effect.type === 'pixelize')
+ this.build_pixelize_effect(effect);
+ else if ('new_' + effect.type + '_effect' in this.effects_manager)
this.build_effect(effect);
else
this._warn(`could not add effect to actor, effect "${effect.type}" not found`);
@@ -156,32 +185,143 @@ export const Pipeline = class Pipeline {
// add the effects to the actor
if (this.actor)
- this.effects.forEach(effect => this.actor.add_effect(effect));
+ this.effects.forEach(effect => {
+ this.actor.add_effect(effect);
+ uniforms.mark_dirty(effect);
+ });
else
this._warn(`could not add effect to actor, actor does not exist anymore`);
}
+ build_pixelize_effect(effect_infos) {
+ const effect_params = this.get_effect_params(effect_infos);
+ const effect_overrides = this.get_effect_overrides(effect_infos.type, effect_params);
+ const params = {
+ ...effect_params,
+ ...effect_overrides,
+ };
+
+ const downscale = this.effects_manager.new_downscale_effect({
+ divider: params.factor,
+ downsampling_mode: params.downsampling_mode,
+ opacity_factor: params.opacity_factor,
+ });
+ const upscale = this.effects_manager.new_upscale_effect({
+ factor: params.factor,
+ opacity_factor: params.opacity_factor,
+ });
+
+ this.setup_effect(downscale, effect_infos, effect_params, 'downscale');
+ this.setup_effect(upscale, effect_infos, effect_params, 'upscale');
+ }
+
/// Given an `effect_infos` object containing the effect type, id and params, build an effect
/// and append it to the effects list
build_effect(effect_infos) {
- let effect = this.effects_manager['new_' + effect_infos.type + '_effect'](effect_infos.params);
+ const effect_params = this.get_effect_params(effect_infos);
+ const effect_overrides = this.get_effect_overrides(effect_infos.type, effect_params);
+ let effect = this.effects_manager['new_' + effect_infos.type + '_effect']({
+ ...effect_params,
+ ...effect_overrides,
+ });
+ this.setup_effect(effect, effect_infos, effect_params);
+ }
+
+ setup_effect(effect, effect_infos, effect_params, pixelize_role = null) {
+ effect._bms_effect_type = effect_infos.type;
+ effect._bms_effect_id = effect_infos.id;
+ effect._bms_effect_params = effect_params;
+ effect._bms_pixelize_role = pixelize_role;
this.effects.push(effect);
// connect to settings changes
effect._effect_key_removed_id = this.pipelines_manager.connect(
- this.pipeline_id + '::effect-' + effect_infos.id + '-key-removed',
- (_, key) => effect[key] = effect.constructor.default_params[key]
+ this.pipeline_id + '::effect-' + effect_infos.id + '-key-removed', (_, key) => {
+ const default_value = this.get_effect_default_param(effect, key);
+ effect._bms_effect_params[key] = default_value;
+ if (!this.apply_effect_override(effect, key))
+ this.set_effect_param(effect, key, default_value);
+ }
);
effect._effect_key_updated_id = this.pipelines_manager.connect(
- this.pipeline_id + '::effect-' + effect_infos.id + '-key-updated',
- (_, key, value) => effect[key] = value
+ this.pipeline_id + '::effect-' + effect_infos.id + '-key-updated', (_, key, value) => {
+ effect._bms_effect_params[key] = value;
+ if (!this.apply_effect_override(effect, key))
+ this.set_effect_param(effect, key, value);
+ }
);
effect._effect_key_added_id = this.pipelines_manager.connect(
- this.pipeline_id + '::effect-' + effect_infos.id + '-key-added',
- (_, key, value) => effect[key] = value
+ this.pipeline_id + '::effect-' + effect_infos.id + '-key-added', (_, key, value) => {
+ effect._bms_effect_params[key] = value;
+ if (!this.apply_effect_override(effect, key))
+ this.set_effect_param(effect, key, value);
+ }
);
}
+ get_effect_params(effect_infos) {
+ const effect_class = this.effects_manager.SUPPORTED_EFFECTS[effect_infos.type]?.class;
+ return {
+ ...(effect_class?.default_params ?? {}),
+ ...(effect_infos.params ?? {}),
+ };
+ }
+
+ get_effect_default_param(effect, key) {
+ return this.effects_manager.SUPPORTED_EFFECTS[effect._bms_effect_type]
+ ?.class
+ ?.default_params
+ ?.[key];
+ }
+
+ get_effect_overrides(effect_type, effect_params = {}) {
+ const overrides = this.effect_overrides[effect_type] ?? {};
+ return typeof overrides === 'function' ? overrides(effect_params) : overrides;
+ }
+
+ apply_effect_override(effect, key) {
+ const overrides = this.get_effect_overrides(effect._bms_effect_type, effect._bms_effect_params);
+ if (!(key in overrides))
+ return false;
+
+ this.set_effect_param(effect, key, overrides[key]);
+ return true;
+ }
+
+ apply_effect_overrides(effect_type = null) {
+ this.effects.forEach(effect => {
+ if (effect_type && effect._bms_effect_type !== effect_type)
+ return;
+
+ const overrides = this.get_effect_overrides(effect._bms_effect_type, effect._bms_effect_params);
+ Object.keys(overrides).forEach(key => this.set_effect_param(effect, key, overrides[key]));
+ });
+ }
+
+ set_effect_param(effect, key, value) {
+ if (effect._bms_effect_type !== 'pixelize') {
+ effect[key] = value;
+ return;
+ }
+
+ if (key === 'factor') {
+ if (effect._bms_pixelize_role === 'downscale')
+ effect.divider = value;
+ else if (effect._bms_pixelize_role === 'upscale')
+ effect.factor = value;
+ return;
+ }
+
+ if (key === 'downsampling_mode') {
+ if (effect._bms_pixelize_role === 'downscale')
+ effect.downsampling_mode = value;
+ return;
+ }
+
+ if (key in effect)
+ effect[key] = value;
+ }
+
/// Remove every effect from the actor it is attached to. Please note that they are not
/// destroyed, but rather stored (thanks to the `EffectManager` class) to be reused later.
remove_all_effects() {
@@ -197,6 +337,10 @@ export const Pipeline = class Pipeline {
delete effect._effect_key_removed_id;
delete effect._effect_key_updated_id;
delete effect._effect_key_added_id;
+ delete effect._bms_effect_type;
+ delete effect._bms_effect_id;
+ delete effect._bms_effect_params;
+ delete effect._bms_pixelize_role;
});
this.effects = [];
}
@@ -211,7 +355,6 @@ export const Pipeline = class Pipeline {
/// Resets the `Pipeline` object to a sane state, removing every effect and signal.
/// Note: exposed to public API.
destroy() {
- this.remove_all_effects();
this.remove_connections();
this.remove_pipeline_from_actor();
this.pipeline_id = null;
@@ -220,4 +363,4 @@ export const Pipeline = class Pipeline {
_warn(str) {
console.warn(`[Blur my Shell > pipeline] ${str}`);
}
-}; \ No newline at end of file
+};