273 Commits

Author SHA1 Message Date
kenji 400b1a89d2 remove(hypr): hypr-window-rules is removed
for unknown reason, it slows down firefox
2026-06-07 09:19:58 -05:00
kenji f4bb5e4ca8 fix(bitwarden): resize, center, and fix background execution
- Float to 600x800 centered on the active monitor after title match
- Fix socat -u so the daemon works when launched in the background
- Add debug logging to /tmp/hypr-window-rules.log

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 13:03:58 -05:00
kenji 1a435a8676 add(bitwarden): added window rule for bitwarden extension via socket listening 2026-05-31 12:47:43 -05:00
kenji 53f9e2d925 feat(hyprpaper): now hovers over previously selected wallpaper 2026-05-31 12:21:53 -05:00
kenji c85ba7f69b fix(matugen): source dominant color as priority
it will no longer prompt user to pick a color
2026-05-31 12:10:59 -05:00
kenji 263133a86a fix(matugen): update to version 4.1.0
issue regarding old version as to error change of color
2026-05-31 12:02:50 -05:00
kenji 4c37e35d2c fix(monitor): removed HDR
deadlock is not compatible with HDR (will have graphical issue)
2026-05-31 11:48:10 -05:00
kenji 99f57dca0c fix(monitor): DP-1 sdrbrightness has incorrect syntax 2026-05-30 10:36:12 -05:00
kenji b5f2538c19 update(hyprland): switched to hyprland 0.55.1 2026-05-28 12:12:21 -05:00
kenji 91f91212db update(apps): vicinae updated 2026-05-28 10:14:27 -05:00
kenji 9071abeacc fix(steam): steam now only shows up on special workspace. 2026-05-28 09:27:09 -05:00
CLAUDE AI f7ab887ed0 revert(hypr): remove game-focus-watcher, restore steam rules
Keep only DP-1 forcing changes: gamingMonitor variable, monitor rules
for steam_app/mkGameRules, gaming-focus script, and SUPER+G binding.

Remove game-focus-watcher (caused game freeze on workspace switch).
Revert steam workspace rule back to title:Steam only.
Revert ghostty exec-once order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 08:18:42 -05:00
CLAUDE AI fe0d006f2e fix(hypr): reliable gaming workspace focus across monitors
- Add gaming-focus script: closes special workspace on DP-1 via
  --batch dispatch (fixes async race), then focuses gaming workspace;
  replaces raw workspace binding for SUPER+G
- Add game-focus-watcher: listens on Hyprland socket, auto-focuses
  gaming workspace when a game launches regardless of current monitor
- Fix monitor 0 → DP-1 in mkGameRules and steam_app windowrules
- Fix steam dialogs leaking to normal workspaces (broaden workspace
  rule from title:Steam to all class:steam)
- Extract gamingMonitor variable as single source of truth
- Drop redundant workspace dispatch after togglespecialworkspace to
  prevent game freeze on special→gaming transition

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 08:13:47 -05:00
CLAUDE AI 40b7db2c00 fix(hypr): reliable gaming workspace focus across monitors
- Add game-focus-watcher: listens on hyprland socket, auto-focuses
  gaming workspace when a game opens, closing any special workspace
  on DP-1 first via --batch to avoid async dispatch races
- Add gaming-focus script: SUPER+G now handles special workspaces on
  DP-1 regardless of focused monitor, with toggle-back behavior
- Fix steam windowrule to send all class:steam windows to special:steam,
  not just title:Steam, preventing dialogs leaking to normal workspaces
- Fix monitor 0 -> monitor DP-1 in mkGameRules and steam_app rules
  so games always launch at correct resolution on the gaming monitor
- Extract gamingMonitor variable as single source of truth
2026-05-28 07:57:33 -05:00
kenji 4205ab5429 fix(firefox): now used as default instead of chromium
there were instance where chromium is opened by default.
2026-05-25 07:54:52 -05:00
kenji 8c43b183eb add(flatpak): some auto-installation on .flatpak extension.
will remain unused for now...
2026-05-24 22:35:33 -05:00
kenji 8c5200d2fb add(nixos): flatpak support
used for deadlock mod manager flatpak
2026-05-24 22:16:57 -05:00
kenji 38ba89c2b7 update(nix): updated nixpkgs 2026-05-21 20:59:55 -05:00
kenji d22beb4580 fix(hypr): plugins future proofing via following hyprland pkgs
although hyprlandPlugins is an easy way to handle plugins, it is not
great due to pkg incompatibility.
2026-05-21 20:59:17 -05:00
kenji ccbd2362b2 upd 2026-05-17 18:51:07 -05:00
kenji 9b85f9edd5 upd 2026-05-07 11:45:52 -05:00
kenji 459ad6081b fix(mpv): changed size again for testing 2026-05-07 11:42:09 -05:00
kenji 1c1ba8b776 add(hyprland): workspace-toggle
workspace-toggle force workspace toggle between special and nonspecial;
improve user intuitive action.
2026-05-07 11:34:56 -05:00
kenji f76b350d94 feat(waybar): workspace 6-... replaced with 1-5
visual clarity
2026-05-07 11:30:59 -05:00
kenji 25ad6502fc feat(cursor): replaced cursor with modern ice bibata
for visual clarity
2026-05-07 11:30:27 -05:00
kenji ba8c0bdf3d refactor(optional-apps): wireshark removed
finished with testing
2026-05-07 11:29:49 -05:00
kenji c161673102 fix(wireshark): removed dumpcap 2026-05-07 11:29:16 -05:00
kenji 6929369c28 feat(mpv): size change 2026-05-07 11:29:00 -05:00
kenji ee4ab0e8a6 add(CLAUDE): more info 2026-05-07 09:00:08 -05:00
kenji f7108a173a add(nixos): wireshark and her tools
used for testing wh80 keyboard
2026-04-11 07:46:30 -05:00
kenji 0a3f0ada27 refactor(apps): removed redundant via
i added `via` originally to test out qmk keyboard, but it turns out to
be redundant.
2026-04-04 17:14:14 -05:00
kenji 74699ff880 add(anki): set .apkg files open to anki by default
mostly a personal taste. may adjust later if conflict arise
2026-04-04 17:10:31 -05:00
kenji 1b5cf2cf39 fix(yazi): can open non-assigned extensions again
needed to change a few lines to enable defaults again.
2026-04-04 17:09:47 -05:00
kenji a4f0cbb017 refactor(firefox): moved hypr rule firefox opacity to firefox default.nix instead.
organized even more.
2026-03-29 08:11:10 -05:00
kenji 6b5dedb3e6 add(firefox): bitwarden floats 2026-03-29 08:09:04 -05:00
kenji 2f11bf580d feat(gaming): added godot 2026-03-29 07:49:03 -05:00
kenji f58cd9a516 add(system): python added [finally!!] 2026-03-26 18:36:02 -05:00
kenji 7bf2c6fea2 add(nixos): mouse-wakeup 2026-03-21 19:08:49 -05:00
kenji ba09321f6b feat(yazi): added open with options 2026-03-19 16:30:05 -05:00
kenji 7d938288ab add(print): added print support 2026-03-19 16:29:47 -05:00
kenji 9f16735547 feat(btop): updated binds for btop-power
this allows for
2026-03-19 16:29:35 -05:00
kenji 19a4870450 add(system): btop.nix
gives more permission to btop (specifically for reading CPU power)
2026-03-15 17:22:25 -05:00
kenji f33330b2d6 add(system): amdcpu.nix 2026-03-15 17:10:44 -05:00
kenji 2de8603b49 fix(gaming): revamped how steam and gaming works
1. hyprbars are now disabled for steam
2. set float for steam extended windows (e.g., settings, friends list)
3. fix game `properties` forced to `gaming` workspace
2026-03-15 17:04:15 -05:00
kenji 13524322a2 revert(gaming): move steam back to special workspace
Reverts the recent change that moved Steam into a named workspace. Steam is now handled via a special workspace again. The Waybar module configuration has also been updated to reflect this change.
2026-03-15 09:22:00 -05:00
kenji ecb13d8b19 feat(hypr): firefox will always have the same opacity as active.
vidoes are now easier to look at even when unfocused
2026-03-14 09:02:06 -05:00
kenji 3558d604eb fix(firefox): Use noblur rule to prevent blur
Resolve the persistent issue of Firefox windows blurring when inactive by:
- Removing the ineffective  rule from .
- Implementing the direct  window rule for all relevant Firefox classes (, , ), ensuring explicit exemption from Hyprland's blur effect.
2026-03-14 08:45:13 -05:00
kenji fffe6bc7cc fix(hyprland): Resolve Firefox blur issue
Address the issue where Firefox windows were still blurring when inactive, despite a specific window rule.
- Refined the  in  to use a simplified and more robust regex, , ensuring it targets all relevant Firefox profiles.
- Adjusted the opacity for inactive Firefox windows to  (from ) in , as a potential workaround for Hyprland's blur handling with fully opaque windows.
- Ensured  is  and  is  in  for the global blur effect.
2026-03-14 08:40:32 -05:00
kenji 1c71784ac9 feat(hyprland): Refactor workspaces and add blur effect
Refactor Hyprland configuration to:
- Move Steam and Music from special workspaces to unique, named workspaces for better integration into the regular workflow.
- Update Waybar's workspace module to correctly display icons for these new named workspaces and filter them out from the special workspaces module.
- Implement a global blur effect for inactive windows, with a specific exception to keep Firefox windows fully opaque, enhancing focus on active content.
2026-03-14 08:29:12 -05:00
kenji dca67e19bc fix(gaming): now only stay focus on selected games
an issue in `Deadlock` does not focus its mouse even when the player is
not in the menu
2026-03-14 07:54:19 -05:00
kenji 4a9aa15b77 feat(hyprlock): removed cyberpunk random-text
it does not fit the theme very well.
2026-03-09 17:47:07 -05:00
kenji 86f044235a fix(btop): monitor is now setup to HDMI-A-1 (the mini-monitor) instead of DP-1 2026-03-09 08:38:02 -05:00
kenji 5b6477cab6 feat(btop): added ctrl+shift+esc keybind for preset 2 2026-03-08 11:39:16 -05:00
kenji c86358010c feat(btop): autostart btop on misc monitor
note: may not work on very small monitor. needs to auto change to `btm`
if conditions are met.
2026-03-08 11:36:13 -05:00
kenji 318718aabd feat(btop): added new preset for minimalistic configuration
note that it may not work on small monitors. keep that in mind. also the
new preset is located at `btop -p 2`
2026-03-08 11:29:05 -05:00
kenji d592750de7 move(btm): switched to apps-optional 2026-03-08 11:07:41 -05:00
kenji 688f8e8a1e feat(btm): added current usage to the field 2026-03-08 11:05:12 -05:00
kenji c986952c50 fix(btm): missing parameters 2026-03-08 10:35:20 -05:00
kenji d914905d01 add(apps): bottom
Added `btm`; a lightweight, diagnostic application. It is preferrable to
`btop`.
2026-03-08 10:31:56 -05:00
kenji 784e44901d fix(btop): enable rocmSupport for AMD GPU monitoring
Fixes btop not displaying GPU information by compiling it with rocm support enabled.
2026-03-08 10:18:41 -05:00
kenji 35707279b4 fix(asrock): spacing for nct
note that this is read-only. the nct6683d did not work
2026-03-08 10:15:07 -05:00
kenji 4fb3325326 add(asrock-a620i): new setup for testing fan
by default, system does not automatically detect fan configuration for
chassis and the cpu. quite inconvenient to setup fan speeds
2026-03-08 08:48:01 -05:00
kenji ae3a43d25d feat(amd): added overdrive for testing
may remove later. tested for fan noise.
2026-03-07 07:19:19 -06:00
kenji acadd94b31 fix(zathura): added ocr for easier ctrl+f
zathura had an issue where pdf's cannot be read via `find word` due to
the process being unable to read `image text`. a solution is to convert
it to ocr.
2026-03-07 07:18:57 -06:00
kenji 7cadace240 feat(binds): exchanged wiremix bind to that of steam
steam is mouse-based application; preferrable to have a commonly used
bind use only one hand.
2026-03-07 07:17:04 -06:00
kenji f097c9e15f feat(hypr): re-enabled HDR and removed hyprsunset
HDR is still quite buggy with the current ASUS ultrawide monitor.
2026-03-07 07:17:04 -06:00
kenji 9b5134c32d fix(swayosd): capslock improper interpretation 2026-02-28 13:40:14 -06:00
kenji e39f5d46ff minor change 2026-02-26 18:50:15 -06:00
kenji b21bcf5e7a fix(hypr): keyboard formatting fix 2026-01-30 20:10:32 -06:00
kenji 0bb78842c0 feat(gaming): comment out stayfocused rule 2026-01-25 16:44:01 -06:00
kenji d148acd6dd fix(gaming): add Deadlock window classes and enable stayfocused
- Adds 'project8' and 'citadel' to the games list to correctly match Valve's Deadlock window class.
- Enables 'stayfocused' rule in mkGameRules to prevent focus loss.
2026-01-25 16:43:07 -06:00
kenji 00011ed365 fix(gaming): removed workspace 2026-01-21 20:05:57 -06:00
kenji 54737695af feat(gaming): unify and automate game window rules
Refactors 'modules/home/gaming.nix' to use a unified 'mkGameRules' function.
Applies full gaming rules (monitor 0, workspace gaming, immediate, fullscreen) to:
- Steam apps (class:^steam_app_\d+$)
- Gamescope, Lutris, Heroic
- Wine/Proton windows
Preserves manual overrides in the 'games' list.
2026-01-21 20:02:25 -06:00
kenji ac3232ac80 feat(yazi): hide hidden files by default 2026-01-20 11:07:12 -06:00
kenji 5bb996c93f add(apps): libreoffice 2026-01-20 10:27:44 -06:00
kenji 8a7b475562 feat(hyprland): add OCR bind (SUPER+ALT+E) and remove TODO 2026-01-18 10:33:37 -06:00
kenji dccc191c24 add(firefox): new-tab-override 2026-01-17 09:10:57 -06:00
kenji 25477c0f7c feat(yazi): changed sort directory first to false 2026-01-17 08:51:36 -06:00
kenji 6351495541 add(utils): appimage-run 2026-01-17 08:51:16 -06:00
kenji 428488f11d feat(hyprland): improve gaming experience and workspace navigation
- Implemented a modular gaming configuration with a local games list.
- Added dynamic window rules for games: monitor 0, dedicated 'gaming' workspace, fullscreen, immediate mode, and stayfocused.
- Enabled 'allow_tearing' to support immediate mode for reduced latency.
- Created a dedicated 'name:gaming' workspace bound to monitor 0 with a 'SUPER+G' shortcut.
- Enabled 'workspace_back_and_forth' for intuitive workspace toggling.
2026-01-16 19:36:10 -06:00
kenji f8e843ec94 feat: add global theme mode and Yazi shortcut
- Added theme.mode to config.nix for global dark/light mode control.
- Updated Matugen to apply GTK dark mode preferences based on the global theme.
- Added a Hyprland bind (SUPER+X) to launch Yazi via uwsm.
2026-01-16 14:38:41 -06:00
kenji 679f2e8f6b fix(zathura): preserve original colors in dark mode
Enabled 'recolor-keephue' to prevent documents from becoming purely monochrome
when recolor mode is active. This ensures images and colored text retain their
hue while still adapting brightness for the theme.
2026-01-15 16:18:18 -06:00
kenji 9aae7d6df9 feat(yazi): sort by newest (mtime) as default 2026-01-15 16:17:22 -06:00
kenji c6cd00f955 feat(yazi): enable full mouse support
Added 'mouse_events' to the Yazi manager configuration, enabling click, scroll,
touch, move, and drag interactions for better navigation and control.
2026-01-15 16:16:13 -06:00
kenji 33cb851539 fix(yazi): set as default handler for directories
This fixes the issue where "Show in folder" (e.g., in Firefox) would incorrectly
open other applications like Zathura. By explicitly associating 'inode/directory'
with 'yazi.desktop', folders will now open in Yazi as expected.
2026-01-15 16:14:27 -06:00
kenji 5ec7f5edc7 style(matugen): update zathura template to mimic pywal aesthetic
- Flattened UI elements (statusbar, inputbar, notifications) to use the
  surface background color, creating a seamless look similar to pywal themes.
- Changed highlight colors to use 'tertiary' and 'secondary' accents for
  better visibility and style consistency.
- Updated completion highlights for higher contrast.
2026-01-15 16:11:59 -06:00
kenji e7e5226c87 fix(zathura): use absolute path for matugen config and ensure file exists
- Updated 'extraConfig' to use an absolute path for the 'zathura-matugen'
  include, fixing path resolution issues.
- Added a home activation script to create an empty 'zathura-matugen' file
  if it doesn't exist, preventing zathura from crashing on fresh installs
  before matugen has run.
2026-01-15 16:08:45 -06:00
kenji b550064a15 fix(hyprland): set warps to false for stability 2026-01-15 15:56:30 -06:00
kenji 9ff47e94b2 fix(swayosd): ensure swayosd starts reliably
- Add explicit 'systemctl --user start swayosd' to Hyprland exec-once
- Harden systemd service definition with proper dependencies and targets
2026-01-15 15:52:35 -06:00
kenji 3dc170984b docs: add TODO to revise 2026-01-14 19:20:57 -06:00
kenji 97a23a26dd add(binds): focus between nonfloating and floaters 2026-01-14 19:20:13 -06:00
kenji da383a3526 feat(apps): add anki flashcards 2026-01-14 18:31:38 -06:00
kenji ad8b59f314 feat(apps): add zathura document viewer with matugen theming 2026-01-14 16:14:17 -06:00
kenji cfcf9d6f3a fix(nextcloud): removed redundant setsid 2026-01-14 16:10:52 -06:00
kenji 44af726a53 fix(nextcloud): use uwsm app for nexcloud 2026-01-14 09:14:42 -06:00
kenji 35f810dcf1 feat(nextcloud): add hyprland autostart 2026-01-13 16:27:47 -06:00
kenji af331d967a feat(apps): add nextcloud client 2026-01-13 16:25:45 -06:00
kenji d54fa4e999 feat(ghostty): optimize configuration 2026-01-11 20:11:42 -06:00
kenji 0197c58ea1 fix(waybar): resolve keybinding conflicts for system popups 2026-01-11 19:47:57 -06:00
kenji 1b4cfbe350 feat(waybar): add hyprland keybindings for system popups 2026-01-11 19:46:07 -06:00
kenji c4ed00e6c8 refactor(terminal): more modularity for default terminal font 2026-01-11 19:32:56 -06:00
kenji b720c1ff02 docs: add FIXME for nixovim 2026-01-11 19:32:29 -06:00
kenji 9ee5f40aa8 docs: add FIXME for waybar popup 2026-01-11 19:32:11 -06:00
kenji 2ef1d58ea7 fix(power): writes disabled on certain usb devices to avoid random wake-ups 2026-01-11 19:02:18 -06:00
kenji 7281eedf56 feat(cursor): cursor changed to catppuccin mocha dark 2026-01-11 19:00:58 -06:00
kenji 8394a4cf35 fix(waybar): correctly launch btop 2026-01-11 19:00:43 -06:00
kenji f50c57c7b2 docs: add fixme for jellyfin-tui 2026-01-11 19:00:21 -06:00
kenji 795a7babd0 fix(cursor): removed invasive expansion of cursor at certain threshold 2026-01-11 19:00:15 -06:00
kenji 97d50851f6 feat(hyprbars): add double click to expand with fullscreen 1 2026-01-11 14:53:23 -06:00
kenji 870c8d2df3 fix(waybar): btop now works 2026-01-11 14:52:49 -06:00
kenji 80e38516a6 refactor(cursor): migrate hyprcursor for modularity 2026-01-11 14:52:49 -06:00
kenji 04627242a8 add(waybar): on right click, dispatch overview 2026-01-11 14:04:51 -06:00
kenji bcad6c2f69 docs: add FIXME for calculator 2026-01-11 13:59:28 -06:00
kenji 0940fd31d7 fix(swayosd): added auto-restart functionality 2026-01-11 13:59:21 -06:00
kenji 9fc1763073 feat(textfox): updated rev 2026-01-11 13:54:21 -06:00
kenji 3d51e1db83 feat(firefox): now uses web-app for versatility 2026-01-11 13:53:48 -06:00
kenji 992ca558dd feat(swayimg): wrapper dynamically adjust image size without overlapping waybar 2026-01-11 13:24:45 -06:00
kenji 72c94dbd63 fix(yazi): expanded image_bound for versatilty 2026-01-11 13:09:57 -06:00
kenji 0a4bfdfab8 remove(apps): imv replaced by yazi 2026-01-11 13:09:18 -06:00
kenji cfbc56ab6d remove(firefox): web-app css set to default, awaiting textfox migration 2026-01-11 13:09:04 -06:00
kenji 516fe436e6 feat(yazi): use TUI to acquire files from sites. 2026-01-11 12:51:14 -06:00
kenji 373f3f1f3f refactor(apps): switched gemini to apps-optional 2026-01-11 12:10:57 -06:00
kenji 283f572371 Revert "feat(yazi): enable yazi as system-wide file chooser"
This reverts commit f345fef540.
2026-01-11 12:01:43 -06:00
kenji 272b5b8545 remove(yazi): shell script was not working 2026-01-11 11:55:16 -06:00
kenji f345fef540 feat(yazi): enable yazi as system-wide file chooser
Configure xdg-desktop-portal-termfilechooser to use yazi (via ghostty) for file selection dialogs in portal-aware apps like Firefox. Includes a wrapper script and Hyprland window rules.
2026-01-11 11:33:08 -06:00
kenji dd9281dcf1 docs: removed some redundant TODO 2026-01-11 11:29:07 -06:00
kenji 14b873d704 fix(matugen): correct sidebar text contrast in GTK file picker
Explicitly set sidebar background and text colors in GTK3 and GTK4 templates to resolve white-on-white text issue in file dialogs.
2026-01-11 11:24:05 -06:00
kenji a793429622 revert: remove yazi image saving feature and portal changes 2026-01-11 11:18:50 -06:00
kenji d9f848f626 fix(firefox): change yazi bind to ;y and add logging 2026-01-11 11:17:23 -06:00
kenji 2d77a5d42e feat(firefox): add tridactyl yazi image saver, revert portal attempt 2026-01-11 11:12:10 -06:00
kenji 8d01f300be fix(yazi): add environment logging to picker 2026-01-11 11:03:42 -06:00
kenji 975b2c2002 fix(hypridle): changed lockscreen session to custom hakase-hyprlock 2026-01-11 11:02:34 -06:00
kenji f28ed60390 fix(yazi): add debug logging and correct portal config 2026-01-11 10:49:43 -06:00
kenji 63becaaa09 feat(hyprland): integrate yazi as global file picker via xdg-portal 2026-01-11 10:44:25 -06:00
kenji 78f6ede871 fix(hyprlock): removed strategies 2026-01-10 23:27:01 -06:00
kenji d34494d3be add(hyprlock): more text 2026-01-10 23:25:21 -06:00
kenji 7930757d88 add(hyprlock): more language greetings added 2026-01-10 23:18:41 -06:00
kenji f3517d04fc remove: some random mpv screenshot 2026-01-10 23:08:18 -06:00
kenji 5edc88fc23 fix(matugen): script converted to sh 2026-01-10 23:06:36 -06:00
kenji 461b1099ad add(matugen): auto-theme switch 2026-01-10 23:01:23 -06:00
kenji 51a35355df fix(vicinae): use the icons 2026-01-10 22:59:48 -06:00
kenji cc681ffe91 add(apps): ttyper 2026-01-10 22:54:24 -06:00
kenji 45213f1f7d add(apps): qmk as system 2026-01-10 18:36:59 -06:00
kenji 27f52450c3 fix(power): added udev game rules 2026-01-10 18:25:39 -06:00
kenji 4bfc554e35 fix(hypridle): decrease timeout 2026-01-10 17:44:56 -06:00
kenji 2558f4a9b0 fix(jellyfin): ensure autostart and modernize config
Forces autostart via Hyprland exec-once. Adds uosc, thumbfast, and better MPV defaults.
2026-01-07 19:44:27 -06:00
kenji 4e882084b1 add(wallpapers): lighthouse 2026-01-07 18:40:19 -06:00
kenji aa28cf999f add(jellyfin): jellyfin-mpv-shim 2026-01-07 18:40:11 -06:00
kenji 4a911de198 fix(amd): disable overdrive and lact
Disabling AMD GPU overdrive and LACT service to troubleshoot system freezes.
2026-01-07 18:39:35 -06:00
kenji a4f5cddcb2 refactor(system): consolidate kernel parameters
Moves all kernel parameters to modules/nixos/kernel.nix to avoid duplication and conflicts. Prioritizes quiet boot settings.
2026-01-07 18:37:50 -06:00
kenji bd75285889 add(apps): jellyfin-mpv-shim proper 2026-01-05 22:47:11 -06:00
kenji d263ea39f8 fix(jellyfin-mpv-shim): was not using template 2026-01-05 22:27:24 -06:00
kenji 002799deee add(matugen): new template 2026-01-05 22:20:33 -06:00
kenji 6f884ad114 add(binds): jellyfin 2026-01-05 22:02:08 -06:00
kenji 1f3c44afb7 add(hyprlock): now use 50 languages 2026-01-05 22:02:01 -06:00
kenji 7bc837aeaf fix(monitors): color and vrr are borked 2026-01-05 22:01:35 -06:00
kenji cd440d2b00 fix(monitor): movefocus was not owrking 2026-01-05 20:29:53 -06:00
kenji 5e3902c22c fix(monitor): position 2026-01-05 19:41:20 -06:00
kenji 7280b68f14 add(fonts): modular fonts 2026-01-05 19:26:30 -06:00
kenji 2b9067f87b add(vicinae): fallback if vicinae crashed 2026-01-05 18:39:00 -06:00
kenji 7fd73ba79e add(binds): vicinae calculator history and emoji picker 2026-01-05 18:32:22 -06:00
kenji 00f6c9840b feat(vicinae): add emoji picker bind 2026-01-05 16:08:10 -06:00
kenji 8da1baea93 feat(firefox): finalize modular web-app profile with new-tab-override
- Integrated New Tab Override extension for reliable per-profile redirection.

- Confirmed Tridactyl compatibility via 'set newtab about:newtab'.

- Polished autohide toolbox with solid background.
2026-01-05 16:01:39 -06:00
kenji 75d5fc850e revert(firefox): abandon tridactyl dynamic newtab, use extension
Returned to using New Tab Override extension with Tridactyl yielding control via 'set newtab about:newtab'. This proved most reliable.
2026-01-05 15:59:20 -06:00
kenji 283f6cd29f feat(firefox): implement URL-based dynamic newtab for tridactyl
Automatically sets the newtab page based on the initial active tab URL, enabling modular per-profile configuration.
2026-01-05 15:53:56 -06:00
kenji d3d9371e71 revert(firefox): use new-tab-override instead of tridactyl dynamic newtab
Tridactyl dynamic environment variables proved unreliable. Reverting to the verified extension-based solution.
2026-01-05 15:37:39 -06:00
kenji eec7fe5808 feat(firefox): implement robust modular newtab logic
Uses a shell-based environment check in tridactylrc to set the newtab URL dynamically, allowing per-profile overrides without hardcoding URLs.
2026-01-05 15:31:58 -06:00
kenji 683ceefae3 feat(firefox): finalize web-app profile with solid autohide and tridactyl integration
- Unified autohide for Tabs and Nav-bar with solid background.

- Implemented dynamic newtab via TRIDACTYL_NEWTAB env var.

- Cleaned up redundant new-tab-override extension.
2026-01-05 15:22:53 -06:00
kenji b8f28a6277 fix(firefox): redundant modules 2026-01-05 15:03:49 -06:00
kenji 73aab2452e style(firefox): finalize autohide toolbox for web-app profile
Successfully autohides both Tabs and Nav-bar using MrOtherGuy's strategy with a fixed trigger zone.
2026-01-05 15:03:00 -06:00
kenji 109fdb4672 style(firefox): improve autohide CSS for web-app profile
Ensures both tabs and address bar hide and reveal together seamlessly.
2026-01-05 14:48:18 -06:00
kenji 6281f9ea6f feat(firefox): implement dynamic tridactyl newtab via env var
Allows per-profile newtab overrides using TRIDACTYL_NEWTAB environment variable.
2026-01-05 14:42:18 -06:00
kenji edfb269308 feat(firefox): add new-tab-override to web-app profile
Ensures that new tabs and closed-tab fallbacks always redirect to the specified app URL.
2026-01-05 14:37:27 -06:00
kenji eed84ec64c fix(firefox): resolve syntax error in web-app profile 2026-01-05 14:32:24 -06:00
kenji ae7d017d2b feat(firefox): generalize youtube profile into modular web-app profile
- Renamed profiles/youtube.nix to profiles/web-app.nix.

- Refactored to accept id, name, and url as arguments.

- Added settings to force homepage on startup and new tabs.

- Disabled session restore and undo-close-tab for web-app profiles.
2026-01-05 14:31:20 -06:00
kenji e17b21ab69 feat(jellyfin): wrap mpv-shim in uwsm for better session management 2026-01-05 14:14:00 -06:00
kenji 59d29c6cea refactor(jellyfin): decentralize mpv-shim autostart
Move Hyprland autostart logic into the app's own module for better modularity.
2026-01-05 14:12:11 -06:00
kenji 29792a1307 feat(jellyfin): add jellyfin-mpv-shim for high-quality casting 2026-01-05 14:08:57 -06:00
kenji b86df062df feat(mpv): add uosc and thumbfast scripts for a minimalist UI 2026-01-05 14:01:54 -06:00
kenji b02be43aa0 feat(mpv): add hyprland window rules to match imv behavior 2026-01-05 13:58:00 -06:00
kenji 6d19db6577 feat: replace loupe with imv and update plymouth theme
- Replaced Loupe with imv for a keyboard-driven image viewer experience.

- Updated Plymouth logo with Firewatch-inspired ASCII art gradient.

- Updated Plymouth background color to match Firewatch palette (#2D112A).
2026-01-05 13:55:04 -06:00
kenji e8f35bf283 Revert "feat(hyprland): integrate force-switch script with split:workspace"
This reverts commit c656cf81d2.
2026-01-05 13:25:24 -06:00
kenji ec1e9a9b59 feat(plymouth): implement custom hakase theme based on omarchy assets 2026-01-05 13:22:08 -06:00
kenji f1fede7cd5 docs: update README.md to reflect multi-host support and project structure 2026-01-05 13:22:08 -06:00
kenji 9d3ba797d7 refactor(home): separate home-manager config per host (hakase/macbook) 2026-01-05 13:22:08 -06:00
kenji 39b190fcc3 refactor(user): switch to mutable users with initial password for easier bootstrapping 2026-01-05 13:22:08 -06:00
kenji b8df78e935 feat(nixos): scaffold macbook host for apple silicon (aarch64-linux) 2026-01-05 13:22:08 -06:00
kenji 425c429297 refactor(hyprland): final decentralization of rules and binds 2026-01-05 13:22:08 -06:00
kenji c656cf81d2 feat(hyprland): integrate force-switch script with split:workspace 2026-01-05 13:22:08 -06:00
kenji 2ed2e28ba2 refactor(hyprland): decentralize window rules and binds 2026-01-05 12:42:53 -06:00
kenji daa3ed6eef refactor(hyprland): decentralize exec-once and clean up app configs 2026-01-05 12:38:12 -06:00
kenji c640e5514e add(apps): fcitx5 on their own folder 2026-01-05 12:36:28 -06:00
kenji 796e311a29 refactor(general): organized more 2026-01-05 12:28:16 -06:00
kenji 5fe83ddc8a docs: add gemini.md 2026-01-05 12:27:19 -06:00
kenji 6167ca3d0a fix(waybar): add hakase-popup-launch 2026-01-04 22:08:11 -06:00
kenji 10374ba152 remove(rules): removed redundant rules 2026-01-04 21:07:24 -06:00
kenji f20d6fbe83 fix(popup): popup script was inconsistent, removed temp 2026-01-04 20:44:36 -06:00
kenji 4bb65bd5ec fix(power): does not work, so commented it 2026-01-04 20:42:57 -06:00
kenji 214f709b59 fix(bluetooth): was not working 2026-01-04 15:08:08 -06:00
kenji ae76a1b13b remove(hypridle): rmeoved tte-screensaver due to instability 2026-01-04 11:26:07 -06:00
kenji f4a2d28806 add(apps): mpv 2026-01-03 23:16:38 -06:00
kenji 483bd73ecd add(gaming): hardware support 2026-01-03 15:03:37 -06:00
kenji 3bb0844544 docs: added TODO 2026-01-03 15:03:18 -06:00
kenji 137576a9a9 add(nixos): power module udev 2026-01-03 14:56:48 -06:00
kenji ac265015eb add(TODO): stuff 2026-01-03 14:54:19 -06:00
kenji bb97da851d add(nixos): lact for amd 2026-01-03 14:54:09 -06:00
kenji 3b33aec48b docs: add credits 2026-01-03 11:20:53 -06:00
kenji 1694a23bf6 docs: added more feat desc 2026-01-03 11:12:04 -06:00
kenji 62a99d8992 docs: moved terminal windows 2026-01-03 11:10:28 -06:00
kenji 1d28b04845 docs: implemented screenshots 2026-01-03 11:09:39 -06:00
kenji 31a9de7979 fix(hyprlock): fix incorrect description 2026-01-03 11:08:12 -06:00
kenji 863d91a0f8 docs: added more screenshots 2026-01-03 11:07:55 -06:00
kenji 69a6571d5b docs: add screenshots sample 2026-01-03 10:58:10 -06:00
kenji 80ea4c9e55 remove(wallpapers): redundancies 2026-01-03 10:37:33 -06:00
kenji c82d3872a1 docs: fix minor mistakes 2026-01-03 10:15:57 -06:00
kenji d061d30426 docs: rewrite README with comprehensive configuration overview
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 10:11:47 -06:00
kenji 15b2c36247 add(README): migrated SOPS documentation to secrets/ 2026-01-03 10:09:11 -06:00
kenji 5443027e94 fix(binds): incorrect description corrected 2026-01-03 10:05:30 -06:00
kenji 8fbfe2f011 add(binds): binds for special workspace 2026-01-03 10:05:10 -06:00
kenji 31a2d191f9 fix(swayosd): mute works now 2026-01-03 09:53:43 -06:00
kenji 5788ef1bcd add(hyprpaper): rewrite pls 2026-01-03 09:53:20 -06:00
kenji 354db486bf add(waybar): FIXME 2026-01-03 09:53:09 -06:00
kenji bcf913e431 remove(config): removed FIXME 2026-01-03 09:51:54 -06:00
kenji 973d32228d remove(README): removed TODO 2026-01-03 09:46:26 -06:00
kenji f6afc23771 add(hypridle): tte-screensaver at 3min 2026-01-03 09:43:42 -06:00
kenji 1ed219c697 add(TODO): vicinae fallback 2026-01-03 09:43:29 -06:00
kenji 39aa8a421e Revert "fix(screensaver): fix shifting issue on tte-loop"
This reverts commit 40efab98b9.
2026-01-03 09:39:36 -06:00
kenji 40efab98b9 fix(screensaver): fix shifting issue on tte-loop 2026-01-03 09:35:26 -06:00
kenji aaa635f25e fix(screensaver): line increase to prevent branding from moving after the effect is finished 2026-01-03 09:25:28 -06:00
kenji 7a5c811ec7 fix(screensaver): finally works 2026-01-03 09:14:52 -06:00
kenji b656898f48 add(services): added upower for services 2026-01-02 15:37:14 -06:00
kenji aa7d9964a6 fix(hypridle): removed tte-screensaver temp 2026-01-02 14:49:41 -06:00
kenji da45e673af feat(branding): changed branding 2026-01-02 14:49:24 -06:00
kenji e87d4207b2 add(ghostty): screensaver! 2026-01-02 14:13:21 -06:00
kenji 897908da86 fix(hyprland): some stuff 2026-01-02 13:43:56 -06:00
kenji 404f272d83 add(screenshot): screenshot now saves and copies 2026-01-02 13:11:40 -06:00
kenji e0a6aa12e8 fix(firefox): removed initial startup 2026-01-02 13:02:00 -06:00
kenji 77583b9c8f feat(fastfetch): changed config 2026-01-02 12:52:48 -06:00
kenji d667dbdb91 refactor(hypr): separated even mooore 2026-01-02 12:26:36 -06:00
kenji a2acedf2bb refactor(hypr): separated exec-once to their corresponding apps 2026-01-02 12:00:26 -06:00
kenji b398d5b797 add(matugen): added qt support 2026-01-02 11:47:10 -06:00
kenji fc0c7d9405 feat(vicinae): close on unfocus 2026-01-02 11:47:04 -06:00
kenji 7d8f6ad78e add(hyprpolkit): finally works 2026-01-02 11:46:54 -06:00
kenji bb77bb6ab8 fix(random-text): truncated greeting 2026-01-02 11:28:57 -06:00
kenji a9aed4b7c8 add(vicinae): binds vimlike 2026-01-02 08:58:24 -06:00
kenji a6641d71d7 add(template): vicinae matugen 2026-01-02 08:32:14 -06:00
kenji c016d3ba66 fix(nix): fix substitution for vicinae 2026-01-02 08:07:18 -06:00
kenji 18e67e1c4c feat(vicinae): added configuration 2026-01-02 07:57:34 -06:00
kenji 6b3662c07c add(apps): vicinae 2026-01-02 07:47:53 -06:00
kenji bf279b426e add(TODO): more tasks 2026-01-02 07:45:03 -06:00
kenji 5b541fc4ad fix(screenshots): better binds 2026-01-02 00:33:54 -06:00
kenji ec70617dc2 add(apps): screenshot 2026-01-02 00:27:59 -06:00
kenji 321dbbe979 add(mako): notification 2026-01-02 00:07:33 -06:00
kenji b62e4cbafb add(apps): mako--a notification daemon 2026-01-01 23:47:05 -06:00
kenji 39fb2b4d27 add(TODO): added more TODOs 2026-01-01 23:45:26 -06:00
kenji 0327caa6d2 add(hyprland): hyprbars 2026-01-01 23:40:10 -06:00
kenji d224b12bab add(hyprland): hyprspace 2026-01-01 23:27:23 -06:00
kenji fdcabbe543 add(hypr): dynamic cursor 2026-01-01 22:09:53 -06:00
kenji 26e597e087 fix(hypr): adjusted transparency 2026-01-01 17:38:02 -06:00
kenji 7bdc88389b add(hyprlock): use no animation 2026-01-01 17:31:50 -06:00
kenji 237a7996f5 add(hyprlock): random-text 2026-01-01 17:07:24 -06:00
kenji a85014188f add(hyprlock): added typewriter animtaion 2026-01-01 16:56:02 -06:00
kenji f2f44f2fdd remove(hyprlock): typewriter for revise 2026-01-01 11:41:58 -06:00
kenji d71be6d7d9 add(nixos): input method 2026-01-01 11:26:09 -06:00
kenji 2cfa182da2 fix(hyprlock): slowed it down 2026-01-01 11:25:54 -06:00
kenji 36bc769452 refactor(hypr): organized a little more 2026-01-01 11:18:10 -06:00
kenji 4e9d47a886 fix(loupe): oversized images 2026-01-01 11:03:34 -06:00
kenji e73d9477f7 add(apps): added loupe 2026-01-01 10:58:54 -06:00
kenji 906ce21aaa add(hyprland): plugin is fixed! 2025-12-31 13:57:52 -06:00
kenji 588f1a17ca fix(monitors): fix multi-monitor setup 2025-12-31 13:57:30 -06:00
kenji 8a9569bb76 add(cursor): added rose pine hyprcursor 2025-12-31 13:57:30 -06:00
kenji 6e9949ac39 feat(hyprlock): decreased blink count 2025-12-31 13:57:30 -06:00
kenji 74446a9e81 add(apps): added delfin 2025-12-31 13:57:30 -06:00
130 changed files with 4100 additions and 847 deletions
+73 -32
View File
@@ -5,9 +5,15 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Build Commands
```bash
# Rebuild and switch to new configuration
# Rebuild and switch to new configuration (desktop x86_64)
sudo nixos-rebuild switch --flake ~/.config/nixos/#hakase
# Rebuild MacBook configuration (aarch64)
sudo nixos-rebuild switch --flake ~/.config/nixos/#macbook
# Dry-run build to check for errors without applying
sudo nixos-rebuild build --flake ~/.config/nixos/#hakase
# Manage SOPS secrets
nix-shell -p sops --run "sops secrets/secrets.yaml"
nix-shell -p sops --run "sops updatekeys secrets/secrets.yaml"
@@ -15,65 +21,100 @@ nix-shell -p sops --run "sops updatekeys secrets/secrets.yaml"
## Architecture Overview
This is a modular, flake-based NixOS configuration for a single host (`hakase`).
This is a modular, flake-based NixOS configuration supporting two hosts: `hakase` (x86_64 desktop) and `macbook` (aarch64 Apple Silicon).
### Key Entry Points
- `flake.nix` - Declares inputs and creates NixOS configuration
- `config.nix` - Central configuration values (username, hostname, paths, theme settings, bookmarks)
- `hosts/hakase/configuration.nix` - Host-level entry point that imports system modules
- `flake.nix` - Declares inputs and creates both NixOS configurations (hakase, macbook)
- `config.nix` - Central configuration values separated by host (hakase, macbook keys)
- `hosts/{hakase,macbook}/configuration.nix` - Host-level entry points importing system modules
- `home/hakase.nix` - Home Manager entry point for user environment (referenced from flake)
### Module Organization
**Two-tier module system:**
- `modules/nixos/` - NixOS system-level modules (boot, kernel, services, hardware)
- `modules/home/` - Home Manager user-level modules (imported via `home/hakase.nix`)
**Three-tier system:**
1. **System modules** (`modules/nixos/`) - NixOS-level settings (boot, kernel, services, hardware)
2. **Home Manager modules** (`modules/home/`) - User-level environment and applications
3. **Application configs** (`apps/`) - Per-application configuration directories with `default.nix` files
**Application configs:** Each application has its own directory in `apps/` with a `default.nix` and optional sub-modules (e.g., `apps/hyprland/hypr/*.nix` for Hyprland settings).
Examples:
- `apps/hyprland/default.nix` + `apps/hyprland/hypr/*.nix` - Hyprland compositor config
- `apps/firefox/default.nix` - Browser with bookmarks and theming
- `apps/ghostty/default.nix` - Terminal emulator
- `apps/neovim/default.nix` - Editor (via nixovim external flake)
### Configuration Flow
```
flake.nix
nixosConfigurations.hakase
├─ hosts/hakase/configuration.nix
│ └─ modules/nixos/default.nix (imports all system modules)
└─ home-manager
└─ home/hakase.nix
└─ modules/home/* → apps/*
flake.nix (outputs)
hakase (x86_64-linux)
├─ hosts/hakase/configuration.nix
│ └─ modules/nixos/default.nix (imports system modules)
└─ home-manager
└─ home/hakase.nix
└─ modules/home/* (imports Home Manager modules)
│ └─ apps/* (application configurations)
└─ macbook (aarch64-linux)
├─ hosts/macbook/configuration.nix
│ └─ modules/nixos/default.nix
└─ Similar home-manager structure
config.nix provides myConfig via specialArgs to both configurations
```
### Configuration Structure (config.nix)
The `config.nix` file defines host-specific configuration under `hakase` and `macbook` keys. Common values include:
```nix
myConfig = {
nixos = { username, hostname, timezone }
git = { username, email, defaultBranch }
theme = { mode } # "dark" or "light"
terminal = { default, font, aliases }
font = { monospace, monospaceScript, sans }
hyprland = { monitors, wallpaper, kb_options }
firefox = { bookmarks, newtabpage }
# ... more app-specific configs
}
```
To add a host-specific override, define it in the host's `myConfig` section in `config.nix`. The flake passes `allConfig.{hostname}` as specialArgs, so modules access the correct host configuration.
### Module Pattern
Modules receive these parameters:
Modules receive standard NixOS parameters plus custom ones:
```nix
{ pkgs, config, myConfig, inputs, ... }:
{ pkgs, config, lib, myConfig, inputs, system, ... }:
```
Access configuration values via `myConfig`:
```nix
myConfig.nixos.username # "hakase"
myConfig.nixos.hostname # "hakase"
myConfig.terminal.default # Terminal emulator
myConfig.hyprland.monitors # Monitor configuration
```
**Key patterns:**
- Access host config: `myConfig.nixos.username`, `myConfig.terminal.default`
- Use host-specific packages: `pkgs.unstable` (from nixpkgs), `inputs.neovim` (from flake inputs)
- Reference other modules via `config` (e.g., `config.home.homeDirectory`)
- Conditional logic: Check `system` or `myConfig` values
### Secrets Management
Uses SOPS for encrypted secrets. Keys stored at `~/.config/sops/age/keys.txt`.
SOPS-encrypted secrets stored in `secrets/secrets.yaml`. Age key at `~/.config/sops/age/keys.txt`.
Access secrets in modules:
In modules, reference secrets via:
```nix
config.sops.secrets.secret_name.path
```
## Key Technologies
- **Hyprland** with UWSM (systemd session management)
- **Stylix** for system-wide theming from wallpaper colors
- **Home Manager** for user environment
- **nixovim** flake for Neovim configuration
- **Hyprland** with UWSM (systemd user session management)
- **Matugen** for automatic system-wide theming from wallpaper colors
- **Home Manager** for user environment and program configuration
- **nixovim** external flake for Neovim configuration (treesitter disabled due to read-only NixOS constraints)
- **SOPS-Nix** for secrets encryption
- **CachyOS kernel** on hakase (x86_64), **Asahi Linux** on macbook (aarch64)
## Git Commit Convention
Use conventional commits: `feat(scope):`, `fix(scope):`, `refactor:`, `add:`, `remove:`, `cleanup:`
Use conventional commits with scope: `feat(scope):`, `fix(scope):`, `refactor:`, `add:`, `remove:`, `cleanup:`
Common scopes: `nixos`, `home`, `apps`, `config`, `modules`, `hyprland`, `firefox`, etc.
+65
View File
@@ -0,0 +1,65 @@
# HakaseOS - NixOS Configuration
This is a modular, flake-based NixOS configuration for a single host (`hakase`). It features a custom Hyprland desktop environment, automated theming via Matugen, and strict separation of concerns using a custom `myConfig` object.
## Project Structure
* **`flake.nix`**: The entry point. Defines inputs (Hyprland, Chaotic, Home Manager, etc.) and creates the system configuration.
* **`config.nix`**: Central source of truth. Defines global variables (user details, monitor config, theme settings) exposed as `myConfig`.
* **`hosts/hakase/`**: Host-specific configuration.
* `configuration.nix`: Main system entry point.
* **`modules/`**: Reusable modules.
* `nixos/`: System-level modules (boot, hardware, services).
* `home/`: Home-manager modules (UI, apps, user services).
* **`apps/`**: Application-specific configurations. Each app has its own directory (e.g., `hyprland`, `firefox`, `ghostty`) with a `default.nix`.
* **`assets/`**: Static assets like wallpapers (`firewatch.png`).
* **`secrets/`**: Encrypted secrets managed by SOPS.
## Architecture & Conventions
### 1. The `myConfig` Object
Global configuration is not hardcoded in modules. Instead, it is defined in `config.nix` and passed to all modules via `specialArgs`.
**Usage Pattern:**
```nix
# In any module
{ pkgs, config, myConfig, ... }:
{
# Access values
home.username = myConfig.nixos.username;
}
```
### 2. Module Hierarchy
* **System**: `flake.nix` -> `hosts/hakase/configuration.nix` -> `modules/nixos/default.nix` -> `modules/nixos/*.nix`
* **User**: `modules/nixos/user.nix` (or similar) -> `home-manager` -> `home/hakase.nix` -> `modules/home/*.nix` -> `apps/*/default.nix`
### 3. Application Configuration
Do not dump config into one large file. Create a dedicated folder in `apps/<app_name>/` with a `default.nix`.
* Example: `apps/ghostty/default.nix`
## Key Commands
### System Management
* **Rebuild & Switch**:
```bash
sudo nixos-rebuild switch --flake ~/.config/nixos/#hakase
# or alias:
update
```
### Secrets (SOPS)
* **Edit Secrets**:
```bash
nix-shell -p sops --run "sops secrets/secrets.yaml"
```
* **Update Keys**:
```bash
nix-shell -p sops --run "sops updatekeys secrets/secrets.yaml"
```
## Development Guidelines
* **Matugen**: used for theming. Templates are located in `apps/matugen/templates/`.
* **Hyprland**: Config is split into `apps/hyprland/hypr/*.nix`.
* **Formatting**: Follow existing indentation (2 spaces usually).
* **Commits**: Use Conventional Commits (e.g., `feat(hyprland): add new bind`).
+92 -48
View File
@@ -1,57 +1,101 @@
# HakaseOS
HakaseOS is an opinionated NixOS configuration heavily inspired by OmarchyOS.
A modular, flake-based NixOS configuration for my personal devices (`hakase` desktop and `macbook`). Heavily inspired by [OmarchyOS](https://omarchy.org/).
## Features
* Vim keybindings
* Simple Setup
* Pre-configured Firefox
## How to Use SOPS
SOPS is an important aspect of this operating system. Learning to use it is important for security and modularity. It is impertinent that you do not lose the `private key`, as it is irrecoverable.
- **Hyprland** compositor with UWSM (systemd session management)
- **Multi-Architecture Support**: Runs on x86_64 (Desktop) and aarch64 (Apple Silicon M1/M2)
- **Matugen** for automatic system-wide theming from wallpaper colors
- **Hardened Firefox** with custom bookmarks and new tab page
- **Vim keybindings** throughout the system
- **SOPS** for encrypted secrets management
- **CachyOS kernel** (Desktop) and **Asahi Linux** (MacBook) support
To get started, follow the instructions below.
1. Create a folder.
```sh
mkdir -p ~/.config/sops/age
```
2. Generate a private key using `age`
```sh
nix-shell -p age --run "age-keygen -o ~/.config/sops/age/keys.txt"
```
**OR**
Use `ssh-to-age` to convert `id_ed22519` to `age`.
```sh
nix-shell -p ssh-to-age --run "ssh-to-age -private-key -i ~/.ssh/id_ed25519 > ~/.config/sops/age/keys.txt"
```
There are other ways of generating a private key. Refer to [sops-nix](https://github.com/Mic92/sops-nix).
3. Get a **public key**.
```sh
nix-shell -p age --run "age-keygen -y ~/.config/sops/age/keys.txt"
```
4. On the same directory as `flake.nix`, create `.sops.yaml` and paste the following below.
```yaml
# This example uses YAML anchors which allows reuse of multiple keys
# without having to repeat yourself.
# Also see https://github.com/Mic92/dotfiles/blob/d6114726d859df36ccaa32891c4963ae5717ef7f/nixos/.sops.yaml
# for a more complex example.
keys:
- &admin_alice 2504791468b153b8a3963cc97ba53d1919c5dfd4
- &admin_bob age12zlz6lvcdk6eqaewfylg35w0syh58sm7gh53q5vvn7hd7c6nngyseftjxl
creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *admin_alice
age:
- *admin_bob
## 🚧 TODO
- LUKS designed
## Screenshots
![Display overview](assets/example/desktop_display.png)
![Terminal windows](assets/example/desktop_terminals.png)
![Lockscreen](assets/example/lockscreen.png)
![Desktop Music](assets/example/desktop_music.png)
![Desktop with Hakase](assets/example/desktop_hakase.png)
## Structure
```
Replace as according to your needs.
5. Create a sops `.yaml` file.
```sh
nix-shell -p sops --run "sops secrets/example.yaml"
.
├── flake.nix # Entry point defining hosts (hakase, macbook)
├── config.nix # Central configuration values per host
├── hosts/
│ ├── hakase/ # Desktop configuration (x86_64)
│ └── macbook/ # Laptop configuration (aarch64, Apple Silicon)
├── modules/
│ ├── nixos/ # System-level modules (boot, kernel, services)
│ └── home/ # Home Manager modules
├── home/ # Host-specific Home Manager entry points
├── apps/ # Per-application configurations
│ ├── hyprland/ # Hyprland window manager
│ ├── waybar/ # Status bar
│ ├── firefox/ # Browser configuration
│ ├── ghostty/ # Terminal emulator
│ ├── neovim/ # Editor (via nixovim flake)
│ ├── vicinae/ # Application launcher
│ └── ... # And many more
├── secrets/ # SOPS encrypted secrets
└── assets/ # Wallpapers and other assets
```
NOTE: If you add a new host to your `.sops.yaml`, you will need to update the keys for all secrets.
```sh
nix-shell -p sops --run "sops updatekeys secrets/example.yaml"
## Usage
### Rebuild System
**Desktop (Hakase):**
```bash
sudo nixos-rebuild switch --flake ~/.config/nixos/#hakase
```
**MacBook (Asahi):**
```bash
sudo nixos-rebuild switch --flake ~/.config/nixos/#macbook
```
### Manage Secrets
```bash
# Edit secrets
nix-shell -p sops --run "sops secrets/secrets.yaml"
# Update keys
nix-shell -p sops --run "sops updatekeys secrets/secrets.yaml"
```
## Configuration
Central configuration values are defined in `config.nix`, separated by host:
- `hakase` / `macbook` keys define host-specific overrides
- `myConfig.nixos` - System settings (username, hostname, timezone)
- `myConfig.hyprland` - Monitor configuration (Hz, Resolution) and wallpaper
## Flake Inputs
| Input | Description |
|-------|-------------|
| nixpkgs | NixOS unstable |
| home-manager | User environment management |
| hyprland | Wayland compositor |
| chaotic | CachyOS kernel and packages (x86 only) |
| apple-silicon | Asahi Linux support for NixOS (aarch64 only) |
| sops-nix | Secrets management |
| nixovim | Neovim configuration |
| matugen | System-wide theming |
| vicinae | Application launcher |
| textfox | Firefox CSS theme |
## License
Personal configuration - use at your own discretion.
-3
View File
@@ -1,3 +0,0 @@
* fix: special workspace preload always loads first. Toggling it back is easy, but i'd rather create a new sh script that forces back to normal workspace.
* add: similar to omarchy-menu
* cleanup: stylix configurations and wallpaper
+12
View File
@@ -0,0 +1,12 @@
{pkgs, ...}: {
home.packages = with pkgs; [anki-bin];
xdg.mimeApps = {
enable = true;
defaultApplications = {
"application/x-apkg" = "anki.desktop";
"application/x-anki-deck" = "anki.desktop";
"application/x-anki-collection" = "anki.desktop";
};
};
}
+39
View File
@@ -0,0 +1,39 @@
{pkgs, ...}: {
programs.bottom = {
enable = true;
settings = {
flags = {
rate = 1000;
hide_table_gap = true;
hide_time = true;
left_legend = true;
network_use_bytes = true;
temperature_type = "c";
mem_as_value = true;
current_usage = true;
};
row = [
{
ratio = 4;
child = [
{ type = "cpu"; }
];
}
{
ratio = 3;
child = [
{ type = "mem"; }
{ type = "net"; }
];
}
{
ratio = 3;
child = [
{ type = "temp"; }
{ type = "disk"; }
];
}
];
};
};
}
+26 -1
View File
@@ -1,10 +1,35 @@
{
pkgs,
lib,
myConfig,
...
}: {
# This enables the btop configuration file generation in your home directory.
# The btop package itself is now installed system-wide via modules/nixos/btop.nix
programs.btop = {
enable = true;
settings = {
vim_keys = true;
color_theme = "TTY";
theme_background = false;
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty cpu:0:default,mem:0:default,net:0:default,gpu0:0:default";
};
};
}
# This updates your Hyprland settings to use the btop-power wrapper.
wayland.windowManager.hyprland.settings = lib.mkMerge [
{
bindd = [
"CTRL SHIFT, Escape, Open Btop Minimal, exec, uwsm app -- xdg-terminal-exec -e btop-power -p 2"
];
}
(lib.mkIf (myConfig.btop.autostart) {
exec-once = [
"uwsm app -- xdg-terminal-exec -e btop-power -p 2"
];
windowrule = [
"match:title ^(btop)$, monitor ${myConfig.btop.monitor}"
];
})
];
}
+66 -37
View File
@@ -10,69 +10,98 @@
};
};
display = {
separator = " ";
separator = " : ";
};
modules = [
"break"
"break"
"title"
{
type = "command";
key = " ";
keyColor = "blue";
text = "splash=$(hakase-hyprlock-text-generator);echo $splash";
}
{
type = "custom";
format = "";
}
{
type = "os";
key = "os ";
keyColor = "33";
key = " 󰣇 OS";
format = "{2}";
keyColor = "red";
}
{
type = "kernel";
key = "kernel";
keyColor = "33";
}
{
type = "host";
format = "{2} {1}";
key = "host ";
keyColor = "33";
key = " 󰌽 Kernel";
format = "{2}";
keyColor = "red";
}
{
type = "packages";
format = "{} (nix)";
key = "pkgs ";
keyColor = "33";
key = " 󰏗 Pkgs";
keyColor = "green";
}
{
type = "terminal";
key = " 󰆍 Terminal";
keyColor = "yellow";
}
{
type = "wm";
key = " 󱗃 WM";
format = "{2}";
keyColor = "yellow";
}
{
type = "custom";
format = "";
}
"break"
{
type = "title";
key = " ";
format = "{6} {7} {8}";
}
{
type = "custom";
format = "";
}
{
type = "cpu";
format = " {1}";
key = "cpu";
keyColor = "33";
format = "{1} @ {7}";
key = " 󰻠 CPU";
keyColor = "blue";
}
{
type = "gpu";
format = " {2}";
key = "gpu";
format = "{1} {2}";
key = " 󰊴 GPU";
keyColor = "blue";
hideType = "integrated";
keyColor = "33";
}
{
type = "memory";
key = "memory";
keyColor = "33";
key = " 󰍛 Memory";
keyColor = "magenta";
}
{
type = "disk";
key = "disk";
keyColor = "33";
folders = ["/"]; # Restricts output to only the root partition
format = " {1} / {2} ({3})"; # Output: Used / Total (Percentage)
key = " 󰃭 OS Age";
folders = "/";
keyColor = "red";
format = "{days} days";
}
{
type = "uptime";
key = " 󰅐 Uptime";
keyColor = "red";
}
{
type = "custom";
format = "";
}
# {
# type = "uptime";
# key = "uptime";
# keyColor = "33";
# }
"break"
{
type = "colors";
paddingLeft = "2";
paddingLeft = 2;
symbol = "circle";
}
"break"
+5
View File
@@ -0,0 +1,5 @@
{pkgs, ...}: {
wayland.windowManager.hyprland.settings.exec-once = [
"fcitx5 -d --replace"
];
}
+71 -30
View File
@@ -4,6 +4,30 @@
inputs,
...
}: {
wayland.windowManager.hyprland.settings = {
exec-once = [
"uwsm app -- pywalfox start"
];
bindd = [
"SUPER, W, Open Browser, exec, uwsm app -- firefox"
"SUPER, Y, Toggle YouTube, togglespecialworkspace, youtube"
"SUPER SHIFT, Y, Move to YouTube Special Workspace, movetoworkspace, special:youtube"
"SUPER, I, Toggle Jellyfin, togglespecialworkspace, jellyfin"
"SUPER SHIFT, I, Move to Jellyfin Special Workspace, movetoworkspace, special:jellyfin"
];
workspace = [
"special:youtube, on-created-empty:uwsm app -- firefox -P web-app --name youtube https://youtube.com"
"special:jellyfin, on-created-empty:uwsm app -- firefox -P web-app --name jellyfin https://watch.sakamoto.dev"
];
windowrule = [
"match:class (?i)(firefox|youtube|jellyfin), opacity 1 1"
"match:class ^(youtube)$, workspace special:youtube"
"match:class ^(jellyfin)$, workspace special:jellyfin"
];
};
imports = [
inputs.textfox.homeManagerModules.default
./textfox.nix
@@ -19,8 +43,22 @@
bind J tabnext
bind K tabprev
unbind <C-e>
" Force Tridactyl to yield new tab control to Firefox/Extensions
set newtab about:newtab
'';
xdg.mimeApps = {
enable = true;
defaultApplications = {
"text/html" = "firefox.desktop";
"x-scheme-handler/http" = "firefox.desktop";
"x-scheme-handler/https" = "firefox.desktop";
"x-scheme-handler/about" = "firefox.desktop";
"x-scheme-handler/unknown" = "firefox.desktop";
};
};
programs.firefox = {
enable = true;
languagePacks = ["en-US"];
@@ -30,16 +68,34 @@
];
profiles = {
youtube = import ./profiles/youtube.nix {inherit pkgs myConfig;};
youtube = import ./profiles/web-app.nix {
inherit pkgs myConfig;
id = 1;
name = "YouTube";
url = "https://youtube.com";
};
jellyfin = import ./profiles/web-app.nix {
inherit pkgs myConfig;
id = 2;
name = "Jellyfin";
url = "https://watch.sakamoto.dev";
};
web-app = import ./profiles/web-app.nix {
inherit pkgs myConfig;
id = 3;
name = "web-app";
url = "about:blank";
};
hakase = {
search.force = true;
isDefault = true;
search.default = "ddg";
extensions.packages = with pkgs.nur.repos.rycee.firefox-addons; [
pywalfox
ublock-origin
bitwarden
tridactyl
# pywalfox
new-tab-override
];
bookmarks = {
@@ -56,12 +112,12 @@
settings = {
# --- Privacy & Hardening ---
"browser.contentblocking.category" = "strict";
"privacy.trackingprotection.enabled" = true;
"privacy.resistFingerprinting" = true; # Note: Spoofs timezone and caps FPS to 60
"geo.enabled" = false;
"media.peerconnection.enabled" = false; # Prevents WebRTC IP leaks
"network.dns.disablePrefetch" = true;
"network.prefetch-next" = false;
"privacy.resistFingerprinting" = true; # Note: Spoofs timezone and caps FPS to 60
"privacy.trackingprotection.enabled" = true;
# --- NixOS / Hyprland Integration ---
"widget.use-xdg-desktop-portal.file-picker" = 1; # Use native file picker
@@ -69,28 +125,28 @@
# --- UI & Behavior ---
"accessibility.typeaheadfind" = false;
"browser.compactmode.show" = true;
"browser.tabs.closeWindowWithLastTab" = false;
"extensions.pocket.enabled" = false;
"extensions.screenshots.disabled" = true;
"browser.topsites.contile.enabled" = false;
"browser.formfill.enable" = false;
"browser.search.suggest.enabled" = false;
"browser.search.suggest.enabled.private" = false;
"browser.urlbar.suggest.searches" = false;
"browser.urlbar.showSearchSuggestionsFirst" = false;
"browser.newtabpage.activity-stream.feeds.section.topstories" = false;
"browser.newtabpage.activity-stream.feeds.snippets" = false;
"browser.newtabpage.activity-stream.section.highlights.includePocket" = false;
"browser.newtabpage.activity-stream.section.highlights.includeBookmarks" = false;
"browser.newtabpage.activity-stream.section.highlights.includeDownloads" = false;
"browser.newtabpage.activity-stream.section.highlights.includePocket" = false;
"browser.newtabpage.activity-stream.section.highlights.includeVisited" = false;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.system.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"browser.newtabpage.activity-stream.system.showSponsored" = false;
"browser.search.suggest.enabled" = false;
"browser.search.suggest.enabled.private" = false;
"browser.tabs.closeWindowWithLastTab" = false;
"browser.topsites.contile.enabled" = false;
"browser.urlbar.showSearchSuggestionsFirst" = false;
"browser.urlbar.suggest.searches" = false;
"extensions.pocket.enabled" = false;
"extensions.screenshots.disabled" = true;
# --- Homepage & Navigation ---
"browser.startup.homepage" = "https://dash.sakamoto.dev";
"browser.newtabpage.pinned" = myConfig.firefox.newtabpage;
"browser.startup.homepage" = "https://dash.sakamoto.dev";
# --- DNS over HTTPS (Quad9) ---
"network.trr.mode" = 2; # Use DoH with system fallback
@@ -126,21 +182,6 @@
UrlbarInterventions = false;
WhatsNew = false;
};
# ExtensionSettings = {
# "uBlock0@raymondhill.net" = {
# install_url = "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi";
# installation_mode = "force_installed";
# };
# "{446900e4-71c2-419f-a6a7-df9c091e268b}" = {
# install_url = "https://addons.mozilla.org/firefox/downloads/latest/bitwarden-password-manager/latest.xpi";
# installation_mode = "force_installed";
# };
# "tridactyl.vim@cmcaine.co.uk" = {
# install_url = "https://addons.mozilla.org/firefox/downloads/latest/tridactyl-vim/latest.xpi";
# installation_mode = "force_installed";
# };
# };
};
};
}
+178
View File
@@ -0,0 +1,178 @@
{
pkgs,
myConfig,
id,
name,
url,
...
}: {
inherit id name;
# Note: This profile relies on the global tridactylrc logic in default.nix
# to dynamically set 'newtab' via the TRIDACTYL_NEWTAB environment variable.
search.force = true;
search.default = "ddg";
extensions.force = true;
extensions.packages = with pkgs.nur.repos.rycee.firefox-addons; [
ublock-origin
bitwarden
tridactyl
new-tab-override
pywalfox
];
settings = {
# --- New Tab Override ---
"extensions.newtaboverride@agenedia.com.url" = url;
"extensions.newtaboverride@agenedia.com.type" = 1; # URL mode
# --- Privacy & Hardening ---
"browser.contentblocking.category" = "strict";
"privacy.trackingprotection.enabled" = true;
"privacy.resistFingerprinting" = true; # Note: Spoofs timezone and caps FPS to 60
"geo.enabled" = false;
"media.peerconnection.enabled" = false; # Prevents WebRTC IP leaks
"network.dns.disablePrefetch" = true;
"network.prefetch-next" = false;
# --- NixOS / Hyprland Integration ---
"widget.use-xdg-desktop-portal.file-picker" = 1; # Use native file picker
# --- UI & Behavior ---
"browser.toolbars.bookmarks.visibility" = "never";
"browser.compactmode.show" = true;
"browser.tabs.closeWindowWithLastTab" = false;
"extensions.pocket.enabled" = false;
"extensions.screenshots.disabled" = true;
"browser.topsites.contile.enabled" = false;
"browser.formfill.enable" = false;
"browser.search.suggest.enabled" = false;
"browser.search.suggest.enabled.private" = false;
"browser.urlbar.suggest.searches" = false;
"browser.urlbar.showSearchSuggestionsFirst" = false;
"browser.newtabpage.activity-stream.feeds.section.topstories" = false;
"browser.newtabpage.activity-stream.feeds.snippets" = false;
"browser.newtabpage.activity-stream.section.highlights.includePocket" = false;
"browser.newtabpage.activity-stream.section.highlights.includeBookmarks" = false;
"browser.newtabpage.activity-stream.section.highlights.includeDownloads" = false;
"browser.newtabpage.activity-stream.section.highlights.includeVisited" = false;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.system.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"extensions.autoDisableScopes" = 0; # Enable extensions by default
# --- Homepage & Navigation ---
"browser.startup.page" = 1; # Always open the homepage
"browser.startup.homepage" = url;
"browser.newtab.url" = url; # Try to set newtab to homepage
"browser.sessionstore.resume_from_crash" = false; # Always start fresh
"browser.sessionstore.max_tabs_undo" = 0; # Disable undo close tab
# --- DNS over HTTPS (Quad9) ---
"network.trr.mode" = 2; # Use DoH with system fallback
"network.trr.uri" = "https://dns.quad9.net/dns-query";
};
#
# userChrome = ''
# /* --- Autohide Entire Toolbox (Tabs + Address Bar) --- */
# /* Adapted from MrOtherGuy's autohide_main_toolbar.css */
#
# :root{
# /* Height of Tabs + Nav Bar approx 80px */
# --uc-navbar-transform: -85px;
# --uc-autohide-toolbar-delay: 0.1s;
# --uc-autohide-toolbar-duration: 200ms;
# }
# :root[uidensity="compact"]{ --uc-navbar-transform: -70px }
#
# #navigator-toolbox > div{ display: contents; }
#
# /* Apply transform to TabsToolbar AND Nav-bar */
# :root[sessionrestored] :where(#nav-bar,#PersonalToolbar,#TabsToolbar,#tab-notification-deck,.global-notificationbox,#notifications-toolbar){
# transform: translateY(var(--uc-navbar-transform))
# }
#
# :root:is([customizing],[chromehidden*="toolbar"]) :where(#nav-bar,#PersonalToolbar,#TabsToolbar,#tab-notification-deck,.global-notificationbox,#notifications-toolbar){
# transform: none !important;
# opacity: 1 !important;
# }
#
# /* Hide styles for Nav-Bar AND TabsToolbar */
# :where(#nav-bar,#TabsToolbar):not([customizing]){
# opacity: 0;
# transition: transform var(--uc-autohide-toolbar-duration) ease var(--uc-autohide-toolbar-delay), opacity var(--uc-autohide-toolbar-duration) ease var(--uc-autohide-toolbar-delay) !important;
# position: relative;
# z-index: 2;
# background-color: #1c1b22 !important; /* Solid background */
# }
#
# #navigator-toolbox,
# #sidebar-box,
# #sidebar-main,
# #sidebar-splitter,
# #tabbrowser-tabbox{
# z-index: auto !important;
# }
#
# /* Show when toolbox is focused or hovered */
# #navigator-toolbox:focus-within > .browser-toolbar,
# .browser-titlebar:hover ~ :is(#nav-bar,#PersonalToolbar,#TabsToolbar),
# #nav-bar:hover,
# #TabsToolbar:hover,
# #nav-bar:hover + #PersonalToolbar{
# transform: translateY(0);
# opacity: 1;
# transition-duration: var(--uc-autohide-toolbar-duration), var(--uc-autohide-toolbar-duration) !important;
# transition-delay: 0s !important;
# }
#
# /* Ensure popups still work (URL bar) */
# :root[sessionrestored] #urlbar[popover]{
# opacity: 0;
# pointer-events: none;
# transition: transform var(--uc-autohide-toolbar-duration) ease var(--uc-autohide-toolbar-delay), opacity var(--uc-autohide-toolbar-duration) ease var(--uc-autohide-toolbar-delay);
# transform: translateY(var(--uc-navbar-transform));
# }
# #mainPopupSet:has(> [panelopen]:not(#ask-chat-shortcuts,#selection-shortcut-action-panel,#chat-shortcuts-options-panel,#tab-preview-panel)) ~ toolbox #urlbar[popover],
# .browser-titlebar:is(:hover,:focus-within) ~ #nav-bar #urlbar[popover],
# #nav-bar:is(:hover,:focus-within) #urlbar[popover],
# #urlbar-container > #urlbar[popover]:is([focused],[open]){
# opacity: 1;
# pointer-events: auto;
# transition-delay: 0ms;
# transform: translateY(0);
# }
# :where(:root[sessionrestored]) #urlbar-container > #urlbar[popover]:is([focused],[open]){
# transition-duration: 100ms;
# }
#
# /* --- CRITICAL FIX: Trigger Zone --- */
# /* Since we hide EVERYTHING, we need a hitbox at the top of the screen */
# #navigator-toolbox::after {
# content: "";
# position: fixed;
# top: 0;
# left: 0;
# width: 100%;
# height: 20px; /* Generous hit target */
# z-index: 10000;
# pointer-events: auto;
# }
#
# /* When hitbox is hovered, reveal bars */
# #navigator-toolbox:hover :where(#nav-bar,#PersonalToolbar,#TabsToolbar) {
# transform: translateY(0) !important;
# opacity: 1 !important;
# transition-delay: 0s !important;
# }
#
# /* Move up the content view to fill the gap */
# :root[sessionrestored]:not([chromehidden~="toolbar"]) > body > #browser{
# margin-top: var(--uc-navbar-transform);
# }
#
# /* Fix Titlebar and Bookmarks */
# #titlebar { appearance: none !important; }
# #PersonalToolbar { visibility: collapse !important; }
# '';
}
-120
View File
@@ -1,120 +0,0 @@
{
pkgs,
myConfig,
...
}: {
id = 1;
name = "YouTube";
search.force = true;
search.default = "ddg";
extensions.force = true;
extensions.packages = with pkgs.nur.repos.rycee.firefox-addons; [
ublock-origin
bitwarden
tridactyl
];
settings = {
# --- Privacy & Hardening ---
"browser.contentblocking.category" = "strict";
"privacy.trackingprotection.enabled" = true;
"privacy.resistFingerprinting" = true; # Note: Spoofs timezone and caps FPS to 60
"geo.enabled" = false;
"media.peerconnection.enabled" = false; # Prevents WebRTC IP leaks
"network.dns.disablePrefetch" = true;
"network.prefetch-next" = false;
# --- NixOS / Hyprland Integration ---
"widget.use-xdg-desktop-portal.file-picker" = 1; # Use native file picker
# --- UI & Behavior ---
"browser.compactmode.show" = true;
"browser.tabs.closeWindowWithLastTab" = false;
"extensions.pocket.enabled" = false;
"extensions.screenshots.disabled" = true;
"browser.topsites.contile.enabled" = false;
"browser.formfill.enable" = false;
"browser.search.suggest.enabled" = false;
"browser.search.suggest.enabled.private" = false;
"browser.urlbar.suggest.searches" = false;
"browser.urlbar.showSearchSuggestionsFirst" = false;
"browser.newtabpage.activity-stream.feeds.section.topstories" = false;
"browser.newtabpage.activity-stream.feeds.snippets" = false;
"browser.newtabpage.activity-stream.section.highlights.includePocket" = false;
"browser.newtabpage.activity-stream.section.highlights.includeBookmarks" = false;
"browser.newtabpage.activity-stream.section.highlights.includeDownloads" = false;
"browser.newtabpage.activity-stream.section.highlights.includeVisited" = false;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.system.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"extensions.autoDisableScopes" = 0; # Enable extensions by default
# --- Homepage & Navigation ---
"browser.startup.homepage" = "https://youtube.com";
"browser.newtabpage.pinned" = myConfig.firefox.newtabpage;
# --- DNS over HTTPS (Quad9) ---
"network.trr.mode" = 2; # Use DoH with system fallback
"network.trr.uri" = "https://dns.quad9.net/dns-query";
};
userChrome = ''
/* --- Floating Autohide Toolbox (Tabs Only) --- */
/* Take toolbox out of the document flow so web content is 100% height */
#navigator-toolbox {
position: fixed !important;
top: 0;
left: 0;
width: 100%;
z-index: 9999 !important;
background-color: var(--toolbar-bgcolor, #1c1b22) !important;
/* Start hidden */
transform: translateY(-100%) !important;
opacity: 0 !important;
transition: transform 0.2s ease, opacity 0.2s ease !important;
}
/* Trigger zone */
#navigator-toolbox::after {
content: "";
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 10px;
z-index: 10000 !important;
}
/* Reveal when hovering */
#navigator-toolbox:hover {
transform: translateY(0) !important;
opacity: 1 !important;
}
/* --- Hide specific bars --- */
/* Hide Navigation Bar (Address Bar) COMPLETELY */
#nav-bar {
visibility: collapse !important;
height: 0px !important;
min-height: 0px !important;
padding: 0 !important;
margin: 0 !important;
}
/* Hide Bookmarks Toolbar */
#PersonalToolbar { visibility: collapse !important; }
/* Hide Titlebar */
#titlebar { appearance: none !important; }
/* Ensure TabsToolbar looks okay on its own */
#TabsToolbar {
border: none !important;
background: transparent !important;
}
'';
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
textfox = {
enable = true;
profile = "hakase";
profiles = ["hakase" "web-app"];
config = {
# background = {
# color = "#123456";
+53
View File
@@ -1,8 +1,46 @@
{
config,
pkgs,
myConfig,
...
}: {
home.packages = [
# TODO: will rewrite later
(pkgs.writeShellScriptBin "tte-loop" ''
trap 'printf "\e[?25h"; exit 0' INT
printf '\e[?25l'
effects=(beams binarypath blackhole bouncyballs bubbles burn colorshift crumble decrypt errorcorrect expand fireworks highlight laseretch matrix middleout orbittingvolley overflow pour print rain randomsequence rings scattered slice slide spotlights spray swarm sweep synthgrid unstable vhstape waves wipe)
while true; do
clear
cols=$(tput cols)
lines=$(tput lines)
effect="''${effects[RANDOM % ''${#effects[@]}]}"
printf '\e[?25l'
${pkgs.terminaltexteffects}/bin/tte --input-file ${config.home.homeDirectory}/.config/nixos/assets/branding.txt --anchor-canvas c --anchor-text c --canvas-width "$cols" --canvas-height "$((lines-2))" --frame-rate 120 "$effect"
printf '\e[?25l'
sleep 2
done
'')
(pkgs.writeShellScriptBin "tte-screensaver" ''
# Get all monitors
monitors=$(${pkgs.hyprland}/bin/hyprctl monitors -j | ${pkgs.jq}/bin/jq -r '.[].name')
# Launch ghostty on each monitor one at a time
for monitor in $monitors; do
${pkgs.hyprland}/bin/hyprctl dispatch focusmonitor "$monitor"
sleep 0.3
${pkgs.ghostty}/bin/ghostty --config-file=${config.home.homeDirectory}/.config/ghostty/screensaver --fullscreen -e tte-loop &
sleep 1
done
# Monitor for any input and exit when detected
${pkgs.libinput}/bin/libinput debug-events 2>/dev/null | head -n 1 >/dev/null
# Input detected, kill all screensaver instances
${pkgs.procps}/bin/pkill -f "ghostty.*tte-loop"
'')
];
home.file.".config/ghostty/screensaver".text = ''
window-padding-x = 0
window-padding-y = 0
@@ -17,11 +55,26 @@
enableFishIntegration = true;
settings = {
font-family = myConfig.terminal.font;
confirm-close-surface = false;
app-notifications = false;
window-padding-x = 15;
window-padding-y = 15;
window-padding-balance = true;
gtk-titlebar = false;
mouse-hide-while-typing = true;
copy-on-select = "clipboard";
auto-update = "off";
};
};
wayland.windowManager.hyprland.settings.bindd = [
"SUPER, P, Toggle Preload, togglespecialworkspace, preload"
"SUPER SHIFT, P, Move to Preload Special Workspace, movetoworkspace, special:preload"
];
wayland.windowManager.hyprland.settings.exec-once = [
"[workspace special:preload silent] uwsm app -- xdg-terminal-exec"
"[workspace 1] uwsm app -- ghostty -e bash -c 'fastfetch; exec $SHELL'" # TODO: must be xdg-terminal-exec, or default user terminal
];
}
+14 -6
View File
@@ -1,19 +1,27 @@
{ pkgs, ... }:
{
{pkgs, ...}: {
wayland.windowManager.hyprland.settings = {
exec-once = [
"uwsm app -- hypridle"
];
};
services.hypridle = {
enable = true;
settings = {
general = {
after_sleep_cmd = "hyprctl dispatch dpms on";
ignore_dbus_inhibit = false;
lock_cmd = "hyprlock";
before_sleep_cmd = "loginctl lock-session"; # lock before suspend
lock_cmd = "hakase-hyprlock";
before_sleep_cmd = "hakase-hyprlock"; # lock before suspend
};
listener = [
# {
# timeout = 180; # 3min
# on-timeout = "tte-screensaver";
# }
{
timeout = 300; # 5min
on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
on-timeout = "hakase-hyprlock"; # lock screen when timeout has passed
}
{
timeout = 330; # 5.5min
@@ -21,7 +29,7 @@
on-resume = "hyprctl dispatch dpms on"; # screen on when activity is detected after timeout has passed
}
{
timeout = 1800; # 30min
timeout = 660;
on-timeout = "systemctl suspend"; # suspend pc
}
];
+18 -5
View File
@@ -1,15 +1,28 @@
{
pkgs,
inputs,
...
}: {
imports = [
./hypr/binds.nix
./hypr/general.nix
./hypr/exec.nix
./hypr/rules.nix
./hypr/animation.nix
./hypr/misc.nix
./hypr/binds.nix
./hypr/exec.nix
./hypr/general.nix
./hypr/input.nix
./hypr/layers.nix
./hypr/misc.nix
./hypr/rules.nix
./scripts/movement.nix
./scripts/window-rules.nix
./scripts/workspace-toggle.nix
];
wayland.windowManager.hyprland.enable = true;
wayland.windowManager.hyprland.systemd.enable = false; # for UWSM support...
wayland.windowManager.hyprland.plugins = [
inputs.hyprsplit.packages.${pkgs.system}.hyprsplit
# inputs.hypr-dynamic-cursors.packages.${pkgs.system}.hypr-dynamic-cursors
# inputs.hyprspace.packages.${pkgs.system}.Hyprspace
pkgs.hyprlandPlugins.hyprbars
];
}
-19
View File
@@ -28,24 +28,5 @@
"workspaces, 0, 0, ease"
];
};
decoration = {
rounding = 0;
shadow = {
enabled = true;
range = 2;
render_power = 3;
color = "rgba(1a1a1aee)";
};
blur = {
enabled = true;
size = 2;
passes = 2;
special = true;
brightness = 0.60;
contrast = 0.75;
};
};
};
}
+27 -34
View File
@@ -1,24 +1,13 @@
{pkgs, ...}: {
services.swayosd.enable = true;
home.packages = [
pkgs.playerctl
];
# TODO: implement a way to show binds, preferably use vicinae.
wayland.windowManager.hyprland.settings = {
binds = {
workspace_back_and_forth = true;
};
bindel = [
", XF86AudioRaiseVolume, exec, swayosd-client --output-volume raise"
", XF86AudioLowerVolume, exec, swayosd-client --output-volume lower"
", XF86MonBrightnessUp, exec, ddcutil setvcp 10 + 10"
", XF86MonBrightnessDown, exec, ddcutil setvcp 10 - 10"
];
bindl = [
", XF86AudioMute, exec, swayosd-client --output-volume mute-toggle"
", Caps_Lock, exec, swayosd-client --caps-lock"
", XF86AudioPlay, exec, playerctl play-pause && notify-send -u low -t 1000 \"Media\" \"$(playerctl status)\""
", XF86AudioPrev, exec, playerctl previous && notify-send -u low -t 1000 \"Previous Track\" \"$(playerctl metadata title)\""
", XF86AudioNext, exec, playerctl next && notify-send -u low -t 1000 \"Next Track\" \"$(playerctl metadata title)\""
", XF86AudioMute, exec, swayosd-client --output-volume mute-toggle"
]; # FIXME: not working
bindm = [
"SUPER, mouse:272, movewindow"
"SUPER, mouse:273, resizewindow"
@@ -41,6 +30,7 @@
"SUPER, K, Move focus up, movefocus, u"
"SUPER, H, Move focus left, movefocus, l"
"SUPER, L, Move focus right, movefocus, r"
"SUPER, G, Switch Focus (Float/Tile), exec, hakase-focus-switch"
# move window
"SUPER SHIFT, h, Move window left, movewindow, l"
@@ -56,37 +46,40 @@
"SUPER, O, Toggle Split, layoutmsg, togglesplit"
# apps
"SUPER, W, Open Browser, exec, uwsm app -- firefox" # FIXME: must be xdg-open
"SUPER, SPACE, Open App Launcher, exec, nc -U $XDG_RUNTIME_DIR/walker/walker.sock"
"SUPER, T, Toggle Steam, togglespecialworkspace, steam"
"SUPER, M, Toggle Music, togglespecialworkspace, music"
"SUPER, Y, Toggle YouTube, togglespecialworkspace, youtube"
"SUPER, P, Toggle Preload, togglespecialworkspace, preload"
"SUPER CTRL, I, Switch Wallpaper, exec, hakase-wallpaper-switch"
# "SUPER, SPACE, Open App Launcher, exec, nc -U $XDG_RUNTIME_DIR/walker/walker.sock"
"SUPER, S, Toggle Special Workspace, togglespecialworkspace, custom"
"SUPER + Shift, S, Move to Special Workspace, movetoworkspace, special:custom"
# TODO:
# add screen recording
# Special workspace
"SUPER, U, Toggle Special Workspace, togglespecialworkspace, custom"
"SUPER SHIFT, U, Move to Special Workspace, movetoworkspace, special:custom"
# [Workspaces] Toggle between most recent workspaces
"SUPER, Tab, Cycle workspaces, workspace, previous"
# [Workspaces] Move to another workspace
"CTRL SHIFT, H, Move to previous workspace, split:workspace, -1"
"CTRL SHIFT, L, Move to next workspace, split:workspace, +1"
"CTRL SHIFT, K, Move to previous workspace, split:workspace, -1"
"CTRL SHIFT, J, Move to next workspace, split:workspace, +1"
# hyprspace - workspace overview
# "SUPER, E, Toggle Workspace Overview, overview:toggle"
]
++ (
# Generate binds for Super + [1-10] to switch workspaces
# and Super + Shift + [1-10] to move window to workspace
# Generate binds for Super + [1-5] to switch workspaces with special workspace toggle support
# and Super + Shift + [1-5] to move window to workspace on current monitor
builtins.concatLists (builtins.genList (
i: let
ws = i + 1;
key = toString (
if ws == 10
then 0
else ws
);
key = toString ws;
in [
"SUPER, ${key}, Switch to workspace ${toString ws}, exec, hakase-workspace-switch-force ${toString ws}"
"SUPER SHIFT, ${key}, Move window to workspace ${toString ws}, movetoworkspace, ${toString ws}"
"SUPER, ${key}, Switch to workspace ${toString ws}, exec, workspace-toggle ${toString ws}"
"SUPER SHIFT, ${key}, Move window to workspace ${toString ws}, split:movetoworkspace, ${toString ws}"
]
)
10)
5)
);
};
}
-2
View File
@@ -4,8 +4,6 @@
];
wayland.windowManager.hyprland.settings = {
env = [
"HYPRCURSOR_THEME,rose-pine-hyprcursor"
"HYPRCURSOR_SIZE,24"
"GUM_CONFIRM_PROMPT_FOREGROUND,6"
"GUM_CONFIRM_SELECTED_FOREGROUND,0"
"GUM_CONFIRM_SELECTED_BACKGROUND,2"
+11 -20
View File
@@ -1,31 +1,22 @@
{pkgs, ...}: {
{
pkgs,
config,
...
}: {
home.packages = with pkgs; [
psmisc
];
wayland.windowManager.hyprland.settings = {
exec = [
# "pkill -x hyprpaper; uwsm app -- hyprpaper"
"killall -SIGUSR2 .ghostty-wrappe"
# "matugen image ${config.home.homeDirectory}/.cache/current_wallpaper"
];
exec-once = [
"[workspace special:preload silent] uwsm app -- firefox"
"[workspace special:preload silent] uwsm app -- firefox -P YouTube"
"[workspace special:preload silent] uwsm app -- xdg-terminal-exec"
"uwsm app -- waybar"
"uwsm app -- hyprpaper"
"uwsm app -- elephant"
"uwsm app -- swayosd-server"
"uwsm app -- pywalfox start"
"uwsm app -- pywalfox start"
"uwsm app -- hypridle"
"walker --gapplication-service"
"sh -c 'sleep 2.5; hakase-workspace-switch-force 1'"
"[workspace 1] uwsm app -- ghostty -e bash -c 'fastfetch; exec $SHELL'"
"[workspace special:steam silent] uwsm app -- steam"
# essentials
"hyprpm reload -n"
"systemctl --user start hyprpolkitagent"
"systemctl --user start swayosd"
# "hyprsunset -t 4500" # TODO: must be optional
];
};
}
+22 -1
View File
@@ -4,10 +4,31 @@
gaps_in = 5;
gaps_out = 15;
layout = "dwindle";
allow_tearing = true;
resize_on_border = true;
};
decoration = {
rounding = 0;
active_opacity = 1;
inactive_opacity = 0.99;
shadow = {
enabled = true;
range = 2;
render_power = 3;
color = "rgba(1a1a1aee)";
};
blur = {
enabled = true;
size = 8;
passes = 2;
new_optimizations = true;
special = true;
brightness = 0.60;
contrast = 0.75;
};
};
monitor = myConfig.hyprland.monitors;
dwindle = {
pseudotile = true;
preserve_split = true;
smart_split = false;
};
+5 -2
View File
@@ -1,11 +1,14 @@
{
{myConfig, ...}: {
wayland.windowManager.hyprland.settings = {
input = {
repeat_rate = 50;
repeat_delay = 300;
numlock_by_default = true;
kb_options = myConfig.hyprland.kb_options;
};
cursor = {
hide_on_key_press = true;
hide_on_key_press = false;
no_warps = false;
};
};
}
+7
View File
@@ -0,0 +1,7 @@
{pkgs, ...}: {
wayland.windowManager.hyprland.settings = {
layerrule = [
"match:namespace vicinae, blur true, ignore_alpha 0.0, no_anim true"
];
};
}
+43 -2
View File
@@ -1,13 +1,17 @@
{
{myConfig, ...}: {
wayland.windowManager.hyprland.settings = {
misc = {
disable_hyprland_logo = true;
disable_splash_rendering = true;
focus_on_activate = true;
anr_missed_pings = 3;
new_window_takes_over_fullscreen = 1;
on_focus_under_fullscreen = 1;
};
# experimental = {
# hdr = true;
# };
cursor = {
no_hardware_cursors = true;
no_break_fs_vrr = true;
@@ -18,5 +22,42 @@
direct_scanout = true;
cm_enabled = true;
};
plugin = {
hyprsplit = {
num_workspaces = 5;
persistent_workspaces = false;
};
dynamic-cursors = {
mode = "tilt";
shake = {
enabled = true;
threshold = 4.0;
limit = 4.0;
timeout = 200;
};
};
overview = {
# Using default settings
};
hyprbars = {
bar_height = 24;
bar_color = "$surface_container_high";
bar_text_color = "$on_surface";
bar_text_size = 0;
bar_text_font = myConfig.font.sans;
bar_button_padding = 4;
bar_padding = 8;
bar_precedence_over_border = true;
on_double_click = "hyprctl dispatch fullscreen 1";
hyprbars-button = [
"$error, 10, , hyprctl dispatch killactive"
"$tertiary, 10, , hyprctl dispatch fullscreen 1"
];
};
};
};
}
+5 -50
View File
@@ -1,56 +1,11 @@
{
wayland.windowManager.hyprland.settings = {
workspace = [
"special:youtube, on-created-empty:uwsm app -- firefox -P YouTube --name youtube"
"special:music, on-created-empty:hakase-music-launch"
windowrule = [
# Make all inactive windows transparent
"match:class .*, opacity 1 0.8"
"match:class firefox, match:title (?i).*bitwarden.*, no_screen_share on"
];
windowrulev2 = [
# --- POPUP RULES (Wifi, BT, Audio) ---
"float, class:^(org\.hakase\.popup\..*)$"
"animation slide right, class:^(org\.hakase\.popup\..*)$"
"dimaround, class:^(org\.hakase\.popup\..*)$"
# --- WALLPAPER PICKER ---
"float, class:^(org\.hakase\.switch-wallpaper)$"
"float, initialTitle:^(Wallpaper Selector)$"
"center, class:^(org\.hakase\.switch-wallpaper)$"
"center, initialTitle:^(Wallpaper Selector)$"
"size 60% 60%, class:^(org\.hakase\.switch-wallpaper)$"
"size 60% 60%, initialTitle:^(Wallpaper Selector)$"
"dimaround, class:^(org\.hakase\.switch-wallpaper)$"
"dimaround, initialTitle:^(Wallpaper Selector)$"
# Prevent Firefox and Terminal from stealing focus on launch
"suppressevent activate, workspace:special:preload"
"noinitialfocus, workspace:special:preload"
# --- STEAM RULES ---
"workspace special:steam silent, class:^(steam)$"
"noinitialfocus, class:^(steam)$"
"suppressevent activate, class:^(steam)$"
# --- MUSIC RULES (Jellyfin-TUI) ---
"workspace special:music silent, title:^(jellyfin-tui)$"
"workspace special:music silent, initialTitle:^(jellyfin-tui)$"
# --- CAVA RULES ---
"workspace special:music silent, title:^(cava)$"
"workspace special:music silent, initialTitle:^(cava)$"
# --- YOUTUBE RULES ---
"workspace special:youtube, class:^(youtube)$"
# --- GAMING RULES ---
# Steam Apps, Gamescope, Lutris, Heroic, and Wine/Proton apps
"fullscreen, class:^steam_app_\d+$"
"monitor 0, class:^steam_app_\d+$"
"workspace 1, class:^steam_app_\d+$"
"fullscreen, class:^(gamescope)$"
"fullscreen, class:^(lutris)$"
"fullscreen, class:^(heroic)$"
"fullscreen, class:^wine-.*$"
"fullscreen, title:^Wine .*$"
workspace = [
];
};
}
+21 -7
View File
@@ -1,16 +1,12 @@
{pkgs, ...}: let
hakase-workspace-switch-force = pkgs.writeShellScriptBin "hakase-workspace-switch-force" ''
# Define binary paths to ensure they work regardless of environment PATH
HYPRCTL="${pkgs.hyprland}/bin/hyprctl"
JQ="${pkgs.jq}/bin/jq"
# Get the special workspace name
special_workspace=$($HYPRCTL monitors -j | $JQ -r '.[] | select(.focused) | .specialWorkspace.name')
# Strip the "special:" prefix (Nix escape: ''${var#*:})
workspace_name=''${special_workspace#*:}
# Get the target workspace number from argument
chosen_workspace_num=$1
if [[ -z ''${chosen_workspace_num} ]]; then
@@ -18,14 +14,11 @@
exit 1
fi
# Check if we are actually in a special workspace
if [[ "''${special_workspace}" == *"special"* ]]; then
echo "[LOG] workspace is ''${special_workspace}"
# Toggle the special workspace OFF
$HYPRCTL dispatch togglespecialworkspace "''${workspace_name}"
# Switch to the requested normal workspace
$HYPRCTL dispatch workspace "''${chosen_workspace_num}"
else
echo "[LOG] workspace is not special"
@@ -35,8 +28,29 @@
exit 0
'';
# TODO: revise
hakase-focus-switch = pkgs.writeShellScriptBin "hakase-focus-switch" ''
HYPRCTL="${pkgs.hyprland}/bin/hyprctl"
JQ="${pkgs.jq}/bin/jq"
workspace_id=$($HYPRCTL activeworkspace -j | $JQ '.id')
active_window=$($HYPRCTL activewindow -j)
is_floating=$(echo "$active_window" | $JQ '.floating')
if [ "$is_floating" == "true" ]; then
target_addr=$($HYPRCTL clients -j | $JQ -r --argjson ws "$workspace_id" '[.[] | select(.workspace.id == $ws and .floating == false)] | .[0].address')
else
target_addr=$($HYPRCTL clients -j | $JQ -r --argjson ws "$workspace_id" '[.[] | select(.workspace.id == $ws and .floating == true)] | .[0].address')
fi
if [ "$target_addr" != "null" ] && [ -n "$target_addr" ]; then
$HYPRCTL dispatch focuswindow address:$target_addr
fi
'';
in {
home.packages = [
hakase-workspace-switch-force
hakase-focus-switch
];
}
+71
View File
@@ -0,0 +1,71 @@
{pkgs, ...}: let
hyprctl = "${pkgs.hyprland}/bin/hyprctl";
jq = "${pkgs.jq}/bin/jq";
socat = "${pkgs.socat}/bin/socat";
hypr-window-rules = pkgs.writeShellScriptBin "hypr-window-rules" ''
LOG=/tmp/hypr-window-rules.log
log() { echo "[$(date +%T)] $*" >> "$LOG"; }
handle() {
local event="$1"
case "$event" in
windowtitlev2*)
local data="''${event#windowtitlev2>>}"
local addr="0x''${data%%,*}"
local title="''${data#*,}"
if echo "$title" | grep -qi "bitwarden"; then
log "bitwarden title detected: addr=$addr title=$title"
local info
info=$(${hyprctl} clients -j | ${jq} -r --arg addr "$addr" \
'.[] | select(.address == $addr) | "\(.class)|\(.floating)"')
local class="''${info%|*}"
local floating="''${info#*|}"
log " -> class=$class floating=$floating"
if [[ "$class" == "firefox" && "$floating" == "false" ]]; then
${hyprctl} dispatch togglefloating "address:$addr"
local target_w=600
local target_h=800
local mon_id
mon_id=$(${hyprctl} clients -j | ${jq} -r --arg addr "$addr" \
'.[] | select(.address == $addr) | .monitor')
local center
center=$(${hyprctl} monitors -j | ${jq} -r \
--argjson id "$mon_id" --argjson tw "$target_w" --argjson th "$target_h" \
'.[] | select(.id == $id) |
"\(.x + ((.width / .scale) - $tw) / 2 | floor)|\(.y + ((.height / .scale) - $th) / 2 | floor)"')
local cx="''${center%%|*}"
local cy="''${center#*|}"
${hyprctl} dispatch resizewindowpixel "exact $target_w $target_h, address:$addr"
${hyprctl} dispatch movewindowpixel "exact $cx $cy, address:$addr"
log " -> floated, resized to $target_w x $target_h, moved to $cx,$cy"
else
log " -> skipped (class or floating mismatch)"
fi
fi
;;
esac
}
log "started (HYPRLAND_INSTANCE_SIGNATURE=$HYPRLAND_INSTANCE_SIGNATURE)"
${socat} -u \
"UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" \
- \
| while IFS= read -r line; do handle "$line"; done
log "socat exited"
'';
in {
home.packages = [hypr-window-rules];
wayland.windowManager.hyprland.settings.exec-once = [
# FIXME: removed `hypr-window-rule` for excessive CPU usage. Reason unknown.
# "hypr-window-rules"
];
}
@@ -0,0 +1,27 @@
{pkgs, ...}: let
workspace-toggle = pkgs.writeShellScriptBin "workspace-toggle" ''
#!/usr/bin/env bash
target_workspace="$1"
# activeworkspace always returns the underlying workspace, even when a special
# workspace is open. Check the monitor's specialWorkspace field instead.
special=$(${pkgs.hyprland}/bin/hyprctl monitors -j | ${pkgs.jq}/bin/jq -r '.[] | select(.focused) | .specialWorkspace.name')
if [[ -n "$special" ]]; then
${pkgs.hyprland}/bin/hyprctl dispatch togglespecialworkspace "''${special#special:}"
current=$(${pkgs.hyprland}/bin/hyprctl activeworkspace -j | ${pkgs.jq}/bin/jq -r '.id')
if [[ $current -ne $target_workspace ]]; then
${pkgs.hyprland}/bin/hyprctl dispatch focusworkspaceoncurrentmonitor "$target_workspace"
fi
else
current=$(${pkgs.hyprland}/bin/hyprctl activeworkspace -j | ${pkgs.jq}/bin/jq -r '.id')
if [[ $current -eq $target_workspace ]]; then
${pkgs.hyprland}/bin/hyprctl dispatch workspace previous
else
${pkgs.hyprland}/bin/hyprctl dispatch split:workspace "$target_workspace"
fi
fi
'';
in {
home.packages = [workspace-toggle];
}
+36 -67
View File
@@ -1,66 +1,45 @@
{ config, pkgs, ... }:
let
{
config,
pkgs,
myConfig,
...
}: let
cacheWallpaper = "${config.home.homeDirectory}/.cache/current_wallpaper";
clockFont = "JetBrains Mono";
clockFont = myConfig.font.monospace;
scriptFont = myConfig.font.monospaceScript;
greetingConf = "${config.home.homeDirectory}/.cache/hyprlock-greeting.conf";
typewriter = pkgs.writeShellScript "hyprlock-typewriter" ''
text="Welcome back"
state_file="/tmp/hyprlock_typewriter"
lock_pid="/tmp/hyprlock_pid"
blink_file="/tmp/hyprlock_blink"
hakase-hyprlock = pkgs.writeShellScriptBin "hakase-hyprlock" ''
# Get focused monitor
monitor=$(hyprctl monitors -j | ${pkgs.jq}/bin/jq -r '.[] | select(.focused) | .name')
# Get current hyprlock PID
current_pid=$(pgrep -x hyprlock | head -1)
# Generate greeting label config
cat > ${greetingConf} << EOF
label {
monitor = $monitor
text = cmd[update:200] hakase-hyprlock-typewriter "\$(hakase-hyprlock-text-generator)"
color = \$on_surface_variant
font_size = 120
font_family = ${clockFont} Bold
position = 0, 480
halign = center
valign = center
}
EOF
# Reset if this is a new hyprlock session
if [ -f "$lock_pid" ]; then
old_pid=$(cat "$lock_pid")
if [ "$current_pid" != "$old_pid" ]; then
rm -f "$state_file" "$blink_file"
echo "$current_pid" > "$lock_pid"
fi
else
echo "$current_pid" > "$lock_pid"
fi
# Initialize position
if [ ! -f "$state_file" ]; then
echo 0 > "$state_file"
fi
pos=$(cat "$state_file")
len=''${#text}
# Increment position only if not complete
if [ "$pos" -lt "$len" ]; then
pos=$((pos + 1))
echo "$pos" > "$state_file"
echo "''${text:0:$pos}_"
else
# Blink cursor via foreground color toggle (slow blink)
if [ ! -f "$blink_file" ]; then
echo "0 0" > "$blink_file"
fi
read -r blink count < "$blink_file"
count=$((count + 1))
# Toggle every 5 updates (~600ms at 120ms interval)
if [ "$count" -ge 5 ]; then
count=0
blink=$((1 - blink))
fi
echo "$blink $count" > "$blink_file"
if [ "$blink" -eq 0 ]; then
echo "''${text}_"
else
echo "''${text}<span fgalpha=\"1\">_</span>"
fi
fi
exec hyprlock "$@"
'';
in {
imports = [
./scripts/typewriter.nix
./scripts/random-text.nix
];
home.packages = [hakase-hyprlock];
programs.hyprlock = {
enable = true;
extraConfig = ''
source = ~/.config/hypr/hyprlock-colors.conf
source = ${greetingConf}
general {
hide_cursor = true
@@ -77,18 +56,6 @@ in {
vibrancy = 0.2
}
# Typewriter greeting (above clock)
label {
monitor =
text = cmd[update:120] ${typewriter}
color = $on_surface_variant
font_size = 24
font_family = ${clockFont}
position = 0, 200
halign = center
valign = center
}
# Hours (top)
label {
monitor =
@@ -116,10 +83,10 @@ in {
# Date
label {
monitor =
text = cmd[update:60000] date '+%A, %B %d'
text = cmd[update:60000] echo "<span font_features='ss02'>$(date '+%A, %B %d')</span>"
color = $on_surface_variant
font_size = 18
font_family = ${clockFont}
font_family = ${clockFont} Italic
position = 0, -320
halign = center
valign = center
@@ -162,6 +129,8 @@ in {
fail_timeout = 2000
fail_transition = 300
}
'';
};
}
+247
View File
@@ -0,0 +1,247 @@
{pkgs, ...}: let
hakase-hyprlock-text-generator = pkgs.writeShellScriptBin "hakase-hyprlock-text-generator" ''
cache_file="''${XDG_RUNTIME_DIR:-/tmp}/hyprlock_greeting"
pid_file="''${XDG_RUNTIME_DIR:-/tmp}/hyprlock_greeting_pid"
current_pid=$(pgrep -x hyprlock | head -1)
# Pick new greeting only when hyprlock restarts
if [[ -f $pid_file && -f $cache_file ]]; then
old_pid=$(cat "$pid_file")
if [[ "$old_pid" == "$current_pid" ]]; then
cat "$cache_file"
exit 0
fi
fi
greetings=(
"Hello"
"Hola"
"Bonjour"
"Hallo"
"Ciao"
"Olá"
"Привет"
""
""
""
"مرحبا"
"שלום"
""
""
"Γειά σου"
"Merhaba"
"Xin chào"
"Cześć"
"Hej"
"Ahoj"
"Szia"
"Salut"
"Привіт"
""
""
"Jambo"
"Aloha"
"Sawubona"
"Hei"
"Hallå"
"Kamusta"
"Salam"
"Selamat"
"Saluton"
"Tere"
"Sveiki"
"Labas"
"Здраво"
"Здравей"
"Bok"
"Përshëndetje"
"Բարև"
""
"Сайн уу"
""
""
""
""
"Dia dhuit"
"Halò"
"Shwmae"
"Hoi"
"Halló"
"Kaixo"
"Bon dia"
"Ola"
"Ħello"
"ਿ "
" "
""
""
""
""
""
"Bawo"
"Ndeewo"
"Sannu"
"Iska warran"
"Kia ora"
"Bula"
"Talofa"
"Mālō e lelei"
""
""
"Yá'át'ééh"
"Allinllachu"
"Mba'éichapa"
"Salve"
"Moien"
"Apa khabar"
"Сәлем"
"Assalomu alaykum"
"Slav"
""
)
inspirations=(
"Dream Big"
"Stay True"
"Be Kind"
"Work Hard"
"Keep Going"
"Be Brave"
"Love Life"
"Stay Calm"
"Think Positive"
"Be Happy"
"No Fear"
"Have Faith"
"Trust Yourself"
"Focus Now"
"Take Action"
"Never Settle"
"Rise Up"
"Shine On"
"Stand Tall"
"Live Free"
"Just Begin"
"Create Joy"
"Stay Strong"
"Breathe Deep"
"Be Bold"
"Look Ahead"
"Move Forward"
"Aim High"
"Stay Humble"
"Find Peace"
"Do Good"
"Seek Truth"
"Love More"
"Be Yourself"
"Let Go"
"Keep Smiling"
"Stay Wild"
"Think Big"
"Be Awesome"
"Start Now"
"Enjoy Today"
"Choose Joy"
"Dream On"
"Fly High"
"Stay Focused"
"Be Fearless"
"Don't Stop"
"Make Waves"
"Be Original"
"Stay Curious"
"Be grateful"
"Keep pushing"
"Stay sharp"
"Why not?"
"Be still"
"Keep cool"
"Think twice"
"Be ready"
"Stay gold"
"Game on"
"Level up"
"Code on"
"Git commit"
"Hack on"
)
cyberpunk=(
"System: ONLINE"
"Encryption: ACTIVE"
"Access: GRANTED"
"Uptime: OPTIMAL"
"Link: ESTABLISHED"
"Protocol: SECURE"
"Daemon: WATCHING"
"Netrunner: READY"
"Signal: STRONG"
"Proxy: ENGAGED"
"Root: ACCESS"
"Kernel: PANIC"
)
yojijukugo=(
""
""
""
""
""
""
""
""
)
habits=(
"Check posture"
"Drink water"
"Shoulders down"
"Eyes off screen"
"Deep breath"
"Stretch now"
"Unclench jaw"
"Touch grass"
"Blink now"
"Stand up"
)
dev=(
"It works locally"
"Sudo please"
"Flake locked"
"Compiling..."
"Git push force"
"rm -rf /"
":q! to exit"
"Works on my machine"
"Coffee needed"
"Fixing bugs"
"Hello World"
"Null Pointer"
"Segfault"
)
# Combine all arrays
combined=(
"''${greetings[@]}"
"''${inspirations[@]}"
# "''${cyberpunk[@]}"
"''${yojijukugo[@]}"
"''${habits[@]}"
"''${dev[@]}"
)
idx=$((RANDOM % ''${#combined[@]}))
greeting="''${combined[$idx]}"
echo "$current_pid" > "$pid_file"
echo "$greeting" > "$cache_file"
echo "$greeting"
'';
in {
home.packages = [
hakase-hyprlock-text-generator
];
}
+60
View File
@@ -0,0 +1,60 @@
{pkgs, ...}: let
hakase-hyprlock-typewriter = pkgs.writeShellScriptBin "hakase-hyprlock-typewriter" ''
text="$1"
if [[ -z "$text" ]]; then
echo "Usage: $(basename "$0") [text]"
exit 1
fi
state_file="''${XDG_RUNTIME_DIR:-/tmp}/typewriter_pos"
blink_file="''${XDG_RUNTIME_DIR:-/tmp}/typewriter_blink"
pid_file="''${XDG_RUNTIME_DIR:-/tmp}/typewriter_pid"
current_pid=$(pgrep -x hyprlock | head -1)
if [[ -f $pid_file ]]; then
old_pid=$(cat $pid_file)
if [[ "''${old_pid}" != "''${current_pid}" ]]; then
rm -f "$state_file" "$blink_file"
fi
fi
echo "$current_pid" >"$pid_file"
if [[ ! -f $state_file ]]; then
echo 0 >"$state_file"
fi
if [[ ! -f $blink_file ]]; then
echo 0 >"$blink_file"
fi
len=''${#text}
letter=$(cat "$state_file")
blink=$(cat "$blink_file")
if [[ $letter -lt $len ]]; then
letter=$((letter + 1))
echo "$letter" >"$state_file"
echo "''${text:0:$letter}_"
else
# Toggle every 4 calls (at 200ms update = ~800ms blink)
if (((blink / 4) % 2 == 0)); then
echo "''${text}_"
else
echo "''${text}<span alpha=\"1%\">_</span>"
fi
fi
blink=$((blink + 1))
echo "$blink" >"$blink_file"
'';
hakase-test-hyprlock-typewriter = pkgs.writeShellScriptBin "hakase-test-hyprlock-typewriter" ''
for i in {1..10}; do
hakase-hyprlock-typewriter
done
'';
in {
home.packages = [
hakase-hyprlock-typewriter
hakase-test-hyprlock-typewriter
];
}
+42 -6
View File
@@ -5,6 +5,7 @@
myConfig,
...
}: let
# TODO: rewrite
wallpaperDir = "${config.home.homeDirectory}/.config/nixos/assets/Wallpapers";
defaultWallpaper = "${wallpaperDir}/${myConfig.hyprland.wallpaper}";
cacheWallpaper = "${config.home.homeDirectory}/.cache/current_wallpaper";
@@ -21,13 +22,24 @@
fi
tmp_file=$(mktemp)
target_dir="$HOME/Pictures/Wallpapers"
if [ ! -d "$target_dir" ]; then
target_dir="$HOME"
LAST_WALLPAPER_FILE="$HOME/.cache/last_wallpaper_path"
if [ -f "$LAST_WALLPAPER_FILE" ]; then
last_path=$(cat "$LAST_WALLPAPER_FILE")
if [ -f "$last_path" ]; then
yazi_target="$last_path"
fi
fi
if [ -z "$yazi_target" ]; then
yazi_target="$HOME/Pictures/Wallpapers"
if [ ! -d "$yazi_target" ]; then
yazi_target="$HOME"
fi
fi
# Ensure we are in a terminal that supports yazi
${pkgs.yazi}/bin/yazi "$target_dir" --chooser-file="$tmp_file"
${pkgs.yazi}/bin/yazi "$yazi_target" --chooser-file="$tmp_file"
if [ ! -f "$tmp_file" ]; then
echo "No selection file created."
@@ -45,18 +57,42 @@
# Persistence logic
CACHE_FILE="$HOME/.cache/current_wallpaper"
cp "$WALLPAPER" "$CACHE_FILE"
echo "$WALLPAPER" > "$HOME/.cache/last_wallpaper_path"
# Reload hyprpaper
${pkgs.hyprland}/bin/hyprctl hyprpaper unload all
${pkgs.hyprland}/bin/hyprctl hyprpaper preload "$CACHE_FILE"
${pkgs.hyprland}/bin/hyprctl hyprpaper wallpaper ",$CACHE_FILE"
exec matugen image "$CACHE_FILE"
exec matugen image "$CACHE_FILE" --source-color-index 0
'';
in {
wayland.windowManager.hyprland.settings = {
exec-once = [
"uwsm app -- hyprpaper"
];
bindd = [
"SUPER CTRL, I, Switch Wallpaper, exec, hakase-wallpaper-switch"
];
windowrule = [
# --- WALLPAPER PICKER ---
"match:class ^(org\.hakase\.switch-wallpaper)$, float on"
"match:initial_title ^(Wallpaper Selector)$, float on"
"match:class ^(org\.hakase\.switch-wallpaper)$, center on"
"match:initial_title ^(Wallpaper Selector)$, center on"
"match:class ^(org\.hakase\.switch-wallpaper)$, size 60% 60%"
"match:initial_title ^(Wallpaper Selector)$, size 60% 60%"
"match:class ^(org\.hakase\.switch-wallpaper)$, dim_around on"
"match:initial_title ^(Wallpaper Selector)$, dim_around on"
];
};
services.hyprpaper = {
enable = true;
settings = {
splash = false;
preload = [cacheWallpaper];
wallpaper = [
",${cacheWallpaper}"
@@ -81,4 +117,4 @@ in {
'';
systemd.user.startServices = "sd-switch";
}
}
+81
View File
@@ -0,0 +1,81 @@
{pkgs, ...}: let
# Max window size (leave room for waybar/hyprbars)
maxW = 2800;
maxH = 1100;
swayimg-wrapper = pkgs.writeShellScriptBin "swayimg-wrapper" ''
if [ -z "$1" ]; then
exec ${pkgs.swayimg}/bin/swayimg
fi
# Get image dimensions
dims=$(${pkgs.file}/bin/file -b "$1" | ${pkgs.gnugrep}/bin/grep -oP '\d+ ?x ?\d+' | head -1 | tr -d ' ')
if [ -z "$dims" ]; then
# Fallback if file doesn't report dimensions
exec ${pkgs.swayimg}/bin/swayimg "$@"
fi
imgW=$(echo "$dims" | cut -dx -f1)
imgH=$(echo "$dims" | cut -dx -f2)
# Calculate scale to fit within max bounds while preserving aspect ratio
scaleW=$(echo "scale=4; ${toString maxW} / $imgW" | ${pkgs.bc}/bin/bc)
scaleH=$(echo "scale=4; ${toString maxH} / $imgH" | ${pkgs.bc}/bin/bc)
# Use the smaller scale factor
if [ $(echo "$scaleW < $scaleH" | ${pkgs.bc}/bin/bc) -eq 1 ]; then
scale=$scaleW
else
scale=$scaleH
fi
# Only scale down, not up
if [ $(echo "$scale >= 1" | ${pkgs.bc}/bin/bc) -eq 1 ]; then
exec ${pkgs.swayimg}/bin/swayimg "$@"
fi
# Calculate new size
newW=$(echo "$imgW * $scale / 1" | ${pkgs.bc}/bin/bc)
newH=$(echo "$imgH * $scale / 1" | ${pkgs.bc}/bin/bc)
exec ${pkgs.swayimg}/bin/swayimg --size="$newW,$newH" "$@"
'';
in {
home.packages = [pkgs.swayimg swayimg-wrapper];
xdg.mimeApps = {
enable = true;
defaultApplications = {
"image/png" = "swayimg-wrapper.desktop";
"image/jpeg" = "swayimg-wrapper.desktop";
"image/gif" = "swayimg-wrapper.desktop";
"image/webp" = "swayimg-wrapper.desktop";
"image/bmp" = "swayimg-wrapper.desktop";
"image/svg+xml" = "swayimg-wrapper.desktop";
"image/tiff" = "swayimg-wrapper.desktop";
};
};
xdg.desktopEntries.swayimg-wrapper = {
name = "Swayimg";
exec = "swayimg-wrapper %f";
terminal = false;
type = "Application";
mimeType = ["image/png" "image/jpeg" "image/gif" "image/webp" "image/bmp" "image/svg+xml" "image/tiff"];
};
# swayimg config
xdg.configFile."swayimg/config".text = ''
[viewer]
scale = fit
[info]
show = no
'';
wayland.windowManager.hyprland.settings.windowrule = [
# --- IMAGE VIEWER (swayimg) ---
"match:class ^(swayimg)$, float on"
"match:class ^(swayimg)$, center on"
];
}
+75
View File
@@ -0,0 +1,75 @@
{pkgs, ...}: {
services.jellyfin-mpv-shim = {
enable = true;
package = pkgs.jellyfin-mpv-shim;
mpvConfig = {
osc = false;
osd-bar = false;
load-scripts = true;
input-vo-keyboard = true;
input-default-bindings = true;
# Automatic subtitle selection logic:
# Prefer English subtitles
slang = "eng,en";
# Prefer Japanese/Non-English audio first (if that's what you usually watch)
# or just ensure English subs are picked when audio isn't English.
sub-auto = "fuzzy";
sub-visibility = "yes";
};
mpvBindings = {
"j" = "cycle sub";
"S-j" = "cycle sub rev";
"v" = "cycle sub-visibility";
};
settings = {
use_mpv_config = false;
enable_osc = false;
menu_mouse = true;
# Shim specific auto-sub logic
# "subs-fallback" is a known good setting for the shim to handle this
subtitle_color = "#FFFFFFFF";
subtitle_size = 100;
audio_output = "hdmi";
auto_play = true;
fullscreen = true;
player_name = "hakase";
remote_kbps = 100000;
local_kbps = 1000000;
};
};
# Modern OSC + Quality scripts
home.file.".config/jellyfin-mpv-shim/scripts/uosc" = {
source = "${pkgs.mpvScripts.uosc}/share/mpv/scripts/uosc";
};
home.file.".config/jellyfin-mpv-shim/scripts/thumbfast.lua" = {
source = "${pkgs.mpvScripts.thumbfast}/share/mpv/scripts/thumbfast.lua";
};
home.file.".config/jellyfin-mpv-shim/scripts/autocrop.lua" = {
source = "${pkgs.mpvScripts.autocrop}/share/mpv/scripts/autocrop.lua";
};
home.file.".config/jellyfin-mpv-shim/fonts" = {
source = "${pkgs.mpvScripts.uosc}/share/fonts";
recursive = true;
};
wayland.windowManager.hyprland.settings = {
exec-once = [ "systemctl --user start jellyfin-mpv-shim" ];
windowrule = [
# --- JELLYFIN MPV SHIM ---
"match:class ^(jellyfin-mpv-shim)$, float on"
"match:class ^(jellyfin-mpv-shim)$, center on"
"match:class ^(jellyfin-mpv-shim)$, size 70% 70%"
"match:class ^(jellyfin-mpv-shim)$, opacity 1.0 override 1.0 override"
"match:class ^(jellyfin-mpv-shim)$, idle_inhibit focus"
"match:class ^(jellyfin-mpv-shim)$, no_blur on"
];
};
}
+1
View File
@@ -1,5 +1,6 @@
{pkgs, ...}: {
home.packages = with pkgs; [
# FIXME: only dark mode works. use matugen
jellyfin-tui
];
}
+5
View File
@@ -0,0 +1,5 @@
{pkgs, ...}: {
home.packages = with pkgs; [
libreoffice-fresh
];
}
+11
View File
@@ -0,0 +1,11 @@
{
pkgs,
config,
...
}: {
home.packages = with pkgs; [
libnotify
];
services.mako.enable = true;
}
+18
View File
@@ -24,6 +24,10 @@ output_path = "~/.config/starship.toml"
input_path = "~/.config/matugen/templates/walker"
output_path = "~/.config/walker/themes/nixos/style.css"
[templates.zathura]
input_path = "~/.config/matugen/templates/zathura"
output_path = "~/.config/zathura/zathura-matugen"
[templates.pywalfox]
input_path = '~/.config/matugen/templates/firefox'
output_path = '~/.cache/wal/colors.json'
@@ -46,3 +50,17 @@ output_path = "~/.config/gtk-4.0/colors.css"
input_path = "~/.config/matugen/templates/hyprlock"
output_path = "~/.config/hypr/hyprlock-colors.conf"
[templates.mako]
input_path = "~/.config/matugen/templates/mako"
output_path = "~/.config/mako/config"
post_hook = "makoctl reload"
[templates.vicinae]
input_path = "~/.config/matugen/templates/vicinae"
output_path = "~/.local/share/vicinae/themes/matugen.toml"
post_hook = "vicinae theme set matugen"
[templates.theme-switch]
input_path = "~/.config/matugen/templates/theme-switch"
output_path = "~/.config/matugen/scripts/theme-switch.sh"
post_hook = "sh ~/.config/matugen/scripts/theme-switch.sh"
+362 -5
View File
@@ -1,26 +1,371 @@
{
pkgs,
inputs,
myConfig,
...
}: {
home.packages = with pkgs; [
matugen
inputs.matugen.packages.${pkgs.system}.default
dconf
psmisc # for killall
];
home.file.".config/matugen/config.toml" = {
source = ./config.toml;
};
home.file.".config/matugen/templates" = {
source = ./templates;
recursive = true;
# Copy static templates
home.file.".config/matugen/templates/theme-switch".text = ''
#!/bin/sh
# Generated by Matugen
# mode will be replaced by 'dark' or 'light'
MODE="{{mode}}"
if [ "$MODE" = "dark" ]; then
${pkgs.dconf}/bin/dconf write /org/gnome/desktop/interface/color-scheme "'prefer-dark'"
else
${pkgs.dconf}/bin/dconf write /org/gnome/desktop/interface/color-scheme "'prefer-light'"
fi
'';
home.file.".config/matugen/templates/cava".source = ./templates/cava;
home.file.".config/matugen/templates/firefox".source = ./templates/firefox;
home.file.".config/matugen/templates/ghostty".source = ./templates/ghostty;
home.file.".config/matugen/templates/gtk3".source = ./templates/gtk3;
home.file.".config/matugen/templates/gtk4".source = ./templates/gtk4;
home.file.".config/matugen/templates/hyprland".source = ./templates/hyprland;
home.file.".config/matugen/templates/hyprlock".source = ./templates/hyprlock;
home.file.".config/matugen/templates/starship".source = ./templates/starship;
home.file.".config/matugen/templates/waybar".source = ./templates/waybar;
home.file.".config/matugen/templates/zathura".source = ./templates/zathura;
home.file.".config/matugen/templates/vicinae".text = ''
# Vicinae Matugen Theme Template
[meta]
name = "Matugen"
description = "Material You theme generated by Matugen - {{mode}} variant"
variant = "{{mode}}"
# ============================================================================
# Typography
# ============================================================================
[typography]
font_family = "${myConfig.font.monospace}"
# ============================================================================
# Core Colors
# ============================================================================
[colors.core]
accent = "{{colors.primary.default.hex}}"
accent_foreground = "{{colors.on_primary.default.hex}}"
background = "{{colors.surface.default.hex}}"
foreground = "{{colors.on_surface.default.hex}}"
secondary_background = "{{colors.surface_container.default.hex}}"
border = "{{colors.outline_variant.default.hex}}"
# ============================================================================
# Window Borders
# ============================================================================
[colors.main_window]
border = "{{colors.outline_variant.default.hex}}"
[colors.settings_window]
border = "{{colors.outline.default.hex}}"
# ============================================================================
# Accent Palette
# ============================================================================
[colors.accents]
blue = "{{colors.primary.default.hex}}"
green = "{{colors.tertiary.default.hex}}"
magenta = "{{colors.secondary.default.hex}}"
orange = { name = "{{colors.error.default.hex}}", lighter = 40 }
red = "{{colors.error.default.hex}}"
yellow = { name = "{{colors.tertiary.default.hex}}", lighter = 80 }
cyan = { name = "{{colors.primary.default.hex}}", lighter = 50 }
purple = "{{colors.secondary.default.hex}}"
# ============================================================================
# Text System
# ============================================================================
[colors.text]
default = "{{colors.on_surface.default.hex}}"
muted = "{{colors.on_surface_variant.default.hex}}"
danger = "{{colors.error.default.hex}}"
success = "{{colors.tertiary.default.hex}}"
placeholder = { name = "{{colors.on_surface_variant.default.hex}}", opacity = 0.6 }
[colors.text.selection]
background = "{{colors.primary.default.hex}}"
foreground = "{{colors.on_primary.default.hex}}"
[colors.text.links]
default = "{{colors.primary.default.hex}}"
visited = { name = "{{colors.tertiary.default.hex}}", darker = 20 }
# ============================================================================
# Input Fields
# ============================================================================
[colors.input]
border = "{{colors.outline.default.hex}}"
border_focus = "{{colors.primary.default.hex}}"
border_error = "{{colors.error.default.hex}}"
# ============================================================================
# Buttons
# ============================================================================
[colors.button.primary]
background = "{{colors.surface_container_high.default.hex}}"
foreground = "{{colors.on_surface.default.hex}}"
[colors.button.primary.hover]
background = "{{colors.surface_container_highest.default.hex}}"
[colors.button.primary.focus]
outline = "{{colors.primary.default.hex}}"
# ============================================================================
# Lists
# ============================================================================
[colors.list.item.hover]
background = { name = "{{colors.primary_container.default.hex}}", opacity = 0.25 }
foreground = "{{colors.on_surface.default.hex}}"
[colors.list.item.selection]
background = { name = "{{colors.primary_container.default.hex}}", opacity = 0.50 }
foreground = "{{colors.on_primary_container.default.hex}}"
secondary_background = "{{colors.primary_container.default.hex}}"
secondary_foreground = "{{colors.on_primary_container.default.hex}}"
# ============================================================================
# Grid Items
# ============================================================================
[colors.grid.item]
background = "{{colors.surface_container.default.hex}}"
[colors.grid.item.hover]
outline = { name = "{{colors.secondary.default.hex}}", opacity = 0.8 }
[colors.grid.item.selection]
outline = { name = "{{colors.primary.default.hex}}" }
# ============================================================================
# Scrollbars
# ============================================================================
[colors.scrollbars]
background = { name = "{{colors.primary.default.hex}}", opacity = 0.2 }
# ============================================================================
# Loading States
# ============================================================================
[colors.loading]
bar = "{{colors.primary.default.hex}}"
spinner = "{{colors.primary.default.hex}}"
'';
# Generate templates with font interpolation
home.file.".config/matugen/templates/walker".text = ''
/* @import "../../../../../../../.config/omarchy/current/theme/walker.css"; */
/* Define Matugen Colors */
@define-color text {{colors.on_surface.default.hex}};
@define-color base {{colors.surface_container.default.hex}};
@define-color border {{colors.primary.default.hex}};
@define-color selected_text {{colors.primary.default.hex}};
@define-color background {{colors.surface.default.hex}};
* {
all: unset;
}
* {
font-family: ${myConfig.font.monospace};
font-size: 18px;
color: @text;
}
scrollbar {
opacity: 0;
}
.normal-icons {
-gtk-icon-size: 16px;
}
.large-icons {
-gtk-icon-size: 32px;
}
.box-wrapper {
background: alpha(@base, 0.95);
padding: 20px;
border: 2px solid @border;
}
.preview-box {
}
.box {
}
.search-container {
background: @base;
padding: 10px;
}
.input placeholder {
opacity: 0.5;
}
.input {
}
.input:focus,
.input:active {
box-shadow: none;
outline: none;
}
.content-container {
}
.placeholder {
}
.scroll {
}
.list {
}
child,
child > * {
}
child:hover .item-box {
}
child:selected .item-box {
}
child:selected .item-box * {
color: @selected_text;
}
.item-box {
padding-left: 14px;
}
.item-text-box {
all: unset;
padding: 14px 0;
}
.item-text {
}
.item-subtext {
font-size: 0px;
min-height: 0px;
margin: 0px;
padding: 0px;
}
.item-image {
margin-right: 14px;
-gtk-icon-transform: scale(0.9);
}
.current {
font-style: italic;
}
.keybind-hints {
background: @background;
padding: 10px;
margin-top: 10px;
}
.preview {
}
'';
home.file.".config/matugen/templates/mako".text = ''
# Mako notification daemon configuration
# Generated by matugen
# Appearance
font=${myConfig.font.sans} 11
width=350
height=150
margin=10
padding=15
border-size=2
border-radius=8
# Behavior
default-timeout=5000
ignore-timeout=false
layer=overlay
anchor=top-right
# Interaction
markup=true
actions=true
# Grouping
group-by=app-name
max-visible=5
sort=-time
# Theme colors from matugen
background-color=#{{colors.surface_container_high.default.hex_stripped}}
text-color=#{{colors.on_surface.default.hex_stripped}}
border-color=#{{colors.primary.default.hex_stripped}}
progress-color=over #{{colors.primary_container.default.hex_stripped}}
[urgency=low]
border-color=#{{colors.tertiary.default.hex_stripped}}
[urgency=normal]
border-color=#{{colors.primary.default.hex_stripped}}
[urgency=high]
border-color=#{{colors.error.default.hex_stripped}}
default-timeout=0
'';
# Qt theming - follow GTK theme
qt = {
enable = true;
platformTheme.name = "gtk";
};
dconf.settings = {
"org/gnome/desktop/interface" = {
color-scheme =
if myConfig.theme.mode == "dark"
then "prefer-dark"
else "prefer-light";
};
};
# GTK theming with adw-gtk3 and Matugen colors
gtk = {
enable = true;
theme = {
name = "adw-gtk3-dark";
name = "adw-gtk3";
package = pkgs.adw-gtk3;
};
iconTheme = {
@@ -28,7 +373,19 @@
package = pkgs.papirus-icon-theme;
};
gtk3.extraCss = ''@import url("colors.css");'';
gtk3.extraConfig = {
gtk-application-prefer-dark-theme =
if myConfig.theme.mode == "dark"
then 1
else 0;
};
gtk4.extraCss = ''@import url("colors.css");'';
gtk4.extraConfig = {
gtk-application-prefer-dark-theme =
if myConfig.theme.mode == "dark"
then 1
else 0;
};
};
programs.ghostty.settings.theme = "matugen";
+16
View File
@@ -76,3 +76,19 @@
@define-color dark_3 {{colors.surface_container.default.hex}};
@define-color dark_4 {{colors.surface_container_high.default.hex}};
@define-color dark_5 {{colors.surface_container_highest.default.hex}};
/* Sidebar Fixes */
.sidebar, .navigation-sidebar {
background-color: @view_bg_color;
color: @view_fg_color;
}
.sidebar list, .navigation-sidebar list {
background-color: transparent;
color: @view_fg_color;
}
filechooser .sidebar {
background-color: @view_bg_color;
color: @view_fg_color;
}
+16
View File
@@ -76,3 +76,19 @@
@define-color dark_3 {{colors.surface_container.default.hex}};
@define-color dark_4 {{colors.surface_container_high.default.hex}};
@define-color dark_5 {{colors.surface_container_highest.default.hex}};
/* Sidebar Fixes */
.sidebar, .navigation-sidebar {
background-color: @view_bg_color;
color: @view_fg_color;
}
.sidebar list, .navigation-sidebar list {
background-color: transparent;
color: @view_fg_color;
}
filechooser .sidebar {
background-color: @view_bg_color;
color: @view_fg_color;
}
+42
View File
@@ -0,0 +1,42 @@
# Mako notification daemon configuration
# Generated by matugen
# Appearance
font=Sans 11
width=350
height=150
margin=10
padding=15
border-size=2
border-radius=8
# Behavior
default-timeout=5000
ignore-timeout=false
layer=overlay
anchor=top-right
# Interaction
markup=true
actions=true
# Grouping
group-by=app-name
max-visible=5
sort=-time
# Theme colors from matugen
background-color=#{{colors.surface_container_high.default.hex_stripped}}
text-color=#{{colors.on_surface.default.hex_stripped}}
border-color=#{{colors.primary.default.hex_stripped}}
progress-color=over #{{colors.primary_container.default.hex_stripped}}
[urgency=low]
border-color=#{{colors.tertiary.default.hex_stripped}}
[urgency=normal]
border-color=#{{colors.primary.default.hex_stripped}}
[urgency=high]
border-color=#{{colors.error.default.hex_stripped}}
default-timeout=0
+41
View File
@@ -0,0 +1,41 @@
set default-bg "#{{colors.surface.default.hex_stripped}}"
set default-fg "#{{colors.on_surface.default.hex_stripped}}"
set statusbar-bg "#{{colors.surface.default.hex_stripped}}"
set statusbar-fg "#{{colors.on_surface.default.hex_stripped}}"
set inputbar-bg "#{{colors.surface.default.hex_stripped}}"
set inputbar-fg "#{{colors.on_surface.default.hex_stripped}}"
set notification-bg "#{{colors.surface.default.hex_stripped}}"
set notification-fg "#{{colors.on_surface.default.hex_stripped}}"
set notification-error-bg "#{{colors.error.default.hex_stripped}}"
set notification-error-fg "#{{colors.on_error.default.hex_stripped}}"
set notification-warning-bg "#{{colors.tertiary.default.hex_stripped}}"
set notification-warning-fg "#{{colors.on_tertiary.default.hex_stripped}}"
set highlight-color "#{{colors.tertiary.default.hex_stripped}}"
set highlight-active-color "#{{colors.secondary.default.hex_stripped}}"
set completion-bg "#{{colors.surface.default.hex_stripped}}"
set completion-fg "#{{colors.on_surface.default.hex_stripped}}"
set completion-group-bg "#{{colors.surface.default.hex_stripped}}"
set completion-group-fg "#{{colors.on_surface.default.hex_stripped}}"
set completion-highlight-bg "#{{colors.on_surface.default.hex_stripped}}"
set completion-highlight-fg "#{{colors.surface.default.hex_stripped}}"
set index-bg "#{{colors.surface.default.hex_stripped}}"
set index-fg "#{{colors.on_surface.default.hex_stripped}}"
set index-active-bg "#{{colors.surface_container.default.hex_stripped}}"
set index-active-fg "#{{colors.on_surface.default.hex_stripped}}"
set render-loading-bg "#{{colors.surface.default.hex_stripped}}"
set render-loading-fg "#{{colors.on_surface.default.hex_stripped}}"
set recolor-lightcolor "#{{colors.surface.default.hex_stripped}}"
set recolor-darkcolor "#{{colors.on_surface.default.hex_stripped}}"
+39
View File
@@ -0,0 +1,39 @@
{pkgs, ...}: {
programs.mpv = {
enable = true;
scripts = with pkgs.mpvScripts; [
uosc
thumbfast
];
config = {
# uosc provides its own UI
osc = "no";
osd-bar = "no";
border = "no";
# Subtitle preferences - prefer full subtitles over forced
# slang = "eng,en,enm"; # English subtitle preference order
# subs-fallback = "default"; # Use default if preferred not found
# sub-forced-events-only = "no"; # Don't limit to forced subtitle events
};
};
xdg.mimeApps = {
enable = true;
defaultApplications = {
"video/mp4" = "mpv.desktop";
"video/mkv" = "mpv.desktop";
"video/webm" = "mpv.desktop";
"video/avi" = "mpv.desktop";
"video/x-matroska" = "mpv.desktop";
"video/quicktime" = "mpv.desktop";
};
};
wayland.windowManager.hyprland.settings.windowrule = [
# --- VIDEO PLAYER (mpv) ---
"match:class ^(mpv)$, float on"
"match:class ^(mpv)$, center on"
"match:class ^(mpv)$, size 60% 70%"
];
}
+1
View File
@@ -5,6 +5,7 @@
...
}: {
home.packages = [
# FIXME: does not dynamically update with matugen when open
inputs.nixovim.packages.${pkgs.system}.full
];
}
+9
View File
@@ -0,0 +1,9 @@
{pkgs, ...}: {
home.packages = with pkgs; [
nextcloud-client
];
wayland.windowManager.hyprland.settings.exec-once = [
"uwsm app -- nextcloud --background"
];
}
+13
View File
@@ -0,0 +1,13 @@
{pkgs, ...}: {
home.packages = [
pkgs.playerctl
];
wayland.windowManager.hyprland.settings = {
bindl = [
", XF86AudioPlay, exec, playerctl play-pause && notify-send -u low -t 1000 \"Media\" \"$(playerctl status)\""
", XF86AudioPrev, exec, playerctl previous && notify-send -u low -t 1000 \"Previous Track\" \"$(playerctl metadata title)\""
", XF86AudioNext, exec, playerctl next && notify-send -u low -t 1000 \"Next Track\" \"$(playerctl metadata title)\""
];
};
}
+17
View File
@@ -0,0 +1,17 @@
{ pkgs }:
pkgs.stdenv.mkDerivation {
pname = "hakase-plymouth-theme";
version = "1.0";
src = ./themes/hakase;
installPhase = ''
mkdir -p $out/share/plymouth/themes/hakase
cp * $out/share/plymouth/themes/hakase/
# Patch the .plymouth file to point to the store path
sed -i "s@ImageDir=.*@ImageDir=$out/share/plymouth/themes/hakase@" $out/share/plymouth/themes/hakase/hakase.plymouth
sed -i "s@ScriptFile=.*@ScriptFile=$out/share/plymouth/themes/hakase/hakase.script@" $out/share/plymouth/themes/hakase/hakase.plymouth
'';
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

@@ -0,0 +1,11 @@
[Plymouth Theme]
Name=Omarchy
Description=Omarchy splash screen.
ModuleName=script
[script]
ImageDir=/usr/share/plymouth/themes/omarchy
ScriptFile=/usr/share/plymouth/themes/omarchy/omarchy.script
ConsoleLogBackgroundColor=0x1a1b26
MonospaceFont=Cantarell 11
Font=Cantarell 11
+257
View File
@@ -0,0 +1,257 @@
# Omarchy Plymouth Theme Script
Window.SetBackgroundTopColor(0.176, 0.067, 0.165);
Window.SetBackgroundBottomColor(0.176, 0.067, 0.165);
logo.image = Image("logo.png");
logo.sprite = Sprite(logo.image);
logo.sprite.SetX (Window.GetWidth() / 2 - logo.image.GetWidth() / 2);
logo.sprite.SetY (Window.GetHeight() / 2 - logo.image.GetHeight() / 2);
logo.sprite.SetOpacity (1);
# Use these to adjust the progress bar timing
global.fake_progress_limit = 0.7; # Target percentage for fake progress (0.0 to 1.0)
global.fake_progress_duration = 15.0; # Duration in seconds to reach limit
# Progress bar animation variables
global.fake_progress = 0.0;
global.real_progress = 0.0;
global.fake_progress_active = 0; # 0 / 1 boolean
global.animation_frame = 0;
global.fake_progress_start_time = 0; # Track when fake progress started
global.password_shown = 0; # Track if password dialog has been shown
global.max_progress = 0.0; # Track the maximum progress reached to prevent backwards movement
fun refresh_callback ()
{
global.animation_frame++;
# Animate fake progress to limit over time with easing
if (global.fake_progress_active == 1)
{
# Calculate elapsed time since start
elapsed_time = global.animation_frame / 50.0; # Convert frames to seconds (50 FPS)
# Calculate linear progress ratio (0 to 1) based on time
time_ratio = elapsed_time / global.fake_progress_duration;
if (time_ratio > 1.0)
time_ratio = 1.0;
# Apply easing curve: ease-out quadratic
# Formula: 1 - (1 - x)^2
eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio));
# Calculate fake progress based on eased ratio
global.fake_progress = eased_ratio * global.fake_progress_limit;
# Update progress bar with fake progress
update_progress_bar(global.fake_progress);
}
}
Plymouth.SetRefreshFunction (refresh_callback);
#----------------------------------------- Helper Functions --------------------------------
fun update_progress_bar(progress)
{
# Only update if progress is moving forward
if (progress > global.max_progress)
{
global.max_progress = progress;
width = Math.Int(progress_bar.original_image.GetWidth() * progress);
if (width < 1) width = 1; # Ensure minimum width of 1 pixel
progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight());
progress_bar.sprite.SetImage(progress_bar.image);
}
}
fun show_progress_bar()
{
progress_box.sprite.SetOpacity(1);
progress_bar.sprite.SetOpacity(1);
}
fun hide_progress_bar()
{
progress_box.sprite.SetOpacity(0);
progress_bar.sprite.SetOpacity(0);
}
fun show_password_dialog()
{
lock.sprite.SetOpacity(1);
entry.sprite.SetOpacity(1);
}
fun hide_password_dialog()
{
lock.sprite.SetOpacity(0);
entry.sprite.SetOpacity(0);
for (index = 0; bullet.sprites[index]; index++)
bullet.sprites[index].SetOpacity(0);
}
fun start_fake_progress()
{
# Don't reset if we already have progress
if (global.max_progress == 0.0)
{
global.fake_progress = 0.0;
global.real_progress = 0.0;
update_progress_bar(0.0);
}
global.fake_progress_active = 1;
global.animation_frame = 0;
}
fun stop_fake_progress()
{
global.fake_progress_active = 0;
}
#----------------------------------------- Dialogue --------------------------------
lock.image = Image("lock.png");
entry.image = Image("entry.png");
bullet.image = Image("bullet.png");
entry.sprite = Sprite(entry.image);
entry.x = Window.GetWidth()/2 - entry.image.GetWidth() / 2;
entry.y = logo.sprite.GetY() + logo.image.GetHeight() + 40;
entry.sprite.SetPosition(entry.x, entry.y, 10001);
entry.sprite.SetOpacity(0);
# Scale lock to be slightly shorter than entry field height
# Original lock is 84x96, entry height determines scale
lock_height = entry.image.GetHeight() * 0.8;
lock_scale = lock_height / 96;
lock_width = 84 * lock_scale;
scaled_lock = lock.image.Scale(lock_width, lock_height);
lock.sprite = Sprite(scaled_lock);
lock.x = entry.x - lock_width - 15;
lock.y = entry.y + entry.image.GetHeight()/2 - lock_height/2;
lock.sprite.SetPosition(lock.x, lock.y, 10001);
lock.sprite.SetOpacity(0);
# Bullet array
bullet.sprites = [];
fun display_normal_callback ()
{
hide_password_dialog();
# Get current mode
mode = Plymouth.GetMode();
# Only show progress bar for boot and resume modes
if ((mode == "boot" || mode == "resume") && global.password_shown == 1)
{
show_progress_bar();
start_fake_progress();
}
}
fun display_password_callback (prompt, bullets)
{
global.password_shown = 1; # Mark that password dialog has been shown
# Reset progress when password dialog appears
stop_fake_progress();
hide_progress_bar();
global.max_progress = 0.0;
global.fake_progress = 0.0;
global.real_progress = 0.0;
show_password_dialog();
# Clear all bullets first
for (index = 0; bullet.sprites[index]; index++)
bullet.sprites[index].SetOpacity(0);
# Create and show bullets for current password (max 21)
max_bullets = 21;
bullets_to_show = bullets;
if (bullets_to_show > max_bullets)
bullets_to_show = max_bullets;
for (index = 0; index < bullets_to_show; index++)
{
if (!bullet.sprites[index])
{
# Scale bullet image to 7x7 pixels
scaled_bullet = bullet.image.Scale(7, 7);
bullet.sprites[index] = Sprite(scaled_bullet);
bullet.x = entry.x + 20 + index * (7 + 5);
bullet.y = entry.y + entry.image.GetHeight() / 2 - 3.5;
bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002);
}
bullet.sprites[index].SetOpacity(1);
}
}
Plymouth.SetDisplayNormalFunction(display_normal_callback);
Plymouth.SetDisplayPasswordFunction(display_password_callback);
#----------------------------------------- Progress Bar --------------------------------
progress_box.image = Image("progress_box.png");
progress_box.sprite = Sprite(progress_box.image);
progress_box.x = Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
progress_box.y = entry.y + entry.image.GetHeight() / 2 - progress_box.image.GetHeight() / 2;
progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);
progress_box.sprite.SetOpacity(0);
progress_bar.original_image = Image("progress_bar.png");
progress_bar.sprite = Sprite();
progress_bar.image = progress_bar.original_image.Scale(1, progress_bar.original_image.GetHeight());
progress_bar.x = Window.GetWidth() / 2 - progress_bar.original_image.GetWidth() / 2;
progress_bar.y = progress_box.y + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);
progress_bar.sprite.SetOpacity(0);
fun progress_callback (duration, progress)
{
global.real_progress = progress;
# If real progress is above limit, stop fake progress and use real progress
if (progress > global.fake_progress_limit)
{
stop_fake_progress();
update_progress_bar(progress);
}
}
Plymouth.SetBootProgressFunction(progress_callback);
#----------------------------------------- Quit --------------------------------
fun quit_callback ()
{
logo.sprite.SetOpacity (1);
}
Plymouth.SetQuitFunction(quit_callback);
#----------------------------------------- Message --------------------------------
message_sprite = Sprite();
message_sprite.SetPosition(10, 10, 10000);
fun display_message_callback (text)
{
my_image = Image.Text(text, 1, 1, 1);
message_sprite.SetImage(my_image);
}
fun hide_message_callback (text)
{
message_sprite.SetOpacity(0);
}
Plymouth.SetDisplayMessageFunction (display_message_callback);
Plymouth.SetHideMessageFunction (hide_message_callback);
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

+4
View File
@@ -0,0 +1,4 @@
{pkgs, ...}: {
environment.systemPackages = with pkgs; [via];
services.udev.packages = with pkgs; [via];
}
+77
View File
@@ -0,0 +1,77 @@
{pkgs, myConfig, ...}: let
# Screenshot script with swappy integration
screenshot = pkgs.writeShellScriptBin "screenshot" ''
#!/usr/bin/env bash
case "$1" in
region)
# Select region and edit
grim -g "$(slurp)" - | swappy -f -
;;
window)
# Screenshot active window
grim -g "$(hyprctl -j activewindow | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')" - | swappy -f -
;;
screen)
# Screenshot current monitor
grim -o "$(hyprctl -j monitors | jq -r '.[] | select(.focused) | .name')" - | swappy -f -
;;
all)
# Screenshot all monitors
grim - | swappy -f -
;;
region-save)
# Quick region screenshot (save without editing and copy to clipboard)
filepath=~/Pictures/Screenshots/$(date +'%Y-%m-%d_%H-%M-%S.png')
grim -g "$(slurp)" "$filepath"
wl-copy < "$filepath"
notify-send "Screenshot saved" "Saved and copied to clipboard"
;;
ocr)
# OCR Selection
grim -g "$(slurp)" - | tesseract stdin stdout | wl-copy
notify-send "OCR" "Text extracted to clipboard"
;;
*)
echo "Usage: screenshot {region|window|screen|all|region-save|ocr}"
exit 1
;;
esac
'';
in {
home.packages = with pkgs; [
grim # Screenshot utility
slurp # Region selector
swappy # Annotation tool
jq # For window selection
wl-clipboard # For copying to clipboard
tesseract # OCR tool
screenshot # Our wrapper script
];
# Create Screenshots directory
home.file."Pictures/Screenshots/.keep".text = "";
# Swappy configuration
home.file.".config/swappy/config".text = ''
[Default]
save_dir=$HOME/Pictures/Screenshots
save_filename_format=screenshot_%Y%m%d_%H%M%S.png
show_panel=true
line_size=5
text_size=20
text_font=${myConfig.font.sans}
paint_mode=brush
early_exit=false
fill_shape=false
'';
wayland.windowManager.hyprland.settings.bindd = [
# Screenshots
"SUPER, S, Screenshot Region (with edit), exec, screenshot region"
"SUPER SHIFT, S, Screenshot Active Window, exec, screenshot window"
"SUPER ALT, S, Quick Screenshot (no edit), exec, screenshot region-save"
"SUPER ALT SHIFT, S, Screenshot Current Monitor, exec, screenshot screen"
"SUPER ALT, E, OCR Selection, exec, screenshot ocr"
];
}
+33
View File
@@ -0,0 +1,33 @@
{
pkgs,
lib,
...
}: {
services.swayosd.enable = true;
# Auto-restart swayosd on crash
systemd.user.services.swayosd = {
Unit = {
StartLimitBurst = lib.mkForce 5;
StartLimitIntervalSec = lib.mkForce 30;
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
Restart = lib.mkForce "on-failure";
RestartSec = lib.mkForce "1s";
};
Install.WantedBy = [ "graphical-session.target" ];
};
wayland.windowManager.hyprland.settings = {
bindel = [
", XF86AudioRaiseVolume, exec, swayosd-client --output-volume raise"
", XF86AudioLowerVolume, exec, swayosd-client --output-volume lower"
];
bindl = [
", XF86AudioMute, exec, swayosd-client --output-volume mute-toggle"
", Caps_Lock, exec, sleep 0.1 && swayosd-client --caps-lock"
];
};
}
+5
View File
@@ -0,0 +1,5 @@
{ pkgs, ... }: {
home.packages = with pkgs; [
ttyper
];
}
+86
View File
@@ -0,0 +1,86 @@
{
pkgs,
inputs,
...
}: let
vicinae-toggle = pkgs.writeShellScriptBin "vicinae-toggle" ''
VICINAE_BIN="${inputs.vicinae.packages.${pkgs.system}.default}/bin/vicinae"
ARGS=("$@")
if [ ''${#ARGS[@]} -eq 0 ]; then
ARGS=("toggle")
fi
if ! "$VICINAE_BIN" "''${ARGS[@]}" 2>/dev/null; then
${pkgs.systemd}/bin/systemctl --user restart vicinae || "$VICINAE_BIN" server &
sleep 0.4
exec "$VICINAE_BIN" "''${ARGS[@]}"
fi
'';
in {
services.vicinae = {
enable = true;
systemd = {
enable = true;
autoStart = true;
environment = {
USE_LAYER_SHELL = 1;
};
};
settings = {
# Escape closes window (vim-like :q behavior)
escape_key_behavior = "close_window";
pop_to_root_on_close = true;
close_on_unfocus = true;
keybinds = {
# UI shortcuts
"open-search-filter" = "control+/"; # vim search
"open-settings" = "control+,";
"toggle-action-panel" = "control+B";
# Vim-like action keybinds
"action.move-up" = "control+shift+K";
"action.move-down" = "control+shift+J";
"action.copy" = "control+Y"; # yank
"action.copy-name" = "control+shift+Y";
"action.remove" = "control+D"; # delete
"action.dangerous-remove" = "control+shift+D";
"action.edit" = "control+E";
"action.open" = "control+O";
"action.refresh" = "control+R";
"action.pin" = "control+P";
"action.new" = "control+N";
"action.save" = "control+S";
};
theme = {
light = {
name = "matugen";
icon_theme = "Papirus-Dark";
};
dark = {
name = "matugen";
icon_theme = "Papirus-Dark";
};
};
};
};
# Ensure vicinae themes directory exists for matugen output
home.file.".local/share/vicinae/themes/.keep".text = "";
home.packages = [vicinae-toggle];
wayland.windowManager.hyprland.settings = {
exec-once = [
"vicinae server"
];
bindd = [
"SUPER, SPACE, Open Vicinae, exec, vicinae-toggle"
"SUPER, period, Open Emoji Picker, exec, vicinae-toggle deeplink vicinae://launch/core/search-emojis"
"SUPER, C, Open Calculator, exec, vicinae-toggle deeplink vicinae://launch/calculator/history"
"SUPER, V, Open Clipboard History, exec, vicinae-toggle deeplink vicinae://launch/clipboard/history"
];
};
}
+6
View File
@@ -4,6 +4,12 @@
pkgs,
...
}: {
wayland.windowManager.hyprland.settings = {
exec-once = [
"uwsm app -- elephant"
"walker --gapplication-service"
];
};
imports = [
# ./style.nix
./layout.nix
+110 -149
View File
@@ -4,143 +4,82 @@
myConfig,
...
}: let
# --- POPUP SCRIPTS ---
hakase-launch-or-focus = pkgs.writeShellScriptBin "hakase-launch-or-focus" ''
if (($# == 0)); then
echo "Usage: hakase-launch-or-focus [window-pattern] [launch-command]"
exit 1
fi
# FIXME: waybar overlaps fullscreen display when restarting waybar
hakase-popup-launch = pkgs.writeShellScriptBin "hakase-popup-launch" ''
tui_name=$1
active_popup=$(${pkgs.hyprland}/bin/hyprctl clients -j | ${pkgs.jq}/bin/jq -r '.[] | select(.class | startswith("org.hakase.")) | .class')
WINDOW_PATTERN="$1"
# Escaped Nix interpolation for shell default value logic
LAUNCH_COMMAND="''${2:- \"uwsm-app -- $WINDOW_PATTERN\"}"
if [[ -z "''${tui_name}" ]]; then
echo "Usage: $(basename "$0") [tui-name]"
exit 1
fi
# Locate window address via hyprctl and jq
WINDOW_ADDRESS=$(${pkgs.hyprland}/bin/hyprctl clients -j | ${pkgs.jq}/bin/jq -r --arg p "$WINDOW_PATTERN"
'.[] | select((.class | test("\\b" + $p + "\\b"; "i")) or (.title | test("\\b" + $p + "\\b"; "i"))) | .address' | head -n1)
if [[ -n $WINDOW_ADDRESS ]]; then
# If found, focus the existing window
${pkgs.hyprland}/bin/hyprctl dispatch focuswindow "address:$WINDOW_ADDRESS"
else
# If not found, execute the launch command
eval exec setsid $LAUNCH_COMMAND
fi
'';
hakase-launch-tui = pkgs.writeShellScriptBin "hakase-launch-tui" ''
APP_NAME=$(basename "$1")
# Using org.hakase prefix so the focus script can find it via class name
exec setsid uwsm-app -- xdg-terminal-exec --app-id=org.hakase."$APP_NAME" -e "$@"
'';
hakase-focus-wrapper = pkgs.writeShellScriptBin "hakase-focus-wrapper" ''
APP_NAME=$(basename "$1")
WINDOW_PATTERN="org.hakase.$APP_NAME"
LAUNCH_CMD="hakase-launch-tui $*"
exec hakase-launch-or-focus "$WINDOW_PATTERN" "$LAUNCH_CMD"
'';
hakase-launch-wifi = pkgs.writeShellScriptBin "hakase-launch-wifi" ''
# Use the focus wrapper to launch or switch to Impala
exec hakase-focus-wrapper impala
'';
hakase-launch-bluetooth = pkgs.writeShellScriptBin "hakase-launch-bluetooth" ''
exec hakase-focus-wrapper bluetui
'';
hakase-launch-popup = pkgs.writeShellScriptBin "hakase-launch-popup" ''
if (($# < 3)); then
echo "Usage: hakase-launch-popup [width] [height] [command...]"
exit 1
fi
# --- ARGS & CONFIG ---
WIN_WIDTH="$1"
WIN_HEIGHT="$2"
shift 2
MARGIN=10
BAR_HEIGHT=40
# ---------------------
CMD_NAME=$(basename "$1")
TARGET_CLASS="org.hakase.popup.$CMD_NAME"
# 1. SINGLETON LOGIC: Check for ANY existing hakase popup
EXISTING_JSON=$(${pkgs.hyprland}/bin/hyprctl clients -j | ${pkgs.jq}/bin/jq -r '.[] | select(.class | startswith("org.hakase.popup."))')
if [[ -n "$EXISTING_JSON" ]]; then
OLD_ADDR=$(echo "$EXISTING_JSON" | ${pkgs.jq}/bin/jq -r '.address')
OLD_CLASS=$(echo "$EXISTING_JSON" | ${pkgs.jq}/bin/jq -r '.class')
# Close the existing popup
${pkgs.hyprland}/bin/hyprctl dispatch closewindow "address:$OLD_ADDR"
if [[ "$OLD_CLASS" == "$TARGET_CLASS" ]]; then
exit 0
fi
sleep 0.15
fi
# 2. Calculate Geometry
MONITOR_INFO=$(${pkgs.hyprland}/bin/hyprctl monitors -j | ${pkgs.jq}/bin/jq '.[] | select(.focused == true)')
MON_X=$(echo "$MONITOR_INFO" | ${pkgs.jq}/bin/jq '.x')
MON_Y=$(echo "$MONITOR_INFO" | ${pkgs.jq}/bin/jq '.y')
MON_WIDTH=$(echo "$MONITOR_INFO" | ${pkgs.jq}/bin/jq '.width')
TARGET_X=$((MON_X + MON_WIDTH - WIN_WIDTH - MARGIN))
TARGET_Y=$((MON_Y + BAR_HEIGHT + MARGIN))
# 3. Launch with Rules
RULE="[float;pin;size $WIN_WIDTH $WIN_HEIGHT;move $TARGET_X $TARGET_Y]"
${pkgs.hyprland}/bin/hyprctl dispatch exec "$RULE xdg-terminal-exec --app-id=$TARGET_CLASS -e $@"
# 4. Background Listener (Close on Blur)
(
TIMEOUT=0
WINDOW_ADDR=""
while [[ -z "$WINDOW_ADDR" && $TIMEOUT -lt 20 ]]; do
sleep 0.1
WINDOW_ADDR=$(${pkgs.hyprland}/bin/hyprctl clients -j | ${pkgs.jq}/bin/jq -r --arg c "$TARGET_CLASS" '.[] | select(.class == $c) | .address')
((TIMEOUT++))
done
if [[ -n "$WINDOW_ADDR" ]]; then
${pkgs.socat}/bin/socat -U - UNIX-CONNECT:"$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" | while read -r line; do
if [[ "$line" == "activewindow>>"* ]]; then
NEW_FOCUS="0x$(echo "$line" | cut -d '>' -f3 | cut -d ',' -f1)"
if [[ "$WINDOW_ADDR" != "$NEW_FOCUS" ]]; then
${pkgs.hyprland}/bin/hyprctl dispatch closewindow "address:$WINDOW_ADDR"
break
fi
popup_checker() {
if [[ -z "$active_popup" ]]; then
echo "no_popup"
elif [[ "$active_popup" != "org.hakase.popup.''${tui_name}" ]]; then
echo "different"
else
echo "same"
fi
done
fi
) &
}
launch() {
exec ${pkgs.util-linux}/bin/setsid uwsm-app -- xdg-terminal-exec --app-id=org.hakase.popup."''${tui_name}" -e "''${tui_name}"
}
exit 0
'';
focus() {
exec ${pkgs.hyprland}/bin/hyprctl dispatch focuswindow "class:org.hakase.popup.''${tui_name}"
}
hakase-popup-wifi = pkgs.writeShellScriptBin "hakase-popup-wifi" ''
exec hakase-launch-popup 800 500 impala
'';
replace() {
${pkgs.hyprland}/bin/hyprctl dispatch closewindow "class:''${active_popup}"
sleep 0.3
launch
}
hakase-popup-bluetooth = pkgs.writeShellScriptBin "hakase-popup-bluetooth" ''
exec hakase-launch-popup 600 500 bluetui
'';
run() {
local status
status=$(popup_checker)
hakase-popup-volume = pkgs.writeShellScriptBin "hakase-popup-volume" ''
exec hakase-launch-popup 800 300 wiremix
if [[ "$status" == "no_popup" ]]; then
launch
elif [[ "$status" == "same" ]]; then
focus
elif [[ "$status" == "different" ]]; then
replace
fi
}
run
'';
in {
wayland.windowManager.hyprland.settings = {
exec-once = [
"uwsm app -- waybar"
];
bind = [
"SUPER, Escape, exec, hakase-popup-launch btop"
"SUPER, N, exec, hakase-popup-launch impala"
"SUPER, B, exec, hakase-popup-launch bluetui"
"SUPER, T, exec, hakase-popup-launch wiremix"
];
windowrule = [
# --- POPUP RULES (Wifi, BT, Audio) ---
"match:class ^(org\.hakase\.popup\..*)$, float on"
"match:class ^(org\.hakase\.popup\..*)$, size 900 600"
"match:class ^(org\.hakase\.popup\..*)$, center on"
"match:class ^(org\.hakase\.popup\..*)$, animation slide right"
"match:class ^(org\.hakase\.popup\..*)$, dim_around on"
];
};
imports = [
./style.nix
];
home.packages = [
hakase-popup-launch
pkgs.jq
pkgs.socat
pkgs.util-linux
@@ -148,17 +87,6 @@ in {
pkgs.impala
pkgs.wiremix
pkgs.pamixer
hakase-launch-popup
hakase-popup-wifi
hakase-popup-bluetooth
hakase-popup-volume
hakase-launch-or-focus
hakase-launch-tui
hakase-focus-wrapper
hakase-launch-wifi
hakase-launch-bluetooth
];
programs.waybar = {
@@ -188,18 +116,38 @@ in {
all-outputs = true;
format = "{icon}";
format-icons = {
"music" = "󰎆";
"gaming" = "󰊖";
"default" = "";
"active" = "󱓻";
# Numbered workspaces 1-5
"1" = "1";
"2" = "2";
"3" = "3";
"4" = "4";
"5" = "5";
"6" = "6";
"7" = "7";
"8" = "8";
"9" = "9";
"10" = "0";
"active" = "󱓻";
# Kanji for workspaces 6-10
"6" = "1";
"7" = "2";
"8" = "3";
"9" = "4";
"10" = "5";
# Dice for workspaces 11-15
"11" = "1";
"12" = "2";
"13" = "3";
"14" = "4";
"15" = "5";
# Circled numbers for 16-20
"16" = "1";
"17" = "2";
"18" = "3";
"19" = "4";
"20" = "5";
};
persistent-workspaces = {
"1" = [];
@@ -207,6 +155,11 @@ in {
"3" = [];
"4" = [];
"5" = [];
"6" = [];
"7" = [];
"8" = [];
"9" = [];
"10" = [];
};
};
@@ -215,26 +168,34 @@ in {
show-special = true;
special-visible-only = true;
all-outputs = true;
ignore-workspaces = ["1" "2" "3" "4" "5" "6" "7" "8" "9" "10"];
ignore-workspaces = ["^([0-9]+|gaming|music|jellyfin)$"];
format = "{icon}";
format-icons = {
"special:youtube" = "󰗃";
"special:music" = "󰎆";
"special:steam" = "󰓓";
"special:custom" = "󱗼";
"special:preload" = "󱗼";
"special:jellyfin" = "󰟞";
"jellyfin" = "󰟞";
"youtube" = "󰗃";
"steam" = "󰓓";
"custom" = "󱗼";
"preload" = "󱗼";
"default" = "󱗼";
};
};
"custom/omarchy" = {
format = "";
on-click = "omarchy-menu";
on-click-right = "xdg-terminal-exec";
on-click = "vicinae-toggle";
on-click-right = "hyprctl dispatch overview:toggle";
tooltip-format = "Omarchy Menu\n\nSuper + Alt + Space";
};
"cpu" = {
interval = 5;
format = "󰍛";
on-click = "hakase-focus-wrapper btop";
on-click = "hakase-popup-launch btop";
on-click-right = "xdg-terminal-exec";
};
@@ -256,7 +217,7 @@ in {
tooltip-format-disconnected = "Disconnected";
interval = 3;
spacing = 1;
on-click = "hakase-popup-wifi";
on-click = "hakase-popup-launch impala";
};
"battery" = {
@@ -285,12 +246,12 @@ in {
format-connected = "󰂱";
format-no-controller = "";
tooltip-format = "Devices connected: {num_connections}";
on-click = "hakase-popup-bluetooth";
on-click = "hakase-popup-launch bluetui";
};
"pulseaudio" = {
format = "{icon}";
on-click = "hakase-popup-volume";
on-click = "hakase-popup-launch wiremix ";
on-click-right = "pamixer -t";
tooltip-format = "Playing at {volume}%";
scroll-step = 5;
@@ -328,4 +289,4 @@ in {
};
};
};
}
}
+18 -2
View File
@@ -1,4 +1,8 @@
{config, ...}: {
{
config,
myConfig,
...
}: {
programs.waybar = {
style = ''
@import "matugen.css";
@@ -9,7 +13,7 @@
border: none;
border-radius: 0;
min-height: 0;
font-family: 'JetBrainsMono Nerd Font';
font-family: '${myConfig.font.monospace}';
font-size: 12px;
}
@@ -32,6 +36,18 @@
opacity: 0.5;
}
/* Add spacing separator every 5 workspaces */
#workspaces button:nth-child(5),
#workspaces button:nth-child(10),
#workspaces button:nth-child(15) {
margin-right: 10px;
}
/* Separator between normal and special workspaces */
#workspaces.special {
margin-left: 12px;
}
#cpu,
#battery,
#pulseaudio,
+5
View File
@@ -0,0 +1,5 @@
{
programs.wireshark.enable = true;
# dumpcap.enable = true;
usbmon.enable = true;
}
+152 -4
View File
@@ -1,14 +1,162 @@
{pkgs, ...}: {
{
pkgs,
myConfig,
...
}: let
# Yazi wrapper for xdg-desktop-portal-termfilechooser
# TODO: rewrite in the future
yaziWrapper = pkgs.writeShellScript "yazi-wrapper.sh" ''
if [[ "$6" == "1" ]]; then
set -x
fi
multiple="$1"
directory="$2"
save="$3"
path="$4"
out="$5"
termcmd="${pkgs.util-linux}/bin/setsid uwsm-app -- xdg-terminal-exec --app-id=org.hakase.popup.yazi -e"
cleanup() {
if [ -f "$tmpfile" ]; then
rm "$tmpfile" || :
fi
if [ "$save" = "1" ] && [ ! -s "$out" ]; then
rm "$path" || :
fi
}
trap cleanup EXIT HUP INT QUIT ABRT TERM
if [ "$save" = "1" ]; then
tmpfile=$(mktemp)
printf '%s' 'xdg-desktop-portal-termfilechooser saving files tutorial
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! === WARNING! === !!!
!!! The contents of *whatever* file you open last in !!!
!!! yazi will be *overwritten*! !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Instructions:
1) Move this file wherever you want.
2) Rename the file if needed.
3) Confirm your selection by opening the file, for
example by pressing <Enter>.
Notes:
1) This file is provided for your convenience. You can
only choose this placeholder file otherwise the save operation aborted.
2) If you quit yazi without opening a file, this file
will be removed and the save operation aborted.
' >"$path"
$termcmd ${pkgs.yazi}/bin/yazi --chooser-file="$tmpfile" "$path"
elif [ "$directory" = "1" ]; then
$termcmd ${pkgs.yazi}/bin/yazi --cwd-file="$out" "$path"
elif [ "$multiple" = "1" ]; then
$termcmd ${pkgs.yazi}/bin/yazi --chooser-file="$out" "$path"
else
$termcmd ${pkgs.yazi}/bin/yazi --chooser-file="$out" "$path"
fi
# Handle save file case
if [ "$save" = "1" ] && [ -s "$tmpfile" ]; then
selected_file=$(head -n 1 "$tmpfile")
if [ -f "$selected_file" ] && grep -qi "^xdg-desktop-portal-termfilechooser saving files tutorial" "$selected_file"; then
echo "$selected_file" >"$out"
fi
fi
'';
in {
wayland.windowManager.hyprland.settings = {
bindd = [
"SUPER, X, Open File Manager, exec, uwsm app -- yazi"
];
};
programs.yazi = {
enable = true;
enableFishIntegration = true;
settings = {
manager = {
show_hidden = true;
sort_by = "natural";
sort_dir_first = true;
show_hidden = false;
sort_by = "mtime";
sort_reverse = true;
sort_dir_first = false;
linemode = "size";
mouse_events = ["click" "scroll" "touch" "move" "drag"];
};
tasks = {
image_bound = [10000 10000];
};
opener = {
anki = [
{
run = "anki \"$@\"";
desc = "Open with Anki";
}
];
pdf = [
{
run = "zathura \"$@\"";
desc = "Open with Zathura";
}
{
run = "firefox \"$@\"";
desc = "Open with Firefox";
}
];
};
open = {
prepend_rules = [
{
name = "*.{apkg,colpkg}";
use = "anki";
}
{
mime = "application/pdf";
use = "pdf";
}
];
};
};
};
# Portal packages need to be in user profile for proper path resolution
home.packages = [
pkgs.xdg-desktop-portal-hyprland
pkgs.xdg-desktop-portal-gtk
pkgs.xdg-desktop-portal-termfilechooser
];
# xdg-desktop-portal-termfilechooser configuration
xdg.configFile."xdg-desktop-portal-termfilechooser/config".text = ''
[filechooser]
cmd=${yaziWrapper}
default_dir=$HOME/Downloads
'';
# Portal routing configuration - use termfilechooser for file dialogs
xdg.configFile."xdg-desktop-portal/portals.conf".text = ''
[preferred]
default=hyprland;gtk
org.freedesktop.impl.portal.FileChooser=termfilechooser
'';
xdg.mimeApps = {
enable = true;
defaultApplications = {
"inode/directory" = "yazi.desktop";
};
};
wayland.windowManager.hyprland.settings.windowrule = [
# File picker yazi - floating, centered, smaller size
"match:class ^(org\\.hakase\\.popup\\.yazi)$, float on"
"match:class ^(org\\.hakase\\.popup\\.yazi)$, size 60% 70%"
"match:class ^(org\\.hakase\\.popup\\.yazi)$, center on"
];
}
+38
View File
@@ -0,0 +1,38 @@
{
pkgs,
config,
lib,
...
}: {
home.packages = with pkgs; [
ocrmypdf
];
programs.zathura = {
enable = true;
options = {
selection-clipboard = "clipboard";
adjust-open = "best-fit";
pages-per-row = 1;
scroll-page-aware = "true";
scroll-full-overlap = "0.01";
scroll-step = 100;
zoom-min = 10;
recolor = true;
recolor-keephue = true;
};
extraConfig = "include ${config.home.homeDirectory}/.config/zathura/zathura-matugen";
};
home.activation.createZathuraMatugen = lib.hm.dag.entryAfter ["writeBoundary"] ''
if [ ! -f "${config.home.homeDirectory}/.config/zathura/zathura-matugen" ]; then
touch "${config.home.homeDirectory}/.config/zathura/zathura-matugen"
fi
'';
xdg.mimeApps = {
enable = true;
defaultApplications = {
"application/pdf" = "org.pwmt.zathura.desktop";
};
};
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

@@ -1 +0,0 @@
/nix/store/yckzy9k5i7pvmlk6xjkdj4wwbfms1zpl-home-manager-files/Pictures/Wallpapers/1-Pawel-Czerwinski-Abstract-Purple-Blue.jpg
-1
View File
@@ -1 +0,0 @@
/nix/store/yckzy9k5i7pvmlk6xjkdj4wwbfms1zpl-home-manager-files/Pictures/Wallpapers/1-everforest.jpg
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 KiB

-1
View File
@@ -1 +0,0 @@
/nix/store/yckzy9k5i7pvmlk6xjkdj4wwbfms1zpl-home-manager-files/Pictures/Wallpapers/gruvbox-1.jpg
-1
View File
@@ -1 +0,0 @@
/nix/store/yckzy9k5i7pvmlk6xjkdj4wwbfms1zpl-home-manager-files/Pictures/Wallpapers/kanagawa-1.png
Binary file not shown.

Before

Width:  |  Height:  |  Size: 607 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

-1
View File
@@ -1 +0,0 @@
/nix/store/yckzy9k5i7pvmlk6xjkdj4wwbfms1zpl-home-manager-files/Pictures/Wallpapers/nord-1.png
+6 -10
View File
@@ -1,10 +1,6 @@
▄▄▄
▄█████▄ ███████████▄ ▄███████ ▄███████ ▄███████ ▄█ █▄ ▄█ █▄
███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███
███ ███ ███ ███ ███ ███ ███ ███ ███ ███ █▀ ███ ███ ███ ███
██ ███ ███ ██ ███ ▄███▄▄▄███ ▄███▄▄▄██▀ ███ ▄███▄▄▄███▄ ███▄▄▄███
███ ███ ███ ███ ███ ▀███▀▀▀███ ▀███▀▀▀▀ ███ ▀▀███▀▀▀███ ▀▀▀▀▀▀███
███ ███ ███ ███ ███ ███ ███ ██████████ ███ █▄ ███ ███ ▄██ ███
███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███
▀█████▀ ▀█ ███ █▀ ███ █▀ ███ ███ ███████▀ ███ █▀ ▀█████▀
███ █▀
██╗ ██╗ █████╗ ██╗ ██╗ █████╗ ███████╗███████╗
██║ ████╔══████║ ██╔╝██╔══██╗██╔════╝██╔════╝
███████║███████║█████╔╝ ███████║███████╗█████╗
██╔══██║██╔══██║██╔═██╗ ██╔══██║╚════██║██╔══╝
██ ████ ██║██║ ██╗██║ ██║███████║███████
╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝
Binary file not shown.

After

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

+120 -45
View File
@@ -1,52 +1,127 @@
{
myConfig = {
nixos = {
username = "kenji";
hostname = "hakase";
timezone = "America/Chicago";
};
git = {
username = "kenji";
email = "kenji@hakase";
defaultBranch = "master";
};
terminal = {
default = "ghostty";
aliases = {
update = "sudo nixos-rebuild switch --flake ~/.config/nixos/#hakase";
hakase = {
myConfig = {
font = {
monospace = "MonoLisa";
monospaceScript = "MonoLisa Italic @ss02=1";
sans = "Sans";
};
nixos = {
username = "kenji";
hostname = "hakase";
timezone = "America/Chicago";
};
git = {
username = "kenji";
email = "kenji@hakase";
defaultBranch = "master";
};
theme = {
mode = "dark";
};
terminal = {
default = "ghostty";
font = "MonoLisa";
aliases = {
update = "sudo nixos-rebuild switch --flake ~/.config/nixos/#hakase";
};
};
btop = {
autostart = true;
monitor = "HDMI-A-1";
};
hyprland = {
monitors = [
# "DP-1,highres@180,0x1080,1,vrr,1,bitdepth,10,cm,hdr,sdrbrightness,2.5"
"DP-1,highres@180,0x1080,1,vrr,0"
"DP-2, highres@165,760x0,1"
"HDMI-A-1, highres@highrr@120, 3440x1440, 1.6"
];
wallpaper = "firewatch.png";
kb_options = "";
};
wakeup = {
mouse = {
disable = true;
vendor = "3710";
product = "5406";
};
};
firefox = {
bookmarks = [
{
name = "Home Manager";
url = "https://mynixos.com/home-manager/options/programs";
}
{
name = "YouTube";
url = "https://youtube.com";
}
{
name = "Nur";
url = "https://nur.nix-community.org/repos";
}
];
newtabpage = [
{
title = "Dashboard";
url = "https://dash.sakamoto.dev";
}
];
};
};
hyprland = {
monitors = [
"DP-1,highres@180,0x1080,1,bitdepth,10,cm,hdr,sdrbrightness,1.4,sdrsaturation,0.98,vrr,0"
"DP-2, highres@165,760x0,1"
"HDMI-A-1, highres@highrr@120, 3440x1440, 1.6"
];
};
# wallpaper = "nixos_rainbow.png";
wallpaper = "ai_pixel_purple.jpg"; # FIXME: redundant
};
firefox = {
bookmarks = [
{
name = "Home Manager";
url = "https://mynixos.com/home-manager/options/programs";
}
{
name = "YouTube";
url = "https://youtube.com";
}
{
name = "Nur";
url = "https://nur.nix-community.org/repos";
}
];
newtabpage = [
{
title = "Dashboard";
url = "https://dash.sakamoto.dev";
}
];
macbook = {
myConfig = {
font = {
monospace = "MonoLisa";
monospaceScript = "MonoLisa Italic @ss02=1";
sans = "Sans";
};
nixos = {
username = "kenji";
hostname = "macbook";
timezone = "America/Chicago";
};
git = {
username = "kenji";
email = "kenji@macbook";
defaultBranch = "master";
};
theme = {
mode = "dark";
};
terminal = {
default = "ghostty";
font = "MonoLisa";
aliases = {
update = "sudo nixos-rebuild switch --flake ~/.config/nixos/#macbook";
};
};
btop = {
autostart = false;
monitor = "eDP-1";
};
hyprland = {
# M1 Pro/Max/Air screens are usually built-in eDP-1.
# HiDPI scale 2.0 is safe for Retina.
monitors = [
"eDP-1, highres, auto, 2"
];
wallpaper = "firewatch.png";
kb_options = "";
};
firefox = {
bookmarks = [
{
name = "Asahi Linux";
url = "https://asahilinux.org/";
}
];
newtabpage = [];
};
};
};
}
Generated
+387 -77
View File
@@ -1,5 +1,26 @@
{
"nodes": {
"apple-silicon": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1767637567,
"narHash": "sha256-njwPfL5gM/KRGLJ29CbQ4nLBoEkNPMvEHBAAPOP8BZc=",
"owner": "tpwrules",
"repo": "nixos-apple-silicon",
"rev": "530aa73aa9a21a078ff861b84767ae1d469715fa",
"type": "github"
},
"original": {
"owner": "tpwrules",
"repo": "nixos-apple-silicon",
"type": "github"
}
},
"aquamarine": {
"inputs": {
"hyprutils": [
@@ -20,11 +41,11 @@
]
},
"locked": {
"lastModified": 1765900596,
"narHash": "sha256-+hn8v9jkkLP9m+o0Nm5SiEq10W0iWDSotH2XfjU45fA=",
"lastModified": 1778857089,
"narHash": "sha256-TclWRW2SdFeETLaiTG4BA8C8C4m/LppQEldncqyTzAQ=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "d83c97f8f5c0aae553c1489c7d9eff3eadcadace",
"rev": "ab2b0af63fbc9fb779d684f19149b790978be8a8",
"type": "github"
},
"original": {
@@ -103,17 +124,32 @@
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1761588595,
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
"owner": "edolstra",
"lastModified": 1746162366,
"narHash": "sha256-5SSSZ/oQkwfcAz/o/6TlejlVGqeK08wyREBQ5qFFPhM=",
"owner": "nix-community",
"repo": "flake-compat",
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
"rev": "0f158086a2ecdbb138cd0429410e44994f1b7e4b",
"type": "github"
},
"original": {
"owner": "edolstra",
"owner": "nix-community",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "NixOS",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "flake-compat",
"type": "github"
}
@@ -145,11 +181,11 @@
]
},
"locked": {
"lastModified": 1765835352,
"narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=",
"lastModified": 1778716662,
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "a34fae9c08a15ad73f295041fec82323541400a9",
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
"type": "github"
},
"original": {
@@ -193,6 +229,24 @@
"url": "https://flakehub.com/f/DeterminateSystems/flake-schemas/%3D0.1.5.tar.gz"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_6"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
@@ -256,6 +310,27 @@
"type": "github"
}
},
"hypr-dynamic-cursors": {
"inputs": {
"hyprland": [
"hyprland"
],
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1779050734,
"narHash": "sha256-uE/I8TrhVEyQJb8t+HeHNYQRv7VlwbZxXlTrMfP0x/A=",
"owner": "Virtcode",
"repo": "hypr-dynamic-cursors",
"rev": "39fe4ab66b45b011667f548d759d58e707521378",
"type": "github"
},
"original": {
"owner": "Virtcode",
"repo": "hypr-dynamic-cursors",
"type": "github"
}
},
"hyprcursor": {
"inputs": {
"hyprlang": [
@@ -272,11 +347,11 @@
]
},
"locked": {
"lastModified": 1753964049,
"narHash": "sha256-lIqabfBY7z/OANxHoPeIrDJrFyYy9jAM4GQLzZ2feCM=",
"lastModified": 1776511930,
"narHash": "sha256-fCpwFiTW0rT7oKJqr3cqHMnkwypSwQKpbtUEtxdkgrM=",
"owner": "hyprwm",
"repo": "hyprcursor",
"rev": "44e91d467bdad8dcf8bbd2ac7cf49972540980a5",
"rev": "39435900785d0c560c6ae8777d29f28617d031ef",
"type": "github"
},
"original": {
@@ -301,11 +376,11 @@
]
},
"locked": {
"lastModified": 1763733840,
"narHash": "sha256-JnET78yl5RvpGuDQy3rCycOCkiKoLr5DN1fPhRNNMco=",
"lastModified": 1776426399,
"narHash": "sha256-RUESLKNikIeEq9ymGJ6nmcDXiSFQpUW1IhJ245nL3xM=",
"owner": "hyprwm",
"repo": "hyprgraphics",
"rev": "8f1bec691b2d198c60cccabca7a94add2df4ed1a",
"rev": "68d064434787cf1ed4a2fe257c03c5f52f33cf84",
"type": "github"
},
"original": {
@@ -333,11 +408,11 @@
"xdph": "xdph"
},
"locked": {
"lastModified": 1766498696,
"narHash": "sha256-74qO6ynwUav+QqNhBVn/4yoBCpU6r3/eCkX/V11uL+E=",
"lastModified": 1779983308,
"narHash": "sha256-mvjt5EqRubXF5w1RnyLsWOduJQzHDZCjohWJz/TUvJM=",
"ref": "refs/heads/main",
"rev": "f7f357f15f83612078eb0919ca08b71cac01c25e",
"revCount": 6741,
"rev": "ebc1816dfb27f1091c9713876669e092a215382d",
"revCount": 7376,
"submodules": true,
"type": "git",
"url": "https://github.com/hyprwm/Hyprland"
@@ -381,11 +456,11 @@
]
},
"locked": {
"lastModified": 1765643131,
"narHash": "sha256-CCGohW5EBIRy4B7vTyBMqPgsNcaNenVad/wszfddET0=",
"lastModified": 1776426575,
"narHash": "sha256-KI6nIfVihn/DPaeB5Et46Xg3dkNHrrEtUd5LBBVomB0=",
"owner": "hyprwm",
"repo": "hyprland-guiutils",
"rev": "e50ae912813bdfa8372d62daf454f48d6df02297",
"rev": "a968d211048e3ed538e47b84cb3649299578f19d",
"type": "github"
},
"original": {
@@ -394,6 +469,36 @@
"type": "github"
}
},
"hyprland-plugins": {
"inputs": {
"hyprland": [
"hyprland"
],
"nixpkgs": [
"hyprland-plugins",
"hyprland",
"nixpkgs"
],
"systems": [
"hyprland-plugins",
"hyprland",
"systems"
]
},
"locked": {
"lastModified": 1779209205,
"narHash": "sha256-asc7NpeB8vD66gvZeYcQkaWOs2X6Jgd29vBtP17vjxo=",
"owner": "hyprwm",
"repo": "hyprland-plugins",
"rev": "1cb37fad68dff5f5840010c314fed5809b4ee66f",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprland-plugins",
"type": "github"
}
},
"hyprland-protocols": {
"inputs": {
"nixpkgs": [
@@ -406,11 +511,11 @@
]
},
"locked": {
"lastModified": 1765214753,
"narHash": "sha256-P9zdGXOzToJJgu5sVjv7oeOGPIIwrd9hAUAP3PsmBBs=",
"lastModified": 1772460177,
"narHash": "sha256-/6G/MsPvtn7bc4Y32pserBT/Z4SUUdBd4XYJpOEKVR4=",
"owner": "hyprwm",
"repo": "hyprland-protocols",
"rev": "3f3860b869014c00e8b9e0528c7b4ddc335c21ab",
"rev": "1cb6db5fd6bb8aee419f4457402fa18293ace917",
"type": "github"
},
"original": {
@@ -435,11 +540,11 @@
]
},
"locked": {
"lastModified": 1764612430,
"narHash": "sha256-54ltTSbI6W+qYGMchAgCR6QnC1kOdKXN6X6pJhOWxFg=",
"lastModified": 1777320127,
"narHash": "sha256-Qu+Wf2Bp5qUjyn2YpZNq8a7JyzTGowhT1knrwE38a9U=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "0d00dc118981531aa731150b6ea551ef037acddd",
"rev": "090117506ddc3d7f26e650ff344d378c2ec329cc",
"type": "github"
},
"original": {
@@ -448,6 +553,48 @@
"type": "github"
}
},
"hyprspace": {
"inputs": {
"hyprland": [
"hyprland"
],
"systems": "systems_3"
},
"locked": {
"lastModified": 1775071961,
"narHash": "sha256-LXkeeH9Blr6ohS1LAsVZbkJ/EAkkMDATh5qu45hC7Zo=",
"owner": "KZDKM",
"repo": "Hyprspace",
"rev": "12ddde04f8584bf7de3151e6169918e0dda9f822",
"type": "github"
},
"original": {
"owner": "KZDKM",
"repo": "Hyprspace",
"type": "github"
}
},
"hyprsplit": {
"inputs": {
"hyprland": [
"hyprland"
],
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1779414137,
"narHash": "sha256-XpwuFhwnfwPbzImZeUWWns///UEpoKNkpl1hN90C3Ag=",
"owner": "shezdy",
"repo": "hyprsplit",
"rev": "0fc01e7930625ecb3e069f5dc8e1d61eab929f3b",
"type": "github"
},
"original": {
"owner": "shezdy",
"repo": "hyprsplit",
"type": "github"
}
},
"hyprtoolkit": {
"inputs": {
"aquamarine": [
@@ -487,11 +634,11 @@
]
},
"locked": {
"lastModified": 1764592794,
"narHash": "sha256-7CcO+wbTJ1L1NBQHierHzheQGPWwkIQug/w+fhTAVuU=",
"lastModified": 1772462885,
"narHash": "sha256-5pHXrQK9zasMnIo6yME6EOXmWGFMSnCITcfKshhKJ9I=",
"owner": "hyprwm",
"repo": "hyprtoolkit",
"rev": "5cfe0743f0e608e1462972303778d8a0859ee63e",
"rev": "9af245a69fa6b286b88ddfc340afd288e00a6998",
"type": "github"
},
"original": {
@@ -512,11 +659,11 @@
]
},
"locked": {
"lastModified": 1766160771,
"narHash": "sha256-roINUGikWRqqgKrD4iotKbGj3ZKJl3hjMz5l/SyKrHw=",
"lastModified": 1779475241,
"narHash": "sha256-Nw4DN0A5krWNcPBvuWe5Gz2yuxsUUPiDgtu6SVPJQeU=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "5ac060bfcf2f12b3a6381156ebbc13826a05b09f",
"rev": "3cd3972b2ee658a14d2610d8494e09259e530124",
"type": "github"
},
"original": {
@@ -537,11 +684,11 @@
]
},
"locked": {
"lastModified": 1763640274,
"narHash": "sha256-Uan1Nl9i4TF/kyFoHnTq1bd/rsWh4GAK/9/jDqLbY5A=",
"lastModified": 1777159683,
"narHash": "sha256-Jxixw6wZphUp+nHYxOKUYSckL17QMBx2d5Zp0rJHr1g=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "f6cf414ca0e16a4d30198fd670ec86df3c89f671",
"rev": "b8632713a6beaf28b56f2a7b0ab2fb7088dbb404",
"type": "github"
},
"original": {
@@ -566,11 +713,11 @@
]
},
"locked": {
"lastModified": 1766253200,
"narHash": "sha256-26qPwrd3od+xoYVywSB7hC2cz9ivN46VPLlrsXyGxvE=",
"lastModified": 1778410714,
"narHash": "sha256-o6RzFj4nJXaPRY7EM01siuCQeT41RfwwmcmFQqwFJJg=",
"owner": "hyprwm",
"repo": "hyprwire",
"rev": "1079777525b30a947c8d657fac158e00ae85de9d",
"rev": "85148a8e612808cf5ddb25d0b3c5840f3498a7dc",
"type": "github"
},
"original": {
@@ -601,6 +748,27 @@
"type": "github"
}
},
"matugen": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_4"
},
"locked": {
"lastModified": 1780068618,
"narHash": "sha256-LFiV5gdD4MkPrzBrc3Lq966vTQGuwwXC5WkgglWz7i4=",
"owner": "InioX",
"repo": "Matugen",
"rev": "74bfe9369a46589c5048072142796343a8d74168",
"type": "github"
},
"original": {
"owner": "InioX",
"repo": "Matugen",
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
@@ -634,11 +802,11 @@
"rust-overlay": "rust-overlay_2"
},
"locked": {
"lastModified": 1766882181,
"narHash": "sha256-Xmu3JL68gT623ySytIOoyKqoH0tj3qhtNOnT79RRews=",
"lastModified": 1779062503,
"narHash": "sha256-CYyaA/qV6TzccHJuEwi8LE9x/rVpMAFztsymq+HYsQ8=",
"ref": "refs/heads/master",
"rev": "ddb728dae4c9d6842664395635c9d55fb65c8b56",
"revCount": 78,
"rev": "4fd264f24fdf87d701ec82e7c6a4ca3e15c1c0aa",
"revCount": 79,
"type": "git",
"url": "https://git.sakamoto.dev/kenji/nixovim.git"
},
@@ -649,16 +817,16 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1744536153,
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
"owner": "NixOS",
"lastModified": 1768127708,
"narHash": "sha256-1Sm77VfZh3mU0F5OqKABNLWxOuDeHIlcFjsXeeiPazs=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
"rev": "ffbc9f8cbaacfb331b6017d5a5abb21a492c9a38",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
@@ -677,11 +845,43 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1766309749,
"narHash": "sha256-3xY8CZ4rSnQ0NqGhMKAy5vgC+2IVK0NoVEzDoOh4DA4=",
"lastModified": 1778869304,
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a6531044f6d0bef691ea18d4d4ce44d0daa6e816",
"rev": "d233902339c02a9c334e7e593de68855ad26c4cb",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1744536153,
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1778869304,
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d233902339c02a9c334e7e593de68855ad26c4cb",
"type": "github"
},
"original": {
@@ -698,14 +898,14 @@
"nixovim",
"nixpkgs"
],
"systems": "systems_3"
"systems": "systems_5"
},
"locked": {
"lastModified": 1766443759,
"narHash": "sha256-iGDhUPOPyY9NOTNHkhNzZKoz3+OlBNGg451qtvPq/Ic=",
"lastModified": 1779023681,
"narHash": "sha256-K7RLGyiK3J6wHr/JDxXdlGF0+0DEsdBf1w9mXjSyL8I=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "1787eeda5a2ce35bcd57dbb482718b0d897786ae",
"rev": "0d05726bfb060f6559f6d64c1d427f3663dba178",
"type": "github"
},
"original": {
@@ -737,7 +937,7 @@
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"flake-compat": "flake-compat_2",
"gitignore": "gitignore",
"nixpkgs": [
"hyprland",
@@ -745,11 +945,11 @@
]
},
"locked": {
"lastModified": 1765911976,
"narHash": "sha256-t3T/xm8zstHRLx+pIHxVpQTiySbKqcQbK+r+01XVKc0=",
"lastModified": 1778507602,
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "b68b780b69702a090c8bb1b973bab13756cc7a27",
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"type": "github"
},
"original": {
@@ -760,15 +960,23 @@
},
"root": {
"inputs": {
"apple-silicon": "apple-silicon",
"chaotic": "chaotic",
"elephant": "elephant",
"home-manager": "home-manager_2",
"hypr-dynamic-cursors": "hypr-dynamic-cursors",
"hyprland": "hyprland",
"hyprland-plugins": "hyprland-plugins",
"hyprspace": "hyprspace",
"hyprsplit": "hyprsplit",
"matugen": "matugen",
"nixovim": "nixovim",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs_4",
"nur": "nur",
"sops-nix": "sops-nix",
"textfox": "textfox",
"unlisted-fonts": "unlisted-fonts",
"vicinae": "vicinae",
"walker": "walker"
}
},
@@ -795,7 +1003,7 @@
},
"rust-overlay_2": {
"inputs": {
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1766544144,
@@ -818,11 +1026,11 @@
]
},
"locked": {
"lastModified": 1766289575,
"narHash": "sha256-BOKCwOQQIP4p9z8DasT5r+qjri3x7sPCOq+FTjY8Z+o=",
"lastModified": 1777944972,
"narHash": "sha256-VfGRo1qTBKOe3s2gOv8LSoA6Fk19PvBlwQ1ECN0Evn8=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "9836912e37aef546029e48c8749834735a6b9dad",
"rev": "c591bf665727040c6cc5cb409079acb22dcce33c",
"type": "github"
},
"original": {
@@ -862,6 +1070,36 @@
}
},
"systems_3": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
},
"systems_5": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
@@ -876,7 +1114,37 @@
"type": "github"
}
},
"systems_4": {
"systems_6": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_7": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_8": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
@@ -899,11 +1167,11 @@
]
},
"locked": {
"lastModified": 1763730250,
"narHash": "sha256-OPlKRltdA2iIm70Nw/kWt5FnwxR1xmxC44tqGUX7Hro=",
"lastModified": 1767427579,
"narHash": "sha256-q9aFfPohbMS6ehkQHReMeIjtld0wGiUsxlHoPRRvsp4=",
"owner": "adriankarlen",
"repo": "textfox",
"rev": "2f385d16abab56984b874627ca0dd4f3ca7ae4ac",
"rev": "29c31979e5583d9367247f0af8675f88482ff481",
"type": "github"
},
"original": {
@@ -912,6 +1180,48 @@
"type": "github"
}
},
"unlisted-fonts": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1748987994,
"narHash": "sha256-13QQRwZx9tRDmL79+XBM1YaC4W68mVrVW2NCv2w25WA=",
"ref": "refs/heads/master",
"rev": "468d51f24d3dd22c543e657c359fb333ff4df726",
"revCount": 1,
"type": "git",
"url": "https://git.sakamoto.dev/kenji/nix-fonts.git"
},
"original": {
"type": "git",
"url": "https://git.sakamoto.dev/kenji/nix-fonts.git"
}
},
"vicinae": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_7"
},
"locked": {
"lastModified": 1779832601,
"narHash": "sha256-/dtn1sOTEcb/rNInzkdnK8PNIIDfQi7fEJfQEq+Is4g=",
"owner": "vicinaehq",
"repo": "vicinae",
"rev": "dc1f7d47725c68debdb31be26781a96c14bac059",
"type": "github"
},
"original": {
"owner": "vicinaehq",
"repo": "vicinae",
"type": "github"
}
},
"walker": {
"inputs": {
"elephant": [
@@ -920,7 +1230,7 @@
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_4"
"systems": "systems_8"
},
"locked": {
"lastModified": 1766324177,
@@ -964,11 +1274,11 @@
]
},
"locked": {
"lastModified": 1761431178,
"narHash": "sha256-xzjC1CV3+wpUQKNF+GnadnkeGUCJX+vgaWIZsnz9tzI=",
"lastModified": 1778265244,
"narHash": "sha256-8jlPtGSsv/CQY6tVVyLF4Jjd0gnS+Zbn9yk/V13A9nM=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "4b8801228ff958d028f588f0c2b911dbf32297f9",
"rev": "813ea5ca9a1702a9a2d1f5836bc00172ef698968",
"type": "github"
},
"original": {
+61 -9
View File
@@ -18,7 +18,6 @@
url = "github:nix-community/NUR";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
@@ -27,6 +26,22 @@
url = "git+https://github.com/hyprwm/Hyprland?submodules=1";
inputs.nixpkgs.follows = "nixpkgs";
};
hyprsplit = {
url = "github:shezdy/hyprsplit";
inputs.hyprland.follows = "hyprland";
};
hyprland-plugins = {
url = "github:hyprwm/hyprland-plugins";
inputs.hyprland.follows = "hyprland";
};
hyprspace = {
url = "github:KZDKM/Hyprspace";
inputs.hyprland.follows = "hyprland";
};
hypr-dynamic-cursors = {
url = "github:Virtcode/hypr-dynamic-cursors";
inputs.hyprland.follows = "hyprland";
};
nixovim = {
# FIXME: treesitter does not install automatically (disabled due to read-only problems)
url = "git+https://git.sakamoto.dev/kenji/nixovim.git";
@@ -41,6 +56,25 @@
inputs.nixpkgs.follows = "nixpkgs";
inputs.elephant.follows = "elephant";
};
vicinae = {
url = "github:vicinaehq/vicinae";
inputs.nixpkgs.follows = "nixpkgs";
};
apple-silicon = {
url = "github:tpwrules/nixos-apple-silicon";
inputs.nixpkgs.follows = "nixpkgs";
};
unlisted-fonts = {
url = "git+https://git.sakamoto.dev/kenji/nix-fonts.git";
inputs.nixpkgs.follows = "nixpkgs";
};
# TODO: unstable.nixpkgs `matugen` is stuck at v4.0.0
# may need to use `git` version first
matugen = {
url = "github:/InioX/Matugen";
inputs.nixpkgs.follows = "nixpkgs";
# ...
};
};
outputs = {
@@ -51,26 +85,44 @@
chaotic,
sops-nix,
textfox,
apple-silicon,
...
} @ inputs: let
config = import ./config.nix;
system = "x86_64-linux";
args =
{
inherit inputs system;
}
// config;
allConfig = import ./config.nix;
in {
nixosConfigurations = {
hakase = nixpkgs.lib.nixosSystem {
specialArgs = args;
system = "x86_64-linux";
specialArgs =
{
inherit inputs;
system = "x86_64-linux";
}
// allConfig.hakase;
modules = [
inputs.matugen.nixosModules.default
home-manager.nixosModules.home-manager
sops-nix.nixosModules.sops
chaotic.nixosModules.default
./hosts/hakase/configuration.nix
];
};
macbook = nixpkgs.lib.nixosSystem {
system = "aarch64-linux";
specialArgs =
{
inherit inputs;
system = "aarch64-linux";
}
// allConfig.macbook;
modules = [
home-manager.nixosModules.home-manager
sops-nix.nixosModules.sops
apple-silicon.nixosModules.apple-silicon-support
./hosts/macbook/configuration.nix
];
};
};
};
}
+2
View File
@@ -6,6 +6,7 @@
}: {
imports = [
../modules/home/terminal.nix
# ../modules/home/flatpak.nix
../modules/home/apps.nix
../modules/home/apps-optional.nix
../modules/home/hyprland.nix
@@ -15,6 +16,7 @@
../modules/home/music.nix
inputs.walker.homeManagerModules.default
inputs.sops-nix.homeManagerModules.sops
inputs.vicinae.homeManagerModules.default
];
home.sessionVariables = {
+25
View File
@@ -0,0 +1,25 @@
{
pkgs,
inputs,
config,
...
}: {
imports = [
../modules/home/terminal.nix
../modules/home/apps.nix
../modules/home/apps-optional.nix
../modules/home/hyprland.nix
../modules/home/waybar.nix
../modules/home/theme.nix
../modules/home/music.nix
# No gaming.nix for MacBook
inputs.walker.homeManagerModules.default
inputs.sops-nix.homeManagerModules.sops
inputs.vicinae.homeManagerModules.default
];
home.sessionVariables = {
};
home.stateVersion = "25.05";
}
+2
View File
@@ -8,5 +8,7 @@
../../modules/nixos/default.nix
../../modules/nixos/hyprland.nix
../../modules/nixos/gaming.nix
../../modules/nixos/amd.nix
../../modules/nixos/amdcpu.nix
];
}
+24
View File
@@ -0,0 +1,24 @@
{
pkgs,
myConfig,
...
}: {
imports = [
./hardware-configuration.nix
../../modules/nixos/default.nix
../../modules/nixos/hyprland.nix
# No gaming.nix (Steam is x86 only)
# No amd.nix
];
# Apple Silicon specific hardware tweaks
hardware.asahi = {
# peripheralFirmwareDirectory = ./firmware; # If you have extracted firmware
useExperimentalGPUDriver = true;
experimentalGPUInstallMode = "replace";
};
# Bootloader for Asahi is usually systemd-boot or grub, but asahi-module handles m1n1
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = false; # Asahi often prefers this false to avoid bricking nvram
}
+30
View File
@@ -0,0 +1,30 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "usb_storage" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/00000000-0000-0000-0000-000000000000";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/0000-0000";
fsType = "vfat";
};
swapDevices = [ ];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
}
+14 -1
View File
@@ -1,8 +1,21 @@
{
{pkgs, ...}: {
imports = [
../../apps/btop
../../apps/bottom
../../apps/anki
../../apps/gemini
../../apps/jellyfin
../../apps/tickrs
../../apps/claude
../../apps/delfin
../../apps/jellyfin-mpv-shim
../../apps/nextcloud
../../apps/ttyper
../../apps/libreoffice
];
home.packages = with pkgs; [
chromium
imagemagick
hidapitester
];
}
+4 -1
View File
@@ -1,8 +1,11 @@
{
imports = [
../../apps/yazi
../../apps/gemini
../../apps/firefox
../../apps/imv
../../apps/zathura
../../apps/mpv
../../apps/mako
# ../../apps/starship
];
}
+25
View File
@@ -0,0 +1,25 @@
{pkgs, ...}: let
flatpak-install = pkgs.writeShellScriptBin "flatpak-install" ''
flatpak install --user --bundle "$1"
echo
read -p "Press Enter to close..."
'';
in {
home.packages = [flatpak-install];
xdg.mimeApps = {
enable = true;
defaultApplications = {
"application/vnd.flatpak" = "flatpak-bundle-installer.desktop";
};
};
xdg.desktopEntries.flatpak-bundle-installer = {
name = "Flatpak Bundle Installer";
exec = "flatpak-install %f";
terminal = true;
noDisplay = true;
type = "Application";
mimeType = ["application/vnd.flatpak"];
};
}

Some files were not shown because too many files have changed in this diff Show More