Compare commits
3 Commits
2f28ec735d
...
e68321ac1e
| Author | SHA1 | Date | |
|---|---|---|---|
| e68321ac1e | |||
| 5357ba307b | |||
| 9960e874c4 |
@@ -1,6 +1,6 @@
|
|||||||
{ ... }: {
|
{ ... }: {
|
||||||
flake.lib.hyprlandBinds =
|
flake.lib.hyprlandBinds =
|
||||||
{ lib, dmsEnabled ? false }:
|
{ lib, dmsEnabled ? false, dmsIpcBinds }:
|
||||||
let
|
let
|
||||||
workspaceBinds =
|
workspaceBinds =
|
||||||
(builtins.map (i: "Super, ${toString i}, workspace, ${toString i}") (builtins.genList (n: n + 1) 9))
|
(builtins.map (i: "Super, ${toString i}, workspace, ${toString i}") (builtins.genList (n: n + 1) 9))
|
||||||
@@ -28,17 +28,15 @@
|
|||||||
"Super, Equal, splitratio, 0.1"
|
"Super, Equal, splitratio, 0.1"
|
||||||
"AltSuper, Space, togglefloating"
|
"AltSuper, Space, togglefloating"
|
||||||
"Super, P, pin"
|
"Super, P, pin"
|
||||||
]
|
] ++ lib.optionals dmsEnabled [
|
||||||
++ lib.optionals dmsEnabled [
|
"Super, Space, exec, ${dmsIpcBinds.spotlight}"
|
||||||
"Super, Space, exec, dms ipc call spotlight toggle"
|
"Super, I, exec, ${dmsIpcBinds.settingsFocus}"
|
||||||
"Super, I, exec, dms ipc call settings focusOrToggle"
|
"Super, N, exec, ${dmsIpcBinds.notepad}"
|
||||||
"Super, N, exec, dms ipc call notepad toggle"
|
"ShiftSuper, N, exec, ${dmsIpcBinds.notifications}"
|
||||||
"ShiftSuper, N, exec, dms ipc call notifications toggle"
|
"Super, M, exec, ${dmsIpcBinds.processlistFocus}"
|
||||||
"Super, M, exec, dms ipc call processlist focusOrToggle"
|
"Super, L, exec, ${dmsIpcBinds.lock}"
|
||||||
"Super, L, exec, dms ipc call lock lock"
|
"ShiftSuper, V, exec, ${dmsIpcBinds.clipboard}"
|
||||||
"ShiftSuper, V, exec, dms ipc call clipboard toggle"
|
] ++ [
|
||||||
]
|
|
||||||
++ [
|
|
||||||
"Super, Tab, cyclenext"
|
"Super, Tab, cyclenext"
|
||||||
"Super, Tab, bringactivetotop"
|
"Super, Tab, bringactivetotop"
|
||||||
"Super, left, movefocus, l"
|
"Super, left, movefocus, l"
|
||||||
|
|||||||
@@ -101,7 +101,10 @@
|
|||||||
"sleep 1 && hyprctl reload"
|
"sleep 1 && hyprctl reload"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
(self.lib.hyprlandBinds { inherit lib dmsEnabled; })
|
(self.lib.hyprlandBinds {
|
||||||
|
inherit lib dmsEnabled;
|
||||||
|
dmsIpcBinds = self.lib.dmsIpcBinds;
|
||||||
|
})
|
||||||
{
|
{
|
||||||
decoration = {
|
decoration = {
|
||||||
rounding = 10;
|
rounding = 10;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{ ... }: {
|
{ ... }: {
|
||||||
flake.lib.niriBinds =
|
flake.lib.niriBinds =
|
||||||
{ pkgs, dmsEnabled ? false }:
|
{ pkgs, dmsEnabled ? false, dmsIpcBinds }:
|
||||||
let
|
let
|
||||||
lib = pkgs.lib;
|
lib = pkgs.lib;
|
||||||
in
|
in
|
||||||
@@ -12,16 +12,16 @@
|
|||||||
"Mod+E"."spawn-sh" = "nemo";
|
"Mod+E"."spawn-sh" = "nemo";
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs dmsEnabled {
|
// lib.optionalAttrs dmsEnabled {
|
||||||
"Mod+Space"."spawn-sh" = "dms ipc call spotlight toggle";
|
"Mod+Space"."spawn-sh" = dmsIpcBinds.spotlight;
|
||||||
"Mod+V"."spawn-sh" = "dms ipc call clipboard toggle";
|
"Mod+V"."spawn-sh" = dmsIpcBinds.clipboard;
|
||||||
"Mod+N"."spawn-sh" = "dms ipc call notepad toggle";
|
"Mod+N"."spawn-sh" = dmsIpcBinds.notepad;
|
||||||
"Mod+Shift+N"."spawn-sh" = "dms ipc call notifications toggle";
|
"Mod+Shift+N"."spawn-sh" = dmsIpcBinds.notifications;
|
||||||
"Mod+M"."spawn-sh" = "dms ipc call processlist toggle";
|
"Mod+M"."spawn-sh" = dmsIpcBinds.processlist;
|
||||||
"Mod+B"."spawn-sh" = ''dms ipc call bar toggle name "Main Bar"; dms ipc call bar toggle name "Bar 2"'';
|
"Mod+B"."spawn-sh" = dmsIpcBinds.barToggle;
|
||||||
"Mod+Shift+B"."spawn-sh" = ''dms ipc call bar toggle name "Bar 2"'';
|
"Mod+Shift+B"."spawn-sh" = dmsIpcBinds.barToggleBar2;
|
||||||
"Mod+A"."spawn-sh" = "dms ipc call ephemera toggle";
|
"Mod+A"."spawn-sh" = dmsIpcBinds.ephemera;
|
||||||
"Mod+numbersign"."spawn-sh" = "dms ipc call wallpaperCarousel toggle";
|
"Mod+numbersign"."spawn-sh" = dmsIpcBinds.wallpaperCarousel;
|
||||||
"Mod+L"."spawn-sh" = "dms ipc call lock lock";
|
"Mod+L"."spawn-sh" = dmsIpcBinds.lock;
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
"Mod+Q"."close-window" = _: { };
|
"Mod+Q"."close-window" = _: { };
|
||||||
|
|||||||
@@ -21,7 +21,10 @@
|
|||||||
niriBaseSettings =
|
niriBaseSettings =
|
||||||
pkgs: dmsEnabled:
|
pkgs: dmsEnabled:
|
||||||
self.lib.niriBaseSettings pkgs // {
|
self.lib.niriBaseSettings pkgs // {
|
||||||
binds = self.lib.niriBinds { inherit pkgs dmsEnabled; };
|
binds = self.lib.niriBinds {
|
||||||
|
inherit pkgs dmsEnabled;
|
||||||
|
dmsIpcBinds = self.lib.dmsIpcBinds;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
mergeNiriSettings =
|
mergeNiriSettings =
|
||||||
|
|||||||
@@ -124,31 +124,64 @@ let
|
|||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
thirdPartyPlugins = {
|
# Plugin registry auto-derived from flake inputs matching `dms-plugin-*`.
|
||||||
dankVault = inputs.dms-plugin-dank-vault;
|
# Adding a plugin now requires editing only `flake.nix`. The on-disk
|
||||||
calculator = inputs.dms-plugin-calculator;
|
# plugin id (= path under ~/.config/DankMaterialShell/plugins/) is camelCase
|
||||||
homeAssistantMonitor = inputs.dms-plugin-home-assistant;
|
# per upstream convention; the kebab→camel transform matches it. The
|
||||||
dropdownMenu = inputs.dms-plugin-dropdown-menu;
|
# `idExceptions` map carries the one plugin whose manifest id does not
|
||||||
ocrScanner = inputs.dms-plugin-ocr-scanner;
|
# follow the default rule.
|
||||||
unifiedTaskbar = inputs.dms-plugin-unified-taskbar;
|
pluginInputs = lib.filterAttrs (n: _: lib.hasPrefix "dms-plugin-" n) inputs;
|
||||||
widgetGroup = inputs.dms-plugin-widget-group;
|
|
||||||
nixPackageRunner = inputs.dms-plugin-nix-package-runner;
|
# `dank-vault` → `dankVault`. `lib.splitString` yields ≥ 1 element so
|
||||||
ambientSound = inputs.dms-plugin-ambient-sound;
|
# `head parts` is safe; `map` runs over the tail only (no-op for
|
||||||
cavaVisualizer = inputs.dms-plugin-cava-visualizer;
|
# single-word names like `calculator`). `builtins.substring 1 (-1) p`
|
||||||
emojiLauncher = inputs.dms-plugin-emoji-launcher;
|
# returns the rest of `p` from index 1, dropping the first char
|
||||||
|
# (Nix treats a negative `len` as "rest of string from `start`").
|
||||||
|
toCamel = s:
|
||||||
|
let parts = lib.splitString "-" s; in
|
||||||
|
builtins.head parts
|
||||||
|
+ lib.concatStrings (map (
|
||||||
|
p: if p == "" then ""
|
||||||
|
else lib.toUpper (builtins.substring 0 1 p)
|
||||||
|
+ builtins.substring 1 (-1) p
|
||||||
|
) (builtins.tail parts));
|
||||||
|
|
||||||
|
# The `home-assistant` plugin ships its manifest under id
|
||||||
|
# `homeAssistantMonitor` (not the default kebab→camel result).
|
||||||
|
idExceptions = { "home-assistant" = "homeAssistantMonitor"; };
|
||||||
|
|
||||||
|
# NB: don't rewrite as `idExceptions.${stripped} or toCamel stripped`.
|
||||||
|
# Nix grammar: `or` binds tighter than function application, so the
|
||||||
|
# `toCamel` and its arg parse as separate postfix args to the select.
|
||||||
|
# When the lookup succeeds the resolved string is then applied as a
|
||||||
|
# function, producing `attempt to call something which is not a function
|
||||||
|
# but a string: "homeAssistantMonitor"`. Explicit `if/hasAttr` sidesteps
|
||||||
|
# the parse entirely.
|
||||||
|
camelMap = lib.mapAttrs' (n: src:
|
||||||
|
let stripped = lib.removePrefix "dms-plugin-" n; in
|
||||||
|
lib.nameValuePair
|
||||||
|
(if builtins.hasAttr stripped idExceptions
|
||||||
|
then idExceptions.${stripped}
|
||||||
|
else toCamel stripped)
|
||||||
|
src
|
||||||
|
) pluginInputs;
|
||||||
|
|
||||||
|
# The official plugin pack bundles multiple QML apps. Ship only the
|
||||||
|
# DankDesktopWeather subdir (verified by its manifest) to slim closure
|
||||||
|
# and avoid overlapping with future dedicated `dms-plugin-*` flakes.
|
||||||
|
thirdPartyPlugins =
|
||||||
|
builtins.removeAttrs camelMap [ "official" ] // {
|
||||||
dankDesktopWeather = inputs.dms-plugin-official + "/DankDesktopWeather";
|
dankDesktopWeather = inputs.dms-plugin-official + "/DankDesktopWeather";
|
||||||
webSearch = inputs.dms-plugin-web-search;
|
|
||||||
wallpaperCarousel = inputs.dms-plugin-wallpaper-carousel;
|
|
||||||
ephemera = inputs.dms-plugin-ephemera;
|
|
||||||
appShortcut = inputs.dms-plugin-app-shortcut;
|
|
||||||
wvkbdToggle = inputs.dms-plugin-wvkbd-toggle;
|
|
||||||
rbwLockToggle = inputs.dms-plugin-rbw-lock-toggle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
shipPlugin =
|
# DMS reads plugins from ~/.config/DankMaterialShell/plugins/<id>/, so
|
||||||
_id: src:
|
# we route each plugin source there via HM's `xdg.configFile.target`.
|
||||||
{
|
# The attrset name is scoped under `dms-plugin-${id}` (not the bare
|
||||||
|
# camelCase id) so unrelated HM modules can ship a same-named file
|
||||||
|
# (e.g. `xdg.configFile.calculator`) without colliding with us.
|
||||||
|
shipPlugin = id: src: {
|
||||||
source = src;
|
source = src;
|
||||||
|
target = "DankMaterialShell/plugins/${id}";
|
||||||
onChange = "${dmsRestartOnceScript}";
|
onChange = "${dmsRestartOnceScript}";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
@@ -160,7 +193,8 @@ in
|
|||||||
|
|
||||||
config = lib.mkIf dmsEnabled (lib.mkMerge [
|
config = lib.mkIf dmsEnabled (lib.mkMerge [
|
||||||
(lib.mkIf (dmsOs.bundleThirdPartyPlugins or true) {
|
(lib.mkIf (dmsOs.bundleThirdPartyPlugins or true) {
|
||||||
xdg.configFile = lib.mapAttrs (_id: src: shipPlugin _id src) thirdPartyPlugins;
|
xdg.configFile = lib.mapAttrs' (id: src: lib.nameValuePair
|
||||||
|
"dms-plugin-${id}" (shipPlugin id src)) thirdPartyPlugins;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
programs.nix-monitor = {
|
programs.nix-monitor = {
|
||||||
@@ -203,10 +237,23 @@ in
|
|||||||
enableDynamicTheming = true;
|
enableDynamicTheming = true;
|
||||||
enableAudioWavelength = true;
|
enableAudioWavelength = true;
|
||||||
enableCalendarEvents = false;
|
enableCalendarEvents = false;
|
||||||
|
# Empty on purpose: DMS owns ~/.config/DankMaterialShell/{settings,session}.json
|
||||||
|
# at runtime (seeded by `home.activation.dmsSeedConfig`). Setting these
|
||||||
|
# to non-empty here would clobber the runtime seed on every activation.
|
||||||
settings = { };
|
settings = { };
|
||||||
session = { };
|
session = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Surface bad obsidianVaults paths at build time instead of at first matugen run.
|
||||||
|
# Each entry must point at the `<vault>/.obsidian` dir (matugen writes
|
||||||
|
# `<vault>/.obsidian/snippets/matugen.css` from there).
|
||||||
|
assertions = lib.mkIf ((dmsOs.obsidianVaults or [ ]) != [ ]) [
|
||||||
|
{
|
||||||
|
assertion = builtins.all (v: lib.hasSuffix "/.obsidian" v) (dmsOs.obsidianVaults or [ ]);
|
||||||
|
message = "chiasson.desktop.shells.dms.obsidianVaults entries must end in '/.obsidian' (matugen writes <vault>/.obsidian/snippets/matugen.css). Example: /home/olivier/Documents/HomeLab/.obsidian";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
home.activation.dmsSeedConfig = lib.hm.dag.entryAfter [ "writeBoundary" ] "${dmsSeedConfigScript}";
|
home.activation.dmsSeedConfig = lib.hm.dag.entryAfter [ "writeBoundary" ] "${dmsSeedConfigScript}";
|
||||||
|
|
||||||
systemd.user.services.dms.serviceConfig.ExecStartPre =
|
systemd.user.services.dms.serviceConfig.ExecStartPre =
|
||||||
|
|||||||
@@ -46,4 +46,25 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
flake.homeManagerModules.desktopShellDms = import ./_private/hm.nix;
|
flake.homeManagerModules.desktopShellDms = import ./_private/hm.nix;
|
||||||
|
|
||||||
|
# DMS IPC commands shared between Niri and Hyprland keybind tables.
|
||||||
|
# Defines flake.lib.dmsIpcBinds so each compositor formats the same
|
||||||
|
# command string in its native shape — Niri attrs vs Hyprland string-list.
|
||||||
|
# Adding a new DMS keybind requires editing this file plus the
|
||||||
|
# per-compositor bind layout, not the command string.
|
||||||
|
flake.lib.dmsIpcBinds = {
|
||||||
|
spotlight = "dms ipc call spotlight toggle";
|
||||||
|
clipboard = "dms ipc call clipboard toggle";
|
||||||
|
notepad = "dms ipc call notepad toggle";
|
||||||
|
notifications = "dms ipc call notifications toggle";
|
||||||
|
processlist = "dms ipc call processlist toggle";
|
||||||
|
# Hyprland prefers focusOrToggle (window-aware); niri subscribes to toggle.
|
||||||
|
processlistFocus = "dms ipc call processlist focusOrToggle";
|
||||||
|
settingsFocus = "dms ipc call settings focusOrToggle";
|
||||||
|
barToggle = ''dms ipc call bar toggle name "Main Bar"; dms ipc call bar toggle name "Bar 2"'';
|
||||||
|
barToggleBar2 = ''dms ipc call bar toggle name "Bar 2"'';
|
||||||
|
ephemera = "dms ipc call ephemera toggle";
|
||||||
|
wallpaperCarousel = "dms ipc call wallpaperCarousel toggle";
|
||||||
|
lock = "dms ipc call lock lock";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,6 +486,10 @@
|
|||||||
{
|
{
|
||||||
"name": "DP-3",
|
"name": "DP-3",
|
||||||
"model": "34GL750"
|
"model": "34GL750"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Virtual-1",
|
||||||
|
"model": "Virtual-1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"showOnLastDisplay": false,
|
"showOnLastDisplay": false,
|
||||||
|
|||||||
Reference in New Issue
Block a user