Commit Graph

40 Commits

Author SHA1 Message Date
daniil-berg 031bad3238 feat(waybar): add window title module and styled clock calendar
Center a `hyprland/window` title module and move the clock/date to the far
right of the bar. Give the clock a month-calendar tooltip with One Dark
Pango styling (yellow header, purple weekdays, blue underlined today, dim
ISO week-number gutter), 3-per-row year view via right-click.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 08:03:48 +02:00
daniil-berg dc676b6f8c refactor(i18n): make defaultLocale overridable via mkDefault
Template hard-set `en_US.UTF-8`, so a consumer setting `i18n.defaultLocale`
in the private inventory hit a conflicting-definition eval error. Wrap the
template default in `lib.mkDefault` per the overrides-are-options contract.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 08:03:43 +02:00
daniil-berg f64d68ac05 fix(mc): discard xdg-open stdout/stderr so app logs don't clobber mc pane 2026-07-13 07:03:03 +02:00
daniil-berg 4be1c4fb67 feat(mc): open files with their configured app via xdg-open
Ship `mc.ext.ini` as the `local.mc.extIni` option (like `local.mc.menu`):
Enter browses archives in-place as before and delegates every other type to
`xdg-open`. Add public `mime.nix` with `xdg.mimeApps` defaults (pdf ->
zathura, images -> imv, audio/video -> mpv, office -> libreoffice) -- public
because those handlers are; personal browser/mail defaults stay private.

Also document, at the Hyprland swallow config, how swallowing differs from an
app opening fullscreen/maximized (LibreOffice restores its own maximized state
and looks swallowed but isn't).
2026-07-12 22:09:01 +02:00
daniil-berg 7205841c4d fix(ssh): spawn askpass pinentry off-tree so push doesn't swallow terminal 2026-07-12 16:45:18 +02:00
daniil-berg 0851515de0 fix(hyprland): exempt pinentry dialog from terminal swallowing 2026-07-12 16:22:59 +02:00
daniil-berg de6c3993cc feat(systemd): add shutdown/boot hang diagnostics module
Shutdown stalls are hard to debug because journald is torn down mid-way,
so late hangs never reach the journal. `modules/shutdown-debug.nix`
exposes `local.shutdownDebug.*`: verbose systemd logging routed to kmsg
(recoverable from pstore after a forced power-off), an opt-in tty9 debug
shell, and a shortened `DefaultTimeoutStopSec` preset (system + user) so
a hung unit is killed and logged in seconds instead of spinning at 90s.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 14:47:30 +02:00
daniil-berg 98eb0f87ba feat(waybar): highlight active workspace and flag urgent ones
Style the `hyprland/workspaces` buttons so the focused workspace is
distinguishable when several are occupied: white text, darker
background, blue underline; urgent workspaces turn red.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 08:01:41 +02:00
daniil-berg d8d86aadcb fix(hyprland): repair master-width, fullscreen, and brightness binds
- `$mod+h`/`l` used dwindle's `splitratio`, a no-op in the master layout;
  switch to `mfact` so they actually resize the master area.
- `$mod+f` ran `fullscreen 1` (maximize, bar/gaps kept); swap so `$mod+f` is
  true fullscreen and `$mod SHIFT+f` maximizes.
- add `$mod+space` `swapwithmaster` (dwm-style zoom).
- the `XF86MonBrightness` binds called `brightnessctl`, which was never
  installed; add the package. It writes via the active logind session.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 07:56:59 +02:00
daniil-berg c375a15561 feat(hyprland): swallow GUI windows spawned from foot into the terminal
A viewer opened from a foot shell (zathura/imv, incl. from mc) now hides
the terminal and takes its place, restoring it on close. Requires
standalone foot: server/client mode shares one process across all
windows, so PID-based swallow cannot tell them apart. `$mod+Return` runs
`foot`, not `footclient`, and the `foot --server` exec-once is dropped.
2026-07-11 14:01:04 +02:00
daniil-berg 08a14d52f2 feat(mc): make the F2 menu overridable via local.mc.menu
Expose the user menu as a `types.lines` option instead of a baked source
file. The shipped menu is a `mkBefore` definition (not a `default`, which a
consumer definition would drop), so `local.mc.menu = "…"` appends entries
after the baseline and `lib.mkForce "…"` replaces it wholesale.

`ini` stays a baked source file: it is section/key=value, so append-to-extend
risks duplicate keys — not a safe override path.
2026-07-10 23:07:16 +02:00
daniil-berg eab578e699 feat(mc): add midnight commander with declarative config
Public baseline module: installs `mc` plus `ouch` (backs the F2 pack/unpack
entries, archive format inferred from the extension), and ships `ini`, `menu`,
and a generated `panels.ini` into `$XDG_CONFIG_HOME/mc`.

`local.mc.otherDir` exposes the other-panel start dir as an option defaulting
to `config.home.homeDirectory`, so the one personal value isn't baked in. The
F2 user menu is trimmed to the entries that match this config (imv/zathura/mpv
openers, ouch pack/unpack, man view); the stock rcp/uudecode/news/latex cruft
is dropped. `auto_save_setup=false` keeps mc from rewriting the read-only store
symlinks on exit.
2026-07-10 22:46:32 +02:00
daniil-berg 8f9eff1640 feat(librewolf): expose package as an overridable option
Move librewolf out of the bare package list into its own module declaring
`local.librewolf.package` (default pkgs.librewolf), mirroring texlive. Lets a
consumer swap the wrapped package — extraPolicies/extraPrefs — to share
extensions and an about:config baseline across profiles without editing the
module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:19:40 +02:00
daniil-berg 3e093b02d1 docs: explain how consumers override public module defaults
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 09:00:50 +02:00
daniil-berg b907a39c41 feat(home): add pandoc with texlive for PDF output
texlive scheme is the `local.texlive.package` option (default scheme-medium)
so consumers can swap schemes without editing the module; TEXMF* vars keep
its cache/config out of $HOME. pandoc PDF defaults to xelatex — pdflatex
fails on combining Unicode (e.g. U+0308 in decomposed ä).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 09:00:33 +02:00
daniil-berg c1ec7401d1 feat(home): add pv to packages 2026-07-09 07:43:42 +02:00
daniil-berg 80c90c03ae feat(python): manage python with uv via nix-ld 2026-07-08 14:32:05 +02:00
daniil-berg 53f079c242 feat(home): add jq to packages 2026-07-08 11:25:15 +02:00
daniil-berg e6d96725ad feat(home): put ~/.local/bin on PATH 2026-07-08 10:49:45 +02:00
daniil-berg f9c3dad584 fix(desktop): suppress hyprland default wallpaper flash on login
awww starts after the compositor, so hyprland painted its bundled
splash until the real wallpaper landed. Disable it via `misc`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 10:40:10 +02:00
daniil-berg 270ffa8208 fix(ssh): give ssh-agent askpass env for verify-required sk keys
The agent, not the client, collects the FIDO PIN when signing with an
agent-held verify-required `sk-ssh-ed25519` key. Its systemd user service
started with a minimal env lacking `SSH_ASKPASS`, so those signatures failed
as "incorrect passphrase supplied to decrypt private key". Set `SSH_ASKPASS`
and `SSH_ASKPASS_REQUIRE=force` on the unit so the agent can pop pinentry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 10:21:14 +02:00
daniil-berg b6f9a9beec chore(git): drop github:/gh: remote rewrite rules
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 09:37:18 +02:00
daniil-berg 0c2ae04cdf feat(home): enable ssh-agent user service
gnome-keyring 50 dropped its ssh component and gpg's ssh support is off,
so there was no agent at all — SSH_AUTH_SOCK unset, `ssh-add` failed.
Keys stay added-on-demand (`AddKeysToAgent = "no"` in the inventory).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 07:58:29 +02:00
daniil-berg eb8693e853 fix(desktop): dark ssh-askpass pinentry via hyprland env
QT_QPA_PLATFORMTHEME=gtk3 (what makes Qt apps read Adwaita-dark) reaches
the systemd-user env — so gpg-agent's signing pinentry is dark — but not
Hyprland's children, so the shell-spawned ssh askpass pinentry launched
without it and came up light. Export it in the compositor env so every
session child inherits it. Keeps pinentry-qt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 22:02:02 +02:00
daniil-berg 7b44fe8bf1 feat(desktop): dark fuzzel, curated launcher, dmenu power menu
Fuzzel ignores the portal color-scheme, so set its palette explicitly to
match waybar. Hide non-launcher `.desktop` entries (foot variants, mpv/
umpv, zathura, nvim) via `noDisplay` shadows. Replace the per-action
app-list power entries with a `$mod+Backspace` `fuzzel --dmenu` power
menu (Log Out / Reboot / Shut Down), colored Papirus icons.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 20:36:52 +02:00
daniil-berg b2fabbc764 feat(desktop): dark-mode Qt/GTK apps via portal color-scheme
Qt apps (keepassxc, pinentry-qt) rendered light while the GTK side was
Adwaita-dark. keepassxc's `auto` theme reads dark/light only from the
xdg-desktop-portal `color-scheme` value, which the gtk portal serves from
dconf `org/gnome/desktop/interface/color-scheme` — unset, so it reported
"no preference" and fell back to light. Set it to `prefer-dark`.

Also route Qt through the `gtk3` platform theme (`libqgtk3` ships in
qtbase, unlike an external `adwaita-qt` style plugin which nixpkgs' baked
`QT_PLUGIN_PATH` makes unreachable), and set the GTK prefer-dark flag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:26:38 +02:00
daniil-berg 5172ca4d18 feat(desktop): Print-key screenshots via grim/slurp
Bare Print grabs the whole screen to a timestamped PNG under
~/Pictures/Screenshots; $mod selects a region (slurp), SHIFT sends to the
clipboard instead. A mako toast confirms each capture. Adds grim/slurp and
enables xdg.userDirs for the Pictures target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 14:09:51 +02:00
daniil-berg 46cebeb8fd fix(desktop): add GTK portal so file dialogs work
Home-manager's Hyprland module enables `xdg.portal` and pins the portal
search dir to the user profile with only the Hyprland backend, which has
no FileChooser implementation. File dialogs in Chromium/Electron apps
(signal, brave) fail with a DBus "No such interface
org.freedesktop.portal.FileChooser" error. Add `xdg-desktop-portal-gtk`
at the home-manager layer (system-level extraPortals aren't in the pinned
dir) and route FileChooser to it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 13:56:41 +02:00
daniil-berg f35037387c feat(desktop): run Chromium/Electron apps natively on Wayland
Set NIXOS_OZONE_WL=1 so nixpkgs' chromium/electron wrappers inject the
Ozone Wayland flags. This is a Wayland-only session, so the XWayland
fallback is pure downside (blurry fractional scaling, extra hop).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 13:56:05 +02:00
daniil-berg d43381727d fix(desktop): don't prompt on ssh presence/confirm askpass calls
Forced askpass routes the "Confirm user presence" touch notifications
(SSH_ASKPASS_PROMPT=none) through the helper too, which blindly asked for a
PIN — three dialogs per push. Only prompt for the real passphrase; let the
informational calls succeed silently (the FIDO touch is hardware-enforced).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 08:54:48 +02:00
daniil-berg 2cba23b804 fix(desktop): drive ssh askpass via pinentry-qt
`pkgs.ksshaskpass` no longer exists top-level (moved under kdePackages) and
would drag in ~1 GB of KDE Frameworks. Reuse the pinentry-qt already pulled
for GPG through a small SSH_ASKPASS wrapper instead: no new GUI toolkit, and
ssh PIN prompts match the commit-signing dialog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 08:45:11 +02:00
daniil-berg 0d6b8ca13a feat(desktop): GUI askpass for ssh passphrase/PIN prompts
Add ksshaskpass and point SSH_ASKPASS at it, without forcing: a tty still
prompts inline, but a caller may set SSH_ASKPASS_REQUIRE to route the prompt
to the GUI (e.g. a headless context driving `git push`).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 08:32:19 +02:00
daniil-berg 238528f961 feat(desktop): provide Secret Service via gnome-keyring
Bare Wayland session ships no `org.freedesktop.secrets` provider, so
libsecret/qtkeychain apps can't persist credentials. Run gnome-keyring
and unlock it at the greetd login via PAM.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 08:18:59 +02:00
daniil-berg 213d2d0b5b feat(home): drag to move/resize windows with $mod+mouse
Reach oversized floating dialogs (GTK pickers) whose confirm button
lands off-screen on short displays.
2026-07-06 20:47:05 +02:00
daniil-berg 7437ed9dc0 feat(home): add libreoffice 2026-07-06 20:46:55 +02:00
daniil-berg 60d1d89d04 fix(media): rebind imv open-in-editor from g to e
`g` is reserved by imv's `gg` first-image chord.
2026-07-06 20:46:35 +02:00
daniil-berg 0731e78003 feat(media): add zathura pdf/document viewer
minimal keyboard-driven viewer; bundled mupdf backend covers PDFs out of the
box. yank selection to the wayland clipboard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:35:54 +02:00
daniil-berg 1e163fe025 feat(media): add mpv and imv media viewers
new `modules/media.nix`: mpv (with mpv-gallery-view) for video/audio, imv for
images. imv key binds run per-file actions — copy path via `wl-copy`, rotate/
flip via `magick`, delete, open in gimp, show `mediainfo`. wallpaper via awww
plus a `setbg` wrapper (symlink to ~/.local/share/bg + live push); awww-daemon
and boot restore wired as hyprland exec-once. add mako as the notification
daemon backing the notify-send toasts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:32:51 +02:00
daniil-berg 24b7930363 feat(git): add logs and logo log aliases 2026-07-05 15:50:12 +02:00
daniil-berg aee4d0aa15 chore: initial commit 2026-07-05 15:40:35 +02:00