Skip to content

Commit

Permalink
feat: add a basic configuration system
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreasHGK committed Nov 1, 2024
1 parent 9db3698 commit c806118
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 7 deletions.
8 changes: 5 additions & 3 deletions ags/bar/widgets/workspaces.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { config } from "lib/settings.js";
import { BarWidget } from "../bar-widget.js";

const hyprland = await Service.import("hyprland");
Expand All @@ -22,9 +23,10 @@ export const Workspaces = (monitor: number) =>
(workspaces, active) => {
// Workspaces start with ID 1. It is limited to 25 to keep it reasonable should hyprland
// return anything unexpected.
const workspaces_num = Math.min(
25,
Math.max(...workspaces.map((workspace) => workspace.id)),
const workspaces_num = Math.max(
// Always prioritize the value from the config as a minimum amount.
config.minWorkspaces,
Math.min(25, Math.max(...workspaces.map((workspace) => workspace.id))),
);
const children = new Array(workspaces_num);

Expand Down
46 changes: 46 additions & 0 deletions ags/lib/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import GLib from "gi://GLib";

/** The folder where this program's config files are found. */
export let config_root = "";

const xdg_config_home = GLib.getenv("XDG_CONFIG_HOME");
if (xdg_config_home !== null) {
config_root = `${xdg_config_home}/mithril-shell`;
} else {
config_root = `${Utils.HOME}/.config/mithril-shell`;
}

/** The program configuration. */
export let config = {
minWorkspaces: opt<number>(3),
lockCommand: opt<string | null>(null),
};

/**
* Reads the program configuration from the config file and updates the configuration.
*
* For the sake of simplicity this expects all keys to be set in the config file (home-manager will
* set missing keys). If no config file is found, the default configuration is used.
*/
export function readConfig() {
try {
const config_str = Utils.readFile(`${config_root}/settings.json`);
if (config_str === "") {
// Use the default config when no configuration file is found.
print("No configuration file found.");
return;
}

// The configuration should be type checked in the home-manager module, so it is not too big of
// a deal to just do this.
config = JSON.parse(config_str);
} catch (e) {
print(`Failed to read configuration: ${e}`);
return;
}
}

/** Helper function to define a config value with a type in a nice manner. */
function opt<T>(fallback: T): T {
return fallback;
}
2 changes: 2 additions & 0 deletions ags/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Gdk from "gi://Gdk";
import type Gtk from "gi://Gtk?version=3.0";

import { Bar } from "./bar/bar.js";
import { readConfig } from "./lib/settings.js";
import { Quicksettings } from "./quicksettings/quicksettings.js";

function forMonitors(widget: (monitor: number) => Gtk.Window) {
Expand All @@ -10,6 +11,7 @@ function forMonitors(widget: (monitor: number) => Gtk.Window) {
}

export function main(dest: string): void {
readConfig();
App.config({
style: `${dest}/style.css`,
windows: [...forMonitors(Bar), Quicksettings()],
Expand Down
12 changes: 8 additions & 4 deletions ags/quicksettings/quicksettings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { config } from "lib/settings";
import type { Icon } from "lib/types";
import type { Binding } from "types/service";
import { PopupWindow, showModal } from "window";
Expand Down Expand Up @@ -82,11 +83,14 @@ export const Quicksettings = () => {
Button({
icon: "system-lock-screen-symbolic",
onClick() {
// TODO: implement this when a configuration system is introduced.
Utils.execAsync(
`notify-send -a System "Unable to lock" "Locking via the bar is not yet implemented."`,
);
App.closeWindow("quicksettings");

if (config.lockCommand === null) {
Utils.execAsync(`notify-send -a System "Unable to lock" "No lock command configured."`);
return;
}

Utils.execAsync(config.lockCommand);
},
}),
Button({
Expand Down
26 changes: 26 additions & 0 deletions modules/mithril-shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,28 @@ in
surface0 = mkHexColorOption "#313244";
};

settings = {
minWorkspaces = mkOption {
type = types.int;
default = 3;
example = 10;
description = ''
The minimum amount of workspaces to show regardless of if they are empty or not.
'';
};

lockCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = ''
''${pkgs.hyprlock}/bin/hyprlock --immediate
'';
description = ''
The command used to lock the screen. Set to null to disable.
'';
};
};

integrations = {
hyprland.enable = mkOption {
type = types.bool;
Expand Down Expand Up @@ -109,6 +131,10 @@ in
};
};

xdg.configFile = {
"mithril-shell/settings.json".text = builtins.toJSON cfg.settings;
};

services.mithril-shell.finalPackage =
let
generateThemeScss = colors: ''
Expand Down

0 comments on commit c806118

Please sign in to comment.