summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-gnome-theme/theme-data')
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/appfolders.js87
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/applications.js182
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/dash_to_dock.js378
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/overview.js35
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/panel.js400
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup.js1
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/blur_surface.js484
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/index.js556
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/message_stacks.js571
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/static_actor.js301
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/static_corner.js70
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_fade.js132
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js291
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_placement.js328
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_signals.js117
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_style.js59
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_transitions.js139
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/targets.js255
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/window_list.js8
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js154
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/dummy_pipeline.js49
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/effects_manager.js68
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/keys.js23
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/paint_signals.js101
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js187
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline_settings.js136
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipelines_manager.js56
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings.js180
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/shader_uniforms.js61
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js108
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/iface.xml12
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/services.js26
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl16
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js76
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl33
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js105
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl57
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js73
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl36
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js80
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effect_groups.js31
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js175
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl29
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js59
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl5
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js59
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.glsl11
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.js64
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl20
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js58
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js54
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js19
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl12
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js58
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js49
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl412
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.js849
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl5
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js59
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl26
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js78
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/extension.js132
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/popup-symbolic.svg3
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mobin17338 -> 23620 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ca/LC_MESSAGES/blur-my-shell@aunetx.mobin17426 -> 18261 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mobin17602 -> 17762 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/eo/LC_MESSAGES/blur-my-shell@aunetx.mobin367 -> 630 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mobin17198 -> 20791 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mobin17362 -> 20983 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ga/LC_MESSAGES/blur-my-shell@aunetx.mobin0 -> 1045 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/he/LC_MESSAGES/blur-my-shell@aunetx.mobin592 -> 584 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/id/LC_MESSAGES/blur-my-shell@aunetx.mobin16293 -> 19714 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ja/LC_MESSAGES/blur-my-shell@aunetx.mobin18237 -> 18553 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ml/LC_MESSAGES/blur-my-shell@aunetx.mobin523 -> 515 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/mrh/LC_MESSAGES/blur-my-shell@aunetx.mobin521 -> 513 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mobin17158 -> 17176 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt_BR/LC_MESSAGES/blur-my-shell@aunetx.mobin16986 -> 20437 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ro/LC_MESSAGES/blur-my-shell@aunetx.mobin10058 -> 10222 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mobin22226 -> 22404 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mobin28451 -> 34125 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/uk/LC_MESSAGES/blur-my-shell@aunetx.mobin21475 -> 25916 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_CN/LC_MESSAGES/blur-my-shell@aunetx.mobin15371 -> 15976 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/metadata.json33
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js5
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js4
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js36
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js7
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/popup.js121
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/prefs.js2
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/gschemas.compiledbin10240 -> 0 bytes
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml105
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/appfolders.css55
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/dash.css26
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/overview.css364
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/panel-light-text.css92
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/panel.css97
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/base.css729
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/dark.css258
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/light.css335
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/menu-items.css120
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/transparent.css262
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/stylesheet.css583
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/applications.ui19
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/dash.ui2
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/other.ui9
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/panel.ui66
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/popup.ui288
107 files changed, 10098 insertions, 1818 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/appfolders.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/appfolders.js
index 8824777..b04e39d 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/appfolders.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/appfolders.js
@@ -2,11 +2,8 @@ import Shell from 'gi://Shell';
import Clutter from 'gi://Clutter';
import Cogl from 'gi://Cogl';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
-import { adjustAnimationTime } from 'resource:///org/gnome/shell/misc/animationUtils.js';
import { PaintSignals } from '../conveniences/paint_signals.js';
-// TODO drop Tweener in favour of Clutter's `ease` (will need to extend the blur effect for it)
-const Tweener = imports.tweener.tweener;
// TODO: Drop GNOME 46 backwards compatibility
const transparent = Clutter.Color ?
@@ -30,6 +27,26 @@ let original_zoomAndFadeOut = null;
let sigma;
let brightness;
+const BLUR_RADIUS_PROPERTY = '@effects.appfolder-blur.radius';
+const BLUR_BRIGHTNESS_PROPERTY = '@effects.appfolder-blur.brightness';
+
+function stop_blur_animation(dialog) {
+ dialog.remove_transition(BLUR_RADIUS_PROPERTY);
+ dialog.remove_transition(BLUR_BRIGHTNESS_PROPERTY);
+}
+
+function animate_blur(dialog, target, mode) {
+ stop_blur_animation(dialog);
+ dialog.ease_property(BLUR_RADIUS_PROPERTY, target.radius, {
+ duration: FOLDER_DIALOG_ANIMATION_TIME,
+ mode,
+ });
+ dialog.ease_property(BLUR_BRIGHTNESS_PROPERTY, target.brightness, {
+ duration: FOLDER_DIALOG_ANIMATION_TIME,
+ mode,
+ });
+}
+
let _zoomAndFadeIn = function () {
let [sourceX, sourceY] =
this._source.get_transformed_position();
@@ -50,13 +67,10 @@ let _zoomAndFadeIn = function () {
blur_effect.radius = 0;
blur_effect.brightness = 1.0;
- Tweener.addTween(blur_effect,
- {
- radius: sigma * 2,
- brightness: brightness,
- time: adjustAnimationTime(FOLDER_DIALOG_ANIMATION_TIME / 1000),
- transition: 'easeOutQuad'
- }
+ animate_blur(
+ this,
+ { radius: sigma * 2, brightness },
+ Clutter.AnimationMode.EASE_OUT_QUAD
);
this.child.ease({
@@ -93,14 +107,10 @@ let _zoomAndFadeOut = function () {
this.set_background_color(transparent);
- let blur_effect = this.get_effect("appfolder-blur");
- Tweener.addTween(blur_effect,
- {
- radius: 0,
- brightness: 1.0,
- time: adjustAnimationTime(FOLDER_DIALOG_ANIMATION_TIME / 1000),
- transition: 'easeInQuad'
- }
+ animate_blur(
+ this,
+ { radius: 0, brightness: 1.0 },
+ Clutter.AnimationMode.EASE_IN_QUAD
);
this.child.ease({
@@ -172,15 +182,19 @@ export const AppFoldersBlur = class AppFoldersBlur {
original_zoomAndFadeOut = icon._dialog._zoomAndFadeOut;
}
- let blur_effect = new Shell.BlurEffect({
- name: "appfolder-blur",
- radius: sigma * 2,
- brightness: brightness,
- mode: Shell.BlurMode.BACKGROUND
- });
-
- icon._dialog.remove_effect_by_name("appfolder-blur");
- icon._dialog.add_effect(blur_effect);
+ let blur_effect = icon._dialog.get_effect('appfolder-blur');
+ if (!blur_effect) {
+ blur_effect = new Shell.BlurEffect({
+ name: 'appfolder-blur',
+ radius: sigma * 2,
+ brightness,
+ mode: Shell.BlurMode.BACKGROUND,
+ });
+ icon._dialog.add_effect(blur_effect);
+ } else {
+ stop_blur_animation(icon._dialog);
+ blur_effect.set({ radius: sigma * 2, brightness });
+ }
DIALOGS_STYLES.forEach(
style => icon._dialog._viewBox.remove_style_class_name(style)
@@ -218,19 +232,31 @@ export const AppFoldersBlur = class AppFoldersBlur {
set_sigma(s) {
sigma = s;
if (this.settings.appfolder.BLUR)
- this.blur_appfolders();
+ this.update_blur_effects({ radius: sigma * 2 });
}
set_brightness(b) {
brightness = b;
if (this.settings.appfolder.BLUR)
- this.blur_appfolders();
+ this.update_blur_effects({ brightness });
+ }
+
+ update_blur_effects(params) {
+ const appDisplay = Main.overview._overview.controls._appDisplay;
+ appDisplay._folderIcons.forEach(icon => {
+ if (!icon._dialog)
+ return;
+
+ stop_blur_animation(icon._dialog);
+ icon._dialog.get_effect('appfolder-blur')?.set(params);
+ });
}
disable() {
this._log("removing blur from appfolders");
let appDisplay = Main.overview._overview.controls._appDisplay;
+ this.paint_signals.disconnect_all();
if (original_zoomAndFadeIn != null) {
appDisplay._folderIcons.forEach(icon => {
@@ -248,6 +274,7 @@ export const AppFoldersBlur = class AppFoldersBlur {
appDisplay._folderIcons.forEach(icon => {
if (icon._dialog) {
+ stop_blur_animation(icon._dialog);
icon._dialog.remove_effect_by_name("appfolder-blur");
DIALOGS_STYLES.forEach(
s => icon._dialog._viewBox.remove_style_class_name(s)
@@ -262,4 +289,4 @@ export const AppFoldersBlur = class AppFoldersBlur {
if (this.settings.DEBUG)
console.log(`[Blur my Shell > appfolders] ${str}`);
}
-}; \ No newline at end of file
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/applications.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/applications.js
index 5280b55..4711a0e 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/applications.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/applications.js
@@ -145,34 +145,23 @@ export const ApplicationsBlur = class ApplicationsBlur {
/// shown on every window of the workspaces viewer.
connect_to_overview() {
this.connections.disconnect_all_for(Main.overview);
+ this.overview_visible = Main.overview.visible;
- if (this.settings.applications.BLUR_ON_OVERVIEW) {
- // when the overview is opened, show every window actors (which
- // allows the blur to be shown too)
- this.connections.connect(
- Main.overview, 'showing',
- _ => this.meta_window_map.forEach((meta_window, _pid) => {
- let window_actor = meta_window.get_compositor_private();
- window_actor?.show();
- })
- );
-
- // when the overview is closed, hide every actor that is not on the
- // current workspace (to mimic the original behaviour)
- this.connections.connect(
- Main.overview, 'hidden',
- _ => {
- this.meta_window_map.forEach((meta_window, _pid) => {
- let window_actor = meta_window.get_compositor_private();
+ const reconcile_windows = () => this.meta_window_map.forEach(
+ (meta_window, _pid) => this.reconcile_window_visibility(meta_window)
+ );
+ this.connections.connect(Main.overview, 'showing', _ => {
+ this.overview_visible = true;
+ reconcile_windows();
+ });
+ this.connections.connect(Main.overview, 'hidden', _ => {
+ this.overview_visible = false;
+ reconcile_windows();
+ });
- if (
- (!meta_window.get_workspace().active) || meta_window.minimized
- )
- window_actor.hide();
- });
- }
- );
- }
+ this.meta_window_map.forEach((meta_window, _pid) =>
+ this.reconcile_window_visibility(meta_window)
+ );
}
/// Iterate through all existing windows and add blur as needed.
@@ -239,14 +228,14 @@ export const ApplicationsBlur = class ApplicationsBlur {
if (this.settings.applications.STATIC_BLUR && meta_window.get_client_type() === Meta.WindowClientType.X11) {
const window_actor = meta_window.get_compositor_private();
- window_actor.connect('child-added', _ => {
- if (!meta_window.blur_actor) {
- this._warn("can't move blur actor to back, it doesn't exist");
- return;
- }
+ if (window_actor) {
+ this.connections.connect(window_actor, 'child-added', _ => {
+ if (!meta_window.blur_actor)
+ return;
- window_actor.set_child_below_sibling(meta_window.blur_actor, null);
- });
+ window_actor.set_child_below_sibling(meta_window.blur_actor, null);
+ });
+ }
}
}
@@ -375,19 +364,17 @@ export const ApplicationsBlur = class ApplicationsBlur {
meta_window.blur_actor = blur_actor;
- // make sure window is blurred in overview
- if (this.settings.applications.BLUR_ON_OVERVIEW)
- this.enforce_window_visibility_on_overview_for(window_actor);
+ if (!this.settings.applications.BLUR_ON_OVERVIEW && Main.overview.visible)
+ blur_actor.hide();
// update the size
this.update_size(pid);
- // set the window actor's opacity
- this.set_window_opacity(window_actor, this.settings.applications.OPACITY);
-
// update corner radius based on window state
this.update_corner_radius(meta_window);
+ this.reconcile_window_visibility(meta_window);
+
// now set up the signals, for the window actor only: they are disconnected
// in `remove_blur`, whereas the signals for the meta window are disconnected
// only when the whole component is disabled
@@ -403,15 +390,17 @@ export const ApplicationsBlur = class ApplicationsBlur {
);
this.connections.connect(
meta_window, 'notify::fullscreen',
- _ => this.update_corner_radius(meta_window)
+ _ => {
+ this.update_corner_radius(meta_window);
+ this.reconcile_window_visibility(meta_window);
+ }
);
// update the window opacity when it changes, else we don't control it fully
this.connections.connect(
window_actor, 'notify::opacity',
_ => {
- if (this.focused_window_pid != pid)
- this.set_window_opacity(window_actor, this.settings.applications.OPACITY);
+ this.reconcile_window_visibility(meta_window);
}
);
@@ -422,12 +411,7 @@ export const ApplicationsBlur = class ApplicationsBlur {
this.connections.connect(
window_actor,
'notify::visible',
- window_actor => {
- if (window_actor.visible)
- meta_window.blur_actor.show();
- else
- meta_window.blur_actor.hide();
- }
+ _ => this.reconcile_window_visibility(meta_window)
);
}
@@ -435,57 +419,18 @@ export const ApplicationsBlur = class ApplicationsBlur {
/// we are not focused anymore). It automatically removes the ancient focus.
/// With `focus=false`, just remove the focus from said window (which can still be null).
set_focus_for_window(meta_window, focus = true) {
- let blur_actor = null;
- let window_actor = null;
let new_pid = null;
if (meta_window) {
- blur_actor = meta_window.blur_actor;
- window_actor = meta_window.get_compositor_private();
new_pid = meta_window.bms_pid;
}
- if (focus) {
- // remove old focused window if any
- if (this.focused_window_pid) {
- const old_focused_window = this.meta_window_map.get(this.focused_window_pid);
- if (old_focused_window)
- this.set_focus_for_window(old_focused_window, false);
- }
- // set new focused window pid
+ if (focus)
this.focused_window_pid = new_pid;
- // if we have blur, hide it and make the window opaque
- if (this.settings.applications.DYNAMIC_OPACITY && blur_actor) {
- blur_actor.hide();
- this.set_window_opacity(window_actor, 255);
- }
- }
- // if we remove the focus and have blur, show it and make the window transparent
- else if (blur_actor) {
- blur_actor.show();
- this.set_window_opacity(window_actor, this.settings.applications.OPACITY);
- }
- }
+ else
+ this.focused_window_pid = null;
- /// Makes sure that, when the overview is visible, the window actor will
- /// stay visible no matter what.
- /// We can instead hide the last child of the window actor, which will
- /// improve performances without hiding the blur effect.
- enforce_window_visibility_on_overview_for(window_actor) {
- this.connections.connect(window_actor, 'notify::visible',
- _ => {
- if (this.settings.applications.BLUR_ON_OVERVIEW) {
- if (
- !window_actor.visible
- && Main.overview.visible
- ) {
- window_actor.show();
- window_actor.get_last_child().hide();
- } else if (
- window_actor.visible
- )
- window_actor.get_last_child().show();
- }
- }
+ this.meta_window_map.forEach((tracked_window, _pid) =>
+ this.reconcile_window_visibility(tracked_window)
);
}
@@ -504,11 +449,38 @@ export const ApplicationsBlur = class ApplicationsBlur {
})
} else {
if (meta_window.bg_manager?._bms_pipeline?.effect)
- meta_window.bg_manager._bms_pipeline.effect.corner_radius = use_0_radius ?
+ meta_window.bg_manager._bms_pipeline.effect.unscaled_corner_radius = use_0_radius ?
0 : this.settings.applications.CORNER_RADIUS;
}
}
+ reconcile_window_visibility(meta_window, overview_visible = this.overview_visible) {
+ const window_actor = meta_window.get_compositor_private();
+ const blur_actor = meta_window.blur_actor;
+ if (!window_actor || !blur_actor)
+ return;
+
+ const is_focused = this.settings.applications.DYNAMIC_OPACITY
+ && meta_window.bms_pid === this.focused_window_pid;
+ const is_fullscreen = this.settings.applications.UNBLUR_WHEN_FULLSCREEN
+ && meta_window.fullscreen;
+ const visible_for_blur = window_actor.visible
+ || (this.settings.applications.BLUR_ON_OVERVIEW && overview_visible);
+ const show_blur = visible_for_blur
+ && !is_focused
+ && !is_fullscreen
+ && (this.settings.applications.BLUR_ON_OVERVIEW || !overview_visible);
+
+ if (show_blur)
+ blur_actor.show();
+ else
+ blur_actor.hide();
+
+ this.set_window_opacity(window_actor, show_blur
+ ? this.settings.applications.OPACITY
+ : 255);
+ }
+
/// Update all corners, to use when the setting has been changed.
update_all_corner_radii() {
this.meta_window_map.forEach(
@@ -516,24 +488,30 @@ export const ApplicationsBlur = class ApplicationsBlur {
)
}
+ update_fullscreen_status() {
+ this.meta_window_map.forEach(
+ (meta_window, _pid) => this.reconcile_window_visibility(meta_window)
+ );
+ }
+
/// Set the opacity of the window actor that sits on top of the blur effect.
set_window_opacity(window_actor, opacity) {
+ // Define known blur actor names. This makes it easy to update if names change again.
+ const BLUR_ACTOR_NAMES = new Set(["blur-actor", "bms-application-blurred-widget"]);
+
window_actor?.get_children().forEach(child => {
- if (child.name !== "blur-actor" && child.opacity != opacity)
+ // Check against the Set and the opacity
+ if (!BLUR_ACTOR_NAMES.has(child.name) && child.opacity != opacity) {
child.opacity = opacity;
+ }
});
}
/// Update the opacity of all window actors.
set_opacity() {
- let opacity = this.settings.applications.OPACITY;
-
- this.meta_window_map.forEach(((meta_window, pid) => {
- if (pid != this.focused_window_pid && meta_window.blur_actor) {
- let window_actor = meta_window.get_compositor_private();
- this.set_window_opacity(window_actor, opacity);
- }
- }));
+ this.meta_window_map.forEach((meta_window, _pid) =>
+ this.reconcile_window_visibility(meta_window)
+ );
}
/// Find the system's window scaling.
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/dash_to_dock.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/dash_to_dock.js
index 4ff212c..d386722 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/dash_to_dock.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/dash_to_dock.js
@@ -3,6 +3,7 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as Signals from 'resource:///org/gnome/shell/misc/signals.js';
import { PaintSignals } from '../conveniences/paint_signals.js';
+import * as utils from '../conveniences/utils.js';
import { Pipeline } from '../conveniences/pipeline.js';
import { DummyPipeline } from '../conveniences/dummy_pipeline.js';
@@ -21,7 +22,7 @@ const DASH_STYLES = [
class DashInfos {
constructor(
dash_blur, dash, dash_container, dash_background,
- background, background_group, bg_manager
+ background, background_group, bg_manager, paint_signals
) {
// the parent DashBlur object, to communicate
this.dash_blur = dash_blur;
@@ -31,28 +32,55 @@ class DashInfos {
this.background = background;
this.background_group = background_group;
this.bg_manager = bg_manager;
+ this.paint_signals = paint_signals;
this.settings = dash_blur.settings;
- this.old_style = this.dash._background.style;
+ this.old_style = this.dash._background?.style;
+
+ this.updateId = 0;
+ this._first_boot = true;
+
+ this.bg_allocation_id = this.background_group?.connect('notify::allocation', () => {
+ this.schedule_update();
+ });
+
+ let monitor = Main.layoutManager.findMonitorForActor(this.dash_container);
+ this.current_monitor_index = monitor ? monitor.index : null;
- this.dash_destroy_id = dash.connect('destroy', () => this.remove_dash_blur(false));
+ this.dash_destroy_id = dash.connect('destroy', () => this.remove_dash_blur());
this.dash_blur_connections_ids = [];
this.dash_blur_connections_ids.push(
this.dash_blur.connect('remove-dashes', () => this.remove_dash_blur()),
this.dash_blur.connect('override-style', () => this.override_style()),
this.dash_blur.connect('remove-style', () => this.remove_style()),
- this.dash_blur.connect('show', () => this.background_group.show()),
- this.dash_blur.connect('hide', () => this.background_group.hide()),
- this.dash_blur.connect('update-size', () => this.update_size()),
+ this.dash_blur.connect('show', () => this.background_group?.show()),
+ this.dash_blur.connect('hide', () => this.background_group?.hide()),
+ this.dash_blur.connect('update-size', () => this.schedule_update()),
this.dash_blur.connect('change-blur-type', () => this.change_blur_type()),
this.dash_blur.connect('update-pipeline', () => this.update_pipeline())
);
}
+ schedule_update() {
+ this.clear_pending_idles();
+ this.updateId = global.compositor.get_laters().add(Meta.LaterType.IDLE, () => {
+ this.updateId = 0;
+ this.update_size();
+ return false;
+ });
+ }
+
+ clear_pending_idles() {
+ if (this.updateId) {
+ global.compositor.get_laters().remove(this.updateId);
+ this.updateId = 0;
+ }
+ }
+
// IMPORTANT: do never call this in a mutable `this.dash_blur.forEach`
- remove_dash_blur(dash_not_already_destroyed = true) {
+ remove_dash_blur() {
// remove the style and destroy the effects
this.remove_style();
- this.destroy_dash(dash_not_already_destroyed);
+ this.destroy_dash();
// remove the dash infos from their list
const dash_infos_index = this.dash_blur.dashes.indexOf(this);
@@ -60,6 +88,10 @@ class DashInfos {
this.dash_blur.dashes.splice(dash_infos_index, 1);
// disconnect everything
+ if (this.bg_allocation_id && this.background_group) {
+ this.background_group.disconnect(this.bg_allocation_id);
+ this.bg_allocation_id = null;
+ }
this.dash_blur_connections_ids.forEach(id => { if (id) this.dash_blur.disconnect(id); });
this.dash_blur_connections_ids = [];
if (this.dash_destroy_id)
@@ -70,36 +102,74 @@ class DashInfos {
override_style() {
this.remove_style();
- this.dash.set_style_class_name(
- DASH_STYLES[this.settings.dash_to_dock.STYLE_DASH_TO_DOCK]
- );
+ const style = DASH_STYLES[
+ this.settings.dash_to_dock.STYLE_DASH_TO_DOCK
+ ];
+
+ // Dash to Dock owns its style class list. Replacing it removes the
+ // extension's layout and border-radius rules. Add Blur My Shell's
+ // visual modifier alongside the native classes instead.
+ if (style && !this.dash.has_style_class_name(style))
+ this.dash.add_style_class_name(style);
}
remove_style() {
- this.dash._background.style = this.old_style;
+ if (this.dash?._background)
+ this.dash._background.style = this.old_style;
DASH_STYLES.forEach(
- style => this.dash.remove_style_class_name(style)
+ style => {
+ this.dash?.remove_style_class_name(style);
+ this.dash_background?.remove_style_class_name(style);
+ }
);
}
- destroy_dash(dash_not_already_destroyed = true) {
- if (!dash_not_already_destroyed)
+ destroy_dash() {
+ this.clear_pending_idles();
+
+ if (this.paint_signals)
+ this.paint_signals.disconnect_all();
+
+ if (this.background_group && this.dash) {
+ const parent = this.dash.get_parent();
+ if (parent)
+ parent.remove_child(this.background_group);
+ }
+
+ if (this.bg_manager) {
+ if (this.bg_manager._bms_pipeline) {
+ this.bg_manager._bms_pipeline.destroy();
+ this.bg_manager._bms_pipeline = null;
+ }
this.bg_manager.backgroundActor = null;
+ this.bg_manager.destroy();
+ this.bg_manager = null;
+ }
+
+ if (this.bg_allocation_id && this.background_group) {
+ this.background_group.disconnect(this.bg_allocation_id);
+ this.bg_allocation_id = null;
+ }
+
+ this._first_boot = null;
- this.paint_signals?.disconnect_all();
- this.dash.get_parent().remove_child(this.background_group);
- this.bg_manager._bms_pipeline.destroy();
- this.bg_manager.destroy();
- this.background_group.destroy();
+ if (this.background_group) {
+ this.background_group.destroy();
+ this.background_group = null;
+ }
}
change_blur_type() {
this.destroy_dash();
+ let blur_result = this.dash_blur.add_blur(this.dash, this.dash_container);
+ if (!blur_result)
+ return;
+
let [
background, background_group, bg_manager, paint_signals
- ] = this.dash_blur.add_blur(this.dash);
+ ] = blur_result;
this.background = background;
this.background_group = background_group;
@@ -108,50 +178,52 @@ class DashInfos {
this.dash.get_parent().insert_child_at_index(this.background_group, 0);
- this.update_size();
+ // Apply the layout instantly before drawing the first frame
+ this.bg_allocation_id = this.background_group.connect('notify::allocation', () => {
+ this.schedule_update();
+ });
+
+ this.schedule_update();
}
update_pipeline() {
- this.bg_manager._bms_pipeline.change_pipeline_to(
- this.settings.dash_to_dock.PIPELINE
- );
+ if (this.bg_manager?._bms_pipeline) {
+ this.bg_manager._bms_pipeline.change_pipeline_to(
+ this.settings.dash_to_dock.PIPELINE
+ );
+ }
}
update_size() {
+ if (!this.dash_blur._has_valid_allocation(this.dash_container) ||
+ !this.dash_blur._has_valid_allocation(this.dash) ||
+ !this.dash_blur._has_valid_allocation(this.dash_background))
+ return;
+
if (this.dash_blur.is_static) {
- let [x, y] = this.get_dash_position(this.dash_container, this.dash_background);
+ let monitor = Main.layoutManager.findMonitorForActor(this.dash_container);
+ if (!monitor) return;
+
+ if (this.current_monitor_index !== monitor.index) {
+ this.current_monitor_index = monitor.index;
+ this.change_blur_type();
+ return;
+ }
- this.background.x = -x;
- this.background.y = -y;
+ let dash_box = this.get_dash_position(this.dash_container);
+ if (!dash_box)
+ return;
- if (this.dash_container.get_style_class_name().includes("top"))
- this.background.set_clip(
- x,
- y + this.dash.y + this.dash_background.y,
- this.dash_background.width,
- this.dash_background.height
- );
- else if (this.dash_container.get_style_class_name().includes("bottom"))
- this.background.set_clip(
- x,
- y + this.dash.y + this.dash_background.y,
- this.dash_background.width,
- this.dash_background.height
- );
- else if (this.dash_container.get_style_class_name().includes("left"))
- this.background.set_clip(
- x + this.dash.x + this.dash_background.x,
- y + this.dash.y + this.dash_background.y,
- this.dash_background.width,
- this.dash_background.height
- );
- else if (this.dash_container.get_style_class_name().includes("right"))
- this.background.set_clip(
- x + this.dash.x + this.dash_background.x,
- y + this.dash.y + this.dash_background.y,
- this.dash_background.width,
- this.dash_background.height
- );
+ const inset = utils.static_blur_clip_inset();
+ const clip_x = Math.floor(dash_box.clip_x) - inset;
+ const clip_y = Math.floor(dash_box.clip_y) - inset;
+ const clip_w = Math.ceil(this.dash_background.width) + inset * 2;
+ const clip_h = Math.ceil(this.dash_background.height) + inset * 2;
+
+ this.background.x = dash_box.background_x + inset;
+ this.background.y = dash_box.background_y + inset;
+
+ this.background.set_clip(clip_x, clip_y, clip_w, clip_h);
} else {
this.background.width = this.dash_background.width;
this.background.height = this.dash_background.height;
@@ -159,29 +231,38 @@ class DashInfos {
this.background.x = this.dash_background.x;
this.background.y = this.dash_background.y + this.dash.y;
}
+
+ if (this._first_boot) {
+ if (this.settings.dash_to_dock.UNBLUR_IN_OVERVIEW && Main.overview.visible) {
+ this.background_group?.hide();
+ }
+ this._first_boot = false;
+ }
}
- get_dash_position(dash_container, dash_background) {
- var x, y;
+ get_dash_position(dash_container) {
+ let monitor = Main.layoutManager.findMonitorForActor(this.dash_container);
+ if (!monitor)
+ return;
- let monitor = Main.layoutManager.findMonitorForActor(dash_container);
let dash_box = dash_container._slider.get_child();
+ if (!dash_box)
+ return null;
- if (dash_container.get_style_class_name().includes("top")) {
- x = (monitor.width - dash_background.width) / 2;
- y = dash_box.y;
- } else if (dash_container.get_style_class_name().includes("bottom")) {
- x = (monitor.width - dash_background.width) / 2;
- y = monitor.height - dash_container.height;
- } else if (dash_container.get_style_class_name().includes("left")) {
- x = dash_box.x;
- y = dash_container.y + (dash_container.height - dash_background.height) / 2 - dash_background.y;
- } else if (dash_container.get_style_class_name().includes("right")) {
- x = monitor.width - dash_container.width;
- y = dash_container.y + (dash_container.height - dash_background.height) / 2 - dash_background.y;
- }
+ let parent = this.background_group?.get_parent();
+ if (!parent)
+ return;
- return [x, y];
+ let [parent_stage_x, parent_stage_y] = parent.get_transformed_position();
+ let [bg_stage_x, bg_stage_y] = this.dash_background.get_transformed_position();
+
+ let background_x = monitor.x - parent_stage_x;
+ let background_y = monitor.y - parent_stage_y;
+
+ let clip_x = bg_stage_x - monitor.x;
+ let clip_y = bg_stage_y - monitor.y;
+
+ return {background_x, background_y, clip_x, clip_y};
}
_log(str) {
@@ -234,28 +315,110 @@ export const DashBlur = class DashBlur extends Signals.EventEmitter {
}).forEach(dash_container => this.try_blur(dash_container));
}
+ _has_valid_allocation(actor) {
+ return actor &&
+ (!actor.has_allocation || actor.has_allocation()) &&
+ actor.width > 0 && actor.height > 0;
+ }
+
+ _defer_blur_until_allocated(dash_container, dash) {
+ if (dash_container._bms_pending_blur_setup)
+ return;
+
+ dash_container._bms_pending_blur_setup = true;
+
+ const connections = [];
+ const cleanup = () => {
+ delete dash_container._bms_pending_blur_setup;
+ delete dash_container._bms_defer_cleanup;
+ connections.forEach(({ actor, id }) => {
+ if (actor && id)
+ actor.disconnect(id);
+ });
+ };
+
+ const retry = () => {
+ if (!dash_container._bms_pending_blur_setup)
+ return;
+
+ let current_dash_box = dash_container._slider?.get_child();
+ let current_dash = dash || current_dash_box?.get_children().find(child => child.get_name() === 'dash');
+
+ if (!this._has_valid_allocation(dash_container) ||
+ !this._has_valid_allocation(current_dash_box) ||
+ !this._has_valid_allocation(current_dash))
+ return;
+
+ cleanup();
+ this.try_blur(dash_container);
+ };
+
+ const dash_cont_id = dash_container.connect('notify::allocation', retry);
+ connections.push({ actor: dash_container, id: dash_cont_id });
+
+ if (dash) {
+ const dash_id = dash.connect('notify::allocation', retry);
+ connections.push({ actor: dash, id: dash_id });
+ }
+
+ const destroy_id = dash_container.connect('destroy', cleanup);
+ connections.push({ actor: dash_container, id: destroy_id });
+
+ dash_container._bms_defer_cleanup = cleanup;
+ }
+
// Tries to blur the dash contained in the given actor
try_blur(dash_container) {
- let dash_box = dash_container._slider.get_child();
+ let dash_box = dash_container._slider?.get_child();
+ if (!dash_box){
+ this._defer_blur_until_allocated(dash_container);
+ return;
+ }
- // verify that we did not already blur that dash
- if (!dash_box.get_children().some(child =>
+ let dash = dash_box.get_children().find(child => {
+ return child.get_name() === 'dash';
+ });
+
+ if (!dash ||
+ !this._has_valid_allocation(dash_container) ||
+ !this._has_valid_allocation(dash_box) ||
+ !this._has_valid_allocation(dash)) {
+ this._defer_blur_until_allocated(dash_container, dash);
+ return;
+ }
+
+ let dash_exist = this.dashes.find(info => info.dash === dash);
+ if (dash_exist) {
+ dash_exist.remove_dash_blur();
+ }
+
+ let existing_bg = dash_box.get_children().find(child =>
child.get_name() === "bms-dash-backgroundgroup"
- )) {
- this._log("dash to dock found, blurring it");
+ );
- // finally blur the dash
- let dash = dash_box.get_children().find(child => {
- return child.get_name() === 'dash';
- });
+ if (existing_bg) {
+ if (dash_box.contains(existing_bg))
+ dash_box.remove_child(existing_bg);
+
+ existing_bg.destroy();
+ }
+
+ // verify that we did not already blur that dash
+ this._log("dash to dock found, blurring it");
- this.dashes.push(this.blur_dash_from(dash, dash_container));
+ let infos = this.blur_dash_from(dash, dash_container);
+ if (infos) {
+ this.dashes.push(infos);
}
}
// Blurs the dash and returns a `DashInfos` containing its information
blur_dash_from(dash, dash_container) {
- let [background, background_group, bg_manager, paint_signals] = this.add_blur(dash);
+ let blur_result = this.add_blur(dash, dash_container);
+ if (!blur_result)
+ return null;
+
+ let [background, background_group, bg_manager, paint_signals] = blur_result;
// insert the background group to the right element
dash.get_parent().insert_child_at_index(background_group, 0);
@@ -268,14 +431,32 @@ export const DashBlur = class DashBlur extends Signals.EventEmitter {
);
this.connections.connect(
dash_container,
- ['notify::width', 'notify::height', 'notify::y', 'notify::x'],
+ [
+ 'notify::width',
+ 'notify::height',
+ 'notify::y',
+ 'notify::x',
+ 'notify::style-class-name',
+ 'notify::allocation'
+ ],
_ => this.update_size()
);
- const dash_background = dash.get_children().find(child => {
- return child.get_style_class_name() === 'dash-background';
- });
+ const slider = dash_container._slider;
+ if (slider) {
+ this.connections.connect(
+ slider,
+ ['notify::slide-x', 'notify::allocation'],
+ _ => this.update_size()
+ );
+ }
+
+ const dash_background = dash._background ||
+ dash.get_children().find(child => child.has_style_class_name('dash-background')) ||
+ dash;
+ if (!dash_background)
+ return null;
// create infos
let infos = new DashInfos(
this,
@@ -289,16 +470,23 @@ export const DashBlur = class DashBlur extends Signals.EventEmitter {
);
this.update_size();
+
+ global.compositor.get_laters().add(Meta.LaterType.BEFORE_REDRAW, () => {
+ this.update_size();
+ return false;
+ });
+
this.update_background();
// returns infos
return infos;
}
- add_blur(dash) {
- const monitor = Main.layoutManager.findMonitorForActor(dash);
+ add_blur(dash, dash_container = null) {
+ const target_actor = dash_container || dash;
+ const monitor = Main.layoutManager.findMonitorForActor(target_actor) || Main.layoutManager.primaryMonitor;
if (!monitor)
- return;
+ return null;
const background_group = new Meta.BackgroundGroup({
name: 'bms-dash-backgroundgroup', width: 0, height: 0
@@ -404,6 +592,12 @@ export const DashBlur = class DashBlur extends Signals.EventEmitter {
this.emit('remove-dashes');
+ for (let child of Main.uiGroup.get_children()) {
+ if (child._bms_defer_cleanup)
+ child._bms_defer_cleanup();
+ delete child._bms_pending_blur_setup;
+ }
+
this.dashes = [];
this.connections.disconnect_all();
@@ -418,4 +612,4 @@ export const DashBlur = class DashBlur extends Signals.EventEmitter {
_warn(str) {
console.warn(`[Blur my Shell > dash manager] ${str}`);
}
-}; \ No newline at end of file
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/overview.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/overview.js
index 3bbde61..c97a459 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/overview.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/overview.js
@@ -104,13 +104,39 @@ export const OverviewBlur = class OverviewBlur {
// this hides windows that are not on the current workspace
if (
outer_this.settings.applications.BLUR
- )
+ ) {
+ // compile blacklist patterns once for this switch
+ const blacklist = outer_this.settings.applications.BLACKLIST || [];
+ const blacklist_regexes = blacklist.map(pattern => {
+ const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&');
+ return new RegExp('^' + escaped.replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
+ });
+
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()
+ window => {
+ // skip windows on all workspaces (e.g. secondary
+ // monitor windows under `workspaces-only-on-primary`);
+ // hiding them on any inactive workspace hides them globally
+ if (window.is_on_all_workspaces()) return;
+
+ // skip desktop-type windows (e.g. DING, Nautilus desktop):
+ // they should always remain visible
+ if (window.get_window_type() === Meta.WindowType.DESKTOP)
+ return;
+
+ // skip blacklisted windows:
+ // they are not blurred and should always remain visible
+ const wm_class = window.get_wm_class();
+ if (wm_class && blacklist_regexes.some(re => re.test(wm_class)))
+ return;
+
+ window.get_compositor_private().hide();
+ }
);
}
+ }
Main.uiGroup.remove_child(outer_this.animation_background_group);
};
@@ -149,14 +175,11 @@ export const OverviewBlur = class OverviewBlur {
// add the container widget for the overview only to the overview group
Main.layoutManager.overviewGroup.insert_child_at_index(this.overview_background_group, 0);
// make sure it stays below
- let _reordering = false;
this.connections.connect(Main.layoutManager.overviewGroup, "child-added", (_, child) => {
- if (!_reordering && child !== this.overview_background_group) {
- _reordering = true;
+ if (child !== this.overview_background_group) {
if (this.overview_background_group.get_parent())
Main.layoutManager.overviewGroup.remove_child(this.overview_background_group);
Main.layoutManager.overviewGroup.insert_child_at_index(this.overview_background_group, 0);
- _reordering = false;
}
});
}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/panel.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/panel.js
index bd39166..7d00224 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/panel.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/panel.js
@@ -4,6 +4,7 @@ import Meta from 'gi://Meta';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import { PaintSignals } from '../conveniences/paint_signals.js';
+import * as utils from '../conveniences/utils.js';
import { Pipeline } from '../conveniences/pipeline.js';
import { DummyPipeline } from '../conveniences/dummy_pipeline.js';
@@ -16,9 +17,10 @@ const PANEL_STYLES = [
"contrasted-panel"
];
-// global listener, so we don't miss the panel destruction event
-let isMainPanelAlive = true;
-Main.panel.connect('destroy', () => isMainPanelAlive = false);
+const GRADIENT_PANEL_STYLES = [
+ "gradient-panel",
+ "gradient-panel-reverse"
+];
export const PanelBlur = class PanelBlur {
constructor(connections, settings, effects_manager) {
@@ -27,7 +29,9 @@ export const PanelBlur = class PanelBlur {
this.settings = settings;
this.effects_manager = effects_manager;
this.actors_list = [];
+ this.queued_updates = new Set();
this.enabled = false;
+ this._first_boot = true;
}
enable() {
@@ -36,6 +40,12 @@ export const PanelBlur = class PanelBlur {
return;
}
+ // global listener, so we don't miss the panel destruction event
+ this._isMainPanelAlive = true;
+ this.connections.connect(Main.panel, 'destroy', () => {
+ this._isMainPanelAlive = false;
+ });
+
this._log("blurring top panel");
// check for panels when Dash to Panel is activated
@@ -59,6 +69,9 @@ export const PanelBlur = class PanelBlur {
this.blur_existing_panels();
+ // Hide the panel blur first to avoid the panel background from display on login
+ this.panel_hide_blur_startup();
+
// connect to overview being opened/closed, and dynamically show or not
// the blur when a window is near a panel
this.connect_to_windows_and_overview();
@@ -113,20 +126,16 @@ export const PanelBlur = class PanelBlur {
// blur already existing ones
if (global.dashToPanel.panels)
this.blur_dtp_panels();
-
- // blur main panel if requested in settings
- if (this.settings.dash_to_panel.BLUR_ORIGINAL_PANEL && isMainPanelAlive)
- this.maybe_blur_panel(Main.panel);
} else {
// if no dash-to-panel, blur the main panel
- if (isMainPanelAlive)
+ if (this._isMainPanelAlive)
this.maybe_blur_panel(Main.panel);
// blur panels already created by extension multi-monitors-bar@frederykabryan
Main.uiGroup.get_children().forEach(actor => {
if (actor.get_name() === "panelBox" && actor.get_n_children() === 1) {
let multi_monitor_panel = actor.get_child_at_index(0);
- if (isMainPanelAlive && multi_monitor_panel != Main.panel)
+ if (this._isMainPanelAlive && multi_monitor_panel != Main.panel)
this.maybe_blur_panel(multi_monitor_panel);
}
})
@@ -145,12 +154,27 @@ export const PanelBlur = class PanelBlur {
this._log("Blurring Dash to Panel panels after idle.");
- // blur every panel, except Main.panel (this is handled in blur_existing_panels() method above)
+ // blur every panel found
global.dashToPanel.panels.forEach(p => {
- if (p.panel != Main.panel)
+ if (
+ p.panel != Main.panel ||
+ this.settings.dash_to_panel.BLUR_ORIGINAL_PANEL
+ )
this.maybe_blur_panel(p.panel);
});
+ // if main panel is not included in the previous panels, blur it
+ if (
+ !global.dashToPanel.panels
+ .map(p => p.panel)
+ .includes(Main.panel)
+ &&
+ this.settings.dash_to_panel.BLUR_ORIGINAL_PANEL
+ &&
+ this._isMainPanelAlive
+ )
+ this.maybe_blur_panel(Main.panel);
+
return GLib.SOURCE_REMOVE;
});
};
@@ -169,10 +193,14 @@ export const PanelBlur = class PanelBlur {
/// Blur a panel
blur_panel(panel) {
+ let geometry_actor = panel;
+ let wrapper = null;
let panel_box = panel.get_parent();
let is_dtp_panel = false;
if (!panel_box.name) {
is_dtp_panel = true;
+ wrapper = panel_box;
+ geometry_actor = panel; // Track the inner panel dynamically
panel_box = panel_box.get_parent();
}
@@ -186,9 +214,11 @@ export const PanelBlur = class PanelBlur {
let background, bg_manager;
let static_blur = this.settings.panel.STATIC_BLUR;
+ let pipeline; // Hoist the pipeline variable so our proxy can access it
+
if (static_blur) {
let bg_manager_list = [];
- const pipeline = new Pipeline(
+ pipeline = new Pipeline(
this.effects_manager,
global.blur_my_shell._pipelines_manager,
this.settings.panel.PIPELINE
@@ -200,32 +230,55 @@ export const PanelBlur = class PanelBlur {
bg_manager = bg_manager_list[0];
}
else {
- const pipeline = new DummyPipeline(this.effects_manager, this.settings.panel);
+ pipeline = new DummyPipeline(this.effects_manager, this.settings.panel);
[background, bg_manager] = pipeline.create_background_with_effect(
background_group, 'bms-panel-blurred-widget'
);
+ }
- let paint_signals = new PaintSignals(this.connections);
+ let paint_signals = new PaintSignals(this.connections);
- // HACK
- //
- //`Shell.BlurEffect` does not repaint when shadows are under it. [1]
- //
- // This does not entirely fix this bug (shadows caused by windows
- // still cause artifacts), but it prevents the shadows of the panel
- // buttons to cause artifacts on the panel itself
- //
- // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857
+ // HACK
+ //
+ //`Shell.BlurEffect` does not repaint when shadows are under it. [1]
+ //
+ // This does not entirely fix this bug (shadows caused by windows
+ // still cause artifacts), but it prevents the shadows of the panel
+ // buttons to cause artifacts on the panel itself
+ //
+ // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857
- {
- if (this.settings.HACKS_LEVEL === 1) {
- this._log("panel hack level 1");
+ {
+ if (this.settings.HACKS_LEVEL === 1) {
+ this._log("panel hack level 1");
- paint_signals.disconnect_all();
- paint_signals.connect(background, pipeline.effect);
- } else {
- paint_signals.disconnect_all();
- }
+ // Proxy object to dynamically resolve the active blur effect.
+ // This ensures repaints continue safely even if pipeline effects are rebuilt.
+ let dynamic_target = {
+ queue_repaint: () => {
+ let active_pipeline = (bg_manager && bg_manager._bms_pipeline) ? bg_manager._bms_pipeline : pipeline;
+
+ if (static_blur && active_pipeline && active_pipeline.effects) {
+ // Repaint all effects in the static pipeline to be agnostic of the active effects
+ for (let i = 0; i < active_pipeline.effects.length; i++) {
+ let eff = active_pipeline.effects[i];
+ if (eff && typeof eff.queue_repaint === 'function') {
+ eff.queue_repaint();
+ }
+ }
+ } else if (!static_blur && active_pipeline) {
+ let eff = active_pipeline.effect; // Dynamic pipeline uses a single effect
+ if (eff && typeof eff.queue_repaint === 'function') {
+ eff.queue_repaint();
+ }
+ }
+ }
+ };
+
+ paint_signals.disconnect_all();
+ paint_signals.connect(background, dynamic_target);
+ } else {
+ paint_signals.disconnect_all();
}
}
@@ -234,75 +287,151 @@ export const PanelBlur = class PanelBlur {
// the object that is used to remembering each elements that is linked to the blur effect
let actors = {
- widgets: { panel, panel_box, background, background_group },
+ widgets: {
+ panel,
+ wrapper,
+ panel_box,
+ background,
+ background_group,
+ geometry_actor
+ },
static_blur,
monitor,
bg_manager,
is_dtp_panel
};
this.actors_list.push(actors);
+ background_group.connect('destroy', () => {
+ actors.widgets.background_group = null;
+ });
- // update the size of the actor
- this.update_size(actors);
+ // defer size update to idle to avoid allocation race
+ this.queue_update_size(actors);
- // connect to panel, panel_box and its parent position or size change
+ // connect to the relevant actors geometry changes
// this should fire update_size every time one of its params change
this.connections.connect(
- panel,
- 'notify::position',
- _ => this.update_size(actors)
+ geometry_actor,
+ ['notify::allocation', 'notify::size', 'notify::position'],
+ _ => this.queue_update_size(actors)
);
+
+ if (wrapper) {
+ this.connections.connect(
+ wrapper,
+ ['notify::allocation', 'notify::size', 'notify::position'],
+ _ => this.queue_update_size(actors)
+ );
+ }
this.connections.connect(
panel_box,
['notify::size', 'notify::position'],
- _ => this.update_size(actors)
+ _ => this.queue_update_size(actors)
);
this.connections.connect(
panel_box.get_parent(),
'notify::position',
- _ => this.update_size(actors)
+ _ => this.queue_update_size(actors)
);
// connect to the panel getting destroyed
this.connections.connect(
panel,
'destroy',
- _ => this.destroy_blur(actors, true)
+ _ => this.destroy_blur(actors)
);
}
+ queue_update_size(actors) {
+ if (this.queued_updates.has(actors))
+ return;
+
+ this.queued_updates.add(actors);
+ GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
+ this.queued_updates.delete(actors);
+
+ if (!this.enabled || !this.actors_list.includes(actors))
+ return GLib.SOURCE_REMOVE;
+
+ this.update_size(actors);
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+
update_size(actors) {
- let panel = actors.widgets.panel;
+ let geometry_actor = actors.widgets.geometry_actor;
let panel_box = actors.widgets.panel_box;
+ let wrapper = actors.widgets.wrapper;
let background = actors.widgets.background;
let [width, height] = panel_box.get_size();
+ let [geometry_width, geometry_height] = geometry_actor.get_size();
+
+ if (!width || !height || !geometry_width || !geometry_height) {
+ this.queue_update_size(actors);
+ return;
+ }
// if static blur, need to clip the background
if (actors.static_blur) {
- let monitor = Main.layoutManager.findMonitorForActor(panel);
- if (!monitor)
+ let monitor = Main.layoutManager.findMonitorForActor(geometry_actor);
+ if (!monitor) {
+ this.queue_update_size(actors);
return;
+ }
- // an alternative to panel.get_transformed_position, because it
- // sometimes yields NaN (probably when the actor is not fully
- // positionned yet)
let [p_x, p_y] = panel_box.get_position();
let [p_p_x, p_p_y] = panel_box.get_parent().get_position();
- let x = p_x + p_p_x - monitor.x + (width - panel.width) / 2;
- let y = p_y + p_p_y - monitor.y + (height - panel.height) / 2;
- background.set_clip(x, y, panel.width, panel.height);
- background.x = (width - panel.width) / 2 - x;
- background.y = .5 + (height - panel.height) / 2 - y;
+ // updated coordinates for static blur
+ let g_x, g_y;
+ if (actors.is_dtp_panel) {
+ let [w_x, w_y] = wrapper.get_position();
+ let [pan_x, pan_y] = geometry_actor.get_position();
+ g_x = w_x + pan_x;
+ g_y = w_y + pan_y;
+ } else {
+ [g_x, g_y] = geometry_actor.get_position();
+ }
+
+ let x = p_x + p_p_x - monitor.x + g_x;
+ let y = p_y + p_p_y - monitor.y + g_y;
+ let is_horizontal = geometry_width >= geometry_height;
+ let distance_to_top = Math.abs(y);
+ let distance_to_bottom = Math.abs(
+ monitor.height - (y + geometry_height)
+ );
+ let is_bottom_panel = is_horizontal &&
+ distance_to_bottom < distance_to_top;
+
+ const inset = utils.static_blur_clip_inset();
+ const offset = utils.subpixel_stage_offset();
+ const workspace_edge_inset = is_bottom_panel
+ ? Math.max(inset, 1)
+ : inset;
+ const clip_x = Math.floor(x) - inset;
+ const clip_y = Math.floor(y) - workspace_edge_inset;
+ const clip_w = Math.ceil(geometry_width) + inset * 2;
+ const clip_h = Math.ceil(geometry_height) +
+ inset + workspace_edge_inset;
+
+ background.set_clip(clip_x, clip_y, clip_w, clip_h);
+ background.x = g_x - x + inset;
+ background.y = offset + g_y - y + inset;
} else {
- background.x = panel.x;
- background.y = panel.y;
- background.width = panel.width;
- background.height = panel.height;
+ // updated coordinates for dynamic blur
+ if (actors.is_dtp_panel) {
+ background.x = wrapper.x + geometry_actor.x;
+ background.y = wrapper.y + geometry_actor.y;
+ } else {
+ background.x = geometry_actor.x;
+ background.y = geometry_actor.y;
+ }
+ background.width = geometry_width;
+ background.height = geometry_height;
}
// update the monitor panel is on
- actors.monitor = Main.layoutManager.findMonitorForActor(panel);
+ actors.monitor = Main.layoutManager.findMonitorForActor(geometry_actor);
}
/// Connect when overview if opened/closed to hide/show the blur accordingly
@@ -322,23 +451,27 @@ export const PanelBlur = class PanelBlur {
this.connections.connect(
Main.overview, 'showing', _ => this.hide()
);
+
this.connections.connect(
- Main.overview, 'hidden', _ => this.show()
+ Main.overview, 'hidden', _ => {
+ this.panel_hide_blur_dynamically();
+ this.update_visibility();
+ }
);
} else {
let appDisplay = Main.overview._overview._controls._appDisplay;
-
+
this.connections.connect(
appDisplay, 'show', _ => this.hide()
);
+
this.connections.connect(
- appDisplay, 'hide', _ => this.show()
+ appDisplay, 'hide', _ => this.update_visibility()
);
this.connections.connect(
- Main.overview, 'hidden', _ => this.show()
+ Main.overview, 'hidden', _ => this.update_visibility()
);
}
-
}
}
@@ -418,13 +551,13 @@ export const PanelBlur = class PanelBlur {
/// Update the css classname of the panel for light theme
update_light_text_classname(disable = false) {
- if (!isMainPanelAlive)
+ if (!this._isMainPanelAlive)
return;
if (this.settings.panel.FORCE_LIGHT_TEXT && !disable)
- Main.panel.add_style_class_name("panel-light-text");
+ Main.uiGroup.add_style_class_name("panel-light-text");
else
- Main.panel.remove_style_class_name("panel-light-text");
+ Main.uiGroup.remove_style_class_name("panel-light-text");
}
/// Callback when a new window is added
@@ -452,7 +585,7 @@ export const PanelBlur = class PanelBlur {
/// Update the visibility of the blur effect
update_visibility() {
if (
- isMainPanelAlive && Main.panel.has_style_pseudo_class('overview')
+ this._isMainPanelAlive && Main.panel.has_style_pseudo_class('overview')
|| !Main.sessionMode.hasWindows
) {
this.actors_list.forEach(
@@ -469,7 +602,13 @@ export const PanelBlur = class PanelBlur {
const windows = workspace.list_windows().filter(meta_window =>
meta_window.showing_on_its_workspace()
&& !meta_window.is_hidden()
- && meta_window.get_window_type() !== Meta.WindowType.DESKTOP
+ // Whitelist only standard application windows.
+ // This prevents system overlays from disabling panel blur.
+ && [
+ Meta.WindowType.NORMAL,
+ Meta.WindowType.DIALOG,
+ Meta.WindowType.MODAL_DIALOG
+ ].includes(meta_window.get_window_type())
// exclude Desktop Icons NG
&& meta_window.get_gtk_application_id() !== "com.rastersoft.ding"
&& meta_window.get_gtk_application_id() !== "com.desktop.ding"
@@ -499,10 +638,10 @@ export const PanelBlur = class PanelBlur {
// if so, and if in the same monitor, then it overlaps
if (same_monitor
&&
- // check if panel is on top
- ((panel_top === 0 && window_vertical_pos < panel_bottom + 5 * scale) ||
+ // check if panel is on top (relative to the monitor's Y origin)
+ ((panel_top === actors.monitor.y && window_vertical_pos < panel_bottom + 5 * scale) ||
// check if panel is at the bottom
- (panel_top > 0 && window_vertical_bottom > panel_top - 5 * scale))
+ (panel_top > actors.monitor.y && window_vertical_bottom > panel_top - 5 * scale))
)
window_overlap_panel = true;
});
@@ -519,22 +658,100 @@ export const PanelBlur = class PanelBlur {
set_should_override_panel(actors, should_override) {
let panel = actors.widgets.panel;
- PANEL_STYLES.forEach(style => panel.remove_style_class_name(style));
-
- if (
- this.settings.panel.OVERRIDE_BACKGROUND
- &&
- should_override
- ) {
- panel.add_style_class_name(
- PANEL_STYLES[this.settings.panel.STYLE_PANEL]
- );
+ if (this.settings.panel.OVERRIDE_BACKGROUND) {
+ if (this.settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY) {
+ if (this.settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_MODE == 0) {
+ // This is an invert of the above behavior,
+ // Blur and all styling is hidden when "should_override" is true.
+ if (!should_override) {
+ this.proximity_show(actors, panel);
+ }
+ else {
+ this.proximity_hide(actors, panel);
+ };
+ }
+ if (this.settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_MODE == 1) {
+ if (should_override) {
+ this.update_panel_style_class(panel, PANEL_STYLES[this.settings.panel.STYLE_PANEL]);
+ } else {
+ this.update_panel_style_class(panel, null); // Clear custom styles
+ }
+ }
+ }
+ else {
+ this.update_panel_style_class(panel, PANEL_STYLES[this.settings.panel.STYLE_PANEL]);
+ }
+ }
+ else {
+ this.update_panel_style_class(panel, null);
}
// update the classname if the panel to have or have not light text
this.update_light_text_classname(!should_override);
}
+ update_panel_style_class(panel, target_class) {
+ const ALL_STYLES = [...PANEL_STYLES, ...GRADIENT_PANEL_STYLES];
+
+ // Remove all managed classes EXCEPT the target class we are moving to
+ ALL_STYLES.forEach(style => {
+ if (style !== target_class) {
+ panel.remove_style_class_name(style);
+ }
+ });
+
+ // Add the target class if specified and not already present
+ if (target_class && !panel.has_style_class_name(target_class)) {
+ panel.add_style_class_name(target_class);
+ }
+ }
+
+ panel_hide_blur_dynamically() {
+ if (this.settings.panel.OVERRIDE_BACKGROUND && this.settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY) {
+ if (this.settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_MODE == 0) {
+ this.hide()
+ }
+ else {this.show()}
+ }
+ else {
+ this.show()
+ }
+ }
+
+ proximity_hide(actors, panel) {
+ let target_style = null;
+ if (this.settings.panel.GRADIENT_PANEL) {
+ if (!Main.overview.visible) {
+ target_style = GRADIENT_PANEL_STYLES[this.settings.panel.GRADIENT_PANEL_MODE];
+ }
+ else {
+ target_style = this.settings.panel.UNBLUR_IN_OVERVIEW
+ ? PANEL_STYLES[0]
+ : GRADIENT_PANEL_STYLES[this.settings.panel.GRADIENT_PANEL_MODE];
+ }
+ }
+ else {
+ target_style = PANEL_STYLES[this.settings.panel.STYLE_PANEL];
+ }
+
+ this.update_panel_style_class(panel, target_style);
+ actors.widgets.background.hide();
+ }
+
+ proximity_show(actors, panel) {
+ this.update_panel_style_class(panel, PANEL_STYLES[this.settings.panel.STYLE_PANEL]);
+ actors.widgets.background.show();
+ }
+
+ panel_hide_blur_startup(){
+ if (this._first_boot) {
+ if (this.settings.panel.UNBLUR_IN_OVERVIEW && Main.overview.visible) {
+ this.hide();
+ }
+ this._first_boot = false;
+ }
+ }
+
update_pipeline() {
this.actors_list.forEach(actors =>
actors.bg_manager._bms_pipeline.change_pipeline_to(
@@ -556,19 +773,22 @@ export const PanelBlur = class PanelBlur {
}
// IMPORTANT: do never call this in a mutable `this.actors_list.forEach`
- destroy_blur(actors, panel_already_destroyed) {
+ destroy_blur(actors) {
this.set_should_override_panel(actors, false);
- actors.bg_manager._bms_pipeline.destroy();
-
- if (panel_already_destroyed)
+ if (actors.bg_manager) {
+ if (actors.bg_manager._bms_pipeline) {
+ actors.bg_manager._bms_pipeline.destroy();
+ actors.bg_manager._bms_pipeline = null;
+ }
actors.bg_manager.backgroundActor = null;
- actors.bg_manager.destroy();
+ actors.bg_manager.destroy();
+ actors.bg_manager = null;
+ }
- if (!panel_already_destroyed) {
- actors.widgets.panel_box.remove_child(actors.widgets.background_group);
- actors.widgets.background_group.destroy_all_children();
+ if (actors.widgets && actors.widgets.background_group) {
actors.widgets.background_group.destroy();
+ actors.widgets.background_group = null;
}
let index = this.actors_list.indexOf(actors);
@@ -589,10 +809,12 @@ export const PanelBlur = class PanelBlur {
this.update_light_text_classname(true);
const immutable_actors_list = [...this.actors_list];
- immutable_actors_list.forEach(actors => this.destroy_blur(actors, false));
+ immutable_actors_list.forEach(actors => this.destroy_blur(actors));
this.actors_list = [];
+ this.queued_updates.clear();
this._dirty = true;
+ this._first_boot = null;
this.connections.disconnect_all();
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup.js
new file mode 100644
index 0000000..959b2f4
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup.js
@@ -0,0 +1 @@
+export { PopupBlur } from './popup/index.js';
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/blur_surface.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/blur_surface.js
new file mode 100644
index 0000000..8fcf82b
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/blur_surface.js
@@ -0,0 +1,484 @@
+import GLib from 'gi://GLib';
+import Meta from 'gi://Meta';
+import St from 'gi://St';
+
+import { DummyPipeline } from '../../conveniences/dummy_pipeline.js';
+import { PaintSignals } from '../../conveniences/paint_signals.js';
+import { PopupBlurSurfaceFade } from './surface_fade.js';
+import { PopupBlurSurfacePlacement } from './surface_placement.js';
+import { PopupBlurSurfaceSignals } from './surface_signals.js';
+import { PopupBlurSurfaceStyle } from './surface_style.js';
+import { PopupBlurSurfaceTransitions } from './surface_transitions.js';
+import { PopupBlurStaticActor } from './static_actor.js';
+
+const NOTIFICATION_STYLE_CLASSES = ['notification-banner'];
+const FULL_GEOMETRY_STYLE_CLASSES = [
+ 'popup-menu-content', 'candidate-popup-content',
+ 'quick-settings', 'quick-toggle-menu', 'screenshot-ui-panel',
+ 'notification-banner', 'snap-assistant',
+ 'osd-window', 'resize-popup', 'workspace-switcher',
+ 'modal-dialog', 'run-dialog',
+ 'bms-keyboard-surface',
+];
+const IS_HEAVY_SURFACE_STYLE_CLASSES = [
+ 'datemenu-popover', 'quick-settings', 'modal-dialog',
+ 'candidate-popup-content', 'candidate-popup-boxpointer',
+];
+const IS_QUICK_SETTINGS_STYLE_CLASSES = [
+ 'quick-toggle-menu', 'quick-settings', 'datemenu-popover',
+];
+
+export const PopupBlurSurface = class PopupBlurSurface {
+ constructor(connections, settings, effects_manager, target, root_actor, parent, sibling, corner_radius) {
+ this.connections = connections;
+ this.settings = settings;
+ this.effects_manager = effects_manager;
+ this.target = target;
+ this.root_actor = root_actor;
+ this.parent = parent;
+ this.sibling = sibling;
+ this.corner_radius = corner_radius;
+ this.paint_signals = new PaintSignals(connections);
+ this.placement = new PopupBlurSurfacePlacement(this);
+ this.signals = new PopupBlurSurfaceSignals(this);
+ this.style = new PopupBlurSurfaceStyle(this);
+ this.transitions = new PopupBlurSurfaceTransitions(this);
+ this.repaint_id = 0;
+ this.update_id = 0;
+ this.transition_update_id = 0;
+ this.opacity = null;
+ this.static_blur = settings.popup.STATIC_BLUR;
+ this.static_actor = null;
+ this.actor = null;
+ this.blur_actor = null;
+ }
+
+ enable() {
+ if (!this.create_actor()) {
+ if (this.static_blur)
+ this.destroy_static_actor();
+ return false;
+ }
+
+ this.fade = new PopupBlurSurfaceFade(
+ this.actor,
+ this.target,
+ this.root_actor,
+ this.parent
+ );
+ this.actor.hide();
+ this.parent.add_child(this.actor);
+ this.set_actor_position();
+ this.style.capture_target_style();
+ this.style.update_target_style();
+
+ this.connect_repaints();
+ this.signals.connect_actor(this.target);
+ this.signals.connect_actor(this.root_actor);
+ this.signals.connect_ancestors(this.target);
+ this.signals.connect_ancestors(this.root_actor);
+ if (this.style.has_any_style_class(this.target, ['screenshot-ui-panel']))
+ this.signals.connect_actor(this.parent);
+ this.signals.connect_layout();
+ this.signals.connect_settings();
+ this.queue_update();
+
+ return true;
+ }
+
+ create_actor() {
+ if (this.static_blur)
+ return this.create_static_actor();
+
+ this.blur_actor = new St.Widget({
+ name: 'bms-popup-blurred-widget',
+ reactive: false,
+ });
+ this.blur_actor.add_style_class_name('bms-popup-blurred-widget');
+ this.track_owned_actor(this.blur_actor);
+ this.pipeline = new DummyPipeline(
+ this.effects_manager,
+ this.settings.popup,
+ this.blur_actor,
+ {
+ corner_radius_key: this.corner_radius.key,
+ corner_radius_getter: () => this.get_corner_radius(),
+ }
+ );
+ this.actor = this.blur_actor;
+ return true;
+ }
+
+ create_static_actor() {
+ this.static_actor = new PopupBlurStaticActor(
+ this.settings,
+ this.effects_manager,
+ this.target,
+ this.root_actor,
+ this.parent,
+ () => this.get_corner_radius()
+ );
+ if (!this.static_actor.create())
+ return false;
+ this.sync_static_actor();
+ return true;
+ }
+
+ sync_static_actor() {
+ this.actor = this.static_actor.actor;
+ this.blur_actor = this.static_actor.blur_actor;
+ this.pipeline = this.static_actor.pipeline;
+ }
+
+ track_owned_actor(actor) {
+ this.connections.connect(actor, 'destroy', () => {
+ this.actor = null;
+ this.blur_actor = null;
+ });
+ }
+
+ set_actor_position() {
+ if (!this.is_actor_valid())
+ return;
+ const sibling = this.sibling?.get_parent() === this.parent ? this.sibling : null;
+ if (this.is_below_sibling(sibling))
+ return;
+ this.parent.set_child_below_sibling(this.actor, sibling);
+ }
+
+ is_below_sibling(sibling) {
+ const children = this.parent.get_children();
+ const actor_index = children.indexOf(this.actor);
+ if (actor_index < 0)
+ return false;
+ if (!sibling)
+ return actor_index === 0;
+ const sibling_index = children.indexOf(sibling);
+ return sibling_index >= 0 && actor_index < sibling_index;
+ }
+
+ is_quick_settings() {
+ return this.style.has_any_style_class(this.target, IS_QUICK_SETTINGS_STYLE_CLASSES)
+ || this.style.has_any_style_class(this.root_actor, IS_QUICK_SETTINGS_STYLE_CLASSES);
+ }
+
+ is_heavy_surface() {
+ return this.style.has_any_style_class(this.target, IS_HEAVY_SURFACE_STYLE_CLASSES)
+ || this.style.has_any_style_class(this.root_actor, IS_HEAVY_SURFACE_STYLE_CLASSES);
+ }
+
+ update() {
+ if (this.is_notification_surface()) {
+ this.update_live_surface();
+ return;
+ }
+ let transition_state = this.transitions.get_state();
+ let geometry = this.placement.get_surface_geometry();
+ const visible = this.is_visible();
+ const geometry_changed = this.placement.has_surface_geometry_changed(geometry);
+ if (
+ !visible
+ || !this.placement.has_valid_geometry(geometry)
+ || (!transition_state.geometry && geometry_changed)
+ )
+ transition_state = this.transitions.complete_state(transition_state);
+ if (!visible && !transition_state.running) {
+ this.hide_surface();
+ return;
+ }
+ if (!this.placement.has_valid_geometry(geometry)) {
+ if (this.placement.offscreen)
+ return this.hide_surface();
+ if (this.placement.keep_transition_visible(transition_state)) {
+ this.queue_repaint(true);
+ this.queue_transition_update(transition_state);
+ return;
+ }
+
+ if (transition_state.running) {
+ this.queue_transition_update(transition_state);
+ return;
+ }
+ this.hide_surface();
+ return;
+ }
+ this.set_actor_position();
+ if (!this.placement.update_surface_geometry(geometry))
+ return;
+ if (!this.placement.prepare_visible_geometry())
+ return;
+ const opacity = this.update_opacity(transition_state);
+ if (opacity > 0)
+ this.show_actors();
+ else
+ this.hide_actors();
+ this.queue_repaint(!visible);
+ this.queue_transition_update(transition_state);
+ }
+
+ update_live_surface() {
+ if (!this.is_visible()) {
+ this.hide_surface();
+ return;
+ }
+ this.set_actor_position();
+ const geometry = this.placement.get_unclipped_monitor_surface_geometry();
+ if (!this.placement.has_valid_geometry(geometry))
+ return this.hide_surface();
+ if (!this.placement.update_surface_geometry(geometry))
+ return;
+ if (!this.placement.prepare_visible_geometry())
+ return;
+ if (this.update_opacity() > 0)
+ this.show_actors();
+ else
+ this.hide_actors();
+ this.queue_repaint();
+ this.queue_transition_update();
+ }
+
+ hide_surface() {
+ this.opacity = 0;
+ this.update_surface_opacity(0);
+ this.hide_actors();
+ this.placement.hide();
+ }
+
+ update_opacity(transition_state = null) {
+ const opacity = this.fade.get_opacity();
+ const transition_opacity = this.get_transition_opacity(opacity, transition_state);
+ if (
+ this.opacity === transition_opacity
+ && this.has_surface_opacity(transition_opacity)
+ )
+ return transition_opacity;
+ this.update_surface_opacity(transition_opacity);
+ this.opacity = transition_opacity;
+ return transition_opacity;
+ }
+
+ get_transition_opacity(opacity, transition_state) {
+ if (
+ this.static_blur
+ || !transition_state?.geometry
+ || transition_state.opacity
+ || this.opacity <= 0
+ )
+ return opacity;
+ return Math.max(opacity, this.opacity);
+ }
+
+ has_surface_opacity(opacity) {
+ if (this.static_blur)
+ return this.static_actor.has_opacity(opacity);
+ if (!this.is_actor_valid())
+ return false;
+ return this.actor.opacity === opacity;
+ }
+
+ update_surface_opacity(opacity) {
+ const pipeline_opacity = this.get_pipeline_opacity(opacity);
+ if (this.static_blur) {
+ this.static_actor.set_opacity(opacity, pipeline_opacity);
+ return;
+ }
+ this.fade.set_opacity(opacity);
+ this.pipeline?.set_opacity_factor(pipeline_opacity / 255);
+ }
+
+ get_pipeline_opacity(opacity) {
+ if (!this.style.has_any_style_class(this.target, ['screenshot-ui-panel']))
+ return opacity;
+ return Math.round(opacity * (this.parent?.opacity ?? 255) / 255);
+ }
+
+ get_geometry_actor() {
+ return this.target;
+ }
+
+ should_use_content_geometry() {
+ return !this.uses_full_actor_geometry();
+ }
+
+ should_use_margin_geometry() {
+ return !this.uses_full_actor_geometry();
+ }
+
+ uses_full_actor_geometry() {
+ return (
+ this.style.has_any_style_class(this.target, FULL_GEOMETRY_STYLE_CLASSES)
+ || this.style.has_any_style_class(this.root_actor, FULL_GEOMETRY_STYLE_CLASSES)
+ );
+ }
+
+ is_notification_surface() {
+ return (
+ this.style.has_any_style_class(this.target, NOTIFICATION_STYLE_CLASSES)
+ || this.style.has_any_style_class(this.root_actor, NOTIFICATION_STYLE_CLASSES)
+ );
+ }
+
+ show_actors() {
+ if (this.is_actor_valid())
+ this.actor?.show();
+ }
+
+ hide_actors() {
+ if (this.is_actor_valid())
+ this.actor?.hide();
+ }
+
+ is_actor_valid() {
+ return (
+ !!this.actor
+ && (!this.static_blur || !!this.static_actor?.background_group)
+ );
+ }
+
+ queue_update() {
+ if (!this.actor || this.update_id || this.transition_update_id)
+ return;
+ this.update_id = global.compositor.get_laters().add(
+ Meta.LaterType.BEFORE_REDRAW,
+ () => {
+ this.update_id = 0;
+ if (this.actor)
+ this.update();
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+ }
+
+ queue_transition_update(transition_state = null) {
+ const has_running_transition = transition_state?.running ?? this.transitions.has_running();
+ if (!this.actor || this.transition_update_id || this.update_id || !has_running_transition)
+ return;
+ this.transition_update_id = global.compositor.get_laters().add(
+ Meta.LaterType.BEFORE_REDRAW,
+ () => {
+ this.transition_update_id = 0;
+ if (this.actor)
+ this.update();
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+ }
+
+ connect_repaints() {
+ if (this.static_blur || this.settings.HACKS_LEVEL !== 1)
+ return;
+ const repaint_source = {
+ queue_repaint: () => this.queue_repaint(),
+ };
+ [
+ this.blur_actor,
+ this.target,
+ ].forEach(actor => {
+ this.paint_signals.disconnect_all_for_actor(actor);
+ this.paint_signals.connect(actor, repaint_source);
+ });
+ }
+
+ update_settings() {
+ this.style.update_target_style();
+ this.static_actor?.update_settings();
+ }
+
+ get_corner_radius() {
+ return this.settings.popup[this.corner_radius.property] ?? this.settings.popup.CORNER_RADIUS;
+ }
+
+ queue_repaint(force = false) {
+ if (this.static_blur || this.repaint_id || (!force && !this.should_repaint()))
+ return;
+ this.repaint_id = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
+ this.repaint_id = 0;
+ if (force || this.should_repaint())
+ this.pipeline?.repaint_effect();
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+
+ should_repaint() {
+ return this.is_visible();
+ }
+
+ is_visible() {
+ return this.is_actor_visible(this.target) && this.is_actor_visible(this.root_actor);
+ }
+
+ is_keyboard_surface() {
+ return (
+ this.style.has_style_class(this.target, 'bms-keyboard-surface')
+ || this.style.has_style_class(this.root_actor, 'bms-keyboard-surface')
+ );
+ }
+
+ is_actor_visible(actor) {
+ if (!actor)
+ return false;
+ if (actor.visible && actor.mapped)
+ return true;
+ if (!this.is_keyboard_surface())
+ return false;
+
+ const parent = actor.get_parent();
+ return parent?.visible && parent?.mapped;
+ }
+
+ update_pipeline() {
+ if (this.static_blur) {
+ this.static_actor.update_pipeline();
+ this.sync_static_actor();
+ }
+ }
+
+ destroy() {
+ if (this.update_id) {
+ global.compositor.get_laters().remove(this.update_id);
+ this.update_id = 0;
+ }
+ if (this.transition_update_id) {
+ global.compositor.get_laters().remove(this.transition_update_id);
+ this.transition_update_id = 0;
+ }
+ if (this.repaint_id) {
+ GLib.Source.remove(this.repaint_id);
+ this.repaint_id = 0;
+ }
+
+ this.signals.disconnect_all();
+ this.paint_signals.disconnect_all_for_actor(this.blur_actor);
+ this.paint_signals.disconnect_all_for_actor(this.target);
+ this.style.restore_target_style();
+
+ if (this.static_blur)
+ this.destroy_static_actor();
+ else
+ this.destroy_dynamic_actor();
+
+ this.fade = null;
+ }
+
+ destroy_dynamic_actor() {
+ const pipeline = this.pipeline;
+ const blur_actor = this.blur_actor;
+ this.pipeline = null;
+ this.blur_actor = null;
+ this.actor = null;
+ if (pipeline)
+ pipeline.destroy();
+ if (blur_actor)
+ blur_actor.destroy();
+ }
+
+ destroy_static_actor() {
+ if (this.static_actor)
+ this.static_actor.destroy();
+ this.static_actor = null;
+ this.actor = null;
+ this.blur_actor = null;
+ this.pipeline = null;
+ this.placement.clear();
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/index.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/index.js
new file mode 100644
index 0000000..edc9369
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/index.js
@@ -0,0 +1,556 @@
+import GLib from 'gi://GLib';
+import Gio from 'gi://Gio';
+import Meta from 'gi://Meta';
+import St from 'gi://St';
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+
+import {
+ POPUP_BACKGROUND_STYLES,
+ POPUP_SURFACE_STYLES,
+ PopupBlurTargets,
+} from './targets.js';
+import { PopupBlurSurface } from './blur_surface.js';
+import { PopupBlurMessageStacks } from './message_stacks.js';
+
+const POPUP_INTERNAL_STYLE_CLASSES = ['bms-popup-blurred-widget', 'bms-popup-backgroundgroup'];
+const POPUP_INTERNAL_NAMES = ['bms-popup-blurred-widget', 'bms-popup-backgroundgroup'];
+const KEYBOARD_STYLE_CLASS = 'bms-keyboard-surface';
+
+export const PopupBlur = class PopupBlur {
+ constructor(connections, settings, effects_manager) {
+ this.connections = connections;
+ this.settings = settings;
+ this.effects_manager = effects_manager;
+ this.surfaces = new Map();
+ this.containers = new Set();
+ this.queued_actors = new Set();
+ this.watched_actors = new WeakSet();
+ this.destroyed_actors = new WeakSet();
+ this.interface_settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
+ this.message_stacks = new PopupBlurMessageStacks(connections);
+ this.targets = new PopupBlurTargets(this);
+ this.queue_id = 0;
+ this.follow_up_queue_id = 0;
+ this.follow_up_actors = new Set();
+ this.reset_id = 0;
+ this.enabled = false;
+ }
+
+ enable() {
+ if (this.enabled) {
+ this._log("blur already enabled");
+ return;
+ }
+
+ this._log("blurring popup surfaces");
+ this.enabled = true;
+
+ this.update_background();
+ this.message_stacks.enable();
+ this.connections.connect(
+ this.interface_settings,
+ 'changed::color-scheme',
+ () => this.update_background()
+ );
+ this.connections.connect(
+ this.interface_settings,
+ 'changed::gtk-theme',
+ () => this.update_background()
+ );
+ this.connections.connect(
+ Main.sessionMode,
+ 'updated',
+ () => this.update_background()
+ );
+ this.connections.connect(
+ St.Settings.get(),
+ 'notify::color-scheme',
+ () => this.update_background()
+ );
+
+ this.track_container(Main.uiGroup);
+ (Main.osdWindowManager?._osdWindows ?? []).forEach(window => this.track_container(window));
+ this.track_container(Main.layoutManager?.modalDialogGroup);
+ this.track_container(Main.layoutManager?.screenShieldGroup);
+ this.track_container(Main.layoutManager?.unlockDialogGroup);
+ this.track_container(Main.messageTray?._bannerBin);
+ this.track_quick_settings();
+ this.track_container(global.window_group);
+ this.track_keyboard();
+ this.track_container(Main.keyboard?.keyboardActor);
+ }
+
+ track_container(container) {
+ if (!container || this.containers.has(container))
+ return;
+ if (!this.watch_actor(container))
+ return;
+
+ this.containers.add(container);
+ this.message_stacks.track_container(container);
+
+ this.get_children(container).forEach(child => this.try_blur(child));
+
+ this.connections.connect(
+ container,
+ 'child-added',
+ (_, child) => this.queue_try_blur(child)
+ );
+ }
+
+ track_quick_settings() {
+ const menu = Main.panel?.statusArea?.quickSettings?.menu;
+ this.track_container(menu?._overlay);
+ }
+
+ track_keyboard() {
+ const keyboard_box = Main.layoutManager?.keyboardBox;
+ this.track_container(keyboard_box);
+ if (!keyboard_box)
+ return;
+
+ this.connections.connect(
+ keyboard_box,
+ 'child-added',
+ (_, child) => this.update_keyboard_style(child)
+ );
+ }
+
+ try_blur(actor) {
+ if (this.is_internal_actor(actor) || !this.watch_actor(actor))
+ return;
+
+ this.message_stacks.scan(actor);
+ this.track_container(this.get_actor_overlay(actor));
+
+ const targets = this.get_blur_targets(actor);
+
+ if (this.targets.is_blur_target_actor(actor))
+ this.track_container(actor);
+
+ if (this.has_style_class(actor, 'switcher-popup'))
+ this.track_container(actor);
+
+ if (this.is_window_actor(actor))
+ this.track_container(actor);
+
+ targets.forEach(target => this.blur_actor(target, actor));
+ }
+
+ queue_try_blur(actor) {
+ if (this.is_internal_actor(actor) || !this.watch_actor(actor))
+ return;
+
+ this.queued_actors.add(actor);
+ if (this.queue_id)
+ return;
+
+ this.queue_id = global.compositor.get_laters().add(Meta.LaterType.BEFORE_REDRAW, () => {
+ this.queue_id = 0;
+ const actors = [...this.queued_actors];
+ this.queued_actors.clear();
+
+ this.try_blur_actors(actors);
+ this.queue_follow_up_blurs(actors);
+
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+
+ queue_follow_up_blurs(actors) {
+ actors.forEach(actor => this.follow_up_actors.add(actor));
+
+ if (this.follow_up_queue_id || this.follow_up_actors.size === 0)
+ return;
+
+ this.follow_up_queue_id = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
+ this.follow_up_queue_id = 0;
+ const actors = [...this.follow_up_actors];
+ this.follow_up_actors.clear();
+
+ this.try_blur_actors(actors);
+
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+
+ try_blur_actors(actors) {
+ if (!this.enabled)
+ return;
+
+ actors.forEach(actor => {
+ if (!this.destroyed_actors.has(actor) && !this.is_internal_actor(actor))
+ this.try_blur(actor);
+ });
+ }
+
+ cancel_queued_blurs() {
+ if (this.queue_id) {
+ global.compositor.get_laters().remove(this.queue_id);
+ this.queue_id = 0;
+ }
+ if (this.follow_up_queue_id) {
+ GLib.source_remove(this.follow_up_queue_id);
+ this.follow_up_queue_id = 0;
+ }
+ this.queued_actors.clear();
+ this.follow_up_actors.clear();
+ }
+
+ blur_actor(target, root_actor) {
+ if (
+ this.is_internal_actor(target)
+ || this.is_internal_actor(root_actor)
+ || !this.watch_actor(target)
+ || !this.watch_actor(root_actor)
+ )
+ return;
+
+ if (this.surfaces.has(target))
+ return;
+
+ this.destroy_blurred_ancestors(target);
+
+ const { parent, sibling } = this.get_overlay_parent(root_actor, target);
+ const surface = new PopupBlurSurface(
+ this.connections,
+ this.settings,
+ this.effects_manager,
+ target,
+ root_actor,
+ parent,
+ sibling,
+ this.get_corner_radius(target, root_actor),
+ () => this.enabled && this.surfaces.has(target)
+ );
+
+ this.surfaces.set(target, surface);
+
+ if (surface.enable())
+ return this.connect_surface(target, root_actor);
+
+ this.surfaces.delete(target);
+ surface.destroy();
+ }
+
+ connect_surface(target, root_actor) {
+ this.connections.connect(
+ target,
+ 'destroy',
+ () => this.destroy_blur(target)
+ );
+
+ if (root_actor !== target) {
+ this.connections.connect(
+ root_actor,
+ 'destroy',
+ () => this.destroy_blur(target)
+ );
+ }
+ }
+
+ destroy_blurred_ancestors(actor) {
+ actor = actor ? actor.get_parent() : null;
+
+ while (actor && !this.destroyed_actors.has(actor)) {
+ if (this.surfaces.has(actor) && this.targets.prefers_descendant_targets(actor)) {
+ this.destroy_blur(actor);
+ }
+
+ actor = actor.get_parent();
+ }
+ }
+
+ get_overlay_parent(root_actor, target) {
+ if (this.has_any_style_class(target, ['screenshot-ui-panel'])) {
+ const parent = Main.screenshotUI ?? Main.uiGroup;
+ let sibling = target;
+ while (sibling && sibling.get_parent() && sibling.get_parent() !== parent) {
+ sibling = sibling.get_parent();
+ }
+ return {
+ parent,
+ sibling: sibling ?? target,
+ };
+ }
+
+ let actor = root_actor;
+ let child = null;
+ while (actor && !this.destroyed_actors.has(actor)) {
+ let parent = null;
+ parent = actor.get_parent();
+
+ if (!parent)
+ break;
+
+ if (parent === Main.layoutManager.unlockDialogGroup ||
+ parent === Main.layoutManager.screenShieldGroup ||
+ parent === Main.uiGroup ||
+ parent === Main.layoutManager.uiGroup)
+ return { parent, sibling: actor };
+
+ if (parent === global.window_group)
+ return { parent: actor, sibling: child ?? actor.get_last_child() };
+
+ child = actor;
+ actor = parent;
+ }
+
+ return { parent: Main.uiGroup, sibling: null };
+ }
+
+ get_corner_radius(target, root_actor) {
+ return this.targets.get_corner_radius(target, root_actor);
+ }
+
+ get_blur_targets(actor) {
+ return this.targets.find(actor);
+ }
+
+ has_any_style_class(actor, style_classes) {
+ if (!actor || this.destroyed_actors.has(actor))
+ return false;
+
+ if (actor.get_style_class_name) {
+ const class_names = actor.get_style_class_name();
+ if (typeof class_names === 'string') {
+ const normalized = ` ${class_names.trim().replace(/\s+/g, ' ')} `;
+ return style_classes.some(style_class => normalized.includes(` ${style_class} `));
+ }
+ }
+
+ return style_classes.some(style => this.has_style_class(actor, style));
+ }
+
+ has_style_class(actor, style_class) {
+ if (!actor || this.destroyed_actors.has(actor))
+ return false;
+
+ if (actor.has_style_class_name)
+ return actor.has_style_class_name(style_class);
+
+ if (actor.get_style_class_name)
+ return (actor.get_style_class_name() ?? '').split(/\s+/).includes(style_class);
+
+ return false;
+ }
+
+ is_window_actor(actor) {
+ if (!actor || this.destroyed_actors.has(actor))
+ return false;
+ return actor.get_parent() === global.window_group;
+ }
+
+ is_internal_actor(actor) {
+ if (!actor)
+ return false;
+
+ if (this.has_any_style_class(actor, POPUP_INTERNAL_STYLE_CLASSES))
+ return true;
+
+ if (this.destroyed_actors.has(actor))
+ return false;
+
+ return POPUP_INTERNAL_NAMES.includes(actor.name ?? actor.get_name());
+ }
+
+ watch_actor(actor) {
+ if (!actor || this.destroyed_actors.has(actor))
+ return false;
+ if (this.watched_actors.has(actor))
+ return true;
+
+ this.connections.connect(actor, 'destroy', () => {
+ this.destroyed_actors.add(actor);
+ this.containers.delete(actor);
+ });
+
+ this.watched_actors.add(actor);
+ return true;
+ }
+
+ get_children(actor) {
+ if (!this.watch_actor(actor))
+ return [];
+
+ return actor.get_children();
+ }
+
+ get_actor_delegate(actor) {
+ if (!this.watch_actor(actor))
+ return null;
+
+ return actor._delegate || null;
+ }
+
+ get_actor_overlay(actor) {
+ const delegate = this.get_actor_delegate(actor);
+ return (delegate && delegate._overlay) || null;
+ }
+
+ get_actor_dialog_layout(actor) {
+ if (!this.watch_actor(actor))
+ return null;
+
+ return actor.dialogLayout || null;
+ }
+
+ destroy_blur(actor) {
+ const surface = this.surfaces.get(actor);
+ if (!surface)
+ return;
+
+ this.surfaces.delete(actor);
+ surface.destroy();
+ }
+
+ reset() {
+ if (!this.enabled)
+ return;
+
+ this.cancel_queued_blurs();
+
+ this.disable();
+ this.reset_id = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
+ this.reset_id = 0;
+
+ if (this.settings.popup.BLUR)
+ this.enable();
+
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+
+ update_pipeline() {
+ this.surfaces.forEach(surface => surface.update_pipeline());
+ }
+
+ _get_keyboard_actors() {
+ const actors = new Set();
+ if (Main.keyboard && Main.keyboard.keyboardActor)
+ actors.add(Main.keyboard.keyboardActor);
+ if (Main.keyboard && Main.keyboard._keyboard)
+ actors.add(Main.keyboard._keyboard);
+ if (Main.layoutManager.keyboardBox)
+ Main.layoutManager.keyboardBox.get_children().forEach(child => actors.add(child));
+ return [...actors];
+ }
+
+ update_background() {
+ [...POPUP_BACKGROUND_STYLES, ...POPUP_SURFACE_STYLES]
+ .forEach(style => Main.uiGroup.remove_style_class_name(style));
+
+ const keyboard_actors = this._get_keyboard_actors();
+ keyboard_actors.forEach(actor => this.clear_keyboard_style(actor));
+ [...POPUP_BACKGROUND_STYLES, ...POPUP_SURFACE_STYLES]
+ .forEach(style => keyboard_actors.forEach(actor => actor.remove_style_class_name(style)));
+
+ let background_style = null;
+ if (this.settings.popup.OVERRIDE_BACKGROUND) {
+ const style = this.get_background_style();
+ background_style = this.settings.popup.PRESERVE_SHELL_THEME ?
+ POPUP_SURFACE_STYLES[style] :
+ POPUP_BACKGROUND_STYLES[style];
+ Main.uiGroup.add_style_class_name(
+ background_style
+ );
+ }
+ keyboard_actors.forEach(actor => this.update_keyboard_style(actor, background_style));
+ this.surfaces.forEach(surface => surface.update_settings());
+ }
+
+ clear_keyboard_style(actor, remove_marker = false) {
+ if (!actor)
+ return;
+
+ if (remove_marker)
+ actor.remove_style_class_name(KEYBOARD_STYLE_CLASS);
+
+ if (!this.settings.popup.OVERRIDE_BACKGROUND)
+ return;
+
+ [...POPUP_BACKGROUND_STYLES, ...POPUP_SURFACE_STYLES]
+ .forEach(style => actor.remove_style_class_name(style));
+ }
+
+ update_keyboard_style(actor, background_style = null) {
+ if (!actor)
+ return;
+
+ this.clear_keyboard_style(actor);
+ actor.add_style_class_name(KEYBOARD_STYLE_CLASS);
+ if (!this.settings.popup.OVERRIDE_BACKGROUND)
+ return;
+
+ const style = background_style ?? (
+ this.settings.popup.PRESERVE_SHELL_THEME ?
+ POPUP_SURFACE_STYLES[this.get_background_style()] :
+ POPUP_BACKGROUND_STYLES[this.get_background_style()]
+ );
+ actor.add_style_class_name(style);
+ }
+
+ get_background_style() {
+ const style = this.settings.popup.STYLE_POPUP;
+
+ if (style >= 0 && style < POPUP_BACKGROUND_STYLES.length)
+ return style;
+
+ const theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
+ let uri = theme?.default_stylesheet?.get_uri();
+ if (theme?.application_stylesheet)
+ uri = theme?.application_stylesheet?.get_uri();
+ const lower_uri = typeof uri === 'string' ? uri.toLowerCase() : '';
+ if (lower_uri.includes('yaru'))
+ return lower_uri.includes('dark') ? 2 : 1;
+
+ const shell_style = Main.getStyleVariant();
+ if (shell_style === 'light')
+ return 1;
+
+ if (shell_style === 'dark')
+ return 2;
+
+ return this.interface_settings.get_string('color-scheme') === 'prefer-dark' ? 2 : 1;
+ }
+
+ disable() {
+ if (this.reset_id) {
+ GLib.source_remove(this.reset_id);
+ this.reset_id = 0;
+ }
+
+ this.cancel_queued_blurs();
+
+ if (!this.enabled) {
+ this._log("blur already removed");
+ return;
+ }
+
+ this._log("removing blur from popup surfaces");
+ this.enabled = false;
+
+ const keyboard_actors = this._get_keyboard_actors();
+ keyboard_actors.forEach(actor => this.clear_keyboard_style(actor, true));
+ [...POPUP_BACKGROUND_STYLES, ...POPUP_SURFACE_STYLES]
+ .forEach(style => keyboard_actors.forEach(actor => actor.remove_style_class_name(style)));
+
+ [...POPUP_BACKGROUND_STYLES, ...POPUP_SURFACE_STYLES]
+ .forEach(style => Main.uiGroup.remove_style_class_name(style));
+
+ const actors = [...this.surfaces.keys()];
+ actors.forEach(actor => this.destroy_blur(actor));
+ this.surfaces.clear();
+ this.containers.clear();
+ this.watched_actors = new WeakSet();
+ this.destroyed_actors = new WeakSet();
+ this.message_stacks.disable();
+
+ this.connections.disconnect_all();
+ }
+
+ _log(str) {
+ if (this.settings.DEBUG)
+ console.log(`[Blur my Shell > popup blur] ${str}`);
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/message_stacks.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/message_stacks.js
new file mode 100644
index 0000000..cc4af30
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/message_stacks.js
@@ -0,0 +1,571 @@
+import GLib from 'gi://GLib';
+
+const STACKED_PSEUDO_CLASSES = ['second-in-stack', 'lower-in-stack'];
+const MESSAGE_CONTAINER_STYLE_CLASSES = ['message-list', 'message-view', 'message-notification-group'];
+const INTERNAL_STYLE_CLASSES = ['bms-popup-blurred-widget', 'bms-popup-backgroundgroup'];
+const INTERNAL_NAMES = ['bms-popup-blurred-widget', 'bms-popup-backgroundgroup'];
+
+export const PopupBlurMessageStacks = class PopupBlurMessageStacks {
+ constructor(connections) {
+ this.connections = connections;
+ this.containers = new Set();
+ this.groups = new Set();
+ this.messages = new Set();
+ this.queued_actors = new WeakSet();
+ this.watched_actors = new WeakSet();
+ this.destroyed_actors = new WeakSet();
+ this.bms_clipped = new WeakSet();
+ this.group_connections = new Map();
+ this.update_ids = new Map();
+ this.original_opacity = new WeakMap();
+ this.original_message_opacity = new WeakMap();
+ this.enabled = false;
+ }
+
+ enable() {
+ this.enabled = true;
+ }
+
+ track_container(container) {
+ if (!container || this.containers.has(container))
+ return;
+ if (!this.watch_actor(container))
+ return;
+
+ this.containers.add(container);
+ this.scan(container);
+
+ this.connect(
+ container,
+ 'child-added',
+ (_, child) => {
+ this.queue_scan(child);
+ this.queue_update_all();
+ }
+ );
+
+ this.connect(
+ container,
+ 'child-removed',
+ () => this.queue_update_all()
+ );
+ }
+
+ queue_scan(actor) {
+ if (this.is_internal_actor(actor) || !this.watch_actor(actor) || this.queued_actors.has(actor))
+ return;
+
+ this.queued_actors.add(actor);
+ this.scan(actor);
+ this.queued_actors.delete(actor);
+ }
+
+ scan(actor, seen = new WeakSet()) {
+ if (this.is_internal_actor(actor) || !this.watch_actor(actor) || seen.has(actor))
+ return;
+
+ seen.add(actor);
+
+ if (this.has_any_style_class(actor, MESSAGE_CONTAINER_STYLE_CLASSES))
+ this.track_container(actor);
+
+ if (this.has_style_class(actor, 'message-notification-group'))
+ this.track_group(actor);
+
+ if (this.has_style_class(actor, 'message'))
+ this.track_message(actor);
+
+ this.get_children(actor).forEach(child => this.scan(child, seen));
+
+ const child = this.get_child(actor);
+ if (child)
+ this.scan(child, seen);
+ }
+
+ track_message(message) {
+ if (this.is_internal_actor(message) || !this.watch_actor(message) || this.messages.has(message))
+ return;
+
+ this.messages.add(message);
+ this.update_message(message);
+
+ this.connect(
+ message,
+ 'style-changed',
+ () => this.queue_update_message(message)
+ );
+
+ this.connect(
+ message,
+ 'notify::pseudo-class',
+ () => this.queue_update_message(message)
+ );
+
+ this.connect(
+ message,
+ 'notify::allocation',
+ () => this.queue_update_message(message)
+ );
+
+ this.connect(
+ message,
+ 'destroy',
+ () => {
+ this.cancel_update(message);
+ this.remove_stack_mask(message);
+ this.messages.delete(message);
+ }
+ );
+ }
+
+ track_group(group) {
+ if (!this.watch_actor(group) || this.groups.has(group))
+ return;
+
+ this.groups.add(group);
+ this.update_group_header(group);
+
+ this.connect(
+ group,
+ 'notify::expanded',
+ () => this.update_all()
+ );
+
+ this.connect(
+ group,
+ 'notify::allocation',
+ () => this.update_group_header(group)
+ );
+
+ if (group.layout_manager) {
+ const lm = group.layout_manager;
+ const id = lm.connect('notify::expansion', () => {
+ this.update_group_header(group);
+ this.update_group_messages(group);
+ });
+ this.group_connections.set(group, { lm, id });
+ }
+ }
+
+ untrack_group(group) {
+ if (this.group_connections.has(group)) {
+ const { lm, id } = this.group_connections.get(group);
+ lm.disconnect(id);
+ this.group_connections.delete(group);
+ }
+ this.groups.delete(group);
+ }
+
+ update_all() {
+ this.groups.forEach(group => {
+ this.update_group_header(group);
+ this.update_group_messages(group);
+ });
+ this.messages.forEach(message => {
+ if (!this.get_message_group(message))
+ this.update_message(message);
+ });
+ }
+
+ update_group_header(group) {
+ if (!this.watch_actor(group))
+ return;
+
+ const header = group._headerBox;
+ if (!header)
+ return;
+
+ const expansion = group.layout_manager?.expansion ?? (group.expanded ? 1 : 0);
+ const target_opacity = this.enabled ? Math.round(expansion * 255) : 255;
+
+ header.opacity = target_opacity;
+ }
+
+ get_group_messages(group) {
+ const list = [];
+ const find_messages = actor => {
+ if (this.has_style_class(actor, 'message')) {
+ list.push(actor);
+ return;
+ }
+ this.get_children(actor).forEach(find_messages);
+ };
+ find_messages(group);
+ return list;
+ }
+
+ update_group_messages(group) {
+ if (!this.enabled || !this.watch_actor(group))
+ return;
+
+ const expansion = group.layout_manager?.expansion ?? (group.expanded ? 1.0 : 0.0);
+ const messages = this.get_group_messages(group);
+
+ messages.forEach((message, index) => {
+ this.update_message_with_expansion(message, index, expansion, group);
+ });
+ }
+
+ queue_update_all() {
+ this.messages.forEach(message => this.queue_update_message(message));
+ }
+
+ queue_update_message(message) {
+ if (this.update_ids.has(message))
+ return;
+
+ const id = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
+ this.update_ids.delete(message);
+
+ if (this.enabled && this.messages.has(message))
+ this.update_message(message);
+
+ return GLib.SOURCE_REMOVE;
+ });
+
+ this.update_ids.set(message, id);
+ }
+
+ update_message(message) {
+ if (!this.enabled) {
+ this.remove_stack_mask(message);
+ return;
+ }
+
+ const group = this.get_message_group(message);
+ if (group) {
+ const expansion = group.layout_manager?.expansion ?? (group.expanded ? 1.0 : 0.0);
+ const index = this.get_message_index_in_group(message);
+ this.update_message_with_expansion(message, index >= 0 ? index : 0, expansion, group);
+ } else {
+ const is_expanded = this.is_in_expanded_group(message);
+ if (this.is_stacked(message) && !is_expanded) {
+ this.apply_stack_mask(message);
+ this.hide_message_content(message);
+ this.restore_message_opacity(message);
+ } else {
+ this.remove_stack_mask(message);
+ }
+ }
+ }
+
+ update_message_with_expansion(message, index, expansion, group) {
+ if (!this.enabled || !this.watch_actor(message))
+ return;
+
+ const is_stacked = this.is_stacked(message) || index > 0;
+
+ if (!is_stacked) {
+ this.remove_stack_mask(message);
+ return;
+ }
+
+ if (expansion >= 0.99) {
+ this.remove_stack_mask(message);
+ return;
+ }
+
+ if (expansion <= 0.01) {
+ this.apply_stack_mask(message);
+ this.hide_message_content(message);
+ this.restore_message_opacity(message);
+ return;
+ }
+
+ // 0.01 < expansion < 0.99: Animating unravel / collapse
+ const height = message.height || message.get_height() || 0;
+ const width = message.width || message.get_width() || 0;
+
+ if (height <= 0 || width <= 0)
+ return;
+
+ const base_edge = (index === 1) ? 10 : (index === 2 ? 7 : 0);
+ const visible_edge = Math.round(base_edge + (height - base_edge) * expansion);
+ const clip_y = Math.max(0, height - visible_edge);
+
+ message.set_clip(0, clip_y, width, visible_edge);
+ this.bms_clipped.add(message);
+
+ // Staggered opacity progress for cards so they smoothly fade in as they unravel
+ const stagger_start = Math.min(0.8, index * 0.04);
+ const progress = Math.min(1.0, Math.max(0.0, (expansion - stagger_start) / (1.0 - stagger_start)));
+ const target_alpha = Math.round(255 * progress);
+
+ this.set_child_opacity(message, target_alpha);
+
+ if (index >= 3) {
+ this.set_message_opacity(message, target_alpha);
+ } else {
+ this.restore_message_opacity(message);
+ }
+ }
+
+ apply_stack_mask(message) {
+ if (!this.watch_actor(message))
+ return;
+
+ const height = message.height || message.get_height() || 0;
+ const width = message.width || message.get_width() || 0;
+
+ if (height <= 0 || width <= 0)
+ return;
+
+ const index = this.get_message_index_in_group(message);
+
+ if (index === 1) {
+ // 2nd card: tight visible strip of 10px (matches exact 10px bottom offset below card 1)
+ const visible_edge = 10;
+ const clip_y = Math.max(0, height - visible_edge);
+ message.set_clip(0, clip_y, width, visible_edge);
+ this.bms_clipped.add(message);
+ } else if (index === 2) {
+ // 3rd card: tight visible strip of 7px (matches exact 7px bottom offset below card 2)
+ const visible_edge = 7;
+ const clip_y = Math.max(0, height - visible_edge);
+ message.set_clip(0, clip_y, width, visible_edge);
+ this.bms_clipped.add(message);
+ } else if (index >= 3) {
+ // 4th+ cards: hidden when collapsed so they don't stack behind card 3
+ message.set_clip(0, height, width, 0);
+ this.bms_clipped.add(message);
+ } else {
+ // Fallback by pseudo class
+ const is_second = this.has_pseudo_class(message, 'second-in-stack');
+ const visible_edge = is_second ? 10 : 6;
+ const clip_y = Math.max(0, height - visible_edge);
+ message.set_clip(0, clip_y, width, visible_edge);
+ this.bms_clipped.add(message);
+ }
+ }
+
+ remove_stack_mask(message) {
+ if (!message || this.destroyed_actors.has(message))
+ return;
+
+ if (this.bms_clipped.has(message)) {
+ message.remove_clip();
+ this.bms_clipped.delete(message);
+ }
+
+ this.restore_message_content(message);
+ this.restore_message_opacity(message);
+ }
+
+ set_child_opacity(message, opacity) {
+ const child = this.get_child(message);
+ if (!child)
+ return;
+
+ if (!this.original_opacity.has(child))
+ this.original_opacity.set(child, child.opacity ?? 255);
+
+ child.opacity = opacity;
+ }
+
+ hide_message_content(message) {
+ this.set_child_opacity(message, 0);
+ }
+
+ restore_message_content(message) {
+ const child = this.get_child(message);
+ if (!child)
+ return;
+
+ if (this.original_opacity.has(child)) {
+ child.opacity = this.original_opacity.get(child);
+ this.original_opacity.delete(child);
+ }
+ }
+
+ set_message_opacity(message, opacity) {
+ if (!this.watch_actor(message))
+ return;
+
+ if (!this.original_message_opacity.has(message))
+ this.original_message_opacity.set(message, message.opacity ?? 255);
+
+ message.opacity = opacity;
+ }
+
+ restore_message_opacity(message) {
+ if (!message || this.destroyed_actors.has(message))
+ return;
+
+ if (this.original_message_opacity.has(message)) {
+ message.opacity = this.original_message_opacity.get(message);
+ this.original_message_opacity.delete(message);
+ }
+ }
+
+ get_message_index_in_group(message) {
+ const group = this.get_message_group(message);
+ if (!group)
+ return -1;
+
+ const list = [];
+ const find_messages = actor => {
+ if (this.has_style_class(actor, 'message')) {
+ list.push(actor);
+ return;
+ }
+ actor.get_children().forEach(find_messages);
+ };
+ find_messages(group);
+ return list.indexOf(message);
+ }
+
+ has_pseudo_class(actor, pseudo_class) {
+ if (!actor || this.destroyed_actors.has(actor))
+ return false;
+
+ if (actor.has_style_pseudo_class)
+ return actor.has_style_pseudo_class(pseudo_class);
+
+ if (actor.get_style_pseudo_class)
+ return (actor.get_style_pseudo_class() ?? '').split(/\s+/).includes(pseudo_class);
+
+ return false;
+ }
+
+ get_message_group(message) {
+ let actor = message ? message.get_parent() : null;
+
+ while (actor && !this.destroyed_actors.has(actor)) {
+ if (this.has_style_class(actor, 'message-notification-group'))
+ return actor;
+ actor = actor.get_parent();
+ }
+ return null;
+ }
+
+ is_in_expanded_group(message) {
+ let actor = message ? message.get_parent() : null;
+
+ while (actor && !this.destroyed_actors.has(actor)) {
+ if (
+ this.has_style_class(actor, 'message-notification-group')
+ && actor.expanded
+ )
+ return true;
+ actor = actor.get_parent();
+ }
+
+ return false;
+ }
+
+ is_stacked(message) {
+ if (!message || this.destroyed_actors.has(message))
+ return false;
+ return STACKED_PSEUDO_CLASSES.some(pseudo_class => {
+ if (message.has_style_pseudo_class)
+ return message.has_style_pseudo_class(pseudo_class);
+
+ if (message.get_style_pseudo_class)
+ return (message.get_style_pseudo_class() ?? '').split(/\s+/).includes(pseudo_class);
+
+ return false;
+ });
+ }
+
+ has_any_style_class(actor, style_classes) {
+ return style_classes.some(style_class => this.has_style_class(actor, style_class));
+ }
+
+ is_internal_actor(actor) {
+ if (!actor)
+ return false;
+
+ if (this.has_any_style_class(actor, INTERNAL_STYLE_CLASSES))
+ return true;
+
+ if (this.destroyed_actors.has(actor))
+ return false;
+
+ return INTERNAL_NAMES.includes(actor.name ?? actor.get_name());
+ }
+
+ has_style_class(actor, style_class) {
+ if (!actor || this.destroyed_actors.has(actor))
+ return false;
+
+ if (actor.has_style_class_name)
+ return actor.has_style_class_name(style_class);
+
+ if (actor.get_style_class_name)
+ return (actor.get_style_class_name() ?? '').split(/\s+/).includes(style_class);
+
+ return false;
+ }
+
+ watch_actor(actor) {
+ if (!actor || this.destroyed_actors.has(actor))
+ return false;
+ if (this.watched_actors.has(actor))
+ return true;
+
+ this.connections.connect(actor, 'destroy', () => {
+ this.destroyed_actors.add(actor);
+ this.containers.delete(actor);
+ if (this.groups.has(actor)) {
+ this.untrack_group(actor);
+ }
+ this.messages.delete(actor);
+ this.cancel_update(actor);
+ });
+
+ this.watched_actors.add(actor);
+ return true;
+ }
+
+ get_children(actor) {
+ if (this.is_internal_actor(actor) || !this.watch_actor(actor))
+ return [];
+
+ return actor.get_children();
+ }
+
+ get_child(actor) {
+ if (!this.watch_actor(actor))
+ return null;
+
+ return (actor.get_child ? actor.get_child() : actor.child) || null;
+ }
+
+ cancel_update(message) {
+ const id = this.update_ids.get(message);
+ if (!id)
+ return;
+
+ GLib.source_remove(id);
+ this.update_ids.delete(message);
+ }
+
+ connect(actor, signal, handler) {
+ this.connections.connect(actor, signal, handler);
+ }
+
+ disable() {
+ this.update_ids.forEach(id => GLib.source_remove(id));
+ this.update_ids.clear();
+ this.messages.forEach(message => this.remove_stack_mask(message));
+ this.groups.forEach(group => {
+ if (group._headerBox) {
+ group._headerBox.opacity = 255;
+ }
+ this.untrack_group(group);
+ });
+ this.group_connections.forEach(({ lm, id }) => {
+ lm.disconnect(id);
+ });
+ this.group_connections.clear();
+ this.messages.clear();
+ this.groups.clear();
+ this.containers.clear();
+ this.watched_actors = new WeakSet();
+ this.destroyed_actors = new WeakSet();
+ this.bms_clipped = new WeakSet();
+ this.original_opacity = new WeakMap();
+ this.original_message_opacity = new WeakMap();
+ this.enabled = false;
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/static_actor.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/static_actor.js
new file mode 100644
index 0000000..c933b36
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/static_actor.js
@@ -0,0 +1,301 @@
+import Meta from 'gi://Meta';
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+
+import { Pipeline } from '../../conveniences/pipeline.js';
+import { transform_to_actor_space } from './surface_geometry.js';
+import { PopupBlurStaticCorner } from './static_corner.js';
+import { has_style_class } from './targets.js';
+
+export const PopupBlurStaticActor = class PopupBlurStaticActor {
+ constructor(settings, effects_manager, target, root_actor, parent, get_corner_radius) {
+ this.settings = settings;
+ this.effects_manager = effects_manager;
+ this.target = target;
+ this.root_actor = root_actor;
+ this.parent = parent;
+ this.get_corner_radius = get_corner_radius;
+ this.static_corner = new PopupBlurStaticCorner(effects_manager, get_corner_radius);
+ this.background_group = null;
+ this.blur_actor = null;
+ this.bg_manager = null;
+ this.pipeline = null;
+ this.monitor_index = null;
+ this.opacity_factor = 1;
+ this.background_opacity = null;
+ this.x = null;
+ this.y = null;
+ this.width = null;
+ this.height = null;
+ }
+
+ create() {
+ this.background_group = new Meta.BackgroundGroup({
+ name: 'bms-popup-backgroundgroup',
+ width: 0,
+ height: 0,
+ });
+ this.background_group.hide();
+ this.background_group.connect('destroy', () => {
+ this.background_group = null;
+ });
+
+ return this.update_background();
+ }
+
+ get actor() {
+ return this.background_group;
+ }
+
+ update_background(monitor_index = null) {
+ const monitor = this.find_monitor(monitor_index);
+ if (!monitor)
+ return false;
+
+ if (monitor.index === this.monitor_index && this.blur_actor)
+ return true;
+
+ this.destroy_background();
+
+ const bg_manager_list = [];
+ const pipeline = new Pipeline(
+ this.effects_manager,
+ global.blur_my_shell._pipelines_manager,
+ this.settings.popup.PIPELINE,
+ null,
+ {
+ effect_overrides: {
+ native_static_gaussian_blur: params => this.get_blur_effect_overrides(params, 'unscaled_radius'),
+ gaussian_blur: params => this.get_blur_effect_overrides(params, 'radius'),
+ monte_carlo_blur: params => this.get_blur_effect_overrides(params, 'radius'),
+ downscale: () => this.get_texture_effect_overrides(),
+ upscale: () => this.get_texture_effect_overrides(),
+ pixelize: () => this.get_texture_effect_overrides(),
+ derivative: () => this.get_texture_effect_overrides(),
+ refraction: () => this.get_texture_effect_overrides(),
+ color: params => this.get_color_effect_overrides(params),
+ luminosity: () => this.get_luminosity_effect_overrides(),
+ noise: params => this.get_noise_effect_overrides(params),
+ rgb_to_hsl: () => this.get_texture_effect_overrides(),
+ hsl_to_rgb: () => this.get_texture_effect_overrides(),
+ corner: () => ({ radius: this.get_corner_radius() }),
+ },
+ }
+ );
+
+ this.blur_actor = pipeline.create_background_with_effects(
+ monitor.index,
+ bg_manager_list,
+ this.background_group,
+ 'bms-popup-blurred-widget'
+ );
+ this.blur_actor.connect('destroy', () => {
+ this.blur_actor = null;
+ });
+ this.blur_actor.hide();
+ this.bg_manager = bg_manager_list[0];
+ this.pipeline = pipeline;
+ this.monitor_index = monitor.index;
+ this.static_corner.bind(this.pipeline, this.blur_actor);
+
+ return true;
+ }
+
+ find_monitor(monitor_index = null) {
+ if (monitor_index !== null)
+ return Main.layoutManager.monitors[monitor_index] || null;
+
+ return (
+ Main.layoutManager.findMonitorForActor(this.target)
+ ?? Main.layoutManager.findMonitorForActor(this.root_actor)
+ ?? Main.layoutManager.primaryMonitor
+ );
+ }
+
+ is_screenshot_ui() {
+ return has_style_class(this.target, 'screenshot-ui-panel')
+ || has_style_class(this.root_actor, 'screenshot-ui-panel');
+ }
+
+ update_geometry(target_x, target_y, width, height, monitor_index = null) {
+ if (!this.update_background(monitor_index))
+ return false;
+ if (!this.blur_actor)
+ return false;
+
+ const monitor = Main.layoutManager.monitors[this.monitor_index];
+ if (!monitor)
+ return false;
+
+ const monitor_geometry = transform_to_actor_space(this.parent, monitor);
+ const target_geometry = transform_to_actor_space(this.parent, {
+ x: target_x,
+ y: target_y,
+ width,
+ height,
+ });
+ if (!monitor_geometry || !target_geometry)
+ return false;
+
+ const clip_x = Math.round(target_geometry.x - monitor_geometry.x);
+ const clip_y = Math.round(target_geometry.y - monitor_geometry.y);
+ const clip_width = Math.ceil(target_geometry.width);
+ const clip_height = Math.ceil(target_geometry.height);
+
+ if (!this.blur_actor)
+ return false;
+
+ if (this.is_screenshot_ui() && this.background_group) {
+ this.background_group.set_position(0, 0);
+ this.background_group.set_size(monitor_geometry.width, monitor_geometry.height);
+ }
+
+ if (this.blur_actor.x !== monitor_geometry.x || this.blur_actor.y !== monitor_geometry.y)
+ this.blur_actor.set_position(monitor_geometry.x, monitor_geometry.y);
+ if (
+ this.blur_actor.width !== monitor_geometry.width
+ || this.blur_actor.height !== monitor_geometry.height
+ )
+ this.blur_actor.set_size(monitor_geometry.width, monitor_geometry.height);
+
+ if (
+ this.x !== clip_x
+ || this.y !== clip_y
+ || this.width !== clip_width
+ || this.height !== clip_height
+ ) {
+ this.blur_actor.set_clip(clip_x, clip_y, clip_width, clip_height);
+ this.x = clip_x;
+ this.y = clip_y;
+ this.width = clip_width;
+ this.height = clip_height;
+ }
+
+ this.blur_actor.show();
+
+ return { x: clip_x, y: clip_y, width: clip_width, height: clip_height };
+ }
+
+ has_opacity(opacity) {
+ if (this.background_opacity !== opacity)
+ return false;
+
+ const background_actor = this.get_background_actor();
+ return !background_actor || background_actor.opacity === opacity;
+ }
+
+ set_opacity(opacity, pipeline_opacity = opacity) {
+ this.set_opacity_factor(pipeline_opacity / 255);
+ if (this.background_group)
+ this.background_group.opacity = 255;
+ if (this.blur_actor)
+ this.blur_actor.opacity = 255;
+
+ this.background_opacity = opacity;
+
+ const background_actor = this.get_background_actor();
+ if (background_actor)
+ background_actor.opacity = opacity;
+
+ this.blur_actor?.get_children().forEach(child => child.opacity = opacity);
+ }
+
+ set_opacity_factor(opacity_factor) {
+ opacity_factor = Math.max(0, Math.min(1, opacity_factor));
+ if (this.opacity_factor === opacity_factor)
+ return;
+
+ this.opacity_factor = opacity_factor;
+ this.pipeline?.apply_effect_overrides();
+ }
+
+ get_blur_effect_overrides(params, radius_key) {
+ const overrides = {};
+
+ if (radius_key in params)
+ overrides[radius_key] = params[radius_key] * this.opacity_factor;
+ if ('brightness' in params)
+ overrides.brightness = 1 - (1 - params.brightness) * this.opacity_factor;
+
+ return overrides;
+ }
+
+ get_color_effect_overrides(params) {
+ const overrides = this.get_texture_effect_overrides();
+
+ if (Array.isArray(params.color) && params.color.length >= 4)
+ overrides.color = params.color;
+
+ return overrides;
+ }
+
+ get_luminosity_effect_overrides() {
+ return this.get_texture_effect_overrides();
+ }
+
+ get_noise_effect_overrides(params) {
+ const overrides = this.get_texture_effect_overrides();
+
+ if ('noise' in params)
+ overrides.noise = params.noise;
+
+ return overrides;
+ }
+
+ get_texture_effect_overrides() {
+ return {
+ opacity_factor: this.opacity_factor,
+ };
+ }
+
+ get_background_actor() {
+ return this.bg_manager ? (this.bg_manager.backgroundActor || null) : null;
+ }
+
+ update_settings() {
+ this.static_corner.update();
+ }
+
+ update_pipeline() {
+ this.bg_manager?._bms_pipeline.change_pipeline_to(this.settings.popup.PIPELINE);
+ this.static_corner.update();
+ }
+
+ destroy() {
+ const background_group = this.background_group;
+ this.destroy_background();
+ this.background_group = null;
+
+ if (background_group)
+ background_group.destroy();
+ }
+
+ destroy_background() {
+ const bg_manager = this.bg_manager;
+ const blur_actor = this.blur_actor;
+ this.bg_manager = null;
+ this.blur_actor = null;
+ this.pipeline = null;
+
+ this.static_corner.destroy();
+
+ if (bg_manager) {
+ if (bg_manager._bms_pipeline) {
+ bg_manager._bms_pipeline.destroy();
+ bg_manager._bms_pipeline = null;
+ }
+ if (!blur_actor)
+ bg_manager.backgroundActor = null;
+ bg_manager.destroy();
+ } else if (this.background_group) {
+ this.background_group.destroy_all_children();
+ }
+ blur_actor?.destroy();
+
+ this.monitor_index = null;
+ this.background_opacity = null;
+ this.x = null;
+ this.y = null;
+ this.width = null;
+ this.height = null;
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/static_corner.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/static_corner.js
new file mode 100644
index 0000000..e575e09
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/static_corner.js
@@ -0,0 +1,70 @@
+export const PopupBlurStaticCorner = class PopupBlurStaticCorner {
+ constructor(effects_manager, get_radius) {
+ this.effects_manager = effects_manager;
+ this.get_radius = get_radius;
+ this.pipeline = null;
+ this.actor = null;
+ this.effect = null;
+ }
+
+ bind(pipeline, actor) {
+ this.pipeline = pipeline;
+ this.actor = actor;
+ this.update();
+ }
+
+ update() {
+ if (!this.pipeline || !this.actor)
+ return;
+
+ this.pipeline.apply_effect_overrides('corner');
+
+ if (this.pipeline_has_corner_effect()) {
+ this.destroy_external_effect();
+ return;
+ }
+
+ if (!this.effect) {
+ this.effect = this.effects_manager.new_corner_effect({
+ radius: this.get_radius(),
+ });
+ this.attach_external_effect_as_outermost();
+ return;
+ }
+
+ this.effect.radius = this.get_radius();
+ }
+
+ attach_external_effect_as_outermost() {
+ const existing_effects = this.pipeline?.effects ?? [];
+
+ existing_effects.forEach(effect => {
+ this.actor.remove_effect(effect);
+ });
+
+ this.actor.add_effect(this.effect);
+
+ existing_effects.forEach(effect => {
+ this.actor.add_effect(effect);
+ });
+ }
+
+ pipeline_has_corner_effect() {
+ const corner_class = this.effects_manager.SUPPORTED_EFFECTS.corner.class;
+ return this.pipeline.effects.some(effect => effect instanceof corner_class);
+ }
+
+ destroy_external_effect() {
+ if (!this.effect)
+ return;
+
+ this.effects_manager.remove(this.effect);
+ this.effect = null;
+ }
+
+ destroy() {
+ this.destroy_external_effect();
+ this.pipeline = null;
+ this.actor = null;
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_fade.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_fade.js
new file mode 100644
index 0000000..2a0b9a5
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_fade.js
@@ -0,0 +1,132 @@
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+import { has_style_class } from './targets.js';
+
+export const PopupBlurSurfaceFade = class PopupBlurSurfaceFade {
+ constructor(actor, target, root_actor, parent) {
+ this.actor = actor;
+ this.target = target;
+ this.root_actor = root_actor;
+ this.parent = parent;
+ }
+
+ get_opacity() {
+ let opacity = 255;
+ const visited = new WeakSet();
+ let actor = this.target;
+
+ while (actor && actor !== this.parent) {
+ opacity = this.apply_actor_opacity(opacity, actor, visited);
+ actor = actor.get_parent();
+ }
+
+ opacity = this.apply_actor_opacity(opacity, this.root_actor, visited);
+
+ [
+ this.target,
+ this.root_actor,
+ ].forEach(actor => {
+ const paint_opacity = this.get_paint_opacity(actor);
+ if (paint_opacity !== null)
+ opacity = Math.min(opacity, paint_opacity);
+ });
+
+ if (this.is_notification_banner()) {
+ opacity = Math.round(opacity * this.get_banner_position_alpha());
+ }
+
+ return opacity;
+ }
+
+ is_notification_banner() {
+ if (has_style_class(this.target, 'notification-banner'))
+ return true;
+ if (this.root_actor?.name === 'notification-container')
+ return true;
+ let a = this.target;
+ while (a && a !== this.parent) {
+ if (has_style_class(a, 'notification-banner'))
+ return true;
+ a = a.get_parent();
+ }
+ return false;
+ }
+
+ get_banner_position_alpha() {
+ try {
+ const [, stage_y] = this.target.get_transformed_position();
+
+ if (!Main.panel)
+ return 1;
+
+ const monitor = Main.layoutManager.findMonitorForActor(Main.panel)
+ ?? Main.layoutManager.primaryMonitor;
+
+ if (!monitor)
+ return 1;
+
+ const [, panel_y] = Main.panel.get_transformed_position();
+ const panel_width = Main.panel.width || Main.panel.get_width() || 0;
+ const panel_height = Main.panel.height || Main.panel.get_height() || 36;
+
+ // Must be a horizontal panel anchored at the monitor's top edge
+ const is_horizontal = panel_width > panel_height;
+ const is_at_monitor_top = Math.abs(panel_y - monitor.y) <= 5;
+
+ if (!is_horizontal || !is_at_monitor_top)
+ return 1;
+
+ const panel_bottom = panel_y + panel_height;
+ const threshold = panel_bottom + 5;
+
+ if (stage_y <= panel_y)
+ return 0;
+ if (stage_y >= threshold)
+ return 1;
+
+ return Math.clamp((stage_y - panel_y) / (threshold - panel_y), 0, 1);
+ } catch (e) {
+ return 1;
+ }
+ }
+
+ set_opacity(opacity) {
+ this.actor.opacity = opacity;
+ }
+
+ apply_actor_opacity(opacity, actor, visited) {
+ if (!actor || visited.has(actor))
+ return opacity;
+
+ visited.add(actor);
+
+ let visible = actor.visible;
+ let mapped = actor.mapped;
+ if (!visible && this.is_keyboard_actor(actor)) {
+ const parent = actor.get_parent();
+ visible = parent?.visible && parent?.mapped;
+ mapped = parent?.mapped;
+ }
+ if (!visible || !mapped)
+ return 0;
+
+ return Math.round(opacity * (actor.opacity ?? 255) / 255);
+ }
+
+ is_keyboard_actor(actor) {
+ return (
+ has_style_class(actor, 'bms-keyboard-surface')
+ );
+ }
+
+ get_paint_opacity(actor) {
+ if (this.is_keyboard_actor(actor) && (!actor.visible || !actor.mapped)) {
+ const parent = actor.get_parent();
+ if (parent?.visible && parent?.mapped)
+ return null;
+ }
+ if (actor?.get_paint_opacity)
+ return actor.get_paint_opacity();
+
+ return null;
+ }
+}; \ No newline at end of file
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js
new file mode 100644
index 0000000..84832d9
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js
@@ -0,0 +1,291 @@
+import St from 'gi://St';
+
+export function transform_to_actor_space(actor, { x, y, width, height }) {
+ if (!actor)
+ return null;
+ const [actor_x, actor_y] = actor.get_transformed_position();
+ const [actor_width, actor_height] = actor.get_size();
+ const [transformed_width, transformed_height] = actor.get_transformed_size();
+ const scale_x = actor_width > 0 ? transformed_width / actor_width : 1;
+ const scale_y = actor_height > 0 ? transformed_height / actor_height : 1;
+
+ return {
+ x: (x - actor_x) / scale_x,
+ y: (y - actor_y) / scale_y,
+ width: width / scale_x,
+ height: height / scale_y,
+ };
+}
+
+export const PopupBlurSurfaceGeometry = class PopupBlurSurfaceGeometry {
+ get(actor, { use_content = true, use_margins = true } = {}) {
+ const actor_geometry = this.get_transformed_actor(actor);
+ if (!this.has_valid_geometry(actor_geometry))
+ return actor_geometry;
+
+ const margin_geometry = use_margins
+ ? this.get_margin_adjusted(actor, actor_geometry)
+ : actor_geometry;
+ if (!use_content)
+ return margin_geometry;
+
+ const content_geometry = this.get_transformed_content(actor, margin_geometry);
+
+ if (!this.should_use_content(margin_geometry, content_geometry))
+ return margin_geometry;
+
+ return content_geometry;
+ }
+
+ get_transformed_actor(actor) {
+ const extents = actor.get_transformed_extents();
+ const top_left = extents?.get_top_left();
+ const bottom_right = extents?.get_bottom_right();
+
+ if (top_left && bottom_right) {
+ return {
+ x: top_left.x,
+ y: top_left.y,
+ width: bottom_right.x - top_left.x,
+ height: bottom_right.y - top_left.y,
+ };
+ }
+
+ if (!actor)
+ return null;
+ const [x, y] = actor.get_transformed_position();
+ const [width, height] = actor.get_transformed_size();
+ return { x, y, width, height };
+ }
+
+ get_transformed_clip(actor) {
+ if (!actor?.has_clip)
+ return null;
+
+ const [clip_x, clip_y, clip_width, clip_height] = actor.get_clip();
+ if (clip_width <= 0 || clip_height <= 0)
+ return null;
+
+ const [actor_x, actor_y] = actor.get_transformed_position();
+ const [actor_width, actor_height] = actor.get_transformed_size();
+ const scale_x = this.get_actor_scale(actor, actor_width, 'width');
+ const scale_y = this.get_actor_scale(actor, actor_height, 'height');
+
+ return {
+ x: actor_x + clip_x * scale_x,
+ y: actor_y + clip_y * scale_y,
+ width: clip_width * scale_x,
+ height: clip_height * scale_y,
+ };
+ }
+
+ get_margin_adjusted(actor, geometry) {
+ const margins = this.get_margins(actor);
+ if (!margins)
+ return geometry;
+
+ const scale_x = this.get_actor_scale(actor, geometry.width, 'width');
+ const scale_y = this.get_actor_scale(actor, geometry.height, 'height');
+
+ return this.shrink(geometry,
+ margins.top * scale_y,
+ margins.right * scale_x,
+ margins.bottom * scale_y,
+ margins.left * scale_x
+ ) ?? geometry;
+ }
+
+ get_transformed_content(actor, boundary) {
+ const children = this.get_transformed_children(actor);
+ if (!this.has_valid_geometry(children))
+ return null;
+
+ const insets = this.get_paint_insets(actor, boundary);
+ const geometry = this.inflate(
+ children,
+ insets.top,
+ insets.right,
+ insets.bottom,
+ insets.left
+ );
+
+ return this.intersect(geometry, boundary);
+ }
+
+ get_transformed_children(actor) {
+ let geometry = null;
+
+ this.get_children(actor).forEach(child => {
+ if (!this.is_visible(child))
+ return;
+
+ const child_geometry = this.get_transformed_actor(child);
+ if (!this.has_valid_geometry(child_geometry))
+ return;
+
+ geometry = this.union(geometry, child_geometry);
+ });
+
+ return geometry;
+ }
+
+ get_margins(actor) {
+ const margins = {
+ top: this.get_margin(actor, 'top', St.Side.TOP),
+ right: this.get_margin(actor, 'right', St.Side.RIGHT),
+ bottom: this.get_margin(actor, 'bottom', St.Side.BOTTOM),
+ left: this.get_margin(actor, 'left', St.Side.LEFT),
+ };
+
+ return Object.values(margins).some(margin => margin > 0) ? margins : null;
+ }
+
+ get_margin(actor, side_name, side) {
+ const property_names = [
+ `margin_${side_name}`,
+ `margin${side_name[0].toUpperCase()}${side_name.slice(1)}`,
+ ];
+
+ for (const property of property_names) {
+ const value = actor[property];
+ if (typeof value === 'number')
+ return value;
+ }
+
+ const getter = actor[`get_margin_${side_name}`];
+ if (getter) {
+ const value = getter.call(actor);
+ if (typeof value === 'number')
+ return value;
+ }
+
+ try {
+ const theme_node = actor.get_theme_node();
+ if (!theme_node?.get_margin)
+ return 0;
+
+ return theme_node.get_margin(side);
+ } catch (e) {
+ // get_theme_node() may throw when actor is not yet mapped to a stage
+ return 0;
+ }
+ }
+
+ get_paint_insets(actor, geometry) {
+ const scale_x = this.get_actor_scale(actor, geometry.width, 'width');
+ const scale_y = this.get_actor_scale(actor, geometry.height, 'height');
+
+ return {
+ top: this.get_inset(actor, St.Side.TOP) * scale_y,
+ right: this.get_inset(actor, St.Side.RIGHT) * scale_x,
+ bottom: this.get_inset(actor, St.Side.BOTTOM) * scale_y,
+ left: this.get_inset(actor, St.Side.LEFT) * scale_x,
+ };
+ }
+
+ get_inset(actor, side) {
+ try {
+ const theme_node = actor.get_theme_node();
+ if (!theme_node)
+ return 0;
+
+ let inset = 0;
+ if (theme_node.get_padding)
+ inset += theme_node.get_padding(side);
+ if (theme_node.get_border_width)
+ inset += theme_node.get_border_width(side);
+ return inset;
+ } catch (e) {
+ // get_theme_node() may throw when actor is not yet mapped to a stage
+ return 0;
+ }
+ }
+
+ get_actor_scale(actor, transformed_size, property) {
+ const size = actor ? (actor[property] ?? (actor[`get_${property}`] ? actor[`get_${property}`]() : 0)) : 0;
+ return size > 0 ? transformed_size / size : 1;
+ }
+
+ should_use_content(outer, content) {
+ if (!this.has_valid_geometry(content))
+ return false;
+
+ if (
+ content.width > outer.width + 1
+ || content.height > outer.height + 1
+ )
+ return false;
+
+ return outer.width - content.width > 2 || outer.height - content.height > 2;
+ }
+
+ is_visible(actor) {
+ return actor?.visible && actor.mapped;
+ }
+
+ get_children(actor) {
+ return actor ? actor.get_children() : [];
+ }
+
+ has_valid_geometry(geometry) {
+ return geometry?.width > 0 && geometry?.height > 0;
+ }
+
+ shrink(geometry, top, right, bottom, left) {
+ const width = geometry.width - left - right;
+ const height = geometry.height - top - bottom;
+
+ if (width <= 0 || height <= 0)
+ return null;
+
+ return {
+ x: geometry.x + left,
+ y: geometry.y + top,
+ width,
+ height,
+ };
+ }
+
+ inflate(geometry, top, right, bottom, left) {
+ return {
+ x: geometry.x - left,
+ y: geometry.y - top,
+ width: geometry.width + left + right,
+ height: geometry.height + top + bottom,
+ };
+ }
+
+ intersect(a, b) {
+ const x1 = Math.max(a.x, b.x);
+ const y1 = Math.max(a.y, b.y);
+ const x2 = Math.min(a.x + a.width, b.x + b.width);
+ const y2 = Math.min(a.y + a.height, b.y + b.height);
+
+ if (x2 <= x1 || y2 <= y1)
+ return null;
+
+ return {
+ x: x1,
+ y: y1,
+ width: x2 - x1,
+ height: y2 - y1,
+ };
+ }
+
+ union(a, b) {
+ if (!a)
+ return b;
+
+ const x1 = Math.min(a.x, b.x);
+ const y1 = Math.min(a.y, b.y);
+ const x2 = Math.max(a.x + a.width, b.x + b.width);
+ const y2 = Math.max(a.y + a.height, b.y + b.height);
+
+ return {
+ x: x1,
+ y: y1,
+ width: x2 - x1,
+ height: y2 - y1,
+ };
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_placement.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_placement.js
new file mode 100644
index 0000000..cad36f9
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_placement.js
@@ -0,0 +1,328 @@
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+
+import { PopupBlurSurfaceGeometry, transform_to_actor_space } from './surface_geometry.js';
+
+export const PopupBlurSurfacePlacement = class PopupBlurSurfacePlacement {
+ constructor(surface) {
+ this.surface = surface;
+ this.geometry = new PopupBlurSurfaceGeometry();
+ this.clear();
+ this.ready = false;
+ }
+
+ get_surface_geometry() {
+ this.offscreen = false;
+
+ const geometry = this.get_unclipped_surface_geometry();
+ if (!this.has_valid_geometry(geometry))
+ return null;
+
+ const clipped_geometry = this.get_clipped_surface_geometry(geometry);
+ if (!this.has_valid_geometry(clipped_geometry))
+ return null;
+
+ const monitor_geometry = this.get_monitor_clipped_surface_geometry(clipped_geometry);
+ if (!this.has_valid_geometry(monitor_geometry)) {
+ this.offscreen = true;
+ return null;
+ }
+
+ return monitor_geometry;
+ }
+
+ get_unclipped_monitor_surface_geometry() {
+ this.offscreen = false;
+
+ const geometry = this.get_unclipped_surface_geometry();
+ if (!this.has_valid_geometry(geometry))
+ return null;
+
+ const monitor_geometry = this.get_monitor_clipped_surface_geometry(geometry);
+ if (!this.has_valid_geometry(monitor_geometry)) {
+ this.offscreen = true;
+ return null;
+ }
+
+ return monitor_geometry;
+ }
+
+ get_unclipped_surface_geometry() {
+ const geometry_actor = this.surface.get_geometry_actor();
+ const geometry = this.geometry.get(geometry_actor, {
+ use_content: this.surface.should_use_content_geometry(),
+ use_margins: this.surface.should_use_margin_geometry(),
+ });
+ if (!this.has_valid_geometry(geometry))
+ return null;
+
+ return this.create_surface_geometry(
+ geometry.x,
+ geometry.y,
+ geometry.width,
+ geometry.height
+ );
+ }
+
+ create_surface_geometry(target_x, target_y, width, height) {
+ const local_geometry = transform_to_actor_space(this.surface.parent, {
+ x: target_x,
+ y: target_y,
+ width,
+ height,
+ });
+ if (!local_geometry)
+ return null;
+
+ return {
+ target_x,
+ target_y,
+ target_width: width,
+ target_height: height,
+ x: Math.round(local_geometry.x),
+ y: Math.round(local_geometry.y),
+ width: Math.ceil(local_geometry.width),
+ height: Math.ceil(local_geometry.height),
+ };
+ }
+
+ get_clipped_surface_geometry(geometry) {
+ let clipped = {
+ x: geometry.target_x,
+ y: geometry.target_y,
+ width: geometry.target_width,
+ height: geometry.target_height,
+ };
+
+ let actor = this.surface.get_geometry_actor();
+ while (actor && actor !== this.surface.parent) {
+ const clip = this.geometry.get_transformed_clip(actor);
+ if (clip) {
+ clipped = this.geometry.intersect(clipped, clip);
+ if (!this.has_valid_geometry(clipped))
+ return null;
+ }
+
+ actor = actor.get_parent();
+ }
+
+ return this.create_surface_geometry(
+ clipped.x,
+ clipped.y,
+ clipped.width,
+ clipped.height
+ );
+ }
+
+ get_monitor_clipped_surface_geometry(geometry) {
+ const rect = {
+ x: geometry.target_x,
+ y: geometry.target_y,
+ width: geometry.target_width,
+ height: geometry.target_height,
+ };
+ const cached_monitor = this.get_cached_monitor();
+ const match = cached_monitor
+ ? this.get_monitor_intersection(rect, cached_monitor.monitor, cached_monitor.index)
+ : this.find_best_monitor_intersection(rect);
+
+ if (!match)
+ return null;
+
+ this.monitor_index = match.monitor_index;
+
+ const surface_geometry = this.create_surface_geometry(
+ rect.x,
+ rect.y,
+ rect.width,
+ rect.height
+ );
+ surface_geometry.monitor_index = match.monitor_index;
+ return surface_geometry;
+ }
+
+ get_cached_monitor() {
+ if (this.monitor_index === null)
+ return null;
+
+ const monitor = Main.layoutManager.monitors?.[this.monitor_index];
+ if (!monitor) {
+ this.monitor_index = null;
+ return null;
+ }
+
+ return { monitor, index: this.monitor_index };
+ }
+
+ find_best_monitor_intersection(rect) {
+ let best_match = null;
+ let best_area = 0;
+
+ (Main.layoutManager.monitors ?? []).forEach((monitor, index) => {
+ const match = this.get_monitor_intersection(rect, monitor, index);
+ if (!match)
+ return;
+
+ const area = match.intersection.width * match.intersection.height;
+ if (area > best_area) {
+ best_match = match;
+ best_area = area;
+ }
+ });
+
+ return best_match;
+ }
+
+ get_monitor_intersection(rect, monitor, monitor_index) {
+ const intersection = this.geometry.intersect(rect, monitor);
+ if (!this.has_valid_geometry(intersection))
+ return null;
+
+ return {
+ monitor_index,
+ intersection,
+ };
+ }
+
+ has_valid_geometry(geometry) {
+ return geometry?.width > 0 && geometry?.height > 0;
+ }
+
+ keep_transition_visible(transition_state) {
+ if (this.offscreen || !this.ready || !this.has_cached_geometry() || !transition_state.running)
+ return false;
+
+ const opacity = this.surface.update_opacity(transition_state);
+ if (opacity <= 0)
+ return false;
+
+ if (this.surface.static_blur) {
+ this.surface.blur_actor?.show();
+ }
+ this.surface.show_actors();
+ return true;
+ }
+
+ has_cached_geometry() {
+ return (
+ this.x !== null
+ && this.y !== null
+ && this.width > 0
+ && this.height > 0
+ );
+ }
+
+ has_cached_surface_geometry() {
+ return (
+ this.surface_x !== null
+ && this.surface_y !== null
+ && this.surface_width > 0
+ && this.surface_height > 0
+ );
+ }
+
+ has_surface_geometry_changed(geometry) {
+ return (
+ this.has_valid_geometry(geometry)
+ && (
+ !this.has_cached_surface_geometry()
+ || this.surface_x !== geometry.x
+ || this.surface_y !== geometry.y
+ || this.surface_width !== geometry.width
+ || this.surface_height !== geometry.height
+ )
+ );
+ }
+
+ store_surface_geometry(geometry) {
+ this.surface_x = geometry.x;
+ this.surface_y = geometry.y;
+ this.surface_width = geometry.width;
+ this.surface_height = geometry.height;
+ }
+
+ prepare_visible_geometry() {
+ if (this.ready)
+ return true;
+
+ this.ready = true;
+ this.surface.opacity = 0;
+ this.surface.update_surface_opacity(0);
+ this.surface.hide_actors();
+ this.surface.queue_update();
+ return false;
+ }
+
+ update_surface_geometry(geometry) {
+ if (this.surface.static_blur) {
+ if (!this.update_static_geometry(
+ geometry.target_x,
+ geometry.target_y,
+ geometry.target_width,
+ geometry.target_height
+ ))
+ return false;
+ } else {
+ if (!this.update_dynamic_geometry(geometry.x, geometry.y, geometry.width, geometry.height))
+ return false;
+ }
+
+ this.store_surface_geometry(geometry);
+ return true;
+ }
+
+ update_dynamic_geometry(x, y, width, height) {
+ if (this.x !== x || this.y !== y) {
+ this.surface.blur_actor.set_position(x, y);
+ this.x = x;
+ this.y = y;
+ }
+
+ if (this.width !== width || this.height !== height) {
+ this.surface.blur_actor.set_size(width, height);
+ this.width = width;
+ this.height = height;
+ }
+
+ return true;
+ }
+
+ update_static_geometry(target_x, target_y, width, height) {
+ const geometry = this.surface.static_actor.update_geometry(
+ target_x,
+ target_y,
+ width,
+ height,
+ this.monitor_index
+ );
+ this.surface.sync_static_actor();
+
+ if (!geometry) {
+ this.surface.hide_actors();
+ return false;
+ }
+
+ this.x = geometry.x;
+ this.y = geometry.y;
+ this.width = geometry.width;
+ this.height = geometry.height;
+ return true;
+ }
+
+ hide() {
+ this.ready = false;
+ this.clear();
+ }
+
+ clear() {
+ this.x = null;
+ this.y = null;
+ this.width = null;
+ this.height = null;
+ this.surface_x = null;
+ this.surface_y = null;
+ this.surface_width = null;
+ this.surface_height = null;
+ this.monitor_index = null;
+ this.offscreen = false;
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_signals.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_signals.js
new file mode 100644
index 0000000..47adb91
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_signals.js
@@ -0,0 +1,117 @@
+import Meta from 'gi://Meta';
+import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+
+const SURFACE_SIGNALS = [
+ 'notify::allocation',
+ 'notify::position',
+ 'notify::size',
+ 'notify::x',
+ 'notify::y',
+ 'notify::width',
+ 'notify::height',
+ 'notify::clip-rect',
+ 'notify::visible',
+ 'notify::mapped',
+ 'notify::opacity',
+ 'notify::translation-x',
+ 'notify::translation-y',
+ 'notify::scale-x',
+ 'notify::scale-y',
+ 'notify::pseudo-class',
+];
+
+export const PopupBlurSurfaceSignals = class PopupBlurSurfaceSignals {
+ constructor(surface) {
+ this.surface = surface;
+ this.signal_ids = [];
+ this.signal_actors = new WeakSet();
+ this.destroyed_actors = new WeakSet();
+ }
+
+ connect_actor(actor) {
+ if (!actor || this.signal_actors.has(actor))
+ return;
+
+ this.signal_actors.add(actor);
+ this.track_destroy(actor);
+
+ const is_heavy_surface = this.surface.is_heavy_surface();
+
+ SURFACE_SIGNALS.forEach(signal => {
+ let id = actor.connect(signal, () => {
+ this.clear_pending_idles();
+ const is_visibility_change = signal === 'notify::visible' || signal === 'notify::mapped';
+ if (is_heavy_surface || is_visibility_change) {
+ this.surface.queue_update();
+ return;
+ }
+ else {
+ this.updateId = global.compositor.get_laters().add(Meta.LaterType.IDLE, () => {
+ this.updateId = 0;
+ this.surface.queue_update();
+ return false;
+ });
+ }
+ });
+ this.signal_ids.push([actor, id, signal]);
+ });
+ }
+
+ track_destroy(actor) {
+ const id = actor.connect('destroy', () => this.destroyed_actors.add(actor));
+ this.signal_ids.push([actor, id]);
+ }
+
+ connect_ancestors(actor) {
+ actor = actor ? actor.get_parent() : null;
+
+ while (actor && actor !== this.surface.parent) {
+ this.connect_actor(actor);
+ actor = actor.get_parent();
+ }
+ }
+
+ connect_layout() {
+ if (!this.surface.static_blur)
+ return;
+
+ this.signal_ids.push([
+ Main.layoutManager,
+ Main.layoutManager.connect('monitors-changed', () => this.surface.queue_update()),
+ ]);
+ }
+
+ connect_settings() {
+ [
+ this.surface.corner_radius.key,
+ 'override-background',
+ 'style-popup',
+ ].forEach(key => {
+ const id = this.surface.settings.popup.settings.connect(
+ `changed::${key}`,
+ () => this.surface.update_settings()
+ );
+ this.signal_ids.push([this.surface.settings.popup.settings, id]);
+ });
+ }
+
+ clear_pending_idles() {
+ if (this.updateId) {
+ global.compositor.get_laters().remove(this.updateId);
+ this.updateId = 0;
+ }
+ }
+
+ disconnect_all() {
+ this.clear_pending_idles();
+ this.signal_ids.forEach(([signal_actor, signal_id]) => {
+ if (this.destroyed_actors.has(signal_actor))
+ return;
+
+ signal_actor.disconnect(signal_id);
+ });
+ this.signal_ids = [];
+ this.signal_actors = new WeakSet();
+ this.destroyed_actors = new WeakSet();
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_style.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_style.js
new file mode 100644
index 0000000..1dfb947
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_style.js
@@ -0,0 +1,59 @@
+export const PopupBlurSurfaceStyle = class PopupBlurSurfaceStyle {
+ constructor(surface) {
+ this.surface = surface;
+ this.original_target_style = null;
+ this.target_style_set = false;
+ }
+
+ capture_target_style() {
+ this.original_target_style = this.surface.target ? this.surface.target.get_style() : null;
+ }
+
+ update_target_style() {
+ if (
+ !this.surface.target.set_style
+ || !this.surface.settings.popup.OVERRIDE_BACKGROUND
+ ) {
+ this.restore_target_style();
+ return;
+ }
+
+ if (
+ this.has_style_class(this.surface.target, 'bms-keyboard-surface')
+ )
+ return;
+
+ const base_style = this.original_target_style ?? '';
+ const separator = base_style.trim() && !base_style.trim().endsWith(';') ? '; ' : '';
+
+ this.surface.target.set_style(
+ `${base_style}${separator}border-radius: ${this.surface.get_corner_radius()}px;`
+ );
+ this.target_style_set = true;
+ }
+
+ restore_target_style() {
+ if (!this.target_style_set || !this.surface.target.set_style)
+ return;
+
+ this.surface.target.set_style(this.original_target_style);
+ this.target_style_set = false;
+ }
+
+ has_any_style_class(actor, style_classes) {
+ return style_classes.some(style_class => this.has_style_class(actor, style_class));
+ }
+
+ has_style_class(actor, style_class) {
+ if (!actor)
+ return false;
+
+ if (actor.has_style_class_name)
+ return actor.has_style_class_name(style_class);
+
+ if (actor.get_style_class_name)
+ return (actor.get_style_class_name() ?? '').split(/\s+/).includes(style_class);
+
+ return false;
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_transitions.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_transitions.js
new file mode 100644
index 0000000..70fd520
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_transitions.js
@@ -0,0 +1,139 @@
+const GEOMETRY_TRANSITION_PROPERTIES = [
+ 'x',
+ 'y',
+ 'width',
+ 'height',
+ 'clip-rect',
+ 'clip_rect',
+ 'translation-x',
+ 'translation-y',
+ 'translation_x',
+ 'translation_y',
+ 'scale-x',
+ 'scale-y',
+ 'scale_x',
+ 'scale_y',
+];
+
+export const PopupBlurSurfaceTransitions = class PopupBlurSurfaceTransitions {
+ constructor(surface) {
+ this.surface = surface;
+ }
+
+ has_running() {
+ return this.get_state().running;
+ }
+
+ get_state(include_descendants = false) {
+ const surface_actors = this.get_surface_actors();
+ const actors = include_descendants
+ ? this.get_actors(surface_actors)
+ : surface_actors;
+ const geometry_properties = this.get_running_properties(
+ GEOMETRY_TRANSITION_PROPERTIES,
+ actors
+ );
+ const opacity = this.has_running_for(['opacity'], surface_actors);
+
+ return {
+ complete: include_descendants,
+ running: opacity || geometry_properties.size > 0,
+ geometry: geometry_properties.size > 0,
+ geometry_properties,
+ opacity,
+ };
+ }
+
+ complete_state(transition_state) {
+ if (transition_state.complete)
+ return transition_state;
+
+ return this.get_state(true);
+ }
+
+ has_running_for(properties, actors) {
+ return actors.some(actor =>
+ properties.some(property => this.has_transition(actor, property))
+ );
+ }
+
+ get_running_properties(properties, actors) {
+ const running_properties = new Set();
+
+ actors.forEach(actor => {
+ properties.forEach(property => {
+ if (this.has_transition(actor, property))
+ running_properties.add(this.normalize_property(property));
+ });
+ });
+
+ return running_properties;
+ }
+
+ normalize_property(property) {
+ return property.replace(/_/g, '-');
+ }
+
+ get_actors(surface_actors = this.get_surface_actors()) {
+ const actors = [...surface_actors];
+ const seen = new WeakSet();
+ actors.forEach(actor => seen.add(actor));
+
+ if (!this.surface.is_quick_settings()) {
+ this.add_descendants(actors, seen, this.surface.target);
+ this.add_descendants(actors, seen, this.surface.root_actor);
+ }
+
+ return actors;
+ }
+
+ get_surface_actors() {
+ const actors = [];
+ const seen = new WeakSet();
+
+ this.add_actor(actors, seen, this.surface.target);
+ this.add_actor(actors, seen, this.surface.root_actor);
+ this.add_actor(actors, seen, this.surface.get_geometry_actor());
+ this.add_ancestors(actors, seen, this.surface.target);
+ this.add_ancestors(actors, seen, this.surface.root_actor);
+
+ return actors;
+ }
+
+ add_actor(actors, seen, actor) {
+ if (!actor || seen.has(actor))
+ return;
+
+ seen.add(actor);
+ actors.push(actor);
+ }
+
+ add_ancestors(actors, seen, actor) {
+ actor = actor?.get_parent();
+ while (actor && actor !== this.surface.parent) {
+ this.add_actor(actors, seen, actor);
+ actor = actor.get_parent();
+ }
+ }
+
+ add_descendants(actors, seen, actor) {
+ const stack = this.get_children(actor).slice().reverse();
+
+ while (stack.length > 0) {
+ const child = stack.pop();
+ if (seen.has(child))
+ continue;
+
+ this.add_actor(actors, seen, child);
+ stack.push(...this.get_children(child).slice().reverse());
+ }
+ }
+
+ has_transition(actor, property) {
+ return !!actor?.get_transition(property);
+ }
+
+ get_children(actor) {
+ return actor ? actor.get_children() : [];
+ }
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/targets.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/targets.js
new file mode 100644
index 0000000..dd537b0
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/targets.js
@@ -0,0 +1,255 @@
+const POPUP_STYLE_CLASSES = ['popup-menu', 'quick-toggle-menu-container', 'candidate-popup-boxpointer'];
+const POPUP_TARGET_STYLE_CLASSES = ['popup-menu-content', 'quick-settings', 'quick-toggle-menu', 'notification-banner', 'candidate-popup-content','screenshot-ui-panel'];
+const POPUP_CHILD_STYLE_CLASSES = ['osd-window', 'resize-popup', 'switcher-list', 'workspace-switcher', 'modal-dialog', 'run-dialog'];
+const POPUP_TARGET_STYLE_CLASSES_OSK = ['bms-keyboard-surface']
+const POPUP_DESCENDANT_TARGET_STYLE_CLASSES = ['switcher-list'];
+
+export const POPUP_BACKGROUND_STYLES = ['bms-popup-background-transparent', 'bms-popup-background-light', 'bms-popup-background-dark'];
+export const POPUP_SURFACE_STYLES = POPUP_BACKGROUND_STYLES.map(
+ style => style.replace('bms-popup-background-', 'bms-popup-surface-')
+);
+export const DEFAULT_CORNER_RADIUS = { key: 'corner-radius', property: 'CORNER_RADIUS' };
+export const POPUP_CORNER_RADII = [
+ {
+ key: 'quick-settings-corner-radius',
+ property: 'QUICK_SETTINGS_CORNER_RADIUS',
+ style_classes: ['quick-settings', 'quick-toggle-menu', 'datemenu-popover','screenshot-ui-panel'],
+ },
+ {
+ key: 'notification-corner-radius',
+ property: 'NOTIFICATION_CORNER_RADIUS',
+ style_classes: ['notification-banner', 'message', 'message-view', 'message-list'],
+ },
+ {
+ key: 'menu-corner-radius',
+ property: 'MENU_CORNER_RADIUS',
+ style_classes: ['popup-menu-content', 'popup-menu', 'candidate-popup-content', 'candidate-popup-boxpointer'],
+ },
+ {
+ key: 'osd-corner-radius',
+ property: 'OSD_CORNER_RADIUS',
+ style_classes: ['osd-window', 'resize-popup', 'switcher-list', 'workspace-switcher'],
+ },
+ {
+ key: 'dialog-corner-radius',
+ property: 'DIALOG_CORNER_RADIUS',
+ style_classes: ['modal-dialog', 'run-dialog'],
+ },
+ {
+ key: 'osk-corner-radius',
+ property: 'OSK_CORNER_RADIUS',
+ style_classes: ['bms-keyboard-surface'],
+ },
+];
+
+export const PopupBlurTargets = class PopupBlurTargets {
+ constructor(actor) {
+ this.actor = actor;
+ this.style_cache = null;
+ }
+
+ find(actor) {
+ return this.with_style_cache(() => this.find_actor(actor));
+ }
+
+ find_actor(actor) {
+ if (this.actor.is_internal_actor(actor) || !this.actor.watch_actor(actor))
+ return [];
+
+ const targets = this.create_targets();
+ const delegate = this.actor.get_actor_delegate(actor);
+
+ if (this.prefers_descendant_targets(actor)) {
+ this.find_target_children(actor, targets);
+ if (targets.actors.length > 0)
+ return targets.actors;
+ }
+
+ if (this.actor.watch_actor(delegate?.box) && (this.has_any_style_class(delegate.box, POPUP_TARGET_STYLE_CLASSES) || this.has_any_style_class(delegate.box, POPUP_TARGET_STYLE_CLASSES_OSK)))
+ this.add(targets, delegate.box);
+
+ if (this.has_any_style_class(actor, POPUP_TARGET_STYLE_CLASSES))
+ this.add(targets, actor);
+
+ if (this.has_any_style_class(actor, POPUP_TARGET_STYLE_CLASSES_OSK))
+ this.add(targets, actor);
+
+ if (this.has_any_style_class(actor, POPUP_CHILD_STYLE_CLASSES))
+ this.add(targets, actor);
+
+ const dialog_layout = this.actor.get_actor_dialog_layout(actor);
+ if (this.actor.watch_actor(dialog_layout) && this.has_any_style_class(dialog_layout, POPUP_CHILD_STYLE_CLASSES))
+ this.add(targets, dialog_layout);
+
+ if (targets.actors.length === 0)
+ this.find_target_children(actor, targets);
+
+ if (
+ targets.actors.length === 0
+ && this.has_any_style_class(actor, POPUP_STYLE_CLASSES)
+ )
+ this.add(targets, actor);
+
+ return targets.actors;
+ }
+
+ find_target_children(actor, targets, seen = new WeakSet()) {
+ const stack = this.get_children(actor)
+ .slice()
+ .reverse()
+ .map(child => ({ actor: child, fallback_count: null }));
+
+ while (stack.length > 0) {
+ const { actor: child, fallback_count } = stack.pop();
+ if (
+ !child
+ || this.actor.is_internal_actor(child)
+ )
+ continue;
+
+ if (fallback_count !== null) {
+ if (
+ targets.actors.length === fallback_count
+ && this.is_blur_target_actor(child)
+ )
+ this.add(targets, child);
+ continue;
+ }
+
+ if (seen.has(child))
+ continue;
+
+ seen.add(child);
+
+ if (this.prefers_descendant_targets(child)) {
+ const children = this.get_children(child);
+ if (children.length > 0) {
+ stack.push({
+ actor: child,
+ fallback_count: targets.actors.length,
+ });
+ this.push_children(stack, children);
+ continue;
+ }
+ }
+
+ if (this.is_blur_target_actor(child)) {
+ this.add(targets, child);
+ continue;
+ }
+
+ this.push_children(stack, this.get_children(child));
+ }
+ }
+
+ prefers_descendant_targets(actor) {
+ return this.has_any_style_class(actor, POPUP_DESCENDANT_TARGET_STYLE_CLASSES);
+ }
+
+ is_blur_target_actor(actor) {
+ return (
+ this.has_any_style_class(actor, POPUP_TARGET_STYLE_CLASSES)
+ || this.has_any_style_class(actor, POPUP_TARGET_STYLE_CLASSES_OSK)
+ || this.has_any_style_class(actor, POPUP_CHILD_STYLE_CLASSES)
+ );
+ }
+
+ get_corner_radius(target, root_actor) {
+ return POPUP_CORNER_RADII.find(radius =>
+ this.has_any_style_class(target, radius.style_classes)
+ || this.has_any_style_class(root_actor, radius.style_classes)
+ ) ?? DEFAULT_CORNER_RADIUS;
+ }
+
+ with_style_cache(callback) {
+ const previous_cache = this.style_cache;
+ this.style_cache = new WeakMap();
+
+ try {
+ return callback();
+ } finally {
+ this.style_cache = previous_cache;
+ }
+ }
+
+ has_any_style_class(actor, style_classes) {
+ if (!actor)
+ return false;
+
+ const classes = this.get_style_classes(actor);
+ if (classes)
+ return style_classes.some(style_class => classes.has(style_class));
+
+ return style_classes.some(style_class => this.has_style_class(actor, style_class));
+ }
+
+ has_style_class(actor, style_class) {
+ return has_style_class(actor, style_class);
+ }
+
+ get_style_classes(actor) {
+ if (!actor || !this.style_cache)
+ return null;
+
+ if (this.style_cache.has(actor))
+ return this.style_cache.get(actor);
+
+ if (!actor.get_style_class_name) {
+ this.style_cache.set(actor, null);
+ return null;
+ }
+
+ const class_names = actor.get_style_class_name();
+ if (typeof class_names !== 'string') {
+ this.style_cache.set(actor, null);
+ return null;
+ }
+
+ const classes = new Set(class_names.split(/\s+/).filter(Boolean));
+ this.style_cache.set(actor, classes);
+ return classes;
+ }
+
+ create_targets() {
+ return {
+ actors: [],
+ seen: new WeakSet(),
+ };
+ }
+
+ get_children(actor) {
+ return actor ? actor.get_children() : [];
+ }
+
+ push_children(stack, children) {
+ children
+ .slice()
+ .reverse()
+ .forEach(child => stack.push({ actor: child, fallback_count: null }));
+ }
+
+ add(targets, target) {
+ if (
+ this.actor.is_internal_actor(target)
+ || !this.actor.watch_actor(target)
+ || targets.seen.has(target)
+ )
+ return;
+
+ targets.seen.add(target);
+ targets.actors.push(target);
+ }
+};
+
+export function has_style_class(actor, style_class) {
+ if (!actor || !style_class)
+ return false;
+
+ if (actor.has_style_class_name)
+ return actor.has_style_class_name(style_class);
+
+ if (actor.get_style_class_name)
+ return (actor.get_style_class_name() ?? '').split(/\s+/).includes(style_class);
+
+ return false;
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/window_list.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/window_list.js
index 6ab0644..33a9be3 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/window_list.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/window_list.js
@@ -66,7 +66,7 @@ export const WindowListBlur = class WindowListBlur {
this.connections.connect(
actor,
'destroy',
- _ => this.destroy_blur(pipeline, true)
+ _ => this.destroy_blur(pipeline)
);
@@ -98,8 +98,8 @@ export const WindowListBlur = class WindowListBlur {
}
// IMPORTANT: do never call this in a mutable `this.pipelines.forEach`
- destroy_blur(pipeline, actor_destroyed = false) {
- if (!actor_destroyed) {
+ destroy_blur(pipeline) {
+ if (pipeline.actor) {
this.remove_style(pipeline.actor);
this.paint_signals.disconnect_all_for_actor(pipeline.actor);
}
@@ -108,7 +108,7 @@ export const WindowListBlur = class WindowListBlur {
let index = this.pipelines.indexOf(pipeline);
if (index >= 0)
- this.pipelines.splice(pipeline, 1);
+ this.pipelines.splice(index, 1);
}
remove_style(actor) {
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js
index 0583db3..8d17b62 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js
@@ -1,106 +1,98 @@
import GObject from 'gi://GObject';
-/// An object to easily manage signals.
+function supports_destroy_signal(object) {
+ const gtype = object?.constructor?.$gtype;
+ return gtype && GObject.signal_lookup('destroy', gtype) !== 0;
+}
+
export const Connections = class Connections {
constructor() {
- this.buffer = [];
+ this.records = new Map();
}
- /// Adds a connection.
- ///
- /// Takes as arguments:
- /// - an actor, which fires the signal
- /// - signal(s) (string or array of strings), which are watched for
- /// - a callback, which is called when the signal is fired
- connect(actor, signals, handler) {
- if (signals instanceof Array) {
- signals.forEach(signal => {
- let id = actor.connect(signal, handler);
- this.process_connection(actor, id);
- });
- } else {
- let id = actor.connect(signals, handler);
- this.process_connection(actor, id);
- }
+ connect(object, signals, handler) {
+ const names = Array.isArray(signals) ? signals : [signals];
+ const record = this.get_record(object);
+ const ids = [];
+ for (const signal of names) {
+ const id = object.connect(signal, handler);
+ record.ids.add(id);
+ ids.push(id);
+ }
+ return Array.isArray(signals) ? ids : ids[0];
}
- /// Process the given actor and id.
- ///
- /// This makes sure that the signal is disconnected when the actor is
- /// destroyed, and that the signal can be managed through other Connections
- /// methods.
- process_connection(actor, id) {
- let infos = {
- actor: actor,
- id: id
- };
+ get_record(object) {
+ let record = this.records.get(object);
+ if (record)
+ return record;
- // remove the signal when the actor is destroyed
- if (
- actor.connect &&
- (
- !(actor instanceof GObject.Object) ||
- GObject.signal_lookup('destroy', actor)
- )
- ) {
- let destroy_id = actor.connect('destroy', () => {
- actor.disconnect(id);
- actor.disconnect(destroy_id);
+ record = {
+ ids: new Set(),
+ destroy_id: null,
+ };
+ this.records.set(object, record);
- let index = this.buffer.indexOf(infos);
- if (index >= 0) {
- this.buffer.splice(index, 1);
- }
+ if (supports_destroy_signal(object))
+ record.destroy_id = object.connect('destroy', () => {
+ this.records.delete(object);
+ record.ids.clear();
+ record.destroy_id = null;
});
- infos.destroy_id = destroy_id;
- }
- this.buffer.push(infos);
+ return record;
}
- /// Disconnects every connection found for an actor.
- disconnect_all_for(actor) {
- // get every connection stored for the actor
- let actor_connections = this.buffer.filter(
- infos => infos.actor === actor
- );
+ disconnect_all_for(object) {
+ const record = this.records.get(object);
+ if (!record)
+ return;
- // remove each of them
- actor_connections.forEach(connection => {
- // disconnect
- try {
- connection.actor.disconnect(connection.id);
- if ('destroy_id' in connection)
- connection.actor.disconnect(connection.destroy_id);
- } catch (e) {
- this._warn(`error removing connection: ${e}; continuing`);
- }
-
- // remove from buffer
- let index = this.buffer.indexOf(connection);
- this.buffer.splice(index, 1);
- });
+ this.records.delete(object);
+ for (const id of record.ids)
+ this.raw_disconnect(object, id);
+ if (record.destroy_id)
+ this.raw_disconnect(object, record.destroy_id);
}
- /// Disconnect every connection for each actor.
disconnect_all() {
- this.buffer.forEach(connection => {
- // disconnect
- try {
- connection.actor.disconnect(connection.id);
- if ('destroy_id' in connection)
- connection.actor.disconnect(connection.destroy_id);
- } catch (e) {
- this._warn(`error removing connection: ${e}; continuing`);
- }
- });
+ for (const object of [...this.records.keys()])
+ this.disconnect_all_for(object);
+ }
- // reset buffer
- this.buffer = [];
+ disconnect(object, id) {
+ const record = this.records.get(object);
+ if (record)
+ record.ids.delete(id);
+
+ this.raw_disconnect(object, id);
+
+ if (record && record.ids.size === 0) {
+ this.records.delete(object);
+ if (record.destroy_id)
+ this.raw_disconnect(object, record.destroy_id);
+ }
+ }
+
+ raw_disconnect(object, id) {
+ if (!id)
+ return;
+
+ try {
+ if (
+ object instanceof GObject.Object
+ && !GObject.signal_handler_is_connected(object, id)
+ )
+ return;
+
+ object.disconnect(id);
+ } catch (error) {
+ this._warn(`error removing connection: ${error}; continuing`);
+ }
}
_warn(str) {
console.warn(`[Blur my Shell > connections] ${str}`);
}
-}; \ No newline at end of file
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/dummy_pipeline.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/dummy_pipeline.js
index 02b2d13..4d71d46 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/dummy_pipeline.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/dummy_pipeline.js
@@ -4,9 +4,12 @@ import Clutter from 'gi://Clutter';
/// A dummy `Pipeline`, for dynamic blur only.
/// Instead of a pipeline id, we take the settings of the component we want to blur.
export const DummyPipeline = class DummyPipeline {
- constructor(effects_manager, settings, actor = null) {
+ constructor(effects_manager, settings, actor = null, options = {}) {
this.effects_manager = effects_manager;
this.settings = settings;
+ this.corner_radius_key = options.corner_radius_key ?? 'corner-radius';
+ this.corner_radius_getter = options.corner_radius_getter ?? (() => this.settings.CORNER_RADIUS);
+ this.opacity_factor = 1;
this.effect = null;
this.attach_effect_to_actor(actor);
}
@@ -41,9 +44,9 @@ export const DummyPipeline = class DummyPipeline {
// build the new effect to be added
this.build_effect({
- unscaled_radius: 2 * this.settings.SIGMA,
- brightness: this.settings.BRIGHTNESS,
- corner_radius: this.settings.CORNER_RADIUS,
+ unscaled_radius: this.get_unscaled_radius(),
+ brightness: this.get_brightness(),
+ unscaled_corner_radius: this.corner_radius_getter(),
});
this.actor_destroy_id = this.actor.connect(
@@ -70,17 +73,40 @@ export const DummyPipeline = class DummyPipeline {
this.effect = this.effects_manager.new_native_dynamic_gaussian_blur_effect(params);
// connect to settings changes, using the true gsettings object
- this._sigma_changed_id = this.settings.settings.connect(
- 'changed::sigma', () => this.effect.unscaled_radius = 2 * this.settings.SIGMA
- );
- this._brightness_changed_id = this.settings.settings.connect(
- 'changed::brightness', () => this.effect.brightness = this.settings.BRIGHTNESS
- );
+ this._sigma_changed_id = this.settings.settings.connect('changed::sigma', () => this.update_effect());
+ this._brightness_changed_id = this.settings.settings.connect('changed::brightness', () => this.update_effect());
this._corner_radius_changed_id = this.settings.settings.connect(
- 'changed::corner-radius', () => this.effect.corner_radius = this.settings.CORNER_RADIUS
+ `changed::${this.corner_radius_key}`,
+ () => this.update_effect()
);
}
+ set_opacity_factor(opacity_factor) {
+ opacity_factor = Math.max(0, Math.min(1, opacity_factor));
+ if (this.opacity_factor === opacity_factor)
+ return;
+
+ this.opacity_factor = opacity_factor;
+ this.update_effect();
+ }
+
+ update_effect() {
+ if (!this.effect)
+ return;
+
+ this.effect.unscaled_radius = this.get_unscaled_radius();
+ this.effect.brightness = this.get_brightness();
+ this.effect.unscaled_corner_radius = this.corner_radius_getter();
+ }
+
+ get_unscaled_radius() {
+ return 2 * this.settings.SIGMA * this.opacity_factor;
+ }
+
+ get_brightness() {
+ return 1 - (1 - this.settings.BRIGHTNESS) * this.opacity_factor;
+ }
+
repaint_effect() {
this.effect?.queue_repaint();
}
@@ -109,7 +135,6 @@ export const DummyPipeline = class DummyPipeline {
/// Note: exposed to public API.
destroy() {
- this.remove_effect();
this.remove_pipeline_from_actor();
}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/effects_manager.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/effects_manager.js
index 947d535..8b99396 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/effects_manager.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/effects_manager.js
@@ -4,7 +4,7 @@ import { get_supported_effects } from '../effects/effects.js';
export const EffectsManager = class EffectsManager {
constructor(connections) {
this.connections = connections;
- this.used = [];
+ this.used = new Set();
this.SUPPORTED_EFFECTS = get_supported_effects();
Object.keys(this.SUPPORTED_EFFECTS).forEach(effect_name => {
@@ -15,60 +15,56 @@ export const EffectsManager = class EffectsManager {
this['new_' + effect_name + '_effect'] = function (params) {
let effect;
if (this[effect_name + '_effects'].length > 0) {
- effect = this[effect_name + '_effects'].splice(0, 1)[0];
+ effect = this[effect_name + '_effects'].pop();
effect.set({
...this.SUPPORTED_EFFECTS[effect_name].class.default_params, ...params
});
- } else
+ } else {
effect = new this.SUPPORTED_EFFECTS[effect_name].class({
...this.SUPPORTED_EFFECTS[effect_name].class.default_params, ...params
});
+ this.connect_to_destroy(effect);
+ }
- this.used.push(effect);
- this.connect_to_destroy(effect);
+ this.used.add(effect);
return effect;
};
});
}
connect_to_destroy(effect) {
- effect.old_actor = effect.get_actor();
- if (effect.old_actor)
- effect.old_actor_id = effect.old_actor.connect('destroy', _ => {
- this.remove(effect, true);
- });
-
- this.connections.connect(effect, 'notify::actor', _ => {
- let actor = effect.get_actor();
+ const update_actor = () => {
+ const actor = effect.get_actor();
+ if (actor === effect._bms_actor)
+ return;
- if (effect.old_actor && actor != effect.old_actor)
- effect.old_actor.disconnect(effect.old_actor_id);
+ this.disconnect_actor_destroy(effect);
+ effect._bms_actor = actor;
+ if (actor)
+ effect._bms_actor_destroy_id = actor.connect(
+ 'destroy', () => this.remove(effect, true)
+ );
+ };
- if (actor && actor != effect.old_actor) {
- effect.old_actor_id = actor.connect('destroy', _ => {
- this.remove(effect, true);
- });
- }
- });
+ this.connections.connect(effect, 'notify::actor', update_actor);
+ update_actor();
}
- // IMPORTANT: do never call this in a mutable `this.used.forEach`
- remove(effect, actor_already_destroyed = false) {
- if (!actor_already_destroyed)
- try {
- effect.get_actor()?.remove_effect(effect);
- } catch (e) {
- this._warn(`could not remove the effect, continuing: ${e}`);
- }
- if (effect.old_actor)
- effect.old_actor.disconnect(effect.old_actor_id);
- delete effect.old_actor;
- delete effect.old_actor_id;
+ disconnect_actor_destroy(effect) {
+ if (effect._bms_actor && effect._bms_actor_destroy_id) {
+ effect._bms_actor.disconnect(effect._bms_actor_destroy_id);
+ }
+ effect._bms_actor = null;
+ effect._bms_actor_destroy_id = null;
+ }
- let index = this.used.indexOf(effect);
- if (index >= 0) {
- this.used.splice(index, 1);
+ remove(effect) {
+ const actor = effect.get_actor();
+ if (actor)
+ actor.remove_effect(effect);
+ this.disconnect_actor_destroy(effect);
+ if (this.used.delete(effect)) {
Object.keys(this.SUPPORTED_EFFECTS).forEach(effect_name => {
if (effect instanceof this.SUPPORTED_EFFECTS[effect_name].class)
this[effect_name + '_effects'].push(effect);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/keys.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/keys.js
index d821b88..0876d16 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/keys.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/keys.js
@@ -38,6 +38,9 @@ export const KEYS = [
{ type: Type.B, name: "override-background" },
{ type: Type.I, name: "style-panel" },
{ type: Type.B, name: "override-background-dynamically" },
+ { type: Type.I, name: "override-background-dynamically-mode" },
+ { type: Type.B, name: "gradient-panel" },
+ { type: Type.I, name: "gradient-panel-mode" },
]
},
{
@@ -65,6 +68,7 @@ export const KEYS = [
{ type: Type.I, name: "opacity" },
{ type: Type.B, name: "dynamic-opacity" },
{ type: Type.B, name: "blur-on-overview" },
+ { type: Type.B, name: "unblur-when-fullscreen" },
{ type: Type.B, name: "enable-all" },
{ type: Type.AS, name: "whitelist" },
{ type: Type.AS, name: "blacklist" },
@@ -97,6 +101,25 @@ export const KEYS = [
]
},
{
+ component: "popup", schemas: [
+ { type: Type.B, name: "blur" },
+ { type: Type.B, name: "static-blur" },
+ { type: Type.S, name: "pipeline" },
+ { type: Type.I, name: "sigma" },
+ { type: Type.D, name: "brightness" },
+ { type: Type.I, name: "corner-radius" },
+ { type: Type.I, name: "menu-corner-radius" },
+ { type: Type.I, name: "quick-settings-corner-radius" },
+ { type: Type.I, name: "notification-corner-radius" },
+ { type: Type.I, name: "osd-corner-radius" },
+ { type: Type.I, name: "dialog-corner-radius" },
+ { type: Type.I, name: "osk-corner-radius" },
+ { type: Type.B, name: "override-background" },
+ { type: Type.B, name: "preserve-shell-theme" },
+ { type: Type.I, name: "style-popup" },
+ ]
+ },
+ {
component: "hidetopbar", schemas: [
{ type: Type.B, name: "compatibility" },
]
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/paint_signals.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/paint_signals.js
index 5fbfee4..10a6d26 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/paint_signals.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/paint_signals.js
@@ -1,91 +1,64 @@
import GObject from 'gi://GObject';
import Clutter from 'gi://Clutter';
+const PAINTS_BETWEEN_REPAINTS = 2;
export const PaintSignals = class PaintSignals {
constructor(connections) {
- this.buffer = [];
+ this.entries = new Map();
this.connections = connections;
}
connect(actor, blur_effect) {
- let paint_effect = new EmitPaintSignal();
- let infos = {
- actor: actor,
- paint_effect: paint_effect
- };
- let counter = 0;
+ this.disconnect_all_for_actor(actor);
- actor.add_effect(paint_effect);
- this.connections.connect(paint_effect, 'update-blur', () => {
- try {
- // checking if blur_effect.queue_repaint() has been recently called
- if (counter === 0) {
- counter = 2;
- blur_effect.queue_repaint();
- }
- else counter--;
- } catch (e) { }
- });
+ let paints_to_skip = 0;
+ const paint_effect = new PaintCallbackEffect();
+ paint_effect.set_callback(() => {
+ if (paints_to_skip > 0) {
+ paints_to_skip--;
+ return;
+ }
- // remove the actor from buffer when it is destroyed
- if (
- actor.connect &&
- (
- !(actor instanceof GObject.Object) ||
- GObject.signal_lookup('destroy', actor)
- )
- )
- this.connections.connect(actor, 'destroy', () => {
- const immutable_buffer = [...this.buffer];
- immutable_buffer.forEach(infos => {
- if (infos.actor === actor) {
- // remove from buffer
- let index = this.buffer.indexOf(infos);
- this.buffer.splice(index, 1);
- }
- });
- });
+ paints_to_skip = PAINTS_BETWEEN_REPAINTS;
+ blur_effect.queue_repaint();
+ });
- this.buffer.push(infos);
+ actor.add_effect(paint_effect);
+ const destroy_id = this.connections.connect(actor, 'destroy', () => {
+ paint_effect.set_callback(null);
+ this.entries.delete(actor);
+ });
+ this.entries.set(actor, { paint_effect, destroy_id });
}
disconnect_all_for_actor(actor) {
- const immutable_buffer = [...this.buffer];
- immutable_buffer.forEach(infos => {
- if (infos.actor === actor) {
- this.connections.disconnect_all_for(infos.paint_effect);
- infos.actor.remove_effect(infos.paint_effect);
+ const entry = this.entries.get(actor);
+ if (!entry)
+ return;
- // remove from buffer
- let index = this.buffer.indexOf(infos);
- this.buffer.splice(index, 1);
- }
- });
+ this.entries.delete(actor);
+ entry.paint_effect.set_callback(null);
+ this.connections.disconnect(actor, entry.destroy_id);
+ actor.remove_effect(entry.paint_effect);
}
disconnect_all() {
- this.buffer.forEach(infos => {
- this.connections.disconnect_all_for(infos.paint_effect);
- infos.actor.remove_effect(infos.paint_effect);
- });
-
- this.buffer = [];
+ for (const actor of [...this.entries.keys()])
+ this.disconnect_all_for_actor(actor);
}
};
-export const EmitPaintSignal = GObject.registerClass({
- GTypeName: 'EmitPaintSignal',
- Signals: {
- 'update-blur': {
- param_types: []
- },
- }
-},
- class EmitPaintSignal extends Clutter.Effect {
+const PaintCallbackEffect = GObject.registerClass(
+ { GTypeName: 'BmsPaintCallbackEffect' },
+ class PaintCallbackEffect extends Clutter.Effect {
+ set_callback(callback) {
+ this._callback = callback;
+ }
+
vfunc_paint(node, paint_context, paint_flags) {
- this.emit("update-blur");
+ this._callback();
super.vfunc_paint(node, paint_context, paint_flags);
}
}
-); \ No newline at end of file
+);
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
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline_settings.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline_settings.js
new file mode 100644
index 0000000..eb5c173
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline_settings.js
@@ -0,0 +1,136 @@
+import GLib from 'gi://GLib';
+
+function is_plain_object(value) {
+ return value !== null
+ && typeof value === 'object'
+ && value.constructor === Object;
+}
+
+function unpack_string(value, label) {
+ const unpacked = value?.deep_unpack();
+ if (typeof unpacked !== 'string')
+ throw new Error(`${label} is not a string`);
+
+ return unpacked;
+}
+
+function unpack_effect(effect_variant) {
+ const effect = effect_variant?.deep_unpack();
+ if (!is_plain_object(effect))
+ throw new Error('effect is not an object');
+ if (!('type' in effect))
+ throw new Error('effect has no type');
+ if (!('id' in effect))
+ throw new Error('effect has no id');
+
+ const params = 'params' in effect ? effect.params.deep_unpack() : {};
+ if (!is_plain_object(params))
+ throw new Error('effect params is not an object');
+
+ return {
+ type: unpack_string(effect.type, 'effect type'),
+ id: unpack_string(effect.id, 'effect id'),
+ params: Object.fromEntries(
+ Object.entries(params).map(([key, value]) => [key, value.deep_unpack()])
+ ),
+ };
+}
+
+export function unpack_pipelines(value) {
+ const unpacked = value.deep_unpack();
+ if (!is_plain_object(unpacked))
+ throw new Error('pipelines is not an object');
+
+ const pipelines = {};
+ for (const [pipeline_id, pipeline] of Object.entries(unpacked)) {
+ if (!is_plain_object(pipeline))
+ throw new Error(`pipeline ${pipeline_id} is not an object`);
+ if (!('name' in pipeline))
+ throw new Error(`pipeline ${pipeline_id} has no name`);
+ if (!('effects' in pipeline))
+ throw new Error(`pipeline ${pipeline_id} has no effects`);
+
+ const effects = pipeline.effects.deep_unpack();
+ if (!Array.isArray(effects))
+ throw new Error(`pipeline ${pipeline_id} effects is not an array`);
+
+ pipelines[pipeline_id] = {
+ name: unpack_string(pipeline.name, `pipeline ${pipeline_id} name`),
+ effects: effects.map(unpack_effect),
+ };
+ }
+
+ return pipelines;
+}
+
+function pack_param(value, label) {
+ if (typeof value === 'boolean')
+ return GLib.Variant.new_boolean(value);
+ if (typeof value === 'number')
+ return Number.isInteger(value)
+ ? GLib.Variant.new_int32(value)
+ : GLib.Variant.new_double(value);
+ if (typeof value === 'string')
+ return GLib.Variant.new_string(value);
+ if (
+ Array.isArray(value)
+ && value.length === 4
+ && value.every(component => typeof component === 'number')
+ )
+ return new GLib.Variant('(dddd)', value);
+
+ throw new Error(`${label} has an unsupported type`);
+}
+
+function pack_effect(effect, label) {
+ if (!is_plain_object(effect))
+ throw new Error(`${label} is not an object`);
+ if (typeof effect.type !== 'string')
+ throw new Error(`${label} type is not a string`);
+ if (typeof effect.id !== 'string')
+ throw new Error(`${label} id is not a string`);
+
+ const params = effect.params ?? {};
+ if (!is_plain_object(params))
+ throw new Error(`${label} params is not an object`);
+
+ const packed_params = Object.fromEntries(
+ Object.entries(params).map(([key, value]) => [
+ key,
+ pack_param(value, `${label} parameter ${key}`),
+ ])
+ );
+
+ return new GLib.Variant('a{sv}', {
+ type: GLib.Variant.new_string(effect.type),
+ id: GLib.Variant.new_string(effect.id),
+ params: new GLib.Variant('a{sv}', packed_params),
+ });
+}
+
+export function pack_pipelines(pipelines) {
+ if (!is_plain_object(pipelines))
+ throw new Error('pipelines is not an object');
+
+ const packed = {};
+ for (const [pipeline_id, pipeline] of Object.entries(pipelines)) {
+ if (!is_plain_object(pipeline))
+ throw new Error(`pipeline ${pipeline_id} is not an object`);
+ if (typeof pipeline.name !== 'string')
+ throw new Error(`pipeline ${pipeline_id} name is not a string`);
+ if (!Array.isArray(pipeline.effects))
+ throw new Error(`pipeline ${pipeline_id} effects is not an array`);
+
+ packed[pipeline_id] = {
+ name: GLib.Variant.new_string(pipeline.name),
+ effects: new GLib.Variant(
+ 'av',
+ pipeline.effects.map((effect, index) =>
+ pack_effect(effect, `pipeline ${pipeline_id} effect ${index}`)
+ )
+ ),
+ };
+ }
+
+ return new GLib.Variant('a{sa{sv}}', packed);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipelines_manager.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipelines_manager.js
index 0fdfe9e..6d9749a 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipelines_manager.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipelines_manager.js
@@ -1,5 +1,23 @@
+import GLib from 'gi://GLib';
+
const Signals = imports.signals;
+function new_id(prefix) {
+ return `${prefix}_${GLib.uuid_string_random()}`;
+}
+
+function clone_effect(effect) {
+ return {
+ ...effect,
+ params: Object.fromEntries(
+ Object.entries(effect.params ?? {}).map(([key, value]) => [
+ key,
+ Array.isArray(value) ? [...value] : value,
+ ])
+ ),
+ };
+}
+
/// The `PipelinesManager` object permits to store the list of pipelines and their effects in
/// memory. It is meant to *always* be in sync with the `org.gnome.shell.extensions.blur-my-shell`'s
/// `pipelines` gschema. However, we do not want to re-create every effect each time this schema is
@@ -36,10 +54,8 @@ export class PipelinesManager {
}
create_pipeline(name, effects = []) {
- // select a random id for the pipeline
- let id = "pipeline_" + ("" + Math.random()).slice(2, 16);
- // add a random ID for each effect, to help tracking them
- effects.forEach(effect => effect.id = "effect_" + ("" + Math.random()).slice(2, 16));
+ const id = new_id('pipeline');
+ effects.forEach(effect => effect.id = new_id('effect'));
this.pipelines[id] = { name, effects };
this.settings.PIPELINES = this.pipelines;
@@ -54,8 +70,10 @@ export class PipelinesManager {
return;
}
const pipeline = this.pipelines[id];
- this.create_pipeline(pipeline.name + " - duplicate", [...pipeline.effects]);
- this.settings.PIPELINES = this.pipelines;
+ this.create_pipeline(
+ `${pipeline.name} - duplicate`,
+ pipeline.effects.map(clone_effect)
+ );
}
delete_pipeline(id) {
@@ -89,7 +107,7 @@ export class PipelinesManager {
this._warn(`could not rename pipeline, id ${id} does not exist`);
return;
}
- this.pipelines[id].name = name.slice();
+ this.pipelines[id].name = name;
this.settings.PIPELINES = this.pipelines;
this._emit(id + '::pipeline-renamed', name);
this._emit('pipeline-names-changed');
@@ -98,8 +116,18 @@ export class PipelinesManager {
on_pipeline_update() {
const old_pipelines = this.pipelines;
this.pipelines = this.settings.PIPELINES;
+ const old_ids = Object.keys(old_pipelines);
+ const new_ids = Object.keys(this.pipelines);
+ const list_changed = old_ids.length !== new_ids.length
+ || old_ids.some(id => !(id in this.pipelines));
+ let names_changed = false;
- for (var pipeline_id in old_pipelines) {
+ for (const pipeline_id of new_ids) {
+ if (!(pipeline_id in old_pipelines))
+ this._emit('pipeline-created', pipeline_id, this.pipelines[pipeline_id]);
+ }
+
+ for (const pipeline_id of old_ids) {
// if we find a pipeline that does not exist anymore, signal it
if (!(pipeline_id in this.pipelines)) {
this._emit(pipeline_id + '::pipeline-destroyed');
@@ -109,6 +137,11 @@ export class PipelinesManager {
const old_pipeline = old_pipelines[pipeline_id];
const new_pipeline = this.pipelines[pipeline_id];
+ if (old_pipeline.name !== new_pipeline.name) {
+ this._emit(pipeline_id + '::pipeline-renamed', new_pipeline.name);
+ names_changed = true;
+ }
+
// verify if both pipelines have effects in the same order
// if they have, then check for their parameters
if (
@@ -144,6 +177,11 @@ export class PipelinesManager {
else
this._emit(pipeline_id + '::pipeline-updated', new_pipeline);
}
+
+ if (list_changed)
+ this._emit('pipeline-list-changed');
+ if (names_changed)
+ this._emit('pipeline-names-changed');
}
destroy() {
@@ -165,4 +203,4 @@ export class PipelinesManager {
}
}
-Signals.addSignalMethods(PipelinesManager.prototype); \ No newline at end of file
+Signals.addSignalMethods(PipelinesManager.prototype);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings.js
index 53f8497..337c8c2 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings.js
@@ -1,4 +1,5 @@
import GLib from 'gi://GLib';
+import { pack_pipelines, unpack_pipelines } from './pipeline_settings.js';
const Signals = imports.signals;
/// An enum non-extensively describing the type of gsettings key.
@@ -122,171 +123,20 @@ export const Settings = class Settings {
case Type.PIPELINES:
Object.defineProperty(component, property_name, {
get() {
- let pips = component_settings.get_value(key.name).deep_unpack();
- Object.keys(pips).forEach(pipeline_id => {
- let pipeline = pips[pipeline_id];
-
- if (!('name' in pipeline)) {
- this._warn('impossible to get pipelines, pipeline has not name, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
- let name = pipeline.name.deep_unpack();
- if (typeof name !== 'string') {
- this._warn('impossible to get pipelines, pipeline name is not a string, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
-
- if (!('effects' in pipeline)) {
- this._warn('impossible to get pipelines, pipeline has not effects, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
- let effects = pipeline.effects.deep_unpack();
- if (!Array.isArray(effects)) {
- this._warn('impossible to get pipelines, pipeline effects is not an array, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
-
- effects = effects.map(effect => effect.deep_unpack());
- effects.forEach(effect => {
- if (!('type' in effect)) {
- this._warn('impossible to get pipelines, effect has not type, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
- let type = effect.type.deep_unpack();
- if (typeof type !== 'string') {
- this._warn('impossible to get pipelines, effect type is not a string, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
-
- if (!('id' in effect)) {
- this._warn('impossible to get pipelines, effect has not id, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
- let id = effect.id.deep_unpack();
- if (typeof id !== 'string') {
- this._warn('impossible to get pipelines, effect id is not a string, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
-
- let params = {};
- if ('params' in effect)
- params = effect.params.deep_unpack();
- if (!(params && typeof params === 'object' && params.constructor === Object)) {
- this._warn('impossible to get pipelines, effect params is not an object, resetting');
- component[property_name + '_reset']();
- return component[property_name];
- }
- Object.keys(params).forEach(param_key => {
- params[param_key] = params[param_key].deep_unpack();
- });
-
- effect.type = type;
- effect.id = id;
- effect.params = params;
- });
- pipeline.name = name;
- pipeline.effects = effects;
- });
- return pips;
+ try {
+ return unpack_pipelines(component_settings.get_value(key.name));
+ } catch (error) {
+ this._warn(`impossible to get pipelines, resetting: ${error.message}`);
+ component_settings.reset(key.name);
+ return unpack_pipelines(component_settings.get_value(key.name));
+ }
},
- set(pips) {
- let pipelines = {};
- Object.keys(pips).forEach(pipeline_id => {
- let pipeline = pips[pipeline_id];
- if (!(pipeline && typeof pipeline === 'object' && pipeline.constructor === Object)) {
- this._warn('impossible to set pipelines, pipeline is not an object');
- return;
- }
-
- if (!('name' in pipeline)) {
- this._warn('impossible to set pipelines, pipeline has no name');
- return;
- }
- if (typeof pipeline.name !== 'string') {
- this._warn('impossible to set pipelines, pipeline name is not a string');
- return;
- }
-
- if (!('effects' in pipeline)) {
- this._warn('impossible to set pipelines, pipeline has no effect');
- return;
- }
- if (!Array.isArray(pipeline.effects)) {
- this._warn('impossible to set pipelines, effects is not an array');
- return;
- }
-
- let gvariant_effects = [];
- pipeline.effects.forEach(effect => {
- if (!(effect instanceof Object)) {
- this._warn('impossible to set pipelines, effect is not an object');
- return;
- }
-
- if (!('type' in effect)) {
- this._warn('impossible to set pipelines, effect has not type');
- return;
- }
- if (typeof effect.type !== 'string') {
- this._warn('impossible to set pipelines, effect type is not a string');
- return;
- }
-
- if (!('id' in effect)) {
- this._warn('impossible to set pipelines, effect has not id');
- return;
- }
- if (typeof effect.id !== 'string') {
- this._warn('impossible to set pipelines, effect id is not a string');
- return;
- }
-
- let params = {};
- if ('params' in effect) {
- params = effect.params;
- }
- let gvariant_params = {};
- Object.keys(params).forEach(param_key => {
- let param = params[param_key];
- if (typeof param === 'boolean')
- gvariant_params[param_key] = GLib.Variant.new_boolean(param);
- else if (typeof param === 'number') {
- if (Number.isInteger(param))
- gvariant_params[param_key] = GLib.Variant.new_int32(param);
- else
- gvariant_params[param_key] = GLib.Variant.new_double(param);
- } else if (typeof param === 'string')
- gvariant_params[param_key] = GLib.Variant.new_string(param);
- else if (Array.isArray(param) && param.length == 4)
- gvariant_params[param_key] = new GLib.Variant("(dddd)", param);
- else
- this._warn('impossible to set pipeline, effect parameter type is unknown');
- });
-
- gvariant_effects.push(
- new GLib.Variant("a{sv}", {
- type: GLib.Variant.new_string(effect.type),
- id: GLib.Variant.new_string(effect.id),
- params: new GLib.Variant("a{sv}", gvariant_params)
- })
- );
- });
-
- pipelines[pipeline_id] = {
- name: GLib.Variant.new_string(pipeline.name),
- effects: new GLib.Variant("av", gvariant_effects)
- };
- });
- let val = new GLib.Variant("a{sa{sv}}", pipelines);
- component_settings.set_value(key.name, val);
+ set(pipelines) {
+ try {
+ component_settings.set_value(key.name, pack_pipelines(pipelines));
+ } catch (error) {
+ this._warn(`impossible to set pipelines: ${error.message}`);
+ }
}
});
break;
@@ -360,4 +210,4 @@ export const Settings = class Settings {
}
};
-Signals.addSignalMethods(Settings.prototype); \ No newline at end of file
+Signals.addSignalMethods(Settings.prototype);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/shader_uniforms.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/shader_uniforms.js
new file mode 100644
index 0000000..a82b261
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/shader_uniforms.js
@@ -0,0 +1,61 @@
+import GObject from 'gi://GObject';
+
+const INTEGRAL_UNIFORMS = new Set([
+ 'corners_bottom',
+ 'corners_top',
+ 'divider',
+ 'dir',
+ 'downsampling_mode',
+ 'factor',
+ 'iterations',
+ 'mode',
+ 'operation',
+ 'prefer_closer_pixels',
+ 'straight_corners',
+ 'use_base_pixel',
+]);
+
+export function set_uniform(effect, name, value) {
+ if (!effect._bms_uniforms)
+ effect._bms_uniforms = new Map();
+
+ effect._bms_uniforms.set(name, value);
+ effect._bms_uniforms_dirty = true;
+ effect.queue_repaint();
+}
+
+export function mark_dirty(effect) {
+ if (effect._bms_uniforms)
+ effect._bms_uniforms_dirty = true;
+}
+
+export function upload_uniforms(effect) {
+ if (!effect._bms_uniforms_dirty || !effect._bms_uniforms || !effect.get_actor())
+ return;
+
+ for (const [name, value] of effect._bms_uniforms) {
+ try {
+ effect.set_uniform_value(name, get_shader_value(name, value));
+ } catch (e) {
+ if (!effect._bms_uniform_warning_shown) {
+ effect._bms_uniform_warning_shown = true;
+ console.warn(`[Blur my Shell] shader uniform upload failed for ${effect.constructor.name}`, e);
+ }
+ }
+ }
+
+ effect._bms_uniforms_dirty = false;
+}
+
+function get_shader_value(name, value) {
+ if (typeof value !== 'number')
+ return value;
+
+ if (INTEGRAL_UNIFORMS.has(name))
+ return Math.trunc(value);
+
+ const float_value = new GObject.Value();
+ float_value.init(GObject.TYPE_FLOAT);
+ float_value.set_float(value);
+ return float_value;
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js
index 20def0b..b7bcff3 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js
@@ -1,4 +1,5 @@
import GLib from 'gi://GLib';
+import GObject from 'gi://GObject';
export const IS_IN_PREFERENCES = typeof global === 'undefined';
@@ -10,12 +11,32 @@ export async function import_in_shell_only(module) {
if (IS_IN_PREFERENCES)
return null;
try {
- return (await import(module)).default;
+ const imported = await import(module);
+ return imported.default ?? imported;
} catch (e) {
return null;
}
}
+const Clutter = await import_in_shell_only('gi://Clutter');
+const Cogl = await import_in_shell_only('gi://Cogl');
+const USES_SHADER_SNIPPET_API =
+ typeof Clutter?.ShaderEffect?.new_with_snippet === 'function';
+
+export function is_usable_blur_module(ns) {
+ if (!ns)
+ return false;
+ try {
+ const { BlurEffect } = ns;
+ if (typeof BlurEffect !== 'function' || !BlurEffect.$gtype)
+ return false;
+ GObject.type_name(BlurEffect.$gtype);
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
// In use for the effects, to prevent boilerplate code
export function setup_params(outer_this, params) {
// setup each parameter, either with the given or the default value
@@ -39,4 +60,87 @@ export const get_shader_source = (Shell, shader_filename, self_uri) => {
console.warn(`[Blur my Shell > effect] error loading shader from ${shader_path}: ${e}`);
return null;
}
-}; \ No newline at end of file
+};
+
+export function subpixel_stage_offset() {
+ return USES_SHADER_SNIPPET_API ? 0 : 0.5;
+}
+
+export function static_blur_clip_inset() {
+ return USES_SHADER_SNIPPET_API ? 1 : 0;
+}
+
+export function register_shader_effect(meta, effect_class, source) {
+ if (USES_SHADER_SNIPPET_API) {
+ Object.defineProperty(effect_class.prototype, 'vfunc_get_static_snippet', {
+ value() {
+ return create_fragment_shader_snippet(source);
+ },
+ });
+ }
+
+ return GObject.registerClass(meta, effect_class);
+}
+
+function split_fragment_shader(source) {
+ const main_index = source.search(/void\s+main\s*(?:\(\s*(?:void)?\s*\))?\s*\{/);
+ if (main_index < 0)
+ return null;
+
+ const declarations = source.slice(0, main_index).trim();
+ const brace_index = source.indexOf('{', main_index);
+ if (brace_index < 0)
+ return null;
+
+ let depth = 0;
+ for (let i = brace_index; i < source.length; i++) {
+ if (source[i] === '{')
+ depth++;
+ else if (source[i] === '}') {
+ depth--;
+ if (depth === 0) {
+ return {
+ declarations,
+ body: source.slice(brace_index + 1, i).trim(),
+ };
+ }
+ }
+ }
+
+ return null;
+}
+
+function create_fragment_shader_snippet(source) {
+ if (!Cogl || !source)
+ return null;
+
+ const parts = split_fragment_shader(source);
+ if (!parts) {
+ console.warn('[Blur my Shell > effect] could not split shader source');
+ return null;
+ }
+
+ try {
+ const snippet = Cogl.Snippet.new(
+ Cogl.SnippetHook.FRAGMENT,
+ parts.declarations,
+ null
+ );
+ snippet.set_replace(parts.body);
+ return snippet;
+ } catch (e) {
+ console.warn(`[Blur my Shell > effect] could not create shader snippet: ${e}`);
+ return null;
+ }
+}
+
+export function initialize_shader_effect(effect, source) {
+ if (!source || !effect || USES_SHADER_SNIPPET_API)
+ return;
+
+ try {
+ effect.set_shader_source(source);
+ } catch (e) {
+ console.warn(`[Blur my Shell > effect] set_shader_source failed: ${e}`);
+ }
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/iface.xml b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/iface.xml
deleted file mode 100644
index 4f298ad..0000000
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/iface.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<node>
- <interface name="dev.aunetx.BlurMyShell">
- <!-- This method is called in preferences to pick a window -->
- <method name="pick" />
- <!-- When window is picking, send a signal to preferences -->
- <signal name="picking"></signal>
- <!-- If window is picked, send a signal to preferences -->
- <signal name="picked">
- <arg name="window" type="s" />
- </signal>
- </interface>
-</node> \ No newline at end of file
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/services.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/services.js
index 4b1f4f0..0b2f144 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/services.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/services.js
@@ -3,18 +3,24 @@ import GLib from 'gi://GLib';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as LookingGlass from 'resource:///org/gnome/shell/ui/lookingGlass.js';
+const IFACE_XML = `
+<node>
+ <interface name="dev.aunetx.BlurMyShell">
+ <!-- This method is called in preferences to pick a window -->
+ <method name="pick" />
+ <!-- When window is picking, send a signal to preferences -->
+ <signal name="picking"></signal>
+ <!-- If window is picked, send a signal to preferences -->
+ <signal name="picked">
+ <arg name="window" type="s" />
+ </signal>
+ </interface>
+</node>
+`;
export const ApplicationsService = class ApplicationsService {
constructor() {
- let decoder = new TextDecoder();
- let path = GLib.filename_from_uri(GLib.uri_resolve_relative(
- import.meta.url, 'iface.xml', GLib.UriFlags.NONE)
- )[0];
- let [, buffer] = GLib.file_get_contents(path);
- let iface = decoder.decode(buffer);
- GLib.free(buffer);
-
- this.DBusImpl = Gio.DBusExportedObject.wrapJSObject(iface, this);
+ this.DBusImpl = Gio.DBusExportedObject.wrapJSObject(IFACE_XML, this);
}
/// Pick Window for Preferences Page, exported to DBus client.
@@ -49,7 +55,7 @@ export const ApplicationsService = class ApplicationsService {
// inspect window now
const inspector = new LookingGlass.Inspector(Main.createLookingGlass());
- inspector.connect('target', (me, target, x, y) => {
+ inspector.connect('target', (me, target, _x, _y) => {
// remove border effect when window is picked.
const effect_name = 'lookingGlass_RedBorderEffect';
target
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl
index 5df6512..af9b1df 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl
@@ -3,6 +3,7 @@ uniform float red;
uniform float green;
uniform float blue;
uniform float blend;
+uniform float opacity_factor;
uniform int mode;
const int NORMAL = 0;
@@ -53,7 +54,7 @@ float soft_light_channel(float base, float _blend) {
vec3 get_blend(vec3 base, vec3 _blend) {
if (mode == MULTIPLY) return base * _blend;
- if (mode == SCREEN) return 1 - (1 - base) * (1 - _blend);
+ if (mode == SCREEN) return 1.0 - (1.0 - base) * (1.0 - _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));
@@ -63,10 +64,10 @@ vec3 get_blend(vec3 base, vec3 _blend) {
}
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_DARKER) return base + _blend - vec3(1.0);
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 == COLOR_DODGE) return base / max(vec3(1e-6), 1.0 - _blend);
+ if (mode == COLOR_BURN) return 1.0 - (1.0 - base) / max(vec3(1e-6), _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));
@@ -78,7 +79,7 @@ vec3 get_blend(vec3 base, vec3 _blend) {
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 == EXCLUSION) return 0.5 - 2.0 * (base - 0.5) * (_blend - 0.5);
if (mode == HUE) {
vec3 base_hsl = rgb_to_hsl(base);
vec3 blend_hsl = rgb_to_hsl(_blend);
@@ -106,6 +107,7 @@ 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));
+ float amount = blend * opacity_factor;
- cogl_color_out = vec4(mix(pix_color, color, blend), 1.);
-} \ No newline at end of file
+ cogl_color_out = vec4(mix(pix_color, color, amount), c.a);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js
index 1f4bdf4..95ce4c1 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js
@@ -1,20 +1,21 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
const DEFAULT_PARAMS = {
color: [0.0, 0.0, 0.0, 0.0],
- blend_mode: 0
+ blend_mode: 0,
+ opacity_factor: 1
};
-export const ColorEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const COLOR_EFFECT_META = {
GTypeName: "ColorEffect",
Properties: {
'red': GObject.ParamSpec.double(
@@ -56,31 +57,37 @@ export const ColorEffect = utils.IS_IN_PREFERENCES ?
GObject.ParamFlags.READWRITE,
0, 17,
0,
+ ),
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.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 {
+};
+
+const ColorEffectClass = utils.IS_IN_PREFERENCES ? null : class ColorEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- // initialize without color as a parameter
- const { color, ...parent_params } = params;
- super(parent_params);
+ super();
+
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
+
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);
+ this._opacity_factor = null;
// set params; utils.setup_params doesn't work here with color
- this.color = 'color' in params ? color : this.constructor.default_params.color;
+ this.color = 'color' in params ? params.color : this.constructor.default_params.color;
this.blend_mode = 'blend_mode' in params ? params.blend_mode : this.constructor.default_params.blend_mode;
+ this.opacity_factor = 'opacity_factor' in params ? params.opacity_factor : this.constructor.default_params.opacity_factor;
}
static get default_params() {
@@ -95,7 +102,7 @@ export const ColorEffect = utils.IS_IN_PREFERENCES ?
if (this._red !== value) {
this._red = value;
- this.set_uniform_value('red', parseFloat(this._red - 1e-6));
+ uniforms.set_uniform(this, 'red', parseFloat(this._red - 1e-6));
}
}
@@ -107,7 +114,7 @@ export const ColorEffect = utils.IS_IN_PREFERENCES ?
if (this._green !== value) {
this._green = value;
- this.set_uniform_value('green', parseFloat(this._green - 1e-6));
+ uniforms.set_uniform(this, 'green', parseFloat(this._green - 1e-6));
}
}
@@ -119,7 +126,7 @@ export const ColorEffect = utils.IS_IN_PREFERENCES ?
if (this._blue !== value) {
this._blue = value;
- this.set_uniform_value('blue', parseFloat(this._blue - 1e-6));
+ uniforms.set_uniform(this, 'blue', parseFloat(this._blue - 1e-6));
}
}
@@ -131,7 +138,7 @@ export const ColorEffect = utils.IS_IN_PREFERENCES ?
if (this._blend !== value) {
this._blend = value;
- this.set_uniform_value('blend', parseFloat(this._blend - 1e-6));
+ uniforms.set_uniform(this, 'blend', parseFloat(this._blend - 1e-6));
this.set_enabled(this.blend > 0);
}
}
@@ -144,7 +151,19 @@ export const ColorEffect = utils.IS_IN_PREFERENCES ?
if (this._blend_mode !== value) {
this._blend_mode = value;
- this.set_uniform_value('mode', this._blend_mode);
+ uniforms.set_uniform(this, 'mode', this._blend_mode);
+ }
+ }
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
+
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
}
}
@@ -164,5 +183,16 @@ export const ColorEffect = utils.IS_IN_PREFERENCES ?
set(params) {
this.color = params.color;
this.blend_mode = params.blend_mode;
+ if ('opacity_factor' in params)
+ this.opacity_factor = params.opacity_factor;
}
- }); \ No newline at end of file
+
+ vfunc_paint_target(paint_node, paint_context) {
+ uniforms.upload_uniforms(this);
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+};
+
+export const ColorEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(COLOR_EFFECT_META, ColorEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl
index 0b7b0fb..fa5f45c 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl
@@ -5,9 +5,9 @@ uniform sampler2D tex;
uniform float radius;
uniform float width;
uniform float height;
-uniform bool corners_top;
-uniform bool corners_bottom;
-uniform bool straight_corners;
+uniform int corners_top;
+uniform int corners_bottom;
+uniform int straight_corners;
uniform float clip_x0;
uniform float clip_y0;
@@ -30,17 +30,20 @@ float circle_bounds(vec2 p, vec2 center, float clip_radius) {
}
vec4 getTexture(vec2 uv) {
- if (uv.x < 2. / width)
- uv.x = 2. / width;
+ float w = max(1.0, width);
+ float h = max(1.0, height);
- if (uv.y < 2. / height)
- uv.y = 2. / height;
+ if (uv.x < 2. / w)
+ uv.x = 2. / w;
- if (uv.x > 1. - 3. / width)
- uv.x = 1. - 3. / width;
+ if (uv.y < 2. / h)
+ uv.y = 2. / h;
- if (uv.y > 1. - 3. / height)
- uv.y = 1. - 3. / height;
+ if (uv.x > 1. - 3. / w)
+ uv.x = 1. - 3. / w;
+
+ if (uv.y > 1. - 3. / h)
+ uv.y = 1. - 3. / h;
return texture2D(tex, uv);
}
@@ -66,11 +69,11 @@ float rounded_rect_coverage(vec2 p, vec4 bounds, float clip_radius) {
float center_top = bounds.y + clip_radius;
float center_bottom = bounds.w - clip_radius;
- if (straight_corners)
+ if (straight_corners != 0)
return 1.0;
- else if (corners_top && p.y < center_top)
+ else if (corners_top != 0 && p.y < center_top)
center.y = center_top + 2.;
- else if (corners_bottom && p.y > center_bottom)
+ else if (corners_bottom != 0 && p.y > center_bottom)
center.y = center_bottom - 1.;
else
return 1.0;
@@ -93,4 +96,4 @@ void main(void) {
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-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js
index 1727e30..6a44430 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js
@@ -1,21 +1,24 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
const DEFAULT_PARAMS = {
radius: 12, width: 0, height: 0,
corners_top: true, corners_bottom: true,
- clip: [0, 0, -1, -1]
+ clip: [0, 0, -1, -1],
+ // Reset on reuse: `EffectsManager` pools `CornerEffect` instances, and a
+ // pooled instance could otherwise keep rendering square (see corner.glsl).
+ straight_corners: false,
};
-export const CornerEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const CORNER_EFFECT_META = {
GTypeName: "CornerEffect",
Properties: {
'radius': GObject.ParamSpec.double(
@@ -56,20 +59,15 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
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 {
+};
+
+const CornerEffectClass = utils.IS_IN_PREFERENCES ? null : class CornerEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
+
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
this._clip_x0 = null;
this._clip_y0 = null;
@@ -77,12 +75,6 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
this._clip_height = null;
utils.setup_params(this, params);
- this.straight_corners = false;
-
- // 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);
@@ -113,7 +105,7 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
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));
+ uniforms.set_uniform(this, 'radius', parseFloat(radius - 1e-6));
}
get width() {
@@ -121,10 +113,11 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
}
set width(value) {
- if (this._width !== value) {
- this._width = value;
+ const v = Math.max(1, value || 1);
+ if (this._width !== v) {
+ this._width = v;
- this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6));
+ uniforms.set_uniform(this, 'width', parseFloat(this._width + 3.0 - 1e-6));
this.update_radius();
}
}
@@ -134,10 +127,11 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
}
set height(value) {
- if (this._height !== value) {
- this._height = value;
+ const v = Math.max(1, value || 1);
+ if (this._height !== v) {
+ this._height = v;
- this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6));
+ uniforms.set_uniform(this, 'height', parseFloat(this._height + 3.0 - 1e-6));
this.update_radius();
}
}
@@ -150,7 +144,7 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
if (this._corners_top !== value) {
this._corners_top = value;
- this.set_uniform_value('corners_top', this._corners_top ? 1 : 0);
+ uniforms.set_uniform(this, 'corners_top', this._corners_top ? 1 : 0);
}
}
@@ -162,7 +156,7 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
if (this._corners_bottom !== value) {
this._corners_bottom = value;
- this.set_uniform_value('corners_bottom', this._corners_bottom ? 1 : 0);
+ uniforms.set_uniform(this, 'corners_bottom', this._corners_bottom ? 1 : 0);
}
}
@@ -174,20 +168,37 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
if (this._straight_corners !== value) {
this._straight_corners = value;
- this.set_uniform_value('straight_corners', this._straight_corners ? 1 : 0);
+ uniforms.set_uniform(this, 'straight_corners', this._straight_corners ? 1 : 0);
}
}
+ detach_actor_clip_sync(actor = this.get_actor()) {
+ if (!actor || !this._actor_connection_clip_rect_id)
+ return;
+
+ actor.disconnect(this._actor_connection_clip_rect_id);
+
+ this._actor_connection_clip_rect_id = null;
+ }
+
+ sync_actor_clip(actor) {
+ this.detach_actor_clip_sync(actor);
+ 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];
+ });
+ }
+
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));
+ uniforms.set_uniform(this, 'clip_x0', parseFloat(this._clip_x0 - 1e-6));
+ uniforms.set_uniform(this, 'clip_y0', parseFloat(this._clip_y0 - 1e-6));
+ uniforms.set_uniform(this, 'clip_width', parseFloat(this._clip_width <= 0 ? -1 : this._clip_width + 3 - 1e-6));
+ uniforms.set_uniform(this, 'clip_height', parseFloat(this._clip_height <= 0 ? -1 : this._clip_height + 3 - 1e-6));
this.update_radius();
}
@@ -196,10 +207,7 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
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);
- }
+ this.detach_actor_clip_sync();
if (actor) {
this.width = actor.width;
@@ -209,16 +217,21 @@ export const CornerEffect = utils.IS_IN_PREFERENCES ?
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];
- });
+ this.sync_actor_clip(actor);
}
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
+
+ vfunc_paint_target(paint_node, paint_context) {
+ uniforms.upload_uniforms(this);
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+};
+
+export const CornerEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(CORNER_EFFECT_META, CornerEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl
index 64c1682..b497b69 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl
@@ -2,21 +2,22 @@ uniform sampler2D tex;
uniform int operation;
uniform float width;
uniform float height;
+uniform float opacity_factor;
#define CORRECTION 2.25
-#define SIZE_ADDITION 3
+#define SIZE_ADDITION 3.0
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);
+ vec2 raw_uv = raw_position / vec2(max(1.0, width + SIZE_ADDITION), max(1.0, 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);
+ any(lessThan(position, vec2(0.0, 0.0)))) {
+ return vec4(0.0);
} else {
count++;
return get_texture_at_position(position);
@@ -31,41 +32,45 @@ ivec2 get_corrected_position() {
void main() {
ivec2 corrected_position = get_corrected_position();
+ vec4 source_color = get_texture_at_position(vec2(corrected_position));
+ vec4 effect_color = source_color;
// 1-step derivative
if (operation == 0) {
- vec4 color = vec4(0);
+ vec4 color = vec4(0.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);
+ color += try_get_texture_at_position(vec2(corrected_position) + vec2(0.0, 1.0), c);
+ color -= try_get_texture_at_position(vec2(corrected_position) + vec2(0.0, 0.0), c);
+ color += try_get_texture_at_position(vec2(corrected_position) + vec2(1.0, 0.0), c);
+ color -= try_get_texture_at_position(vec2(corrected_position) + vec2(0.0, 0.0), c);
if (c < 4) {
- color = vec4(0);
+ color = vec4(0.0);
}
- cogl_color_out = vec4(color.xyz, 1);
+ effect_color = vec4(color.xyz, source_color.a);
} else
// 2-step derivative
if (operation == 1) {
- vec4 color = vec4(0);
+ vec4 color = vec4(0.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);
+ color += try_get_texture_at_position(vec2(corrected_position) + vec2(0.0, 1.0), c);
+ color -= try_get_texture_at_position(vec2(corrected_position) + vec2(0.0, -1.0), c);
+ color += try_get_texture_at_position(vec2(corrected_position) + vec2(1.0, 0.0), c);
+ color -= try_get_texture_at_position(vec2(corrected_position) + vec2(-1.0, 0.0), c);
if (c < 4) {
- color = vec4(0);
+ color = vec4(0.0);
}
- cogl_color_out = vec4(color.xyz / 2, 1);
+ effect_color = vec4(color.xyz / 2.0, source_color.a);
} 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);
+ vec4 color = vec4(0.0);
+ color = -4.0 * get_texture_at_position(vec2(corrected_position));
+ color += get_texture_at_position(vec2(corrected_position) + vec2(0.0, 1.0));
+ color += get_texture_at_position(vec2(corrected_position) + vec2(0.0, -1.0));
+ color += get_texture_at_position(vec2(corrected_position) + vec2(1.0, 0.0));
+ color += get_texture_at_position(vec2(corrected_position) + vec2(-1.0, 0.0));
+ effect_color = vec4(color.xyz, source_color.a);
}
-} \ No newline at end of file
+
+ cogl_color_out = mix(source_color, effect_color, opacity_factor);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js
index 04d6100..a2d2bef 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js
@@ -1,18 +1,18 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
const DEFAULT_PARAMS = {
- operation: 0, width: 0, height: 0
+ operation: 0, opacity_factor: 1, width: 0, height: 0
};
-export const DerivativeEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const DERIVATIVE_EFFECT_META = {
GTypeName: "DerivativeEffect",
Properties: {
'operation': GObject.ParamSpec.int(
@@ -23,6 +23,14 @@ export const DerivativeEffect = utils.IS_IN_PREFERENCES ?
0, 2,
0,
),
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
'width': GObject.ParamSpec.double(
`width`,
`Width`,
@@ -40,16 +48,17 @@ export const DerivativeEffect = utils.IS_IN_PREFERENCES ?
0.0,
)
}
- }, class DerivativeEffect extends Clutter.ShaderEffect {
+};
+
+const DerivativeEffectClass = utils.IS_IN_PREFERENCES ? null : class DerivativeEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
+
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- 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);
+ utils.setup_params(this, params);
}
static get default_params() {
@@ -64,7 +73,19 @@ export const DerivativeEffect = utils.IS_IN_PREFERENCES ?
if (this._operation !== value) {
this._operation = value;
- this.set_uniform_value('operation', this._operation);
+ uniforms.set_uniform(this, 'operation', this._operation);
+ }
+ }
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
+
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
}
}
@@ -73,10 +94,11 @@ export const DerivativeEffect = utils.IS_IN_PREFERENCES ?
}
set width(value) {
- if (this._width !== value) {
- this._width = value;
+ const v = Math.max(1, value || 1);
+ if (this._width !== v) {
+ this._width = v;
- this.set_uniform_value('width', parseFloat(this._width - 1e-6));
+ uniforms.set_uniform(this, 'width', parseFloat(this._width - 1e-6));
}
}
@@ -85,10 +107,11 @@ export const DerivativeEffect = utils.IS_IN_PREFERENCES ?
}
set height(value) {
- if (this._height !== value) {
- this._height = value;
+ const v = Math.max(1, value || 1);
+ if (this._height !== v) {
+ this._height = v;
- this.set_uniform_value('height', parseFloat(this._height - 1e-6));
+ uniforms.set_uniform(this, 'height', parseFloat(this._height - 1e-6));
}
}
@@ -112,9 +135,17 @@ export const DerivativeEffect = utils.IS_IN_PREFERENCES ?
}
vfunc_paint_target(paint_node, paint_context) {
- // force setting nearest-neighbour texture filtering
- this.get_pipeline().set_layer_filters(0, 9728, 9728);
+ uniforms.upload_uniforms(this);
+
+ const pipeline = this.get_pipeline();
+ if (pipeline) {
+ pipeline.set_layer_filters(0, 9728, 9728);
+ }
super.vfunc_paint_target(paint_node, paint_context);
}
- }); \ No newline at end of file
+};
+
+export const DerivativeEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(DERIVATIVE_EFFECT_META, DerivativeEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl
index 9871268..8b57367 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl
@@ -3,13 +3,14 @@ uniform int divider;
uniform float width;
uniform float height;
uniform int downsampling_mode;
+uniform float opacity_factor;
#define CORRECTION 2.25
-#define SIZE_ADDITION 3
+#define SIZE_ADDITION 3.0
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);
+ vec2 raw_uv = raw_position / vec2(max(1.0, width + SIZE_ADDITION), max(1.0, height + SIZE_ADDITION));
return texture2D(tex, raw_uv);
}
@@ -21,11 +22,14 @@ vec2 get_corrected_position() {
}
void main() {
+ vec4 source_color = texture2D(tex, cogl_tex_coord0_in.st);
+ vec4 effect_color = vec4(0.0);
ivec2 corrected_position = ivec2(get_corrected_position());
- vec2 multiplied_position = corrected_position * divider;
+ vec2 multiplied_position = vec2(corrected_position) * float(divider);
if (any(greaterThan(multiplied_position, vec2(width, height)))) {
- discard;
+ cogl_color_out = mix(source_color, effect_color, opacity_factor);
+ return;
}
// mode 0: boxcar downsampling
@@ -35,15 +39,15 @@ void main() {
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))) &&
+ vec2 lookup_position = multiplied_position + vec2(float(i), float(j));
+ if (all(greaterThanEqual(lookup_position, vec2(0.0, 0.0))) &&
all(lessThan(lookup_position, vec2(width, height)))) {
color += get_texture_at_position(lookup_position);
count += 1;
}
}
}
- cogl_color_out = color / count;
+ effect_color = color / max(1.0, float(count));
} else
// mode 1: triangular downsampling
@@ -54,23 +58,25 @@ void main() {
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))) &&
+ vec2 lookup_position = multiplied_position + vec2(float(i), float(j));
+ if (all(greaterThanEqual(lookup_position, vec2(0.0, 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;
+ force = 1 + divider - int(abs(float(divider - i - j)));
+ color += get_texture_at_position(lookup_position) * float(force);
count += force;
}
}
}
- cogl_color_out = color / count;
+ effect_color = color / max(1.0, float(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);
+ vec2 lookup_position = min(multiplied_position + vec2(float(divider)) * 0.5, vec2(width - 1.0, height - 1.0));
+ effect_color = get_texture_at_position(lookup_position);
}
-} \ No newline at end of file
+
+ cogl_color_out = mix(source_color, effect_color, opacity_factor);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js
index 8103486..b6e08c4 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js
@@ -1,18 +1,18 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
const DEFAULT_PARAMS = {
- divider: 8, downsampling_mode: 0, width: 0, height: 0
+ divider: 8, downsampling_mode: 0, opacity_factor: 1, width: 0, height: 0
};
-export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const DOWNSCALE_EFFECT_META = {
GTypeName: "DownscaleEffect",
Properties: {
'divider': GObject.ParamSpec.int(
@@ -31,6 +31,14 @@ export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
0, 2,
0,
),
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
'width': GObject.ParamSpec.double(
`width`,
`Width`,
@@ -48,16 +56,17 @@ export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
0.0,
)
}
- }, class DownscaleEffect extends Clutter.ShaderEffect {
+};
+
+const DownscaleEffectClass = utils.IS_IN_PREFERENCES ? null : class DownscaleEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
+
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- 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);
+ utils.setup_params(this, params);
}
static get default_params() {
@@ -69,10 +78,11 @@ export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
}
set divider(value) {
- if (this._divider !== value) {
- this._divider = value;
+ const v = Math.max(1, value || 1);
+ if (this._divider !== v) {
+ this._divider = v;
- this.set_uniform_value('divider', this._divider);
+ uniforms.set_uniform(this, 'divider', this._divider);
}
}
@@ -84,7 +94,19 @@ export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
if (this._downsampling_mode !== value) {
this._downsampling_mode = value;
- this.set_uniform_value('downsampling_mode', this._downsampling_mode);
+ uniforms.set_uniform(this, 'downsampling_mode', this._downsampling_mode);
+ }
+ }
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
+
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
}
}
@@ -93,10 +115,11 @@ export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
}
set width(value) {
- if (this._width !== value) {
- this._width = value;
+ const v = Math.max(1, value || 1);
+ if (this._width !== v) {
+ this._width = v;
- this.set_uniform_value('width', parseFloat(this._width - 1e-6));
+ uniforms.set_uniform(this, 'width', parseFloat(this._width - 1e-6));
}
}
@@ -105,10 +128,11 @@ export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
}
set height(value) {
- if (this._height !== value) {
- this._height = value;
+ const v = Math.max(1, value || 1);
+ if (this._height !== v) {
+ this._height = v;
- this.set_uniform_value('height', parseFloat(this._height - 1e-6));
+ uniforms.set_uniform(this, 'height', parseFloat(this._height - 1e-6));
}
}
@@ -132,9 +156,17 @@ export const DownscaleEffect = utils.IS_IN_PREFERENCES ?
}
vfunc_paint_target(paint_node, paint_context) {
- // force setting nearest-neighbour texture filtering
- this.get_pipeline().set_layer_filters(0, 9728, 9728);
+ uniforms.upload_uniforms(this);
+
+ const pipeline = this.get_pipeline();
+ if (pipeline) {
+ pipeline.set_layer_filters(0, 9728, 9728);
+ }
super.vfunc_paint_target(paint_node, paint_context);
}
- }); \ No newline at end of file
+};
+
+export const DownscaleEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(DOWNSCALE_EFFECT_META, DownscaleEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effect_groups.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effect_groups.js
new file mode 100644
index 0000000..c53a647
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effect_groups.js
@@ -0,0 +1,31 @@
+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',
+ 'refraction',
+ 'derivative',
+ 'noise',
+ 'color',
+ 'luminosity',
+ 'rgb_to_hsl',
+ 'hsl_to_rgb',
+ ],
+ },
+ shape_effects: {
+ name: _('Shape effects'),
+ contains: ['corner'],
+ },
+ };
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js
index 4ab5a71..984aa47 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js
@@ -12,41 +12,8 @@ import { DerivativeEffect } from './derivative.js';
import { RgbToHslEffect } from './rgb_to_hsl.js';
import { HslToRgbEffect } from './hsl_to_rgb.js';
import { LuminosityEffect } from './luminosity.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",
- "luminosity",
- "rgb_to_hsl",
- "hsl_to_rgb"
- ]
- },
- shape_effects: {
- name: _("Shape effects"),
- contains: [
- "corner"
- ]
- }
- };
-};
+import { RefractionEffect } from './refraction.js';
+export { get_effects_groups } from './effect_groups.js';
export function get_supported_effects(_ = () => "") {
return {
@@ -378,6 +345,140 @@ export function get_supported_effects(_ = () => "") {
}
},
+ refraction: {
+ class: RefractionEffect,
+ name: _("Liquid Glass"),
+ description: _("A glossy translucent material with edge refraction, rim lighting, tint, and inner shadow."),
+ is_advanced: false,
+ editable_params: {
+ strength: {
+ name: _("Refraction scale"),
+ description: _("How strongly the glass bends the sampled blur texture."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ blur_radius: {
+ name: _("Blur radius"),
+ description: _("Blurs the sampled backdrop before the liquid-glass shader is applied."),
+ type: "float",
+ min: 0.,
+ max: 48.,
+ increment: 1.,
+ big_increment: 10.,
+ digits: 0
+ },
+ edge_size: {
+ name: _("Bezel width"),
+ description: _("How far the liquid-glass lens reaches inward from the edge."),
+ type: "float",
+ min: 1.,
+ max: 100.,
+ increment: 1.,
+ big_increment: 10.,
+ digits: 0
+ },
+ rim_width: {
+ name: _("Rim spread"),
+ description: _("How far the refraction eases inward from the glass edge."),
+ type: "float",
+ min: 1.,
+ max: 6.5,
+ increment: 0.1,
+ big_increment: 0.5,
+ digits: 2
+ },
+ falloff: {
+ name: _("Glass thickness"),
+ description: _("Depth used by the Snell-style refraction profile."),
+ type: "float",
+ min: 0.25,
+ max: 8.,
+ increment: 0.05,
+ big_increment: 0.5,
+ digits: 2
+ },
+ corner_radius: {
+ name: _("Corner radius"),
+ description: _("The rounded shape used for the glass edge and highlight."),
+ type: "float",
+ min: 0.,
+ max: 100.,
+ increment: 1.,
+ big_increment: 10.,
+ digits: 0
+ },
+ gloss: {
+ name: _("Fresnel glare"),
+ description: _("Strength of the Schlick fresnel rim glare from the glass edge."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ tint: {
+ name: _("Tint strength"),
+ description: _("Amount of subtle milky glass tint over the blurred texture."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ tint_color: {
+ name: _("Tint color"),
+ description: _("Color blended over the blurred texture, weighted by the tint strength."),
+ type: "rgba",
+ use_alpha: true
+ },
+ backdrop_zoom: {
+ name: _("Backdrop zoom"),
+ description: _("Zoom level of the backdrop visible through the glass."),
+ type: "float",
+ min: 0.1,
+ max: 4.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ shadow: {
+ name: _("Inner shadow"),
+ description: _("Darkens the lower and inner edge for a deeper glass surface."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ rgb_fringing: {
+ name: _("Chromatic dispersion"),
+ description: _("Physical per-channel refraction dispersion at the glass edge."),
+ type: "float",
+ min: 0.,
+ max: 1.,
+ increment: 0.01,
+ big_increment: 0.1,
+ digits: 2
+ },
+ texture_repeat: {
+ name: _("Edge behavior"),
+ description: _("How texture coordinates outside the actor are sampled."),
+ type: "dropdown",
+ options: [
+ _("Clamp"),
+ _("Mirror")
+ ]
+ }
+ }
+ },
+
rgb_to_hsl: {
class: RgbToHslEffect,
name: _("RGB to HSL (advanced effect)"),
@@ -402,7 +503,7 @@ export function get_supported_effects(_ = () => "") {
editable_params: {
radius: {
name: _("Radius"),
- description: _("The radius of the corner. GNOME apps use a radius of 12 px by default."),
+ description: _("The radius of the corner. GNOME apps use a radius of 15 px by default."),
type: "integer",
min: 0,
max: 150,
@@ -421,4 +522,4 @@ export function get_supported_effects(_ = () => "") {
}
}
};
-}; \ No newline at end of file
+};
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl
index 809cc93..2bc641f 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl
@@ -6,30 +6,35 @@ uniform float width;
uniform float height;
vec4 getTexture(vec2 uv) {
- if (uv.x < 3. / width)
- uv.x = 3. / width;
+ float w = max(1.0, width);
+ float h = max(1.0, height);
- if (uv.y < 3. / height)
- uv.y = 3. / height;
+ if (uv.x < 3. / w)
+ uv.x = 3. / w;
- if (uv.x > 1. - 3. / width)
- uv.x = 1. - 3. / width;
+ if (uv.y < 3. / h)
+ uv.y = 3. / h;
- if (uv.y > 1. - 3. / height)
- uv.y = 1. - 3. / height;
+ if (uv.x > 1. - 3. / w)
+ uv.x = 1. - 3. / w;
+
+ if (uv.y > 1. - 3. / h)
+ uv.y = 1. - 3. / h;
return texture2D(tex, uv);
}
void main(void) {
vec2 uv = cogl_tex_coord_in[0].xy;
- vec2 direction = vec2(dir, (1.0 - dir));
+ vec2 direction = vec2(float(dir), 1.0 - float(dir));
+ float w = max(1.0, width);
+ float h = max(1.0, height);
float pixel_step;
if (dir == 0)
- pixel_step = 1.0 / height;
+ pixel_step = 1.0 / h;
else
- pixel_step = 1.0 / width;
+ pixel_step = 1.0 / w;
vec3 gauss_coefficient;
gauss_coefficient.x = 1.0 / (sqrt(2.0 * 3.14159265) * sigma);
@@ -67,4 +72,4 @@ void main(void) {
}
cogl_color_out = outColor;
-} \ No newline at end of file
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js
index 113a6fd..631831e 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js
@@ -1,20 +1,20 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
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({
+const GAUSSIAN_BLUR_EFFECT_META = {
GTypeName: "GaussianBlurEffect",
Properties: {
'radius': GObject.ParamSpec.double(
@@ -65,21 +65,22 @@ export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ?
GObject.Object,
),
}
- }, class GaussianBlurEffect extends Clutter.ShaderEffect {
+};
+
+const GaussianBlurEffectClass = utils.IS_IN_PREFERENCES ? null : class GaussianBlurEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
+
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- 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);
+ utils.setup_params(this, params);
const theme_context = St.ThemeContext.get_for_stage(global.stage);
theme_context.connectObject(
'notify::scale-factor', _ =>
- this.set_uniform_value('sigma',
+ uniforms.set_uniform(this, 'sigma',
parseFloat(this.radius * theme_context.scale_factor / 2 - 1e-6)
),
this
@@ -101,7 +102,7 @@ export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ?
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));
+ uniforms.set_uniform(this, 'sigma', parseFloat(this._radius * scale_factor / 2 - 1e-6));
this.set_enabled(this.radius > 0.);
if (this.chained_effect)
@@ -117,7 +118,7 @@ export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ?
if (this._brightness !== value) {
this._brightness = value;
- this.set_uniform_value('brightness', parseFloat(this._brightness - 1e-6));
+ uniforms.set_uniform(this, 'brightness', parseFloat(this._brightness - 1e-6));
if (this.chained_effect)
this.chained_effect.brightness = value;
@@ -129,13 +130,14 @@ export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ?
}
set width(value) {
- if (this._width !== value) {
- this._width = value;
+ const v = Math.max(1, value || 1);
+ if (this._width !== v) {
+ this._width = v;
- this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6));
+ uniforms.set_uniform(this, 'width', parseFloat(this._width + 3.0 - 1e-6));
if (this.chained_effect)
- this.chained_effect.width = value;
+ this.chained_effect.width = v;
}
}
@@ -144,13 +146,14 @@ export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ?
}
set height(value) {
- if (this._height !== value) {
- this._height = value;
+ const v = Math.max(1, value || 1);
+ if (this._height !== v) {
+ this._height = v;
- this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6));
+ uniforms.set_uniform(this, 'height', parseFloat(this._height + 3.0 - 1e-6));
if (this.chained_effect)
- this.chained_effect.height = value;
+ this.chained_effect.height = v;
}
}
@@ -159,8 +162,10 @@ export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ?
}
set direction(value) {
- if (this._direction !== value)
+ if (this._direction !== value) {
this._direction = value;
+ uniforms.set_uniform(this, "dir", this._direction);
+ }
}
get chained_effect() {
@@ -202,12 +207,16 @@ export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ?
});
if (actor !== null)
actor.add_effect(this.chained_effect);
+ uniforms.mark_dirty(this.chained_effect);
}
}
vfunc_paint_target(paint_node, paint_context) {
- this.set_uniform_value("dir", this.direction);
-
+ uniforms.upload_uniforms(this);
super.vfunc_paint_target(paint_node, paint_context);
}
- }); \ No newline at end of file
+};
+
+export const GaussianBlurEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(GAUSSIAN_BLUR_EFFECT_META, GaussianBlurEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl
index 58d2694..8b9990d 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl
@@ -1,4 +1,5 @@
uniform sampler2D tex;
+uniform float opacity_factor;
vec3 hsl_to_rgb(vec3 c) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
@@ -10,5 +11,5 @@ 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
+ cogl_color_out = mix(hsla, rgba, opacity_factor);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js
index fe53114..b79ee84 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js
@@ -1,31 +1,64 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 = {};
+const SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+const DEFAULT_PARAMS = {
+ opacity_factor: 1
+};
-export const HslToRgbEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const HSL_TO_RGB_EFFECT_META = {
GTypeName: "HslToRgbEffect",
- Properties: {}
- }, class HslToRgbEffect extends Clutter.ShaderEffect {
+ Properties: {
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
+ }
+};
+
+const HslToRgbEffectClass = utils.IS_IN_PREFERENCES ? null : class HslToRgbEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
- utils.setup_params(this, params);
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- // set shader source
- this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
- if (this._source)
- this.set_shader_source(this._source);
+
+ utils.setup_params(this, params);
}
static get default_params() {
return DEFAULT_PARAMS;
}
- }); \ No newline at end of file
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
+
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
+ }
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ uniforms.upload_uniforms(this);
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+};
+
+export const HslToRgbEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(HSL_TO_RGB_EFFECT_META, HslToRgbEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.glsl
index 4c50ca4..e7cc855 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.glsl
@@ -4,6 +4,7 @@ uniform float brightness_multiplicator;
uniform float contrast;
uniform float contrast_center;
uniform float saturation_multiplicator;
+uniform float opacity_factor;
vec3 hsl_to_rgb(vec3 c) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
@@ -24,10 +25,16 @@ vec3 rgb_to_hsl(vec3 c) {
void main() {
vec4 c = texture2D(tex, cogl_tex_coord_in[0].st);
+ if (c.a <= 0.0) {
+ cogl_color_out = c;
+ return;
+ }
+
vec3 pix_hsl = rgb_to_hsl(c.xyz) / c.a;
pix_hsl.z = clamp(pix_hsl.z * brightness_multiplicator, 0., 1.);
pix_hsl.z = clamp((pix_hsl.z - contrast_center) * contrast + contrast_center + brightness_shift, 0., 1.);
pix_hsl.y = clamp(pix_hsl.y * saturation_multiplicator, 0., 1.);
- cogl_color_out = vec4(hsl_to_rgb(pix_hsl) * c.a, c.a);
-} \ No newline at end of file
+ vec4 effect_color = vec4(hsl_to_rgb(pix_hsl) * c.a, c.a);
+ cogl_color_out = mix(c, effect_color, opacity_factor);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.js
index c22636d..a4b6364 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/luminosity.js
@@ -1,18 +1,18 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.js';
const Shell = await utils.import_in_shell_only('gi://Shell');
const Clutter = await utils.import_in_shell_only('gi://Clutter');
const SHADER_FILENAME = 'luminosity.glsl';
+const SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
const DEFAULT_PARAMS = {
- brightness_shift: 0., brightness_multiplicator: 1., contrast: 1., contrast_center: 0.5, saturation_multiplicator: 1.
+ brightness_shift: 0., brightness_multiplicator: 1., contrast: 1., contrast_center: 0.5, saturation_multiplicator: 1., opacity_factor: 1.
};
-export const LuminosityEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const LUMINOSITY_EFFECT_META = {
GTypeName: "LuminosityEffect",
Properties: {
'brightness_shift': GObject.ParamSpec.double(
@@ -55,17 +55,26 @@ export const LuminosityEffect = utils.IS_IN_PREFERENCES ?
0.0, 2.0,
1.0,
),
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
}
- }, class LuminosityEffect extends Clutter.ShaderEffect {
+};
+
+const LuminosityEffectClass = utils.IS_IN_PREFERENCES ? null : class LuminosityEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
- utils.setup_params(this, params);
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- // set shader source
- this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
- if (this._source)
- this.set_shader_source(this._source);
+
+ utils.setup_params(this, params);
}
static get default_params() {
@@ -80,7 +89,7 @@ export const LuminosityEffect = utils.IS_IN_PREFERENCES ?
if (this._brightness_shift !== value) {
this._brightness_shift = value;
- this.set_uniform_value('brightness_shift', parseFloat(this._brightness_shift - 1e-6));
+ uniforms.set_uniform(this, 'brightness_shift', parseFloat(this._brightness_shift - 1e-6));
}
}
@@ -96,7 +105,7 @@ export const LuminosityEffect = utils.IS_IN_PREFERENCES ?
let brightness_mul = 600.;
if (value < 1.995)
brightness_mul = 3. * (1. / (1. - (value / 2.) ** 2) - 1.);
- this.set_uniform_value('brightness_multiplicator', parseFloat(brightness_mul - 1e-6));
+ uniforms.set_uniform(this, 'brightness_multiplicator', parseFloat(brightness_mul - 1e-6));
}
}
@@ -108,7 +117,7 @@ export const LuminosityEffect = utils.IS_IN_PREFERENCES ?
if (this._contrast !== value) {
this._contrast = value;
- this.set_uniform_value('contrast', parseFloat(this._contrast - 1e-6));
+ uniforms.set_uniform(this, 'contrast', parseFloat(this._contrast - 1e-6));
}
}
@@ -120,7 +129,7 @@ export const LuminosityEffect = utils.IS_IN_PREFERENCES ?
if (this._contrast_center !== value) {
this._contrast_center = value;
- this.set_uniform_value('contrast_center', parseFloat(this._contrast_center - 1e-6));
+ uniforms.set_uniform(this, 'contrast_center', parseFloat(this._contrast_center - 1e-6));
}
}
@@ -135,7 +144,28 @@ export const LuminosityEffect = utils.IS_IN_PREFERENCES ?
let saturation_mul = 600.;
if (value < 1.995)
saturation_mul = 3. * (1. / (1. - (value / 2.) ** 2) - 1.);
- this.set_uniform_value('saturation_multiplicator', parseFloat(saturation_mul - 1e-6));
+ uniforms.set_uniform(this, 'saturation_multiplicator', parseFloat(saturation_mul - 1e-6));
}
}
- }); \ No newline at end of file
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
+
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
+ }
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ uniforms.upload_uniforms(this);
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+};
+
+export const LuminosityEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(LUMINOSITY_EFFECT_META, LuminosityEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl
index c63d266..ee0c35f 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl
@@ -4,8 +4,8 @@ uniform int iterations;
uniform float brightness;
uniform float width;
uniform float height;
-uniform bool use_base_pixel;
-uniform bool prefer_closer_pixels;
+uniform int use_base_pixel;
+uniform int prefer_closer_pixels;
float srand(vec2 a) {
return sin(dot(a, vec2(1233.224, 1743.335)));
@@ -18,7 +18,7 @@ float rand(inout float r) {
void main() {
vec2 uv = cogl_tex_coord0_in.st;
- vec2 p = 16 * radius / vec2(width, height);
+ vec2 p = 16.0 * radius / vec2(width, height);
float r = srand(uv);
vec2 rv;
@@ -35,18 +35,18 @@ void main() {
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) * (iterations - i)) : 1;
- c += strength * texture2D(tex, new_uv);
+ strength = prefer_closer_pixels != 0 ? ((iterations - i) * (iterations - i)) : 1;
+ c += float(strength) * texture2D(tex, new_uv);
count += strength;
}
}
- if (count == 0 || use_base_pixel) {
- strength = prefer_closer_pixels ? ((iterations + 1) * (iterations + 1)) : 1;
- c += strength * texture2D(tex, uv);
+ if (count == 0 || use_base_pixel != 0) {
+ strength = prefer_closer_pixels != 0 ? ((iterations + 1) * (iterations + 1)) : 1;
+ c += float(strength) * texture2D(tex, uv);
count += strength;
}
c.xyz *= brightness;
- cogl_color_out = c / count;
-} \ No newline at end of file
+ cogl_color_out = c / max(1.0, float(count));
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js
index 0da56ed..e8deb9c 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js
@@ -1,11 +1,13 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
const DEFAULT_PARAMS = {
radius: 2., iterations: 5, brightness: .6,
width: 0, height: 0, use_base_pixel: true,
@@ -13,9 +15,7 @@ const DEFAULT_PARAMS = {
};
-export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const MONTE_CARLO_BLUR_EFFECT_META = {
GTypeName: "MonteCarloBlurEffect",
Properties: {
'radius': GObject.ParamSpec.double(
@@ -73,21 +73,22 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
true,
),
}
- }, class MonteCarloBlurEffect extends Clutter.ShaderEffect {
+};
+
+const MonteCarloBlurEffectClass = utils.IS_IN_PREFERENCES ? null : class MonteCarloBlurEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
+
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- 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);
+ utils.setup_params(this, params);
const theme_context = St.ThemeContext.get_for_stage(global.stage);
theme_context.connectObject(
'notify::scale-factor',
- _ => this.set_uniform_value('radius',
+ _ => uniforms.set_uniform(this, 'radius',
parseFloat(this._radius * theme_context.scale_factor - 1e-6)
),
this
@@ -108,7 +109,7 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
const scale_factor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
- this.set_uniform_value('radius', parseFloat(this._radius * scale_factor - 1e-6));
+ uniforms.set_uniform(this, 'radius', parseFloat(this._radius * scale_factor - 1e-6));
this.set_enabled(this.radius > 0. && this.iterations > 0);
}
}
@@ -121,7 +122,7 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
if (this._iterations !== value) {
this._iterations = value;
- this.set_uniform_value('iterations', this._iterations);
+ uniforms.set_uniform(this, 'iterations', this._iterations);
this.set_enabled(this.radius > 0. && this.iterations > 0);
}
}
@@ -134,7 +135,7 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
if (this._brightness !== value) {
this._brightness = value;
- this.set_uniform_value('brightness', parseFloat(this._brightness - 1e-6));
+ uniforms.set_uniform(this, 'brightness', parseFloat(this._brightness - 1e-6));
}
}
@@ -143,10 +144,11 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
}
set width(value) {
- if (this._width !== value) {
- this._width = value;
+ const v = Math.max(1, value || 1);
+ if (this._width !== v) {
+ this._width = v;
- this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6));
+ uniforms.set_uniform(this, 'width', parseFloat(this._width + 3.0 - 1e-6));
}
}
@@ -155,10 +157,11 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
}
set height(value) {
- if (this._height !== value) {
- this._height = value;
+ const v = Math.max(1, value || 1);
+ if (this._height !== v) {
+ this._height = v;
- this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6));
+ uniforms.set_uniform(this, 'height', parseFloat(this._height + 3.0 - 1e-6));
}
}
@@ -170,7 +173,7 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
if (this._use_base_pixel !== value) {
this._use_base_pixel = value;
- this.set_uniform_value('use_base_pixel', this._use_base_pixel ? 1 : 0);
+ uniforms.set_uniform(this, 'use_base_pixel', this._use_base_pixel ? 1 : 0);
}
}
@@ -182,7 +185,7 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
if (this._prefer_closer_pixels !== value) {
this._prefer_closer_pixels = value;
- this.set_uniform_value('prefer_closer_pixels', this._prefer_closer_pixels ? 1 : 0);
+ uniforms.set_uniform(this, 'prefer_closer_pixels', this._prefer_closer_pixels ? 1 : 0);
}
}
@@ -204,4 +207,13 @@ export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ?
super.vfunc_set_actor(actor);
}
- }); \ No newline at end of file
+
+ vfunc_paint_target(paint_node, paint_context) {
+ uniforms.upload_uniforms(this);
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+};
+
+export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(MONTE_CARLO_BLUR_EFFECT_META, MonteCarloBlurEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js
index 3df621b..fc24e07 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js
@@ -3,55 +3,72 @@ import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
const St = await utils.import_in_shell_only('gi://St');
-let BlurOrShell = await utils.import_in_shell_only('gi://Blur');
-let IS_BLUR_MODULE = true;
-if (BlurOrShell === null) {
- BlurOrShell = await utils.import_in_shell_only('gi://Shell');
- IS_BLUR_MODULE = false;
-}
+const BlurModule = await utils.import_in_shell_only('gi://Blur');
+const Shell = await utils.import_in_shell_only('gi://Shell');
+const BlurOrShell = utils.is_usable_blur_module(BlurModule) ? BlurModule : Shell;
+const SUPPORTS_CORNER_RADIUS = Boolean(
+ BlurOrShell?.BlurEffect?.list_properties()
+ .some(property => property.name === 'corner-radius')
+);
const DEFAULT_PARAMS = {
- unscaled_radius: 30, brightness: 0.6, corner_radius: 14
+ unscaled_radius: 30,
+ brightness: 0.6,
+ unscaled_corner_radius: 0,
};
export const NativeDynamicBlurEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
+ { default_params: DEFAULT_PARAMS, supports_corner_radius: false } :
new GObject.registerClass({
GTypeName: "NativeDynamicBlurEffect"
}, class NativeDynamicBlurEffect extends BlurOrShell.BlurEffect {
constructor(params) {
- const { unscaled_radius, brightness, corner_radius, ...parent_params } = params;
- if (IS_BLUR_MODULE)
- super({ ...parent_params, mode: BlurOrShell.BlurMode.BACKGROUND, ...{ 'corner_radius': corner_radius } });
- else
- super({ ...parent_params, mode: BlurOrShell.BlurMode.BACKGROUND });
+ const normalized_params = { ...params };
+ if (!('unscaled_radius' in normalized_params) && 'radius' in normalized_params)
+ normalized_params.unscaled_radius = normalized_params.radius;
+ delete normalized_params.radius;
+
+ if (!('unscaled_corner_radius' in normalized_params) && 'corner_radius' in normalized_params)
+ normalized_params.unscaled_corner_radius = normalized_params.corner_radius;
+ delete normalized_params.corner_radius;
+
+ const parent_params = { ...normalized_params };
+ delete parent_params.unscaled_radius;
+ delete parent_params.brightness;
+ delete parent_params.unscaled_corner_radius;
+ super({ ...parent_params, mode: BlurOrShell.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.corner_radius = this.unscaled_corner_radius * this._theme_context.scale_factor;
+ this.radius = Math.max(0, this.unscaled_radius * this._theme_context.scale_factor);
+ if (SUPPORTS_CORNER_RADIUS)
+ this.corner_radius = this.unscaled_corner_radius * this._theme_context.scale_factor;
},
this
);
- utils.setup_params(this, params);
+ utils.setup_params(this, normalized_params);
}
static get default_params() {
return DEFAULT_PARAMS;
}
+ static get supports_corner_radius() {
+ return SUPPORTS_CORNER_RADIUS;
+ }
+
get unscaled_radius() {
return this._unscaled_radius;
}
set unscaled_radius(value) {
this._unscaled_radius = value;
- this.radius = value * this._theme_context.scale_factor;
+ this.radius = Math.max(0, value * this._theme_context.scale_factor);
}
get unscaled_corner_radius() {
@@ -60,6 +77,7 @@ export const NativeDynamicBlurEffect = utils.IS_IN_PREFERENCES ?
set unscaled_corner_radius(value) {
this._unscaled_corner_radius = value;
- this.corner_radius = value * this._theme_context.scale_factor;
+ if (SUPPORTS_CORNER_RADIUS)
+ this.corner_radius = value * this._theme_context.scale_factor;
}
});
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js
index fe003f5..cc7aa7b 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js
@@ -15,17 +15,26 @@ export const NativeStaticBlurEffect = utils.IS_IN_PREFERENCES ?
GTypeName: "NativeStaticBlurEffect"
}, class NativeStaticBlurEffect extends Shell.BlurEffect {
constructor(params) {
- const { unscaled_radius, brightness, ...parent_params } = params;
+ const normalized_params = { ...params };
+ if (!('unscaled_radius' in normalized_params) && 'radius' in normalized_params)
+ normalized_params.unscaled_radius = normalized_params.radius;
+ delete normalized_params.radius;
+
+ const {
+ unscaled_radius: _unscaled_radius,
+ brightness: _brightness,
+ ...parent_params
+ } = normalized_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.radius = Math.max(0.5, this.unscaled_radius * this._theme_context.scale_factor),
this
);
- utils.setup_params(this, params);
+ utils.setup_params(this, normalized_params);
}
static get default_params() {
@@ -38,6 +47,6 @@ export const NativeStaticBlurEffect = utils.IS_IN_PREFERENCES ?
set unscaled_radius(value) {
this._unscaled_radius = value;
- this.radius = value * this._theme_context.scale_factor;
+ this.radius = Math.max(0.5, value * this._theme_context.scale_factor);
}
- }); \ No newline at end of file
+ });
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl
index 6d701b6..df03b71 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl
@@ -1,9 +1,10 @@
uniform sampler2D tex;
uniform float noise;
uniform float lightness;
+uniform float opacity_factor;
float PHI = 1.61803398874989484820459;
-float SEED = 24;
+float SEED = 24.0;
float noise_gen(in vec2 xy) {
float r = fract(tan(distance(xy * PHI, xy) * SEED) * xy.x);
@@ -13,8 +14,9 @@ float noise_gen(in vec2 xy) {
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));
+ float blend = noise * (1. - noise_gen(gl_FragCoord.xy)) * opacity_factor;
+ vec3 pix_color = c.rgb;
+ vec3 noise_color = vec3(lightness);
- cogl_color_out = vec4(mix(pix_color, lightness * pix_color, blend), 1.);
-} \ No newline at end of file
+ cogl_color_out = vec4(mix(pix_color, noise_color, blend), c.a);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js
index 3049fa1..5b2c2e1 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js
@@ -1,18 +1,18 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
const DEFAULT_PARAMS = {
- noise: 0.4, lightness: 0.4
+ noise: 0.4, lightness: 0.4, opacity_factor: 1
};
-export const NoiseEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const NOISE_EFFECT_META = {
GTypeName: "NoiseEffect",
Properties: {
'noise': GObject.ParamSpec.double(
@@ -31,17 +31,26 @@ export const NoiseEffect = utils.IS_IN_PREFERENCES ?
0.0, 2.0,
0.4,
),
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
}
- }, class NoiseEffect extends Clutter.ShaderEffect {
+};
+
+const NoiseEffectClass = utils.IS_IN_PREFERENCES ? null : class NoiseEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
+
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- 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);
+ utils.setup_params(this, params);
}
static get default_params() {
@@ -56,7 +65,7 @@ export const NoiseEffect = utils.IS_IN_PREFERENCES ?
if (this._noise !== value) {
this._noise = value;
- this.set_uniform_value('noise', parseFloat(this._noise - 1e-6));
+ uniforms.set_uniform(this, 'noise', parseFloat(this._noise - 1e-6));
this.set_enabled(this.noise > 0. && this.lightness != 1);
}
}
@@ -69,8 +78,29 @@ export const NoiseEffect = utils.IS_IN_PREFERENCES ?
if (this._lightness !== value) {
this._lightness = value;
- this.set_uniform_value('lightness', parseFloat(this._lightness - 1e-6));
+ uniforms.set_uniform(this, 'lightness', parseFloat(this._lightness - 1e-6));
this.set_enabled(this.noise > 0. && this.lightness != 1);
}
}
- }); \ No newline at end of file
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
+
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
+ }
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ uniforms.upload_uniforms(this);
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+};
+
+export const NoiseEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(NOISE_EFFECT_META, NoiseEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js
index e9cad9b..e4a833c 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js
@@ -3,11 +3,8 @@ 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
+ factor: 8, downsampling_mode: 0, opacity_factor: 1
};
@@ -31,15 +28,20 @@ export const PixelizeEffect = utils.IS_IN_PREFERENCES ?
GObject.ParamFlags.READWRITE,
0, 2,
0,
+ ),
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
)
}
}, class PixelizeEffect extends Clutter.Effect {
constructor(params) {
super();
- this.upscale_effect = new UpscaleEffect({});
- this.downscale_effect = new DownscaleEffect({});
-
utils.setup_params(this, params);
}
@@ -48,41 +50,26 @@ export const PixelizeEffect = utils.IS_IN_PREFERENCES ?
}
get factor() {
- // should be the same as `this.downscale_effect.divider`
- return this.upscale_effect.factor;
+ return this._factor;
}
set factor(value) {
- this.upscale_effect.factor = value;
- this.downscale_effect.divider = value;
+ this._factor = value;
}
get downsampling_mode() {
- return this.downscale_effect.downsampling_mode;
+ return this._downsampling_mode;
}
set downsampling_mode(value) {
- this.downscale_effect.downsampling_mode = value;
+ this._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);
+ get opacity_factor() {
+ return this._opacity_factor;
}
- 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);
+ set opacity_factor(value) {
+ this._opacity_factor = value;
}
- }); \ No newline at end of file
+ });
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl
new file mode 100644
index 0000000..5d1d241
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.glsl
@@ -0,0 +1,412 @@
+// GLSL port of winaviation-tweaks/liquidass LiquidAssBackboardd/Tweak.mm kShaderSrc.
+// The sampling and blur pass are adapted for Blur my Shell's Clutter pipeline.
+uniform sampler2D tex;
+uniform float width;
+uniform float height;
+uniform float strength;
+uniform float blur_radius;
+uniform float edge_size;
+uniform float falloff;
+uniform float corner_radius;
+uniform float rim_width;
+uniform float rgb_fringing;
+uniform float gloss;
+uniform float tint;
+uniform float tint_r;
+uniform float tint_g;
+uniform float tint_b;
+uniform float tint_a;
+uniform float backdrop_zoom;
+uniform float shadow;
+uniform int texture_repeat;
+uniform int blur_direction;
+uniform int private_pass;
+uniform float clip_x0;
+uniform float clip_y0;
+uniform float clip_width;
+uniform float clip_height;
+uniform float opacity_factor;
+
+const float PI = 3.14159265;
+const float REFRACTIVE_INDEX = 1.52;
+const float DISPERSION_SCALE = 20.0;
+
+const float kDispersionRedIndex = 0.98;
+const float kDispersionGreenIndex = 1.00;
+const float kDispersionBlueIndex = 1.02;
+
+float surfaceConvexSquircle(float x) {
+ return pow(1.0 - pow(1.0 - x, 4.0), 0.25);
+}
+
+vec2 refractRay(vec2 normal, float eta) {
+ float cosI = -normal.y;
+ float k = 1.0 - eta * eta * (1.0 - cosI * cosI);
+ if (k < 0.0)
+ return vec2(0.0);
+
+ float kSqrt = sqrt(k);
+ return vec2(
+ -(eta * cosI + kSqrt) * normal.x,
+ eta - (eta * cosI + kSqrt) * normal.y
+ );
+}
+
+float rawRefraction(float bezelRatio, float glassThickness, float bezelWidth, float eta) {
+ float x = clamp(bezelRatio, 0.05, 0.95);
+ float y = surfaceConvexSquircle(x);
+ float y2 = surfaceConvexSquircle(x + 0.001);
+ float deriv = (y2 - y) / 0.001;
+ float mag = sqrt(deriv * deriv + 1.0);
+ vec2 n = vec2(-deriv / mag, -1.0 / mag);
+ vec2 r = refractRay(n, eta);
+ if (length(r) < 0.0001 || abs(r.y) < 0.0001)
+ return 0.0;
+
+ float remaining = y * bezelWidth + glassThickness;
+ return r.x * (remaining / r.y);
+}
+
+float displacementAtRatio(float bezelRatio, float glassThickness, float bezelWidth, float eta) {
+ float peak = rawRefraction(0.05, glassThickness, bezelWidth, eta);
+ if (abs(peak) < 0.0001)
+ return 0.0;
+
+ float raw = rawRefraction(bezelRatio, glassThickness, bezelWidth, eta);
+ float norm = raw / peak;
+ float profileFalloff = 1.0 - smoothstep(0.0, 1.0, bezelRatio);
+ return norm * profileFalloff;
+}
+
+float fresnelAtRatio(float bezelRatio, float refractiveIndex) {
+ float x = clamp(bezelRatio, 0.02, 0.98);
+ float y0 = surfaceConvexSquircle(max(0.001, x - 0.001));
+ float y1 = surfaceConvexSquircle(min(0.999, x + 0.001));
+ float slope = (y1 - y0) / 0.002;
+ float cosTheta = inversesqrt(1.0 + slope * slope);
+ float f0Base = (refractiveIndex - 1.0) / (refractiveIndex + 1.0);
+ float f0 = f0Base * f0Base;
+ float grazing = pow(1.0 - clamp(cosTheta, 0.0, 1.0), 5.0);
+ float fresnel = f0 + (1.0 - f0) * grazing;
+ return fresnel * (1.0 - smoothstep(0.0, 1.0, bezelRatio));
+}
+
+float dispersionOffsetScale(float channelIndex, float strengthValue) {
+ return 1.0 - (channelIndex - 1.0) * strengthValue;
+}
+
+float luminance(vec3 color) {
+ return dot(color, vec3(0.2126, 0.7152, 0.0722));
+}
+
+vec2 clampUV(vec2 uv) {
+ vec2 px = vec2(1.5 / width, 1.5 / height);
+ return clamp(uv, px, vec2(1.0) - px);
+}
+
+vec2 resolveUV(vec2 uv) {
+ if (texture_repeat == 1) {
+ vec2 mirrored = abs(fract(uv * 0.5) * 2.0 - 1.0);
+ return clampUV(mirrored);
+ }
+
+ return clampUV(uv);
+}
+
+vec4 sampleBackdrop(vec2 uv) {
+ return texture2D(tex, resolveUV(uv));
+}
+
+vec4 sampleGlassBackdrop(vec2 uv) {
+ if (blur_radius <= 0.01)
+ return sampleBackdrop(uv);
+
+ float sigma = max(0.1, blur_radius * 0.5);
+ float pixelStep = blur_direction == 1 ? 1.0 / width : 1.0 / height;
+ vec2 direction = vec2(float(blur_direction), 1.0 - float(blur_direction));
+
+ vec3 gauss;
+ gauss.x = 1.0 / (sqrt(2.0 * PI) * sigma);
+ gauss.y = exp(-0.5 / (sigma * sigma));
+ gauss.z = gauss.y * gauss.y;
+
+ vec4 accum = sampleBackdrop(uv) * gauss.x;
+ float weightSum = gauss.x;
+
+ gauss.xy *= gauss.yz;
+
+ int radius = int(ceil(1.5 * sigma)) * 2;
+ for (int i = 1; i <= radius; i += 2) {
+ float subtotal = gauss.x;
+
+ gauss.xy *= gauss.yz;
+ subtotal += gauss.x;
+
+ float gaussRatio = gauss.x / subtotal;
+ float offset = float(i) + gaussRatio;
+ vec2 uvOffset = direction * offset * pixelStep;
+
+ accum += sampleBackdrop(uv + uvOffset) * subtotal;
+ accum += sampleBackdrop(uv - uvOffset) * subtotal;
+ weightSum += subtotal * 2.0;
+
+ gauss.xy *= gauss.yz;
+ }
+
+ return accum / weightSum;
+}
+
+vec4 tintFallbackSample() {
+ return vec4(vec3(tint_r, tint_g, tint_b), 1.0);
+}
+
+vec4 sampleOrTintFallback(vec2 uv) {
+ vec4 sample = sampleGlassBackdrop(uv);
+ return sample.a < 0.01 ? tintFallbackSample() : sample;
+}
+
+float roundedBoxDistance(vec2 p, vec2 halfSize, float radius) {
+ radius = min(radius, min(halfSize.x, halfSize.y));
+ vec2 q = abs(p) - halfSize + vec2(radius);
+ return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
+}
+
+float squircleCornerDistance(vec2 p, vec2 halfSize, float radius) {
+ const float continuousCornerExtent = 1.528;
+
+ vec2 extent = min(vec2(radius * continuousCornerExtent), halfSize);
+ vec2 core = max(halfSize - extent, vec2(0.0));
+ vec2 q = abs(p) - core;
+ vec2 corner = max(q, vec2(0.0));
+ vec2 normalized = corner / max(extent, vec2(0.001));
+ float superLength = pow(pow(normalized.x, 4.0) + pow(normalized.y, 4.0), 0.25);
+
+ if (q.x <= 0.0 && q.y <= 0.0)
+ return -min(halfSize.x - abs(p.x), halfSize.y - abs(p.y));
+
+ return (superLength - 1.0) * min(extent.x, extent.y);
+}
+
+struct EdgeInfo {
+ float distance;
+ float alpha;
+ vec2 dir;
+};
+
+EdgeInfo estimateAnalyticEdge(vec2 px, vec2 halfSize, float radius, float shortest) {
+ vec2 p = px - halfSize;
+ float signedDistance;
+ vec2 core;
+
+ if (radius >= shortest * 0.49 || radius < 0.5) {
+ core = max(halfSize - vec2(radius), vec2(0.0));
+ signedDistance = roundedBoxDistance(p, halfSize, radius);
+ } else {
+ const float continuousCornerExtent = 1.528;
+ vec2 extent = min(vec2(radius * continuousCornerExtent), halfSize);
+ core = max(halfSize - extent, vec2(0.0));
+ signedDistance = squircleCornerDistance(p, halfSize, radius);
+ }
+
+ EdgeInfo info;
+ info.distance = max(0.0, -signedDistance);
+ info.alpha = clamp(1.0 - max(0.0, signedDistance), 0.0, 1.0);
+
+ vec2 cornerDelta = max(abs(p) - core, vec2(0.0));
+ vec2 normalDelta;
+
+ if (radius < shortest * 0.49 && radius >= 0.5 &&
+ cornerDelta.x > 0.0 && cornerDelta.y > 0.0) {
+ normalDelta = sign(p) * pow(cornerDelta, vec2(3.0));
+ } else {
+ vec2 nearestCore = clamp(p, -core, core);
+ normalDelta = p - nearestCore;
+ }
+
+ float normalLength = length(normalDelta);
+
+ if (normalLength > 0.001) {
+ info.dir = normalDelta / normalLength;
+ } else {
+ vec2 lensPx = px;
+ float dL = lensPx.x;
+ float dR = halfSize.x * 2.0 - lensPx.x;
+ float dT = lensPx.y;
+ float dB = halfSize.y * 2.0 - lensPx.y;
+ float dm = min(min(dL, dR), min(dT, dB));
+
+ info.dir = vec2(
+ (dL < dR && dL == dm) ? -1.0 : (dR <= dL && dR == dm) ? 1.0 : 0.0,
+ (dT < dB && dT == dm) ? -1.0 : (dB <= dT && dB == dm) ? 1.0 : 0.0
+ );
+ }
+
+ return info;
+}
+
+vec2 backdropSampleUV(vec2 sampleUV, vec2 displacementPx) {
+ vec2 displaced = sampleUV + displacementPx / vec2(width, height);
+ float zoom = max(backdrop_zoom, 0.01);
+
+ displaced = vec2(0.5) + (displaced - vec2(0.5)) / zoom;
+ return displaced;
+}
+
+vec4 sampleDispersed(vec2 sampleUV, vec2 dispPx, float dispersion) {
+ float greenScale = dispersionOffsetScale(kDispersionGreenIndex, dispersion);
+ vec2 greenUV = resolveUV(backdropSampleUV(sampleUV, dispPx * greenScale));
+ vec4 greenSample = sampleGlassBackdrop(greenUV);
+
+ vec4 fallback = vec4(0.0);
+ bool loadedFallback = false;
+ if (greenSample.a < 0.01) {
+ vec2 fallbackUV = resolveUV(backdropSampleUV(sampleUV, vec2(0.0)));
+
+ fallback = sampleOrTintFallback(fallbackUV);
+ loadedFallback = true;
+ greenSample = fallback;
+ }
+
+ if (greenSample.a < 0.01)
+ return tintFallbackSample();
+
+ vec4 bg = greenSample;
+ if (dispersion > 0.001 && dot(dispPx, dispPx) > 0.0001) {
+ float redScale = dispersionOffsetScale(kDispersionRedIndex, dispersion);
+ float blueScale = dispersionOffsetScale(kDispersionBlueIndex, dispersion);
+
+ vec2 redUV = resolveUV(backdropSampleUV(sampleUV, dispPx * redScale));
+ vec2 blueUV = resolveUV(backdropSampleUV(sampleUV, dispPx * blueScale));
+ vec4 redSample = sampleGlassBackdrop(redUV);
+ vec4 blueSample = sampleGlassBackdrop(blueUV);
+
+ if (redSample.a < 0.01 || blueSample.a < 0.01) {
+ if (!loadedFallback) {
+ vec2 fallbackUV = resolveUV(backdropSampleUV(sampleUV, vec2(0.0)));
+ fallback = sampleOrTintFallback(fallbackUV);
+ }
+
+ if (redSample.a < 0.01)
+ redSample = fallback.a < 0.01 ? tintFallbackSample() : fallback;
+
+ if (blueSample.a < 0.01)
+ blueSample = fallback.a < 0.01 ? tintFallbackSample() : fallback;
+ }
+
+ bg.r = redSample.r;
+ bg.g = greenSample.g;
+ bg.b = blueSample.b;
+ bg.a = greenSample.a;
+ }
+ return bg;
+}
+
+vec4 applyTintAndShadow(vec4 sample, vec2 localUV, float alpha) {
+ vec3 tintColor = vec3(tint_r, tint_g, tint_b);
+ vec3 outRGB = mix(sample.rgb, tintColor, tint * tint_a);
+
+ outRGB *= 1.0 - smoothstep(0.25, 1.0, localUV.y) * shadow * 0.20;
+
+ return vec4(clamp(outRGB, 0.0, 1.0) * alpha, alpha);
+}
+
+void main() {
+ vec2 actorSize = vec2(width, height);
+ vec2 actorUV = cogl_tex_coord_in[0].xy;
+
+ if (private_pass == 1) {
+ cogl_color_out = sampleGlassBackdrop(actorUV);
+ return;
+ }
+
+ vec2 actorPx = actorUV * actorSize;
+ vec4 bounds = clip_width < 0.0 || clip_height < 0.0
+ ? vec4(0.0, 0.0, width, height)
+ : vec4(clip_x0, clip_y0, clip_x0 + clip_width, clip_y0 + clip_height);
+
+ vec2 glassSize = max(bounds.zw - bounds.xy, vec2(1.0));
+ vec2 glassPx = actorPx - bounds.xy;
+ vec2 halfSize = glassSize * 0.5;
+ vec2 localUV = glassPx / glassSize;
+
+ float W = glassSize.x;
+ float H = glassSize.y;
+ float shortestSide = min(W, H);
+ float R = clamp(corner_radius, 0.0, shortestSide * 0.5);
+ float bezel = max(1.0, min(edge_size, shortestSide * 0.5));
+ float glassThickness = max(0.5, edge_size * 0.55 * falloff);
+ float eta = 1.0 / REFRACTIVE_INDEX;
+
+ bool nearlySquare = abs(W - H) < max(4.0, shortestSide * 0.035);
+ bool useCircularSurface = nearlySquare && R >= shortestSide * 0.34;
+
+ EdgeInfo edge = estimateAnalyticEdge(glassPx, halfSize, R, shortestSide);
+ if (edge.alpha <= 0.0) {
+ cogl_color_out = vec4(0.0);
+ return;
+ }
+
+ float distFromSide = edge.distance;
+ float edgeOpacity = edge.alpha;
+ float edgeBand = 1.0;
+ float refractionBand = bezel;
+ vec2 dir = edge.dir;
+
+ if (useCircularSurface) {
+ float circleRadius = shortestSide * 0.5;
+ vec2 circleCenter = glassSize * 0.5;
+ vec2 fromCenter = glassPx - circleCenter;
+ float circleDistance = length(fromCenter);
+
+ if (circleDistance > circleRadius + 1.0) {
+ cogl_color_out = vec4(0.0);
+ return;
+ }
+
+ distFromSide = max(0.0, circleRadius - circleDistance);
+ dir = circleDistance > 0.001 ? normalize(fromCenter) : vec2(0.0, -1.0);
+ edgeOpacity = clamp(1.0 - max(0.0, circleDistance - circleRadius), 0.0, 1.0);
+
+ float rimRadius = max(1.0, bezel * 0.35);
+ refractionBand = rimRadius;
+ edgeBand = clamp(1.0 - (distFromSide / rimRadius), 0.0, 1.0);
+ } else {
+ float rimRadius = max(1.0, bezel * 0.35 * max(1.0, rim_width));
+ refractionBand = rimRadius;
+ edgeBand = clamp(1.0 - (distFromSide / rimRadius), 0.0, 1.0);
+ }
+
+ if (!useCircularSurface && R < shortestSide * 0.45 && distFromSide >= refractionBand) {
+ vec2 flatUV = backdropSampleUV(actorUV, vec2(0.0));
+ vec4 flatSample = sampleOrTintFallback(resolveUV(flatUV));
+ float finalOpacity = edgeOpacity * opacity_factor;
+
+ cogl_color_out = applyTintAndShadow(flatSample, localUV, finalOpacity);
+ return;
+ }
+
+ float bezelRatio = clamp(distFromSide / refractionBand, 0.0, 1.0);
+ float normDisp = distFromSide < refractionBand
+ ? displacementAtRatio(bezelRatio, glassThickness, refractionBand, eta)
+ : 0.0;
+ float dispStrength = useCircularSurface ? edgeOpacity : edgeBand;
+ vec2 dispPx = -dir * normDisp * refractionBand * strength * dispStrength;
+
+ float dispersion = clamp(rgb_fringing * DISPERSION_SCALE, 0.0, 20.0);
+ vec4 bgColor = sampleDispersed(actorUV, dispPx, dispersion);
+ if (bgColor.a < 0.01) {
+ cogl_color_out = vec4(0.0);
+ return;
+ }
+
+ vec3 outRGB = mix(bgColor.rgb, vec3(tint_r, tint_g, tint_b), tint * tint_a);
+ float fresnel = fresnelAtRatio(bezelRatio, REFRACTIVE_INDEX) * edgeOpacity;
+ float bgLuminance = luminance(outRGB);
+ float glare = clamp(fresnel * 0.70 * mix(0.40, 1.0, bgLuminance), 0.0, 0.18)
+ * clamp(gloss, 0.0, 1.0);
+ outRGB = 1.0 - (1.0 - outRGB) * (1.0 - glare);
+ outRGB *= 1.0 - smoothstep(0.25, 1.0, localUV.y) * shadow * 0.20;
+
+ float finalOpacity = edgeOpacity * opacity_factor;
+ cogl_color_out = vec4(clamp(outRGB, 0.0, 1.0) * finalOpacity, finalOpacity);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.js
new file mode 100644
index 0000000..27fdcc0
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/refraction.js
@@ -0,0 +1,849 @@
+import GObject from 'gi://GObject';
+import GLib from 'gi://GLib';
+
+import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 = 'refraction.glsl';
+const SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+const CLIP_STABILIZE_EPSILON = 1.0;
+const MAX_BLUR_RADIUS = 48.0;
+
+const DEFAULT_PARAMS = {
+ strength: 0.42,
+ blur_radius: 10,
+ edge_size: 22,
+ falloff: 2.4,
+ corner_radius: 22,
+ rim_width: 4.8,
+ rgb_fringing: 0.08,
+ gloss: 0.55,
+ webcam_gloss: false,
+ webcam_device: '',
+ tint: 0.18,
+ tint_color: [1.0, 1.0, 1.0, 1.0],
+ backdrop_zoom: 1.0,
+ shadow: 0.28,
+ texture_repeat: 0,
+ blur_direction: 0,
+ private_pass: 0,
+ chained_effect: null,
+ width: 0,
+ height: 0,
+ opacity_factor: 1.0,
+ clip: [0, 0, -1, -1]
+};
+
+const REFRACTION_EFFECT_META = {
+ GTypeName: "RefractionEffect",
+ Properties: {
+ 'strength': GObject.ParamSpec.double(
+ `strength`,
+ `Strength`,
+ `Refraction strength`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.42,
+ ),
+ 'edge_size': GObject.ParamSpec.double(
+ `edge_size`,
+ `Edge Size`,
+ `Refraction edge size`,
+ GObject.ParamFlags.READWRITE,
+ 1.0, 200.0,
+ 22.0,
+ ),
+ 'blur_radius': GObject.ParamSpec.double(
+ `blur_radius`,
+ `Blur Radius`,
+ `Internal glass blur radius`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, MAX_BLUR_RADIUS,
+ 10.0,
+ ),
+ 'falloff': GObject.ParamSpec.double(
+ `falloff`,
+ `Falloff`,
+ `Refraction falloff`,
+ GObject.ParamFlags.READWRITE,
+ 0.25, 8.0,
+ 2.4,
+ ),
+ 'corner_radius': GObject.ParamSpec.double(
+ `corner_radius`,
+ `Corner Radius`,
+ `Refraction corner radius`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 200.0,
+ 22.0,
+ ),
+ 'rim_width': GObject.ParamSpec.double(
+ `rim_width`,
+ `Rim Width`,
+ `Refraction rim width`,
+ GObject.ParamFlags.READWRITE,
+ 1.0, 6.5,
+ 4.8,
+ ),
+ 'rgb_fringing': GObject.ParamSpec.double(
+ `rgb_fringing`,
+ `RGB Fringing`,
+ `Chromatic offset strength`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.08,
+ ),
+ 'gloss': GObject.ParamSpec.double(
+ `gloss`,
+ `Gloss`,
+ `Specular highlight strength`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.55,
+ ),
+ 'webcam_gloss': GObject.ParamSpec.boolean(
+ `webcam_gloss`,
+ `Deprecated Webcam Gloss`,
+ `Deprecated compatibility property`,
+ GObject.ParamFlags.READWRITE,
+ false,
+ ),
+ 'webcam_device': GObject.ParamSpec.string(
+ `webcam_device`,
+ `Deprecated Webcam Device`,
+ `Deprecated compatibility property`,
+ GObject.ParamFlags.READWRITE,
+ '',
+ ),
+ 'tint': GObject.ParamSpec.double(
+ `tint`,
+ `Tint`,
+ `Glass tint strength`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.18,
+ ),
+ 'tint_red': GObject.ParamSpec.double(
+ `tint_red`,
+ `Tint Red`,
+ `Glass tint color red`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
+ 'tint_green': GObject.ParamSpec.double(
+ `tint_green`,
+ `Tint Green`,
+ `Glass tint color green`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
+ 'tint_blue': GObject.ParamSpec.double(
+ `tint_blue`,
+ `Tint Blue`,
+ `Glass tint color blue`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
+ 'tint_alpha': GObject.ParamSpec.double(
+ `tint_alpha`,
+ `Tint Alpha`,
+ `Glass tint color alpha`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
+ 'backdrop_zoom': GObject.ParamSpec.double(
+ `backdrop_zoom`,
+ `Backdrop Zoom`,
+ `Zoom level of the refracted backdrop`,
+ GObject.ParamFlags.READWRITE,
+ 0.1, 4.0,
+ 1.0,
+ ),
+ 'shadow': GObject.ParamSpec.double(
+ `shadow`,
+ `Shadow`,
+ `Inner shadow strength`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 0.28,
+ ),
+ 'texture_repeat': GObject.ParamSpec.int(
+ `texture_repeat`,
+ `Texture Repeat`,
+ `Texture repeat behavior`,
+ GObject.ParamFlags.READWRITE,
+ 0, 1,
+ 0,
+ ),
+ 'blur_direction': GObject.ParamSpec.int(
+ `blur_direction`,
+ `Blur Direction`,
+ `Private Gaussian blur direction`,
+ GObject.ParamFlags.READWRITE,
+ 0, 1,
+ 0,
+ ),
+ 'private_pass': GObject.ParamSpec.int(
+ `private_pass`,
+ `Private Pass`,
+ `Private Gaussian blur pass`,
+ GObject.ParamFlags.READWRITE,
+ 0, 1,
+ 0,
+ ),
+ 'chained_effect': GObject.ParamSpec.object(
+ `chained_effect`,
+ `Chained Effect`,
+ `Private chained blur effect`,
+ GObject.ParamFlags.READWRITE,
+ GObject.Object,
+ ),
+ '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,
+ ),
+ // See corner.js: this is backed by an array setter, but represented
+ // as a dummy property so pipeline parameter assignment can reach it.
+ 'clip': GObject.ParamSpec.double(
+ `clip`,
+ `Clip`,
+ `Clip`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, Number.MAX_SAFE_INTEGER,
+ 0.0,
+ ),
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
+ }
+};
+
+const RefractionEffectClass = utils.IS_IN_PREFERENCES ? null : class RefractionEffect extends Clutter.ShaderEffect {
+
+ constructor(params) {
+ const {
+ webcam_gloss: _webcam_gloss,
+ webcam_device: _webcam_device,
+ tint_color: _tint_color,
+ ...parent_params
+ } = params;
+ super({ ...parent_params });
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
+
+ this._clip_x0 = null;
+ this._clip_y0 = null;
+ this._clip_width = null;
+ this._clip_height = null;
+ this._stable_clip_x0 = null;
+ this._stable_clip_y0 = null;
+ this._stable_clip_width = null;
+ this._stable_clip_height = null;
+ this._stabilize_clip_x = false;
+ this._stabilize_clip_y = false;
+ this._clip_settle_timeout_id = null;
+
+ utils.setup_params(this, params);
+
+ this._theme_context = St.ThemeContext.get_for_stage(global.stage);
+ this._theme_context.connectObject(
+ 'notify::scale-factor',
+ _ => this.update_scaled_uniforms(),
+ this
+ );
+ }
+
+ static get default_params() {
+ return DEFAULT_PARAMS;
+ }
+
+ get strength() {
+ return this._strength;
+ }
+
+ set strength(value) {
+ if (this._strength !== value) {
+ this._strength = value;
+
+ this.set_uniform_value('strength', parseFloat(this._strength - 1e-6));
+ this.set_enabled(this.strength > 0.);
+ }
+ }
+
+ get edge_size() {
+ return this._edge_size;
+ }
+
+ set edge_size(value) {
+ if (this._edge_size !== value) {
+ this._edge_size = value;
+
+ this.update_scaled_uniforms();
+
+ if (this.chained_effect)
+ this.chained_effect.edge_size = value;
+ }
+ }
+
+ get blur_radius() {
+ return this._blur_radius;
+ }
+
+ set blur_radius(value) {
+ if (this._blur_radius !== value) {
+ this._blur_radius = Math.min(value, MAX_BLUR_RADIUS);
+
+ this.update_scaled_uniforms();
+
+ if (this.chained_effect)
+ this.chained_effect.blur_radius = this._blur_radius;
+ }
+ }
+
+ get falloff() {
+ return this._falloff;
+ }
+
+ set falloff(value) {
+ if (this._falloff !== value) {
+ this._falloff = value;
+
+ this.set_uniform_value('falloff', parseFloat(this._falloff - 1e-6));
+
+ if (this.chained_effect)
+ this.chained_effect.falloff = value;
+ }
+ }
+
+ get corner_radius() {
+ return this._corner_radius;
+ }
+
+ set corner_radius(value) {
+ if (this._corner_radius !== value) {
+ this._corner_radius = value;
+
+ this.update_scaled_uniforms();
+
+ if (this.chained_effect)
+ this.chained_effect.corner_radius = value;
+ }
+ }
+
+ get rim_width() {
+ return this._rim_width;
+ }
+
+ set rim_width(value) {
+ const rim_width = Math.max(1.0, Math.min(value, 6.5));
+ if (this._rim_width !== rim_width) {
+ this._rim_width = rim_width;
+
+ this.set_uniform_value('rim_width', parseFloat(this._rim_width - 1e-6));
+
+ if (this.chained_effect)
+ this.chained_effect.rim_width = rim_width;
+ }
+ }
+
+ get rgb_fringing() {
+ return this._rgb_fringing;
+ }
+
+ set rgb_fringing(value) {
+ if (this._rgb_fringing !== value) {
+ this._rgb_fringing = value;
+
+ this.set_uniform_value('rgb_fringing', parseFloat(this._rgb_fringing - 1e-6));
+ }
+ }
+
+ get gloss() {
+ return this._gloss;
+ }
+
+ set gloss(value) {
+ if (this._gloss !== value) {
+ this._gloss = value;
+
+ this.set_uniform_value('gloss', parseFloat(this._gloss - 1e-6));
+ }
+ }
+
+ // Deprecated no-op compatibility properties for old saved pipelines.
+ get webcam_gloss() {
+ return this._webcam_gloss;
+ }
+
+ set webcam_gloss(value) {
+ this._webcam_gloss = value;
+ }
+
+ get webcam_device() {
+ return this._webcam_device;
+ }
+
+ set webcam_device(value) {
+ this._webcam_device = value ?? '';
+ }
+
+ get tint() {
+ return this._tint;
+ }
+
+ set tint(value) {
+ if (this._tint !== value) {
+ this._tint = value;
+
+ this.set_uniform_value('tint', parseFloat(this._tint - 1e-6));
+ }
+ }
+
+ get tint_red() {
+ return this._tint_red;
+ }
+
+ set tint_red(value) {
+ if (this._tint_red !== value) {
+ this._tint_red = value;
+
+ this.set_uniform_value('tint_r', parseFloat(this._tint_red - 1e-6));
+ }
+ }
+
+ get tint_green() {
+ return this._tint_green;
+ }
+
+ set tint_green(value) {
+ if (this._tint_green !== value) {
+ this._tint_green = value;
+
+ this.set_uniform_value('tint_g', parseFloat(this._tint_green - 1e-6));
+ }
+ }
+
+ get tint_blue() {
+ return this._tint_blue;
+ }
+
+ set tint_blue(value) {
+ if (this._tint_blue !== value) {
+ this._tint_blue = value;
+
+ this.set_uniform_value('tint_b', parseFloat(this._tint_blue - 1e-6));
+ }
+ }
+
+ get tint_alpha() {
+ return this._tint_alpha;
+ }
+
+ set tint_alpha(value) {
+ if (this._tint_alpha !== value) {
+ this._tint_alpha = value;
+
+ this.set_uniform_value('tint_a', parseFloat(this._tint_alpha - 1e-6));
+ }
+ }
+
+ get tint_color() {
+ return [this.tint_red, this.tint_green, this.tint_blue, this.tint_alpha];
+ }
+
+ set tint_color(rgba) {
+ const [r, g, b, a] = rgba;
+ this.tint_red = r;
+ this.tint_green = g;
+ this.tint_blue = b;
+ this.tint_alpha = a ?? 1.0;
+ }
+
+ get backdrop_zoom() {
+ return this._backdrop_zoom;
+ }
+
+ set backdrop_zoom(value) {
+ if (this._backdrop_zoom !== value) {
+ this._backdrop_zoom = value;
+
+ this.set_uniform_value('backdrop_zoom', parseFloat(this._backdrop_zoom - 1e-6));
+ }
+ }
+
+ get shadow() {
+ return this._shadow;
+ }
+
+ set shadow(value) {
+ if (this._shadow !== value) {
+ this._shadow = value;
+
+ this.set_uniform_value('shadow', parseFloat(this._shadow - 1e-6));
+ }
+ }
+
+ get texture_repeat() {
+ return this._texture_repeat;
+ }
+
+ set texture_repeat(value) {
+ if (this._texture_repeat !== value) {
+ this._texture_repeat = value;
+
+ this.set_uniform_value('texture_repeat', this._texture_repeat);
+
+ if (this.chained_effect)
+ this.chained_effect.texture_repeat = value;
+ }
+ }
+
+ get blur_direction() {
+ return this._blur_direction;
+ }
+
+ set blur_direction(value) {
+ if (this._blur_direction !== value) {
+ this._blur_direction = value;
+
+ this.set_uniform_value('blur_direction', this._blur_direction);
+ }
+ }
+
+ get private_pass() {
+ return this._private_pass;
+ }
+
+ set private_pass(value) {
+ if (this._private_pass !== value) {
+ this._private_pass = value;
+
+ this.set_uniform_value('private_pass', this._private_pass);
+ if (this._private_pass === 1)
+ this.set_enabled(this.blur_radius > 0.01);
+ }
+ }
+
+ get chained_effect() {
+ return this._chained_effect;
+ }
+
+ set chained_effect(value) {
+ this._chained_effect = value;
+ }
+
+ set(params) {
+ utils.setup_params(this, params);
+ }
+
+ 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_scaled_uniforms();
+
+ 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));
+ this.update_scaled_uniforms();
+
+ if (this.chained_effect)
+ this.chained_effect.height = value;
+ }
+ }
+
+ get clip() {
+ return [this._clip_x0, this._clip_y0, this._clip_width, this._clip_height];
+ }
+
+ set clip(value) {
+ const previous_clip = this.clip;
+ [this._clip_x0, this._clip_y0, this._clip_width, this._clip_height] = value;
+
+ let shader_clip = this._stabilized_clip(previous_clip);
+
+ this.set_uniform_value('clip_x0', parseFloat(shader_clip[0] - 1e-6));
+ this.set_uniform_value('clip_y0', parseFloat(shader_clip[1] - 1e-6));
+ this.set_uniform_value('clip_width', parseFloat(shader_clip[2] + 3.0 - 1e-6));
+ this.set_uniform_value('clip_height', parseFloat(shader_clip[3] + 3.0 - 1e-6));
+ this.update_scaled_uniforms();
+ }
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
+
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
+
+ if (this.chained_effect)
+ this.chained_effect.opacity_factor = value;
+ }
+ }
+
+ _stabilized_clip(previous_clip) {
+ if (this._clip_width < 0 || this._clip_height < 0) {
+ this._stable_clip_x0 = null;
+ this._stable_clip_y0 = null;
+ this._stable_clip_width = null;
+ this._stable_clip_height = null;
+ this._stabilize_clip_x = false;
+ this._stabilize_clip_y = false;
+ if (this._clip_settle_timeout_id) {
+ GLib.Source.remove(this._clip_settle_timeout_id);
+ this._clip_settle_timeout_id = null;
+ }
+ return [
+ this._clip_x0,
+ this._clip_y0,
+ this._clip_width,
+ this._clip_height
+ ];
+ }
+
+ const [previous_x0, previous_y0, previous_width, previous_height] = previous_clip;
+
+ [this._stable_clip_x0, this._stable_clip_width, this._stabilize_clip_x] =
+ this._stabilized_clip_axis(
+ this._clip_x0,
+ this._clip_width,
+ previous_x0,
+ previous_width,
+ this._stable_clip_x0,
+ this._stable_clip_width,
+ this._stabilize_clip_x
+ );
+ [this._stable_clip_y0, this._stable_clip_height, this._stabilize_clip_y] =
+ this._stabilized_clip_axis(
+ this._clip_y0,
+ this._clip_height,
+ previous_y0,
+ previous_height,
+ this._stable_clip_y0,
+ this._stable_clip_height,
+ this._stabilize_clip_y
+ );
+
+ if (this._clip_settle_timeout_id)
+ GLib.Source.remove(this._clip_settle_timeout_id);
+
+ if (!this._stabilize_clip_x && !this._stabilize_clip_y) {
+ this._clip_settle_timeout_id = null;
+ return [
+ this._stable_clip_x0,
+ this._stable_clip_y0,
+ this._stable_clip_width,
+ this._stable_clip_height
+ ];
+ }
+
+ this._clip_settle_timeout_id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 220, () => {
+ this._stable_clip_x0 = this._clip_x0;
+ this._stable_clip_y0 = this._clip_y0;
+ this._stable_clip_width = this._clip_width;
+ this._stable_clip_height = this._clip_height;
+ this._stabilize_clip_x = false;
+ this._stabilize_clip_y = false;
+ this._clip_settle_timeout_id = null;
+ this.clip = [this._clip_x0, this._clip_y0, this._clip_width, this._clip_height];
+ this.queue_repaint();
+ return GLib.SOURCE_REMOVE;
+ });
+
+ return [
+ this._stable_clip_x0,
+ this._stable_clip_y0,
+ this._stable_clip_width,
+ this._stable_clip_height
+ ];
+ }
+
+ _stabilized_clip_axis(
+ start,
+ size,
+ previous_start,
+ previous_size,
+ stable_start,
+ stable_size,
+ stabilizing
+ ) {
+ const size_changed =
+ previous_size !== null &&
+ previous_size >= 0 &&
+ Math.abs(size - previous_size) > CLIP_STABILIZE_EPSILON;
+
+ if (!stabilizing && !size_changed)
+ return [start, size, false];
+
+ const end = start + size;
+ const resolved_stable_start = stable_start ?? previous_start ?? start;
+ const resolved_stable_size = stable_size ?? previous_size ?? size;
+ const stable_end = resolved_stable_start + resolved_stable_size;
+ const resolved_start = Math.min(resolved_stable_start, start);
+ const resolved_end = Math.max(stable_end, end);
+
+ return [resolved_start, resolved_end - resolved_start, true];
+ }
+
+ update_scaled_uniforms() {
+ const scale_factor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
+ const rect_width =
+ this._stable_clip_width ?? (this._clip_width >= 0 ? this._clip_width : this.width);
+ const rect_height =
+ this._stable_clip_height ?? (this._clip_height >= 0 ? this._clip_height : this.height);
+ const max_edge = Math.max(1, Math.min(rect_width, rect_height) / 2);
+ const edge_size = Math.min(this.edge_size * scale_factor, max_edge);
+ const corner_radius = Math.min(this.corner_radius * scale_factor, max_edge);
+
+ this.set_uniform_value('edge_size', parseFloat(edge_size - 1e-6));
+ this.set_uniform_value('corner_radius', parseFloat(corner_radius - 1e-6));
+ const blur_radius = Math.min(this.blur_radius, MAX_BLUR_RADIUS) * scale_factor;
+ this.set_uniform_value('blur_radius', parseFloat(blur_radius - 1e-6));
+ if (this.private_pass === 1)
+ this.set_enabled(blur_radius > 0.01);
+ }
+
+ vfunc_set_actor(actor) {
+ if (this.chained_effect)
+ this.chained_effect.get_actor()?.remove_effect(this.chained_effect);
+
+ 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 (this._clip_settle_timeout_id) {
+ GLib.Source.remove(this._clip_settle_timeout_id);
+ this._clip_settle_timeout_id = null;
+ }
+ 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;
+ this._stable_clip_x0 = null;
+ this._stable_clip_y0 = null;
+ this._stable_clip_width = null;
+ this._stable_clip_height = null;
+ this._stabilize_clip_x = false;
+ this._stabilize_clip_y = false;
+ }
+
+ super.vfunc_set_actor(actor);
+
+ if (this.private_pass === 0) {
+ if (!this.chained_effect) {
+ const chained_params = {
+ strength: this.strength,
+ blur_radius: this.blur_radius,
+ edge_size: this.edge_size,
+ falloff: this.falloff,
+ corner_radius: this.corner_radius,
+ rim_width: this.rim_width,
+ rgb_fringing: this.rgb_fringing,
+ gloss: this.gloss,
+ tint: this.tint,
+ shadow: this.shadow,
+ texture_repeat: this.texture_repeat,
+ width: this.width,
+ height: this.height,
+ clip: this.clip,
+ blur_direction: 1,
+ private_pass: 1,
+ opacity_factor: this._opacity_factor
+ };
+
+ this.chained_effect = new RefractionEffect(chained_params);
+ }
+
+ if (actor !== null)
+ actor.add_effect(this.chained_effect);
+ }
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ uniforms.upload_uniforms(this);
+ this.set_uniform_value('blur_direction', this.blur_direction);
+ this.set_uniform_value('private_pass', this.private_pass);
+
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+
+ vfunc_dispose() {
+ if (this._clip_settle_timeout_id) {
+ GLib.Source.remove(this._clip_settle_timeout_id);
+ this._clip_settle_timeout_id = null;
+ }
+
+ if (this.chained_effect) {
+ this.chained_effect.get_actor()?.remove_effect(this.chained_effect);
+ this.chained_effect = null;
+ }
+
+ this._theme_context?.disconnectObject(this);
+ this._theme_context = null;
+
+ if (super.vfunc_dispose)
+ super.vfunc_dispose();
+ }
+};
+
+export const RefractionEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(REFRACTION_EFFECT_META, RefractionEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl
index b7a35ac..ba09fe0 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl
@@ -1,4 +1,5 @@
uniform sampler2D tex;
+uniform float opacity_factor;
vec3 rgb_to_hsl(vec3 c) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
@@ -14,5 +15,5 @@ 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
+ cogl_color_out = mix(rgba, hsla, opacity_factor);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js
index 5c4eb05..81b3596 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js
@@ -1,31 +1,64 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 = {};
+const SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
+const DEFAULT_PARAMS = {
+ opacity_factor: 1
+};
-export const RgbToHslEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const RGB_TO_HSL_EFFECT_META = {
GTypeName: "RgbToHslEffect",
- Properties: {}
- }, class RgbToHslEffect extends Clutter.ShaderEffect {
+ Properties: {
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
+ }
+};
+
+const RgbToHslEffectClass = utils.IS_IN_PREFERENCES ? null : class RgbToHslEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
- utils.setup_params(this, params);
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- // set shader source
- this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
- if (this._source)
- this.set_shader_source(this._source);
+
+ utils.setup_params(this, params);
}
static get default_params() {
return DEFAULT_PARAMS;
}
- }); \ No newline at end of file
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
+
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
+ }
+ }
+
+ vfunc_paint_target(paint_node, paint_context) {
+ uniforms.upload_uniforms(this);
+ super.vfunc_paint_target(paint_node, paint_context);
+ }
+};
+
+export const RgbToHslEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(RGB_TO_HSL_EFFECT_META, RgbToHslEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl
index 5cc06ec..3d743df 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl
@@ -2,13 +2,14 @@ uniform sampler2D tex;
uniform int factor;
uniform float width;
uniform float height;
+uniform float opacity_factor;
#define CORRECTION 2.25
-#define SIZE_ADDITION 3
+#define SIZE_ADDITION 3.0
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);
+ vec2 raw_uv = raw_position / vec2(max(1.0, width + SIZE_ADDITION), max(1.0, height + SIZE_ADDITION));
return texture2D(tex, raw_uv);
}
@@ -20,38 +21,41 @@ ivec2 get_corrected_position() {
}
void main() {
+ vec4 source_color = texture2D(tex, cogl_tex_coord0_in.st);
ivec2 corrected_position = get_corrected_position();
+ int safe_factor = max(1, factor);
- vec2 adjusted_position = corrected_position / factor;
+ vec2 adjusted_position = vec2(corrected_position / safe_factor);
- cogl_color_out = get_texture_at_position(adjusted_position);
+ vec4 effect_color = get_texture_at_position(adjusted_position);
+ cogl_color_out = mix(source_color, effect_color, opacity_factor);
// round
- if (distance(corrected_position, (floor(adjusted_position) + 0.5) * factor) < factor / 2.5) {
+ if (distance(vec2(corrected_position), (floor(adjusted_position) + 0.5) * float(safe_factor)) < float(safe_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) {
+ if (mod(float(corrected_position.x), float(safe_factor)) >= 2.0 && mod(float(corrected_position.y), float(safe_factor)) >= 2.0) {
//cogl_color_out = get_texture_at_position(adjusted_position);
} else {
//cogl_color_out = vec4(0, 0, 0, 1);
}
// local mix
- vec4 color = vec4(0);
+ vec4 color = vec4(0.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))) {
+ vec2 lookup_position = adjusted_position + vec2(float(i), float(j));
+ if (all(greaterThanEqual(lookup_position, vec2(0.0, 0.0))) &&
+ all(lessThan(lookup_position, vec2(width, height) / float(safe_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-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js
index fb719c3..d29ba8c 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js
@@ -1,18 +1,18 @@
import GObject from 'gi://GObject';
import * as utils from '../conveniences/utils.js';
+import * as uniforms from '../conveniences/shader_uniforms.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 SHADER_SOURCE = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url);
const DEFAULT_PARAMS = {
- factor: 8, width: 0, height: 0
+ factor: 8, opacity_factor: 1, width: 0, height: 0
};
-export const UpscaleEffect = utils.IS_IN_PREFERENCES ?
- { default_params: DEFAULT_PARAMS } :
- new GObject.registerClass({
+const UPSCALE_EFFECT_META = {
GTypeName: "UpscaleEffect",
Properties: {
'factor': GObject.ParamSpec.int(
@@ -23,6 +23,14 @@ export const UpscaleEffect = utils.IS_IN_PREFERENCES ?
0, 64,
8,
),
+ 'opacity_factor': GObject.ParamSpec.double(
+ `opacity_factor`,
+ `Opacity factor`,
+ `Opacity factor`,
+ GObject.ParamFlags.READWRITE,
+ 0.0, 1.0,
+ 1.0,
+ ),
'width': GObject.ParamSpec.double(
`width`,
`Width`,
@@ -40,16 +48,17 @@ export const UpscaleEffect = utils.IS_IN_PREFERENCES ?
0.0,
)
}
- }, class UpscaleEffect extends Clutter.ShaderEffect {
+};
+
+const UpscaleEffectClass = utils.IS_IN_PREFERENCES ? null : class UpscaleEffect extends Clutter.ShaderEffect {
+
constructor(params) {
- super(params);
+ super();
+
+ utils.initialize_shader_effect(this, SHADER_SOURCE);
- 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);
+ utils.setup_params(this, params);
}
static get default_params() {
@@ -61,10 +70,23 @@ export const UpscaleEffect = utils.IS_IN_PREFERENCES ?
}
set factor(value) {
- if (this._factor !== value) {
- this._factor = value;
+ const v = Math.max(1, value || 1);
+ if (this._factor !== v) {
+ this._factor = v;
+
+ uniforms.set_uniform(this, 'factor', this._factor);
+ }
+ }
+
+ get opacity_factor() {
+ return this._opacity_factor;
+ }
+
+ set opacity_factor(value) {
+ if (this._opacity_factor !== value) {
+ this._opacity_factor = value;
- this.set_uniform_value('factor', this._factor);
+ uniforms.set_uniform(this, 'opacity_factor', parseFloat(this._opacity_factor));
}
}
@@ -73,10 +95,11 @@ export const UpscaleEffect = utils.IS_IN_PREFERENCES ?
}
set width(value) {
- if (this._width !== value) {
- this._width = value;
+ const v = Math.max(1, value || 1);
+ if (this._width !== v) {
+ this._width = v;
- this.set_uniform_value('width', parseFloat(this._width - 1e-6));
+ uniforms.set_uniform(this, 'width', parseFloat(this._width - 1e-6));
}
}
@@ -85,10 +108,11 @@ export const UpscaleEffect = utils.IS_IN_PREFERENCES ?
}
set height(value) {
- if (this._height !== value) {
- this._height = value;
+ const v = Math.max(1, value || 1);
+ if (this._height !== v) {
+ this._height = v;
- this.set_uniform_value('height', parseFloat(this._height - 1e-6));
+ uniforms.set_uniform(this, 'height', parseFloat(this._height - 1e-6));
}
}
@@ -112,9 +136,17 @@ export const UpscaleEffect = utils.IS_IN_PREFERENCES ?
}
vfunc_paint_target(paint_node, paint_context) {
- // force setting nearest-neighbour texture filtering
- this.get_pipeline().set_layer_filters(0, 9728, 9728);
+ uniforms.upload_uniforms(this);
+
+ const pipeline = this.get_pipeline();
+ if (pipeline) {
+ pipeline.set_layer_filters(0, 9728, 9728);
+ }
super.vfunc_paint_target(paint_node, paint_context);
}
- }); \ No newline at end of file
+};
+
+export const UpscaleEffect = utils.IS_IN_PREFERENCES
+ ? { default_params: DEFAULT_PARAMS }
+ : utils.register_shader_effect(UPSCALE_EFFECT_META, UpscaleEffectClass, SHADER_SOURCE);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/extension.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/extension.js
index b94ac65..2d7309a 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/extension.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/extension.js
@@ -6,7 +6,6 @@ import * as Config from 'resource:///org/gnome/shell/misc/config.js';
import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js';
import { update_from_old_settings } from './conveniences/settings_updater.js';
-import { import_in_shell_only} from './conveniences/utils.js';
import { PipelinesManager } from './conveniences/pipelines_manager.js';
import { EffectsManager } from './conveniences/effects_manager.js';
import { Connections } from './conveniences/connections.js';
@@ -22,8 +21,8 @@ import { WindowListBlur } from './components/window_list.js';
import { CoverflowAltTabBlur } from './components/coverflow_alt_tab.js';
import { ApplicationsBlur } from './components/applications.js';
import { ScreenshotBlur } from './components/screenshot.js';
-
-const BlurModule = await import_in_shell_only('gi://Blur');
+import { PopupBlur } from './components/popup.js';
+import { NativeDynamicBlurEffect } from './effects/native_dynamic_gaussian_blur.js';
/// The main extension class, created when the GNOME Shell is loaded.
@@ -75,6 +74,7 @@ export default class BlurMyShell extends Extension {
this._coverflow_alt_tab_blur = new CoverflowAltTabBlur(...init());
this._applications_blur = new ApplicationsBlur(...init());
this._screenshot_blur = new ScreenshotBlur(...init());
+ this._popup = new PopupBlur(...init());
// connect each component to preferences change
this._connect_to_settings();
@@ -83,7 +83,7 @@ export default class BlurMyShell extends Extension {
if (this._settings.lockscreen.BLUR && !this._lockscreen_blur.enabled)
this._lockscreen_blur.enable();
- // update whether or not the external rounded corners library was found
+ // update whether or not the active blur effect supports rounded corners
this._update_rounded_blur_found();
// ensure we take the correct action for the current session mode
@@ -117,28 +117,14 @@ export default class BlurMyShell extends Extension {
// try to enable the components as soon as possible anyway, this way the
// overview may load before the user sees it
- try {
- if (this._settings.overview.BLUR && !this._overview_blur.enabled)
- this._overview_blur.enable();
- } catch (e) {
- this._log("Could not enable overview blur directly");
- this._log(e);
- }
- try {
- if (this._settings.dash_to_dock.BLUR
- && !this._dash_to_dock_blur.enabled)
- this._dash_to_dock_blur.enable();
- } catch (e) {
- this._log("Could not enable dash-to-dock blur directly");
- this._log(e);
- }
- try {
- if (this._settings.panel.BLUR && !this._panel_blur.enabled)
- this._panel_blur.enable();
- } catch (e) {
- this._log("Could not enable panel blur directly");
- this._log(e);
- }
+ if (this._settings.overview.BLUR && !this._overview_blur.enabled)
+ this._overview_blur.enable();
+
+ if (this._settings.dash_to_dock.BLUR && !this._dash_to_dock_blur.enabled)
+ this._dash_to_dock_blur.enable();
+
+ if (this._settings.panel.BLUR && !this._panel_blur.enabled)
+ this._panel_blur.enable();
// tells the extension we have enabled the user session components, so that we do not
// disable them later if they were not even enabled to begin with
@@ -166,7 +152,8 @@ export default class BlurMyShell extends Extension {
this._disable_user_session();
this._overview_blur.restore_patched_proto();
- // disable lockscreen blur too
+ // disable components that stay active outside the user session
+ this._popup.disable();
this._lockscreen_blur.disable();
// untrack them
@@ -179,6 +166,12 @@ export default class BlurMyShell extends Extension {
this._coverflow_alt_tab_blur = null;
this._applications_blur = null;
this._screenshot_blur = null;
+ this._popup = null;
+
+ this._effects_manager.destroy_all();
+ this._pipelines_manager.destroy();
+ this._effects_manager = null;
+ this._pipelines_manager = null;
// make sure no settings change can re-enable them
this._settings.disconnect_all_settings();
@@ -204,7 +197,7 @@ export default class BlurMyShell extends Extension {
_disable_user_session() {
this._log("disabling user session mode...");
- // disable every component except lockscreen blur
+ // disable every component except lockscreen blur and popup blur
this._panel_blur.disable();
this._dash_to_dock_blur.disable();
this._overview_blur.disable();
@@ -247,16 +240,14 @@ export default class BlurMyShell extends Extension {
}
}
- /// Verify whether or not the gi://Blur library was found, in order to inform
- /// the preferences and instruct the user to install it to have native rounded
- /// corners in dynamic blur.
+ /// Verify whether the active native blur effect supports rounded corners.
_update_rounded_blur_found() {
- if (BlurModule === null) {
+ if (!NativeDynamicBlurEffect.supports_corner_radius) {
this._settings.ROUNDED_BLUR_FOUND = false;
this._log("using original implementation for the native blur effect")
} else {
this._settings.ROUNDED_BLUR_FOUND = true;
- this._log("using external library for the native blur effect")
+ this._log("using native rounded corners for the blur effect")
}
}
@@ -326,6 +317,9 @@ export default class BlurMyShell extends Extension {
if (this._settings.screenshot.BLUR)
this._screenshot_blur.enable();
+ if (this._settings.popup.BLUR)
+ this._popup.enable();
+
this._log("all components enabled.");
}
@@ -427,8 +421,10 @@ export default class BlurMyShell extends Extension {
// panel override background toggled on/off
this._settings.panel.OVERRIDE_BACKGROUND_changed(() => {
- if (this._settings.panel.BLUR)
+ if (this._settings.panel.BLUR) {
this._panel_blur.connect_to_windows_and_overview();
+ this._panel_blur.reset();
+ }
});
// panel style changed
@@ -439,10 +435,30 @@ export default class BlurMyShell extends Extension {
// panel background's dynamic overriding toggled on/off
this._settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_changed(() => {
- if (this._settings.panel.BLUR)
+ if (this._settings.panel.BLUR) {
this._panel_blur.connect_to_windows_and_overview();
+ this._panel_blur.reset();
+ }
});
+ this._settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_MODE_changed(() => {
+ if (this._settings.panel.BLUR) {
+ this._panel_blur.connect_to_windows_and_overview();
+ this._panel_blur.reset();
+ }
+ });
+
+ this._settings.panel.GRADIENT_PANEL_changed(() => {
+ if (this._settings.panel.BLUR) {
+ this._panel_blur.update_visibility() ;
+ }
+ });
+
+ this._settings.panel.GRADIENT_PANEL_MODE_changed(() => {
+ if (this._settings.panel.BLUR) {
+ this._panel_blur.update_visibility();
+ }
+ });
// ---------- DASH TO DOCK ----------
@@ -533,6 +549,12 @@ export default class BlurMyShell extends Extension {
this._applications_blur.connect_to_overview();
});
+ // application unblur-when-fullscreen changed
+ this._settings.applications.UNBLUR_WHEN_FULLSCREEN_changed(() => {
+ if (this._settings.applications.BLUR)
+ this._applications_blur.update_fullscreen_status();
+ });
+
// application enable-all changed
this._settings.applications.ENABLE_ALL_changed(() => {
if (this._settings.applications.BLUR)
@@ -630,6 +652,46 @@ export default class BlurMyShell extends Extension {
if (this._settings.screenshot.BLUR)
this._screenshot_blur.update_pipeline();
});
+
+
+ // ---------- POPUP BLUR ----------
+
+ // toggled on/off
+ this._settings.popup.BLUR_changed(() => {
+ if (this._settings.popup.BLUR)
+ this._popup.enable();
+ else
+ this._popup.disable();
+ });
+
+ this._settings.popup.STATIC_BLUR_changed(() => {
+ if (this._settings.popup.BLUR)
+ this._popup.reset();
+ });
+
+ this._settings.popup.PIPELINE_changed(() => {
+ if (this._settings.popup.BLUR)
+ this._popup.update_pipeline();
+ });
+
+ // popup background override toggled on/off
+ this._settings.popup.OVERRIDE_BACKGROUND_changed(() => {
+ if (this._settings.popup.BLUR)
+ this._popup.update_background();
+ });
+
+ // Apply only the popup surface override, leaving shell theme control
+ // and text styles intact.
+ this._settings.popup.PRESERVE_SHELL_THEME_changed(() => {
+ if (this._settings.popup.BLUR)
+ this._popup.update_background();
+ });
+
+ // popup background style changed
+ this._settings.popup.STYLE_POPUP_changed(() => {
+ if (this._settings.popup.BLUR)
+ this._popup.update_background();
+ });
}
_log(str) {
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/popup-symbolic.svg b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/popup-symbolic.svg
new file mode 100644
index 0000000..70af5e5
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/popup-symbolic.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <path d="M2 2h12c1.108 0 2 .892 2 2v8c0 1.108-.892 2-2 2H2c-1.108 0-2-.892-2-2V4c0-1.108.892-2 2-2Zm0 1c-.554 0-1 .446-1 1v1h14V4c0-.554-.446-1-1-1Zm-1 3v6c0 .554.446 1 1 1h12c.554 0 1-.446 1-1V6Zm4 2h6c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1H5c-.554 0-1-.446-1-1V9c0-.554.446-1 1-1Z" fill="currentColor"/>
+</svg>
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo
index 91de0ee..42172a1 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ca/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ca/LC_MESSAGES/blur-my-shell@aunetx.mo
index 24e8c8e..d4bfa8d 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ca/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ca/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo
index 2146336..9c61f31 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/eo/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/eo/LC_MESSAGES/blur-my-shell@aunetx.mo
index 76f5653..12a8b8d 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/eo/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/eo/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo
index 4d2e14b..41871cb 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mo
index 170aa00..dd32109 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ga/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ga/LC_MESSAGES/blur-my-shell@aunetx.mo
new file mode 100644
index 0000000..12af447
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ga/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/he/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/he/LC_MESSAGES/blur-my-shell@aunetx.mo
index c00a0b0..eb0ac9e 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/he/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/he/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/id/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/id/LC_MESSAGES/blur-my-shell@aunetx.mo
index 57b3f28..8c9ee01 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/id/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/id/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ja/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ja/LC_MESSAGES/blur-my-shell@aunetx.mo
index 4d399d4..c67d148 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ja/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ja/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ml/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ml/LC_MESSAGES/blur-my-shell@aunetx.mo
index a03d776..8253927 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ml/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ml/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/mrh/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/mrh/LC_MESSAGES/blur-my-shell@aunetx.mo
index 52a61c4..b01552f 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/mrh/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/mrh/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo
index 0a4628a..50a7c8d 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt_BR/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt_BR/LC_MESSAGES/blur-my-shell@aunetx.mo
index 5bc86f8..a45493d 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt_BR/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt_BR/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ro/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ro/LC_MESSAGES/blur-my-shell@aunetx.mo
index 799ffb8..5f233d2 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ro/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ro/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo
index b04ae12..74a6190 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mo
index 6503f17..4185f34 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/uk/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/uk/LC_MESSAGES/blur-my-shell@aunetx.mo
index cfdddf3..e76cac9 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/uk/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/uk/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_CN/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_CN/LC_MESSAGES/blur-my-shell@aunetx.mo
index 7b5f217..fa3e5a1 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_CN/LC_MESSAGES/blur-my-shell@aunetx.mo
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_CN/LC_MESSAGES/blur-my-shell@aunetx.mo
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/metadata.json b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/metadata.json
index 42d2697..bfeec0f 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/metadata.json
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/metadata.json
@@ -1,29 +1,28 @@
{
- "_generated": "Generated by SweetTooth, do not edit",
"description": "Adds a blur look to different parts of the GNOME Shell, including the top panel, dash and overview.\n\nYou can support my work by sponsoring me on:\n- github: https://github.com/sponsors/aunetx\n- ko-fi: https://ko-fi.com/aunetx\n\nIf you use Ubuntu, you may want to change the radius of the corner effect for Dash-to-Dock in preferences, else you may see unpleasantly mixed radii in your dock.\n\nNote: if the extension shows an error after updating, please make sure to restart your session to see if it persists. This is due to a bug in gnome shell, which I can't fix by myself.",
- "donations": {
- "github": "aunetx",
- "kofi": "aunetx"
- },
- "gettext-domain": "blur-my-shell@aunetx",
"name": "Blur my Shell",
- "original-authors": [
- "me@aunetx.dev"
- ],
- "session-modes": [
- "unlock-dialog",
- "user"
- ],
- "settings-schema": "org.gnome.shell.extensions.blur-my-shell",
"shell-version": [
- "45",
"46",
"47",
"48",
"49",
- "50"
+ "50",
+ "51"
],
"url": "https://github.com/aunetx/blur-my-shell",
"uuid": "blur-my-shell@aunetx",
- "version": 72
+ "gettext-domain": "blur-my-shell@aunetx",
+ "settings-schema": "org.gnome.shell.extensions.blur-my-shell",
+ "session-modes": [
+ "unlock-dialog",
+ "user"
+ ],
+ "original-authors": [
+ "me@aunetx.dev"
+ ],
+ "donations": {
+ "github": "aunetx",
+ "kofi": "aunetx"
+ },
+ "version": 74
}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js
index 49d2245..0884f36 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js
@@ -45,6 +45,7 @@ export const Applications = GObject.registerClass({
'opacity',
'dynamic_opacity',
'blur_on_overview',
+ 'unblur_when_fullscreen',
'enable_all',
'whitelist',
'add_window_whitelist',
@@ -91,6 +92,10 @@ export const Applications = GObject.registerClass({
Gio.SettingsBindFlags.DEFAULT
);
this.preferences.applications.settings.bind(
+ 'unblur-when-fullscreen', this._unblur_when_fullscreen, 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.applications.settings.bind(
'enable-all', this._enable_all, 'active',
Gio.SettingsBindFlags.DEFAULT
);
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js
index 0fac364..9115d61 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js
@@ -25,7 +25,7 @@ export const Other = GObject.registerClass({
'debug',
'reset'
],
-}, class Overview extends Adw.PreferencesPage {
+}, class Other extends Adw.PreferencesPage {
constructor(preferences, pipelines_manager, pipelines_page) {
super({});
@@ -83,4 +83,4 @@ export const Other = GObject.registerClass({
this._reset.connect('clicked', () => this.preferences.reset());
}
-}); \ No newline at end of file
+});
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js
index 1115710..66b3b09 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js
@@ -24,6 +24,12 @@ export const Panel = GObject.registerClass({
'override_background',
'style_panel',
'override_background_dynamically',
+ 'override_background_dynamically_mode_row',
+ 'override_background_dynamically_mode',
+ 'gradient_panel_row',
+ 'gradient_panel',
+ 'gradient_panel_mode_row',
+ 'gradient_panel_mode',
'hidetopbar_compatibility',
'dtp_blur_original_panel'
],
@@ -87,6 +93,28 @@ export const Panel = GObject.registerClass({
this._override_background_dynamically, 'active',
Gio.SettingsBindFlags.DEFAULT
);
+ this.preferences.panel.settings.bind(
+ 'override-background-dynamically-mode',
+ this._override_background_dynamically_mode, 'selected',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.panel.settings.bind(
+ 'gradient-panel', this._gradient_panel, 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.panel.settings.bind(
+ 'gradient-panel-mode', this._gradient_panel_mode, 'selected',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_changed(
+ () => this.proximity_option_changed()
+ );
+ this.preferences.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_MODE_changed(
+ () => this.proximity_option_changed()
+ );
+ this.preferences.panel.GRADIENT_PANEL_changed(
+ () => this.proximity_option_changed()
+ );
this.preferences.hidetopbar.settings.bind(
'compatibility', this._hidetopbar_compatibility, 'active',
Gio.SettingsBindFlags.DEFAULT
@@ -97,6 +125,12 @@ export const Panel = GObject.registerClass({
);
}
+ proximity_option_changed() {
+ this._override_background_dynamically_mode_row.set_visible(this.preferences.panel.OVERRIDE_BACKGROUND_DYNAMICALLY);
+ this._gradient_panel_row.set_visible(this.preferences.panel.OVERRIDE_BACKGROUND_DYNAMICALLY && this.preferences.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_MODE == 0);
+ this._gradient_panel_mode_row.set_visible(this.preferences.panel.OVERRIDE_BACKGROUND_DYNAMICALLY && this.preferences.panel.GRADIENT_PANEL && this.preferences.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_MODE == 0);
+ }
+
change_blur_mode(is_static_blur, first_run) {
this._mode_static.set_active(is_static_blur);
if (first_run)
@@ -107,5 +141,7 @@ export const Panel = GObject.registerClass({
this._brightness_row.set_visible(!is_static_blur);
this._corner_radius_row.set_visible(!is_static_blur && this.preferences.ROUNDED_BLUR_FOUND);
this._corner_radius_not_found_row.set_visible(!is_static_blur && !this.preferences.ROUNDED_BLUR_FOUND);
+
+ this.proximity_option_changed();
}
});
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js
index e0c5165..d043bad 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js
@@ -73,7 +73,10 @@ export const PipelineChooseRow = GObject.registerClass({
const pipeline_id = this._pipeline_model.get_string(i);
// if we have more pipelines than we should have: rebuild...
// that is the case when resetting the preferences for example
- if (!(pipeline_id in this.pipelines_manager)) {
+ if (
+ pipeline_id !== 'create_new'
+ && !(pipeline_id in this.pipelines_manager.pipelines)
+ ) {
this.create_pipelines_list();
return;
}
@@ -103,4 +106,4 @@ export const PipelineChooseRow = GObject.registerClass({
this._is_creating_pipelines_list = false;
this.on_selected_pipeline_changed();
}
-}); \ No newline at end of file
+});
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/popup.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/popup.js
new file mode 100644
index 0000000..5d60d8a
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/popup.js
@@ -0,0 +1,121 @@
+import Adw from 'gi://Adw';
+import GLib from 'gi://GLib';
+import GObject from 'gi://GObject';
+import Gio from 'gi://Gio';
+
+
+export const PopupBlur = GObject.registerClass({
+ GTypeName: 'PopupBlur',
+ Template: GLib.uri_resolve_relative(import.meta.url, '../ui/popup.ui', GLib.UriFlags.NONE),
+ InternalChildren: [
+ 'blur',
+ 'pipeline_choose_row',
+ 'mode_static',
+ 'mode_dynamic',
+ 'sigma_row',
+ 'sigma',
+ 'brightness_row',
+ 'brightness',
+ 'corner_radius_row',
+ 'corner_radius',
+ 'menu_corner_radius',
+ 'quick_settings_corner_radius',
+ 'notification_corner_radius',
+ 'osd_corner_radius',
+ 'dialog_corner_radius',
+ 'osk_corner_radius',
+ 'corner_radius_not_found_row',
+ 'override_background',
+ 'preserve_shell_theme',
+ 'style_popup'
+ ],
+}, class PopupBlur extends Adw.PreferencesPage {
+ constructor(preferences, pipelines_manager, pipelines_page) {
+ super({});
+
+ this.preferences = preferences;
+ this.pipelines_manager = pipelines_manager;
+ this.pipelines_page = pipelines_page;
+
+ this.preferences.popup.settings.bind(
+ 'blur', this._blur, 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+
+ this._pipeline_choose_row.initialize(
+ this.preferences.popup, this.pipelines_manager, this.pipelines_page
+ );
+
+ this.change_blur_mode(this.preferences.popup.STATIC_BLUR, true);
+
+ this._mode_static.connect('toggled',
+ () => this.preferences.popup.STATIC_BLUR = this._mode_static.active
+ );
+ this.preferences.popup.STATIC_BLUR_changed(
+ () => this.change_blur_mode(this.preferences.popup.STATIC_BLUR, false)
+ );
+
+ this.preferences.popup.settings.bind(
+ 'sigma', this._sigma, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'brightness', this._brightness, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'corner-radius', this._corner_radius, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'menu-corner-radius', this._menu_corner_radius, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'quick-settings-corner-radius', this._quick_settings_corner_radius, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'notification-corner-radius', this._notification_corner_radius, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'osd-corner-radius', this._osd_corner_radius, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'dialog-corner-radius', this._dialog_corner_radius, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'osk-corner-radius', this._osk_corner_radius, 'value',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'override-background',
+ this._override_background, 'enable-expansion',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'preserve-shell-theme',
+ this._preserve_shell_theme, 'active',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ this.preferences.popup.settings.bind(
+ 'style-popup', this._style_popup, 'selected',
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ }
+
+ change_blur_mode(is_static_blur, first_run) {
+ this._mode_static.set_active(is_static_blur);
+ if (first_run)
+ this._mode_dynamic.set_active(!is_static_blur);
+
+ this._pipeline_choose_row.set_visible(is_static_blur);
+ this._sigma_row.set_visible(!is_static_blur);
+ this._brightness_row.set_visible(!is_static_blur);
+ this._corner_radius_row.set_visible(is_static_blur || this.preferences.ROUNDED_BLUR_FOUND);
+ this._corner_radius_not_found_row.set_visible(!is_static_blur && !this.preferences.ROUNDED_BLUR_FOUND);
+ }
+});
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/prefs.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/prefs.js
index b3d7980..fbfe453 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/prefs.js
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/prefs.js
@@ -14,6 +14,7 @@ import { Panel } from './preferences/panel.js';
import { Overview } from './preferences/overview.js';
import { Dash } from './preferences/dash.js';
import { Applications } from './preferences/applications.js';
+import { PopupBlur } from './preferences/popup.js';
import { Other } from './preferences/other.js';
import './preferences/pipelines_management/pipeline_choose_row.js';
@@ -56,6 +57,7 @@ export default class BlurMyShellPreferences extends ExtensionPreferences {
window.add(new Overview(preferences, pipelines_manager, pipelines_page));
window.add(new Dash(preferences, pipelines_manager, pipelines_page));
window.add(new Applications(preferences, window, pipelines_manager, pipelines_page));
+ window.add(new PopupBlur(preferences, pipelines_manager, pipelines_page));
window.add(new Other(preferences, pipelines_manager, pipelines_page));
window.search_enabled = true;
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/gschemas.compiled b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/gschemas.compiled
deleted file mode 100644
index eb8b556..0000000
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/gschemas.compiled
+++ /dev/null
Binary files differ
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml
index 2c03cc9..588d235 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml
@@ -104,6 +104,7 @@
<child name='lockscreen' schema='org.gnome.shell.extensions.blur-my-shell.lockscreen'></child>
<child name='window-list' schema='org.gnome.shell.extensions.blur-my-shell.window-list'></child>
<child name='coverflow-alt-tab' schema='org.gnome.shell.extensions.blur-my-shell.coverflow-alt-tab'></child>
+ <child name='popup' schema='org.gnome.shell.extensions.blur-my-shell.popup'></child>
<child name='hidetopbar' schema='org.gnome.shell.extensions.blur-my-shell.hidetopbar'></child>
<child name='dash-to-panel' schema='org.gnome.shell.extensions.blur-my-shell.dash-to-panel'></child>
</schema>
@@ -276,10 +277,25 @@
<default>0</default>
<summary>Enum to select the style of the panel (0 transparent, 1 light, 2 dark, 3 contrasted)</summary>
</key>
- <!-- UNBLUR DYNAMICALLY -->
+ <!-- OVERRIDE BACKGROUND DYNAMICALLY -->
<key type="b" name="override-background-dynamically">
<default>false</default>
- <summary>Boolean, whether to disable blur from this component when a window is close to the panel</summary>
+ <summary>Boolean, whether to enable certain effect for this component when a window is close to the panel</summary>
+ </key>
+ <!-- OVERRIDE BACKGROUND DYNAMICALLY MODE -->
+ <key type="i" name="override-background-dynamically-mode">
+ <default>1</default>
+ <summary>Enum to select the override mode (0 Blur on Window Proximity, 1 Background on Window Proximity). Required "override-background-dynamically" to be enabled.</summary>
+ </key>
+ <!-- GRADIENT PANEL -->
+ <key type="b" name="gradient-panel">
+ <default>false</default>
+ <summary>Boolean, whether to enable the gradient panel effect</summary>
+ </key>
+ <!-- GRADIENT PANEL MODE -->
+ <key type="i" name="gradient-panel-mode">
+ <default>0</default>
+ <summary>Enum to select the gradient panel mode (0 Top, 1 Bottom). Required "gradient-panel" to be enabled.</summary>
</key>
</schema>
@@ -426,6 +442,11 @@
<default>false</default>
<summary>Wether or not to blur applications on the overview</summary>
</key>
+ <!-- UNBLUR WHEN FULLSCREEN -->
+ <key type="b" name="unblur-when-fullscreen">
+ <default>false</default>
+ <summary>Wether or not to unblur applications when they are fullscreen</summary>
+ </key>
<!-- ENABLE ALL -->
<key type="b" name="enable-all">
<default>false</default>
@@ -593,6 +614,86 @@
</key>
</schema>
+ <!-- POPUP -->
+ <schema id="org.gnome.shell.extensions.blur-my-shell.popup"
+ path="/org/gnome/shell/extensions/blur-my-shell/popup/">
+ <!-- BLUR -->
+ <key type="b" name="blur">
+ <default>true</default>
+ <summary>Boolean, whether to blur popup menus, notifications, switchers, and dialogs or not</summary>
+ </key>
+ <!-- STATIC BLUR -->
+ <key type="b" name="static-blur">
+ <default>false</default>
+ <summary>Boolean, whether to use a static blur on popup surfaces</summary>
+ </key>
+ <!-- PIPELINE -->
+ <key type="s" name="pipeline">
+ <default>"pipeline_default_rounded"</default>
+ <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary>
+ </key>
+ <!-- SIGMA -->
+ <key type="i" name="sigma">
+ <default>30</default>
+ <summary>Gaussian sigma to use for the blur effect</summary>
+ </key>
+ <!-- BRIGHTNESS -->
+ <key type="d" name="brightness">
+ <default>0.6</default>
+ <summary>Brightness to use for the blur effect</summary>
+ </key>
+ <!-- CORNER RADIUS -->
+ <key type="i" name="corner-radius">
+ <default>18</default>
+ <summary>Radius for the corner rounding effect</summary>
+ </key>
+ <!-- MENU CORNER RADIUS -->
+ <key type="i" name="menu-corner-radius">
+ <default>20</default>
+ <summary>Radius for popup menu corner rounding</summary>
+ </key>
+ <!-- QUICK SETTINGS CORNER RADIUS -->
+ <key type="i" name="quick-settings-corner-radius">
+ <default>36</default>
+ <summary>Radius for quick settings and calendar corner rounding</summary>
+ </key>
+ <!-- NOTIFICATION CORNER RADIUS -->
+ <key type="i" name="notification-corner-radius">
+ <default>18</default>
+ <summary>Radius for notification corner rounding</summary>
+ </key>
+ <!-- OSD CORNER RADIUS -->
+ <key type="i" name="osd-corner-radius">
+ <default>28</default>
+ <summary>Radius for OSD and switcher corner rounding</summary>
+ </key>
+ <!-- DIALOG CORNER RADIUS -->
+ <key type="i" name="dialog-corner-radius">
+ <default>18</default>
+ <summary>Radius for dialog corner rounding</summary>
+ </key>
+ <!-- ON-SCREEN KEYBOARD CORNER RADIUS -->
+ <key type="i" name="osk-corner-radius">
+ <default>0</default>
+ <summary>Radius for on-screen keyboard corner rounding</summary>
+ </key>
+ <!-- OVERRIDE BACKGROUND -->
+ <key type="b" name="override-background">
+ <default>true</default>
+ <summary>Boolean, whether to override the background or not</summary>
+ </key>
+ <!-- PRESERVE SHELL THEME -->
+ <key type="b" name="preserve-shell-theme">
+ <default>false</default>
+ <summary>Boolean, whether to preserve the shell theme's popup control styling</summary>
+ </key>
+ <!-- STYLE POPUP -->
+ <key type="i" name="style-popup">
+ <default>3</default>
+ <summary>Enum to select the style of popup surfaces (0 transparent, 1 light, 2 dark, 3 automatic)</summary>
+ </key>
+ </schema>
+
<!-- HIDETOPBAR -->
<schema id="org.gnome.shell.extensions.blur-my-shell.hidetopbar"
path="/org/gnome/shell/extensions/blur-my-shell/hidetopbar/">
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/appfolders.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/appfolders.css
new file mode 100644
index 0000000..5e8f0d4
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/appfolders.css
@@ -0,0 +1,55 @@
+/*** APPFOLDER DIALOG ***/
+
+/*
+* `.appfolder-dialogs-transparent`
+*/
+
+.appfolder-dialogs-transparent {
+ background-color: rgba(0, 0, 0, 0);
+ border: none;
+ box-shadow: none;
+}
+
+.appfolder-dialogs-transparent .folder-name-entry {
+ color: white;
+ background-color: rgba(0, 0, 0, 0);
+ border: 0;
+ box-shadow: none;
+}
+
+/*
+* `.appfolder-dialogs-light`
+*/
+
+.appfolder-dialogs-light {
+ background-color: rgba(200, 200, 200, 0.2);
+ border: none;
+ box-shadow: none;
+}
+
+.appfolder-dialogs-light .folder-name-entry {
+ color: white;
+ background-color: rgba(200, 200, 200, 0.2);
+ border: 0;
+ box-shadow: none;
+}
+
+
+/*
+* `.appfolder-dialogs-dark`
+*/
+
+.appfolder-dialogs-dark {
+ background-color: rgba(100, 100, 100, 0.35);
+ border: none;
+ box-shadow: none;
+}
+
+.appfolder-dialogs-dark .folder-name-entry {
+ color: white;
+ background-color: rgba(100, 100, 100, 0.35);
+ border: 0;
+ box-shadow: none;
+}
+
+
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/dash.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/dash.css
new file mode 100644
index 0000000..b99da78
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/dash.css
@@ -0,0 +1,26 @@
+/*** DASH-TO-DOCK ***/
+
+/*
+* `.transparent-dash`
+*/
+.transparent-dash .dash-background {
+ background: transparent !important;
+}
+
+/*
+* `.light-dash`
+*/
+.light-dash .dash-background {
+ background: rgba(255, 255, 255, 0.58) !important;
+ border: 1px solid rgba(0, 0, 0, 0.05);
+}
+
+/*
+* `.dark-dash`
+*/
+.dark-dash .dash-background {
+ background: rgba(45, 45, 50, 0.22) !important;
+ border: 1px solid rgba(255, 255, 255, 0.05);
+}
+
+
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/overview.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/overview.css
new file mode 100644
index 0000000..4958bd1
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/overview.css
@@ -0,0 +1,364 @@
+/*** OVERVIEW ***/
+
+/*
+* Add transparency to the workspace animation (between workspaces)
+*/
+.blurred-overview .workspace-animation {
+ background-color: transparent !important;
+}
+
+
+/*
+* `.overview-components-transparent`
+*/
+
+.overview-components-transparent .workspace-thumbnail {
+ border: 1px solid rgba(100, 100, 100, 0.35);
+}
+
+.overview-components-transparent .search-entry {
+ color: white;
+ background-color: rgba(0, 0, 0, 0) !important;
+ border-color: transparent;
+ box-shadow: none;
+}
+
+.overview-components-transparent .search-entry .search-entry-icon {
+ color: rgba(255, 255, 255, 0.65);
+}
+
+.overview-components-transparent .overview-tile,
+.overview-components-transparent .overview-icon,
+.overview-components-transparent .grid-search-result,
+.overview-components-transparent .list-search-result,
+.overview-components-transparent .search-provider-icon,
+/* prevents the extension from interfering with Just Perfection */
+.overview-components-transparent.just-perfection .search-section-content,
+/* remove the rectangular background from the dash */
+.overview-components-transparent #dash .overview-tile,
+.overview-components-transparent #dashtopanelScrollview .overview-tile,
+.overview-components-transparent .multimonitor-dock .overview-tile {
+ background-color: transparent !important;
+}
+
+.overview-components-transparent .workspace-thumbnail,
+.overview-components-transparent .search-section-content,
+.overview-components-transparent .overview-tile.app-folder,
+.overview-components-transparent .page-navigation-arrow,
+.overview-components-transparent .app-folder-dialog .icon-button,
+/* this shouldn't apply to Dash to Dock */
+.overview-components-transparent StBoxLayout>StWidget>#dash>.dash-background,
+.overview-components-transparent .multimonitor-dock .dash-background {
+ background-color: rgba(0, 0, 0, 0) !important;
+}
+
+.overview-components-transparent .overview-tile:hover,
+.overview-components-transparent .overview-tile:focus,
+.overview-components-transparent .overview-tile:selected,
+.overview-components-transparent .overview-tile:highlighted,
+.overview-components-transparent .grid-search-result:hover,
+.overview-components-transparent .grid-search-result:focus,
+.overview-components-transparent .grid-search-result:selected,
+.overview-components-transparent .grid-search-result:highlighted,
+.overview-components-transparent .list-search-result:hover,
+.overview-components-transparent .list-search-result:focus,
+.overview-components-transparent .list-search-result:selected,
+.overview-components-transparent .list-search-result:highlighted,
+.overview-components-transparent .search-provider-icon:hover,
+.overview-components-transparent .search-provider-icon:focus,
+.overview-components-transparent .page-navigation-arrow:hover,
+.overview-components-transparent .page-navigation-arrow:focus,
+.overview-components-transparent .app-folder-dialog .icon-button:hover,
+.overview-components-transparent .app-folder-dialog .icon-button:focus,
+.overview-components-transparent #dash .overview-tile:hover .overview-icon,
+.overview-components-transparent #dash .overview-tile:focus .overview-icon,
+.overview-components-transparent #dash .show-apps:hover .overview-icon,
+.overview-components-transparent #dash .show-apps:focus .overview-icon,
+.overview-components-transparent .multimonitor-dock .overview-tile:hover .overview-icon,
+.overview-components-transparent .multimonitor-dock .overview-tile:focus .overview-icon,
+.overview-components-transparent .multimonitor-dock .show-apps:hover .overview-icon,
+.overview-components-transparent .multimonitor-dock .show-apps:focus .overview-icon {
+ background-color: rgba(230, 230, 230, 0.08) !important;
+}
+
+.overview-components-transparent .overview-tile:active,
+.overview-components-transparent .overview-tile:focus:hover,
+.overview-components-transparent .overview-tile:drop,
+.overview-components-transparent .overview-tile:selected:hover,
+.overview-components-transparent .overview-tile:highlighted:hover,
+.overview-components-transparent .grid-search-result:active,
+.overview-components-transparent .grid-search-result:focus:hover,
+.overview-components-transparent .grid-search-result:selected:hover,
+.overview-components-transparent .grid-search-result:highlighted:hover,
+.overview-components-transparent .list-search-result:active,
+.overview-components-transparent .list-search-result:focus:hover,
+.overview-components-transparent .list-search-result:selected:hover,
+.overview-components-transparent .list-search-result:highlighted:hover,
+.overview-components-transparent .search-provider-icon:active,
+.overview-components-transparent .search-provider-icon:focus:hover,
+.overview-components-transparent .page-navigation-arrow:active,
+.overview-components-transparent .page-navigation-arrow:focus:hover,
+.overview-components-transparent .app-folder-dialog .icon-button:active,
+.overview-components-transparent .app-folder-dialog .icon-button:focus:hover,
+.overview-components-transparent #dash .overview-tile:active .overview-icon,
+.overview-components-transparent #dash .overview-tile:focus:hover .overview-icon,
+.overview-components-transparent #dash .overview-tile:drop .overview-icon,
+.overview-components-transparent #dash .show-apps:checked .overview-icon,
+.overview-components-transparent .multimonitor-dock .overview-tile:hover .overview-icon,
+.overview-components-transparent .multimonitor-dock .overview-tile:focus .overview-icon,
+.overview-components-transparent .multimonitor-dock .show-apps:hover .overview-icon,
+.overview-components-transparent .multimonitor-dock .show-apps:focus .overview-icon {
+ background-color: rgba(230, 230, 230, 0.12) !important;
+}
+
+.overview-components-transparent .overview-tile:focus:active,
+.overview-components-transparent .overview-tile:selected:active,
+.overview-components-transparent .overview-tile:highlighted:active,
+.overview-components-transparent .grid-search-result:focus:active,
+.overview-components-transparent .grid-search-result:selected:active,
+.overview-components-transparent .grid-search-result:highlighted:active,
+.overview-components-transparent .list-search-result:focus:active,
+.overview-components-transparent .list-search-result:selected:active,
+.overview-components-transparent .list-search-result:highlighted:active,
+.overview-components-transparent .search-provider-icon:focus:active,
+.overview-components-transparent .page-navigation-arrow:focus:active,
+.overview-components-transparent .app-folder-dialog .icon-button:focus:active,
+.overview-components-transparent #dash .show-apps:checked .overview-icon:hover,
+.overview-components-transparent .multimonitor-dock .show-apps:checked .overview-icon:hover {
+ background-color: rgba(230, 230, 230, 0.15) !important;
+}
+
+
+/*
+* `.overview-components-light`
+*/
+
+.overview-components-light .search-entry {
+ color: white;
+ background-color: rgba(200, 200, 200, 0.2) !important;
+ border-color: transparent;
+ box-shadow: none;
+}
+
+.overview-components-light .search-entry .search-entry-icon {
+ color: rgba(255, 255, 255, 0.65);
+}
+
+.overview-components-light .overview-tile,
+.overview-components-light .overview-icon,
+.overview-components-light .grid-search-result,
+.overview-components-light .list-search-result,
+.overview-components-light .search-provider-icon,
+/* prevents the extension from interfering with Just Perfection */
+.overview-components-light.just-perfection .search-section-content,
+/* remove the rectangular background from the dash */
+.overview-components-light #dash .overview-tile,
+.overview-components-light #dashtopanelScrollview .overview-tile,
+.overview-components-light .multimonitor-dock .overview-tile {
+ background-color: transparent !important;
+}
+
+.overview-components-light .workspace-thumbnail,
+.overview-components-light .search-section-content,
+.overview-components-light .overview-tile.app-folder,
+.overview-components-light .page-navigation-arrow,
+.overview-components-light .app-folder-dialog .icon-button,
+/* this shouldn't apply to Dash to Dock */
+.overview-components-light StBoxLayout>StWidget>#dash>.dash-background,
+.overview-components-light .multimonitor-dock .dash-background {
+ background-color: rgba(200, 200, 200, 0.2) !important;
+}
+
+.overview-components-light .overview-tile:hover,
+.overview-components-light .overview-tile:focus,
+.overview-components-light .overview-tile:selected,
+.overview-components-light .overview-tile:highlighted,
+.overview-components-light .grid-search-result:hover,
+.overview-components-light .grid-search-result:focus,
+.overview-components-light .grid-search-result:selected,
+.overview-components-light .grid-search-result:highlighted,
+.overview-components-light .list-search-result:hover,
+.overview-components-light .list-search-result:focus,
+.overview-components-light .list-search-result:selected,
+.overview-components-light .list-search-result:highlighted,
+.overview-components-light .search-provider-icon:hover,
+.overview-components-light .search-provider-icon:focus,
+.overview-components-light .page-navigation-arrow:hover,
+.overview-components-light .page-navigation-arrow:focus,
+.overview-components-light .app-folder-dialog .icon-button:hover,
+.overview-components-light .app-folder-dialog .icon-button:focus,
+.overview-components-light #dash .overview-tile:hover .overview-icon,
+.overview-components-light #dash .overview-tile:focus .overview-icon,
+.overview-components-light #dash .show-apps:hover .overview-icon,
+.overview-components-light #dash .show-apps:focus .overview-icon,
+.overview-components-light .multimonitor-dock .overview-tile:hover .overview-icon,
+.overview-components-light .multimonitor-dock .overview-tile:focus .overview-icon,
+.overview-components-light .multimonitor-dock .show-apps:hover .overview-icon,
+.overview-components-light .multimonitor-dock .show-apps:focus .overview-icon {
+ background-color: rgba(230, 230, 230, 0.2) !important;
+}
+
+.overview-components-light .overview-tile:active,
+.overview-components-light .overview-tile:focus:hover,
+.overview-components-light .overview-tile:drop,
+.overview-components-light .overview-tile:selected:hover,
+.overview-components-light .overview-tile:highlighted:hover,
+.overview-components-light .grid-search-result:active,
+.overview-components-light .grid-search-result:focus:hover,
+.overview-components-light .grid-search-result:selected:hover,
+.overview-components-light .grid-search-result:highlighted:hover,
+.overview-components-light .list-search-result:active,
+.overview-components-light .list-search-result:focus:hover,
+.overview-components-light .list-search-result:selected:hover,
+.overview-components-light .list-search-result:highlighted:hover,
+.overview-components-light .search-provider-icon:active,
+.overview-components-light .search-provider-icon:focus:hover,
+.overview-components-light .page-navigation-arrow:active,
+.overview-components-light .page-navigation-arrow:focus:hover,
+.overview-components-light .app-folder-dialog .icon-button:active,
+.overview-components-light .app-folder-dialog .icon-button:focus:hover,
+.overview-components-light #dash .overview-tile:active .overview-icon,
+.overview-components-light #dash .overview-tile:focus:hover .overview-icon,
+.overview-components-light #dash .overview-tile:drop .overview-icon,
+.overview-components-light #dash .show-apps:checked .overview-icon,
+.overview-components-light .multimonitor-dock .overview-tile:hover .overview-icon,
+.overview-components-light .multimonitor-dock .overview-tile:focus .overview-icon,
+.overview-components-light .multimonitor-dock .show-apps:hover .overview-icon,
+.overview-components-light .multimonitor-dock .show-apps:focus .overview-icon {
+ background-color: rgba(230, 230, 230, 0.25) !important;
+}
+
+.overview-components-light .overview-tile:focus:active,
+.overview-components-light .overview-tile:selected:active,
+.overview-components-light .overview-tile:highlighted:active,
+.overview-components-light .grid-search-result:focus:active,
+.overview-components-light .grid-search-result:selected:active,
+.overview-components-light .grid-search-result:highlighted:active,
+.overview-components-light .list-search-result:focus:active,
+.overview-components-light .list-search-result:selected:active,
+.overview-components-light .list-search-result:highlighted:active,
+.overview-components-light .search-provider-icon:focus:active,
+.overview-components-light .page-navigation-arrow:focus:active,
+.overview-components-light .app-folder-dialog .icon-button:focus:active,
+.overview-components-light #dash .show-apps:checked .overview-icon:hover,
+.overview-components-light .multimonitor-dock .show-apps:checked .overview-icon:hover {
+ background-color: rgba(230, 230, 230, 0.3) !important;
+}
+
+
+/*
+* `.overview-components-dark`
+*/
+
+.overview-components-dark .search-entry {
+ color: white;
+ background-color: rgba(100, 100, 100, 0.35) !important;
+ border-color: transparent;
+ box-shadow: none;
+}
+
+.overview-components-dark .search-entry .search-entry-icon {
+ color: rgba(255, 255, 255, 0.65);
+}
+
+.overview-components-dark .overview-tile,
+.overview-components-dark .overview-icon,
+.overview-components-dark .grid-search-result,
+.overview-components-dark .list-search-result,
+.overview-components-dark .search-provider-icon,
+/* prevents the extension from interfering with Just Perfection */
+.overview-components-dark.just-perfection .search-section-content,
+/* remove the rectangular background from the dash */
+.overview-components-dark #dash .overview-tile,
+.overview-components-dark #dashtopanelScrollview .overview-tile,
+.overview-components-dark .multimonitor-dock .overview-tile {
+ background-color: transparent !important;
+}
+
+.overview-components-dark .workspace-thumbnail,
+.overview-components-dark .search-section-content,
+.overview-components-dark .overview-tile.app-folder,
+.overview-components-dark .page-navigation-arrow,
+.overview-components-dark .app-folder-dialog .icon-button,
+/* this shouldn't apply to Dash to Dock */
+.overview-components-dark StBoxLayout>StWidget>#dash>.dash-background,
+.overview-components-dark .multimonitor-dock .dash-background {
+ background-color: rgba(100, 100, 100, 0.35) !important;
+}
+
+.overview-components-dark .overview-tile:hover,
+.overview-components-dark .overview-tile:focus,
+.overview-components-dark .overview-tile:selected,
+.overview-components-dark .overview-tile:highlighted,
+.overview-components-dark .grid-search-result:hover,
+.overview-components-dark .grid-search-result:focus,
+.overview-components-dark .grid-search-result:selected,
+.overview-components-dark .grid-search-result:highlighted,
+.overview-components-dark .list-search-result:hover,
+.overview-components-dark .list-search-result:focus,
+.overview-components-dark .list-search-result:selected,
+.overview-components-dark .list-search-result:highlighted,
+.overview-components-dark .search-provider-icon:hover,
+.overview-components-dark .search-provider-icon:focus,
+.overview-components-dark .page-navigation-arrow:hover,
+.overview-components-dark .page-navigation-arrow:focus,
+.overview-components-dark .app-folder-dialog .icon-button:hover,
+.overview-components-dark .app-folder-dialog .icon-button:focus,
+.overview-components-dark #dash .overview-tile:hover .overview-icon,
+.overview-components-dark #dash .overview-tile:focus .overview-icon,
+.overview-components-dark #dash .show-apps:hover .overview-icon,
+.overview-components-dark #dash .show-apps:focus .overview-icon,
+.overview-components-dark .multimonitor-dock .overview-tile:hover .overview-icon,
+.overview-components-dark .multimonitor-dock .overview-tile:focus .overview-icon,
+.overview-components-dark .multimonitor-dock .show-apps:hover .overview-icon,
+.overview-components-dark .multimonitor-dock .show-apps:focus .overview-icon {
+ background-color: rgba(120, 120, 120, 0.35) !important;
+}
+
+.overview-components-dark .overview-tile:active,
+.overview-components-dark .overview-tile:focus:hover,
+.overview-components-dark .overview-tile:drop,
+.overview-components-dark .overview-tile:selected:hover,
+.overview-components-dark .overview-tile:highlighted:hover,
+.overview-components-dark .grid-search-result:active,
+.overview-components-dark .grid-search-result:focus:hover,
+.overview-components-dark .grid-search-result:selected:hover,
+.overview-components-dark .grid-search-result:highlighted:hover,
+.overview-components-dark .list-search-result:active,
+.overview-components-dark .list-search-result:focus:hover,
+.overview-components-dark .list-search-result:selected:hover,
+.overview-components-dark .list-search-result:highlighted:hover,
+.overview-components-dark .search-provider-icon:active,
+.overview-components-dark .search-provider-icon:focus:hover,
+.overview-components-dark .page-navigation-arrow:active,
+.overview-components-dark .page-navigation-arrow:focus:hover,
+.overview-components-dark .app-folder-dialog .icon-button:active,
+.overview-components-dark .app-folder-dialog .icon-button:focus:hover,
+.overview-components-dark #dash .overview-tile:active .overview-icon,
+.overview-components-dark #dash .overview-tile:focus:hover .overview-icon,
+.overview-components-dark #dash .overview-tile:drop .overview-icon,
+.overview-components-dark #dash .show-apps:checked .overview-icon,
+.overview-components-dark .multimonitor-dock .overview-tile:hover .overview-icon,
+.overview-components-dark .multimonitor-dock .overview-tile:focus .overview-icon,
+.overview-components-dark .multimonitor-dock .show-apps:hover .overview-icon,
+.overview-components-dark .multimonitor-dock .show-apps:focus .overview-icon {
+ background-color: rgba(120, 120, 120, 0.4) !important;
+}
+
+.overview-components-dark .overview-tile:focus:active,
+.overview-components-dark .overview-tile:selected:active,
+.overview-components-dark .overview-tile:highlighted:active,
+.overview-components-dark .grid-search-result:focus:active,
+.overview-components-dark .grid-search-result:selected:active,
+.overview-components-dark .grid-search-result:highlighted:active,
+.overview-components-dark .list-search-result:focus:active,
+.overview-components-dark .list-search-result:selected:active,
+.overview-components-dark .list-search-result:highlighted:active,
+.overview-components-dark .search-provider-icon:focus:active,
+.overview-components-dark .page-navigation-arrow:focus:active,
+.overview-components-dark .app-folder-dialog .icon-button:focus:active,
+.overview-components-dark #dash .show-apps:checked .overview-icon:hover,
+.overview-components-dark .multimonitor-dock .show-apps:checked .overview-icon:hover {
+ background-color: rgba(120, 120, 120, 0.45) !important;
+}
+
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/panel-light-text.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/panel-light-text.css
new file mode 100644
index 0000000..f868dda
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/panel-light-text.css
@@ -0,0 +1,92 @@
+/*** PANEL LIGHT TEXT ***/
+
+/*
+* `.panel-light-text`, adapted from gnome-shell-light.css
+*/
+
+.panel-light-text #panel .panel-button,
+.panel-light-text #panel .panel-button.clock-display,
+.panel-light-text #panel .netSpeedLabel {
+ color: #f6f5f4;
+ box-shadow: none;
+}
+
+.panel-light-text #panel .panel-button:active,
+.panel-light-text #panel .panel-button:focus,
+.panel-light-text #panel .panel-button:checked,
+.panel-light-text #panel .panel-button.clock-display:active .clock,
+.panel-light-text #panel .panel-button.clock-display:focus .clock,
+.panel-light-text #panel .panel-button.clock-display:checked .clock {
+ box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.25);
+}
+
+.panel-light-text #panel .panel-button:active:hover,
+.panel-light-text #panel .panel-button:focus:hover,
+.panel-light-text #panel .panel-button:checked:hover,
+.panel-light-text #panel .panel-button.clock-display:active:hover,
+.panel-light-text #panel .panel-button.clock-display:focus:hover,
+.panel-light-text #panel .panel-button.clock-display:checked:hover,
+.panel-light-text #panel .panel-button.clock-display:active .clock:hover,
+.panel-light-text #panel .panel-button.clock-display:focus .clock:hover,
+.panel-light-text #panel .panel-button.clock-display:checked .clock:hover {
+ box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.35);
+}
+
+.panel-light-text #panel .panel-button:hover,
+.panel-light-text #panel .panel-button.clock-display:hover,
+.panel-light-text #panel .panel-button.clock-display:hover .clock {
+ box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.2);
+}
+
+.panel-light-text #panel .panel-button#panelActivities .workspace-dot {
+ background-color: #f6f5f4;
+}
+
+.panel-light-text #panel .panel-button.clock-display:active,
+.panel-light-text #panel .panel-button.clock-display:focus,
+.panel-light-text #panel .panel-button.clock-display:checked,
+.panel-light-text #panel .panel-button.clock-display:hover {
+ box-shadow: none !important;
+}
+
+.panel-light-text #panel .panel-button.screen-recording-indicator {
+ color: #f6f5f4;
+ box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.8);
+}
+
+.panel-light-text #panel .panel-button.screen-recording-indicator:active,
+.panel-light-text #panel .panel-button.screen-recording-indicator:focus,
+.panel-light-text #panel .panel-button.screen-recording-indicator:checked {
+ box-shadow: inset 0 0 0 100px #c01c28;
+}
+
+.panel-light-text #panel .panel-button.screen-recording-indicator:active:hover,
+.panel-light-text #panel .panel-button.screen-recording-indicator:focus:hover,
+.panel-light-text #panel .panel-button.screen-recording-indicator:checked:hover {
+ box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.95);
+}
+
+.panel-light-text #panel .panel-button.screen-recording-indicator:hover {
+ box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.9);
+}
+
+.panel-light-text #panel .panel-button.screen-sharing-indicator {
+ color: #282828;
+ box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.8);
+}
+
+.panel-light-text #panel .panel-button.screen-sharing-indicator:active,
+.panel-light-text #panel .panel-button.screen-sharing-indicator:focus,
+.panel-light-text #panel .panel-button.screen-sharing-indicator:checked {
+ box-shadow: inset 0 0 0 100px #ff7800;
+}
+
+.panel-light-text #panel .panel-button.screen-sharing-indicator:active:hover,
+.panel-light-text #panel .panel-button.screen-sharing-indicator:focus:hover,
+.panel-light-text #panel .panel-button.screen-sharing-indicator:checked:hover {
+ box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.95);
+}
+
+.panel-light-text #panel .panel-button.screen-sharing-indicator:hover {
+ box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.9);
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/panel.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/panel.css
new file mode 100644
index 0000000..0273cb5
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/panel.css
@@ -0,0 +1,97 @@
+/*** PANEL ***/
+
+/*
+* `.transparent-panel`
+*/
+
+#panel.transparent-panel {
+ background: transparent !important;
+ transition-duration: 500ms;
+}
+
+/*
+* `.dark-panel`
+*/
+#panel.dark-panel {
+ background-color: rgba(100, 100, 100, 0.35) !important;
+ box-shadow: none !important;
+ transition-duration: 500ms;
+}
+
+/*
+* `.light-panel`
+*/
+#panel.light-panel {
+ background-color: rgba(200, 200, 200, 0.2) !important;
+ box-shadow: none !important;
+ transition-duration: 500ms;
+}
+
+/*
+* `.contrasted-panel`
+*/
+#panel.contrasted-panel {
+ background-color: transparent !important;
+ box-shadow: none !important;
+ transition-duration: 500ms;
+}
+
+/*
+* `.gradient-panel`
+*/
+/* Internal use */
+
+#panel.gradient-panel {
+ background-color: transparent !important;
+ background-gradient-direction: vertical !important;
+ background-gradient-start: rgba(0,0,0,0.5) !important;
+ background-gradient-end: rgba(0,0,0,0) !important;
+ box-shadow: none !important;
+ transition-duration: 500ms;
+}
+
+/*
+* `.gradient-panel-reverse`
+*/
+/* Internal use */
+
+#panel.gradient-panel-reverse {
+ background-color: transparent !important;
+ background-gradient-direction: vertical !important;
+ background-gradient-start: rgba(0,0,0,0) !important;
+ background-gradient-end: rgba(0,0,0,0.5) !important;
+ box-shadow: none !important;
+ transition-duration: 500ms;
+}
+
+.contrasted-panel .panel-button,
+.contrasted-panel .clock,
+.contrasted-panel .clock-display StIcon {
+ color: #ffffff;
+ border-radius: 14px;
+ border: 3px solid transparent;
+ background-color: rgba(0, 0, 0, 0.8);
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.03);
+}
+
+
+.contrasted-panel .clock-display StIcon {
+ padding: 8px;
+ margin: 0;
+}
+
+.contrasted-panel .panel-button:hover,
+.contrasted-panel .panel-button:hover .clock {
+ color: #ffffff;
+ background-color: rgba(0, 0, 0, 0.8);
+}
+
+.contrasted-panel .clock-display {
+ background-color: transparent !important;
+ box-shadow: none !important;
+ border: none !important;
+}
+
+.contrasted-panel .clock {
+ margin: 0 !important;
+} \ No newline at end of file
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/base.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/base.css
new file mode 100644
index 0000000..a313eed
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/base.css
@@ -0,0 +1,729 @@
+/*** POPUP ***/
+
+.bms-popup-blurred-widget {
+ background: rgba(0, 0, 0, 0.01);
+}
+
+.bms-popup-background-transparent .popup-menu-content,
+.bms-popup-background-transparent .popup-sub-menu,
+.bms-popup-background-transparent .candidate-popup-content,
+.bms-popup-background-transparent .quick-settings,
+.bms-popup-background-transparent .quick-toggle-menu,
+.bms-popup-background-transparent .osd-window,
+.bms-popup-background-transparent .resize-popup,
+.bms-popup-background-transparent .switcher-list,
+.bms-popup-background-transparent .workspace-switcher,
+.bms-popup-background-transparent .modal-dialog,
+.bms-popup-background-transparent .run-dialog,
+.bms-popup-background-transparent .screenshot-ui-panel,
+.bms-popup-surface-transparent .popup-menu-content,
+.bms-popup-surface-transparent .popup-sub-menu,
+.bms-popup-surface-transparent .candidate-popup-content,
+.bms-popup-surface-transparent .quick-settings,
+.bms-popup-surface-transparent .quick-toggle-menu,
+.bms-popup-surface-transparent .osd-window,
+.bms-popup-surface-transparent .resize-popup,
+.bms-popup-surface-transparent .switcher-list,
+.bms-popup-surface-transparent .workspace-switcher,
+.bms-popup-surface-transparent .modal-dialog,
+.bms-popup-surface-transparent .run-dialog,
+.bms-popup-surface-transparent .screenshot-ui-panel {
+ background: transparent !important;
+ border-color: transparent;
+ box-shadow: none;
+}
+
+.bms-popup-background-light .popup-menu-content,
+.bms-popup-background-light .popup-sub-menu,
+.bms-popup-background-light .candidate-popup-content,
+.bms-popup-background-light .quick-settings,
+.bms-popup-background-light .quick-toggle-menu,
+.bms-popup-background-light .message,
+.bms-popup-background-light .osd-window,
+.bms-popup-background-light .resize-popup,
+.bms-popup-background-light .switcher-list,
+.bms-popup-background-light .workspace-switcher,
+.bms-popup-background-light .modal-dialog,
+.bms-popup-background-light .run-dialog,
+.bms-popup-background-light .screenshot-ui-panel {
+ color: #222226;
+}
+
+.bms-popup-background-light .popup-menu-content,
+.bms-popup-background-light .popup-sub-menu,
+.bms-popup-background-light .candidate-popup-content,
+.bms-popup-background-light .quick-settings,
+.bms-popup-background-light .quick-toggle-menu,
+.bms-popup-background-light .message,
+.bms-popup-background-light .osd-window,
+.bms-popup-background-light .resize-popup,
+.bms-popup-background-light .switcher-list,
+.bms-popup-background-light .workspace-switcher,
+.bms-popup-background-light .modal-dialog,
+.bms-popup-background-light .run-dialog,
+.bms-popup-background-light .screenshot-ui-panel,
+.bms-popup-surface-light .popup-menu-content,
+.bms-popup-surface-light .popup-sub-menu,
+.bms-popup-surface-light .candidate-popup-content,
+.bms-popup-surface-light .quick-settings,
+.bms-popup-surface-light .quick-toggle-menu,
+.bms-popup-surface-light .message,
+.bms-popup-surface-light .osd-window,
+.bms-popup-surface-light .resize-popup,
+.bms-popup-surface-light .switcher-list,
+.bms-popup-surface-light .workspace-switcher,
+.bms-popup-surface-light .modal-dialog,
+.bms-popup-surface-light .run-dialog,
+.bms-popup-surface-light .screenshot-ui-panel {
+ background: rgba(255, 255, 255, 0.58) !important;
+ border-color: rgba(0, 0, 0, 0.05);
+ box-shadow: 0 8px 22px rgba(0, 0, 0, 0.08);
+}
+
+.bms-popup-background-light .modal-dialog,
+.bms-popup-background-light .run-dialog,
+.bms-popup-surface-light .modal-dialog,
+.bms-popup-surface-light .run-dialog,
+.bms-popup-background-dark .modal-dialog,
+.bms-popup-background-dark .run-dialog,
+.bms-popup-surface-dark .modal-dialog,
+.bms-popup-surface-dark .run-dialog {
+ border: 1px solid rgba(0, 0, 0, 0.05);
+}
+
+.bms-popup-background-light .message:hover,
+.bms-popup-surface-light .message:hover {
+ background: rgba(255, 255, 255, 0.4) !important;
+}
+
+.bms-popup-background-light .message:active,
+.bms-popup-surface-light .message:active,
+.bms-popup-background-light .message:focus,
+.bms-popup-surface-light .message:focus {
+ background: rgba(255, 255, 255, 0.7) !important;
+}
+
+.bms-popup-background-dark .popup-menu-content,
+.bms-popup-background-dark .popup-sub-menu,
+.bms-popup-background-dark .candidate-popup-content,
+.bms-popup-background-dark .quick-settings,
+.bms-popup-background-dark .quick-toggle-menu,
+.bms-popup-background-dark .message,
+.bms-popup-background-dark .osd-window,
+.bms-popup-background-dark .resize-popup,
+.bms-popup-background-dark .switcher-list,
+.bms-popup-background-dark .workspace-switcher,
+.bms-popup-background-dark .modal-dialog,
+.bms-popup-background-dark .run-dialog,
+.bms-popup-background-dark .screenshot-ui-panel,
+.bms-popup-background-transparent .message {
+ color: #ffffff;
+}
+
+.bms-popup-background-dark .popup-menu-content,
+.bms-popup-background-dark .popup-sub-menu,
+.bms-popup-background-dark .candidate-popup-content,
+.bms-popup-background-dark .quick-settings,
+.bms-popup-background-dark .quick-toggle-menu,
+.bms-popup-background-dark .osd-window,
+.bms-popup-background-dark .resize-popup,
+.bms-popup-background-dark .switcher-list,
+.bms-popup-background-dark .workspace-switcher,
+.bms-popup-background-dark .modal-dialog,
+.bms-popup-background-dark .run-dialog,
+.bms-popup-background-dark .screenshot-ui-panel,
+.bms-popup-surface-dark .screenshot-ui-panel,
+.bms-popup-surface-dark .popup-menu-content,
+.bms-popup-surface-dark .popup-sub-menu,
+.bms-popup-surface-dark .candidate-popup-content,
+.bms-popup-surface-dark .quick-settings,
+.bms-popup-surface-dark .quick-toggle-menu,
+.bms-popup-surface-dark .osd-window,
+.bms-popup-surface-dark .resize-popup,
+.bms-popup-surface-dark .switcher-list,
+.bms-popup-surface-dark .workspace-switcher,
+.bms-popup-surface-dark .modal-dialog,
+.bms-popup-surface-dark .run-dialog {
+ background: rgba(45, 45, 50, 0.22) !important;
+ border-color: rgba(255, 255, 255, 0.05);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
+}
+
+.bms-popup-background-dark .message,
+.bms-popup-background-transparent .message,
+.bms-popup-surface-dark .message,
+.bms-popup-surface-transparent .message {
+ background: rgba(255, 255, 255, 0.07) !important;
+ border-color: rgba(255, 255, 255, 0.05);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
+}
+
+.bms-popup-background-dark .message:hover,
+.bms-popup-background-transparent .message:hover,
+.bms-popup-surface-dark .message:hover,
+.bms-popup-surface-transparent .message:hover {
+ background: rgba(255, 255, 255, 0.12) !important;
+}
+
+.bms-popup-background-dark .message:focus,
+.bms-popup-background-transparent .message:focus,
+.bms-popup-surface-dark .message:focus,
+.bms-popup-surface-transparent .message:focus,
+.bms-popup-background-dark .message:active,
+.bms-popup-background-transparent .message:active,
+.bms-popup-surface-dark .message:active,
+.bms-popup-surface-transparent .message:active {
+ background: rgba(255, 255, 255, 0.15) !important;
+}
+
+.bms-popup-background-transparent .message,
+.bms-popup-background-light .message,
+.bms-popup-background-dark .message,
+.bms-popup-surface-transparent .message,
+.bms-popup-surface-light .message,
+.bms-popup-surface-dark .message {
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent StScrollBar StBin#trough,
+.bms-popup-background-light StScrollBar StBin#trough,
+.bms-popup-background-dark StScrollBar StBin#trough {
+ background-color: transparent;
+}
+
+.bms-popup-background-transparent StScrollBar > .vhandle,
+.bms-popup-background-transparent StScrollBar > .hhandle,
+.bms-popup-background-dark StScrollBar > .vhandle,
+.bms-popup-background-dark StScrollBar > .hhandle {
+ background-color: rgba(255, 255, 255, 0.28);
+ border-color: transparent;
+}
+
+.bms-popup-background-transparent StScrollBar > .vhandle:hover,
+.bms-popup-background-transparent StScrollBar > .hhandle:hover,
+.bms-popup-background-dark StScrollBar > .vhandle:hover,
+.bms-popup-background-dark StScrollBar > .hhandle:hover {
+ background-color: rgba(255, 255, 255, 0.38);
+}
+
+.bms-popup-background-transparent StScrollBar > .vhandle:active,
+.bms-popup-background-transparent StScrollBar > .hhandle:active,
+.bms-popup-background-dark StScrollBar > .vhandle:active,
+.bms-popup-background-dark StScrollBar > .hhandle:active {
+ background-color: rgba(255, 255, 255, 0.46);
+}
+
+.bms-popup-background-light StScrollBar > .vhandle,
+.bms-popup-background-light StScrollBar > .hhandle {
+ background-color: rgba(34, 34, 38, 0.24);
+ border-color: transparent;
+}
+
+.bms-popup-background-light StScrollBar > .vhandle:hover,
+.bms-popup-background-light StScrollBar > .hhandle:hover {
+ background-color: rgba(34, 34, 38, 0.34);
+}
+
+.bms-popup-background-light StScrollBar > .vhandle:active,
+.bms-popup-background-light StScrollBar > .hhandle:active {
+ background-color: rgba(34, 34, 38, 0.42);
+}
+
+.bms-popup-background-transparent .osd-window,
+.bms-popup-background-light .osd-window,
+.bms-popup-background-dark .osd-window,
+.bms-popup-background-transparent .resize-popup,
+.bms-popup-background-light .resize-popup,
+.bms-popup-background-dark .resize-popup,
+.bms-popup-background-transparent .workspace-switcher,
+.bms-popup-background-light .workspace-switcher,
+.bms-popup-background-dark .workspace-switcher,
+.bms-popup-surface-transparent .osd-window,
+.bms-popup-surface-light .osd-window,
+.bms-popup-surface-dark .osd-window,
+.bms-popup-surface-transparent .resize-popup,
+.bms-popup-surface-light .resize-popup,
+.bms-popup-surface-dark .resize-popup,
+.bms-popup-surface-transparent .workspace-switcher,
+.bms-popup-surface-light .workspace-switcher,
+.bms-popup-surface-dark .workspace-switcher {
+ border-radius: 18px;
+}
+
+.bms-popup-background-light .osd-window .level {
+ -barlevel-background-color: rgba(0, 0, 0, 0.12);
+ -barlevel-active-background-color: #222226;
+ -barlevel-overdrive-color: #c01c28;
+}
+
+.bms-popup-background-dark .osd-window .level {
+ -barlevel-background-color: rgba(255, 255, 255, 0.14);
+ -barlevel-active-background-color: #ffffff;
+ -barlevel-overdrive-color: #f66151;
+}
+
+.bms-popup-background-light .switcher-list .item-box:focus,
+.bms-popup-background-light .switcher-list .item-box:selected,
+.bms-popup-surface-light .switcher-list .item-box:focus,
+.bms-popup-surface-light .switcher-list .item-box:selected {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-dark .switcher-list .item-box:focus,
+.bms-popup-background-dark .switcher-list .item-box:selected,
+.bms-popup-surface-dark .switcher-list .item-box:focus,
+.bms-popup-surface-dark .switcher-list .item-box:selected {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-transparent .switcher-list .item-box:focus,
+.bms-popup-background-transparent .switcher-list .item-box:selected,
+.bms-popup-surface-transparent .switcher-list .item-box:focus,
+.bms-popup-surface-transparent .switcher-list .item-box:selected {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-transparent .popup-sub-menu,
+.bms-popup-background-light .popup-sub-menu,
+.bms-popup-background-dark .popup-sub-menu,
+.bms-popup-surface-transparent .popup-sub-menu,
+.bms-popup-surface-light .popup-sub-menu,
+.bms-popup-surface-dark .popup-sub-menu {
+ background: transparent !important;
+ border-color: transparent;
+ border-radius: 0 0 13px 13px;
+ box-shadow: none;
+}
+
+.bms-popup-background-dark .popup-sub-menu > StBoxLayout,
+.bms-popup-surface-dark .popup-sub-menu > StBoxLayout {
+ background-color: rgba(58, 58, 64, 0.36) !important;
+ border-radius: 0 0 13px 13px;
+}
+
+.bms-popup-background-light .popup-sub-menu > StBoxLayout,
+.bms-popup-surface-light .popup-sub-menu > StBoxLayout {
+ background-color: rgba(255, 255, 255, 0.58) !important;
+ border-radius: 0 0 13px 13px;
+}
+
+.bms-popup-background-transparent .popup-sub-menu .popup-menu-item,
+.bms-popup-background-light .popup-sub-menu .popup-menu-item,
+.bms-popup-background-dark .popup-sub-menu .popup-menu-item {
+ background-color: transparent !important;
+ border-color: transparent;
+ border-radius: 0;
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .popup-sub-menu .popup-menu-item:insensitive,
+.bms-popup-background-light .popup-sub-menu .popup-menu-item:insensitive,
+.bms-popup-background-dark .popup-sub-menu .popup-menu-item:insensitive {
+ background-color: transparent !important;
+}
+
+.bms-popup-background-transparent .screenshot-ui-type-button,
+.bms-popup-background-light .screenshot-ui-type-button,
+.bms-popup-background-dark .screenshot-ui-type-button,
+.bms-popup-background-transparent .screenshot-ui-type-button:insensitive,
+.bms-popup-background-light .screenshot-ui-type-button:insensitive,
+.bms-popup-background-dark .screenshot-ui-type-button:insensitive {
+ background-color: transparent !important;
+}
+
+.bms-popup-background-transparent .screenshot-ui-type-button:checked,
+.bms-popup-background-transparent .screenshot-ui-type-button:focus,
+.bms-popup-background-dark .screenshot-ui-type-button:checked,
+.bms-popup-background-dark .screenshot-ui-type-button:focus {
+ background-color: rgba(255, 255, 255, 0.13) !important
+}
+
+.bms-popup-background-light .screenshot-ui-type-button,
+.bms-popup-background-light .screenshot-ui-show-pointer-button,
+.bms-popup-background-light .screenshot-ui-shot-cast-button {
+ color: #1a1a1e !important;
+}
+
+.bms-popup-background-light .screenshot-ui-type-button:insensitive,
+.bms-popup-background-light .screenshot-ui-show-pointer-button:insensitive,
+.bms-popup-background-light .screenshot-ui-shot-cast-button:insensitive {
+ color: rgba(26, 26, 30, 0.5) !important;
+}
+
+.bms-popup-background-transparent .screenshot-ui-type-button:hover,
+.bms-popup-background-dark .screenshot-ui-type-button:hover {
+ background-color: rgba(255, 255, 255, 0.20) !important;
+}
+
+.bms-popup-background-transparent .screenshot-ui-type-button:active,
+.bms-popup-background-transparent .screenshot-ui-type-button:outlined,
+.bms-popup-background-dark .screenshot-ui-type-button:active,
+.bms-popup-background-dark .screenshot-ui-type-button:outlined {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-type-button:hover {
+ background-color: rgba(0, 0, 0, 0.18) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-type-button:checked,
+.bms-popup-background-light .screenshot-ui-type-button:focus {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-type-button:active,
+.bms-popup-background-light .screenshot-ui-type-button:outlined {
+ background-color: rgba(0, 0, 0, 0.16) !important;
+}
+
+.bms-popup-background-transparent .screenshot-ui-show-pointer-button,
+.bms-popup-background-light .screenshot-ui-show-pointer-button,
+.bms-popup-background-dark .screenshot-ui-show-pointer-button,
+.bms-popup-background-transparent .screenshot-ui-show-pointer-button:insensitive,
+.bms-popup-background-light .screenshot-ui-show-pointer-button:insensitive,
+.bms-popup-background-dark .screenshot-ui-show-pointer-button:insensitive {
+ background-color: transparent !important;
+}
+
+.bms-popup-background-light .screenshot-ui-show-pointer-button:hover {
+ background-color: rgba(0, 0, 0, 0.18) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-show-pointer-button:checked,
+.bms-popup-background-light .screenshot-ui-show-pointer-button:focus {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-transparent .screenshot-ui-show-pointer-button:checked,
+.bms-popup-background-transparent .screenshot-ui-show-pointer-button:focus,
+.bms-popup-background-dark .screenshot-ui-show-pointer-button:checked,
+.bms-popup-background-dark .screenshot-ui-show-pointer-button:focus {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-transparent .screenshot-ui-show-pointer-button:hover,
+.bms-popup-background-dark .screenshot-ui-show-pointer-button:hover {
+ background-color: rgba(255, 255, 255, 0.20) !important;
+}
+
+.bms-popup-background-transparent .screenshot-ui-show-pointer-button:active,
+.bms-popup-background-transparent .screenshot-ui-show-pointer-button:outlined,
+.bms-popup-background-dark .screenshot-ui-show-pointer-button:active,
+.bms-popup-background-dark .screenshot-ui-show-pointer-button:outlined {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-show-pointer-button:active,
+.bms-popup-background-light .screenshot-ui-show-pointer-button:outlined {
+ background-color: rgba(0, 0, 0, 0.16) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-capture-button {
+ border: 4px #1a1a1e !important;
+}
+
+.bms-popup-background-light .screenshot-ui-capture-button .screenshot-ui-capture-button-circle {
+ background-color: #1a1a1e !important;
+}
+
+.bms-popup-background-light .screenshot-ui-capture-button:hover .screenshot-ui-capture-button-circle,
+.bms-popup-background-light .screenshot-ui-capture-button:focus .screenshot-ui-capture-button-circle {
+ background-color: #3a3a3e !important;
+}
+
+.bms-popup-background-light .screenshot-ui-capture-button:active .screenshot-ui-capture-button-circle {
+ background-color: #5a5a5e !important;
+}
+
+.bms-popup-background-light .screenshot-ui-capture-button:cast .screenshot-ui-capture-button-circle {
+ background-color: #c01c28 !important;
+}
+
+.bms-popup-background-light .screenshot-ui-capture-button:cast:hover .screenshot-ui-capture-button-circle,
+.bms-popup-background-light .screenshot-ui-capture-button:cast:focus .screenshot-ui-capture-button-circle {
+ background-color: #d61f2d !important;
+}
+
+.bms-popup-background-light .screenshot-ui-capture-button:cast:active .screenshot-ui-capture-button-circle {
+ background-color: #a11722 !important;
+}
+
+.bms-popup-background-light .screenshot-ui-shot-cast-container {
+ background-color: rgba(0, 0, 0, 0.1) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-shot-cast-button:hover,
+.bms-popup-background-light .screenshot-ui-shot-cast-button:focus {
+ background-color: rgba(0, 0, 0, 0.18) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-shot-cast-button:active {
+ background-color: rgba(0, 0, 0, 0.28) !important;
+}
+
+.bms-popup-background-light .screenshot-ui-shot-cast-button:checked {
+ background-color: #1a1a1e !important;
+ color: #ffffff !important;
+}
+
+.bms-popup-background-light .screenshot-ui-shot-cast-button:insensitive {
+ color: rgba(26, 26, 30, 0.5) !important;
+}
+
+.bms-popup-background-transparent .popup-sub-menu .popup-menu-section,
+.bms-popup-background-light .popup-sub-menu .popup-menu-section,
+.bms-popup-background-dark .popup-sub-menu .popup-menu-section {
+ border-radius: 0 0 12px 12px;
+}
+
+.bms-popup-background-transparent .popup-sub-menu .popup-menu-item:last-child,
+.bms-popup-background-transparent .popup-sub-menu .popup-menu-section .popup-menu-item:last-child,
+.bms-popup-background-transparent .popup-sub-menu .popup-menu-section:last-child .popup-menu-item:last-child,
+.bms-popup-background-light .popup-sub-menu .popup-menu-item:last-child,
+.bms-popup-background-light .popup-sub-menu .popup-menu-section .popup-menu-item:last-child,
+.bms-popup-background-light .popup-sub-menu .popup-menu-section:last-child .popup-menu-item:last-child,
+.bms-popup-background-dark .popup-sub-menu .popup-menu-item:last-child,
+.bms-popup-background-dark .popup-sub-menu .popup-menu-section .popup-menu-item:last-child,
+.bms-popup-background-dark .popup-sub-menu .popup-menu-section:last-child .popup-menu-item:last-child {
+ border-radius: 0 0 12px 12px;
+}
+
+.bms-popup-background-dark .bms-keyboard-surface,
+.bms-popup-surface-dark .bms-keyboard-surface,
+.bms-popup-background-transparent .bms-keyboard-surface,
+.bms-popup-surface-transparent .bms-keyboard-surface {
+ background: rgba(45, 45, 50, 0.22) !important;
+ border: 1px solid rgba(255, 255, 255, 0.05);;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
+}
+
+.bms-popup-background-light .bms-keyboard-surface,
+.bms-popup-surface-light .bms-keyboard-surface {
+ background: rgba(255, 255, 255, 0.58) !important;
+ border: 1px solid rgba(0, 0, 0, 0.05);
+ box-shadow: 0 8px 22px rgba(0, 0, 0, 0.08);
+}
+
+.bms-popup-background-dark .keyboard-subkeys,
+.bms-popup-background-transparent .keyboard-subkeys {
+ -arrow-background-color: rgba(35, 35, 35, 0.98);
+ -arrow-border-color: rgba(255, 255, 255, 0.12);
+}
+
+/* Base Keys */
+.bms-popup-background-dark .keyboard-key,
+.bms-popup-background-transparent .keyboard-key,
+.bms-popup-background-dark .keyboard-subkeys .keyboard-key,
+.bms-popup-background-transparent .keyboard-subkeys .keyboard-key {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.08);
+ border-color: rgba(255, 255, 255, 0.06);
+ box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.25);
+}
+
+/* Interactive States */
+.bms-popup-background-dark .keyboard-key:hover,
+.bms-popup-background-transparent .keyboard-key:hover,
+.bms-popup-background-dark .keyboard-subkeys .keyboard-key:hover,
+.bms-popup-background-transparent .keyboard-subkeys .keyboard-key:hover,
+.bms-popup-background-dark .keyboard-key:focus:hover,
+.bms-popup-background-transparent .keyboard-key:focus:hover,
+.bms-popup-background-dark .keyboard-subkeys .keyboard-key:focus:hover,
+.bms-popup-background-transparent .keyboard-subkeys .keyboard-key:focus:hover {
+ background-color: rgba(255, 255, 255, 0.20) !important;
+ color: #ffffff;
+}
+
+.bms-popup-background-dark .keyboard-key:active,
+.bms-popup-background-transparent .keyboard-key:active,
+.bms-popup-background-dark .keyboard-subkeys .keyboard-key:active,
+.bms-popup-background-transparent .keyboard-subkeys .keyboard-key:active,
+.bms-popup-background-dark .keyboard-key:focus:active,
+.bms-popup-background-transparent .keyboard-key:focus:active,
+.bms-popup-background-dark .keyboard-subkeys .keyboard-key:focus:active,
+.bms-popup-background-transparent .keyboard-subkeys .keyboard-key:focus:active {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+ color: #ffffff;
+}
+
+.bms-popup-background-dark .keyboard-key:checked,
+.bms-popup-background-transparent .keyboard-key:checked,
+.bms-popup-background-dark .keyboard-subkeys .keyboard-key:checked,
+.bms-popup-background-transparent .keyboard-subkeys .keyboard-key:checked {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+ box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.6);
+ color: #ffffff;
+}
+
+.bms-popup-background-dark .keyboard-key:focus,
+.bms-popup-background-transparent .keyboard-key:focus,
+.bms-popup-background-dark .keyboard-subkeys .keyboard-key:focus,
+.bms-popup-background-transparent .keyboard-subkeys .keyboard-key:focus {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+ box-shadow: none;
+ color: #ffffff;
+}
+
+.bms-popup-background-dark .keyboard-key:grayed,
+.bms-popup-background-transparent .keyboard-key:grayed {
+ background-color: rgba(255, 255, 255, 0.03);
+ color: rgba(255, 255, 255, 0.35);
+ border-color: rgba(0, 0, 0, 0.4);
+}
+
+/* Modifier & Function Keys */
+.bms-popup-background-dark .keyboard-key.default-key,
+.bms-popup-background-transparent .keyboard-key.default-key {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.05);
+}
+
+.bms-popup-background-dark .keyboard-key.default-key:hover,
+.bms-popup-background-transparent .keyboard-key.default-key:hover {
+ background-color: rgba(255, 255, 255, 0.20);
+}
+
+.bms-popup-background-dark .keyboard-key.default-key:active,
+.bms-popup-background-transparent .keyboard-key.default-key:active {
+ background-color: rgba(255, 255, 255, 0.18);
+}
+
+.bms-popup-background-dark .keyboard-key.default-key:checked,
+.bms-popup-background-transparent .keyboard-key.default-key:checked {
+ background-color: rgba(255, 255, 255, 0.13);
+}
+
+.bms-popup-background-dark .keyboard-key.default-key:latched,
+.bms-popup-background-transparent .keyboard-key.default-key:latched {
+ border-color: #4b92e7;
+ background-color: #3584e4;
+ color: #ffffff;
+}
+
+/* Enter Key */
+.bms-popup-background-dark .keyboard-key.enter-key,
+.bms-popup-background-transparent .keyboard-key.enter-key {
+ color: #ffffff;
+ background-color: #428ce6;
+}
+
+.bms-popup-background-dark .keyboard-key.enter-key:hover,
+.bms-popup-background-transparent .keyboard-key.enter-key:hover {
+ background-color: #5497e8;
+}
+
+.bms-popup-background-dark .keyboard-key.enter-key:active,
+.bms-popup-background-transparent .keyboard-key.enter-key:active {
+ background-color: #629fea;
+}
+
+/* Shift Key Uppercase */
+.bms-popup-background-dark .keyboard-key.shift-key-uppercase,
+.bms-popup-background-transparent .keyboard-key.shift-key-uppercase {
+ background-color: rgba(255, 255, 255, 0.35);
+ color: #1e1e1e;
+}
+
+.bms-popup-background-dark .keyboard-key.shift-key-uppercase:hover,
+.bms-popup-background-transparent .keyboard-key.shift-key-uppercase:hover {
+ background-color: rgba(255, 255, 255, 0.45);
+}
+
+.bms-popup-background-light .keyboard-subkeys {
+ -arrow-background-color: rgba(240, 240, 240, 0.98);
+ -arrow-border-color: rgba(0, 0, 0, 0.1);
+}
+
+/* Base Keys */
+.bms-popup-background-light .keyboard-key,
+.bms-popup-background-light .keyboard-subkeys .keyboard-key {
+ color: #1a1a1a;
+ background-color: rgba(0, 0, 0, 0.07);
+ border-color: rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.08);
+}
+
+/* Interactive States */
+.bms-popup-background-light .keyboard-key:hover,
+.bms-popup-background-light .keyboard-subkeys .keyboard-key:hover,
+.bms-popup-background-light .keyboard-key:focus:hover,
+.bms-popup-background-light .keyboard-subkeys .keyboard-key:focus:hover {
+ background-color: rgba(0, 0, 0, 0.18) !important;
+ color: #000000;
+}
+
+.bms-popup-background-light .keyboard-key:active,
+.bms-popup-background-light .keyboard-subkeys .keyboard-key:active,
+.bms-popup-background-light .keyboard-key:focus:active,
+.bms-popup-background-light .keyboard-subkeys .keyboard-key:focus:active {
+ background-color: rgba(0, 0, 0, 0.16) !important;
+ color: #000000;
+}
+
+.bms-popup-background-light .keyboard-key:checked,
+.bms-popup-background-light .keyboard-subkeys .keyboard-key:checked {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+ box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.6);
+ color: #000000;
+}
+
+.bms-popup-background-light .keyboard-key:focus,
+.bms-popup-background-light .keyboard-subkeys .keyboard-key:focus {
+ background-color: rgba(0, 0, 0, 0.07) !important;
+ box-shadow: none;
+ color: #1a1a1a;
+}
+
+.bms-popup-background-light .keyboard-key:grayed {
+ background-color: rgba(0, 0, 0, 0.03);
+ color: rgba(0, 0, 0, 0.4);
+ border-color: transparent;
+}
+
+/* Modifier & Function Keys */
+.bms-popup-background-light .keyboard-key.default-key {
+ color: #2c2c2c;
+ background-color: rgba(0, 0, 0, 0.11);
+}
+
+.bms-popup-background-light .keyboard-key.default-key:hover {
+ background-color: rgba(0, 0, 0, 0.18);
+}
+
+.bms-popup-background-light .keyboard-key.default-key:active {
+ background-color: rgba(0, 0, 0, 0.16);
+}
+
+.bms-popup-background-light .keyboard-key.default-key:checked {
+ background-color: rgba(0, 0, 0, 0.12);
+}
+
+.bms-popup-background-light .keyboard-key.default-key:latched {
+ border-color: #3584e4;
+ background-color: #3584e4;
+ color: #ffffff;
+}
+
+/* Enter Key */
+.bms-popup-background-light .keyboard-key.enter-key {
+ color: #ffffff;
+ background-color: #3584e4;
+}
+
+.bms-popup-background-light .keyboard-key.enter-key:hover {
+ background-color: #4b92e7;
+}
+
+.bms-popup-background-light .keyboard-key.enter-key:active {
+ background-color: #2871cc;
+}
+
+/* Shift Key Uppercase */
+.bms-popup-background-light .keyboard-key.shift-key-uppercase {
+ background-color: rgba(0, 0, 0, 0.22);
+ color: #000000;
+}
+
+.bms-popup-background-light .keyboard-key.shift-key-uppercase:hover {
+ background-color: rgba(0, 0, 0, 0.28);
+} \ No newline at end of file
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/dark.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/dark.css
new file mode 100644
index 0000000..460794e
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/dark.css
@@ -0,0 +1,258 @@
+.bms-popup-background-dark .message:second-in-stack,
+.bms-popup-surface-dark .message:second-in-stack {
+ background: rgba(255, 255, 255, 0.05) !important;
+ box-shadow: 0 1px 1px 0 transparent;
+}
+
+.bms-popup-background-dark .message:lower-in-stack,
+.bms-popup-surface-dark .message:lower-in-stack {
+ background: rgba(255, 255, 255, 0.02) !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-dark .message-media-control,
+.bms-popup-surface-dark .message-media-control {
+ background-color: transparent;
+}
+
+.bms-popup-background-dark .message-media-control:hover,
+.bms-popup-surface-dark .message-media-control:hover,
+.bms-popup-background-dark .message-expand-button:hover,
+.bms-popup-surface-dark .message-expand-button:hover,
+.bms-popup-background-dark .switcher-list .item-box:hover,
+.bms-popup-surface-dark .switcher-list .item-box:hover {
+ background-color: rgba(255, 255, 255, 0.20) !important;
+}
+
+.bms-popup-background-dark .message-media-control:active,
+.bms-popup-surface-dark .message-media-control:active,
+.bms-popup-background-dark .message-expand-button:active,
+.bms-popup-surface-dark .message-expand-button:active,
+.bms-popup-background-dark .switcher-list .item-box:active,
+.bms-popup-surface-dark .switcher-list .item-box:active {
+ background-color: rgba(255, 255, 255, 0.24) !important;
+}
+
+.bms-popup-background-dark .message-media-control:focus,
+.bms-popup-background-dark .message-media-control:checked,
+.bms-popup-surface-dark .message-media-control:focus,
+.bms-popup-surface-dark .message-media-control:checked,
+.bms-popup-background-dark .message-expand-button:focus,
+.bms-popup-background-dark .message-expand-button:checked,
+.bms-popup-surface-dark .message-expand-button:focus,
+.bms-popup-surface-dark .message-expand-button:checked,
+.bms-popup-background-dark .message-notification-group StButton:focus,
+.bms-popup-background-dark .message-notification-group StButton:checked,
+.bms-popup-surface-dark .message-notification-group StButton:focus,
+.bms-popup-surface-dark .message-notification-group StButton:checked {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-dark .message-list-controls .message-list-clear-button {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.08) !important;
+}
+
+.bms-popup-background-dark .message-list-controls .message-list-clear-button:hover,
+.bms-popup-background-dark .message-list-controls .message-list-clear-button:focus {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-dark .message-list-controls .message-list-clear-button:active {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-dark .modal-dialog .button:insensitive,
+.bms-popup-background-dark .modal-dialog .modal-dialog-button-box .modal-dialog-button:insensitive {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+}
+
+.bms-popup-background-dark .quick-toggle,
+.bms-popup-background-dark .quick-toggle-has-menu .quick-toggle-menu-button,
+.bms-popup-background-dark .notification-button {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.11) !important;
+ border-color: rgba(255, 255, 255, 0.08);
+}
+
+.bms-popup-background-dark .quick-settings .icon-button,
+.bms-popup-background-dark .quick-settings-system-item .button,
+.bms-popup-background-dark .quick-settings-system-item .power-item {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.08) !important;
+ border-color: rgba(255, 255, 255, 0.06);
+ box-shadow: none;
+}
+
+.bms-popup-background-dark .quick-toggle:hover,
+.bms-popup-background-dark .quick-toggle-has-menu .quick-toggle-menu-button:hover,
+.bms-popup-background-dark .notification-button:hover {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-dark .quick-settings .icon-button:hover,
+.bms-popup-background-dark .quick-settings .icon-button:focus,
+.bms-popup-background-dark .quick-settings-system-item .button:hover,
+.bms-popup-background-dark .quick-settings-system-item .button:focus,
+.bms-popup-background-dark .quick-settings-system-item .power-item:hover,
+.bms-popup-background-dark .quick-settings-system-item .power-item:focus {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-dark .quick-settings .icon-button:active,
+.bms-popup-background-dark .quick-settings-system-item .button:active,
+.bms-popup-background-dark .quick-settings-system-item .power-item:active {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-dark .calendar {
+ color: #ffffff;
+ background-color: transparent;
+ border-color: transparent;
+ box-shadow: none;
+}
+
+.bms-popup-background-dark .datemenu-today-button {
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-dark .datemenu-today-button:hover,
+.bms-popup-background-dark .datemenu-today-button:focus {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+}
+
+.bms-popup-background-dark .datemenu-today-button:active,
+.bms-popup-background-dark .datemenu-today-button:checked {
+ background-color: rgba(255, 255, 255, 0.12) !important;
+}
+
+.bms-popup-background-dark .datemenu-today-button StLabel,
+.bms-popup-background-dark .datemenu-today-button .date-label {
+ color: #ffffff !important;
+}
+
+.bms-popup-background-dark .datemenu-today-button .day-label {
+ color: rgba(255, 255, 255, 0.68) !important;
+}
+
+.bms-popup-background-dark .events-button,
+.bms-popup-background-dark .world-clocks-button,
+.bms-popup-background-dark .weather-button {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.07) !important;
+ border-color: rgba(255, 255, 255, 0.05);
+ box-shadow: none;
+}
+
+.bms-popup-background-dark .events-button:hover,
+.bms-popup-background-dark .world-clocks-button:hover,
+.bms-popup-background-dark .weather-button:hover {
+ background-color: rgba(255, 255, 255, 0.12) !important;
+}
+
+.bms-popup-background-dark .calendar .calendar-month-header .calendar-month-label,
+.bms-popup-background-dark .calendar .calendar-month-header .pager-button {
+ color: #ffffff !important;
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-dark .calendar .calendar-day-heading,
+.bms-popup-background-dark .calendar .calendar-day {
+ color: #ffffff !important;
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-dark .calendar .calendar-day-heading {
+ color: rgba(255, 255, 255, 0.68) !important;
+}
+
+.bms-popup-background-dark .calendar .calendar-day.calendar-weekend {
+ color: rgba(255, 255, 255, 0.68) !important;
+}
+
+.bms-popup-background-dark .calendar .calendar-day.calendar-other-month,
+.bms-popup-background-dark .calendar .calendar-day.calendar-other-month.calendar-weekend {
+ color: rgba(255, 255, 255, 0.5) !important;
+}
+
+.bms-popup-background-dark .calendar-day:selected,
+.bms-popup-background-dark .calendar-day:checked,
+.bms-popup-background-dark .calendar-day.calendar-today {
+ color: #ffffff !important;
+ background-color: #3584e4 !important;
+ color: -st-accent-fg-color !important;
+ background-color: -st-accent-color !important;
+}
+
+.bms-popup-background-dark .calendar .calendar-day:hover,
+.bms-popup-background-dark .calendar .calendar-month-header .pager-button:hover {
+ background-color: rgba(255, 255, 255, 0.1) !important;
+}
+
+.bms-popup-background-dark .calendar-day:selected:hover,
+.bms-popup-background-dark .calendar-day:checked:hover,
+.bms-popup-background-dark .calendar-day.calendar-today:hover {
+ color: #ffffff !important;
+ background-color: #4990e7 !important;
+ color: -st-accent-fg-color !important;
+ background-color: st-lighten(-st-accent-color, 4%) !important;
+}
+
+.bms-popup-background-dark .quick-toggle:checked,
+.bms-popup-background-dark .quick-toggle-has-menu .quick-toggle:checked {
+ color: #ffffff;
+ background-color: #3584e4 !important;
+ color: -st-accent-fg-color;
+ background-color: -st-accent-color !important;
+}
+
+.bms-popup-background-dark .quick-toggle-has-menu:checked .quick-toggle-menu-button,
+.bms-popup-background-dark .quick-toggle-has-menu .quick-toggle-menu-button:checked {
+ color: #ffffff;
+ background-color: #4f96e8 !important;
+ color: -st-accent-fg-color;
+ background-color: st-mix(-st-accent-color, #ffffff, 85%) !important;
+}
+
+.bms-popup-background-dark .quick-toggle:checked:hover,
+.bms-popup-background-dark .quick-toggle-has-menu .quick-toggle:checked:hover {
+ color: #ffffff;
+ background-color: #4990e7 !important;
+ color: -st-accent-fg-color;
+ background-color: st-lighten(-st-accent-color, 4%) !important;
+}
+
+.bms-popup-background-dark .quick-toggle-has-menu:checked .quick-toggle-menu-button:hover,
+.bms-popup-background-dark .quick-toggle-has-menu .quick-toggle-menu-button:checked:hover {
+ color: #ffffff;
+ background-color: #62a0ea !important;
+ color: -st-accent-fg-color;
+ background-color: st-lighten(st-mix(-st-accent-color, #ffffff, 85%), 4%) !important;
+}
+
+.bms-popup-background-dark .quick-toggle-has-menu:checked .quick-toggle-separator {
+ background-color: rgba(255, 255, 255, 0.3);
+ background-color: st-mix(-st-accent-fg-color, -st-accent-color, 30%);
+}
+
+.bms-popup-background-dark StEntry {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+ color: rgba(255, 255, 255, 0.7) !important;
+}
+
+.bms-popup-background-dark StEntry:focus {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+ color: #ffffff !important;
+}
+
+.bms-popup-background-dark StEntry:insensitive {
+ background-color: rgba(255, 255, 255, 0.05) !important;
+ color: rgba(255, 255, 255, 0.5) !important;
+}
+
+.bms-popup-background-dark StEntry StLabel.hint-text {
+ color: rgba(255, 255, 255, 0.5) !important;
+} \ No newline at end of file
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/light.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/light.css
new file mode 100644
index 0000000..7c70ed3
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/light.css
@@ -0,0 +1,335 @@
+.bms-popup-background-light .message:second-in-stack,
+.bms-popup-surface-light .message:second-in-stack {
+ background: rgba(255, 255, 255, 0.54) !important;
+ box-shadow: 0 1px 1px 0 transparent;
+}
+
+.bms-popup-background-light .message:lower-in-stack,
+.bms-popup-surface-light .message:lower-in-stack {
+ background: rgba(255, 255, 255, 0.44) !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-light .message-media-control,
+.bms-popup-surface-light .message-media-control {
+ background-color: transparent;
+}
+
+.bms-popup-background-light .message-media-control:hover,
+.bms-popup-surface-light .message-media-control:hover,
+.bms-popup-background-light .message-expand-button:hover,
+.bms-popup-surface-light .message-expand-button:hover,
+.bms-popup-background-light .message-notification-group StButton:hover,
+.bms-popup-surface-light .message-notification-group StButton:hover,
+.bms-popup-background-light .switcher-list .item-box:hover,
+.bms-popup-surface-light .switcher-list .item-box:hover {
+ background-color: rgba(0, 0, 0, 0.18) !important;
+}
+
+.bms-popup-background-light .message-media-control:active,
+.bms-popup-surface-light .message-media-control:active,
+.bms-popup-background-light .message-expand-button:active,
+.bms-popup-surface-light .message-expand-button:active,
+.bms-popup-background-light .message-notification-group StButton:active,
+.bms-popup-surface-light .message-notification-group StButton:active,
+.bms-popup-background-light .switcher-list .item-box:active,
+.bms-popup-surface-light .switcher-list .item-box:active {
+ background-color: rgba(0, 0, 0, 0.22) !important;
+}
+
+.bms-popup-background-light .message-media-control:focus,
+.bms-popup-background-light .message-media-control:checked,
+.bms-popup-surface-light .message-media-control:focus,
+.bms-popup-surface-light .message-media-control:checked,
+.bms-popup-background-light .message-expand-button:focus,
+.bms-popup-background-light .message-expand-button:checked,
+.bms-popup-surface-light .message-expand-button:focus,
+.bms-popup-surface-light .message-expand-button:checked,
+.bms-popup-background-light .message-notification-group StButton:focus,
+.bms-popup-background-light .message-notification-group StButton:checked,
+.bms-popup-surface-light .message-notification-group StButton:focus,
+.bms-popup-surface-light .message-notification-group StButton:checked {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-light .message .message-header,
+.bms-popup-background-light .message .message-header .message-header-content .event-time {
+ color: rgba(34, 34, 38, 0.68);
+}
+
+.bms-popup-background-light .message .message-header .message-header-content .message-source-title,
+.bms-popup-background-light .message .message-box .message-content .message-title {
+ color: #222226;
+}
+
+.bms-popup-background-light .message .message-header .message-source-icon {
+ color: rgba(34, 34, 38, 0.74);
+}
+
+.bms-popup-background-light .message .message-header .message-expand-button,
+.bms-popup-background-light .message .message-header .message-close-button,
+.bms-popup-background-light .message-notification-group .message-collapse-button {
+ color: #222226;
+ background-color: rgba(0, 0, 0, 0.08) !important;
+}
+
+.bms-popup-background-light .message .message-header .message-expand-button:hover,
+.bms-popup-background-light .message .message-header .message-close-button:hover,
+.bms-popup-background-light .message-notification-group .message-collapse-button:hover {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-light .message .message-header .message-expand-button:active,
+.bms-popup-background-light .message .message-header .message-close-button:active,
+.bms-popup-background-light .message-notification-group .message-collapse-button:active {
+ background-color: rgba(0, 0, 0, 0.16) !important;
+}
+
+.bms-popup-background-light .message-list-controls .message-list-clear-button {
+ color: #222226;
+ background-color: rgba(0, 0, 0, 0.08) !important;
+}
+
+.bms-popup-background-light .message-list-controls .message-list-clear-button:hover,
+.bms-popup-background-light .message-list-controls .message-list-clear-button:focus {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-light .message-list-controls .message-list-clear-button:active {
+ background-color: rgba(0, 0, 0, 0.16) !important;
+}
+
+.bms-popup-background-light .modal-dialog .button,
+.bms-popup-background-light .modal-dialog .modal-dialog-button-box .modal-dialog-button {
+ color: #222226 !important;
+ background-color: rgba(255, 255, 255, 0.42) !important;
+ border-color: rgba(0, 0, 0, 0.08);
+}
+
+.bms-popup-background-light .modal-dialog .button:hover,
+.bms-popup-background-light .modal-dialog .button:focus,
+.bms-popup-background-light .modal-dialog .modal-dialog-button-box .modal-dialog-button:hover,
+.bms-popup-background-light .modal-dialog .modal-dialog-button-box .modal-dialog-button:focus {
+ color: #222226 !important;
+ background-color: rgba(255, 255, 255, 0.54) !important;
+}
+
+.bms-popup-background-light .modal-dialog .button:active,
+.bms-popup-background-light .modal-dialog .button:checked,
+.bms-popup-background-light .modal-dialog .modal-dialog-button-box .modal-dialog-button:active,
+.bms-popup-background-light .modal-dialog .modal-dialog-button-box .modal-dialog-button:checked {
+ color: #222226 !important;
+ background-color: rgba(0, 0, 0, 0.1) !important;
+}
+
+.bms-popup-background-light .modal-dialog .button:insensitive,
+.bms-popup-background-light .modal-dialog .modal-dialog-button-box .modal-dialog-button:insensitive {
+ color: rgba(34, 34, 38, 0.5) !important;
+ background-color: rgba(255, 255, 255, 0.28) !important;
+}
+
+.bms-popup-background-light .quick-toggle,
+.bms-popup-background-light .quick-toggle-has-menu .quick-toggle-menu-button,
+.bms-popup-background-light .notification-button {
+ color: #222226;
+ background-color: rgba(255, 255, 255, 0.62) !important;
+ border-color: rgba(0, 0, 0, 0.08);
+}
+
+.bms-popup-background-light .quick-settings .icon-button,
+.bms-popup-background-light .quick-settings-system-item .button,
+.bms-popup-background-light .quick-settings-system-item .power-item {
+ color: #222226;
+ background-color: rgba(0, 0, 0, 0.08) !important;
+ border-color: rgba(0, 0, 0, 0.05);
+ box-shadow: none;
+}
+
+.bms-popup-background-light .quick-toggle:hover,
+.bms-popup-background-light .quick-toggle-has-menu .quick-toggle-menu-button:hover,
+.bms-popup-background-light .notification-button:hover {
+ background-color: rgba(255, 255, 255, 0.78) !important;
+}
+
+.bms-popup-background-light .quick-settings .icon-button:hover,
+.bms-popup-background-light .quick-settings .icon-button:focus,
+.bms-popup-background-light .quick-settings-system-item .button:hover,
+.bms-popup-background-light .quick-settings-system-item .button:focus,
+.bms-popup-background-light .quick-settings-system-item .power-item:hover,
+.bms-popup-background-light .quick-settings-system-item .power-item:focus {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-light .quick-settings .icon-button:active,
+.bms-popup-background-light .quick-settings-system-item .button:active,
+.bms-popup-background-light .quick-settings-system-item .power-item:active {
+ background-color: rgba(0, 0, 0, 0.16) !important;
+}
+
+.bms-popup-background-light .calendar {
+ color: #222226;
+ background-color: transparent;
+ border-color: transparent;
+ box-shadow: none;
+}
+
+.bms-popup-background-light .datemenu-today-button {
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-light .datemenu-today-button:hover,
+.bms-popup-background-light .datemenu-today-button:focus {
+ background-color: rgba(0, 0, 0, 0.06) !important;
+}
+
+.bms-popup-background-light .datemenu-today-button:active,
+.bms-popup-background-light .datemenu-today-button:checked {
+ background-color: rgba(0, 0, 0, 0.1) !important;
+}
+
+.bms-popup-background-light .datemenu-today-button StLabel,
+.bms-popup-background-light .datemenu-today-button .date-label {
+ color: #222226 !important;
+}
+
+.bms-popup-background-light .datemenu-today-button .day-label {
+ color: rgba(34, 34, 38, 0.68) !important;
+}
+
+.bms-popup-background-light .events-button,
+.bms-popup-background-light .world-clocks-button,
+.bms-popup-background-light .weather-button {
+ color: #222226;
+ background-color: rgba(255, 255, 255, 0.28) !important;
+ border-color: rgba(0, 0, 0, 0.04);
+ box-shadow: none;
+}
+
+.bms-popup-background-light .events-button:hover,
+.bms-popup-background-light .world-clocks-button:hover,
+.bms-popup-background-light .weather-button:hover {
+ background-color: rgba(255, 255, 255, 0.4) !important;
+}
+
+.bms-popup-background-light .calendar .calendar-month-header .calendar-month-label,
+.bms-popup-background-light .calendar .calendar-month-header .pager-button {
+ color: #222226 !important;
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-light .calendar .calendar-day-heading,
+.bms-popup-background-light .calendar .calendar-day {
+ color: #222226 !important;
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-light .calendar .calendar-day-heading {
+ color: rgba(34, 34, 38, 0.68) !important;
+}
+
+.bms-popup-background-light .calendar .calendar-day.calendar-weekend {
+ color: rgba(34, 34, 38, 0.72) !important;
+}
+
+.bms-popup-background-light .calendar .calendar-day.calendar-other-month,
+.bms-popup-background-light .calendar .calendar-day.calendar-other-month.calendar-weekend {
+ color: rgba(34, 34, 38, 0.42) !important;
+}
+
+.bms-popup-background-light .calendar .calendar-day:hover,
+.bms-popup-background-light .calendar .calendar-day:focus,
+.bms-popup-background-light .calendar .calendar-month-header .pager-button:hover,
+.bms-popup-background-light .calendar .calendar-month-header .pager-button:focus {
+ background-color: rgba(0, 0, 0, 0.08) !important;
+}
+
+.bms-popup-background-light .calendar .calendar-day:active,
+.bms-popup-background-light .calendar .calendar-day:selected,
+.bms-popup-background-light .calendar .calendar-day:checked {
+ color: #222226 !important;
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-light .calendar .calendar-day:active:hover,
+.bms-popup-background-light .calendar .calendar-day:selected:hover,
+.bms-popup-background-light .calendar .calendar-day:checked:hover {
+ background-color: rgba(0, 0, 0, 0.16) !important;
+}
+
+.bms-popup-background-light .calendar .calendar-day.calendar-today,
+.bms-popup-background-light .calendar .calendar-day.calendar-today:selected,
+.bms-popup-background-light .calendar .calendar-day.calendar-today:checked {
+ color: #ffffff !important;
+ background-color: #3584e4 !important;
+ color: -st-accent-fg-color !important;
+ background-color: -st-accent-color !important;
+}
+
+.bms-popup-background-light .calendar .calendar-day.calendar-today:hover,
+.bms-popup-background-light .calendar .calendar-day.calendar-today:selected:hover,
+.bms-popup-background-light .calendar .calendar-day.calendar-today:checked:hover {
+ color: #ffffff !important;
+ background-color: #1c71d8 !important;
+ color: -st-accent-fg-color !important;
+ background-color: st-darken(-st-accent-color, 8%) !important;
+}
+
+.bms-popup-background-light .quick-toggle:checked,
+.bms-popup-background-light .quick-toggle-has-menu .quick-toggle:checked {
+ color: #ffffff;
+ background-color: #3584e4 !important;
+ color: -st-accent-fg-color;
+ background-color: -st-accent-color !important;
+}
+
+.bms-popup-background-light .quick-toggle-has-menu:checked .quick-toggle-menu-button,
+.bms-popup-background-light .quick-toggle-has-menu .quick-toggle-menu-button:checked {
+ color: #222226;
+ background-color: #4f96e8 !important;
+ background-color: st-mix(-st-accent-color, #ffffff, 85%) !important;
+}
+
+.bms-popup-background-light .quick-toggle:checked:hover,
+.bms-popup-background-light .quick-toggle-has-menu .quick-toggle:checked:hover {
+ color: #ffffff;
+ background-color: #1c71d8 !important;
+ color: -st-accent-fg-color;
+ background-color: st-darken(-st-accent-color, 4%) !important;
+}
+
+.bms-popup-background-light .quick-toggle-has-menu:checked .quick-toggle-menu-button:hover,
+.bms-popup-background-light .quick-toggle-has-menu:checked .quick-toggle-menu-button:focus,
+.bms-popup-background-light .quick-toggle-has-menu .quick-toggle-menu-button:checked:hover,
+.bms-popup-background-light .quick-toggle-has-menu .quick-toggle-menu-button:checked:focus {
+ color: #222226;
+ background-color: #62a0ea !important;
+ background-color: st-lighten(st-mix(-st-accent-color, #ffffff, 85%), 4%) !important;
+}
+
+.bms-popup-background-light .quick-toggle-has-menu:checked .quick-toggle-separator {
+ background-color: rgba(255, 255, 255, 0.3);
+ background-color: st-mix(-st-accent-fg-color, -st-accent-color, 20%);
+}
+
+.bms-popup-background-light StEntry {
+ color: #222226 !important;
+ background-color: rgba(255, 255, 255, 0.42) !important;
+ border-color: rgba(0, 0, 0, 0.08);
+}
+
+.bms-popup-background-light StEntry:focus {
+ color: #222226 !important;
+ background-color: rgba(255, 255, 255, 0.54) !important;
+}
+
+.bms-popup-background-light StEntry:insensitive {
+ color: rgba(34, 34, 38, 0.5) !important;
+ background-color: rgba(255, 255, 255, 0.28) !important;
+}
+
+.bms-popup-background-light StEntry StLabel.hint-text {
+ color: rgba(34, 34, 38, 0.5) !important;
+} \ No newline at end of file
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/menu-items.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/menu-items.css
new file mode 100644
index 0000000..ac06da4
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/menu-items.css
@@ -0,0 +1,120 @@
+.bms-popup-background-transparent .quick-settings .quick-slider,
+.bms-popup-background-transparent .quick-settings .quick-slider:hover,
+.bms-popup-background-transparent .quick-settings .quick-slider:focus,
+.bms-popup-background-transparent .quick-settings .quick-slider:active,
+.bms-popup-background-transparent .quick-settings .quick-slider:checked,
+.bms-popup-background-light .quick-settings .quick-slider,
+.bms-popup-background-light .quick-settings .quick-slider:hover,
+.bms-popup-background-light .quick-settings .quick-slider:focus,
+.bms-popup-background-light .quick-settings .quick-slider:active,
+.bms-popup-background-light .quick-settings .quick-slider:checked,
+.bms-popup-background-dark .quick-settings .quick-slider,
+.bms-popup-background-dark .quick-settings .quick-slider:hover,
+.bms-popup-background-dark .quick-settings .quick-slider:focus,
+.bms-popup-background-dark .quick-settings .quick-slider:active,
+.bms-popup-background-dark .quick-settings .quick-slider:checked,
+.bms-popup-background-transparent .quick-slider .slider-bin,
+.bms-popup-background-transparent .quick-slider .slider-bin:hover,
+.bms-popup-background-transparent .quick-slider .slider-bin:focus,
+.bms-popup-background-transparent .quick-slider .icon-button,
+.bms-popup-background-transparent .quick-slider .button,
+.bms-popup-background-light .quick-slider .slider-bin,
+.bms-popup-background-light .quick-slider .slider-bin:hover,
+.bms-popup-background-light .quick-slider .slider-bin:focus,
+.bms-popup-background-light .quick-slider .icon-button,
+.bms-popup-background-light .quick-slider .button,
+.bms-popup-background-dark .quick-slider .slider-bin,
+.bms-popup-background-dark .quick-slider .slider-bin:hover,
+.bms-popup-background-dark .quick-slider .slider-bin:focus,
+.bms-popup-background-dark .quick-slider .icon-button,
+.bms-popup-background-dark .quick-slider .button {
+ background-color: transparent !important;
+ border-color: transparent;
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .quick-slider .icon-button:hover,
+.bms-popup-background-transparent .quick-slider .icon-button:focus,
+.bms-popup-background-transparent .quick-slider .button:hover,
+.bms-popup-background-transparent .quick-slider .button:focus {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+}
+
+.bms-popup-background-transparent .quick-slider .icon-button:active,
+.bms-popup-background-transparent .quick-slider .button:active {
+ background-color: rgba(255, 255, 255, 0.12) !important;
+}
+
+.bms-popup-background-light .quick-slider .icon-button:hover,
+.bms-popup-background-light .quick-slider .icon-button:focus,
+.bms-popup-background-light .quick-slider .button:hover,
+.bms-popup-background-light .quick-slider .button:focus {
+ background-color: rgba(0, 0, 0, 0.08) !important;
+}
+
+.bms-popup-background-light .quick-slider .icon-button:active,
+.bms-popup-background-light .quick-slider .button:active {
+ background-color: rgba(0, 0, 0, 0.12) !important;
+}
+
+.bms-popup-background-dark .quick-slider .icon-button:hover,
+.bms-popup-background-dark .quick-slider .icon-button:focus,
+.bms-popup-background-dark .quick-slider .button:hover,
+.bms-popup-background-dark .quick-slider .button:focus {
+ background-color: rgba(255, 255, 255, 0.12) !important;
+}
+
+.bms-popup-background-dark .quick-slider .icon-button:active,
+.bms-popup-background-dark .quick-slider .button:active {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-transparent .popup-menu-item:hover,
+.bms-popup-background-transparent .popup-menu-item:focus,
+.bms-popup-background-transparent .popup-menu-item:selected {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+}
+
+.bms-popup-background-transparent .popup-menu-item:active {
+ background-color: rgba(255, 255, 255, 0.12) !important;
+}
+
+.bms-popup-background-transparent .popup-menu-item:checked,
+.bms-popup-background-transparent .popup-menu-item:open {
+ background-color: transparent !important;
+}
+
+.bms-popup-background-light .popup-menu-item,
+.bms-popup-background-light .popup-menu-item:hover,
+.bms-popup-background-light .popup-menu-item:focus,
+.bms-popup-background-light .popup-menu-item:selected,
+.bms-popup-background-light .popup-menu-item:active,
+.bms-popup-background-light .popup-menu-item:checked {
+ color: #222226;
+}
+
+.bms-popup-background-light .popup-menu-item:insensitive {
+ color: rgba(34, 34, 38, 0.5);
+}
+
+.bms-popup-background-light .popup-menu-item:hover,
+.bms-popup-background-light .popup-menu-item:focus {
+ background-color: rgba(0, 0, 0, 0.06) !important;
+}
+
+.bms-popup-background-light .popup-menu-item:active,
+.bms-popup-background-light .popup-menu-item:open,
+.bms-popup-background-light .popup-menu-item:checked {
+ background-color: rgba(0, 0, 0, 0.1) !important;
+}
+
+.bms-popup-background-dark .popup-menu-item:hover,
+.bms-popup-background-dark .popup-menu-item:focus {
+ background-color: rgba(255, 255, 255, 0.1) !important;
+}
+
+.bms-popup-background-dark .popup-menu-item:active,
+.bms-popup-background-dark .popup-menu-item:open,
+.bms-popup-background-dark .popup-menu-item:checked {
+ background-color: rgba(255, 255, 255, 0.14) !important;
+}
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/transparent.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/transparent.css
new file mode 100644
index 0000000..460ff3d
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/styles/popup/transparent.css
@@ -0,0 +1,262 @@
+.bms-popup-background-transparent .message:second-in-stack,
+.bms-popup-surface-transparent .message:second-in-stack {
+ background: rgba(255, 255, 255, 0.05) !important;
+ box-shadow: 0 1px 1px 0 transparent;
+}
+
+.bms-popup-background-transparent .message:lower-in-stack,
+.bms-popup-surface-transparent .message:lower-in-stack {
+ background: rgba(255, 255, 255, 0.02) !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .message-media-control,
+.bms-popup-surface-transparent .message-media-control {
+ background-color: transparent;
+}
+
+.bms-popup-background-transparent .message-media-control:hover,
+.bms-popup-surface-transparent .message-media-control:hover,
+.bms-popup-background-transparent .message-expand-button:hover,
+.bms-popup-surface-transparent .message-expand-button:hover,
+.bms-popup-background-transparent .message-notification-group StButton:hover,
+.bms-popup-surface-transparent .message-notification-group StButton:hover,
+.bms-popup-background-transparent .switcher-list .item-box:hover,
+.bms-popup-surface-transparent .switcher-list .item-box:hover {
+ background-color: rgba(255, 255, 255, 0.20) !important;
+}
+
+.bms-popup-background-transparent .message-media-control:active,
+.bms-popup-surface-transparent .message-media-control:active,
+.bms-popup-background-transparent .message-expand-button:active,
+.bms-popup-surface-transparent .message-expand-button:active,
+.bms-popup-background-transparent .message-notification-group StButton:active,
+.bms-popup-surface-transparent .message-notification-group StButton:active,
+.bms-popup-background-transparent .switcher-list .item-box:active,
+.bms-popup-surface-transparent .switcher-list .item-box:active {
+ background-color: rgba(255, 255, 255, 0.24) !important;
+}
+
+.bms-popup-background-transparent .message-media-control:focus,
+.bms-popup-background-transparent .message-media-control:checked,
+.bms-popup-surface-transparent .message-media-control:focus,
+.bms-popup-surface-transparent .message-media-control:checked,
+.bms-popup-background-transparent .message-expand-button:focus,
+.bms-popup-background-transparent .message-expand-button:checked,
+.bms-popup-surface-transparent .message-expand-button:focus,
+.bms-popup-surface-transparent .message-expand-button:checked,
+.bms-popup-background-transparent .message-notification-group StButton:focus,
+.bms-popup-background-transparent .message-notification-group StButton:checked,
+.bms-popup-surface-transparent .message-notification-group StButton:focus,
+.bms-popup-surface-transparent .message-notification-group StButton:checked {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-transparent .message-list-controls .message-list-clear-button {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.08) !important;
+}
+
+.bms-popup-background-transparent .message-list-controls .message-list-clear-button:hover,
+.bms-popup-background-transparent .message-list-controls .message-list-clear-button:focus {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-transparent .message-list-controls .message-list-clear-button:active {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-transparent .modal-dialog .button:insensitive,
+.bms-popup-background-transparent .modal-dialog .modal-dialog-button-box .modal-dialog-button:insensitive {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+}
+
+.bms-popup-background-transparent .quick-toggle,
+.bms-popup-background-transparent .quick-toggle-has-menu .quick-toggle-menu-button,
+.bms-popup-background-transparent .notification-button {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.11) !important;
+ border-color: rgba(255, 255, 255, 0.08);
+}
+
+.bms-popup-background-transparent .quick-settings .icon-button,
+.bms-popup-background-transparent .quick-settings-system-item .button,
+.bms-popup-background-transparent .quick-settings-system-item .power-item {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.08) !important;
+ border-color: rgba(255, 255, 255, 0.06);
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .quick-toggle:hover,
+.bms-popup-background-transparent .quick-toggle-has-menu .quick-toggle-menu-button:hover,
+.bms-popup-background-transparent .notification-button:hover {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-transparent .quick-settings .icon-button:hover,
+.bms-popup-background-transparent .quick-settings .icon-button:focus,
+.bms-popup-background-transparent .quick-settings-system-item .button:hover,
+.bms-popup-background-transparent .quick-settings-system-item .button:focus,
+.bms-popup-background-transparent .quick-settings-system-item .power-item:hover,
+.bms-popup-background-transparent .quick-settings-system-item .power-item:focus {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+}
+
+.bms-popup-background-transparent .quick-settings .icon-button:active,
+.bms-popup-background-transparent .quick-settings-system-item .button:active,
+.bms-popup-background-transparent .quick-settings-system-item .power-item:active {
+ background-color: rgba(255, 255, 255, 0.18) !important;
+}
+
+.bms-popup-background-transparent .calendar {
+ color: #ffffff;
+ background-color: transparent;
+ border-color: transparent;
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .datemenu-today-button {
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .datemenu-today-button:hover,
+.bms-popup-background-transparent .datemenu-today-button:focus {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+}
+
+.bms-popup-background-transparent .datemenu-today-button:active,
+.bms-popup-background-transparent .datemenu-today-button:checked {
+ background-color: rgba(255, 255, 255, 0.12) !important;
+}
+
+.bms-popup-background-transparent .datemenu-today-button StLabel,
+.bms-popup-background-transparent .datemenu-today-button .date-label {
+ color: #ffffff !important;
+}
+
+.bms-popup-background-transparent .datemenu-today-button .day-label {
+ color: rgba(255, 255, 255, 0.68) !important;
+}
+
+.bms-popup-background-transparent .events-button,
+.bms-popup-background-transparent .world-clocks-button,
+.bms-popup-background-transparent .weather-button {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.07) !important;
+ border-color: rgba(255, 255, 255, 0.05);
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .events-button:hover,
+.bms-popup-background-transparent .world-clocks-button:hover,
+.bms-popup-background-transparent .weather-button:hover {
+ background-color: rgba(255, 255, 255, 0.12) !important;
+}
+
+.bms-popup-background-transparent .calendar .calendar-month-header .calendar-month-label,
+.bms-popup-background-transparent .calendar .calendar-month-header .pager-button {
+ color: #ffffff !important;
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .calendar .calendar-day-heading,
+.bms-popup-background-transparent .calendar .calendar-day {
+ color: #ffffff !important;
+ background-color: transparent !important;
+ box-shadow: none;
+}
+
+.bms-popup-background-transparent .calendar .calendar-day-heading {
+ color: rgba(255, 255, 255, 0.68) !important;
+}
+
+.bms-popup-background-transparent .calendar .calendar-day.calendar-weekend {
+ color: rgba(255, 255, 255, 0.68) !important;
+}
+
+.bms-popup-background-transparent .calendar .calendar-day.calendar-other-month,
+.bms-popup-background-transparent .calendar .calendar-day.calendar-other-month.calendar-weekend {
+ color: rgba(255, 255, 255, 0.5) !important;
+}
+
+.bms-popup-background-transparent .calendar-day:selected,
+.bms-popup-background-transparent .calendar-day:checked,
+.bms-popup-background-transparent .calendar-day.calendar-today {
+ color: #ffffff !important;
+ background-color: #3584e4 !important;
+ color: -st-accent-fg-color !important;
+ background-color: -st-accent-color !important;
+}
+
+.bms-popup-background-transparent .calendar .calendar-day:hover,
+.bms-popup-background-transparent .calendar .calendar-month-header .pager-button:hover {
+ background-color: rgba(255, 255, 255, 0.1) !important;
+}
+
+.bms-popup-background-transparent .calendar-day:selected:hover,
+.bms-popup-background-transparent .calendar-day:checked:hover,
+.bms-popup-background-transparent .calendar-day.calendar-today:hover {
+ color: #ffffff !important;
+ background-color: #4990e7 !important;
+ color: -st-accent-fg-color !important;
+ background-color: st-lighten(-st-accent-color, 4%) !important;
+}
+
+.bms-popup-background-transparent .quick-toggle:checked,
+.bms-popup-background-transparent .quick-toggle-has-menu .quick-toggle:checked {
+ color: #ffffff;
+ background-color: #3584e4 !important;
+ color: -st-accent-fg-color;
+ background-color: -st-accent-color !important;
+}
+
+.bms-popup-background-transparent .quick-toggle-has-menu:checked .quick-toggle-menu-button,
+.bms-popup-background-transparent .quick-toggle-has-menu .quick-toggle-menu-button:checked {
+ color: #ffffff;
+ background-color: #4f96e8 !important;
+ color: -st-accent-fg-color;
+ background-color: st-mix(-st-accent-color, #ffffff, 85%) !important;
+}
+
+.bms-popup-background-transparent .quick-toggle:checked:hover,
+.bms-popup-background-transparent .quick-toggle-has-menu .quick-toggle:checked:hover {
+ color: #ffffff;
+ background-color: #4990e7 !important;
+ color: -st-accent-fg-color;
+ background-color: st-lighten(-st-accent-color, 4%) !important;
+}
+
+.bms-popup-background-transparent .quick-toggle-has-menu:checked .quick-toggle-menu-button:hover,
+.bms-popup-background-transparent .quick-toggle-has-menu .quick-toggle-menu-button:checked:hover {
+ color: #ffffff;
+ background-color: #62a0ea !important;
+ color: -st-accent-fg-color;
+ background-color: st-lighten(st-mix(-st-accent-color, #ffffff, 85%), 4%) !important;
+}
+
+.bms-popup-background-transparent .quick-toggle-has-menu:checked .quick-toggle-separator {
+ background-color: rgba(255, 255, 255, 0.3);
+ background-color: st-mix(-st-accent-fg-color, -st-accent-color, 30%);
+}
+
+.bms-popup-background-transparent StEntry {
+ background-color: rgba(255, 255, 255, 0.08) !important;
+ color: rgba(255, 255, 255, 0.7) !important;
+}
+
+.bms-popup-background-transparent StEntry:focus {
+ background-color: rgba(255, 255, 255, 0.13) !important;
+ color: #ffffff !important;
+}
+
+.bms-popup-background-transparent StEntry:insensitive {
+ background-color: rgba(255, 255, 255, 0.05) !important;
+ color: rgba(255, 255, 255, 0.5) !important;
+}
+
+.bms-popup-background-transparent StEntry StLabel.hint-text {
+ color: rgba(255, 255, 255, 0.5) !important;
+} \ No newline at end of file
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/stylesheet.css b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/stylesheet.css
index b61e530..f8c3312 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/stylesheet.css
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/stylesheet.css
@@ -1,573 +1,10 @@
-/*** PANEL ***/
-
-/*
-* `.transparent-panel`
-*/
-#panel.transparent-panel {
- background: transparent;
- transition-duration: 500ms;
-}
-
-/*
-* `.dark-panel`
-*/
-#panel.dark-panel {
- background-color: rgba(100, 100, 100, 0.35);
- box-shadow: none;
- transition-duration: 500ms;
-}
-
-/*
-* `.light-panel`
-*/
-#panel.light-panel {
- background-color: rgba(200, 200, 200, 0.2);
- box-shadow: none;
- transition-duration: 500ms;
-}
-
-/*
-* `.contrasted-panel`
-*/
-#panel.contrasted-panel {
- background-color: transparent;
- box-shadow: none;
- transition-duration: 500ms;
-}
-
-.contrasted-panel .panel-button,
-.contrasted-panel .clock,
-.contrasted-panel .clock-display StIcon {
- color: #ffffff;
- border-radius: 14px;
- border: 3px solid transparent;
- background-color: rgba(0, 0, 0, 0.8);
- box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.03);
-}
-
-
-.contrasted-panel .clock-display StIcon {
- padding: 8px;
- margin: 0;
-}
-
-.contrasted-panel .panel-button:hover,
-.contrasted-panel .panel-button:hover .clock {
- color: #ffffff;
- background-color: rgba(0, 0, 0, 0.8);
-}
-
-.contrasted-panel .clock-display {
- background-color: transparent !important;
- box-shadow: none !important;
- border: none !important;
-}
-
-.contrasted-panel .clock {
- margin: 0 !important;
-}
-
-
-/*** DASH-TO-DOCK ***/
-
-/*
-* `.transparent-dash`
-*/
-.transparent-dash .dash-background {
- background-color: transparent !important;
-}
-
-/*
-* `.light-dash`
-*/
-.light-dash .dash-background {
- background-color: rgba(200, 200, 200, 0.2) !important;
-}
-
-/*
-* `.dark-dash`
-*/
-.dark-dash .dash-background {
- background-color: rgba(100, 100, 100, 0.35) !important;
-}
-
-
-/*** OVERVIEW ***/
-
-/*
-* Add transparency to the workspace animation (between workspaces)
-*/
-.blurred-overview .workspace-animation {
- background-color: transparent !important;
-}
-
-
-/*
-* `.overview-components-transparent`
-*/
-
-.overview-components-transparent .workspace-thumbnail {
- border: 1px solid rgba(100, 100, 100, 0.35);
-}
-
-.overview-components-transparent .search-entry {
- color: white;
- background-color: rgba(0, 0, 0, 0);
- border-color: transparent;
- box-shadow: none;
-}
-
-.overview-components-transparent .search-entry .search-entry-icon {
- color: rgba(255, 255, 255, 0.65);
-}
-
-.overview-components-transparent .overview-tile,
-.overview-components-transparent .overview-icon,
-.overview-components-transparent .grid-search-result,
-.overview-components-transparent .list-search-result,
-.overview-components-transparent .search-provider-icon,
-/* prevents the extension from interfering with Just Perfection */
-.overview-components-transparent.just-perfection .search-section-content,
-/* remove the rectangular background from the dash */
-.overview-components-transparent #dash .overview-tile,
-.overview-components-transparent #dashtopanelScrollview .overview-tile {
- background-color: transparent;
-}
-
-.overview-components-transparent .workspace-thumbnail,
-.overview-components-transparent .search-section-content,
-.overview-components-transparent .overview-tile.app-folder,
-.overview-components-transparent .page-navigation-arrow,
-.overview-components-transparent .app-folder-dialog .icon-button,
-/* this shouldn't apply to Dash to Dock */
-.overview-components-transparent StBoxLayout>StWidget>#dash>.dash-background {
- background-color: rgba(0, 0, 0, 0);
-}
-
-.overview-components-transparent .overview-tile:hover,
-.overview-components-transparent .overview-tile:focus,
-.overview-components-transparent .overview-tile:selected,
-.overview-components-transparent .overview-tile:highlighted,
-.overview-components-transparent .grid-search-result:hover,
-.overview-components-transparent .grid-search-result:focus,
-.overview-components-transparent .grid-search-result:selected,
-.overview-components-transparent .grid-search-result:highlighted,
-.overview-components-transparent .list-search-result:hover,
-.overview-components-transparent .list-search-result:focus,
-.overview-components-transparent .list-search-result:selected,
-.overview-components-transparent .list-search-result:highlighted,
-.overview-components-transparent .search-provider-icon:hover,
-.overview-components-transparent .search-provider-icon:focus,
-.overview-components-transparent .page-navigation-arrow:hover,
-.overview-components-transparent .page-navigation-arrow:focus,
-.overview-components-transparent .app-folder-dialog .icon-button:hover,
-.overview-components-transparent .app-folder-dialog .icon-button:focus,
-.overview-components-transparent #dash .overview-tile:hover .overview-icon,
-.overview-components-transparent #dash .overview-tile:focus .overview-icon,
-.overview-components-transparent #dash .show-apps:hover .overview-icon,
-.overview-components-transparent #dash .show-apps:focus .overview-icon {
- background-color: rgba(230, 230, 230, 0.08);
-}
-
-.overview-components-transparent .overview-tile:active,
-.overview-components-transparent .overview-tile:focus:hover,
-.overview-components-transparent .overview-tile:drop,
-.overview-components-transparent .overview-tile:selected:hover,
-.overview-components-transparent .overview-tile:highlighted:hover,
-.overview-components-transparent .grid-search-result:active,
-.overview-components-transparent .grid-search-result:focus:hover,
-.overview-components-transparent .grid-search-result:selected:hover,
-.overview-components-transparent .grid-search-result:highlighted:hover,
-.overview-components-transparent .list-search-result:active,
-.overview-components-transparent .list-search-result:focus:hover,
-.overview-components-transparent .list-search-result:selected:hover,
-.overview-components-transparent .list-search-result:highlighted:hover,
-.overview-components-transparent .search-provider-icon:active,
-.overview-components-transparent .search-provider-icon:focus:hover,
-.overview-components-transparent .page-navigation-arrow:active,
-.overview-components-transparent .page-navigation-arrow:focus:hover,
-.overview-components-transparent .app-folder-dialog .icon-button:active,
-.overview-components-transparent .app-folder-dialog .icon-button:focus:hover,
-.overview-components-transparent #dash .overview-tile:active .overview-icon,
-.overview-components-transparent #dash .overview-tile:focus:hover .overview-icon,
-.overview-components-transparent #dash .overview-tile:drop .overview-icon,
-.overview-components-transparent #dash .show-apps:checked .overview-icon {
- background-color: rgba(230, 230, 230, 0.12);
-}
-
-.overview-components-transparent .overview-tile:focus:active,
-.overview-components-transparent .overview-tile:selected:active,
-.overview-components-transparent .overview-tile:highlighted:active,
-.overview-components-transparent .grid-search-result:focus:active,
-.overview-components-transparent .grid-search-result:selected:active,
-.overview-components-transparent .grid-search-result:highlighted:active,
-.overview-components-transparent .list-search-result:focus:active,
-.overview-components-transparent .list-search-result:selected:active,
-.overview-components-transparent .list-search-result:highlighted:active,
-.overview-components-transparent .search-provider-icon:focus:active,
-.overview-components-transparent .page-navigation-arrow:focus:active,
-.overview-components-transparent .app-folder-dialog .icon-button:focus:active,
-.overview-components-transparent #dash .show-apps:checked .overview-icon:hover {
- background-color: rgba(230, 230, 230, 0.15);
-}
-
-
-/*
-* `.overview-components-light`
-*/
-
-.overview-components-light .search-entry {
- color: white;
- background-color: rgba(200, 200, 200, 0.2);
- border-color: transparent;
- box-shadow: none;
-}
-
-.overview-components-light .search-entry .search-entry-icon {
- color: rgba(255, 255, 255, 0.65);
-}
-
-.overview-components-light .overview-tile,
-.overview-components-light .overview-icon,
-.overview-components-light .grid-search-result,
-.overview-components-light .list-search-result,
-.overview-components-light .search-provider-icon,
-/* prevents the extension from interfering with Just Perfection */
-.overview-components-light.just-perfection .search-section-content,
-/* remove the rectangular background from the dash */
-.overview-components-light #dash .overview-tile,
-.overview-components-light #dashtopanelScrollview .overview-tile {
- background-color: transparent;
-}
-
-.overview-components-light .workspace-thumbnail,
-.overview-components-light .search-section-content,
-.overview-components-light .overview-tile.app-folder,
-.overview-components-light .page-navigation-arrow,
-.overview-components-light .app-folder-dialog .icon-button,
-/* this shouldn't apply to Dash to Dock */
-.overview-components-light StBoxLayout>StWidget>#dash>.dash-background {
- background-color: rgba(200, 200, 200, 0.2);
-}
-
-.overview-components-light .overview-tile:hover,
-.overview-components-light .overview-tile:focus,
-.overview-components-light .overview-tile:selected,
-.overview-components-light .overview-tile:highlighted,
-.overview-components-light .grid-search-result:hover,
-.overview-components-light .grid-search-result:focus,
-.overview-components-light .grid-search-result:selected,
-.overview-components-light .grid-search-result:highlighted,
-.overview-components-light .list-search-result:hover,
-.overview-components-light .list-search-result:focus,
-.overview-components-light .list-search-result:selected,
-.overview-components-light .list-search-result:highlighted,
-.overview-components-light .search-provider-icon:hover,
-.overview-components-light .search-provider-icon:focus,
-.overview-components-light .page-navigation-arrow:hover,
-.overview-components-light .page-navigation-arrow:focus,
-.overview-components-light .app-folder-dialog .icon-button:hover,
-.overview-components-light .app-folder-dialog .icon-button:focus,
-.overview-components-light #dash .overview-tile:hover .overview-icon,
-.overview-components-light #dash .overview-tile:focus .overview-icon,
-.overview-components-light #dash .show-apps:hover .overview-icon,
-.overview-components-light #dash .show-apps:focus .overview-icon {
- background-color: rgba(230, 230, 230, 0.2);
-}
-
-.overview-components-light .overview-tile:active,
-.overview-components-light .overview-tile:focus:hover,
-.overview-components-light .overview-tile:drop,
-.overview-components-light .overview-tile:selected:hover,
-.overview-components-light .overview-tile:highlighted:hover,
-.overview-components-light .grid-search-result:active,
-.overview-components-light .grid-search-result:focus:hover,
-.overview-components-light .grid-search-result:selected:hover,
-.overview-components-light .grid-search-result:highlighted:hover,
-.overview-components-light .list-search-result:active,
-.overview-components-light .list-search-result:focus:hover,
-.overview-components-light .list-search-result:selected:hover,
-.overview-components-light .list-search-result:highlighted:hover,
-.overview-components-light .search-provider-icon:active,
-.overview-components-light .search-provider-icon:focus:hover,
-.overview-components-light .page-navigation-arrow:active,
-.overview-components-light .page-navigation-arrow:focus:hover,
-.overview-components-light .app-folder-dialog .icon-button:active,
-.overview-components-light .app-folder-dialog .icon-button:focus:hover,
-.overview-components-light #dash .overview-tile:active .overview-icon,
-.overview-components-light #dash .overview-tile:focus:hover .overview-icon,
-.overview-components-light #dash .overview-tile:drop .overview-icon,
-.overview-components-light #dash .show-apps:checked .overview-icon {
- background-color: rgba(230, 230, 230, 0.25);
-}
-
-.overview-components-light .overview-tile:focus:active,
-.overview-components-light .overview-tile:selected:active,
-.overview-components-light .overview-tile:highlighted:active,
-.overview-components-light .grid-search-result:focus:active,
-.overview-components-light .grid-search-result:selected:active,
-.overview-components-light .grid-search-result:highlighted:active,
-.overview-components-light .list-search-result:focus:active,
-.overview-components-light .list-search-result:selected:active,
-.overview-components-light .list-search-result:highlighted:active,
-.overview-components-light .search-provider-icon:focus:active,
-.overview-components-light .page-navigation-arrow:focus:active,
-.overview-components-light .app-folder-dialog .icon-button:focus:active,
-.overview-components-light #dash .show-apps:checked .overview-icon:hover {
- background-color: rgba(230, 230, 230, 0.3);
-}
-
-
-/*
-* `.overview-components-dark`
-*/
-
-.overview-components-dark .search-entry {
- color: white;
- background-color: rgba(100, 100, 100, 0.35);
- border-color: transparent;
- box-shadow: none;
-}
-
-.overview-components-dark .search-entry .search-entry-icon {
- color: rgba(255, 255, 255, 0.65);
-}
-
-.overview-components-dark .overview-tile,
-.overview-components-dark .overview-icon,
-.overview-components-dark .grid-search-result,
-.overview-components-dark .list-search-result,
-.overview-components-dark .search-provider-icon,
-/* prevents the extension from interfering with Just Perfection */
-.overview-components-dark.just-perfection .search-section-content,
-/* remove the rectangular background from the dash */
-.overview-components-dark #dash .overview-tile,
-.overview-components-dark #dashtopanelScrollview .overview-tile {
- background-color: transparent;
-}
-
-.overview-components-dark .workspace-thumbnail,
-.overview-components-dark .search-section-content,
-.overview-components-dark .overview-tile.app-folder,
-.overview-components-dark .page-navigation-arrow,
-.overview-components-dark .app-folder-dialog .icon-button,
-/* this shouldn't apply to Dash to Dock */
-.overview-components-dark StBoxLayout>StWidget>#dash>.dash-background {
- background-color: rgba(100, 100, 100, 0.35);
-}
-
-.overview-components-dark .overview-tile:hover,
-.overview-components-dark .overview-tile:focus,
-.overview-components-dark .overview-tile:selected,
-.overview-components-dark .overview-tile:highlighted,
-.overview-components-dark .grid-search-result:hover,
-.overview-components-dark .grid-search-result:focus,
-.overview-components-dark .grid-search-result:selected,
-.overview-components-dark .grid-search-result:highlighted,
-.overview-components-dark .list-search-result:hover,
-.overview-components-dark .list-search-result:focus,
-.overview-components-dark .list-search-result:selected,
-.overview-components-dark .list-search-result:highlighted,
-.overview-components-dark .search-provider-icon:hover,
-.overview-components-dark .search-provider-icon:focus,
-.overview-components-dark .page-navigation-arrow:hover,
-.overview-components-dark .page-navigation-arrow:focus,
-.overview-components-dark .app-folder-dialog .icon-button:hover,
-.overview-components-dark .app-folder-dialog .icon-button:focus,
-.overview-components-dark #dash .overview-tile:hover .overview-icon,
-.overview-components-dark #dash .overview-tile:focus .overview-icon,
-.overview-components-dark #dash .show-apps:hover .overview-icon,
-.overview-components-dark #dash .show-apps:focus .overview-icon {
- background-color: rgba(120, 120, 120, 0.35);
-}
-
-.overview-components-dark .overview-tile:active,
-.overview-components-dark .overview-tile:focus:hover,
-.overview-components-dark .overview-tile:drop,
-.overview-components-dark .overview-tile:selected:hover,
-.overview-components-dark .overview-tile:highlighted:hover,
-.overview-components-dark .grid-search-result:active,
-.overview-components-dark .grid-search-result:focus:hover,
-.overview-components-dark .grid-search-result:selected:hover,
-.overview-components-dark .grid-search-result:highlighted:hover,
-.overview-components-dark .list-search-result:active,
-.overview-components-dark .list-search-result:focus:hover,
-.overview-components-dark .list-search-result:selected:hover,
-.overview-components-dark .list-search-result:highlighted:hover,
-.overview-components-dark .search-provider-icon:active,
-.overview-components-dark .search-provider-icon:focus:hover,
-.overview-components-dark .page-navigation-arrow:active,
-.overview-components-dark .page-navigation-arrow:focus:hover,
-.overview-components-dark .app-folder-dialog .icon-button:active,
-.overview-components-dark .app-folder-dialog .icon-button:focus:hover,
-.overview-components-dark #dash .overview-tile:active .overview-icon,
-.overview-components-dark #dash .overview-tile:focus:hover .overview-icon,
-.overview-components-dark #dash .overview-tile:drop .overview-icon,
-.overview-components-dark #dash .show-apps:checked .overview-icon {
- background-color: rgba(120, 120, 120, 0.4);
-}
-
-.overview-components-dark .overview-tile:focus:active,
-.overview-components-dark .overview-tile:selected:active,
-.overview-components-dark .overview-tile:highlighted:active,
-.overview-components-dark .grid-search-result:focus:active,
-.overview-components-dark .grid-search-result:selected:active,
-.overview-components-dark .grid-search-result:highlighted:active,
-.overview-components-dark .list-search-result:focus:active,
-.overview-components-dark .list-search-result:selected:active,
-.overview-components-dark .list-search-result:highlighted:active,
-.overview-components-dark .search-provider-icon:focus:active,
-.overview-components-dark .page-navigation-arrow:focus:active,
-.overview-components-dark .app-folder-dialog .icon-button:focus:active,
-.overview-components-dark #dash .show-apps:checked .overview-icon:hover {
- background-color: rgba(120, 120, 120, 0.45);
-}
-
-
-/*** APPFOLDER DIALOG ***/
-
-/*
-* `.appfolder-dialogs-transparent`
-*/
-
-.appfolder-dialogs-transparent {
- background-color: rgba(0, 0, 0, 0);
- border: none;
- box-shadow: none;
-}
-
-.appfolder-dialogs-transparent .folder-name-entry {
- color: white;
- background-color: rgba(0, 0, 0, 0);
- border: 0;
- box-shadow: none;
-}
-
-/*
-* `.appfolder-dialogs-light`
-*/
-
-.appfolder-dialogs-light {
- background-color: rgba(200, 200, 200, 0.2);
- border: none;
- box-shadow: none;
-}
-
-.appfolder-dialogs-light .folder-name-entry {
- color: white;
- background-color: rgba(200, 200, 200, 0.2);
- border: 0;
- box-shadow: none;
-}
-
-
-/*
-* `.appfolder-dialogs-dark`
-*/
-
-.appfolder-dialogs-dark {
- background-color: rgba(100, 100, 100, 0.35);
- border: none;
- box-shadow: none;
-}
-
-.appfolder-dialogs-dark .folder-name-entry {
- color: white;
- background-color: rgba(100, 100, 100, 0.35);
- border: 0;
- box-shadow: none;
-}
-
-
-/*** PANEL LIGHT TEXT ***/
-
-/*
-* `.panel-light-text`, adapted from gnome-shell-light.css
-*/
-
-#panel.panel-light-text .panel-button,
-#panel.panel-light-text .panel-button.clock-display,
-#panel.panel-light-text .netSpeedLabel {
- color: #f6f5f4;
- box-shadow: none;
-}
-
-#panel.panel-light-text .panel-button:active,
-#panel.panel-light-text .panel-button:focus,
-#panel.panel-light-text .panel-button:checked,
-#panel.panel-light-text .panel-button.clock-display:active .clock,
-#panel.panel-light-text .panel-button.clock-display:focus .clock,
-#panel.panel-light-text .panel-button.clock-display:checked .clock {
- box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.25);
-}
-
-#panel.panel-light-text .panel-button:active:hover,
-#panel.panel-light-text .panel-button:focus:hover,
-#panel.panel-light-text .panel-button:checked:hover,
-#panel.panel-light-text .panel-button.clock-display:active:hover,
-#panel.panel-light-text .panel-button.clock-display:focus:hover,
-#panel.panel-light-text .panel-button.clock-display:checked:hover,
-#panel.panel-light-text .panel-button.clock-display:active .clock:hover,
-#panel.panel-light-text .panel-button.clock-display:focus .clock:hover,
-#panel.panel-light-text .panel-button.clock-display:checked .clock:hover {
- box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.35);
-}
-
-#panel.panel-light-text .panel-button:hover,
-#panel.panel-light-text .panel-button.clock-display:hover,
-#panel.panel-light-text .panel-button.clock-display:hover .clock {
- box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.2);
-}
-
-#panel.panel-light-text .panel-button#panelActivities .workspace-dot {
- background-color: #f6f5f4;
-}
-
-#panel.panel-light-text .panel-button.clock-display:active,
-#panel.panel-light-text .panel-button.clock-display:focus,
-#panel.panel-light-text .panel-button.clock-display:checked,
-#panel.panel-light-text .panel-button.clock-display:hover {
- box-shadow: none !important;
-}
-
-#panel.panel-light-text .panel-button.screen-recording-indicator {
- color: #f6f5f4;
- box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.8);
-}
-
-#panel.panel-light-text .panel-button.screen-recording-indicator:active,
-#panel.panel-light-text .panel-button.screen-recording-indicator:focus,
-#panel.panel-light-text .panel-button.screen-recording-indicator:checked {
- box-shadow: inset 0 0 0 100px #c01c28;
-}
-
-#panel.panel-light-text .panel-button.screen-recording-indicator:active:hover,
-#panel.panel-light-text .panel-button.screen-recording-indicator:focus:hover,
-#panel.panel-light-text .panel-button.screen-recording-indicator:checked:hover {
- box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.95);
-}
-
-#panel.panel-light-text .panel-button.screen-recording-indicator:hover {
- box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.9);
-}
-
-#panel.panel-light-text .panel-button.screen-sharing-indicator {
- color: #282828;
- box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.8);
-}
-
-#panel.panel-light-text .panel-button.screen-sharing-indicator:active,
-#panel.panel-light-text .panel-button.screen-sharing-indicator:focus,
-#panel.panel-light-text .panel-button.screen-sharing-indicator:checked {
- box-shadow: inset 0 0 0 100px #ff7800;
-}
-
-#panel.panel-light-text .panel-button.screen-sharing-indicator:active:hover,
-#panel.panel-light-text .panel-button.screen-sharing-indicator:focus:hover,
-#panel.panel-light-text .panel-button.screen-sharing-indicator:checked:hover {
- box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.95);
-}
-
-#panel.panel-light-text .panel-button.screen-sharing-indicator:hover {
- box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.9);
-} \ No newline at end of file
+@import url("styles/panel.css");
+@import url("styles/dash.css");
+@import url("styles/popup/base.css");
+@import url("styles/popup/transparent.css");
+@import url("styles/popup/light.css");
+@import url("styles/popup/dark.css");
+@import url("styles/popup/menu-items.css");
+@import url("styles/overview.css");
+@import url("styles/appfolders.css");
+@import url("styles/panel-light-text.css");
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/applications.ui b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/applications.ui
index e7b57fa..2774271 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/applications.ui
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/applications.ui
@@ -9,7 +9,7 @@
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Applications blur</property>
<property name="description" translatable="yes">Adds blur to the applications.
-To get the best results possible, although with reduced performances, you can choose the option “No artifact” in the “Other → Hack level” tab.</property>
+To get the best results possible, although with reduced performances, you can choose the option “No artifact” in the “Other → Artifact handling” tab.</property>
<property name="header-suffix">
<object class="GtkSwitch" id="blur">
<property name="valign">center</property>
@@ -118,7 +118,7 @@ To get the best results possible, although with reduced performances, you can ch
<child type="suffix">
<object class="GtkButton" id="open_gnome_rounded_blur">
- <property name="icon-name">external-link-symbolic</property>
+ <property name="icon-name">adw-external-link-symbolic</property>
<property name="valign">center</property>
<property name="action-name">link.open-gnome-rounded-blur</property>
</object>
@@ -205,6 +205,21 @@ This may cause some latency or performance issues.</property>
<child>
<object class="AdwActionRow">
+ <property name="title" translatable="yes">Unblur when Fullscreen</property>
+ <property name="subtitle" translatable="yes">Forces the blur to be removed when a window is in fullscreen mode.</property>
+ <property name="activatable-widget">unblur_when_fullscreen</property>
+ <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" />
+
+ <child>
+ <object class="GtkSwitch" id="unblur_when_fullscreen">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwActionRow">
<property name="title" translatable="yes">Enable all by default</property>
<property name="subtitle" translatable="yes">Adds blur behind all windows by default.</property>
<property name="activatable-widget">enable_all</property>
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/dash.ui b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/dash.ui
index e95f606..e7bfbe4 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/dash.ui
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/dash.ui
@@ -117,7 +117,7 @@
<child type="suffix">
<object class="GtkButton" id="open_gnome_rounded_blur">
- <property name="icon-name">external-link-symbolic</property>
+ <property name="icon-name">adw-external-link-symbolic</property>
<property name="valign">center</property>
<property name="action-name">link.open-gnome-rounded-blur</property>
</object>
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/other.ui b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/other.ui
index e136e38..2e00846 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/other.ui
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/other.ui
@@ -120,9 +120,8 @@
<child>
<object class="AdwActionRow">
- <property name="title" translatable="yes">Hack level</property>
- <property name="subtitle" translatable="yes">Changes the behaviour of the dynamic blur effect. The default value is highly recommended.
-The “No artifact” option will entirely disable clipped redraws in GNOME shell, and will impact your computer performances significantly.</property>
+ <property name="title" translatable="yes">Artifact handling</property>
+ <property name="subtitle" translatable="yes">Controls how aggressively dynamic blur is repainted. The “No artifact” option disables clipped redraws globally and can reduce GNOME Shell performance.</property>
<property name="activatable-widget">hack_level</property>
<child>
<object class="GtkDropDown" id="hack_level">
@@ -200,9 +199,9 @@ The “No artifact” option will entirely disable clipped redraws in GNOME shel
<object class="GtkStringList" id="hack_level_model">
<items>
- <item translatable="yes">High performances</item>
+ <item translatable="yes">High performance</item>
<item translatable="yes">Default</item>
<item translatable="yes">No artifact</item>
</items>
</object>
-</interface> \ No newline at end of file
+</interface>
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/panel.ui b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/panel.ui
index eb9df61..cd11c0b 100644
--- a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/panel.ui
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/panel.ui
@@ -117,7 +117,7 @@
<child type="suffix">
<object class="GtkButton" id="open_gnome_rounded_blur">
- <property name="icon-name">external-link-symbolic</property>
+ <property name="icon-name">adw-external-link-symbolic</property>
<property name="valign">center</property>
<property name="action-name">link.open-gnome-rounded-blur</property>
</object>
@@ -174,8 +174,8 @@ Recommended unless you want to customize your GNOME theme.</property>
<child>
<object class="AdwActionRow">
- <property name="title" translatable="yes">Disable when a window is near</property>
- <property name="subtitle" translatable="yes">Disables the transparency of the panel when a window is near it.</property>
+ <property name="title" translatable="yes">Override background dynamically</property>
+ <property name="subtitle" translatable="yes">Override the background of the panel and apply certain effect when a window is near it.</property>
<property name="activatable-widget">override_background_dynamically</property>
<child>
@@ -185,6 +185,52 @@ Recommended unless you want to customize your GNOME theme.</property>
</child>
</object>
</child>
+
+ <child>
+ <object class="AdwActionRow" id="override_background_dynamically_mode_row">
+ <property name="title" translatable="yes">When window is near:</property>
+ <property name="subtitle" translatable="yes">Blur on Window Proximity: Blur only when a window is near the panel and transparent when it is not.
+Background on Window Proximity: Solid color background when a window is near the panel and blur when it is not</property>
+ <property name="activatable-widget">override_background_dynamically_mode</property>
+
+ <child>
+ <object class="GtkDropDown" id="override_background_dynamically_mode">
+ <property name="valign">center</property>
+ <property name="model">override_background_dynamically_mode_model</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwActionRow" id="gradient_panel_row">
+ <property name="title" translatable="yes">Gradient background</property>
+ <property name="subtitle" translatable="yes">Apply a gradient effect to the panel background.</property>
+ <property name="activatable-widget">gradient_panel</property>
+
+ <child>
+ <object class="GtkSwitch" id="gradient_panel">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwActionRow" id="gradient_panel_mode_row">
+ <property name="title" translatable="yes">Gradient direction</property>
+ <property name="subtitle" translatable="yes">Change the direction of the gradient background.</property>
+ <property name="activatable-widget">gradient_panel_mode</property>
+
+ <child>
+ <object class="GtkDropDown" id="gradient_panel_mode">
+ <property name="valign">center</property>
+ <property name="model">gradient_panel_mode_model</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
</object>
</child>
@@ -252,6 +298,20 @@ Recommended unless you want to customize your GNOME theme.</property>
</items>
</object>
+ <object class="GtkStringList" id="override_background_dynamically_mode_model">
+ <items>
+ <item translatable="yes">Blur on Window Proximity</item>
+ <item translatable="yes">Background on Window Proximity</item>
+ </items>
+ </object>
+
+ <object class="GtkStringList" id="gradient_panel_mode_model">
+ <items>
+ <item translatable="yes">Top</item>
+ <item translatable="yes">Bottom</item>
+ </items>
+ </object>
+
<object class="GtkAdjustment" id="sigma">
<property name="lower">0</property>
<property name="upper">100</property>
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/popup.ui b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/popup.ui
new file mode 100644
index 0000000..ec8853c
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/ui/popup.ui
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="blur-my-shell@aunetx">
+ <template class="PopupBlur" parent="AdwPreferencesPage">
+ <property name="name">popup</property>
+ <property name="title" translatable="yes">Popups</property>
+ <property name="icon-name">popup-symbolic</property>
+
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="yes">Popup blur</property>
+ <property name="description" translatable="yes">Add blur to GNOME Shell menus, the calendar and notifications popup, notification banners, OSD popups, and dialogs.</property>
+ <property name="header-suffix">
+ <object class="GtkSwitch" id="blur">
+ <property name="valign">center</property>
+ </object>
+ </property>
+
+ <child>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Blur type</property>
+ <property name="subtitle" translatable="yes">The dynamic blur is slower and only compatible with a gaussian blur effect.</property>
+ <property name="activatable-widget">blur_mode_choose</property>
+ <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" />
+
+ <child>
+ <object class="GtkBox" id="blur_mode_choose">
+ <property name="valign">center</property>
+ <property name="hexpand">false</property>
+ <style>
+ <class name="linked" />
+ </style>
+
+ <child>
+ <object class="GtkToggleButton" id="mode_static">
+ <property name="valign">center</property>
+ <property name="hexpand">true</property>
+ <property name="group">mode_dynamic</property>
+ <property name="child">
+ <object class="AdwButtonContent">
+ <property name="icon-name">static-mode-symbolic</property>
+ <property name="label" translatable="yes">Static</property>
+ </object>
+ </property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="mode_dynamic">
+ <property name="valign">center</property>
+ <property name="hexpand">true</property>
+ <property name="child">
+ <object class="AdwButtonContent">
+ <property name="icon-name">dynamic-mode-symbolic</property>
+ <property name="label" translatable="yes">Dynamic</property>
+ </object>
+ </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="PipelineChooseRow" id="pipeline_choose_row">
+ <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" />
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwActionRow" id="sigma_row">
+ <property name="title" translatable="yes">Sigma</property>
+ <property name="subtitle" translatable="yes">The intensity of the blur.</property>
+ <property name="activatable-widget">sigma_scale</property>
+ <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" />
+
+ <child>
+ <object class="GtkScale" id="sigma_scale">
+ <property name="valign">center</property>
+ <property name="hexpand">true</property>
+ <property name="width-request">200px</property>
+ <property name="draw-value">true</property>
+ <property name="value-pos">right</property>
+ <property name="digits">0</property>
+ <property name="adjustment">sigma</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwActionRow" id="brightness_row">
+ <property name="title" translatable="yes">Brightness</property>
+ <property name="subtitle" translatable="yes">The brightness of the blur effect, a high value might make the text harder to read.</property>
+ <property name="activatable-widget">brightness_scale</property>
+ <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" />
+
+ <child>
+ <object class="GtkScale" id="brightness_scale">
+ <property name="valign">center</property>
+ <property name="hexpand">true</property>
+ <property name="width-request">200px</property>
+ <property name="draw-value">true</property>
+ <property name="value-pos">right</property>
+ <property name="digits">2</property>
+ <property name="adjustment">brightness</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwExpanderRow" id="corner_radius_row">
+ <property name="title" translatable="yes">Corner radius</property>
+ <property name="subtitle" translatable="yes">Adjust the rounded corners for each popup surface.</property>
+ <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" />
+
+ <child>
+ <object class="AdwSpinRow" id="menu_corner_radius">
+ <property name="title" translatable="yes">Menus</property>
+ <property name="adjustment">menu_corner_radius_adjustment</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwSpinRow" id="quick_settings_corner_radius">
+ <property name="title" translatable="yes">Quick settings and calendar</property>
+ <property name="adjustment">quick_settings_corner_radius_adjustment</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwSpinRow" id="notification_corner_radius">
+ <property name="title" translatable="yes">Notifications</property>
+ <property name="adjustment">notification_corner_radius_adjustment</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwSpinRow" id="osd_corner_radius">
+ <property name="title" translatable="yes">OSDs and switchers</property>
+ <property name="adjustment">osd_corner_radius_adjustment</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwSpinRow" id="dialog_corner_radius">
+ <property name="title" translatable="yes">Dialogs</property>
+ <property name="adjustment">dialog_corner_radius_adjustment</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwSpinRow" id="osk_corner_radius">
+ <property name="title" translatable="yes">On-screen keyboard</property>
+ <property name="adjustment">osk_corner_radius_adjustment</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwSpinRow" id="corner_radius">
+ <property name="title" translatable="yes">Other popup surfaces</property>
+ <property name="adjustment">corner_radius_adjustment</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwActionRow" id="corner_radius_not_found_row">
+ <property name="title" translatable="yes">Corner radius</property>
+ <property name="subtitle" translatable="yes">Install the GNOME Rounded Blur library to clip dynamic blur with rounded corners.</property>
+ <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" />
+ <property name="activatable-widget">open_gnome_rounded_blur</property>
+
+ <child type="suffix">
+ <object class="GtkButton" id="open_gnome_rounded_blur">
+ <property name="icon-name">adw-external-link-symbolic</property>
+ <property name="valign">center</property>
+ <property name="action-name">link.open-gnome-rounded-blur</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwExpanderRow" id="override_background">
+ <property name="title" translatable="yes">Override background</property>
+ <property name="subtitle" translatable="yes">Override the background of popups to use a transparent or semi-transparent one.</property>
+ <property name="show-enable-switch">true</property>
+ <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" />
+
+ <child>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Preserve shell theme</property>
+ <property name="subtitle" translatable="yes">Keep your shell theme's colors for popup controls.</property>
+ <property name="activatable-widget">preserve_shell_theme</property>
+
+ <child>
+ <object class="GtkSwitch" id="preserve_shell_theme">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Background style</property>
+ <property name="subtitle" translatable="yes">The transparent/semi-transparent style for popups.</property>
+ <property name="activatable-widget">style_popup</property>
+
+ <child>
+ <object class="GtkDropDown" id="style_popup">
+ <property name="valign">center</property>
+ <property name="model">style_popup_model</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+
+ <object class="GtkAdjustment" id="sigma">
+ <property name="lower">0</property>
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ </object>
+
+ <object class="GtkAdjustment" id="brightness">
+ <property name="lower">0.0</property>
+ <property name="upper">1.0</property>
+ <property name="step-increment">0.01</property>
+ </object>
+
+ <object class="GtkAdjustment" id="corner_radius_adjustment">
+ <property name="lower">0</property>
+ <property name="upper">150</property>
+ <property name="step-increment">1</property>
+ </object>
+
+ <object class="GtkAdjustment" id="menu_corner_radius_adjustment">
+ <property name="lower">0</property>
+ <property name="upper">150</property>
+ <property name="step-increment">1</property>
+ </object>
+
+ <object class="GtkAdjustment" id="quick_settings_corner_radius_adjustment">
+ <property name="lower">0</property>
+ <property name="upper">150</property>
+ <property name="step-increment">1</property>
+ </object>
+
+ <object class="GtkAdjustment" id="notification_corner_radius_adjustment">
+ <property name="lower">0</property>
+ <property name="upper">150</property>
+ <property name="step-increment">1</property>
+ </object>
+
+ <object class="GtkAdjustment" id="osd_corner_radius_adjustment">
+ <property name="lower">0</property>
+ <property name="upper">150</property>
+ <property name="step-increment">1</property>
+ </object>
+
+ <object class="GtkAdjustment" id="dialog_corner_radius_adjustment">
+ <property name="lower">0</property>
+ <property name="upper">150</property>
+ <property name="step-increment">1</property>
+ </object>
+
+ <object class="GtkAdjustment" id="osk_corner_radius_adjustment">
+ <property name="lower">0</property>
+ <property name="upper">150</property>
+ <property name="step-increment">1</property>
+ </object>
+
+ <object class="GtkStringList" id="style_popup_model">
+ <items>
+ <item translatable="yes">Transparent</item>
+ <item translatable="yes">Light</item>
+ <item translatable="yes">Dark</item>
+ <item translatable="yes">Automatic</item>
+ </items>
+ </object>
+</interface>