mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-24 12:22:09 +00:00
sidebar: live config: save ags values
This commit is contained in:
parent
5526340041
commit
a238caf3fe
5 changed files with 86 additions and 25 deletions
|
|
@ -14,13 +14,21 @@ function overrideConfigRecursive(userOverrides, configOptions = {}) {
|
|||
}
|
||||
|
||||
// Load default options from ~/.config/ags/modules/.configuration/default_options.jsonc
|
||||
const configFileContents = Utils.readFile(`${App.configDir}/modules/.configuration/default_options.jsonc`);
|
||||
let configOptions = parseJSONC(configFileContents);
|
||||
const userOverrideContents = Utils.readFile(`${App.configDir}/user_options.jsonc`);
|
||||
let userOverrides = parseJSONC(userOverrideContents);
|
||||
const defaultConfigFile = `${App.configDir}/modules/.configuration/default_options.jsonc`;
|
||||
const defaultConfigFileContents = Utils.readFile(defaultConfigFile);
|
||||
const defaultConfigOptions = parseJSONC(defaultConfigFileContents);
|
||||
|
||||
// Clone the default config to avoid modifying the original
|
||||
let configOptions = JSON.parse(JSON.stringify(defaultConfigOptions));
|
||||
|
||||
// Load user overrides
|
||||
const userOverrideFile = `${App.configDir}/user_options.jsonc`;
|
||||
const userOverrideContents = Utils.readFile(userOverrideFile);
|
||||
const userOverrides = parseJSONC(userOverrideContents);
|
||||
|
||||
// Override defaults with user's options
|
||||
overrideConfigRecursive(userOverrides, configOptions);
|
||||
|
||||
globalThis['userOptionsDefaults'] = defaultConfigOptions;
|
||||
globalThis['userOptions'] = configOptions;
|
||||
export default configOptions;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
|
||||
export function parseJSONC(jsoncString) {
|
||||
let result = "";
|
||||
let inString = false;
|
||||
|
|
|
|||
33
.config/ags/modules/.miscutils/objects.js
Normal file
33
.config/ags/modules/.miscutils/objects.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
export function getNestedProperty(obj, path) {
|
||||
return path.split('.').reduce((current, key) => {
|
||||
return (current && typeof current === 'object' && current.hasOwnProperty(key)) ? current[key] : undefined;
|
||||
}, obj);
|
||||
}
|
||||
|
||||
export function updateNestedProperty(obj, path, newValue) {
|
||||
const pathArray = path.split('.');
|
||||
const lastKeyIndex = pathArray.length - 1;
|
||||
|
||||
let current = obj;
|
||||
|
||||
for (let i = 0; i < lastKeyIndex; i++) {
|
||||
const key = pathArray[i];
|
||||
if (!current || typeof current !== 'object') {
|
||||
return false; // Previous part of path is not an object
|
||||
}
|
||||
|
||||
if (!current.hasOwnProperty(key)) {
|
||||
current[key] = {}; // Create the missing object
|
||||
}
|
||||
current = current[key];
|
||||
}
|
||||
|
||||
const lastKey = pathArray[lastKeyIndex];
|
||||
|
||||
if (!current || typeof current !== 'object') {
|
||||
return false; // Parent is not an object
|
||||
}
|
||||
|
||||
current[lastKey] = newValue;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ const { execAsync, exec } = Utils;
|
|||
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
|
||||
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
|
||||
import { ConfigGap, ConfigSpinButton, ConfigToggle } from '../../.commonwidgets/configwidgets.js';
|
||||
import { getNestedProperty, updateNestedProperty } from '../../.miscutils/objects.js';
|
||||
|
||||
const HyprlandToggle = ({ icon, name, desc = null, option, enableValue = 1, disableValue = 0, extraOnChange = () => { }, extraOnReset = () => { }, save = true }) => ConfigToggle({
|
||||
icon: icon,
|
||||
|
|
@ -24,7 +25,7 @@ const HyprlandToggle = ({ icon, name, desc = null, option, enableValue = 1, disa
|
|||
]).catch(print);
|
||||
else
|
||||
execAsync(['hyprctl', 'keyword', option, `${newValue ? enableValue : disableValue}`]).catch(print);
|
||||
|
||||
|
||||
extraOnChange(self, newValue);
|
||||
},
|
||||
onReset: async (self) => {
|
||||
|
|
@ -71,6 +72,38 @@ const HyprlandSpinButton = ({ icon, name, desc = null, option, save = true, extr
|
|||
...rest,
|
||||
});
|
||||
|
||||
const AgsSpinButton = ({
|
||||
icon, name, desc = null, option,
|
||||
save = true, extraOnChange = () => { },
|
||||
...rest
|
||||
}) => ConfigSpinButton({
|
||||
icon: icon,
|
||||
name: name,
|
||||
desc: desc,
|
||||
resetButton: true,
|
||||
initValue: getNestedProperty(userOptions, option),
|
||||
fetchValue: () => getNestedProperty(userOptions, option),
|
||||
step: 10, minValue: 0, maxValue: 1000,
|
||||
onChange: (self, newValue) => {
|
||||
updateNestedProperty(userOptions, option, newValue);
|
||||
if (save) execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
|
||||
--key ${option} \
|
||||
--value ${newValue} \
|
||||
--file ${App.configDir}/user_options.jsonc`
|
||||
]).catch(print);
|
||||
extraOnChange(self, newValue);
|
||||
},
|
||||
onReset: async (self) => {
|
||||
updateNestedProperty(userOptions, option,
|
||||
getNestedProperty(userOptionsDefaults, option));
|
||||
if (save) exec(`bash -c '${App.configDir}/scripts/ags/agsconfigurator.py \
|
||||
--key ${option} \
|
||||
--reset \
|
||||
--file ${App.configDir}/user_options.jsonc'`);
|
||||
},
|
||||
...rest,
|
||||
})
|
||||
|
||||
const Subcategory = (children) => Box({
|
||||
className: 'margin-left-20',
|
||||
vertical: true,
|
||||
|
|
@ -130,15 +163,12 @@ export default (props) => {
|
|||
extraOnReset: (self, newValue) => execAsync(['gsettings', 'set', 'org.gnome.desktop.interface', 'enable-animations', 'true']),
|
||||
}),
|
||||
Subcategory([
|
||||
ConfigSpinButton({
|
||||
AgsSpinButton({
|
||||
option: "animations.choreographyDelay",
|
||||
icon: 'clear_all',
|
||||
name: getString('Choreography delay'),
|
||||
desc: getString('In milliseconds, the delay between animations of a series'),
|
||||
initValue: userOptions.animations.choreographyDelay,
|
||||
step: 10, minValue: 0, maxValue: 1000,
|
||||
onChange: (self, newValue) => {
|
||||
userOptions.animations.choreographyDelay = newValue
|
||||
},
|
||||
})
|
||||
]),
|
||||
]
|
||||
|
|
@ -158,21 +188,12 @@ export default (props) => {
|
|||
className: 'sidebar-centermodules-scrollgradient-bottom'
|
||||
})]
|
||||
});
|
||||
const footNote = Box({
|
||||
homogeneous: true,
|
||||
children: [Label({
|
||||
hpack: 'center',
|
||||
className: 'txt txt-italic txt-subtext margin-5',
|
||||
label: getString('AGS-related changes aren\'t saved'),
|
||||
})]
|
||||
})
|
||||
return Box({
|
||||
...props,
|
||||
className: 'spacing-v-5',
|
||||
vertical: true,
|
||||
children: [
|
||||
mainContent,
|
||||
footNote,
|
||||
]
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
// vim: `:vsp` to split window, move cursor to the path, press `gf`.
|
||||
// `Ctrl-w` twice to switch between the files
|
||||
//
|
||||
// Limitations of this file
|
||||
// Don't expect every JSONC feature in... say, vscode, to work.
|
||||
// You can only have comments on top of the file
|
||||
// Limitations of this file:
|
||||
// * Only line comments (//) are allowed
|
||||
// * Comments are not allowed in or below the actual content
|
||||
// (will be nuked with updates from the UI)
|
||||
//
|
||||
//
|
||||
// Example: Put this to show 8 (instead of 10) workspaces on the bar
|
||||
// "workspaces": {"shown": 8 }
|
||||
|
|
|
|||
Loading…
Reference in a new issue