Compare commits

..
9 Commits
Author SHA1 Message Date
Sweetbread 1f692e1d1e fix: Play WebM in Vivaldi 2026-11-13 00:06:31 +03:00
Sweetbread dccab8e54f Install lucid 2026-11-13 00:06:31 +03:00
Chest 72c85c59ff Theme Eclipse desktop with Miku Frost palette and glass surfaces 2026-11-13 00:06:31 +03:00
Chest d414b3fe6a delete launchers 2026-11-13 00:06:31 +03:00
Sweetbread 2b3dd38316 Show frequency used apps first in walker 2026-11-13 00:06:31 +03:00
Sweetbread 52f14780a4 Stylize walker 2026-11-13 00:06:31 +03:00
Sweetbread 433266c33c Change monitor resolution for Eclipse 2026-11-13 00:06:30 +03:00
Sweetbread 357458c063 Switch timezone 2026-11-13 00:06:30 +03:00
Sweetbread e3e426c3f4 Update 2026-11-13 00:06:30 +03:00
33 changed files with 1784 additions and 137 deletions

No files matched your search

+4
View File
@@ -0,0 +1,4 @@
{ ... }:
{
lucid.liveDecoder = "cuda";
}
+9
View File
@@ -0,0 +1,9 @@
{ config, ... }:
{
lucid.prefsSeed = ./lucid-prefs-impreza.json;
lucid.widgetSeed = ./lucid-widgets-impreza.json;
lucid.initialFiles = {
"${config.home.homeDirectory}/.config/hypr/lucid-settings.lua" = ./lucid-settings-impreza.lua;
"${config.home.homeDirectory}/.config/hypr/lucid-glass.lua" = ./lucid-glass-impreza.lua;
};
}
@@ -0,0 +1,8 @@
-- written by Lucid Settings > Glass, and rewritten on every change there
return {
apps = {
{ name = "VSCodium", class = { "codium", "vscodium" }, opacity = 0.90 },
{ name = "Obsidian", class = { "obsidian" }, opacity = 0.88 },
{ name = "Files", class = { "org.gnome.nautilus", "nautilus" }, opacity = 0.80 },
},
}
@@ -0,0 +1,337 @@
{
"accentPunch": 1.05,
"audioCombine": "",
"audioMeters": true,
"audioMoveStreams": true,
"autoColorMode": false,
"barAutoHide": false,
"barEnabled": true,
"barFullCorner": 18,
"barHeight": 40,
"barHoverGrow": 3,
"barHoverOpen": false,
"barJoinDividers": true,
"barJoins": "[\"workspaces+tray\"]",
"barLayout": "{\"left\":[\"start\",\"workspaces\",\"tray\",\"media\"],\"center\":[\"clock\"],\"right\":[\"window\",\"notifications\",\"system\",\"privacy\",\"power\"]}",
"barMotionScale": 1.2000000000000002,
"barNotchFlare": 20,
"barPopupGap": 10,
"barPopupMode": false,
"barPopupNotched": false,
"barSideMargin": 0,
"barSpacing": 11,
"barStyle": "notch",
"barTopMargin": 22,
"barZoneGap": 28,
"btAgent": true,
"btReceive": true,
"btReceiveAutoPaired": false,
"btScanOnOpen": true,
"btShowUnnamed": false,
"clipboardEnabled": true,
"clock24h": true,
"clockDateFormat": "long",
"clockShowDate": true,
"clockShowSeconds": true,
"clockShowTimer": true,
"clockShowWeather": true,
"clockStyle": "accent",
"clockWorldZones": "Europe/Berlin,Europe/Moscow,America/New_York",
"cornerScale": 0.5,
"desktopIconSize": "medium",
"desktopIconSpacing": "normal",
"desktopIcons": false,
"desktopIconsAutoArrange": false,
"desktopIconsCorner": "left",
"desktopIconsDrives": true,
"desktopIconsHidden": false,
"desktopIconsHideExt": false,
"desktopIconsHome": false,
"desktopIconsOpen": "double",
"desktopIconsShown": true,
"desktopIconsSort": "name",
"desktopIconsSortDesc": false,
"desktopIconsSpring": true,
"desktopIconsThumbs": true,
"desktopIconsTrash": true,
"desktopKeys": "{}",
"desktopMenu": true,
"desktopSelection": true,
"dndAllowCritical": true,
"dndFullscreen": false,
"doNotDisturb": false,
"dockAutoHide": true,
"dockBottomMargin": 13,
"dockDynamicHide": true,
"dockEnabled": true,
"dockHoverEffect": 1,
"dockIconPadding": 0,
"dockIconSize": 37,
"dockIconTiles": true,
"dockMagnify": false,
"dockNotchFlare": 25,
"dockRadius": 40,
"dockShowIndicators": true,
"dockShowRunning": true,
"dockShowTooltips": true,
"dockSpacing": 10,
"dockSplitGap": 8,
"dockStyle": "notch",
"envAdopted": true,
"envAppFont": "DejaVu Sans",
"envAppFontSize": 13,
"envApplyGtk": true,
"envApplyHypr": true,
"envApplyQt": true,
"envColorScheme": "auto",
"envCursorShadow": true,
"envCursorSize": 16,
"envCursorTheme": "Miku",
"envDocumentFont": "DejaVu Sans",
"envDocumentFontSize": 13,
"envFontSync": false,
"envGtkTheme": "adw-gtk3",
"envIconSet": "gravity",
"envIconTheme": "Pop-Dark",
"envLegacyIcons": false,
"envMonoFont": "JetBrains Mono",
"envMonoFontSize": 13,
"envQtPlatformTheme": "",
"envQtStyle": "kvantum",
"fontFamily": "DejaVu Sans",
"fontScale": 1,
"gameModeOffCmd": "",
"gameModeOnCmd": "",
"gameModeStatusCmd": "",
"glassApps": "vscodium,obsidian,nautilus",
"glassValues": "nautilus=0.8,vscodium=0.9",
"gpsEnabled": false,
"hiddenThemes": "",
"hyprOptions": "{\"general.border_size\":1,\"general.gaps_in\":2,\"decoration.dim_strength\":0.55,\"dwindle.split_width_multiplier\":1.1}",
"idleAdopted": false,
"idleAutostart": true,
"idleDim": true,
"idleDimAfter": 120,
"idleDimKeyboard": true,
"idleDimLevel": 10,
"idleEnabled": false,
"idleKeepAwake": false,
"idleLock": false,
"idleLockAfter": 600,
"idleLockBeforeSleep": false,
"idleRespectInhibitors": true,
"idleScreenOff": true,
"idleScreenOffAfter": 900,
"idleSuspend": false,
"idleSuspendAfter": 1800,
"idleSuspendOnAc": false,
"idleWakeAfterSleep": true,
"idleWhileMedia": true,
"jellyAmount": 0.75,
"jellyMotion": true,
"kdeConnectEnabled": true,
"launcherActionHints": true,
"launcherAddressFirst": true,
"launcherAppActions": true,
"launcherAppDescriptions": false,
"launcherCalculator": true,
"launcherContentScale": 0.8,
"launcherDensity": "comfortable",
"launcherFrequentFirst": true,
"launcherHiddenApps": "",
"launcherModeBar": true,
"launcherPowerButtons": "suspend,reboot,shutdown",
"launcherPowerChips": true,
"launcherPowerSearch": true,
"launcherSearchEngine": "google",
"launcherSearchPosition": "bottom",
"launcherSettingsResults": true,
"launcherWebRow": true,
"launcherWidth": "standard",
"launcherWindows": true,
"liveGameMode": "pause",
"livePauseUnder": "fullscreen",
"liveWallpapers": false,
"locationLabel": "",
"locationLat": 52.4083,
"locationLon": 16.9336,
"locationName": "",
"locationTz": "",
"matugenContrast": 0,
"matugenScheme": "scheme-tonal-spot",
"matugenSourceImage": "",
"matugenSourceIndex": 0,
"mediaArtist": true,
"mediaHideIdle": true,
"mediaPanelStyle": "side",
"mediaPlayButton": true,
"mediaStyle": "disc",
"mediaTitleWidth": 210,
"mediaWheelVolume": true,
"motionScale": 1,
"nightLight": false,
"nightLightFrom": 1260,
"nightLightSchedule": "off",
"nightLightTemp": 4600,
"nightLightTo": 420,
"notifGrouping": true,
"notifInlineReply": true,
"notifMaxHistory": 50,
"notifMutedApps": "",
"notifProgress": true,
"notifSeenApps": "",
"notifShowIcons": true,
"notifSound": false,
"notifSoundName": "glint",
"notifSoundUrgentOnly": false,
"notifSoundVolume": 0.6,
"notifTimestamps": true,
"notificationsStyle": "badge",
"osdCapsLock": true,
"osdNumLock": true,
"pinBadge": "top-right",
"pinBorder": "gradient",
"pinPulse": true,
"pomodoroAutoFocus": true,
"pomodoroAutoStart": true,
"pomodoroFocus": 25,
"pomodoroGoal": 0,
"pomodoroLong": 15,
"pomodoroRepeat": true,
"pomodoroRounds": 4,
"pomodoroShort": 5,
"pomodoroSilence": false,
"powerModuleActions": "suspend,hibernate,logout,reboot,shutdown",
"powerModuleConfirm": true,
"powerModulePanelStyle": "list",
"powerModuleStyle": "icon",
"powerModuleUptime": true,
"privacyAlwaysShown": false,
"privacyStyle": "marks",
"privacyToast": true,
"privacyWatch": "mic,camera,screen",
"quietFrom": 1320,
"quietHours": false,
"quietTo": 420,
"recordCountdown": 3,
"recordEncoder": "auto",
"recordFps": 0,
"reminderSound": true,
"shellGap": 5,
"shotLoupe": true,
"shotOcrLang": "eng+rus",
"shotPreview": "preview",
"shotPreviewSeconds": 6,
"shotRoundWindows": true,
"shotSaveFile": false,
"showClock": true,
"showKbLayout": true,
"showMedia": true,
"showNotifications": true,
"showPower": false,
"showPrivacy": false,
"showStart": false,
"showSystem": true,
"showTray": true,
"showWindow": false,
"showWorkspaces": true,
"soundOnBattery": true,
"soundOnBluetooth": true,
"soundOnBrightness": true,
"soundOnCamera": true,
"soundOnCaps": true,
"soundOnCapture": true,
"soundOnCharger": true,
"soundOnMic": true,
"soundOnUsb": true,
"soundOnVolume": true,
"specialBlur": true,
"specialComms": true,
"specialCommsApps": "vesktop,entry:com.ayugram.desktop",
"specialCustom": "[{\"key\":\"daemons\",\"label\":\"Daemons\",\"glyph\":\"build\",\"on\":true,\"apps\":\"\"}]",
"specialDim": 0.2,
"specialGaps": 0,
"specialHideOnSwitch": false,
"specialKeepApps": true,
"specialMusic": true,
"specialMusicApps": "auto",
"specialScratchpad": true,
"specialSysmon": true,
"specialSysmonApps": "auto",
"specialTodo": true,
"specialTodoApps": "auto",
"startModuleStyle": "logo",
"startupApps": "[]",
"startupEnv": "[]",
"startupXdg": false,
"storageLowPercent": 10,
"storageLowWarn": true,
"storageTrashDays": 0,
"surfaceDarkness": -1,
"surfaceTint": -1,
"sysSoundVolume": 0.6,
"sysSounds": true,
"systemTiles": "dnd,awake,dark,airplane,location,mic,capture,record,picker,keyboard,timer,session",
"themeColour": "#6750a4",
"themeOrder": "",
"timeZoneAuto": true,
"timerSound": true,
"toastBodyLines": 4,
"toastCriticalSticky": true,
"toastEnabled": true,
"toastMaxVisible": 3,
"toastOnAudio": true,
"toastOnBattery": true,
"toastOnBluetooth": true,
"toastOnCamera": true,
"toastOnDisplays": true,
"toastOnGameMode": true,
"toastOnLayout": true,
"toastOnPower": true,
"toastOnUsb": true,
"toastOnWifi": true,
"toastShowActions": true,
"toastShowBody": true,
"toastTimeout": 5,
"toastUseAppTimeout": true,
"trayHidden": "",
"trayIconColor": "original",
"trayStyle": "collapsed",
"uiScale": 1.05,
"units": "metric",
"updateBeta": false,
"updateCheck": true,
"urgentBadge": "bottom-right",
"urgentPulse": true,
"wallTransAngle": 45,
"wallTransBezier": ".54,0,.34,.99",
"wallTransCustomPresets": "",
"wallTransDuration": 1,
"wallTransOrigin": "center",
"wallTransPreset": "soft",
"wallTransType": "fade",
"wallTransWave": "20,20",
"wallpaperBentoHero": "medium",
"wallpaperBentoPrev": true,
"wallpaperPickerKeys": "sides",
"wallpaperPickerStyle": "bento",
"wallpaperPillsShape": "uniform",
"wallpaperStripSides": 2,
"wallpaperStripSteps": "normal",
"wallpaperTilesAspect": "square",
"wallpaperTilesRows": 2,
"weekStartMonday": true,
"widgetHideFullscreen": true,
"widgetLockAll": false,
"widgetOnTop": false,
"widgetSnap": true,
"widgetsEnabled": true,
"windowModuleMiddleClose": false,
"windowModuleScroll": true,
"windowModuleText": "title",
"windowModuleWidth": 260,
"workspacesByDisplay": true,
"workspacesShown": 1,
"workspacesStyle": "numbers",
"workspacesWheel": false
}
@@ -0,0 +1,10 @@
-- written by Lucid Settings > Windows and Input, and rewritten on every change there
return {
pinned = { border = "rgba(69dcc7ff) rgba(69dcc7ff)", focused = "rgba(69dcc7ff) rgba(43d6cdff) 45deg", size = 2 },
options = {
["decoration.dim_strength"] = 0.55,
["dwindle.split_width_multiplier"] = 1.1,
["general.border_size"] = 1,
["general.gaps_in"] = 2,
},
}
@@ -0,0 +1,145 @@
{
"nextId": 11,
"boardFull": true,
"laidScale": 1.05,
"preset": "",
"saved": [],
"last": [],
"stash": [],
"instances": [
{
"uid": "w1",
"type": "system",
"variant": "compact",
"wx": 42,
"wy": 773,
"bw": 300,
"bh": 80,
"pinned": false,
"zoom": 1,
"zOrder": 46,
"screenName": "",
"opts": {
"showCpu": true,
"showRam": true,
"showDisk": true,
"showTemp": false,
"showGpu": false,
"interval": "2",
"tone": "auto"
}
},
{
"uid": "w2",
"type": "media",
"variant": "card",
"wx": 2218,
"wy": 137,
"bw": 288,
"bh": 435,
"pinned": false,
"zoom": 1,
"zOrder": 52,
"screenName": "",
"opts": {
"artTint": true,
"showProgress": true,
"scroll": true,
"tone": "auto"
}
},
{
"uid": "w3",
"type": "weather",
"variant": "forecast",
"wx": 32,
"wy": 137,
"bw": 320,
"bh": 232,
"pinned": false,
"zoom": 1,
"zOrder": 49,
"screenName": "",
"opts": {
"tone": "surface"
}
},
{
"uid": "w4",
"type": "kdeconnect",
"variant": "remote",
"wx": 2211,
"wy": 927,
"bw": 300,
"bh": 214,
"pinned": false,
"zoom": 1,
"zOrder": 51,
"screenName": "",
"opts": {
"showShare": true,
"showRing": true,
"showClipboard": true,
"showBrowse": true,
"deviceId": "",
"tone": "auto"
}
},
{
"uid": "w8",
"type": "photo",
"variant": "frame",
"wx": 56,
"wy": 443,
"bw": 300,
"bh": 220,
"pinned": false,
"zoom": 1,
"zOrder": 48,
"screenName": "",
"opts": {
"source": "pictures",
"every": "60",
"shape": "circle",
"showDate": false,
"tone": "auto"
}
},
{
"uid": "w9",
"type": "photo",
"variant": "shape",
"wx": 2253,
"wy": 640,
"bw": 220,
"bh": 220,
"pinned": false,
"zoom": 1,
"zOrder": 53,
"screenName": "",
"opts": {
"source": "pictures",
"every": "15",
"shape": "cookie12",
"showDate": true,
"tone": "auto"
}
},
{
"uid": "w10",
"type": "fetch",
"variant": "card",
"wx": 26,
"wy": 927,
"bw": 330,
"bh": 344,
"pinned": false,
"zoom": 1,
"zOrder": 47,
"screenName": "",
"opts": {
"tone": "auto"
}
}
]
}
-3
View File
@@ -25,9 +25,6 @@
];
programs.gamemode.enable = true;
programs.kdeconnect.enable = true;
home-manager.users.sweetbread.services.kdeconnect.enable = true;
services.printing.enable = true;
hardware.opentabletdriver.enable = true;
+21
View File
@@ -0,0 +1,21 @@
{ config, lib, ... }:
{
lucid.widgetSeed = ./lucid-widgets-rias.json;
lucid.liveDecoder = "cuda";
lucid.bindsModule = lib.mkDefault "${config.lucid.upstreamSource}/support/hypr/modules/binds.lua";
lucid.luaModules = {
"modules/decorations.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/decorations.lua";
"modules/gestures.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/gestures.lua";
"modules/input.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/input.lua";
"modules/layout.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/layout.lua";
"modules/layerrules.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/layerrules.lua";
"modules/lumen.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/lumen.lua";
"modules/misc.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/misc.lua";
"modules/plugins.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/plugins.lua";
"modules/windowrules.lua" = "${config.lucid.upstreamSource}/support/hypr/modules/windowrules.lua";
"modules/monitors.lua" = { content = "${config.lucid.upstreamSource}/support/hypr/modules/monitors.lua"; autoLoad = false; };
"modules/glass.lua" = { content = "${config.lucid.upstreamSource}/support/hypr/modules/glass.lua"; autoLoad = false; };
"modules/settings.lua" = { content = "${config.lucid.upstreamSource}/support/hypr/modules/settings.lua"; autoLoad = false; };
"modules/startup.lua" = { content = "${config.lucid.upstreamSource}/support/hypr/modules/startup.lua"; autoLoad = false; };
};
}
+16 -3
View File
@@ -28,6 +28,13 @@ in {
optImport ../../host/${hostname}/modules/hyprland.nix ++
optImport ../../user/${username}/modules/hyprland.nix;
options.lucidHyprlandBinds = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
default = [];
internal = true;
};
config = {
home.packages = with pkgs; [
ghostty
pamixer
@@ -36,6 +43,8 @@ in {
wl-clipboard
wl-clip-persist
xclip
rbw
wtype
awww
wifitui
];
@@ -119,6 +128,7 @@ in {
workspace_rule = [
{
workspace = "w[t1]";
gaps_in = 0;
gaps_out = 0;
}
];
@@ -154,8 +164,13 @@ in {
])
];
bind = [
bind = lib.mkIf (username != "chest") config.lucidHyprlandBinds;
};
};
lucidHyprlandBinds = [
(bind "SUPER + V" (exec "ghostty --title=clipse -e clipse"))
(bind "SUPER + X" (exec "qs ipc call -- launcher search '>vault'"))
(hyprLua.bind "SUPER + SHIFT + V" (hyprLua.execLauncher "qs ipc call launcher clipboard"))
(bind "Print" (exec "qs ipc call screenshot full"))
(bind "SUPER + Print" (exec "qs ipc call screenshot full"))
@@ -213,7 +228,5 @@ in {
(bindWithFlags "SUPER + mouse:272" "hl.dsp.window.drag()" { mouse = true; })
(bindWithFlags "SUPER + mouse:273" "hl.dsp.window.resize()" { mouse = true; })
];
};
};
}
+1 -1
View File
@@ -17,7 +17,7 @@ let
hl.config({ cursor = { zoom_factor = math.max(1, current * 0.9) } })
end'';
in {
wayland.windowManager.hyprland.settings.bind = [
lucidHyprlandBinds = [
(bind "SUPER + SHIFT + mouse_up" resetZoom)
(bind "SUPER + SHIFT + mouse_down" resetZoom)
(bind "SUPER + SHIFT + minus" resetZoom)
+129
View File
@@ -0,0 +1,129 @@
import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
pragma Singleton
Singleton {
id: root
property var entries: []
property bool loading: false
property string error: ""
property string targetAddress: ""
property string pendingPassword: ""
property var passwordProcess: null
signal passwordReady(string password, string targetAddress)
function refresh() {
if (listReader.running)
return;
root.loading = true;
root.error = "";
listReader.command = ["rbw", "list", "--fields", "id,name,user,folder"];
listReader.running = true;
}
function getPassword(id, target) {
if (root.passwordProcess)
return;
root.targetAddress = target || "";
root.error = "";
root.passwordProcess = passwordProcessComponent.createObject(root, { entryId: id });
if (!root.passwordProcess) {
root.error = "Could not start rbw.";
return;
}
root.passwordProcess.running = true;
}
function typePassword(password, target) {
root.pendingPassword = password;
root.targetAddress = target || "";
typeDelay.restart();
}
Process {
id: listReader
command: []
stdout: StdioCollector {
id: listOutput
}
onExited: (code) => {
root.loading = false;
if (code !== 0) {
root.error = "Could not read the vault. Unlock it with rbw, then retry.";
root.entries = [];
return;
}
root.entries = listOutput.text.split(/\r?\n/).filter((line) => line !== "").map((line) => {
const fields = line.split("\t");
return {
id: fields[0] || "",
name: fields[1] || "Untitled",
user: fields[2] || "",
folder: fields[3] || ""
};
}).filter((entry) => entry.id !== "");
root.error = "";
}
}
Component {
id: passwordProcessComponent
Process {
id: passwordJob
property string entryId: ""
command: ["rbw", "get", entryId]
stdout: StdioCollector {
id: passwordOutput
}
onExited: (code) => {
if (root.passwordProcess === passwordJob)
root.passwordProcess = null;
if (code !== 0) {
root.error = "Could not read that password.";
} else {
root.passwordReady(passwordOutput.text.replace(/\r?\n$/, ""), root.targetAddress);
}
passwordJob.destroy();
}
}
}
Process {
id: typer
command: ["wtype", "-"]
stdinEnabled: true
onStarted: {
write(root.pendingPassword);
stdinEnabled = false;
root.pendingPassword = "";
root.targetAddress = "";
}
}
Timer {
id: typeDelay
interval: 260
onTriggered: {
if (root.targetAddress !== "")
Hyprland.dispatch("focuswindow address:" + root.targetAddress);
typer.running = false;
typer.stdinEnabled = true;
typer.running = true;
}
}
}
@@ -1,9 +1,176 @@
{ config, lib, osConfig, pkgs, ... }:
{ config, lib, pkgs, ... }:
let
host = osConfig.networking.hostName;
isRias = host == "Rias";
liveDecoder = if builtins.elem osConfig.networking.hostName [ "Rias" "Eclipse" ] then "cuda" else "vaapi";
source = pkgs.applyPatches {
staticBindKeys = map (entry: builtins.elemAt entry._args 0) config.wayland.windowManager.hyprland.settings.bind;
nonRiasBinds = pkgs.runCommand "lucid-nix-binds.lua" { nativeBuildInputs = [ pkgs.python3 ]; } ''
python3 - ${source}/support/hypr/modules/binds.lua "$out" ${lib.escapeShellArg (builtins.toJSON staticBindKeys)} <<'PY'
import json
import pathlib
import sys
source = pathlib.Path(sys.argv[1]).read_text()
keys = json.loads(sys.argv[3])
lua_keys = "{ " + ", ".join(json.dumps(key, ensure_ascii=True) for key in keys) + " }"
guard = r"""
local function normalize_nix_bind(keys)
local mods, key = {}, ""
for part in tostring(keys or ""):gmatch("[^+]+") do
local token = (part:match("^%s*(.-)%s*$") or ""):upper()
if token == "CONTROL" then token = "CTRL" end
if token == "WIN" or token == "LOGO" or token == "MOD4" then token = "SUPER" end
if token == "SUPER" or token == "CTRL" or token == "ALT" or token == "SHIFT" then
mods[token] = true
else
key = token
end
end
local out = {}
for _, mod in ipairs({"ALT", "CTRL", "SHIFT", "SUPER"}) do
if mods[mod] then out[#out + 1] = mod end
end
return table.concat(out, "+") .. "+" .. key
end
local nix_binds = {}
for _, key in ipairs(NIX_BIND_KEYS) do nix_binds[normalize_nix_bind(key)] = true end
""".replace("NIX_BIND_KEYS", lua_keys)
marker = "-- several dispatchers on one key, in order"
binding = ' if type(keys) ~= "string" or keys == "" then error("no keys", 0) end'
fallback = ' for _, entry in ipairs(EMERGENCY) do apply(entry) end'
fallback_source = ' status.source = "emergency"'
fallback_text = 'Emergency binds are active - SUPER+S opens Settings.'
for needle in (marker, binding, fallback, fallback_source, fallback_text):
if source.count(needle) != 1:
raise SystemExit("Lucid bind loader changed; refusing to skip conflict protection")
source = source.replace(marker, guard + "\n" + marker, 1)
source = source.replace(binding, binding + '\n if nix_binds[normalize_nix_bind(keys)] then error("Already bound by Nix: " .. keys, 0) end', 1)
source = source.replace(fallback, ' -- Nix supplies the fallback keys on these hosts.', 1)
source = source.replace(fallback_source, ' status.source = "nix"', 1)
source = source.replace(fallback_text, 'Nix bindings remain active.', 1)
pathlib.Path(sys.argv[2]).write_text(source)
PY
'';
vaultwardenLauncherPatch = pkgs.writeText "lucid-vaultwarden-launcher.py" ''
import pathlib
import sys
face_path, dock_path = map(pathlib.Path, sys.argv[1:])
face = face_path.read_text()
dock = dock_path.read_text()
def replace_once(source, old, new, label):
count = source.count(old)
if count != 1:
raise SystemExit(f"Lucid {label} anchor changed (found {count}); refusing an unsafe launcher patch")
return source.replace(old, new, 1)
face = replace_once(face,
' "clipboard": "Search clipboard history",\n',
' "clipboard": "Search clipboard history",\n "vaultwarden": "Search Vaultwarden",\n', "launcher placeholder")
face = replace_once(face,
' "clipboard": "content_paste",\n',
' "clipboard": "content_paste",\n "vaultwarden": "key",\n', "launcher icon")
face = replace_once(face,
' "icon": "content_paste"\n }, {\n "key": "wallpaper",',
' "icon": "content_paste"\n }, {\n "key": "vaultwarden",\n "label": "Vaultwarden",\n "icon": "key"\n }, {\n "key": "wallpaper",', "launcher mode")
face = replace_once(face,
' emptyLabel: {\n',
' emptyLabel: {\n if (face.displayMode === "vaultwarden")\n return "No matching vault entries";\n', "launcher empty label")
face = replace_once(face,
' emptyHint: {\n',
' emptyHint: {\n if (face.displayMode === "vaultwarden")\n return "Unlock the vault with rbw, then search by name, username, or folder.";\n', "launcher empty hint")
dock = replace_once(dock,
' if (q.indexOf(">clip") === 0)\n return "clipboard";\n',
' if (q.indexOf(">clip") === 0)\n return "clipboard";\n\n if (q.indexOf(">pass") === 0)\n return "vaultwarden";\n', "launcher prefix")
dock = replace_once(dock,
' if (mode === "clipboard")\n return ">clip";\n',
' if (mode === "clipboard")\n return ">clip ";\n\n if (mode === "vaultwarden")\n return ">pass ";\n', "launcher mode prefix")
dock = replace_once(dock,
' if (mode === "wallpaper")\n return ">wallpaper";\n',
' if (mode === "wallpaper")\n return ">wallpaper ";\n', "wallpaper prefix spacing")
dock = replace_once(dock,
' if (mode === "theme")\n return ">theme";\n',
' if (mode === "theme")\n return ">theme ";\n', "theme prefix spacing")
dock = replace_once(dock,
' if (mode === "live")\n return ">live";\n',
' if (mode === "live")\n return ">live ";\n', "live prefix spacing")
dock = replace_once(dock,
' if (mode === "commands")\n return ">";\n',
' if (mode === "commands")\n return "> ";\n', "command prefix spacing")
dock = replace_once(dock,
' if (text === ">wallpaper" && !exact && Prefs.liveWallpapers && LiveWall.isVideo(dockWindow.appliedWallpaper))\n text = ">live";\n',
' if (text.trim() === ">wallpaper" && !exact && Prefs.liveWallpapers && LiveWall.isVideo(dockWindow.appliedWallpaper))\n text = ">live ";\n', "wallpaper live prefix spacing")
dock = replace_once(dock,
' dockWindow.setSearchText(">wallpaper");\n } else if (id === "theme") {\n dockWindow.setSearchText(">theme");\n',
' dockWindow.setSearchText(">wallpaper ");\n } else if (id === "theme") {\n dockWindow.setSearchText(">theme ");\n', "menu prefix spacing")
dock = replace_once(dock,
' } else if (id === "clipboard") {\n dockWindow.setSearchText(">clip");\n',
' } else if (id === "clipboard") {\n dockWindow.setSearchText(">clip ");\n', "clipboard prefix spacing")
dock = replace_once(dock,
' dockWindow.setSearchText(">wallpaper", true);',
' dockWindow.setSearchText(">wallpaper ", true);', "wallpaper picker prefix spacing")
dock = replace_once(dock,
'onPickerKindRequested: (kind) => dockWindow.setSearchText(kind === "live" ? ">live" : ">wallpaper", true)',
'onPickerKindRequested: (kind) => dockWindow.setSearchText(kind === "live" ? ">live " : ">wallpaper ", true)', "picker tab prefix spacing")
dock = replace_once(dock,
' dockWindow.openLauncher(">wallpaper");\n }\n\n function live(): void {\n dockWindow.openLauncher(">live");',
' dockWindow.openLauncher(">wallpaper ");\n }\n\n function live(): void {\n dockWindow.openLauncher(">live ");', "wallpaper ipc prefix spacing")
dock = replace_once(dock,
'onBackRequested: dockWindow.setSearchText(dockWindow.mode === "commands" ? "" : ">")',
'onBackRequested: dockWindow.setSearchText(dockWindow.mode === "commands" ? "" : "> ")', "back prefix spacing")
dock = replace_once(dock,
' if (dockWindow.mode === "clipboard")\n Clip.refresh();\n',
' if (dockWindow.mode === "clipboard")\n Clip.refresh();\n if (dockWindow.mode === "vaultwarden")\n Vaultwarden.refresh();\n', "launcher mode activation")
dock = replace_once(dock,
' readonly property var allCommands: [{',
""" Connections {
target: Vaultwarden
function onEntriesChanged() { dockWindow.rebuildResults(); }
function onLoadingChanged() { dockWindow.rebuildResults(); }
function onErrorChanged() { dockWindow.rebuildResults(); }
function onPasswordReady(password, targetAddress) {
dockWindow.menuOpen = false;
Vaultwarden.typePassword(password, targetAddress);
}
}
readonly property var allCommands: [{""", "vaultwarden updates")
dock = replace_once(dock,
' function rebuildResults() {',
""" function vaultRows(query) {
if (Vaultwarden.loading)
return [dockWindow.headerRow("Loading Vaultwarden…")];
if (Vaultwarden.error !== "")
return [dockWindow.headerRow(Vaultwarden.error)];
var rows = [];
var entries = Vaultwarden.entries || [];
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
var haystack = (entry.name + " " + entry.user + " " + entry.folder).toLowerCase();
if (query !== "" && haystack.indexOf(query) === -1)
continue;
var detail = [entry.user, entry.folder].filter((part) => part !== "").join(" · ");
rows.push(dockWindow.makeRow("vaultwarden", "vault-" + entry.id, entry.name, detail, {
"glyph": "key",
"payload": entry.id
}));
}
return rows;
}
function rebuildResults() {""", "vaultwarden search")
dock = replace_once(dock,
' } else if (mode === "clipboard") {\n var ents = Clip.entries;',
' } else if (mode === "vaultwarden") {\n rows = dockWindow.vaultRows(q);\n } else if (mode === "clipboard") {\n var ents = Clip.entries;', "vaultwarden results")
dock = replace_once(dock,
' } else if (row.kind === "clip") {\n Clip.copy(row.payload);\n dockWindow.menuOpen = false;\n',
' } else if (row.kind === "clip") {\n Clip.copy(row.payload);\n dockWindow.menuOpen = false;\n } else if (row.kind === "vaultwarden") {\n Vaultwarden.getPassword(row.payload, Hyprland.activeToplevel ? Hyprland.activeToplevel.address : "");\n', "vaultwarden selection")
face_path.write_text(face)
dock_path.write_text(dock)
'';
baseSource = pkgs.applyPatches {
src = pkgs.fetchgit {
url = "https://github.com/Sn3akyy1/lucid.git";
rev = "bdd7f79da18efd837f79dcecbe5d2ec178abc10c";
@@ -15,7 +182,8 @@ let
];
nonConeMode = true;
};
patches = [ (pkgs.writeText "lucid-scratchpad-target.patch" ''
patches = [
(pkgs.writeText "lucid-scratchpad-target.patch" ''
diff --git a/support/hypr/modules/specials.lua b/support/hypr/modules/specials.lua
--- a/support/hypr/modules/specials.lua
+++ b/support/hypr/modules/specials.lua
@@ -34,15 +202,76 @@ let
+ end
end
end
'') ];
'')
(pkgs.writeText "lucid-nonpersistent-workspaces.patch" ''
diff --git a/support/hypr/modules/gestures.lua b/support/hypr/modules/gestures.lua
--- a/support/hypr/modules/gestures.lua
+++ b/support/hypr/modules/gestures.lua
@@ -6,9 +6,5 @@
hl.gesture({ fingers = 3, direction = "horizontal", action = "workspace" })
hl.gesture({ fingers = 4, direction = "horizontal", action = "workspace" })
--- Pre-create workspaces 1-5 so gesture swipes can always live-track to them
-for i = 1, 6 do
- hl.workspace_rule({ workspace = tostring(i), persistent = true })
-end
-- local function minimize_all()
'')
(pkgs.writeText "lucid-lair-search.patch" ''
--- a/luciddocks/Dock.qml
+++ b/luciddocks/Dock.qml
@@ -683,4 +683,8 @@
readonly property var searchEngines: ({
+ "lair": {
+ "name": "Lair",
+ "url": "https://s.lair.moe/web?s="
+ },
"duckduckgo": {
"name": "DuckDuckGo",
"url": "https://duckduckgo.com/?q="
--- a/lucidprefs/LauncherPage.qml
+++ b/lucidprefs/LauncherPage.qml
@@ -386,5 +386,8 @@
current: Prefs.launcherSearchEngine
options: [{
+ "key": "lair",
+ "label": "Lair"
+ }, {
"key": "duckduckgo",
"label": "DuckDuckGo"
}, {
'')
(pkgs.writeText "lucid-shot-special-workspace-name.patch" ''
diff --git a/lucidshot/ShotOverlay.qml b/lucidshot/ShotOverlay.qml
--- a/lucidshot/ShotOverlay.qml
+++ b/lucidshot/ShotOverlay.qml
@@ -228,1 +228,1 @@
- const ws = mon.activeWorkspace ? mon.activeWorkspace.id : null;
+ const ws = mon.activeWorkspace ? mon.activeWorkspace.name : null;
@@ -229,1 +229,1 @@
- const special = mon.specialWorkspace ? mon.specialWorkspace.id : 0;
+ const special = mon.specialWorkspace ? mon.specialWorkspace.name : "";
@@ -234,1 +234,1 @@
- return c.workspace.id === ws || (special !== 0 && c.workspace.id === special) || (c.pinned && c.monitor === mon.id);
+ return c.workspace.name === ws || (special && c.workspace.name === special) || (c.pinned && c.monitor === mon.id);
@@ -246,1 +246,1 @@
- "special": special !== 0 && c.workspace.id === special,
+ "special": !!special && c.workspace.name === special,
'')
];
};
source = pkgs.runCommand "lucid-vaultwarden-launcher-source" {
nativeBuildInputs = [ pkgs.python3 ];
} ''
cp -r ${baseSource} "$out"
chmod -R u+w "$out"
python3 ${vaultwardenLauncherPatch} "$out/luciddocks/LauncherFace.qml" "$out/luciddocks/Dock.qml"
'';
wallpaperDir = "${config.home.homeDirectory}/Wallpapers";
wallpaperScript = "${config.home.homeDirectory}/.config/hypr/scripts/wallpaper/set-wallpaper.sh";
widgetLayout = if osConfig.networking.hostName == "Rias"
then ../../../modules/user/lucid/lucid-widgets-rias.json
else ../../../modules/user/lucid/lucid-widgets.json;
defaultWallpaper = "${wallpaperDir}/bluehour.jpg";
hyprLua = import ../../../modules/user/hyprland/lua.nix { inherit lib; };
hyprLua = import ../hyprland/lua.nix { inherit lib; };
colors = config.lib.stylix.colors.withHashtag;
paletteFile = pkgs.runCommand "lucid-stylix-palette.json" {
nativeBuildInputs = [ pkgs.python3 ];
@@ -214,7 +443,7 @@ PY
lucid = pkgs.writeShellScript "lucid" ''
export NIXPKGS_QT6_QML_IMPORT_PATH="${lib.makeSearchPath "lib/qt-6/qml" qmlPackages}:''${NIXPKGS_QT6_QML_IMPORT_PATH:-}"
export QT_PLUGIN_PATH="${lib.makeSearchPath "lib/qt-6/plugins" qmlPackages}:''${QT_PLUGIN_PATH:-}"
export PATH="${lib.makeBinPath (with pkgs; [ bash cliphist coreutils curl ffmpeg grim imagemagick jq libnotify pulseaudio kdeConnectBridgePython pywal16 wf-recorder wl-clipboard xdg-utils ])}:${tesseract}/bin:$PATH"
export PATH="${lib.makeBinPath (with pkgs; [ bash brightnessctl cliphist coreutils curl ffmpeg grim imagemagick jq libnotify pulseaudio kdeConnectBridgePython pywal16 wf-recorder wl-clipboard xdg-utils ])}:${tesseract}/bin:$PATH"
exec ${pkgs.quickshell}/bin/qs --no-duplicate --path "${config.home.homeDirectory}/.config/quickshell"
'';
startWallpaper = pkgs.writeShellScript "lucid-wallpaper-start" ''
@@ -239,6 +468,80 @@ PY
exec "${wallpaperScript}" "$selected"
'';
in {
options.lucid = {
upstreamSource = lib.mkOption {
type = lib.types.path;
default = source;
description = "Patched Lucid source tree used by profile modules.";
};
keybindSeed = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Optional initial Lucid keybinding file.";
};
prefsSeed = lib.mkOption {
type = lib.types.path;
default = "${source}/defaults/prefs.json";
description = "Initial Lucid preferences file.";
};
widgetSeed = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Optional initial Lucid widget layout.";
};
initialFiles = lib.mkOption {
type = lib.types.attrsOf lib.types.path;
default = {};
description = "Files to seed once at their absolute destinations.";
};
managedFiles = lib.mkOption {
type = lib.types.attrsOf lib.types.path;
default = {};
description = "Lucid files installed at their absolute destinations.";
};
prefsFilter = lib.mkOption {
type = lib.types.lines;
default = ''.barEnabled = true | .widgetOnTop = false | .widgetHideFullscreen = true | .fontFamily = $font | .wallpaperFolder = $wallpaperDir | .liveDecoder = $decoder'';
description = "Declarative jq updates applied to Lucid preferences.";
};
liveDecoder = lib.mkOption {
type = lib.types.str;
default = "vaapi";
description = "Hardware decoder used by Lucid wallpaper playback.";
};
bindsModule = lib.mkOption {
type = lib.types.path;
default = nonRiasBinds;
description = "Lua module that loads this profile's Hyprland bindings.";
};
luaModules = lib.mkOption {
type = lib.types.attrs;
default = {};
description = "Additional Lucid Hyprland Lua modules for this profile.";
};
extraHyprlandConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Profile-specific Hyprland Lua configuration loaded after the shared Lucid setup.";
};
startWallpaper = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Apply the configured wallpaper before Lucid starts.";
};
installWallpaperSupport = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Install Lucid wallpaper integration scripts.";
};
shellFile = lib.mkOption {
type = lib.types.path;
default = ./lucid-shell.qml;
description = "Lucid Quickshell entry point for this user profile.";
};
};
config = {
programs.waybar.enable = lib.mkForce false;
services.mako.enable = lib.mkForce false;
home.packages = with pkgs; [ cliphist ffmpeg grim imagemagick libnotify pywal16 wf-recorder tesseract ];
@@ -261,7 +564,7 @@ in {
--exclude='/lucidkeys/state.json' \
--exclude='/lucidwidgets/widgets.json' \
"${source}/" "$target/"
$DRY_RUN_CMD ${pkgs.patch}/bin/patch --batch -p1 -d "$target" < ${../../../modules/user/lucid/idle-work.patch}
$DRY_RUN_CMD ${pkgs.patch}/bin/patch --batch -p1 -d "$target" < ${./idle-work.patch}
if ! grep -Fq 'mode === "auto"' "$target/Prefs.qml"; then
$DRY_RUN_CMD ${pkgs.patch}/bin/patch --batch --forward -p1 -d "$target" < ${themeAutoPatch}
fi
@@ -300,14 +603,12 @@ in {
// Nix focus workaround for Hyprland 0.57: detach pointer and keyboard focus while menus are open.\
Quickshell.execDetached(["hyprctl", "eval", "hl.config({ input = { follow_mouse = " + (dockWindow.menuOpen ? 2 : 1) + " } })"]);' "$dock_qml"
fi
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/lucid-shell.qml} "$target/shell.qml"
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/LucidBar.qml} "$target/LucidBar.qml"
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/Agenda.qml} "$target/Agenda.qml"
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/CalendarSource.qml} "$target/CalendarSource.qml"
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/ClockCalendar.qml} "$target/lucidbar/ClockCalendar.qml"
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/thunderbird-calendar.py} "$target/thunderbird-calendar.py"
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/WidgetLayer.qml} "$target/lucidwidgets/WidgetLayer.qml"
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/WidgetsPage.qml} "$target/lucidprefs/WidgetsPage.qml"
$DRY_RUN_CMD install -m644 ${config.lucid.shellFile} "$target/shell.qml"
$DRY_RUN_CMD install -m644 ${./LucidBar.qml} "$target/LucidBar.qml"
$DRY_RUN_CMD install -m644 ${./Vaultwarden.qml} "$target/Vaultwarden.qml"
$DRY_RUN_CMD install -m644 ${./WidgetLayer.qml} "$target/lucidwidgets/WidgetLayer.qml"
$DRY_RUN_CMD install -m644 ${./WidgetsPage.qml} "$target/lucidprefs/WidgetsPage.qml"
${lib.optionalString config.lucid.installWallpaperSupport ''
$DRY_RUN_CMD mkdir -p "${wallpaperDir}" \
"${config.home.homeDirectory}/.config/hypr/scripts/wallpaper"
$DRY_RUN_CMD install -m755 "${source}/support/wallpaper/set-wallpaper.sh" \
@@ -315,16 +616,12 @@ in {
if ! grep -Fq 'CURRENT_THEME" == matugen' "${wallpaperScript}"; then
$DRY_RUN_CMD ${pkgs.patch}/bin/patch --batch --forward -p1 -d "$(dirname ${lib.escapeShellArg wallpaperScript})" < ${wallpaperAutoPatch}
fi
''}
lucid_dir="${config.home.homeDirectory}/.config/lucid"
$DRY_RUN_CMD mkdir -p "$lucid_dir/themes"
if [ "${host}" = Rias ] && [ ! -s "$lucid_dir/keybinds.json" ]; then
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/lucid-keybinds-rias.json} "$lucid_dir/keybinds.json"
fi
monitor_file="${config.home.homeDirectory}/.config/hypr/lucid-monitors.lua"
if [ "${host}" = Rias ] && { [ ! -s "$monitor_file" ] || ! grep -qE 'output[[:space:]]*=' "$monitor_file"; } && \
! grep -qE 'workspace[[:space:]]*=' "$monitor_file" 2>/dev/null; then
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/lucid-monitors-rias.lua} "$monitor_file"
if [ ! -s "$lucid_dir/keybinds.json" ]; then
${lib.optionalString (config.lucid.keybindSeed != null) ''$DRY_RUN_CMD install -m644 ${config.lucid.keybindSeed} "$lucid_dir/keybinds.json"''}
fi
$DRY_RUN_CMD ${pkgs.rsync}/bin/rsync -rltp --chmod=Du+rwx,Fu+rw --ignore-existing \
"${source}/support/lucid/themes/" "$lucid_dir/themes/"
@@ -340,14 +637,14 @@ in {
"$lucid_dir/apply-theme.sh"
if [ ! -e "$target/lucidprefs/prefs.json" ]; then
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/lucid-prefs.json} "$target/lucidprefs/prefs.json"
$DRY_RUN_CMD install -m644 ${config.lucid.prefsSeed} "$target/lucidprefs/prefs.json"
fi
if [ -z "''${DRY_RUN_CMD:-}" ] && [ -f "$target/lucidprefs/prefs.json" ]; then
prefs_tmp=$(${pkgs.coreutils}/bin/mktemp "$target/lucidprefs/prefs.json.XXXXXX")
if ${pkgs.jq}/bin/jq --arg font ${lib.escapeShellArg config.stylix.fonts.sansSerif.name} \
--arg wallpaperDir ${lib.escapeShellArg wallpaperDir} \
--arg decoder ${lib.escapeShellArg liveDecoder} \
'.barEnabled = true | .widgetOnTop = false | .widgetHideFullscreen = true | .fontFamily = $font | .wallpaperFolder = $wallpaperDir | .liveDecoder = $decoder' \
--arg decoder ${lib.escapeShellArg config.lucid.liveDecoder} \
${lib.escapeShellArg config.lucid.prefsFilter} \
"$target/lucidprefs/prefs.json" > "$prefs_tmp"; then
${pkgs.coreutils}/bin/chmod 644 "$prefs_tmp"
${pkgs.coreutils}/bin/mv "$prefs_tmp" "$target/lucidprefs/prefs.json"
@@ -356,12 +653,21 @@ in {
exit 1
fi
fi
if [ ! -e "$target/luciddocks/pinned.json" ]; then
$DRY_RUN_CMD install -m644 ${../../../modules/user/lucid/lucid-pinned.json} "$target/luciddocks/pinned.json"
fi
${lib.optionalString (config.lucid.widgetSeed != null) ''
if [ ! -e "$target/lucidwidgets/widgets.json" ]; then
$DRY_RUN_CMD install -m644 ${widgetLayout} "$target/lucidwidgets/widgets.json"
$DRY_RUN_CMD install -m644 ${config.lucid.widgetSeed} "$target/lucidwidgets/widgets.json"
fi
''}
${lib.concatStringsSep "\n" (lib.mapAttrsToList (destination: sourceFile: ''
if [ ! -e ${lib.escapeShellArg destination} ]; then
$DRY_RUN_CMD mkdir -p ${lib.escapeShellArg (builtins.dirOf destination)}
$DRY_RUN_CMD install -m644 ${sourceFile} ${lib.escapeShellArg destination}
fi
'') config.lucid.initialFiles)}
${lib.concatStringsSep "\n" (lib.mapAttrsToList (destination: sourceFile: ''
$DRY_RUN_CMD mkdir -p ${lib.escapeShellArg (builtins.dirOf destination)}
$DRY_RUN_CMD install -m644 ${sourceFile} ${lib.escapeShellArg destination}
'') config.lucid.managedFiles)}
for pair in \
'blur.json lucidbar/blur.json' \
@@ -402,77 +708,36 @@ in {
PartOf = [ "graphical-session.target" ];
};
Service = {
ExecStartPre = "${startWallpaper}";
ExecStart = "${lucid}";
Restart = "on-failure";
RestartSec = 2;
};
} // lib.optionalAttrs config.lucid.startWallpaper { ExecStartPre = "${startWallpaper}"; };
Install.WantedBy = [ "hyprland-session.target" ];
};
wayland.windowManager.hyprland = {
settings = {
on = [ (hyprLua.onStart [ "systemctl --user start lucid.service" ]) ];
bind = lib.mkIf isRias (lib.mkForce []);
};
# Home Manager autoloads these before its generated settings. Lucid's
# stateful UI modules are installed too, then required after the Nix base
# config below so saved UI choices take effect without losing that base.
extraLuaFiles = lib.mkIf isRias {
"modules/binds.lua" = builtins.toPath "${source}/support/hypr/modules/binds.lua";
extraLuaFiles = {
"modules/binds.lua" = config.lucid.bindsModule;
"modules/json.lua" = builtins.toPath "${source}/support/hypr/modules/json.lua";
"modules/decorations.lua" = builtins.toPath "${source}/support/hypr/modules/decorations.lua";
"modules/gestures.lua" = builtins.toPath "${source}/support/hypr/modules/gestures.lua";
"modules/input.lua" = builtins.toPath "${source}/support/hypr/modules/input.lua";
"modules/layout.lua" = builtins.toPath "${source}/support/hypr/modules/layout.lua";
"modules/layerrules.lua" = builtins.toPath "${source}/support/hypr/modules/layerrules.lua";
"modules/lumen.lua" = builtins.toPath "${source}/support/hypr/modules/lumen.lua";
"modules/misc.lua" = builtins.toPath "${source}/support/hypr/modules/misc.lua";
"modules/plugins.lua" = builtins.toPath "${source}/support/hypr/modules/plugins.lua";
"modules/windowrules.lua" = builtins.toPath "${source}/support/hypr/modules/windowrules.lua";
"modules/glass.lua" = {
content = builtins.toPath "${source}/support/hypr/modules/glass.lua";
autoLoad = false;
};
"modules/monitors.lua" = {
content = builtins.toPath "${source}/support/hypr/modules/monitors.lua";
autoLoad = false;
};
"modules/settings.lua" = {
content = builtins.toPath "${source}/support/hypr/modules/settings.lua";
autoLoad = false;
};
"modules/specials.lua" = {
content = builtins.toPath "${source}/support/hypr/modules/specials.lua";
autoLoad = false;
};
"modules/startup.lua" = {
content = builtins.toPath "${source}/support/hypr/modules/startup.lua";
autoLoad = false;
};
};
} // config.lucid.luaModules;
# Nix owns session startup and environment exports; don't load Lucid's
# generic autostart/env defaults on top of the existing host setup.
extraConfig = lib.mkIf isRias ''
extraConfig = ''
local config_home = os.getenv("XDG_CONFIG_HOME") or ${builtins.toJSON config.xdg.configHome}
package.path = config_home .. "/hypr/?.lua;" .. config_home .. "/hypr/?/init.lua;" .. package.path
require("modules.specials")
require("modules.monitors")
local lucid_monitor_apply = LucidMonitors.apply
LucidMonitors.apply = function(...)
lucid_monitor_apply(...)
hl.monitor({ output = "desc:Huawei Technologies Co. Inc. ZQE-CAA 0xC080F622", cm = "srgb", supports_hdr = -1 })
end
LucidMonitors.apply()
-- Lucid previously left empty workspaces 3-6 persistent on this host.
-- Retire those stale rules after applying the monitor layout so they do
-- not return on the next Hyprland reload.
for _, workspace in ipairs({ "3", "4", "5", "6" }) do
hl.workspace_rule({ workspace = workspace, persistent = false })
end
require("modules.settings")
require("modules.glass")
require("modules.startup")
'';
LucidSpecials.apply()
'' + config.lucid.extraHyprlandConfig;
};
};
}
@@ -0,0 +1,483 @@
{
"version": 1,
"binds": [
{
"id": "wallpaper-picker",
"keys": "SUPER + W",
"desc": "Wallpaper picker",
"category": "Lucid"
},
{
"id": "wallpaper-random",
"keys": "SUPER + SHIFT + W",
"desc": "Set a random wallpaper",
"category": "Desktop"
},
{
"id": "calculator-volume",
"keys": "XF86Calculator",
"desc": "Open volume mixer",
"category": "Apps"
},
{
"id": "zoom-reset-scroll-up",
"keys": "SUPER + SHIFT + mouse_up",
"desc": "Reset cursor zoom",
"category": "Accessibility"
},
{
"id": "zoom-reset-scroll-down",
"keys": "SUPER + SHIFT + mouse_down",
"desc": "Reset cursor zoom",
"category": "Accessibility"
},
{
"id": "zoom-reset-minus",
"keys": "SUPER + SHIFT + minus",
"desc": "Reset cursor zoom",
"category": "Accessibility"
},
{
"id": "zoom-reset-kp-subtract",
"keys": "SUPER + SHIFT + KP_SUBTRACT",
"desc": "Reset cursor zoom",
"category": "Accessibility"
},
{
"id": "zoom-reset-zero",
"keys": "SUPER + SHIFT + 0",
"desc": "Reset cursor zoom",
"category": "Accessibility"
},
{
"id": "zoom-in-equal",
"keys": "SUPER + equal",
"desc": "Zoom in",
"category": "Accessibility",
"opts": {
"repeating": true
}
},
{
"id": "zoom-out-minus",
"keys": "SUPER + minus",
"desc": "Zoom out",
"category": "Accessibility",
"opts": {
"repeating": true
}
},
{
"id": "zoom-in-kp-add",
"keys": "SUPER + KP_ADD",
"desc": "Zoom in",
"category": "Accessibility",
"opts": {
"repeating": true
}
},
{
"id": "zoom-out-kp-subtract",
"keys": "SUPER + KP_SUBTRACT",
"desc": "Zoom out",
"category": "Accessibility",
"opts": {
"repeating": true
}
},
{
"id": "widgets-panel",
"keys": "SUPER + SHIFT + G",
"desc": "Toggle widgets panel",
"category": "Lucid"
},
{
"id": "launcher",
"keys": "SUPER + D",
"desc": "App launcher",
"category": "Lucid"
},
{
"id": "vaultwarden-password",
"keys": "SUPER + X",
"desc": "Type a password from Vaultwarden",
"category": "Apps"
},
{
"id": "clipse",
"keys": "SUPER + V",
"desc": "Clipboard manager",
"category": "Apps"
},
{
"id": "clipboard",
"keys": "SUPER + SHIFT + V",
"desc": "Clipboard history",
"category": "Lucid"
},
{
"id": "screenshot",
"keys": "Print",
"desc": "Full screenshot",
"category": "Screenshots"
},
{
"id": "screenshot-full",
"keys": "SUPER + Print",
"desc": "Full screenshot",
"category": "Screenshots"
},
{
"id": "screenshot-region",
"keys": "CTRL + Print",
"desc": "Region screenshot",
"category": "Screenshots"
},
{
"id": "screenshot-window",
"keys": "ALT + Print",
"desc": "Window screenshot",
"category": "Screenshots"
},
{
"id": "terminal",
"keys": "SUPER + RETURN",
"desc": "Terminal",
"category": "Apps"
},
{
"id": "close-window",
"keys": "SUPER + Q",
"desc": "Close window",
"category": "Windows"
},
{
"id": "exit-hyprland",
"keys": "SUPER + M",
"desc": "Exit Hyprland",
"category": "Session"
},
{
"id": "file-manager",
"keys": "SUPER + E",
"desc": "File manager",
"category": "Apps"
},
{
"id": "toggle-float",
"keys": "SUPER + F",
"desc": "Toggle floating window",
"category": "Windows"
},
{
"id": "toggle-pseudo",
"keys": "SUPER + P",
"desc": "Toggle pseudo-tile",
"category": "Windows"
},
{
"id": "toggle-split",
"keys": "SUPER + J",
"desc": "Toggle split direction",
"category": "Windows"
},
{
"id": "swap-split",
"keys": "SUPER + K",
"desc": "Swap split direction",
"category": "Windows"
},
{
"id": "focus-left",
"keys": "SUPER + LEFT",
"desc": "Focus left",
"category": "Windows"
},
{
"id": "focus-right",
"keys": "SUPER + RIGHT",
"desc": "Focus right",
"category": "Windows"
},
{
"id": "focus-up",
"keys": "SUPER + UP",
"desc": "Focus up",
"category": "Windows"
},
{
"id": "focus-down",
"keys": "SUPER + DOWN",
"desc": "Focus down",
"category": "Windows"
},
{
"id": "swap-left",
"keys": "SUPER + SHIFT + LEFT",
"desc": "Move window left",
"category": "Windows"
},
{
"id": "swap-right",
"keys": "SUPER + SHIFT + RIGHT",
"desc": "Move window right",
"category": "Windows"
},
{
"id": "swap-up",
"keys": "SUPER + SHIFT + UP",
"desc": "Move window up",
"category": "Windows"
},
{
"id": "swap-down",
"keys": "SUPER + SHIFT + DOWN",
"desc": "Move window down",
"category": "Windows"
},
{
"id": "resize-left",
"keys": "SUPER + CTRL + LEFT",
"desc": "Resize window left",
"category": "Windows"
},
{
"id": "resize-right",
"keys": "SUPER + CTRL + RIGHT",
"desc": "Resize window right",
"category": "Windows"
},
{
"id": "resize-up",
"keys": "SUPER + CTRL + UP",
"desc": "Resize window up",
"category": "Windows"
},
{
"id": "resize-down",
"keys": "SUPER + CTRL + DOWN",
"desc": "Resize window down",
"category": "Windows"
},
{
"id": "workspace-focus",
"keys": "SUPER + {key}",
"desc": "Focus workspace {n}",
"category": "Workspaces",
"each": "workspace"
},
{
"id": "workspace-move",
"keys": "SUPER + SHIFT + {key}",
"desc": "Move window to workspace {n}",
"category": "Workspaces",
"each": "workspace"
},
{
"id": "scratchpad",
"keys": "SUPER + ALT + P",
"desc": "Toggle scratchpad",
"category": "Workspaces",
"type": "lua",
"lua": "specials.scratchpad()"
},
{
"id": "scratchpad-stash",
"keys": "SUPER + ALT + S",
"desc": "Stash or restore the focused window",
"category": "Workspaces",
"type": "lua",
"lua": "specials.stash()"
},
{
"id": "special-music",
"keys": "SUPER + ALT + M",
"desc": "Toggle Music workspace",
"category": "Workspaces",
"type": "lua",
"lua": "specials.toggle('music')"
},
{
"id": "special-comms",
"keys": "SUPER + ALT + C",
"desc": "Toggle Comms workspace",
"category": "Workspaces",
"type": "lua",
"lua": "specials.toggle('comms')"
},
{
"id": "special-todo",
"keys": "SUPER + ALT + T",
"desc": "Toggle To-do workspace",
"category": "Workspaces",
"type": "lua",
"lua": "specials.toggle('todo')"
},
{
"id": "special-sysmon",
"keys": "SUPER + ALT + B",
"desc": "Toggle system monitor workspace",
"category": "Workspaces",
"type": "lua",
"lua": "specials.toggle('sysmon')"
},
{
"id": "daemons-workspace",
"keys": "SUPER + ALT + D",
"desc": "Daemons workspace",
"category": "Workspaces",
"type": "lua",
"lua": "specials.toggle('daemons')"
},
{
"id": "fullscreen",
"keys": "SUPER + SHIFT + F",
"desc": "Toggle fullscreen",
"category": "Windows"
},
{
"id": "workspace-next-scroll",
"keys": "SUPER + mouse_down",
"desc": "Next workspace",
"category": "Workspaces"
},
{
"id": "workspace-previous-scroll",
"keys": "SUPER + mouse_up",
"desc": "Previous workspace",
"category": "Workspaces"
},
{
"id": "keyboard-brightness-up",
"keys": "SUPER + F3",
"desc": "Keyboard backlight up",
"category": "Displays"
},
{
"id": "keyboard-brightness-down",
"keys": "SUPER + F2",
"desc": "Keyboard backlight down",
"category": "Displays"
},
{
"id": "audio-mute",
"keys": "XF86AudioMute",
"desc": "Toggle audio mute",
"category": "Media"
},
{
"id": "microphone-mute",
"keys": "XF86AudioMicMute",
"desc": "Toggle microphone mute",
"category": "Media"
},
{
"id": "play-pause",
"keys": "XF86AudioPlay",
"desc": "Play or pause media",
"category": "Media"
},
{
"id": "file-manager-media",
"keys": "XF86Explorer",
"desc": "File manager",
"category": "Apps"
},
{
"id": "email",
"keys": "XF86Mail",
"desc": "Email",
"category": "Apps"
},
{
"id": "browser",
"keys": "XF86WWW",
"desc": "Web browser",
"category": "Apps"
},
{
"id": "display-brightness-down",
"keys": "XF86MonBrightnessDown",
"desc": "Brightness down",
"category": "Displays"
},
{
"id": "display-brightness-up",
"keys": "XF86MonBrightnessUp",
"desc": "Brightness up",
"category": "Displays"
},
{
"id": "volume-up",
"keys": "XF86AudioRaiseVolume",
"desc": "Volume up",
"category": "Media",
"opts": {
"repeating": true
}
},
{
"id": "volume-down",
"keys": "XF86AudioLowerVolume",
"desc": "Volume down",
"category": "Media",
"opts": {
"repeating": true
}
},
{
"id": "previous-seek",
"keys": "XF86AudioPrev",
"desc": "Seek backward",
"category": "Media",
"opts": {
"click": true
}
},
{
"id": "next-seek",
"keys": "XF86AudioNext",
"desc": "Seek forward",
"category": "Media",
"opts": {
"click": true
}
},
{
"id": "previous-track",
"keys": "XF86AudioPrev",
"desc": "Previous track",
"category": "Media",
"opts": {
"long_press": true
}
},
{
"id": "next-track",
"keys": "XF86AudioNext",
"desc": "Next track",
"category": "Media",
"opts": {
"long_press": true
}
},
{
"id": "move-window-drag",
"keys": "SUPER + mouse:272",
"desc": "Move window with mouse",
"category": "Windows",
"opts": {
"mouse": true
}
},
{
"id": "resize-window-drag",
"keys": "SUPER + mouse:273",
"desc": "Resize window with mouse",
"category": "Windows",
"opts": {
"mouse": true
}
}
]
}
@@ -1,9 +0,0 @@
-- Initial Rias display layout; Home Manager seeds this only while the
-- user-owned Lucid monitor list is empty.
return {
monitors = {
{ output = "desc:Huawei Technologies Co. Inc. ZQE-CAA 0xC080F622", mode = "3440x1440@120.00", position = "1920x0", scale = "1" },
{ output = "desc:Samsung Electric Company SAMSUNG 0x01000E00", mode = "1920x1080@60.00", position = "0x0", scale = "1" },
},
workspaces = {},
}
-3
View File
@@ -1,3 +0,0 @@
{
"pinnedApps": []
}
+5
View File
@@ -1,5 +1,6 @@
import "./luciddocks"
import "./lucidedit"
import "./lucidlock"
import "./lucidosd"
import "./lucidprefs"
import "./lucidshot"
@@ -12,6 +13,7 @@ ShellRoot {
id: root
Component.onCompleted: {
void Specials.moduleProbed;
void Clip.probed;
void Capture.state;
}
@@ -127,6 +129,9 @@ ShellRoot {
WidgetIpc {
}
Lock {
}
EditLayer {
}
-20
View File
@@ -1,20 +0,0 @@
{
"nextId": 3,
"boardFull": true,
"instances": [
{
"uid": "w1",
"type": "clock",
"variant": "digital",
"wx": 40,
"wy": 70
},
{
"uid": "w2",
"type": "system",
"variant": "rings",
"wx": 40,
"wy": 250
}
]
}
+2 -5
View File
@@ -188,10 +188,7 @@ in {
'';
};
wayland.windowManager.hyprland.settings.bind = [
(hyprLua.bind "SUPER + D"
(if config.home.username == "sweetbread"
then hyprLua.execLauncher "qs ipc call launcher toggle"
else hyprLua.exec "walker"))
lucidHyprlandBinds = [
(hyprLua.bind "SUPER + D" (hyprLua.execLauncher "qs ipc call launcher toggle"))
];
}
+9 -1
View File
@@ -1,6 +1,14 @@
{ pkgs, pkgs-pinned, host, ... }: {
{ pkgs, pkgs-pinned, lib, osConfig, ... }: {
imports = [
../../modules/user/packages/cs_utils.nix
../../modules/user/lucid
./modules/lucid
] ++ lib.optionals (osConfig.networking.hostName == "Impreza") [
../../host/Impreza/modules/lucid
] ++ lib.optionals (osConfig.networking.hostName == "Rias") [
../../host/Rias/modules/lucid
] ++ lib.optionals (osConfig.networking.hostName == "Eclipse") [
../../host/Eclipse/modules/lucid
];
disabledModules = [
../../modules/user/packages/art.nix
+4 -4
View File
@@ -71,9 +71,9 @@ in {
{ leaf = "fade"; enabled = true; speed = 7; bezier = "default"; }
{ leaf = "workspaces"; enabled = true; speed = 6; bezier = "default"; }
];
bind = [
(hyprLua.bind "SUPER + SHIFT + S" (hyprLua.exec ''${lib.getExe pkgs.grim} -g "$(${lib.getExe pkgs.slurp})" - | ${lib.getExe pkgs.swappy} -f -''))
];
};
lucidHyprlandBinds = [
(hyprLua.bind "SUPER + SHIFT + S" (hyprLua.exec ''${lib.getExe pkgs.grim} -g "$(${lib.getExe pkgs.slurp})" - | ${lib.getExe pkgs.swappy} -f -''))
];
}
+185
View File
@@ -0,0 +1,185 @@
{ config, lib, pkgs, ... }:
let
source = config.lucid.upstreamSource;
specialBindIds = [ "scratchpad" "scratchpad-stash" "special-music" "special-comms" "special-todo" "special-sysmon" "daemons-workspace" ];
specialSeed = pkgs.writeText "lucid-special-bindings.json" (builtins.toJSON {
version = 1;
binds = builtins.filter (entry: builtins.elem entry.id specialBindIds)
(builtins.fromJSON (builtins.readFile ../../../../modules/user/lucid/lucid-keybind-catalog.json)).binds;
});
chestBindingsScript = pkgs.writeText "lucid-chest-bindings.py" ''
import hashlib, json, re, sys
from collections import Counter
source, reference, special, output = sys.argv[1:]
binds = json.loads(source)
refs = json.load(open(reference))["binds"]
specials = json.load(open(special))["binds"]
counts, result = Counter(), []
for entry in binds:
args = entry["_args"]
if not 2 <= len(args) <= 3 or args[1].get("_type") != "lua-inline":
raise ValueError(f"Unsupported Hyprland binding: {entry}")
keys, expr = args[0], args[1]["expr"]
opts = args[2] if len(args) == 3 else {}
signature = json.dumps([keys.upper().replace(" ", ""), opts], sort_keys=True)
counts[signature] += 1
identifier = hashlib.sha256(signature.encode()).hexdigest()[:12]
b = {"id": f"chest-{identifier}-{counts[signature]}", "keys": keys}
match = next((r for r in refs if r.get("keys", "").upper().replace(" ", "") == keys.upper().replace(" ", "") and r.get("opts", {}) == opts), None)
b["desc"] = match.get("desc", keys) if match else keys
b["category"] = match.get("category", "Other") if match else "Other"
workspace = re.search(r"workspace = (\d+)", expr)
if workspace and expr.startswith("hl.dsp.focus("):
b.update(desc=f"Focus workspace {workspace.group(1)}", category="Workspaces")
elif workspace and expr.startswith("hl.dsp.window.move("):
b.update(desc=f"Move window to workspace {workspace.group(1)}", category="Workspaces")
if keys.upper().replace(" ", "") == "SUPER+SHIFT+S": b.update(desc="Region screenshot and edit", category="Screenshots")
m = re.fullmatch(r'hl\.dsp\.exec_cmd\(("(?:\\.|[^"\\])*")\)\s*', expr, re.S)
if m:
cmd = json.loads(m.group(1))
cmd = re.sub(r'/nix/store/[0-9a-z]{32}-[^/\s"\\]+/bin/([A-Za-z0-9_.+-]+)', r'\1', cmd)
b.update(type="exec", cmd=cmd)
else: b.update(type="lua", lua=expr)
if opts: b["opts"] = opts
result.append(b)
json.dump({"version": 1, "binds": result + specials}, open(output, "w"), indent=2)
'';
chestSeed = pkgs.runCommand "lucid-chest-bindings.json" { nativeBuildInputs = [ pkgs.python3 ]; } ''
python3 ${chestBindingsScript} ${lib.escapeShellArg (builtins.toJSON config.lucidHyprlandBinds)} \
${../../../../modules/user/lucid/lucid-keybind-catalog.json} ${specialSeed} "$out"
'';
chestBinds = pkgs.runCommand "lucid-chest-loader.lua" { nativeBuildInputs = [ pkgs.python3 ]; } ''
python3 - ${source}/support/hypr/modules/binds.lua "$out" <<'PY'
import pathlib, sys
source = pathlib.Path(sys.argv[1]).read_text()
old = '{ id = "terminal", keys = "F9", type = "exec", cmd = "kitty" }'
new = '{ id = "terminal", keys = "SUPER + RETURN", type = "exec", cmd = "ghostty" }'
if source.count(old) != 1: raise SystemExit("Lucid emergency bindings changed")
pathlib.Path(sys.argv[2]).write_text(source.replace(old, new, 1))
PY
'';
chestMonitors = pkgs.runCommand "lucid-chest-monitors.lua" { nativeBuildInputs = [ pkgs.python3 ]; } ''
python3 - ${source}/support/hypr/modules/monitors.lua "$out" <<'PY'
import pathlib, sys
source = pathlib.Path(sys.argv[1]).read_text()
rule = """hl.monitor({
output = "",
mode = M.defaults.mode,
position = M.defaults.position,
scale = M.defaults.scale,
})
"""
if source.count(rule) != 1: raise SystemExit("Lucid monitor defaults changed")
pathlib.Path(sys.argv[2]).write_text(source.replace(rule, "", 1))
PY
'';
chestBorders = pkgs.runCommand "lucid-chest-decorations.lua" { nativeBuildInputs = [ pkgs.python3 ]; } ''
python3 - ${source}/support/hypr/modules/decorations.lua "$out" <<'PY'
import pathlib, sys
source = pathlib.Path(sys.argv[1]).read_text()
marker = "local active_border, inactive_border = borders()"
if source.count(marker) != 1: raise SystemExit("Lucid border module changed")
pathlib.Path(sys.argv[2]).write_text(source.split(marker, 1)[0])
PY
'';
chestPrefs = pkgs.writeText "lucid-chest-prefs.json" (builtins.toJSON (
(builtins.fromJSON (builtins.readFile "${source}/defaults/prefs.json")) // {
specialCustom = builtins.toJSON [ { key = "daemons"; label = "Daemons"; glyph = "build"; on = true; apps = ""; } ];
}
));
in
{
lucid.keybindSeed = chestSeed;
lucid.prefsSeed = chestPrefs;
lucid.bindsModule = chestBinds;
lucid.luaModules = {
"modules/decorations.lua" = lib.mkForce chestBorders;
"modules/monitors.lua" = lib.mkForce { content = chestMonitors; autoLoad = false; };
"modules/glass.lua" = { content = "${source}/support/hypr/modules/glass.lua"; autoLoad = false; };
"modules/settings.lua" = { content = "${source}/support/hypr/modules/settings.lua"; autoLoad = false; };
"modules/startup.lua" = { content = "${source}/support/hypr/modules/startup.lua"; autoLoad = false; };
};
lucid.extraHyprlandConfig = ''
require("modules.monitors")
require("modules.settings")
require("modules.glass")
require("modules.startup")
'';
lucid.shellFile = pkgs.writeText "lucid-chest-shell.qml" (builtins.replaceStrings [
''import "./lucidlock"''
" Lock {\n }\n"
" void Clip.probed;"
] [
""
""
" void Notifs.count;\n void KdeConnect.installed;\n void HyprConfig.moduleProbed;\n void Monitors.moduleProbed;\n void Glass.moduleProbed;\n void Startup.moduleProbed;\n void Clip.probed;"
] (builtins.readFile ../../../../modules/user/lucid/lucid-shell.qml));
lucid.prefsFilter = ''.barEnabled = true | .widgetOnTop = false | .widgetHideFullscreen = true | .fontFamily = $font | .liveWallpapers = false | .idleLock = false | .idleLockBeforeSleep = false | .launcherPowerButtons = "suspend,reboot,shutdown" | .powerModuleActions = "suspend,hibernate,logout,reboot,shutdown"'';
home.packages = with pkgs; [ brightnessctl playerctl slurp swappy ];
wayland.windowManager.hyprland.settings = {
bind = lib.mkForce [];
window_rule = [
{
name = "float-lucid-settings";
match = { class = "org.quickshell"; title = "Lucid Settings"; };
float = true;
size = [ 1180 800 ];
center = true;
}
{
name = "float-lucid-choosers";
match = {
class = "^(org\\.gnome\\.Nautilus|xdg-desktop-portal-gtk|xdg-desktop-portal-gnome|zenity|org\\.kde\\.kdialog|kdialog)$";
title = "^(Choose an account picture|Choose a template|Choose a colour scheme|Export the palette|Save received files to|Send files|Send to .+)$";
};
float = true;
center = true;
}
];
};
home.activation.installChestLucidFixes = lib.hm.dag.entryAfter [ "installLucid" ] ''
target="${config.home.homeDirectory}/.config/quickshell"
lock_qml="$target/Lockscreen.qml"
if ! grep -Fq 'return; // Lucid lock disabled for chest' "$lock_qml"; then
grep -Fq 'function lock(settle) {' "$lock_qml" && \
grep -Fq 'function pushLockedHint() {' "$lock_qml" && \
grep -Fq 'id: logindWatch' "$lock_qml" || {
echo "Lucid lock integration changed; refusing to leave it active for chest" >&2
exit 1
}
$DRY_RUN_CMD sed -i \
-e '/function lock(settle) {/a\ return; // Lucid lock disabled for chest' \
-e '/function pushLockedHint() {/a\ return; // Lucid lock disabled for chest' \
-e '/id: logindWatch/{n;n;s/running: true/running: false/;}' "$lock_qml"
fi
if ! grep -Fq 'id: chestBrightnessPoll' "$target/lucidosd/Osd.qml"; then
$DRY_RUN_CMD ${pkgs.patch}/bin/patch --batch --forward -p1 -d "$target" < ${pkgs.writeText "lucid-chest-osd.patch" ''
--- a/lucidosd/Osd.qml
+++ b/lucidosd/Osd.qml
@@ -26 +26 @@
- readonly property int brightnessPercent: osdWindow.maxBrightness > 0 ? Math.round((parseInt(brightnessFile.text()) / osdWindow.maxBrightness) * 100) : 0
+ property int brightnessPercent: 0
@@ -378,2 +378,15 @@
onFileChanged: reload()
+ onLoaded: {
+ const value = parseInt(brightnessFile.text());
+ if (osdWindow.maxBrightness > 0 && !isNaN(value))
+ osdWindow.brightnessPercent = Math.round(value / osdWindow.maxBrightness * 100);
+ }
}
+
+ Timer {
+ id: chestBrightnessPoll
+ interval: 500
+ repeat: true
+ running: osdWindow.backlightDevice !== ""
+ onTriggered: brightnessFile.reload()
+ }
''}
fi
'';
}
+1 -1
View File
@@ -1,5 +1,5 @@
{ pkgs, config, lib, osConfig, inputs, ... }: let
mikuFrost = osConfig.networking.hostName == "Eclipse";
mikuFrost = builtins.elem osConfig.networking.hostName [ "Eclipse" "Impreza" ];
colors = config.lib.stylix.colors.withHashtag;
accent = colors.${config.stylix.accent};
# Render the same Stylix templates, changing only native translucency and accent.
+2
View File
@@ -44,6 +44,8 @@
];
programs.zsh.enable = true;
programs.kdeconnect.enable = true;
home-manager.users.${name}.services.kdeconnect.enable = true;
users = {
defaultUserShell = pkgs.zsh;
+21 -2
View File
@@ -1,11 +1,30 @@
{ pkgs, ... }: {
imports = [ ./modules/lucid.nix ];
{ pkgs, lib, osConfig, ... }: let
# Match the Electron FFmpeg build recommended by Vivaldi 8.2.
vivaldiCodecs = pkgs.runCommand "vivaldi-ffmpeg-electron-44.4.2" {
nativeBuildInputs = [ pkgs.unzip ];
} ''
mkdir -p "$out/lib"
unzip -p ${pkgs.fetchurl {
url = "https://github.com/electron/electron/releases/download/v44.4.2/electron-v44.4.2-linux-x64.zip";
hash = "sha256-rXEGPnfaKaZH+HKwkEePn6nM/9Z957KuYxVAnPHxNDY=";
}} libffmpeg.so > "$out/lib/libffmpeg.so"
echo "39f63af3ef6f8db9eea20803c6f6dff8b2d5ad596d506ea1effb3f856715ac1c $out/lib/libffmpeg.so" | sha256sum -c
'';
in {
imports = [
../../modules/user/lucid
./modules/lucid
] ++ lib.optionals (osConfig.networking.hostName == "Rias") [
../../host/Rias/modules/lucid
./modules/lucid/rias.nix
];
programs.hyprlock.enable = true;
home.packages = with pkgs; [
android-studio
(vivaldi.override {
proprietaryCodecs = true;
vivaldi-ffmpeg-codecs = vivaldiCodecs;
enableWidevine = true;
})
weechat
File renamed without changes.
+28
View File
@@ -0,0 +1,28 @@
{ config, lib, pkgs, ... }:
let
specialCustom = builtins.toJSON [ {
key = "daemons";
label = "Daemons";
glyph = "build";
on = true;
apps = "";
} ];
in {
lucid.keybindSeed = ./lucid-keybinds.json;
lucid.prefsSeed = pkgs.writeText "sweetbread-lucid-prefs.json" (builtins.toJSON (
(builtins.fromJSON (builtins.readFile ./lucid-prefs.json)) // {
specialCustom = specialCustom;
}
));
lucid.startWallpaper = true;
lucid.installWallpaperSupport = true;
lucid.managedFiles = {
"${config.home.homeDirectory}/.config/quickshell/Agenda.qml" = ./Agenda.qml;
"${config.home.homeDirectory}/.config/quickshell/CalendarSource.qml" = ./CalendarSource.qml;
"${config.home.homeDirectory}/.config/quickshell/lucidbar/ClockCalendar.qml" = ./ClockCalendar.qml;
"${config.home.homeDirectory}/.config/quickshell/thunderbird-calendar.py" = ./thunderbird-calendar.py;
};
wayland.windowManager.hyprland.settings.bind = lib.mkForce [];
}
@@ -15,6 +15,7 @@
{ "id": "zoom-out-kp-subtract", "keys": "SUPER + KP_SUBTRACT", "desc": "Zoom out", "category": "Accessibility", "type": "lua", "lua": "function() local current = hl.get_config('cursor.zoom_factor'); hl.config({ cursor = { zoom_factor = math.max(1, current * 0.9) } }) end", "opts": { "repeating": true } },
{ "id": "widgets-panel", "keys": "SUPER + SHIFT + G", "desc": "Toggle widgets panel", "category": "Lucid", "type": "exec", "cmd": "qs ipc call widgets panel" },
{ "id": "launcher", "keys": "SUPER + D", "desc": "App launcher", "category": "Lucid", "type": "exec", "cmd": "hyprctl eval 'hl.config({ input = { follow_mouse = 2 } })' && qs ipc call launcher toggle" },
{ "id": "vaultwarden-password", "keys": "SUPER + X", "desc": "Type a password from Vaultwarden", "category": "Apps", "type": "exec", "cmd": "qs ipc call -- launcher search '>pass '" },
{ "id": "clipse", "keys": "SUPER + V", "desc": "Clipboard manager", "category": "Apps", "type": "exec", "cmd": "ghostty --title=clipse -e clipse" },
{ "id": "clipboard", "keys": "SUPER + SHIFT + V", "desc": "Clipboard history", "category": "Lucid", "type": "exec", "cmd": "hyprctl eval 'hl.config({ input = { follow_mouse = 2 } })' && qs ipc call launcher clipboard" },
{ "id": "screenshot", "keys": "Print", "desc": "Full screenshot", "category": "Screenshots", "type": "exec", "cmd": "qs ipc call screenshot full" },
@@ -144,7 +144,7 @@
"launcherPowerButtons": "lock,suspend,reboot,shutdown",
"launcherPowerChips": false,
"launcherPowerSearch": true,
"launcherSearchEngine": "duckduckgo",
"launcherSearchEngine": "lair",
"launcherSearchPosition": "bottom",
"launcherSettingsResults": true,
"launcherWebRow": true,
+13
View File
@@ -0,0 +1,13 @@
{ config, lib, ... }:
{
lucid.prefsSeed = lib.mkForce (builtins.toFile "sweetbread-rias-lucid-prefs.json" (builtins.toJSON (
(builtins.fromJSON (builtins.readFile ./lucid-prefs.json)) // {
specialCustom = "[]";
}
)));
lucid.extraHyprlandConfig = ''
require("modules.settings")
require("modules.glass")
require("modules.startup")
'';
}