/* exported get_shell_version, is_undef, clamp, is_valid, match_colors, remove_file, get_file, write_to_file, gdk_to_css_color, clutter_to_native_color, tuple_to_native_color, deep_freeze, strip_args */ const GLib = imports.gi.GLib; const Gio = imports.gi.Gio; /* This import can't be a constant as it requires lazy initialization. */ let Meta = null; /* Gnome Versioning */ const MAJOR_VERSION = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[0], 10); const MINOR_VERSION = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1], 10); /* Permission setting for created files. */ const PERMISSIONS_MODE = parseInt('0744', 8); /* Utility Variable Access */ /** * Returns the current shell version. * * @returns {Object} The current shell version. * */ function get_shell_version() { return { major: MAJOR_VERSION, minor: MINOR_VERSION }; } /* Utility Functions */ /** * Evaluates parameter 'value' and returns either 'value' or 'min'/'max' if 'value' is outside of the range. * * @param {Number} value - Test value. * @param {Number} min - Minimum value. * @param {Number} max - Maximum value. * * @returns {Number} 'value' or the minimum or maximum. * */ function clamp(value, min, max) { return Math.min(Math.max(value, min), max); } /** * Determines if 'window' is a valid window to watch. * Will not work outside the extension code. * * @param {Object} window - Window to check. * * @returns {Boolean} Whether 'window' is a valid window to watch. * */ function is_valid(window) { if (!Meta) { Meta = imports.gi.Meta; } let windowTypes = [ Meta.WindowType.NORMAL, Meta.WindowType.DIALOG, Meta.WindowType.MODAL_DIALOG, Meta.WindowType.TOOLBAR, Meta.WindowType.MENU, Meta.WindowType.UTILITY, ]; let type = window.get_window_type(); return (windowTypes.indexOf(type) !== -1); } /** * Retrieves the GFile for a file path. * * @param {string} file_path - Path for a file. * * @returns {Object} GFile for the path or null if the path is not valid. * */ function get_file(file_path) { try { return Gio.file_new_for_path(file_path); } catch (error) { log('[Dynamic Panel Transparency] Error getting file: ' + error); } return null; } /** * Write the given string to a file path; creating the necessary files and directories. * * @param {string} file_path - Path for a file. * @param {string} text - Text to write to the file. * * @returns {Boolean} Whether the file write was a success. * */ function write_to_file(file_path, text) { try { let file = get_file(file_path); let parent = file.get_parent(); if (GLib.mkdir_with_parents(parent.get_path(), PERMISSIONS_MODE) === 0) { let success = file.replace_contents(text, null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, null); return success[0]; } } catch (error) { log('[Dynamic Panel Transparency] Error writing to file: ' + file_path); log(error); } return false; } /** * Deletes the given file_path. * * @param {string} file_path - Path for a file. * * @returns {Boolean} Whether the file deletion was a success. * */ function remove_file(file_path) { try { let file = get_file(file_path); let result = file.delete(null); return result; } catch (error) { log('[Dynamic Panel Transparency] Error removing file: ' + file_path); log(error); } return false; } /** * Converts a GdkColor into a JS/CSS color object. * * @param {Object} color - GdkColor to convert. * * @returns {Object} Converted RGB color. * */ function gdk_to_css_color(color) { let red = Math.round(clamp((color.red * 255), 0, 255)); let green = Math.round(clamp((color.green * 255), 0, 255)); let blue = Math.round(clamp((color.blue * 255), 0, 255)); return { 'red': red, 'green': green, 'blue': blue }; } /** * Converts a ClutterColor into a JS/CSS color object. * * @param {Object} color - ClutterColor to convert. * @param {Boolean} [alpha = false] - Whether to transfer the alpha value. * * @returns {Object} Converted RGB(A) color. * */ function clutter_to_native_color(color, alpha = false) { let output = { red: color.red, green: color.green, blue: color.blue }; if (alpha) { output.alpha = color.alpha; } return output; } /** * Converts a tuple from a GVariant (typically) into a JS/CSS color object. * * @param {Object} color - Tuple to convert. * @param {Boolean} [alpha = false] - Whether to transfer the alpha value. * * @returns {Object} Converted RGB(A) color. * */ function tuple_to_native_color(tuple) { let color = { red: tuple[0], green: tuple[1], blue: tuple[2] }; if (tuple.length === 4) { color.alpha = tuple[3]; } return color; } /** * Compares two colors for equivalency. * * @param {Object} a - First color. * @param {Object} a - Second color. * @param {Boolean} [alpha = false] - Whether to check the alpha value. * * @returns {Boolean} Whether the two colors are equal. * */ function match_colors(a, b, alpha = false) { let result = (a.red === b.red); result = result && (a.green === b.green); result = result && (a.blue === b.blue); if (alpha) { result = result && (a.alpha === b.alpha); } return result; } /** * Freezes an Object's and its children. * * @param {Object} type - Object to freeze. * @param {Boolean} [recursive = false] - Whether to recursively traverse the object's children. * */ function deep_freeze(type, recursive = false) { const freeze_children = function(obj) { Object.keys(obj).forEach(function(value, index, arr) { if (typeof (value) === 'object' && !Object.isFrozen(value)) { Object.freeze(value); if (recursive) { freeze_children(value); } } }); }; Object.freeze(type); freeze_children(type); } /** * Prevents any arguments from passing on. * * @param {Object} method - Method to call. * */ function strip_args(method) { return function() { method.call(this); }; }