summaryrefslogtreecommitdiff
path: root/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects
diff options
context:
space:
mode:
authornippy <you@example.com>2026-04-18 13:49:56 +0200
committernippy <you@example.com>2026-04-18 13:49:56 +0200
commit5d94c0a7d44a2255b81815a52a7056a94a39842d (patch)
tree759bdea9645c6a62f9e1e4c001f7d81cccd120d2 /raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects
parente79cdf210b267f21a186255ce1a4d50029439d54 (diff)
downloadRaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.tar.gz
RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.zip
update Raveos themes
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects')
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl111
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js168
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl93
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js211
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl71
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js120
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl76
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js140
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js362
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl70
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js213
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl14
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js31
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl52
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js207
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js43
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js43
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl20
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js76
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js88
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl18
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js31
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl57
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js120
24 files changed, 2435 insertions, 0 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl
new file mode 100644
index 0000000..5df6512
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl
@@ -0,0 +1,111 @@
+uniform sampler2D tex;
+uniform float red;
+uniform float green;
+uniform float blue;
+uniform float blend;
+uniform int mode;
+
+const int NORMAL = 0;
+const int MULTIPLY = 1;
+const int SCREEN = 2;
+const int OVERLAY = 3;
+const int DARKEN = 4;
+const int LIGHTEN = 5;
+const int PLUS_DARKER = 6;
+const int PLUS_LIGHTER = 7;
+const int COLOR_DODGE = 8;
+const int COLOR_BURN = 9;
+const int HARD_LIGHT = 10;
+const int SOFT_LIGHT = 11;
+const int DIFFERENCE = 12;
+const int EXCLUSION = 13;
+const int HUE = 14;
+const int SATURATION = 15;
+const int COLOR = 16;
+const int LUMINOSITY = 17;
+
+vec3 rgb_to_hsl(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsl_to_rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+
+float soft_light_channel(float base, float _blend) {
+ if (_blend < 0.5) {
+ return base - (1.0 - 2.0 * _blend) * base * (1.0 - base);
+ } else {
+ float d = (base < 0.25)
+ ? ((16.0 * base - 12.0) * base + 4.0) * base
+ : sqrt(base);
+ return base + (2.0 * _blend - 1.0) * (d - base);
+ }
+}
+
+vec3 get_blend(vec3 base, vec3 _blend) {
+ if (mode == MULTIPLY) return base * _blend;
+ if (mode == SCREEN) return 1 - (1 - base) * (1 - _blend);
+ if (mode == OVERLAY) {
+ vec3 result;
+ result.r = base.r < 0.5 ? (2.0 * base.r * _blend.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - _blend.r));
+ result.g = base.g < 0.5 ? (2.0 * base.g * _blend.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - _blend.g));
+ result.b = base.b < 0.5 ? (2.0 * base.b * _blend.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - _blend.b));
+ return result;
+ }
+ if (mode == DARKEN) return min(base, _blend);
+ if (mode == LIGHTEN) return max(base, _blend);
+ if (mode == PLUS_DARKER) return base + _blend - 1;
+ if (mode == PLUS_LIGHTER) return base + _blend;
+ if (mode == COLOR_DODGE) return base / (1 - _blend);
+ if (mode == COLOR_BURN) return 1 - (1 - base) / _blend;
+ if (mode == HARD_LIGHT) {
+ vec3 result;
+ result.r = _blend.r < 0.5 ? (2.0 * base.r * _blend.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - _blend.r));
+ result.g = _blend.g < 0.5 ? (2.0 * base.g * _blend.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - _blend.g));
+ result.b = _blend.b < 0.5 ? (2.0 * base.b * _blend.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - _blend.b));
+ return result;
+ }
+ if (mode == SOFT_LIGHT) {
+ return vec3(soft_light_channel(base.r, _blend.r), soft_light_channel(base.g, _blend.g), soft_light_channel(base.b, _blend.b));
+ }
+ if (mode == DIFFERENCE) return abs(base - _blend);
+ if (mode == EXCLUSION) return 0.5 - 2 * (base - 0.5) * (_blend - 0.5);
+ if (mode == HUE) {
+ vec3 base_hsl = rgb_to_hsl(base);
+ vec3 blend_hsl = rgb_to_hsl(_blend);
+ return hsl_to_rgb(vec3(blend_hsl.x, base_hsl.y, base_hsl.z));
+ }
+ if (mode == SATURATION) {
+ vec3 base_hsl = rgb_to_hsl(base);
+ vec3 blend_hsl = rgb_to_hsl(_blend);
+ return hsl_to_rgb(vec3(base_hsl.x, blend_hsl.y, base_hsl.z));
+ }
+ if (mode == COLOR) {
+ vec3 base_hsl = rgb_to_hsl(base);
+ vec3 blend_hsl = rgb_to_hsl(_blend);
+ return hsl_to_rgb(vec3(blend_hsl.x, blend_hsl.y, base_hsl.z));
+ }
+ if (mode == LUMINOSITY) {
+ vec3 base_hsl = rgb_to_hsl(base);
+ vec3 blend_hsl = rgb_to_hsl(_blend);
+ return hsl_to_rgb(vec3(base_hsl.x, base_hsl.y, blend_hsl.z));
+ }
+ return _blend; // For NORMAL
+}
+
+void main() {
+ vec4 c = texture2D(tex, cogl_tex_coord_in[0].st);
+ vec3 pix_color = c.xyz;
+ vec3 color = get_blend(pix_color, vec3(red, green, blue));
+
+ cogl_color_out = vec4(mix(pix_color, color, blend), 1.);
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js
new file mode 100644
index 0000000..1f4bdf4
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js
@@ -0,0 +1,168 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'color.glsl';
+const DEFAULT_PARAMS = {
+ color: [0.0, 0.0, 0.0, 0.0],
+ blend_mode: 0
+};
+
+
+export const ColorEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "ColorEffect",
+ Properties: {
+ 'red': GObject.ParamSpec.double(
+ `red`,
+ `Red`,
+ `Red value in shader`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.0,
+ ),
+ 'green': GObject.ParamSpec.double(
+ `green`,
+ `Green`,
+ `Green value in shader`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.0,
+ ),
+ 'blue': GObject.ParamSpec.double(
+ `blue`,
+ `Blue`,
+ `Blue value in shader`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.0,
+ ),
+ 'blend': GObject.ParamSpec.double(
+ `blend`,
+ `Blend`,
+ `Amount of blending between the colors`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.0,
+ ),
+ 'blend_mode': GObject.ParamSpec.int(
+ `blend_mode`,
+ `Blend mode`,
+ `Blend mode`,
+ GObject.ParamFlags.READWRITE,
+ 0, 17,
+ 0,
+ )
+ }
+ // Normal (0), Multiply (1), Screen (2), Overlay (3), Darken (4), Lighten (5), Plus darker (6), Plus lighter (7), Color dodge (8),
+ // Color burn (9), Hard light (10), Soft light (11), Difference (12), Exclusion (13), Hue (14), Saturation (15), Color (16),
+ // Luminosity (17)
+ }, class ColorEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ // initialize without color as a parameter
+ const { color, ...parent_params } = params;
+ super(parent_params);
+
+ this._red = null;
+ this._green = null;
+ this._blue = null;
+ this._blend = null;
+ this._blend_mode = null;
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+
+ // set params; utils.setup_params doesn't work here with color
+ this.color = 'color' in params ? color : this.constructor.default_params.color;
+ this.blend_mode = 'blend_mode' in params ? params.blend_mode : this.constructor.default_params.blend_mode;
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get red() {
+ return this._red;
+ }
+
+ set red(value) {
+ if (this._red !== value) {
+ this._red = value;
+
+ this.set_uniform_value('red', parseFloat(this._red - 1e-6));
+ }
+ }
+
+ get green() {
+ return this._green;
+ }
+
+ set green(value) {
+ if (this._green !== value) {
+ this._green = value;
+
+ this.set_uniform_value('green', parseFloat(this._green - 1e-6));
+ }
+ }
+
+ get blue() {
+ return this._blue;
+ }
+
+ set blue(value) {
+ if (this._blue !== value) {
+ this._blue = value;
+
+ this.set_uniform_value('blue', parseFloat(this._blue - 1e-6));
+ }
+ }
+
+ get blend() {
+ return this._blend;
+ }
+
+ set blend(value) {
+ if (this._blend !== value) {
+ this._blend = value;
+
+ this.set_uniform_value('blend', parseFloat(this._blend - 1e-6));
+ this.set_enabled(this.blend > 0);
+ }
+ }
+
+ get blend_mode() {
+ return this._blend_mode;
+ }
+
+ set blend_mode(value) {
+ if (this._blend_mode !== value) {
+ this._blend_mode = value;
+
+ this.set_uniform_value('mode', this._blend_mode);
+ }
+ }
+
+ set color(rgba) {
+ let [r, g, b, a] = rgba;
+ this.red = r;
+ this.green = g;
+ this.blue = b;
+ this.blend = a;
+ }
+
+ get color() {
+ return [this.red, this.green, this.blue, this.blend];
+ }
+
+ /// False set function, only cares about the color. Too hard to change.
+ set(params) {
+ this.color = params.color;
+ this.blend_mode = params.blend_mode;
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl
new file mode 100644
index 0000000..760798a
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl
@@ -0,0 +1,93 @@
+// Heavily based on https://github.com/yilozt/rounded-window-corners
+// which is itself based on upstream Mutter code
+
+uniform sampler2D tex;
+uniform float radius;
+uniform float width;
+uniform float height;
+uniform bool corners_top;
+uniform bool corners_bottom;
+
+uniform float clip_x0;
+uniform float clip_y0;
+uniform float clip_width;
+uniform float clip_height;
+
+float circle_bounds(vec2 p, vec2 center, float clip_radius) {
+ vec2 delta = p - center;
+ float dist_squared = dot(delta, delta);
+
+ float outer_radius = clip_radius + 0.5;
+ if (dist_squared >= (outer_radius * outer_radius))
+ return 0.0;
+
+ float inner_radius = clip_radius - 0.5;
+ if (dist_squared <= (inner_radius * inner_radius))
+ return 1.0;
+
+ return outer_radius - sqrt(dist_squared);
+}
+
+vec4 getTexture(vec2 uv) {
+ if (uv.x < 2. / width)
+ uv.x = 2. / width;
+
+ if (uv.y < 2. / height)
+ uv.y = 2. / height;
+
+ if (uv.x > 1. - 3. / width)
+ uv.x = 1. - 3. / width;
+
+ if (uv.y > 1. - 3. / height)
+ uv.y = 1. - 3. / height;
+
+ return texture2D(tex, uv);
+}
+
+float rounded_rect_coverage(vec2 p, vec4 bounds, float clip_radius) {
+ // Outside the bounds
+ if (p.x < bounds.x || p.x > bounds.z || p.y < bounds.y || p.y > bounds.w) {
+ return 0.;
+ }
+
+ vec2 center;
+
+ float center_left = bounds.x + clip_radius;
+ float center_right = bounds.z - clip_radius;
+
+ if (p.x < center_left)
+ center.x = center_left + 2.;
+ else if (p.x > center_right)
+ center.x = center_right - 1.;
+ else
+ return 1.0;
+
+ float center_top = bounds.y + clip_radius;
+ float center_bottom = bounds.w - clip_radius;
+
+ if (corners_top && p.y < center_top)
+ center.y = center_top + 2.;
+ else if (corners_bottom && p.y > center_bottom)
+ center.y = center_bottom - 1.;
+ else
+ return 1.0;
+
+ return circle_bounds(p, center, clip_radius);
+}
+
+void main(void) {
+ vec2 uv = cogl_tex_coord_in[0].xy;
+ vec2 pos = uv * vec2(width, height);
+ vec4 c = getTexture(uv);
+
+ vec4 bounds;
+ if (clip_width < 0. || clip_height < 0.) {
+ bounds = vec4(clip_x0, clip_y0, clip_x0 + width, clip_y0 + height);
+ } else {
+ bounds = vec4(clip_x0, clip_y0, clip_x0 + clip_width, clip_y0 + clip_height);
+ }
+
+ float alpha = rounded_rect_coverage(pos, bounds, radius);
+
+ cogl_color_out = vec4(c.rgb * alpha, min(alpha, c.a));
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js
new file mode 100644
index 0000000..109be12
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js
@@ -0,0 +1,211 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const St = await utils.import_in_shell_only('gi://St');
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'corner.glsl';
+const DEFAULT_PARAMS = {
+ radius: 12, width: 0, height: 0,
+ corners_top: true, corners_bottom: true,
+ clip: [0, 0, -1, -1]
+};
+
+
+export const CornerEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "CornerEffect",
+ Properties: {
+ 'radius': GObject.ParamSpec.double(
+ `radius`,
+ `Corner Radius`,
+ `Corner Radius`,
+ GObject.ParamFlags.READWRITE,
+ 0, Number.MAX_SAFE_INTEGER,
+ 12,
+ ),
+ 'width': GObject.ParamSpec.double(
+ `width`,
+ `Width`,
+ `Width`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'height': GObject.ParamSpec.double(
+ `height`,
+ `Height`,
+ `Height`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'corners_top': GObject.ParamSpec.boolean(
+ `corners_top`,
+ `Round top corners`,
+ `Round top corners`,
+ GObject.ParamFlags.READWRITE,
+ true,
+ ),
+ 'corners_bottom': GObject.ParamSpec.boolean(
+ `corners_bottom`,
+ `Round bottom corners`,
+ `Round bottom corners`,
+ GObject.ParamFlags.READWRITE,
+ true,
+ ),
+ // FIXME this works but it logs an error, because I'm not a double...
+ // I don't want to fiddle with GVariants again
+ 'clip': GObject.ParamSpec.double(
+ `clip`,
+ `Clip`,
+ `Clip`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ }
+ }, class CornerEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ this._clip_x0 = null;
+ this._clip_y0 = null;
+ this._clip_width = null;
+ this._clip_height = null;
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+
+ const theme_context = St.ThemeContext.get_for_stage(global.stage);
+ theme_context.connectObject('notify::scale-factor', _ => this.update_radius(), this);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get radius() {
+ return this._radius;
+ }
+
+ set radius(value) {
+ if (this._radius !== value) {
+ this._radius = value;
+
+ this.update_radius();
+ }
+ }
+
+ update_radius() {
+ const theme_context = St.ThemeContext.get_for_stage(global.stage);
+ let radius = Math.min(
+ this.radius * theme_context.scale_factor,
+ this.width / 2, this.height / 2
+ );
+ if (this._clip_width >= 0 || this._clip_height >= 0)
+ radius = Math.min(radius, this._clip_width / 2, this._clip_height / 2);
+
+ this.set_uniform_value('radius', parseFloat(radius - 1e-6));
+ }
+
+ get width() {
+ return this._width;
+ }
+
+ set width(value) {
+ if (this._width !== value) {
+ this._width = value;
+
+ this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6));
+ this.update_radius();
+ }
+ }
+
+ get height() {
+ return this._height;
+ }
+
+ set height(value) {
+ if (this._height !== value) {
+ this._height = value;
+
+ this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6));
+ this.update_radius();
+ }
+ }
+
+ get corners_top() {
+ return this._corners_top;
+ }
+
+ set corners_top(value) {
+ if (this._corners_top !== value) {
+ this._corners_top = value;
+
+ this.set_uniform_value('corners_top', this._corners_top ? 1 : 0);
+ }
+ }
+
+ get corners_bottom() {
+ return this._corners_bottom;
+ }
+
+ set corners_bottom(value) {
+ if (this._corners_bottom !== value) {
+ this._corners_bottom = value;
+
+ this.set_uniform_value('corners_bottom', this._corners_bottom ? 1 : 0);
+ }
+ }
+
+ get clip() {
+ return [this._clip_x0, this._clip_y0, this._clip_width, this._clip_height];
+ }
+
+ set clip(value) {
+ [this._clip_x0, this._clip_y0, this._clip_width, this._clip_height] = value;
+ this.set_uniform_value('clip_x0', parseFloat(this._clip_x0 - 1e-6));
+ this.set_uniform_value('clip_y0', parseFloat(this._clip_y0 - 1e-6));
+ this.set_uniform_value('clip_width', parseFloat(this._clip_width + 3 - 1e-6));
+ this.set_uniform_value('clip_height', parseFloat(this._clip_height + 3 - 1e-6));
+ this.update_radius();
+ }
+
+ vfunc_set_actor(actor) {
+ if (this._actor_connection_size_id) {
+ let old_actor = this.get_actor();
+ old_actor?.disconnect(this._actor_connection_size_id);
+ }
+ if (this._actor_connection_clip_rect_id) {
+ let old_actor = this.get_actor();
+ old_actor?.disconnect(this._actor_connection_clip_rect_id);
+ }
+
+ if (actor) {
+ this.width = actor.width;
+ this.height = actor.height;
+ this._actor_connection_size_id = actor.connect('notify::size', _ => {
+ this.width = actor.width;
+ this.height = actor.height;
+ });
+
+ this.clip = actor.has_clip ? actor.get_clip() : [0, 0, -10, -10];
+ this._actor_connection_clip_rect_id = actor.connect('notify::clip-rect', _ => {
+ this.clip = actor.has_clip ? actor.get_clip() : [0, 0, -10, -10];
+ });
+ }
+ else {
+ this._actor_connection_size_id = null;
+ this._actor_connection_clip_rect_id = null;
+ }
+
+ super.vfunc_set_actor(actor);
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl
new file mode 100644
index 0000000..64c1682
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl
@@ -0,0 +1,71 @@
+uniform sampler2D tex;
+uniform int operation;
+uniform float width;
+uniform float height;
+
+#define CORRECTION 2.25
+#define SIZE_ADDITION 3
+
+vec4 get_texture_at_position(vec2 position) {
+ vec2 raw_position = position + vec2(CORRECTION, CORRECTION);
+ vec2 raw_uv = raw_position / vec2(width + SIZE_ADDITION, height + SIZE_ADDITION);
+
+ return texture2D(tex, raw_uv);
+}
+
+vec4 try_get_texture_at_position(vec2 position, inout int count) {
+ if (any(greaterThanEqual(position, vec2(width, height))) ||
+ any(lessThan(position, vec2(0, 0)))) {
+ return vec4(0);
+ } else {
+ count++;
+ return get_texture_at_position(position);
+ }
+}
+
+ivec2 get_corrected_position() {
+ vec2 raw_uv = cogl_tex_coord0_in.st;
+ vec2 raw_position = raw_uv * vec2(width + SIZE_ADDITION, height + SIZE_ADDITION);
+ return ivec2(raw_position - vec2(CORRECTION, CORRECTION));
+}
+
+void main() {
+ ivec2 corrected_position = get_corrected_position();
+
+ // 1-step derivative
+ if (operation == 0) {
+ vec4 color = vec4(0);
+ int c = 0;
+ color += try_get_texture_at_position(corrected_position + vec2(0, 1), c);
+ color -= try_get_texture_at_position(corrected_position + vec2(0, 0), c);
+ color += try_get_texture_at_position(corrected_position + vec2(1, 0), c);
+ color -= try_get_texture_at_position(corrected_position + vec2(0, 0), c);
+ if (c < 4) {
+ color = vec4(0);
+ }
+ cogl_color_out = vec4(color.xyz, 1);
+ } else
+ // 2-step derivative
+ if (operation == 1) {
+ vec4 color = vec4(0);
+ int c = 0;
+ color += try_get_texture_at_position(corrected_position + vec2(0, 1), c);
+ color -= try_get_texture_at_position(corrected_position + vec2(0, -1), c);
+ color += try_get_texture_at_position(corrected_position + vec2(1, 0), c);
+ color -= try_get_texture_at_position(corrected_position + vec2(-1, 0), c);
+ if (c < 4) {
+ color = vec4(0);
+ }
+ cogl_color_out = vec4(color.xyz / 2, 1);
+ } else
+ // laplacian
+ if (operation == 2) {
+ vec4 color = vec4(0);
+ color = -4 * get_texture_at_position(corrected_position);
+ color += get_texture_at_position(corrected_position + vec2(0, 1));
+ color += get_texture_at_position(corrected_position + vec2(0, -1));
+ color += get_texture_at_position(corrected_position + vec2(1, 0));
+ color += get_texture_at_position(corrected_position + vec2(-1, 0));
+ cogl_color_out = vec4(color.xyz, 1);
+ }
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js
new file mode 100644
index 0000000..04d6100
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js
@@ -0,0 +1,120 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'derivative.glsl';
+const DEFAULT_PARAMS = {
+ operation: 0, width: 0, height: 0
+};
+
+
+export const DerivativeEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "DerivativeEffect",
+ Properties: {
+ 'operation': GObject.ParamSpec.int(
+ `operation`,
+ `Operation`,
+ `Operation`,
+ GObject.ParamFlags.READWRITE,
+ 0, 2,
+ 0,
+ ),
+ 'width': GObject.ParamSpec.double(
+ `width`,
+ `Width`,
+ `Width`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'height': GObject.ParamSpec.double(
+ `height`,
+ `Height`,
+ `Height`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ )
+ }
+ }, class DerivativeEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get operation() {
+ return this._operation;
+ }
+
+ set operation(value) {
+ if (this._operation !== value) {
+ this._operation = value;
+
+ this.set_uniform_value('operation', this._operation);
+ }
+ }
+
+ get width() {
+ return this._width;
+ }
+
+ set width(value) {
+ if (this._width !== value) {
+ this._width = value;
+
+ this.set_uniform_value('width', parseFloat(this._width - 1e-6));
+ }
+ }
+
+ get height() {
+ return this._height;
+ }
+
+ set height(value) {
+ if (this._height !== value) {
+ this._height = value;
+
+ this.set_uniform_value('height', parseFloat(this._height - 1e-6));
+ }
+ }
+
+ vfunc_set_actor(actor) {
+ if (this._actor_connection_size_id) {
+ let old_actor = this.get_actor();
+ old_actor?.disconnect(this._actor_connection_size_id);
+ }
+ if (actor) {
+ this.width = actor.width;
+ this.height = actor.height;
+ this._actor_connection_size_id = actor.connect('notify::size', _ => {
+ this.width = actor.width;
+ this.height = actor.height;
+ });
+ }
+ else
+ this._actor_connection_size_id = null;
+
+ super.vfunc_set_actor(actor);
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ // force setting nearest-neighbour texture filtering
+ this.get_pipeline().set_layer_filters(0, 9728, 9728);
+
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl
new file mode 100644
index 0000000..9871268
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl
@@ -0,0 +1,76 @@
+uniform sampler2D tex;
+uniform int divider;
+uniform float width;
+uniform float height;
+uniform int downsampling_mode;
+
+#define CORRECTION 2.25
+#define SIZE_ADDITION 3
+
+vec4 get_texture_at_position(vec2 position) {
+ vec2 raw_position = position + vec2(CORRECTION, CORRECTION);
+ vec2 raw_uv = raw_position / vec2(width + SIZE_ADDITION, height + SIZE_ADDITION);
+
+ return texture2D(tex, raw_uv);
+}
+
+vec2 get_corrected_position() {
+ vec2 raw_uv = cogl_tex_coord0_in.st;
+ vec2 raw_position = raw_uv * vec2(width + SIZE_ADDITION, height + SIZE_ADDITION);
+ return raw_position - vec2(CORRECTION, CORRECTION);
+}
+
+void main() {
+ ivec2 corrected_position = ivec2(get_corrected_position());
+ vec2 multiplied_position = corrected_position * divider;
+
+ if (any(greaterThan(multiplied_position, vec2(width, height)))) {
+ discard;
+ }
+
+ // mode 0: boxcar downsampling
+ if (downsampling_mode == 0) {
+
+ vec4 color = vec4(0.);
+ int count = 0;
+ for (int i = 0; i < divider; i++) {
+ for (int j = 0; j < divider; j++) {
+ vec2 lookup_position = multiplied_position + vec2(i, j);
+ if (all(greaterThanEqual(lookup_position, vec2(0, 0))) &&
+ all(lessThan(lookup_position, vec2(width, height)))) {
+ color += get_texture_at_position(lookup_position);
+ count += 1;
+ }
+ }
+ }
+ cogl_color_out = color / count;
+
+ } else
+ // mode 1: triangular downsampling
+ if (downsampling_mode == 1) {
+
+ vec4 color = vec4(0.);
+ int count = 0;
+ int force = 1;
+ for (int i = 0; i < divider; i++) {
+ for (int j = 0; j < divider; j++) {
+ vec2 lookup_position = multiplied_position + vec2(i, j);
+ if (all(greaterThanEqual(lookup_position, vec2(0, 0))) &&
+ all(lessThan(lookup_position, vec2(width, height)))) {
+ force = 1 + divider - int(abs(divider - i - j));
+ color += get_texture_at_position(lookup_position) * force;
+ count += force;
+ }
+ }
+ }
+ cogl_color_out = color / count;
+
+ } else
+ // mode 2: Dirac downsampling
+ if (downsampling_mode == 2) {
+
+ vec2 lookup_position = min(multiplied_position + vec2(divider, divider) / 2, vec2(width - 1, height - 1));
+ cogl_color_out = get_texture_at_position(lookup_position);
+
+ }
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js
new file mode 100644
index 0000000..8103486
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js
@@ -0,0 +1,140 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'downscale.glsl';
+const DEFAULT_PARAMS = {
+ divider: 8, downsampling_mode: 0, width: 0, height: 0
+};
+
+
+export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "DownscaleEffect",
+ Properties: {
+ 'divider': GObject.ParamSpec.int(
+ `divider`,
+ `Divider`,
+ `Divider`,
+ GObject.ParamFlags.READWRITE,
+ 0, 64,
+ 8,
+ ),
+ 'downsampling_mode': GObject.ParamSpec.int(
+ `downsampling_mode`,
+ `Downsampling mode`,
+ `Downsampling mode`,
+ GObject.ParamFlags.READWRITE,
+ 0, 2,
+ 0,
+ ),
+ 'width': GObject.ParamSpec.double(
+ `width`,
+ `Width`,
+ `Width`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'height': GObject.ParamSpec.double(
+ `height`,
+ `Height`,
+ `Height`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ )
+ }
+ }, class DownscaleEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get divider() {
+ return this._divider;
+ }
+
+ set divider(value) {
+ if (this._divider !== value) {
+ this._divider = value;
+
+ this.set_uniform_value('divider', this._divider);
+ }
+ }
+
+ get downsampling_mode() {
+ return this._downsampling_mode;
+ }
+
+ set downsampling_mode(value) {
+ if (this._downsampling_mode !== value) {
+ this._downsampling_mode = value;
+
+ this.set_uniform_value('downsampling_mode', this._downsampling_mode);
+ }
+ }
+
+ get width() {
+ return this._width;
+ }
+
+ set width(value) {
+ if (this._width !== value) {
+ this._width = value;
+
+ this.set_uniform_value('width', parseFloat(this._width - 1e-6));
+ }
+ }
+
+ get height() {
+ return this._height;
+ }
+
+ set height(value) {
+ if (this._height !== value) {
+ this._height = value;
+
+ this.set_uniform_value('height', parseFloat(this._height - 1e-6));
+ }
+ }
+
+ vfunc_set_actor(actor) {
+ if (this._actor_connection_size_id) {
+ let old_actor = this.get_actor();
+ old_actor?.disconnect(this._actor_connection_size_id);
+ }
+ if (actor) {
+ this.width = actor.width;
+ this.height = actor.height;
+ this._actor_connection_size_id = actor.connect('notify::size', _ => {
+ this.width = actor.width;
+ this.height = actor.height;
+ });
+ }
+ else
+ this._actor_connection_size_id = null;
+
+ super.vfunc_set_actor(actor);
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ // force setting nearest-neighbour texture filtering
+ this.get_pipeline().set_layer_filters(0, 9728, 9728);
+
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js
new file mode 100644
index 0000000..e35588d
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js
@@ -0,0 +1,362 @@
+import { NativeDynamicBlurEffect } from '../effects/native_dynamic_gaussian_blur.js';
+import { NativeStaticBlurEffect } from '../effects/native_static_gaussian_blur.js';
+import { GaussianBlurEffect } from '../effects/gaussian_blur.js';
+import { MonteCarloBlurEffect } from '../effects/monte_carlo_blur.js';
+import { ColorEffect } from '../effects/color.js';
+import { NoiseEffect } from '../effects/noise.js';
+import { CornerEffect } from '../effects/corner.js';
+import { DownscaleEffect } from './downscale.js';
+import { UpscaleEffect } from './upscale.js';
+import { PixelizeEffect } from './pixelize.js';
+import { DerivativeEffect } from './derivative.js';
+import { RgbToHslEffect } from './rgb_to_hsl.js';
+import { HslToRgbEffect } from './hsl_to_rgb.js';
+
+// We do in this way because I've not found another way to store our preferences in a dictionnary
+// while calling `gettext` on it while in preferences. Not so pretty, but works.
+export function get_effects_groups(_ = _ => "") {
+ return {
+ blur_effects: {
+ name: _("Blur effects"),
+ contains: [
+ "native_static_gaussian_blur",
+ "gaussian_blur",
+ "monte_carlo_blur"
+ ]
+ },
+ texture_effects: {
+ name: _("Texture effects"),
+ contains: [
+ "downscale",
+ "upscale",
+ "pixelize",
+ "derivative",
+ "noise",
+ "color",
+ "rgb_to_hsl",
+ "hsl_to_rgb"
+ ]
+ },
+ shape_effects: {
+ name: _("Shape effects"),
+ contains: [
+ "corner"
+ ]
+ }
+ };
+};
+
+export function get_supported_effects(_ = () => "") {
+ return {
+ native_dynamic_gaussian_blur: {
+ class: NativeDynamicBlurEffect
+ },
+
+ native_static_gaussian_blur: {
+ class: NativeStaticBlurEffect,
+ name: _("Native gaussian blur"),
+ description: _("An optimized blur effect that smoothly blends pixels within a given radius."),
+ is_advanced: false,
+ editable_params: {
+ unscaled_radius: {
+ name: _("Radius"),
+ description: _("The intensity of the blur effect."),
+ type: "float",
+ min: 0.,
+ max: 100.,
+ increment: 1.0,
+ big_increment: 10.,
+ digits: 0
+ },
+ brightness: {
+ name: _("Brightness"),
+ description: _("The brightness of the blur effect, a high value might make the text harder to read."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ }
+ },
+
+ gaussian_blur: {
+ class: GaussianBlurEffect,
+ name: _("Gaussian blur (advanced effect)"),
+ description: _("A blur effect that smoothly blends pixels within a given radius. This effect is more precise, but way less optimized."),
+ is_advanced: true,
+ editable_params: {
+ radius: {
+ name: _("Radius"),
+ description: _("The intensity of the blur effect. The bigger it is, the slower it will be."),
+ type: "float",
+ min: 0.,
+ max: 100.,
+ increment: .1,
+ big_increment: 10.,
+ digits: 1
+ },
+ brightness: {
+ name: _("Brightness"),
+ description: _("The brightness of the blur effect, a high value might make the text harder to read."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ }
+ },
+
+ monte_carlo_blur: {
+ class: MonteCarloBlurEffect,
+ name: _("Monte Carlo blur"),
+ description: _("A blur effect that mimics a random walk, by picking pixels further and further away from its origin and mixing them all together."),
+ is_advanced: false,
+ editable_params: {
+ radius: {
+ name: _("Radius"),
+ description: _("The maximum travel distance for each step in the random walk. A higher value will make the blur more randomized."),
+ type: "float",
+ min: 0.,
+ max: 10.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ iterations: {
+ name: _("Iterations"),
+ description: _("The number of iterations. The more there are, the smoother the blur is."),
+ type: "integer",
+ min: 0,
+ max: 50,
+ increment: 1
+ },
+ brightness: {
+ name: _("Brightness"),
+ description: _("The brightness of the blur effect, a high value might make the text harder to read."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ use_base_pixel: {
+ name: _("Use base pixel"),
+ description: _("Whether or not the original pixel is counted for the blur. If it is, the image will be more legible."),
+ type: "boolean"
+ },
+ prefer_closer_pixels: {
+ name: _("Prefer closer pixels"),
+ description: _("Whether or not the pixels that are closer to the original pixel will have more weight."),
+ type: "boolean"
+ }
+ }
+ },
+
+ color: {
+ class: ColorEffect,
+ name: _("Color"),
+ description: _("An effect that blends a color into the pipeline."),
+ is_advanced: false,
+ // TODO make this RGB + blend
+ editable_params: {
+ color: {
+ name: _("Color"),
+ description: _("The color to blend in. The blending amount is controled by the opacity of the color."),
+ type: "rgba"
+ },
+ blend_mode: {
+ name: _("Blend mode"),
+ description: _("How the color is blended in."),
+ type: "dropdown",
+ options: [
+ _("Normal"),
+ _("Multiply"),
+ _("Screen"),
+ _("Overlay"),
+ _("Darken"),
+ _("Lighten"),
+ _("Plus darker"),
+ _("Plus lighter"),
+ _("Color dodge"),
+ _("Color burn"),
+ _("Hard light"),
+ _("Soft light"),
+ _("Difference"),
+ _("Exclusion"),
+ _("Hue"),
+ _("Saturation"),
+ _("Color"),
+ _("Luminosity")
+ ]
+ }
+ }
+ },
+
+ pixelize: {
+ class: PixelizeEffect,
+ name: _("Pixelize"),
+ description: _("An effect that pixelizes the image."),
+ is_advanced: false,
+ editable_params: {
+ factor: {
+ name: _("Factor"),
+ description: _("How much to scale down the image."),
+ type: "integer",
+ min: 1,
+ max: 50,
+ increment: 1
+ },
+ downsampling_mode: {
+ name: _("Downsampling mode"),
+ description: _("The downsampling method that is used."),
+ type: "dropdown",
+ options: [
+ _("Boxcar"),
+ _("Triangular"),
+ _("Dirac")
+ ]
+ }
+ }
+ },
+
+ downscale: {
+ class: DownscaleEffect,
+ name: _("Downscale (advanced effect)"),
+ description: _("An effect that downscales the image and put it on the top-left corner."),
+ is_advanced: true,
+ editable_params: {
+ divider: {
+ name: _("Factor"),
+ description: _("How much to scale down the image."),
+ type: "integer",
+ min: 1,
+ max: 50,
+ increment: 1
+ },
+ downsampling_mode: {
+ name: _("Downsampling mode"),
+ description: _("The downsampling method that is used."),
+ type: "dropdown",
+ options: [
+ _("Boxcar"),
+ _("Triangular"),
+ _("Dirac")
+ ]
+ }
+ }
+ },
+
+ upscale: {
+ class: UpscaleEffect,
+ name: _("Upscale (advanced effect)"),
+ description: _("An effect that upscales the image from the top-left corner."),
+ is_advanced: true,
+ editable_params: {
+ factor: {
+ name: _("Factor"),
+ description: _("How much to scale up the image."),
+ type: "integer",
+ min: 1,
+ max: 50,
+ increment: 1
+ }
+ }
+ },
+
+ derivative: {
+ class: DerivativeEffect,
+ name: _("Derivative"),
+ description: _("Apply a spatial derivative, or a laplacian."),
+ is_advanced: false,
+ editable_params: {
+ operation: {
+ name: _("Operation"),
+ description: _("The mathematical operation to apply."),
+ type: "dropdown",
+ options: [
+ _("1-step derivative"),
+ _("2-step derivative"),
+ _("Laplacian")
+ ]
+ }
+ }
+ },
+
+ noise: {
+ class: NoiseEffect,
+ name: _("Noise"),
+ description: _("An effect that adds a random noise. Prefer the Monte Carlo blur for a more organic effect if needed."),
+ is_advanced: false,
+ editable_params: {
+ noise: {
+ name: _("Noise"),
+ description: _("The amount of noise to add."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ lightness: {
+ name: _("Lightness"),
+ description: _("The luminosity of the noise. A setting of '1.0' will make the effect transparent."),
+ type: "float",
+ min: 0.,
+ max: 2.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ }
+ }
+ },
+
+ rgb_to_hsl: {
+ class: RgbToHslEffect,
+ name: _("RGB to HSL (advanced effect)"),
+ description: _("Converts the image from RGBA colorspace to HSLA."),
+ is_advanced: true,
+ editable_params: {}
+ },
+
+ hsl_to_rgb: {
+ class: HslToRgbEffect,
+ name: _("HSL to RGB (advanced effect)"),
+ description: _("Converts the image from HSLA colorspace to RGBA."),
+ is_advanced: true,
+ editable_params: {}
+ },
+
+ corner: {
+ class: CornerEffect,
+ name: _("Corner"),
+ description: _("An effect that draws corners. Add it last not to have the other effects perturb the corners."),
+ is_advanced: false,
+ editable_params: {
+ radius: {
+ name: _("Radius"),
+ description: _("The radius of the corner. GNOME apps use a radius of 12 px by default."),
+ type: "integer",
+ min: 0,
+ max: 50,
+ increment: 1,
+ },
+ corners_top: {
+ name: _("Top corners"),
+ description: _("Whether or not to round the top corners."),
+ type: "boolean"
+ },
+ corners_bottom: {
+ name: _("Bottom corners"),
+ description: _("Whether or not to round the bottom corners."),
+ type: "boolean"
+ }
+ }
+ }
+ };
+}; \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl
new file mode 100644
index 0000000..809cc93
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl
@@ -0,0 +1,70 @@
+uniform sampler2D tex;
+uniform float sigma;
+uniform int dir;
+uniform float brightness;
+uniform float width;
+uniform float height;
+
+vec4 getTexture(vec2 uv) {
+ if (uv.x < 3. / width)
+ uv.x = 3. / width;
+
+ if (uv.y < 3. / height)
+ uv.y = 3. / height;
+
+ if (uv.x > 1. - 3. / width)
+ uv.x = 1. - 3. / width;
+
+ if (uv.y > 1. - 3. / height)
+ uv.y = 1. - 3. / height;
+
+ return texture2D(tex, uv);
+}
+
+void main(void) {
+ vec2 uv = cogl_tex_coord_in[0].xy;
+ vec2 direction = vec2(dir, (1.0 - dir));
+
+ float pixel_step;
+ if (dir == 0)
+ pixel_step = 1.0 / height;
+ else
+ pixel_step = 1.0 / width;
+
+ vec3 gauss_coefficient;
+ gauss_coefficient.x = 1.0 / (sqrt(2.0 * 3.14159265) * sigma);
+ gauss_coefficient.y = exp(-0.5 / (sigma * sigma));
+ gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y;
+
+ float gauss_coefficient_total = gauss_coefficient.x;
+
+ vec4 ret = getTexture(uv) * gauss_coefficient.x;
+ gauss_coefficient.xy *= gauss_coefficient.yz;
+
+ int n_steps = int(ceil(1.5 * sigma)) * 2;
+
+ for (int i = 1; i <= n_steps; i += 2) {
+ float coefficient_subtotal = gauss_coefficient.x;
+ gauss_coefficient.xy *= gauss_coefficient.yz;
+ coefficient_subtotal += gauss_coefficient.x;
+
+ float gauss_ratio = gauss_coefficient.x / coefficient_subtotal;
+
+ float foffset = float(i) + gauss_ratio;
+ vec2 offset = direction * foffset * pixel_step;
+
+ ret += getTexture(uv + offset) * coefficient_subtotal;
+ ret += getTexture(uv - offset) * coefficient_subtotal;
+
+ gauss_coefficient_total += 2.0 * coefficient_subtotal;
+ gauss_coefficient.xy *= gauss_coefficient.yz;
+ }
+ vec4 outColor = ret / gauss_coefficient_total;
+
+ // apply brightness on the second pass (dir==0 comes last)
+ if (dir == 0) {
+ outColor.rgb *= brightness;
+ }
+
+ cogl_color_out = outColor;
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js
new file mode 100644
index 0000000..113a6fd
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js
@@ -0,0 +1,213 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const St = await utils.import_in_shell_only('gi://St');
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'gaussian_blur.glsl';
+const DEFAULT_PARAMS = {
+ radius: 30, brightness: .6,
+ width: 0, height: 0, direction: 0, chained_effect: null
+};
+
+
+export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "GaussianBlurEffect",
+ Properties: {
+ 'radius': GObject.ParamSpec.double(
+ `radius`,
+ `Radius`,
+ `Blur radius`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 2000.0,
+ 30.0,
+ ),
+ 'brightness': GObject.ParamSpec.double(
+ `brightness`,
+ `Brightness`,
+ `Blur brightness`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.6,
+ ),
+ 'width': GObject.ParamSpec.double(
+ `width`,
+ `Width`,
+ `Width`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'height': GObject.ParamSpec.double(
+ `height`,
+ `Height`,
+ `Height`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'direction': GObject.ParamSpec.int(
+ `direction`,
+ `Direction`,
+ `Direction`,
+ GObject.ParamFlags.READWRITE,
+ 0, 1,
+ 0,
+ ),
+ 'chained_effect': GObject.ParamSpec.object(
+ `chained_effect`,
+ `Chained Effect`,
+ `Chained Effect`,
+ GObject.ParamFlags.READWRITE,
+ GObject.Object,
+ ),
+ }
+ }, class GaussianBlurEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+
+ const theme_context = St.ThemeContext.get_for_stage(global.stage);
+ theme_context.connectObject(
+ 'notify::scale-factor', _ =>
+ this.set_uniform_value('sigma',
+ parseFloat(this.radius * theme_context.scale_factor / 2 - 1e-6)
+ ),
+ this
+ );
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get radius() {
+ return this._radius;
+ }
+
+ set radius(value) {
+ if (this._radius !== value) {
+ this._radius = value;
+
+ const scale_factor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
+
+ // like Clutter, we use the assumption radius = 2*sigma
+ this.set_uniform_value('sigma', parseFloat(this._radius * scale_factor / 2 - 1e-6));
+ this.set_enabled(this.radius > 0.);
+
+ if (this.chained_effect)
+ this.chained_effect.radius = value;
+ }
+ }
+
+ get brightness() {
+ return this._brightness;
+ }
+
+ set brightness(value) {
+ if (this._brightness !== value) {
+ this._brightness = value;
+
+ this.set_uniform_value('brightness', parseFloat(this._brightness - 1e-6));
+
+ if (this.chained_effect)
+ this.chained_effect.brightness = value;
+ }
+ }
+
+ get width() {
+ return this._width;
+ }
+
+ set width(value) {
+ if (this._width !== value) {
+ this._width = value;
+
+ this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6));
+
+ if (this.chained_effect)
+ this.chained_effect.width = value;
+ }
+ }
+
+ get height() {
+ return this._height;
+ }
+
+ set height(value) {
+ if (this._height !== value) {
+ this._height = value;
+
+ this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6));
+
+ if (this.chained_effect)
+ this.chained_effect.height = value;
+ }
+ }
+
+ get direction() {
+ return this._direction;
+ }
+
+ set direction(value) {
+ if (this._direction !== value)
+ this._direction = value;
+ }
+
+ get chained_effect() {
+ return this._chained_effect;
+ }
+
+ set chained_effect(value) {
+ this._chained_effect = value;
+ }
+
+ vfunc_set_actor(actor) {
+ if (this._actor_connection_size_id) {
+ let old_actor = this.get_actor();
+ old_actor?.disconnect(this._actor_connection_size_id);
+ }
+ if (actor) {
+ this.width = actor.width;
+ this.height = actor.height;
+ this._actor_connection_size_id = actor.connect('notify::size', _ => {
+ this.width = actor.width;
+ this.height = actor.height;
+ });
+ }
+ else
+ this._actor_connection_size_id = null;
+
+ super.vfunc_set_actor(actor);
+
+ if (this.direction == 0) {
+ if (this.chained_effect)
+ this.chained_effect.get_actor()?.remove_effect(this.chained_effect);
+ else
+ this.chained_effect = new GaussianBlurEffect({
+ radius: this.radius,
+ brightness: this.brightness,
+ width: this.width,
+ height: this.height,
+ direction: 1
+ });
+ if (actor !== null)
+ actor.add_effect(this.chained_effect);
+ }
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ this.set_uniform_value("dir", this.direction);
+
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl
new file mode 100644
index 0000000..58d2694
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl
@@ -0,0 +1,14 @@
+uniform sampler2D tex;
+
+vec3 hsl_to_rgb(vec3 c) {
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+
+void main(void) {
+ vec2 uv = cogl_tex_coord_in[0].xy;
+ vec4 hsla = texture2D(tex, uv);
+ vec4 rgba = vec4(hsl_to_rgb(hsla.xyz), hsla.w);
+ cogl_color_out = rgba;
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js
new file mode 100644
index 0000000..fe53114
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js
@@ -0,0 +1,31 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'hsl_to_rgb.glsl';
+const DEFAULT_PARAMS = {};
+
+
+export const HslToRgbEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "HslToRgbEffect",
+ Properties: {}
+ }, class HslToRgbEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl
new file mode 100644
index 0000000..27b3806
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl
@@ -0,0 +1,52 @@
+uniform sampler2D tex;
+uniform float radius;
+uniform int iterations;
+uniform float brightness;
+uniform float width;
+uniform float height;
+uniform bool use_base_pixel;
+uniform bool prefer_closer_pixels;
+
+float srand(vec2 a) {
+ return sin(dot(a, vec2(1233.224, 1743.335)));
+}
+
+float rand(inout float r) {
+ r = fract(3712.65 * r + 0.61432);
+ return (r - 0.5) * 2.0;
+}
+
+void main() {
+ vec2 uv = cogl_tex_coord0_in.st;
+ vec2 p = 16 * radius / vec2(width, height);
+ float r = srand(uv);
+
+ vec2 rv;
+ vec2 dir;
+ vec2 new_uv;
+ int strength;
+
+ int count = 0;
+ vec4 c = vec4(0.);
+
+ for (int i = 0; i < iterations; i++) {
+ rv.x = rand(r);
+ rv.y = rand(r) * 3.141592;
+ dir = vec2(cos(rv.y), sin(rv.y));
+ new_uv = uv + rv.x * dir * p;
+ if (new_uv.x > 2. / width && new_uv.y > 2. / height && new_uv.x < 1. - 3. / width && new_uv.y < 1. - 3. / height) {
+ strength = prefer_closer_pixels ? (iterations - i)^2 : 1;
+ c += strength * texture2D(tex, new_uv);
+ count += strength;
+ }
+ }
+
+ if (count == 0 || use_base_pixel) {
+ strength = prefer_closer_pixels ? (iterations + 1)^2 : 1;
+ c += strength * texture2D(tex, uv);
+ count += strength;
+ }
+
+ c.xyz *= brightness;
+ cogl_color_out = c / count;
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js
new file mode 100644
index 0000000..0da56ed
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js
@@ -0,0 +1,207 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const St = await utils.import_in_shell_only('gi://St');
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'monte_carlo_blur.glsl';
+const DEFAULT_PARAMS = {
+ radius: 2., iterations: 5, brightness: .6,
+ width: 0, height: 0, use_base_pixel: true,
+ prefer_closer_pixels: true,
+};
+
+
+export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "MonteCarloBlurEffect",
+ Properties: {
+ 'radius': GObject.ParamSpec.double(
+ `radius`,
+ `Radius`,
+ `Blur radius`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 2000.0,
+ 2.0,
+ ),
+ 'iterations': GObject.ParamSpec.int(
+ `iterations`,
+ `Iterations`,
+ `Blur iterations`,
+ GObject.ParamFlags.READWRITE,
+ 0, 64,
+ 5,
+ ),
+ 'brightness': GObject.ParamSpec.double(
+ `brightness`,
+ `Brightness`,
+ `Blur brightness`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.6,
+ ),
+ 'width': GObject.ParamSpec.double(
+ `width`,
+ `Width`,
+ `Width`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'height': GObject.ParamSpec.double(
+ `height`,
+ `Height`,
+ `Height`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'use_base_pixel': GObject.ParamSpec.boolean(
+ `use_base_pixel`,
+ `Use base pixel`,
+ `Use base pixel`,
+ GObject.ParamFlags.READWRITE,
+ true,
+ ),
+ 'prefer_closer_pixels': GObject.ParamSpec.boolean(
+ `prefer_closer_pixels`,
+ `Prefer closer pixels`,
+ `Prefer closer pixels`,
+ GObject.ParamFlags.READWRITE,
+ true,
+ ),
+ }
+ }, class MonteCarloBlurEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+
+ const theme_context = St.ThemeContext.get_for_stage(global.stage);
+ theme_context.connectObject(
+ 'notify::scale-factor',
+ _ => this.set_uniform_value('radius',
+ parseFloat(this._radius * theme_context.scale_factor - 1e-6)
+ ),
+ this
+ );
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get radius() {
+ return this._radius;
+ }
+
+ set radius(value) {
+ if (this._radius !== value) {
+ this._radius = value;
+
+ const scale_factor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
+
+ this.set_uniform_value('radius', parseFloat(this._radius * scale_factor - 1e-6));
+ this.set_enabled(this.radius > 0. && this.iterations > 0);
+ }
+ }
+
+ get iterations() {
+ return this._iterations;
+ }
+
+ set iterations(value) {
+ if (this._iterations !== value) {
+ this._iterations = value;
+
+ this.set_uniform_value('iterations', this._iterations);
+ this.set_enabled(this.radius > 0. && this.iterations > 0);
+ }
+ }
+
+ get brightness() {
+ return this._brightness;
+ }
+
+ set brightness(value) {
+ if (this._brightness !== value) {
+ this._brightness = value;
+
+ this.set_uniform_value('brightness', parseFloat(this._brightness - 1e-6));
+ }
+ }
+
+ get width() {
+ return this._width;
+ }
+
+ set width(value) {
+ if (this._width !== value) {
+ this._width = value;
+
+ this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6));
+ }
+ }
+
+ get height() {
+ return this._height;
+ }
+
+ set height(value) {
+ if (this._height !== value) {
+ this._height = value;
+
+ this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6));
+ }
+ }
+
+ get use_base_pixel() {
+ return this._use_base_pixel;
+ }
+
+ set use_base_pixel(value) {
+ if (this._use_base_pixel !== value) {
+ this._use_base_pixel = value;
+
+ this.set_uniform_value('use_base_pixel', this._use_base_pixel ? 1 : 0);
+ }
+ }
+
+ get prefer_closer_pixels() {
+ return this._prefer_closer_pixels;
+ }
+
+ set prefer_closer_pixels(value) {
+ if (this._prefer_closer_pixels !== value) {
+ this._prefer_closer_pixels = value;
+
+ this.set_uniform_value('prefer_closer_pixels', this._prefer_closer_pixels ? 1 : 0);
+ }
+ }
+
+ vfunc_set_actor(actor) {
+ if (this._actor_connection_size_id) {
+ let old_actor = this.get_actor();
+ old_actor?.disconnect(this._actor_connection_size_id);
+ }
+ if (actor) {
+ this.width = actor.width;
+ this.height = actor.height;
+ this._actor_connection_size_id = actor.connect('notify::size', _ => {
+ this.width = actor.width;
+ this.height = actor.height;
+ });
+ }
+ else
+ this._actor_connection_size_id = null;
+
+ super.vfunc_set_actor(actor);
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js
new file mode 100644
index 0000000..556ffa4
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js
@@ -0,0 +1,43 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const St = await utils.import_in_shell_only('gi://St');
+const Shell = await utils.import_in_shell_only('gi://Shell');
+
+const DEFAULT_PARAMS = {
+ unscaled_radius: 30, brightness: 0.6
+};
+
+
+export const NativeDynamicBlurEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "NativeDynamicBlurEffect"
+ }, class NativeDynamicBlurEffect extends Shell.BlurEffect {
+ constructor(params) {
+ const { unscaled_radius, brightness, ...parent_params } = params;
+ super({ ...parent_params, mode: Shell.BlurMode.BACKGROUND });
+
+ this._theme_context = St.ThemeContext.get_for_stage(global.stage);
+ this._theme_context.connectObject(
+ 'notify::scale-factor',
+ _ => this.radius = this.unscaled_radius * this._theme_context.scale_factor,
+ this
+ );
+
+ utils.setup_params(this, params);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get unscaled_radius() {
+ return this._unscaled_radius;
+ }
+
+ set unscaled_radius(value) {
+ this._unscaled_radius = value;
+ this.radius = value * this._theme_context.scale_factor;
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js
new file mode 100644
index 0000000..fe003f5
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js
@@ -0,0 +1,43 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const St = await utils.import_in_shell_only('gi://St');
+const Shell = await utils.import_in_shell_only('gi://Shell');
+
+const DEFAULT_PARAMS = {
+ unscaled_radius: 30, brightness: 0.6
+};
+
+
+export const NativeStaticBlurEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "NativeStaticBlurEffect"
+ }, class NativeStaticBlurEffect extends Shell.BlurEffect {
+ constructor(params) {
+ const { unscaled_radius, brightness, ...parent_params } = params;
+ super({ ...parent_params, mode: Shell.BlurMode.ACTOR });
+
+ this._theme_context = St.ThemeContext.get_for_stage(global.stage);
+ this._theme_context.connectObject(
+ 'notify::scale-factor',
+ _ => this.radius = this.unscaled_radius * this._theme_context.scale_factor,
+ this
+ );
+
+ utils.setup_params(this, params);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get unscaled_radius() {
+ return this._unscaled_radius;
+ }
+
+ set unscaled_radius(value) {
+ this._unscaled_radius = value;
+ this.radius = value * this._theme_context.scale_factor;
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl
new file mode 100644
index 0000000..6d701b6
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl
@@ -0,0 +1,20 @@
+uniform sampler2D tex;
+uniform float noise;
+uniform float lightness;
+
+float PHI = 1.61803398874989484820459;
+float SEED = 24;
+
+float noise_gen(in vec2 xy) {
+ float r = fract(tan(distance(xy * PHI, xy) * SEED) * xy.x);
+ r = r != r ? 0.0 : r;
+ return r;
+}
+
+void main() {
+ vec4 c = texture2D(tex, cogl_tex_coord_in[0].st);
+ vec3 pix_color = c.xyz;
+ float blend = noise * (1. - noise_gen(gl_FragCoord.xy));
+
+ cogl_color_out = vec4(mix(pix_color, lightness * pix_color, blend), 1.);
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js
new file mode 100644
index 0000000..3049fa1
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js
@@ -0,0 +1,76 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'noise.glsl';
+const DEFAULT_PARAMS = {
+ noise: 0.4, lightness: 0.4
+};
+
+
+export const NoiseEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "NoiseEffect",
+ Properties: {
+ 'noise': GObject.ParamSpec.double(
+ `noise`,
+ `Noise`,
+ `Amount of noise integrated with the image`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.4,
+ ),
+ 'lightness': GObject.ParamSpec.double(
+ `lightness`,
+ `Lightness`,
+ `Lightness of the grey used for the noise`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 2.0,
+ 0.4,
+ ),
+ }
+ }, class NoiseEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get noise() {
+ return this._noise;
+ }
+
+ set noise(value) {
+ if (this._noise !== value) {
+ this._noise = value;
+
+ this.set_uniform_value('noise', parseFloat(this._noise - 1e-6));
+ this.set_enabled(this.noise > 0. && this.lightness != 1);
+ }
+ }
+
+ get lightness() {
+ return this._lightness;
+ }
+
+ set lightness(value) {
+ if (this._lightness !== value) {
+ this._lightness = value;
+
+ this.set_uniform_value('lightness', parseFloat(this._lightness - 1e-6));
+ this.set_enabled(this.noise > 0. && this.lightness != 1);
+ }
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js
new file mode 100644
index 0000000..e9cad9b
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js
@@ -0,0 +1,88 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+import { UpscaleEffect } from './upscale.js';
+import { DownscaleEffect } from './downscale.js';
+
+const DEFAULT_PARAMS = {
+ factor: 8, downsampling_mode: 0
+};
+
+
+export const PixelizeEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "PixelizeEffect",
+ Properties: {
+ 'factor': GObject.ParamSpec.int(
+ `factor`,
+ `Factor`,
+ `Factor`,
+ GObject.ParamFlags.READWRITE,
+ 0, 64,
+ 8,
+ ),
+ 'downsampling_mode': GObject.ParamSpec.int(
+ `downsampling_mode`,
+ `Downsampling mode`,
+ `Downsampling mode`,
+ GObject.ParamFlags.READWRITE,
+ 0, 2,
+ 0,
+ )
+ }
+ }, class PixelizeEffect extends Clutter.Effect {
+ constructor(params) {
+ super();
+
+ this.upscale_effect = new UpscaleEffect({});
+ this.downscale_effect = new DownscaleEffect({});
+
+ utils.setup_params(this, params);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get factor() {
+ // should be the same as `this.downscale_effect.divider`
+ return this.upscale_effect.factor;
+ }
+
+ set factor(value) {
+ this.upscale_effect.factor = value;
+ this.downscale_effect.divider = value;
+ }
+
+ get downsampling_mode() {
+ return this.downscale_effect.downsampling_mode;
+ }
+
+ set downsampling_mode(value) {
+ this.downscale_effect.downsampling_mode = value;
+ }
+
+ vfunc_set_actor(actor) {
+ // deattach effects from old actor
+ this.upscale_effect?.actor?.remove_effect(this.upscale_effect);
+ this.downscale_effect?.actor?.remove_effect(this.downscale_effect);
+ // attach effects to new actor
+ if (actor) {
+ if (this.upscale_effect)
+ actor.add_effect(this.upscale_effect);
+ if (this.downscale_effect)
+ actor.add_effect(this.downscale_effect);
+ }
+
+ super.vfunc_set_actor(actor);
+ }
+
+ vfunc_set_enabled(is_enabled) {
+ this.upscale_effect?.set_enabled(is_enabled);
+ this.downscale_effect?.set_enabled(is_enabled);
+ super.vfunc_set_enabled(is_enabled);
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl
new file mode 100644
index 0000000..b7a35ac
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl
@@ -0,0 +1,18 @@
+uniform sampler2D tex;
+
+vec3 rgb_to_hsl(vec3 c) {
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+void main(void) {
+ vec2 uv = cogl_tex_coord_in[0].xy;
+ vec4 rgba = texture2D(tex, uv);
+ vec4 hsla = vec4(rgb_to_hsl(rgba.xyz), rgba.w);
+ cogl_color_out = hsla;
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js
new file mode 100644
index 0000000..5c4eb05
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js
@@ -0,0 +1,31 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'rgb_to_hsl.glsl';
+const DEFAULT_PARAMS = {};
+
+
+export const RgbToHslEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "RgbToHslEffect",
+ Properties: {}
+ }, class RgbToHslEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+ }); \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl
new file mode 100644
index 0000000..5cc06ec
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl
@@ -0,0 +1,57 @@
+uniform sampler2D tex;
+uniform int factor;
+uniform float width;
+uniform float height;
+
+#define CORRECTION 2.25
+#define SIZE_ADDITION 3
+
+vec4 get_texture_at_position(vec2 position) {
+ vec2 raw_position = position + vec2(CORRECTION, CORRECTION);
+ vec2 raw_uv = raw_position / vec2(width + SIZE_ADDITION, height + SIZE_ADDITION);
+
+ return texture2D(tex, raw_uv);
+}
+
+ivec2 get_corrected_position() {
+ vec2 raw_uv = cogl_tex_coord0_in.st;
+ vec2 raw_position = raw_uv * vec2(width + SIZE_ADDITION, height + SIZE_ADDITION);
+ return ivec2(raw_position - vec2(CORRECTION, CORRECTION));
+}
+
+void main() {
+ ivec2 corrected_position = get_corrected_position();
+
+ vec2 adjusted_position = corrected_position / factor;
+
+ cogl_color_out = get_texture_at_position(adjusted_position);
+
+ // round
+ if (distance(corrected_position, (floor(adjusted_position) + 0.5) * factor) < factor / 2.5) {
+ //cogl_color_out = get_texture_at_position(adjusted_position);
+ } else {
+ //cogl_color_out = vec4(0, 0, 0, 1);
+ }
+
+ // square
+ if (mod(corrected_position.x, factor) >= 2 && mod(corrected_position.y, factor) >= 2) {
+ //cogl_color_out = get_texture_at_position(adjusted_position);
+ } else {
+ //cogl_color_out = vec4(0, 0, 0, 1);
+ }
+
+ // local mix
+ vec4 color = vec4(0);
+ int count = 0;
+ for (int i = -1; i <= 1; i++) {
+ for (int j = -1; j <= 1; j++) {
+ vec2 lookup_position = adjusted_position + vec2(i, j);
+ if (all(greaterThanEqual(lookup_position, vec2(0, 0))) &&
+ all(lessThan(lookup_position, vec2(width, height) / factor))) {
+ color += get_texture_at_position(lookup_position);
+ count += 1;
+ }
+ }
+ }
+ //cogl_color_out = color / count;
+} \ No newline at end of file
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js
new file mode 100644
index 0000000..fb719c3
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js
@@ -0,0 +1,120 @@
+import GObject from 'gi://GObject';
+
+import * as utils from '../conveniences/utils.js';
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const Clutter = await utils.import_in_shell_only('gi://Clutter');
+
+const SHADER_FILENAME = 'upscale.glsl';
+const DEFAULT_PARAMS = {
+ factor: 8, width: 0, height: 0
+};
+
+
+export const UpscaleEffect = utils.IS_IN_PREFERENCES ?
+ { default_params: DEFAULT_PARAMS } :
+ new GObject.registerClass({
+ GTypeName: "UpscaleEffect",
+ Properties: {
+ 'factor': GObject.ParamSpec.int(
+ `factor`,
+ `Factor`,
+ `Factor`,
+ GObject.ParamFlags.READWRITE,
+ 0, 64,
+ 8,
+ ),
+ 'width': GObject.ParamSpec.double(
+ `width`,
+ `Width`,
+ `Width`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'height': GObject.ParamSpec.double(
+ `height`,
+ `Height`,
+ `Height`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ )
+ }
+ }, class UpscaleEffect extends Clutter.ShaderEffect {
+ constructor(params) {
+ super(params);
+
+ utils.setup_params(this, params);
+
+ // set shader source
+ this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+ if (this._source)
+ this.set_shader_source(this._source);
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get factor() {
+ return this._factor;
+ }
+
+ set factor(value) {
+ if (this._factor !== value) {
+ this._factor = value;
+
+ this.set_uniform_value('factor', this._factor);
+ }
+ }
+
+ get width() {
+ return this._width;
+ }
+
+ set width(value) {
+ if (this._width !== value) {
+ this._width = value;
+
+ this.set_uniform_value('width', parseFloat(this._width - 1e-6));
+ }
+ }
+
+ get height() {
+ return this._height;
+ }
+
+ set height(value) {
+ if (this._height !== value) {
+ this._height = value;
+
+ this.set_uniform_value('height', parseFloat(this._height - 1e-6));
+ }
+ }
+
+ vfunc_set_actor(actor) {
+ if (this._actor_connection_size_id) {
+ let old_actor = this.get_actor();
+ old_actor?.disconnect(this._actor_connection_size_id);
+ }
+ if (actor) {
+ this.width = actor.width;
+ this.height = actor.height;
+ this._actor_connection_size_id = actor.connect('notify::size', _ => {
+ this.width = actor.width;
+ this.height = actor.height;
+ });
+ }
+ else
+ this._actor_connection_size_id = null;
+
+ super.vfunc_set_actor(actor);
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ // force setting nearest-neighbour texture filtering
+ this.get_pipeline().set_layer_filters(0, 9728, 9728);
+
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+ }); \ No newline at end of file