summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/src/utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/src/utils.js')
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/src/utils.js206
1 files changed, 206 insertions, 0 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/src/utils.js b/raveos-gnome-theme/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/src/utils.js
new file mode 100644
index 0000000..2e0d53d
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/src/utils.js
@@ -0,0 +1,206 @@
+//////////////////////////////////////////////////////////////////////////////////////////
+// ) ( //
+// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
+// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
+// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
+// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
+// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
+// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
+// |__/ //
+//////////////////////////////////////////////////////////////////////////////////////////
+
+// SPDX-FileCopyrightText: Simon Schneegans <code@simonschneegans.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+'use strict';
+
+import Gio from 'gi://Gio';
+import GLib from 'gi://GLib';
+
+// We import some modules optionally. This file is used in the preferences process as well
+// as in the GNOME Shell process. Some modules are only available or required in one of
+// these processes.
+const GdkPixbuf = await importInShellOnly('gi://GdkPixbuf');
+const Clutter = await importInShellOnly('gi://Clutter');
+const Cogl = await importInShellOnly('gi://Cogl');
+const St = await importInShellOnly('gi://St');
+
+// We import the Config module. This is done differently in the GNOME Shell process and in
+// the preferences process.
+const Config = await importConfig();
+
+// Returns the given argument, except for "alpha", "beta", and "rc". In these cases -3,
+// -2, and -1 are returned respectively.
+function toNumericVersion(x) {
+ switch (x) {
+ case 'alpha':
+ return -3;
+ case 'beta':
+ return -2;
+ case 'rc':
+ return -1;
+ }
+ return x;
+}
+
+const [GS_MAJOR, GS_MINOR] = Config.PACKAGE_VERSION.split('.').map(toNumericVersion);
+
+// This method returns true if the current GNOME Shell version matches the given
+// arguments.
+export function shellVersionIs(major, minor) {
+ return GS_MAJOR == major && GS_MINOR == toNumericVersion(minor);
+}
+
+// This method returns true if the current GNOME Shell version is at least as high as the
+// given arguments. Supports "alpha" and "beta" for the minor version number.
+export function shellVersionIsAtLeast(major, minor = 0) {
+ if (GS_MAJOR > major) {
+ return true;
+ }
+
+ if (GS_MAJOR == major) {
+ return GS_MINOR >= toNumericVersion(minor);
+ }
+
+ return false;
+}
+
+// This method can be used to import the Config module.
+export async function importConfig() {
+ if (typeof global === 'undefined') {
+ return (await import('resource:///org/gnome/Shell/Extensions/js/misc/config.js'));
+ }
+ return (await import('resource:///org/gnome/shell/misc/config.js'));
+}
+
+
+// This method can be used to write a message to GNOME Shell's log. This is enhances
+// the standard log() functionality by prepending the extension's name and the location
+// where the message was logged. As the extensions name is part of the location, you
+// can more effectively watch the log output of GNOME Shell:
+// journalctl -f -o cat | grep -E 'burn-my-windows|'
+export function debug(message) {
+ const stack = new Error().stack.split('\n');
+
+ // Remove debug() function call from stack.
+ stack.shift();
+
+ // Find the index of the extension directory in the stack entry. We do not want to
+ // print the entire absolute file path.
+ const extensionRoot = stack[0].indexOf('burn-my-windows@schneegans.github.com');
+
+ console.log('[' + stack[0].slice(extensionRoot) + '] ' + message);
+}
+
+// This method can be used to import a module in the GNOME Shell process only. This
+// is useful if you want to use a module in extension.js, but not in the preferences
+// process. This method returns null if it is called in the preferences process.
+export async function importInShellOnly(module) {
+ if (typeof global !== 'undefined') {
+ return (await import(module)).default;
+ }
+ return null;
+}
+
+// This method can be used to import a module in the preferences process only. The same as
+// importInShellOnly(), but the other way around.
+export async function importInPrefsOnly(module) {
+ if (typeof global === 'undefined') {
+ return (await import(module)).default;
+ }
+ return null;
+}
+
+// This method can be used to import gettext. This is done differently in the
+// GNOME Shell process and in the preferences process.
+export async function importGettext() {
+ if (typeof global === 'undefined') {
+ return (await import('resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'))
+ .gettext;
+ }
+ return (await import('resource:///org/gnome/shell/extensions/extension.js')).gettext;
+}
+
+// Reads the contents of a file contained in the global resources archive. The data
+// is returned as a string.
+export function getStringResource(path) {
+ const data = Gio.resources_lookup_data(path, 0);
+ return new TextDecoder().decode(data.get_data());
+}
+
+// Reads the contents of an image file contained in the global resources archive. The data
+// is returned as a St.ImageContent.
+export function getImageResource(path, premultiplied = false) {
+ const data = GdkPixbuf.Pixbuf.new_from_resource(path);
+ const texture = St.ImageContent.new_with_preferred_size(data.width, data.height);
+ const format = data.has_alpha ?
+ (premultiplied ? Cogl.PixelFormat.RGBA_8888_PRE : Cogl.PixelFormat.RGBA_8888) :
+ Cogl.PixelFormat.RGB_888;
+
+ // https://gitlab.gnome.org/GNOME/gnome-shell/-/commit/44b84e458a22046fedb85701ea25ad08ecc0d43f
+ if (shellVersionIsAtLeast(48, 'beta')) {
+ texture.set_data(global.stage.context.get_backend().get_cogl_context(),
+ data.get_pixels(), format, data.width, data.height, data.rowstride);
+ } else {
+ texture.set_data(data.get_pixels(), format, data.width, data.height, data.rowstride);
+ }
+
+ return texture;
+}
+
+// Executes a command asynchronously and returns the output from 'stdout' on success or
+// throw an error with output from 'stderr' on failure. If given, input will be passed to
+// 'stdin' and cancellable can be used to stop the process before it finishes.
+// This is directly taken from here:
+// https://gjs.guide/guides/gio/subprocesses.html#complete-examples
+export async function executeCommand(argv, input = null, cancellable = null) {
+ let cancelId = 0;
+ let flags = (Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE);
+
+ if (input !== null) flags |= Gio.SubprocessFlags.STDIN_PIPE;
+
+ let proc = new Gio.Subprocess({argv: argv, flags: flags});
+ proc.init(cancellable);
+
+ if (cancellable instanceof Gio.Cancellable) {
+ cancelId = cancellable.connect(() => proc.force_exit());
+ }
+
+ return new Promise((resolve, reject) => {
+ proc.communicate_utf8_async(input, null, (proc, res) => {
+ try {
+ let [, stdout, stderr] = proc.communicate_utf8_finish(res);
+ let status = proc.get_exit_status();
+
+ if (status !== 0) {
+ throw new Gio.IOErrorEnum({
+ code: Gio.io_error_from_errno(status),
+ message: stderr ? stderr.trim() : GLib.strerror(status)
+ });
+ }
+
+ resolve(stdout.trim());
+ } catch (e) {
+ reject(e);
+ } finally {
+ if (cancelId > 0) {
+ cancellable.disconnect(cancelId);
+ }
+ }
+ });
+ });
+}
+
+// Converts a hex, rgb, or rgba CSS-like color string to four numbers
+// representing rgba values.
+export function parseColor(string) {
+ let color;
+ if (shellVersionIsAtLeast(47, 'alpha')) {
+ color = Cogl.Color.from_string(string)[1];
+ } else {
+ color = Clutter.Color.from_string(string)[1];
+ }
+
+
+ return [color.red / 255, color.green / 255, color.blue / 255, color.alpha / 255];
+}