summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js')
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js108
1 files changed, 106 insertions, 2 deletions
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}`);
+ }
+}