Compare commits
3 Commits
66e65b91ea
...
e38480e320
| Author | SHA1 | Date | |
|---|---|---|---|
| e38480e320 | |||
| 86d27b80d8 | |||
| ca62a6bd19 |
185
docs/uwsm-migration-summary.md
Normal file
185
docs/uwsm-migration-summary.md
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
# UWSM Migration Complete ✅
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
The Niri desktop environment has been **fully migrated** to UWSM (Universal Wayland Session Manager) for comprehensive systemd-based session management.
|
||||||
|
|
||||||
|
## What Changed
|
||||||
|
|
||||||
|
### 1. Session Launch (Host-Level)
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
- Manual desktop entry files in `/etc/wayland-sessions/`
|
||||||
|
- Manual UWSM package installation
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```nix
|
||||||
|
programs.uwsm = {
|
||||||
|
enable = true;
|
||||||
|
waylandCompositors.niri = {
|
||||||
|
prettyName = "Niri";
|
||||||
|
comment = "Niri scrollable-tiling Wayland compositor managed by UWSM";
|
||||||
|
binPath = "/run/current-system/sw/bin/niri-session";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Startup Applications (Home-Manager)
|
||||||
|
|
||||||
|
**Before:** Using `programs.niri.settings.spawn-at-startup`
|
||||||
|
|
||||||
|
**After:** Using `systemd.user.services` with proper targets
|
||||||
|
|
||||||
|
| Service | Type | Purpose |
|
||||||
|
|---------|------|---------|
|
||||||
|
| `nm-applet` | simple | Network manager tray icon |
|
||||||
|
| `zenbook-autostart` | oneshot | Initial display setup |
|
||||||
|
| `zenbook-delayed-setup` | oneshot | Secondary setup after delay |
|
||||||
|
| `zenbook-inotify-monitor` | simple | DRM status change monitor |
|
||||||
|
| `zenbook-udev-monitor` | simple | udev event monitor |
|
||||||
|
|
||||||
|
All services:
|
||||||
|
- `PartOf = ["graphical-session.target"]` - proper lifecycle
|
||||||
|
- `After = ["graphical-session.target"]` - correct ordering
|
||||||
|
- `WantedBy = ["graphical-session.target"]` - auto-start
|
||||||
|
- `Restart` policies for resilience
|
||||||
|
|
||||||
|
### 3. Application Launches (Keybinds)
|
||||||
|
|
||||||
|
**Before:** Direct binary execution
|
||||||
|
```nix
|
||||||
|
programs.niri.settings.binds."Mod+Return".action.spawn = ["${pkgs.fuzzel}/bin/fuzzel"];
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:** UWSM app wrapper
|
||||||
|
```nix
|
||||||
|
programs.niri.settings.binds."Mod+Return".action.spawn = ["uwsm" "app" "--" "${pkgs.fuzzel}/bin/fuzzel"];
|
||||||
|
```
|
||||||
|
|
||||||
|
All keybinds now use `uwsm app --`:
|
||||||
|
- `Mod+Return` → fuzzel launcher
|
||||||
|
- `Mod+L` → swaylock
|
||||||
|
- `Mod+Z` → zenbook-set-displays
|
||||||
|
|
||||||
|
### 4. Fuzzel Launcher Configuration
|
||||||
|
|
||||||
|
Fuzzel now has `launch-prefix` configured:
|
||||||
|
```nix
|
||||||
|
settings.main.launch-prefix = "uwsm app -- ";
|
||||||
|
```
|
||||||
|
|
||||||
|
This means apps launched from fuzzel are automatically placed in the correct systemd slice.
|
||||||
|
|
||||||
|
## Benefits Achieved
|
||||||
|
|
||||||
|
1. **✅ Environment Variable Inheritance**
|
||||||
|
- Login shell → PAM → systemd → compositor → applications
|
||||||
|
- All environment properly propagated
|
||||||
|
|
||||||
|
2. **✅ Systemd Integration**
|
||||||
|
- All services bound to `graphical-session.target`
|
||||||
|
- Proper dependency ordering and lifecycle management
|
||||||
|
|
||||||
|
3. **✅ Application Slicing**
|
||||||
|
- Apps launched via `uwsm app --` go into `app-graphical.slice`
|
||||||
|
- Better resource management and isolation
|
||||||
|
|
||||||
|
4. **✅ Clean Shutdown**
|
||||||
|
- Proper cleanup when session ends
|
||||||
|
- Services stopped in correct order
|
||||||
|
|
||||||
|
5. **✅ Resilience**
|
||||||
|
- Services auto-restart on failure
|
||||||
|
- Configurable restart policies
|
||||||
|
|
||||||
|
6. **✅ Standards Compliance**
|
||||||
|
- Follows systemd graphical session standards
|
||||||
|
- Compatible with XDG autostart (if needed)
|
||||||
|
|
||||||
|
## How to Use
|
||||||
|
|
||||||
|
### From Display Manager
|
||||||
|
|
||||||
|
Select **"Niri"** from your display manager (GDM, SDDM, etc.)
|
||||||
|
|
||||||
|
The session is now automatically launched via UWSM with full session management.
|
||||||
|
|
||||||
|
### From TTY
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Launch via UWSM
|
||||||
|
uwsm start niri
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify UWSM is Active
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check UWSM status
|
||||||
|
uwsm status
|
||||||
|
|
||||||
|
# List UWSM-managed units
|
||||||
|
systemctl --user list-units 'wayland-*'
|
||||||
|
|
||||||
|
# Check graphical session services
|
||||||
|
systemctl --user list-units --type=service | grep graphical
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check specific service
|
||||||
|
systemctl --user status nm-applet
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
journalctl --user -u zenbook-inotify-monitor -f
|
||||||
|
|
||||||
|
# List all services in graphical session
|
||||||
|
systemctl --user list-dependencies graphical-session.target
|
||||||
|
```
|
||||||
|
|
||||||
|
## Files Modified
|
||||||
|
|
||||||
|
| File | Changes |
|
||||||
|
|------|---------|
|
||||||
|
| `hosts/common/optional/niri.nix` | Added `programs.uwsm` module |
|
||||||
|
| `home/.../niri/waybar.nix` | nm-applet → systemd service |
|
||||||
|
| `home/.../niri/zenbook-screen.nix` | All tools → systemd services, keybind uses `uwsm app` |
|
||||||
|
| `home/.../niri/fuzzel.nix` | Keybind + launch-prefix use `uwsm app` |
|
||||||
|
| `home/.../niri/swaylock.nix` | Keybind uses `uwsm app` |
|
||||||
|
| `docs/uwsm-niri-integration.md` | Updated documentation |
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
After rebuilding:
|
||||||
|
|
||||||
|
1. Log out and select "Niri" from display manager
|
||||||
|
2. Log in and verify all components work:
|
||||||
|
- Waybar appears with tray icons
|
||||||
|
- nm-applet icon visible in tray
|
||||||
|
- `Mod+Return` opens fuzzel
|
||||||
|
- `Mod+L` locks screen
|
||||||
|
- Zenbook displays configured correctly
|
||||||
|
|
||||||
|
3. Check systemd services:
|
||||||
|
```bash
|
||||||
|
systemctl --user status nm-applet waybar zenbook-autostart
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Launch an app from fuzzel and verify it's in the right slice:
|
||||||
|
```bash
|
||||||
|
systemctl --user list-units --type=service | grep app-
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
See `docs/uwsm-niri-integration.md` for:
|
||||||
|
- Detailed UWSM concepts
|
||||||
|
- Troubleshooting guide
|
||||||
|
- Advanced configuration options
|
||||||
|
- Environment variable management
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [UWSM GitHub](https://github.com/vladimir-csp/uwsm)
|
||||||
|
- [NixOS UWSM Module](https://mynixos.com/nixpkgs/options/programs.uwsm)
|
||||||
|
- [UWSM Documentation](https://github.com/vladimir-csp/uwsm/blob/master/README.md)
|
||||||
248
docs/uwsm-niri-integration.md
Normal file
248
docs/uwsm-niri-integration.md
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
# UWSM Integration with Niri
|
||||||
|
|
||||||
|
## Status: ✅ FULLY INTEGRATED
|
||||||
|
|
||||||
|
This Niri configuration has been **fully migrated** to use UWSM (Universal Wayland Session Manager) for comprehensive systemd-based session management.
|
||||||
|
|
||||||
|
All components now use UWSM:
|
||||||
|
- ✅ Session launch via `programs.uwsm.waylandCompositors`
|
||||||
|
- ✅ Startup applications via `systemd.user.services` with `graphical-session.target`
|
||||||
|
- ✅ Application launches via `uwsm app --` wrapper (for proper systemd slice placement)
|
||||||
|
- ✅ Fuzzel launcher configured with UWSM launch-prefix
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
UWSM (Universal Wayland Session Manager) is a systemd-based session manager that provides:
|
||||||
|
|
||||||
|
1. **Proper environment variable inheritance** - Ensures environment variables from login shells, PAM, and system profiles are properly propagated to the Wayland session and all child processes
|
||||||
|
2. **Systemd integration** - Wraps the compositor in proper systemd units with lifecycle management
|
||||||
|
3. **XDG autostart support** - Handles XDG autostart applications with proper slices and dependencies
|
||||||
|
4. **Clean startup/shutdown** - Manages session lifecycle with proper cleanup on exit
|
||||||
|
5. **Session binding** - Can bind session lifecycle to login shell PID for proper TTY management
|
||||||
|
|
||||||
|
## Benefits for Niri
|
||||||
|
|
||||||
|
Currently, our Niri setup uses:
|
||||||
|
- `programs.niri.settings.spawn-at-startup` for starting applications like nm-applet
|
||||||
|
- `programs.waybar.systemd.enable = true` for waybar systemd service
|
||||||
|
- Manual systemd user services for various components
|
||||||
|
|
||||||
|
With UWSM:
|
||||||
|
- All startup applications would be managed consistently through systemd units
|
||||||
|
- Environment variables would be properly inherited from login shell → PAM → systemd → compositor → applications
|
||||||
|
- Better integration with systemd targets (`graphical-session.target`, etc.)
|
||||||
|
- Proper cleanup on logout/shutdown
|
||||||
|
- XDG autostart applications would work automatically
|
||||||
|
- Better compatibility with applications that expect standard Wayland session management
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
### 1. Host-Level Changes (`hosts/common/optional/niri.nix`)
|
||||||
|
|
||||||
|
Add UWSM package and configure it:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
uwsm
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
Enable UWSM mode for Niri (if the niri-flake supports it), or configure it manually.
|
||||||
|
|
||||||
|
### 2. User-Level Changes (`home/panotaka/common/optional/desktops/niri/`)
|
||||||
|
|
||||||
|
#### Option A: Use UWSM's systemd units (Recommended)
|
||||||
|
|
||||||
|
Remove manual `spawn-at-startup` entries and rely on:
|
||||||
|
- Systemd user services with `WantedBy=graphical-session.target`
|
||||||
|
- XDG autostart desktop entries
|
||||||
|
- UWSM's built-in environment preparation
|
||||||
|
|
||||||
|
#### Option B: Hybrid Approach
|
||||||
|
|
||||||
|
Keep some `spawn-at-startup` for compositor-specific tools, but use UWSM for:
|
||||||
|
- Environment variable management
|
||||||
|
- Session lifecycle binding
|
||||||
|
- XDG autostart apps
|
||||||
|
|
||||||
|
### 3. Migration Path
|
||||||
|
|
||||||
|
1. **Phase 1**: Add UWSM package and test manual invocation
|
||||||
|
```bash
|
||||||
|
uwsm start -o niri
|
||||||
|
systemctl --user start wayland-wm@niri.service
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Phase 2**: Migrate startup applications to systemd services
|
||||||
|
- Convert `spawn-at-startup` entries to `systemd.user.services`
|
||||||
|
- Use `WantedBy = ["graphical-session.target"]` for dependency
|
||||||
|
|
||||||
|
3. **Phase 3**: Create UWSM desktop entry for display managers
|
||||||
|
```desktop
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Niri (with UWSM)
|
||||||
|
Comment=Niri Wayland compositor with UWSM session management
|
||||||
|
Exec=uwsm start -D niri -N Niri -C "Niri compositor" -- niri
|
||||||
|
Type=Application
|
||||||
|
DesktopNames=niri
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Phase 4**: Configure environment finalization
|
||||||
|
- Have Niri execute `uwsm finalize` in its config to propagate compositor-specific variables
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
|
||||||
|
### What Uses `spawn-at-startup` Currently:
|
||||||
|
- `Restart` policies for resilience
|
||||||
|
|
||||||
|
#### 3. Application Launches → UWSM App Wrapper
|
||||||
|
|
||||||
|
All applications launched from Niri now use `uwsm app --` wrapper:
|
||||||
|
|
||||||
|
- **Fuzzel launcher**: `uwsm app -- fuzzel`
|
||||||
|
- Also configured with `launch-prefix = "uwsm app -- "` so apps launched from fuzzel are properly managed
|
||||||
|
- **Swaylock**: `uwsm app -- swaylock` (Mod+L keybind)
|
||||||
|
- **Zenbook tools**: `uwsm app -- zenbook-set-displays` (Mod+Z keybind)
|
||||||
|
|
||||||
|
This ensures all applications are placed in the correct systemd slices (`app-graphical.slice`) and inherit proper environment variables.
|
||||||
|
|
||||||
|
### Files Modified
|
||||||
|
|
||||||
|
1. **`hosts/common/optional/niri.nix`**
|
||||||
|
- Replaced manual desktop entries with `programs.uwsm` module
|
||||||
|
- Configured Niri as a UWSM-managed compositor
|
||||||
|
|
||||||
|
2. **`home/panotaka/common/optional/desktops/niri/waybar.nix`**
|
||||||
|
- Migrated nm-applet from spawn-at-startup to systemd.user.services.nm-applet
|
||||||
|
|
||||||
|
3. **`home/panotaka/common/optional/desktops/niri/zenbook-screen.nix`**
|
||||||
|
- Migrated all zenbook display management tools to systemd services:
|
||||||
|
- zenbook-autostart (oneshot initial setup)
|
||||||
|
- zenbook-delayed-setup (delayed secondary setup)
|
||||||
|
- zenbook-inotify-monitor (long-running DRM status watcher)
|
||||||
|
- zenbook-udev-monitor (long-running udev event watcher)
|
||||||
|
- Updated Mod+Z keybind to use `uwsm app --`
|
||||||
|
|
||||||
|
4. **`home/panotaka/common/optional/desktops/niri/fuzzel.nix`**
|
||||||
|
- Updated keybind to launch fuzzel via `uwsm app --`
|
||||||
|
- Added `launch-prefix = "uwsm app -- "` to fuzzel config
|
||||||
|
|
||||||
|
5. **`home/panotaka/common/optional/desktops/niri/swaylock.nix`**
|
||||||
|
- Updated Mod+L keybind to launch swaylock via `uwsm app --`
|
||||||
|
|
||||||
|
### Files Modified
|
||||||
|
|
||||||
|
1. **`home/panotaka/common/optional/desktops/niri/waybar.nix`**
|
||||||
|
- Migrated nm-applet from spawn-at-startup to systemd.user.services.nm-applet
|
||||||
|
|
||||||
|
2. **`home/panotaka/common/optional/desktops/niri/zenbook-screen.nix`**
|
||||||
|
|
||||||
|
### What Already Uses Systemd:
|
||||||
|
- `programs.waybar.systemd.enable = true`
|
||||||
|
- polkit-kde-authentication-agent-1
|
||||||
|
|
||||||
|
## Recommendation
|
||||||
|
|
||||||
|
For now, I recommend a **soft introduction** of UWSM:
|
||||||
|
|
||||||
|
1. **Add UWSM package** to the system so it's available
|
||||||
|
2. **Document how to use it** (this file)
|
||||||
|
3. **Keep current setup** working as-is
|
||||||
|
4. **Provide opt-in migration path** for users who want systemd-managed session
|
||||||
|
|
||||||
|
Later, when fully tested, we can:
|
||||||
|
- Make UWSM the default
|
||||||
|
- Migrate all startup apps to systemd services
|
||||||
|
- Remove manual `spawn-at-startup` entries
|
||||||
|
- Add UWSM desktop entry for GDM/SDDM
|
||||||
|
|
||||||
|
### Systemd User Services (graphical-session.target)
|
||||||
|
|
||||||
|
These services start automatically when the graphical session begins:
|
||||||
|
|
||||||
|
- **waybar** (via programs.waybar.systemd.enable)
|
||||||
|
- **nm-applet** (network manager applet for tray)
|
||||||
|
- **polkit-kde-authentication-agent-1** (authentication dialogs)
|
||||||
|
- **zenbook-autostart** (initial display setup)
|
||||||
|
- **zenbook-delayed-setup** (secondary setup after delay)
|
||||||
|
- **zenbook-inotify-monitor** (DRM status change monitoring)
|
||||||
|
- **zenbook-udev-monitor** (udev event monitoring)
|
||||||
|
|
||||||
|
## Monitoring and Debugging
|
||||||
|
|
||||||
|
### Check Service Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List all graphical session services
|
||||||
|
systemctl --user list-units --type=service | grep graphical
|
||||||
|
|
||||||
|
# Check specific service
|
||||||
|
systemctl --user status nm-applet
|
||||||
|
systemctl --user status zenbook-autostart
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
journalctl --user -u nm-applet -f
|
||||||
|
journalctl --user -u zenbook-inotify-monitor -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### UWSM Session Management
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check current UWSM session
|
||||||
|
uwsm status
|
||||||
|
|
||||||
|
# List UWSM-managed units
|
||||||
|
systemctl --user list-units 'wayland-*'
|
||||||
|
|
||||||
|
# Stop session cleanly
|
||||||
|
uwsm stop
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Service Not Starting
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check why service failed
|
||||||
|
systemctl --user status <service-name>
|
||||||
|
journalctl --user -u <service-name> -n 50
|
||||||
|
|
||||||
|
# Manually start for testing
|
||||||
|
systemctl --user start <service-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment Variables Missing
|
||||||
|
|
||||||
|
UWSM should automatically propagate environment variables. If something is missing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check what's in systemd's environment
|
||||||
|
systemctl --user show-environment
|
||||||
|
|
||||||
|
# Manually import if needed (shouldn't be necessary with UWSM)
|
||||||
|
systemctl --user import-environment VARIABLE_NAME
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing UWSM
|
||||||
|
|
||||||
|
To test UWSM without changing your current setup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate units without starting
|
||||||
|
uwsm start -o niri
|
||||||
|
|
||||||
|
# Check generated units
|
||||||
|
systemctl --user list-units 'wayland-*'
|
||||||
|
|
||||||
|
# Start manually
|
||||||
|
systemctl --user start wayland-wm@niri.service
|
||||||
|
|
||||||
|
# Stop
|
||||||
|
uwsm stop
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- UWSM GitHub: https://github.com/vladimir-csp/uwsm
|
||||||
|
- UWSM in NixOS: Available as `pkgs.uwsm`
|
||||||
|
- Hyprland UWSM integration: `programs.hyprland.withUWSM` option exists in nixpkgs
|
||||||
140
flake.lock
generated
140
flake.lock
generated
@@ -8,11 +8,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758879564,
|
"lastModified": 1759227262,
|
||||||
"narHash": "sha256-qh5X63FN7Wm8tIOhhWD6HaDDUzKX0PRSIegZSwB2VLI=",
|
"narHash": "sha256-ibKJckw+KWH6n+pscOA7DWImanr988zKB7R2Z6ZEMLM=",
|
||||||
"owner": "aylur",
|
"owner": "aylur",
|
||||||
"repo": "ags",
|
"repo": "ags",
|
||||||
"rev": "829827d9493e8a4ce2fdba34782c61eaa20351c8",
|
"rev": "f68a0d03fbb94f4beacedd922ffaa0bf0f10397a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -152,11 +152,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758332798,
|
"lastModified": 1758937572,
|
||||||
"narHash": "sha256-ICRVTu6tDKoKRLpPcXb7oB6uAMut2GQvNOb9n0hGMuY=",
|
"narHash": "sha256-9kz/tV6Mc53rSYBvsh6jw1kBBlhAYZdj0yovFE5sFaw=",
|
||||||
"owner": "caelestia-dots",
|
"owner": "caelestia-dots",
|
||||||
"repo": "cli",
|
"repo": "cli",
|
||||||
"rev": "dd982bcb9612ccc0a31371a2c0053643bd37c968",
|
"rev": "1de7da5f2ba366a7dab54f6f4315e5bc4ff5d823",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -174,11 +174,11 @@
|
|||||||
"quickshell": "quickshell"
|
"quickshell": "quickshell"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758868407,
|
"lastModified": 1759322152,
|
||||||
"narHash": "sha256-tuwgehceA4a29QwqUpbw5r9/dw+OKfmL/jrYtcaa92o=",
|
"narHash": "sha256-WiQnLQL4yJBs6C1JVDAvTuU2gft/QEVeu4DGfK55lwY=",
|
||||||
"owner": "caelestia-dots",
|
"owner": "caelestia-dots",
|
||||||
"repo": "shell",
|
"repo": "shell",
|
||||||
"rev": "87d6196e4db057d51187eca04a23851d7e8de869",
|
"rev": "11dc993f4b54631c88c655f1fe5f3caea0e96605",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -197,11 +197,11 @@
|
|||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758856036,
|
"lastModified": 1759359709,
|
||||||
"narHash": "sha256-aAxkSZGkSWUwdouhpYKaadItc2TS84k5MhEAHF0Epc8=",
|
"narHash": "sha256-A+vFSdQuzZfTpShWsUjQ+DBYYlh3Ta+vVI4qJzO1GqI=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "devenv",
|
"repo": "devenv",
|
||||||
"rev": "11380b77be7f8c0602a45c8625f255db9971a873",
|
"rev": "f0ea46e67b4fc24e91b4f52cb74721fbd68abe1d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -233,11 +233,11 @@
|
|||||||
"firefox-gnome-theme": {
|
"firefox-gnome-theme": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756083905,
|
"lastModified": 1758112371,
|
||||||
"narHash": "sha256-UqYGTBgI5ypGh0Kf6zZjom/vABg7HQocB4gmxzl12uo=",
|
"narHash": "sha256-lizRM2pj6PHrR25yimjyFn04OS4wcdbc38DCdBVa2rk=",
|
||||||
"owner": "rafaelmardojai",
|
"owner": "rafaelmardojai",
|
||||||
"repo": "firefox-gnome-theme",
|
"repo": "firefox-gnome-theme",
|
||||||
"rev": "b655eaf16d4cbec9c3472f62eee285d4b419a808",
|
"rev": "0909cfe4a2af8d358ad13b20246a350e14c2473d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -424,11 +424,11 @@
|
|||||||
},
|
},
|
||||||
"hardware": {
|
"hardware": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758663926,
|
"lastModified": 1759261527,
|
||||||
"narHash": "sha256-6CFdj7Xs616t1W4jLDH7IohAAvl5Dyib3qEv/Uqw1rk=",
|
"narHash": "sha256-wPd5oGvBBpUEzMF0kWnXge0WITNsITx/aGI9qLHgJ4g=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "170ff93c860b2a9868ed1e1102d4e52cb3d934e1",
|
"rev": "e087756cf4abbe1a34f3544c480fc1034d68742f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -444,11 +444,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758876467,
|
"lastModified": 1759337100,
|
||||||
"narHash": "sha256-ueGMsCYo6S6WiszKPpXoRCdMDVmsCwfA09L7blUEPlY=",
|
"narHash": "sha256-CcT3QvZ74NGfM+lSOILcCEeU+SnqXRvl1XCRHenZ0Us=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "173a29f735c69950cfeaac310d7e567115976be0",
|
"rev": "004753ae6b04c4b18aa07192c1106800aaacf6c3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -490,11 +490,11 @@
|
|||||||
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758818425,
|
"lastModified": 1759402670,
|
||||||
"narHash": "sha256-mNtae7u7vYOlj8kUD1nschvL33HPeEFl0WVI9DwiLDA=",
|
"narHash": "sha256-xmUTws/OKlj4sM6Z+tsIAWPA37CBtkMWQqiQ8OZFSo8=",
|
||||||
"owner": "sodiboo",
|
"owner": "sodiboo",
|
||||||
"repo": "niri-flake",
|
"repo": "niri-flake",
|
||||||
"rev": "062a8edd61960989f518d41cbbb9bd57d1d128da",
|
"rev": "c7008abf4b9df7f65991176835628949acb426cd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -523,11 +523,11 @@
|
|||||||
"niri-unstable": {
|
"niri-unstable": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758691861,
|
"lastModified": 1759395653,
|
||||||
"narHash": "sha256-CYgoGrY/Fx+hjzp8graTxJw1M7mn1f2jBkK26M04T0s=",
|
"narHash": "sha256-sv9J1z6CrTPf9lRJLyCN90fZVdQz7LFeX7pIlInH8BQ=",
|
||||||
"owner": "YaLTeR",
|
"owner": "YaLTeR",
|
||||||
"repo": "niri",
|
"repo": "niri",
|
||||||
"rev": "e837e39623457dc5ad29c34a5ce4d4616e5fbf1e",
|
"rev": "ba6e5e082a79901dc89b0d49c5da1b769d652aec",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -562,16 +562,16 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1755029779,
|
"lastModified": 1758763079,
|
||||||
"narHash": "sha256-3+GHIYGg4U9XKUN4rg473frIVNn8YD06bjwxKS1IPrU=",
|
"narHash": "sha256-Bx1A+lShhOWwMuy3uDzZQvYiBKBFcKwy6G6NEohhv6A=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "nix",
|
"repo": "nix",
|
||||||
"rev": "b0972b0eee6726081d10b1199f54de6d2917f861",
|
"rev": "6f0140527c2b0346df4afad7497baa08decb929f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"ref": "devenv-2.30.4",
|
"ref": "devenv-2.30.5",
|
||||||
"repo": "nix",
|
"repo": "nix",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -604,11 +604,11 @@
|
|||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758851723,
|
"lastModified": 1759369869,
|
||||||
"narHash": "sha256-BNDR12ymasahEY+A7l0+6XNEb76DgNzYNhKWx0SHtn0=",
|
"narHash": "sha256-4X76RvMmzngRshwTDFsloxjHYdKtQoMY5Ob8+qwS+Dc=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nix4vscode",
|
"repo": "nix4vscode",
|
||||||
"rev": "cab50c386a191d1348b0a016e7542603f259c2fc",
|
"rev": "c90d1d398e9db998b0852a339dc3dc10efbdb2ce",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -619,11 +619,11 @@
|
|||||||
},
|
},
|
||||||
"nixos-hardware": {
|
"nixos-hardware": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758663926,
|
"lastModified": 1759261527,
|
||||||
"narHash": "sha256-6CFdj7Xs616t1W4jLDH7IohAAvl5Dyib3qEv/Uqw1rk=",
|
"narHash": "sha256-wPd5oGvBBpUEzMF0kWnXge0WITNsITx/aGI9qLHgJ4g=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "170ff93c860b2a9868ed1e1102d4e52cb3d934e1",
|
"rev": "e087756cf4abbe1a34f3544c480fc1034d68742f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -634,11 +634,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1755783167,
|
"lastModified": 1758532697,
|
||||||
"narHash": "sha256-gj7qvMNz7YvhjYxNq4I370cAYIZEw2PbVs5BSwaLrD4=",
|
"narHash": "sha256-bhop0bR3u7DCw9/PtLCwr7GwEWDlBSxHp+eVQhCW9t4=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "devenv-nixpkgs",
|
"repo": "devenv-nixpkgs",
|
||||||
"rev": "4a880fb247d24fbca57269af672e8f78935b0328",
|
"rev": "207a4cb0e1253c7658c6736becc6eb9cace1f25f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -666,11 +666,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-stable": {
|
"nixpkgs-stable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758589230,
|
"lastModified": 1759281824,
|
||||||
"narHash": "sha256-zMTCFGe8aVGTEr2RqUi/QzC1nOIQ0N1HRsbqB4f646k=",
|
"narHash": "sha256-FIBE1qXv9TKvSNwst6FumyHwCRH3BlWDpfsnqRDCll0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d1d883129b193f0b495d75c148c2c3a7d95789a0",
|
"rev": "5b5be50345d4113d04ba58c444348849f5585b4a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -682,11 +682,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-stable_2": {
|
"nixpkgs-stable_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758589230,
|
"lastModified": 1759281824,
|
||||||
"narHash": "sha256-zMTCFGe8aVGTEr2RqUi/QzC1nOIQ0N1HRsbqB4f646k=",
|
"narHash": "sha256-FIBE1qXv9TKvSNwst6FumyHwCRH3BlWDpfsnqRDCll0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d1d883129b193f0b495d75c148c2c3a7d95789a0",
|
"rev": "5b5be50345d4113d04ba58c444348849f5585b4a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -698,11 +698,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758690382,
|
"lastModified": 1759036355,
|
||||||
"narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=",
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e643668fd71b949c53f8626614b21ff71a07379d",
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -714,11 +714,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758690382,
|
"lastModified": 1759036355,
|
||||||
"narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=",
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e643668fd71b949c53f8626614b21ff71a07379d",
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -740,11 +740,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756961635,
|
"lastModified": 1758998580,
|
||||||
"narHash": "sha256-hETvQcILTg5kChjYNns1fD5ELdsYB/VVgVmBtqKQj9A=",
|
"narHash": "sha256-VLx0z396gDCGSiowLMFz5XRO/XuNV+4EnDYjdJhHvUk=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "6ca27b2654ac55e3f6e0ca434c1b4589ae22b370",
|
"rev": "ba8d9c98f5f4630bcb0e815ab456afd90c930728",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -838,11 +838,11 @@
|
|||||||
"tinted-zed": "tinted-zed"
|
"tinted-zed": "tinted-zed"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758757969,
|
"lastModified": 1759404594,
|
||||||
"narHash": "sha256-2zC4aHoDsR12Jyd6WvSxmQbAKT4V93frnHHDjA8o3r8=",
|
"narHash": "sha256-k9hd15rLqG7x3OCUPrcQtpleDlOyQjy16ZEseruypNQ=",
|
||||||
"owner": "danth",
|
"owner": "danth",
|
||||||
"repo": "stylix",
|
"repo": "stylix",
|
||||||
"rev": "484819a16fdc1c76cdd62d8e94018db44e5e1a8b",
|
"rev": "3f70c5855572004f9c630ed4a92aa186755361be",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -918,11 +918,11 @@
|
|||||||
"tinted-schemes": {
|
"tinted-schemes": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1754779259,
|
"lastModified": 1757716333,
|
||||||
"narHash": "sha256-8KG2lXGaXLUE0F/JVwLQe7kOVm21IDfNEo0gfga5P4M=",
|
"narHash": "sha256-d4km8W7w2zCUEmPAPUoLk1NlYrGODuVa3P7St+UrqkM=",
|
||||||
"owner": "tinted-theming",
|
"owner": "tinted-theming",
|
||||||
"repo": "schemes",
|
"repo": "schemes",
|
||||||
"rev": "097d751b9e3c8b97ce158e7d141e5a292545b502",
|
"rev": "317a5e10c35825a6c905d912e480dfe8e71c7559",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -934,11 +934,11 @@
|
|||||||
"tinted-tmux": {
|
"tinted-tmux": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1754788770,
|
"lastModified": 1757811970,
|
||||||
"narHash": "sha256-LAu5nBr7pM/jD9jwFc6/kyFY4h7Us4bZz7dvVvehuwo=",
|
"narHash": "sha256-n5ZJgmzGZXOD9pZdAl1OnBu3PIqD+X3vEBUGbTi4JiI=",
|
||||||
"owner": "tinted-theming",
|
"owner": "tinted-theming",
|
||||||
"repo": "tinted-tmux",
|
"repo": "tinted-tmux",
|
||||||
"rev": "fb2175accef8935f6955503ec9dd3c973eec385c",
|
"rev": "d217ba31c846006e9e0ae70775b0ee0f00aa6b1e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -950,11 +950,11 @@
|
|||||||
"tinted-zed": {
|
"tinted-zed": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1755613540,
|
"lastModified": 1757811247,
|
||||||
"narHash": "sha256-zBFrrTxHLDMDX/OYxkCwGGbAhPXLi8FrnLhYLsSOKeY=",
|
"narHash": "sha256-4EFOUyLj85NRL3OacHoLGEo0wjiRJzfsXtR4CZWAn6w=",
|
||||||
"owner": "tinted-theming",
|
"owner": "tinted-theming",
|
||||||
"repo": "base16-zed",
|
"repo": "base16-zed",
|
||||||
"rev": "937bada16cd3200bdbd3a2f5776fc3b686d5cba0",
|
"rev": "824fe0aacf82b3c26690d14e8d2cedd56e18404e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1004,11 +1004,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758860615,
|
"lastModified": 1759378939,
|
||||||
"narHash": "sha256-ZNzHF498lMfv1N/tlfD/Oaanu+REnIhJdreo2rSzU1w=",
|
"narHash": "sha256-MWCIUqkxoMnvNYjooFiFHzlcZDBOp4DTXERe8xdEWoU=",
|
||||||
"owner": "0xc000022070",
|
"owner": "0xc000022070",
|
||||||
"repo": "zen-browser-flake",
|
"repo": "zen-browser-flake",
|
||||||
"rev": "a5f59feaf757aecb12e2fa2490e8a7c1eed12173",
|
"rev": "3ac78827a82614c394e6f8fcc84c5cea9c3847f4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
24
home/panotaka/.local/bin/fuzzel-power-menu.sh
Normal file
24
home/panotaka/.local/bin/fuzzel-power-menu.sh
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
choices="lock\nsleep\npoweroff\nreboot"
|
||||||
|
|
||||||
|
selected=$(echo -e "$choices" | ${pkgs.fuzzel}/bin/fuzzel --dmenu --prompt " ")
|
||||||
|
|
||||||
|
case "$selected" in
|
||||||
|
lock)
|
||||||
|
uwsm app -- ${pkgs.swaylock}/bin/swaylock
|
||||||
|
;;
|
||||||
|
sleep)
|
||||||
|
systemctl suspend
|
||||||
|
;;
|
||||||
|
poweroff)
|
||||||
|
systemctl poweroff
|
||||||
|
;;
|
||||||
|
reboot)
|
||||||
|
systemctl reboot
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
#
|
#
|
||||||
# FIXME(starter): add or remove any optional config directories or files ehre
|
# FIXME(starter): add or remove any optional config directories or files ehre
|
||||||
common/optional/browsers
|
common/optional/browsers
|
||||||
common/optional/desktops/gnome
|
common/optional/desktops/niri
|
||||||
common/optional/desktops/gnome/zenbook-screen.nix
|
common/optional/desktops/niri/zenbook-screen.nix
|
||||||
common/optional/comms
|
common/optional/comms
|
||||||
common/optional/media
|
common/optional/media
|
||||||
common/optional/coding
|
common/optional/coding
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
# Niri Configuration
|
|
||||||
|
|
||||||
This directory contains the niri desktop configuration, similar to the Hyprland setup but using the niri scrollable tiling Wayland compositor.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **Scrollable tiling**: Niri's unique column-based scrollable tiling layout
|
|
||||||
- **Waybar integration**: Status bar with niri-specific modules
|
|
||||||
- **Wofi launcher**: Application launcher and runner
|
|
||||||
- **Swaylock screen locking**: Screen lock with swayidle integration
|
|
||||||
- **Keyring support**: GNOME keyring integration for password management
|
|
||||||
- **Screenshot support**: Grim + Slurp for screenshots
|
|
||||||
- **Media controls**: Volume and brightness control keybindings
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
- `default.nix`: Main niri configuration with keybindings and settings
|
|
||||||
- `waybar.nix`: Status bar configuration with niri modules
|
|
||||||
- `wofi.nix`: Application launcher configuration
|
|
||||||
- `swaylock.nix`: Screen lock configuration
|
|
||||||
- `swayidle.nix`: Idle management and auto-lock
|
|
||||||
- `keyring.nix`: GNOME keyring integration
|
|
||||||
|
|
||||||
## Key Bindings
|
|
||||||
|
|
||||||
- `Super + Return`: Launch terminal (kitty)
|
|
||||||
- `Super + B`: Launch browser (zen)
|
|
||||||
- `Super + Q`: Close window
|
|
||||||
- `Super + Shift + E`: Quit niri
|
|
||||||
- `Super`: Launch application launcher (wofi drun)
|
|
||||||
- `Super + D`: Launch run prompt (wofi run)
|
|
||||||
- `Super + L`: Lock screen (swaylock)
|
|
||||||
- `Super + 1-0`: Switch to workspace 1-10
|
|
||||||
- `Super + Shift + 1-0`: Move window to workspace 1-10
|
|
||||||
- `Super + Arrow Keys`: Navigate between columns/windows
|
|
||||||
- `Super + Ctrl + Arrow Keys`: Move windows/columns
|
|
||||||
- `Super + R`: Switch column width preset
|
|
||||||
- `Super + Shift + R`: Reset window height
|
|
||||||
- `Print`: Take screenshot
|
|
||||||
- `Super + Print`: Take area screenshot
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
To use this niri configuration, import it in your home manager configuration:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
imports = [
|
|
||||||
./common/optional/desktops/niri
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
Make sure the niri-flake is added to your system's flake inputs.
|
|
||||||
@@ -1,195 +1,25 @@
|
|||||||
{pkgs, ...}: {
|
|
||||||
imports = [
|
|
||||||
./keyring.nix
|
|
||||||
./custom-shell.nix # Our custom shell components
|
|
||||||
];
|
|
||||||
|
|
||||||
# Add network utility packages
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
networkmanager # Network utility
|
|
||||||
wl-clipboard # Wayland clipboard
|
|
||||||
grim # Screenshot utility
|
|
||||||
slurp # Screen selection utility
|
|
||||||
mako # Notification daemon
|
|
||||||
brightnessctl # Brightness control
|
|
||||||
];
|
|
||||||
|
|
||||||
# Configure niri
|
|
||||||
programs.niri = {
|
|
||||||
settings = {
|
|
||||||
input = {
|
|
||||||
keyboard = {
|
|
||||||
xkb = {
|
|
||||||
layout = "us";
|
|
||||||
variant = "";
|
|
||||||
options = "grp:alt_shift_toggle";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
touchpad = {
|
|
||||||
tap = true;
|
|
||||||
dwt = true;
|
|
||||||
natural-scroll = true;
|
|
||||||
click-method = "clickfinger";
|
|
||||||
middle-emulation = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
mouse = {
|
|
||||||
natural-scroll = false;
|
|
||||||
accel-speed = 0.0;
|
|
||||||
accel-profile = "flat";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Focus monitor on mouse hover, but not individual windows
|
|
||||||
focus-follows-mouse = {
|
|
||||||
enable = true;
|
|
||||||
max-scroll-amount = "0%";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = {
|
|
||||||
# Place DP-4 on the left
|
|
||||||
"DP-4" = {
|
|
||||||
position = {
|
|
||||||
x = 1920;
|
|
||||||
y = 0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Place DP-5 to the right of it
|
|
||||||
"DP-5" = {
|
|
||||||
position = {
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
layout = {
|
|
||||||
gaps = 16;
|
|
||||||
center-focused-column = "never";
|
|
||||||
preset-column-widths = [
|
|
||||||
{proportion = 0.333;}
|
|
||||||
{proportion = 0.5;}
|
|
||||||
{proportion = 0.667;}
|
|
||||||
];
|
|
||||||
default-column-width = {proportion = 0.5;};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Prefer dark theme
|
|
||||||
prefer-no-csd = true;
|
|
||||||
|
|
||||||
# Screenshot path
|
|
||||||
screenshot-path = "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png";
|
|
||||||
|
|
||||||
# Hotkey overlay
|
|
||||||
hotkey-overlay = {
|
|
||||||
skip-at-startup = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Spawn programs at startup
|
|
||||||
spawn-at-startup = [
|
|
||||||
{command = ["mako"];}
|
|
||||||
{command = ["swayidle"];}
|
|
||||||
{command = ["ags" "run"];}
|
|
||||||
];
|
|
||||||
|
|
||||||
# Window rules
|
|
||||||
window-rules = [
|
|
||||||
{
|
{
|
||||||
matches = [{app-id = "^org\.gnome\.Nautilus$";}];
|
pkgs,
|
||||||
default-column-width = {proportion = 0.333;};
|
lib,
|
||||||
}
|
...
|
||||||
{
|
}: {
|
||||||
matches = [{app-id = "^pavucontrol$";}];
|
imports = [./waybar.nix ./swayidle.nix ./fuzzel.nix ./swaylock.nix];
|
||||||
default-column-width = {proportion = 0.333;};
|
|
||||||
}
|
# Import patterns similar to other desktop modules
|
||||||
|
home.packages = [
|
||||||
|
pkgs.wl-clipboard
|
||||||
|
pkgs.grim
|
||||||
|
pkgs.slurp
|
||||||
|
pkgs.polkit_gnome
|
||||||
|
pkgs.xdg-desktop-portal-wlr
|
||||||
];
|
];
|
||||||
|
|
||||||
# Keybindings
|
# Enable Niri and provide baseline settings; other modules merge into programs.niri.settings
|
||||||
binds = {
|
programs.niri.settings = lib.mkDefault {
|
||||||
"Mod+B".action.spawn = ["zen"];
|
binds = {};
|
||||||
"Mod+Q".action.close-window = {};
|
|
||||||
"Mod+Shift+E".action.quit = {};
|
|
||||||
|
|
||||||
# Launcher
|
|
||||||
"Mod+D".action.spawn = ["sh" "-c" "pkill wofi || wofi --show drun"];
|
|
||||||
|
|
||||||
# Network utility (NetworkManager TUI)
|
|
||||||
"Mod+N".action.spawn = ["kitty" "-e" "nmtui"];
|
|
||||||
# Secrets manager (Seahorse - GNOME keyring GUI)
|
|
||||||
"Mod+K".action.spawn = ["seahorse"];
|
|
||||||
# Terminal (Ghostty)
|
|
||||||
"Mod+T".action.spawn = ["ghostty"];
|
|
||||||
|
|
||||||
# Workspace navigation
|
|
||||||
"Mod+Page_Up".action.focus-workspace-up = {};
|
|
||||||
"Mod+Page_Down".action.focus-workspace-down = {};
|
|
||||||
|
|
||||||
"Mod+1".action.focus-workspace = 1;
|
|
||||||
"Mod+2".action.focus-workspace = 2;
|
|
||||||
"Mod+3".action.focus-workspace = 3;
|
|
||||||
"Mod+4".action.focus-workspace = 4;
|
|
||||||
"Mod+5".action.focus-workspace = 5;
|
|
||||||
"Mod+6".action.focus-workspace = 6;
|
|
||||||
"Mod+7".action.focus-workspace = 7;
|
|
||||||
"Mod+8".action.focus-workspace = 8;
|
|
||||||
"Mod+9".action.focus-workspace = 9;
|
|
||||||
"Mod+0".action.focus-workspace = 10;
|
|
||||||
|
|
||||||
# Move window to workspace
|
|
||||||
"Mod+Shift+1".action.move-window-to-workspace = 1;
|
|
||||||
"Mod+Shift+2".action.move-window-to-workspace = 2;
|
|
||||||
"Mod+Shift+3".action.move-window-to-workspace = 3;
|
|
||||||
"Mod+Shift+4".action.move-window-to-workspace = 4;
|
|
||||||
"Mod+Shift+5".action.move-window-to-workspace = 5;
|
|
||||||
"Mod+Shift+6".action.move-window-to-workspace = 6;
|
|
||||||
"Mod+Shift+7".action.move-window-to-workspace = 7;
|
|
||||||
"Mod+Shift+8".action.move-window-to-workspace = 8;
|
|
||||||
"Mod+Shift+9".action.move-window-to-workspace = 9;
|
|
||||||
"Mod+Shift+0".action.move-window-to-workspace = 10;
|
|
||||||
|
|
||||||
# Window navigation
|
|
||||||
"Mod+Left".action.focus-column-left = {};
|
|
||||||
"Mod+Right".action.focus-column-right = {};
|
|
||||||
"Mod+Up".action.focus-window-up = {};
|
|
||||||
"Mod+Down".action.focus-window-down = {};
|
|
||||||
|
|
||||||
# Window movement
|
|
||||||
"Mod+Ctrl+Left".action.move-column-left = {};
|
|
||||||
"Mod+Ctrl+Right".action.move-column-right = {};
|
|
||||||
"Mod+Ctrl+Up".action.move-window-up = {};
|
|
||||||
"Mod+Ctrl+Down".action.move-window-down = {};
|
|
||||||
|
|
||||||
# Window resizing
|
|
||||||
"Mod+R".action.switch-preset-column-width = {};
|
|
||||||
"Mod+Shift+R".action.reset-window-height = {};
|
|
||||||
"Mod+F".action.maximize-column = {};
|
|
||||||
|
|
||||||
# Screenshots
|
|
||||||
"Print".action.spawn = ["grim"];
|
|
||||||
"Mod+Print".action.spawn = ["sh" "-c" "grim -g \"$(slurp)\""];
|
|
||||||
|
|
||||||
# Screen lock
|
|
||||||
"Mod+L".action.spawn = ["swaylock"];
|
|
||||||
|
|
||||||
# Brightness control
|
|
||||||
"XF86MonBrightnessUp".action.spawn = ["brightnessctl" "set" "5%+"];
|
|
||||||
"XF86MonBrightnessDown".action.spawn = ["brightnessctl" "set" "5%-"];
|
|
||||||
|
|
||||||
# Volume control
|
|
||||||
"XF86AudioRaiseVolume".action.spawn = ["wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1+"];
|
|
||||||
"XF86AudioLowerVolume".action.spawn = ["wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1-"];
|
|
||||||
"XF86AudioMute".action.spawn = ["wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"];
|
|
||||||
|
|
||||||
# Horizontal window scrolling with mod + scroll wheel
|
|
||||||
"Mod+WheelScrollDown".action.focus-column-right = {};
|
|
||||||
"Mod+WheelScrollUp".action.focus-column-left = {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Session variables for proper integration
|
# Session variables for Wayland compatibility
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
NIXOS_OZONE_WL = "1";
|
NIXOS_OZONE_WL = "1";
|
||||||
MOZ_ENABLE_WAYLAND = "1";
|
MOZ_ENABLE_WAYLAND = "1";
|
||||||
|
|||||||
22
home/panotaka/common/optional/desktops/niri/fuzzel.nix
Normal file
22
home/panotaka/common/optional/desktops/niri/fuzzel.nix
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.fuzzel = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.fuzzel;
|
||||||
|
|
||||||
|
# Write a minimal fuzzel.ini using settings attribute; users can extend this
|
||||||
|
settings = {
|
||||||
|
main = {
|
||||||
|
terminal = "${pkgs.ghostty}/bin/ghostty";
|
||||||
|
# Use UWSM app launcher wrapper for proper systemd slice management
|
||||||
|
launch-prefix = "uwsm app -- ";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add a recommended niri keybind to spawn fuzzel (Mod+Return)
|
||||||
|
# Launch fuzzel itself via UWSM for proper session integration
|
||||||
|
programs.niri.settings.binds."Mod+Return".action.spawn = ["uwsm" "app" "--" "${pkgs.fuzzel}/bin/fuzzel"];
|
||||||
|
|
||||||
|
# Add a keybind to launch the power menu (Mod+Shift+P)
|
||||||
|
programs.niri.settings.binds."Mod+Shift+P".action.spawn = ["uwsm" "app" "--" "$HOME/.local/bin/fuzzel-power-menu.sh"];
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
{pkgs, ...}: {
|
|
||||||
# Additional keyring packages for user interaction
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
kdePackages.kwalletmanager # KDE wallet manager GUI (Qt 6)
|
|
||||||
kdePackages.kwallet # KDE wallet library (Qt 6)
|
|
||||||
libsecret # Secret service API library
|
|
||||||
];
|
|
||||||
|
|
||||||
# Session variables for proper keyring integration
|
|
||||||
home.sessionVariables = {
|
|
||||||
# SSH agent socket for SSH key management
|
|
||||||
SSH_AUTH_SOCK = "$XDG_RUNTIME_DIR/keyring/ssh";
|
|
||||||
# Enable secret service D-Bus API
|
|
||||||
SECRET_SERVICE_API = "1";
|
|
||||||
# Ensure proper D-Bus session bus integration
|
|
||||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=$XDG_RUNTIME_DIR/bus";
|
|
||||||
# Enable password store integration
|
|
||||||
PASSWORD_STORE_ENABLE_EXTENSIONS = "true";
|
|
||||||
# Set keyring backend for KDE wallet
|
|
||||||
KEYRING_BACKEND = "kwallet";
|
|
||||||
# Ensure XDG runtime directory is available
|
|
||||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
|
||||||
# KWallet integration
|
|
||||||
KWALLET_ENABLED = "1";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
31
home/panotaka/common/optional/desktops/niri/swayidle.nix
Normal file
31
home/panotaka/common/optional/desktops/niri/swayidle.nix
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
# Ensure swayidle and swaylock are available for the user
|
||||||
|
home.packages = [pkgs.swayidle pkgs.swaylock pkgs.inotify-tools];
|
||||||
|
|
||||||
|
# Use Home Manager's documented services.swayidle options
|
||||||
|
services.swayidle = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.swayidle;
|
||||||
|
# Timeouts:
|
||||||
|
# - lock after 5 minutes
|
||||||
|
# - suspend after 15 minutes
|
||||||
|
# - hibernate after 60 minutes
|
||||||
|
timeouts = [
|
||||||
|
{
|
||||||
|
timeout = 300; # 5 minutes
|
||||||
|
command = "${pkgs.swaylock}/bin/swaylock -f";
|
||||||
|
resumeCommand = "swaymsg resume";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = 900; # 15 minutes
|
||||||
|
command = "systemctl suspend";
|
||||||
|
resumeCommand = "swaymsg resume";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = 3600; # 60 minutes
|
||||||
|
command = "systemctl hibernate";
|
||||||
|
resumeCommand = "swaymsg resume";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
10
home/panotaka/common/optional/desktops/niri/swaylock.nix
Normal file
10
home/panotaka/common/optional/desktops/niri/swaylock.nix
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
# Enable home-manager swaylock integration
|
||||||
|
programs.swaylock = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add a keybind to spawn swaylock (Mod+L)
|
||||||
|
# Launch via UWSM for proper systemd integration
|
||||||
|
programs.niri.settings.binds."Mod+L".action.spawn = ["uwsm" "app" "--" "${pkgs.swaylock}/bin/swaylock"];
|
||||||
|
}
|
||||||
192
home/panotaka/common/optional/desktops/niri/waybar.nix
Normal file
192
home/panotaka/common/optional/desktops/niri/waybar.nix
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
# Safely access system-level stylix targets (may not always be present during some checks)
|
||||||
|
stylixTargets =
|
||||||
|
if config.stylix != null && config.stylix ? targets
|
||||||
|
then config.stylix.targets
|
||||||
|
else {};
|
||||||
|
waybarOut =
|
||||||
|
if stylixTargets ? waybar && stylixTargets.waybar ? stylixTargets.waybar.outPath
|
||||||
|
then stylixTargets.waybar.outPath
|
||||||
|
else null;
|
||||||
|
colors =
|
||||||
|
if config.lib != null && config.lib.stylix != null && config.lib.stylix.colors != null
|
||||||
|
then config.lib.stylix.colors
|
||||||
|
else {base05 = "ffffff";};
|
||||||
|
in {
|
||||||
|
# Use the programs.waybar home-manager module
|
||||||
|
programs.waybar = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.waybar;
|
||||||
|
systemd.enable = true;
|
||||||
|
|
||||||
|
# Waybar settings tailored for sway/hyprland-style setups
|
||||||
|
settings = {
|
||||||
|
mainBar = {
|
||||||
|
layer = "top";
|
||||||
|
position = "top";
|
||||||
|
height = 35;
|
||||||
|
spacing = 4;
|
||||||
|
|
||||||
|
# Add a placeholder for your window manager's workspace module
|
||||||
|
# For Sway/Hyprland: "sway/workspaces" or "hyprland/workspaces"
|
||||||
|
modules-left = ["sway/workspaces" "sway/mode"];
|
||||||
|
modules-center = ["sway/window"];
|
||||||
|
modules-right = [
|
||||||
|
"bluetooth"
|
||||||
|
"network"
|
||||||
|
"pipewire"
|
||||||
|
"tray"
|
||||||
|
"battery"
|
||||||
|
"clock"
|
||||||
|
];
|
||||||
|
|
||||||
|
# --- Module Definitions ---
|
||||||
|
"sway/workspaces" = {
|
||||||
|
disable-scroll = true;
|
||||||
|
all-outputs = true;
|
||||||
|
format = "{name}: {icon}";
|
||||||
|
format-icons = {
|
||||||
|
"1" = "";
|
||||||
|
"2" = "";
|
||||||
|
"3" = "";
|
||||||
|
"focused" = "";
|
||||||
|
"default" = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
clock = {
|
||||||
|
format = " {:%I:%M %p}";
|
||||||
|
tooltip-format = "<big>{:%A, %B %d, %Y}</big>\n<tt><small>{calendar}</small></tt>";
|
||||||
|
};
|
||||||
|
|
||||||
|
tray = {
|
||||||
|
"icon-size" = 18;
|
||||||
|
spacing = 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
pipewire = {
|
||||||
|
format = "{icon} {volume}%";
|
||||||
|
format-muted = " Muted";
|
||||||
|
format-icons = {
|
||||||
|
"default" = ["" "" ""];
|
||||||
|
};
|
||||||
|
# Native PipeWire control using wpctl
|
||||||
|
on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
|
||||||
|
on-click-right = "wpctl set-mute @DEFAULT_SINK@ toggle";
|
||||||
|
on-scroll-up = "wpctl set-volume @DEFAULT_SINK@ +5%";
|
||||||
|
on-scroll-down = "wpctl set-volume @DEFAULT_SINK@ -5%";
|
||||||
|
scroll-step = 5;
|
||||||
|
};
|
||||||
|
|
||||||
|
network = {
|
||||||
|
format-wifi = " {essid}";
|
||||||
|
format-ethernet = " Wired";
|
||||||
|
format-disconnected = " Off";
|
||||||
|
on-click = "nm-connection-editor";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Battery module (uses sysfs/upower depending on system)
|
||||||
|
battery = {
|
||||||
|
format = "{capacity}% {icon}";
|
||||||
|
tooltip = true;
|
||||||
|
format-icons = {
|
||||||
|
"discharging" = ""; # low battery icon
|
||||||
|
"charging" = ""; # charging icon
|
||||||
|
"full" = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
bluetooth = {
|
||||||
|
format = " {status}";
|
||||||
|
format-disabled = " Off";
|
||||||
|
format-connected = " {device_alias}";
|
||||||
|
on-click = "blueman-manager";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Use Stylix-generated CSS as a base and override icon/text color to a monochrome value
|
||||||
|
style = let
|
||||||
|
importLine =
|
||||||
|
if waybarOut != null
|
||||||
|
then ''@import "${toString waybarOut}";''
|
||||||
|
else ''/* stylix waybar target not available */'';
|
||||||
|
in
|
||||||
|
with colors; ''
|
||||||
|
/* Import the CSS generated by Stylix for Waybar (if available) */
|
||||||
|
${importLine}
|
||||||
|
|
||||||
|
/* Override the color for common modules to a single monochrome color */
|
||||||
|
#workspaces button label,
|
||||||
|
#taskbar button label,
|
||||||
|
#clock,
|
||||||
|
#tray,
|
||||||
|
#network,
|
||||||
|
#pulseaudio,
|
||||||
|
#battery {
|
||||||
|
color: #${base05};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback: target all labels */
|
||||||
|
label {
|
||||||
|
color: #${base05};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prefer a single icon font for consistent monochrome icons */
|
||||||
|
* {
|
||||||
|
font-family: "JetBrainsMono Nerd Font", sans-serif;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# The config file is generated automatically by programs.waybar, so we don't need manual file writes
|
||||||
|
# Users can override by setting programs.waybar.settings directly in their config
|
||||||
|
|
||||||
|
# Keep GUI helper packages but don't autostart applets here.
|
||||||
|
# We prefer Waybar modules (network/pipewire/bluetooth/battery) as the primary
|
||||||
|
# UI so users don't get duplicate tray icons. GUI tools are still available
|
||||||
|
# via `home.packages` and the Waybar on-click actions (pavucontrol, nm-connection-editor,
|
||||||
|
# blueman-manager) will launch them when needed.
|
||||||
|
home.packages = with pkgs; [networkmanagerapplet blueman pavucontrol pasystray];
|
||||||
|
|
||||||
|
# Hide the nm-applet and blueman tray icons by overriding their icon entries
|
||||||
|
# in the user's icon theme with a transparent SVG. This lets the applets run
|
||||||
|
# (providing background/autoconnect and secret-service integration) while Waybar
|
||||||
|
# provides the visible UI with nicer icons.
|
||||||
|
home.file."${config.home.homeDirectory}/.local/share/icons/hicolor/scalable/status/nm-applet.svg".text = ''
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1" viewBox="0 0 1 1"></svg>
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file."${config.home.homeDirectory}/.local/share/icons/hicolor/scalable/status/network-wireless.svg".text = ''
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1" viewBox="0 0 1 1"></svg>
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file."${config.home.homeDirectory}/.local/share/icons/hicolor/scalable/status/blueman.svg".text = ''
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1" viewBox="0 0 1 1"></svg>
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Autostart the applets so they provide background/network/keyring integration
|
||||||
|
# while their icons remain hidden (Waybar shows the label/text UI).
|
||||||
|
home.file."${config.home.homeDirectory}/.config/autostart/nm-applet.desktop".text = ''
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Exec=${pkgs.networkmanagerapplet}/bin/nm-applet
|
||||||
|
Hidden=false
|
||||||
|
X-GNOME-Autostart-enabled=true
|
||||||
|
Name=Network Manager Applet
|
||||||
|
Comment=Autostart nm-applet for network management
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file."${config.home.homeDirectory}/.config/autostart/blueman-manager.desktop".text = ''
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Exec=${pkgs.blueman}/bin/blueman-applet
|
||||||
|
Hidden=false
|
||||||
|
X-GNOME-Autostart-enabled=true
|
||||||
|
Name=Blueman Applet
|
||||||
|
Comment=Autostart blueman for bluetooth management
|
||||||
|
'';
|
||||||
|
}
|
||||||
53
home/panotaka/common/optional/desktops/niri/zenbook-debug.sh
Normal file
53
home/panotaka/common/optional/desktops/niri/zenbook-debug.sh
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Zenbook Duo Debug Script
|
||||||
|
# Run this to diagnose display/keyboard detection issues
|
||||||
|
|
||||||
|
echo "=== Zenbook Duo Debug Info ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "1. USB Devices:"
|
||||||
|
echo " Looking for keyboard (0b05:1b2c)..."
|
||||||
|
lsusb | grep 0b05:1b2c && echo " ✓ Keyboard USB ID found!" || echo " ✗ Keyboard USB ID NOT found"
|
||||||
|
echo ""
|
||||||
|
echo " All ASUS devices:"
|
||||||
|
lsusb | grep -i asus || echo " (none)"
|
||||||
|
echo ""
|
||||||
|
echo " Full lsusb output:"
|
||||||
|
lsusb
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "2. Niri Outputs:"
|
||||||
|
niri msg outputs || echo " ERROR: Could not get niri outputs"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "3. Display Check:"
|
||||||
|
echo " eDP-1 status:"
|
||||||
|
niri msg outputs | grep -A5 "eDP-1" || echo " Not found or off"
|
||||||
|
echo ""
|
||||||
|
echo " eDP-2 status:"
|
||||||
|
niri msg outputs | grep -A5 "eDP-2" || echo " Not found or off"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "4. Systemd Services:"
|
||||||
|
echo " zenbook-autostart:"
|
||||||
|
systemctl --user status zenbook-autostart | grep -E "Active:|Main PID:" || echo " Not running"
|
||||||
|
echo ""
|
||||||
|
echo " zenbook-inotify-monitor:"
|
||||||
|
systemctl --user status zenbook-inotify-monitor | grep -E "Active:|Main PID:" || echo " Not running"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "5. Log Files:"
|
||||||
|
echo " Recent lsusb log:"
|
||||||
|
[ -f /tmp/zenbook-lsusb.log ] && cat /tmp/zenbook-lsusb.log || echo " (no log file yet)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "6. Test Commands:"
|
||||||
|
echo " Try running manually:"
|
||||||
|
echo " - zenbook-normal"
|
||||||
|
echo " - zenbook-top"
|
||||||
|
echo " - zenbook-both"
|
||||||
|
echo " - systemctl --user restart zenbook-inotify-monitor"
|
||||||
|
echo ""
|
||||||
|
echo " View live logs:"
|
||||||
|
echo " - journalctl --user -u zenbook-inotify-monitor -f"
|
||||||
|
echo ""
|
||||||
@@ -1,76 +1,134 @@
|
|||||||
{
|
{pkgs, ...}: let
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
# Configuration variables from your script
|
# Configuration variables from your script
|
||||||
preferred_resolution = "2880x1800";
|
preferred_resolution = "2880x1800";
|
||||||
refresh_rate = "120";
|
refresh_rate = "120";
|
||||||
ui_scale = "1.5";
|
ui_scale = "1.5";
|
||||||
y_offset = "1200";
|
y_offset = "1200";
|
||||||
|
|
||||||
|
# Debug script
|
||||||
|
zenbook-debug = pkgs.writeShellScriptBin "zenbook-debug" ''
|
||||||
|
echo "=== Zenbook Duo Debug Info ==="
|
||||||
|
echo ""
|
||||||
|
echo "1. USB Devices:"
|
||||||
|
echo " Looking for keyboard (0b05:1b2c)..."
|
||||||
|
${pkgs.usbutils}/bin/lsusb | grep 0b05:1b2c && echo " ✓ Keyboard USB ID found!" || echo " ✗ Keyboard USB ID NOT found"
|
||||||
|
echo ""
|
||||||
|
echo " All ASUS devices:"
|
||||||
|
${pkgs.usbutils}/bin/lsusb | grep -i asus || echo " (none)"
|
||||||
|
echo ""
|
||||||
|
echo " Full lsusb output:"
|
||||||
|
${pkgs.usbutils}/bin/lsusb
|
||||||
|
echo ""
|
||||||
|
echo "2. Niri Outputs:"
|
||||||
|
${pkgs.niri}/bin/niri msg outputs || echo " ERROR: Could not get niri outputs"
|
||||||
|
echo ""
|
||||||
|
echo "3. Systemd Services:"
|
||||||
|
systemctl --user status zenbook-autostart 2>&1 | head -3 || echo " Not found"
|
||||||
|
systemctl --user status zenbook-inotify-monitor 2>&1 | head -3 || echo " Not found"
|
||||||
|
echo ""
|
||||||
|
echo "4. Log Files:"
|
||||||
|
[ -f /tmp/zenbook-lsusb.log ] && cat /tmp/zenbook-lsusb.log || echo " (no log file yet)"
|
||||||
|
echo ""
|
||||||
|
echo "5. Manual Test Commands:"
|
||||||
|
echo " - zenbook-normal # Run keyboard detection"
|
||||||
|
echo " - zenbook-top # Force top screen only"
|
||||||
|
echo " - zenbook-both # Force both screens"
|
||||||
|
echo " - journalctl --user -u zenbook-inotify-monitor -f # Watch logs"
|
||||||
|
'';
|
||||||
|
|
||||||
# Inline scripts adapted for niri
|
# Inline scripts adapted for niri
|
||||||
|
# Stage 3: Configuration - applies the display setup
|
||||||
zenbook-top = pkgs.writeShellScriptBin "zenbook-top" ''
|
zenbook-top = pkgs.writeShellScriptBin "zenbook-top" ''
|
||||||
echo "Setting to top screen only"
|
echo "[DEBUG] zenbook-top: Setting to top screen only"
|
||||||
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,0
|
echo "[DEBUG] Configuring eDP-1..."
|
||||||
${pkgs.niri}/bin/niri msg output eDP-2 off
|
${pkgs.niri}/bin/niri msg output eDP-1 on || echo "[ERROR] Failed to turn on eDP-1"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate} || echo "[ERROR] Failed to set eDP-1 mode"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 scale ${ui_scale} || echo "[ERROR] Failed to set eDP-1 scale"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 position set 0 0 || echo "[ERROR] Failed to set eDP-1 position"
|
||||||
|
echo "[DEBUG] Disabling eDP-2..."
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 off || echo "[ERROR] Failed to turn off eDP-2"
|
||||||
|
# Force disable by setting power mode off (if supported)
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 disable 2>/dev/null || echo "[DEBUG] disable command not available, using off"
|
||||||
|
echo "[DEBUG] zenbook-top: Complete"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
zenbook-bottom = pkgs.writeShellScriptBin "zenbook-bottom" ''
|
zenbook-bottom = pkgs.writeShellScriptBin "zenbook-bottom" ''
|
||||||
echo "Setting to bottom screen only"
|
echo "Setting to bottom screen only"
|
||||||
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,0
|
${pkgs.niri}/bin/niri msg output eDP-2 on
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 scale ${ui_scale}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 position set 0 0
|
||||||
${pkgs.niri}/bin/niri msg output eDP-1 off
|
${pkgs.niri}/bin/niri msg output eDP-1 off
|
||||||
|
# Force disable by setting power mode off (if supported)
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 disable 2>/dev/null || echo "[DEBUG] disable command not available, using off"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
zenbook-both = pkgs.writeShellScriptBin "zenbook-both" ''
|
zenbook-both = pkgs.writeShellScriptBin "zenbook-both" ''
|
||||||
echo "Setting to both screens"
|
echo "[DEBUG] zenbook-both: Setting to both screens"
|
||||||
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,0
|
echo "[DEBUG] Configuring eDP-1..."
|
||||||
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,${y_offset}
|
${pkgs.niri}/bin/niri msg output eDP-1 on || echo "[ERROR] Failed to turn on eDP-1"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate} || echo "[ERROR] Failed to set eDP-1 mode"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 scale ${ui_scale} || echo "[ERROR] Failed to set eDP-1 scale"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 position set 0 0 || echo "[ERROR] Failed to set eDP-1 position"
|
||||||
|
echo "[DEBUG] Configuring eDP-2..."
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 on || echo "[ERROR] Failed to turn on eDP-2"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate} || echo "[ERROR] Failed to set eDP-2 mode"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 scale ${ui_scale} || echo "[ERROR] Failed to set eDP-2 scale"
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 position set 0 ${y_offset} || echo "[ERROR] Failed to set eDP-2 position"
|
||||||
|
echo "[DEBUG] zenbook-both: Complete"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
zenbook-left-up = pkgs.writeShellScriptBin "zenbook-left-up" ''
|
zenbook-left-up = pkgs.writeShellScriptBin "zenbook-left-up" ''
|
||||||
echo "Setting to left-right layout"
|
echo "Setting to left-right layout"
|
||||||
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,0
|
${pkgs.niri}/bin/niri msg output eDP-2 on
|
||||||
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position ${y_offset},0
|
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 scale ${ui_scale}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 position set 0 0
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 on
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 scale ${ui_scale}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 position set ${y_offset} 0
|
||||||
'';
|
'';
|
||||||
|
|
||||||
zenbook-right-up = pkgs.writeShellScriptBin "zenbook-right-up" ''
|
zenbook-right-up = pkgs.writeShellScriptBin "zenbook-right-up" ''
|
||||||
echo "Setting to right-left layout"
|
echo "Setting to right-left layout"
|
||||||
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,0
|
${pkgs.niri}/bin/niri msg output eDP-1 on
|
||||||
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position ${y_offset},0
|
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 scale ${ui_scale}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-1 position set 0 0
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 on
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 scale ${ui_scale}
|
||||||
|
${pkgs.niri}/bin/niri msg output eDP-2 position set ${y_offset} 0
|
||||||
'';
|
'';
|
||||||
|
|
||||||
zenbook-normal = pkgs.writeShellScriptBin "zenbook-normal" ''
|
# Stage 2: Detection - determines which configuration to apply
|
||||||
# Check if lid is closed
|
zenbook-detect = pkgs.writeShellScriptBin "zenbook-detect" ''
|
||||||
lid_closed=false
|
# Simple keyboard detection based on the original duo script
|
||||||
if grep -q closed /proc/acpi/button/lid/*/state 2>/dev/null; then
|
echo "[DEBUG] zenbook-detect: Starting detection"
|
||||||
lid_closed=true
|
echo "[DEBUG] Running lsusb to find keyboard..."
|
||||||
fi
|
${pkgs.usbutils}/bin/lsusb > /tmp/zenbook-lsusb.log
|
||||||
|
echo "[DEBUG] lsusb output saved to /tmp/zenbook-lsusb.log"
|
||||||
|
|
||||||
# Check if keyboard is attached (USB dock detection)
|
# Check if keyboard is attached (USB device ID 0b05:1b2c)
|
||||||
keyboard_attached=false
|
if ${pkgs.usbutils}/bin/lsusb | grep -q 0b05:1b2c; then
|
||||||
if ${pkgs.usbutils}/bin/lsusb | grep 0b05:1b2c; then
|
echo "[DEBUG] Keyboard detected (0b05:1b2c found)"
|
||||||
keyboard_attached=true
|
echo "Keyboard attached — top screen only"
|
||||||
fi
|
${zenbook-top}/bin/zenbook-top
|
||||||
|
|
||||||
if [ "$lid_closed" = true ] && [ "$keyboard_attached" = true ]; then
|
|
||||||
echo "Lid closed and keyboard attached — disabling both screens"
|
|
||||||
${pkgs.niri}/bin/niri msg output eDP-1 off
|
|
||||||
${pkgs.niri}/bin/niri msg output eDP-2 off
|
|
||||||
elif [ "$lid_closed" = true ]; then
|
|
||||||
echo "Lid closed — disabling top screen"
|
|
||||||
${pkgs.niri}/bin/niri msg output eDP-1 off
|
|
||||||
${pkgs.niri}/bin/niri msg output eDP-2 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,0
|
|
||||||
elif [ "$keyboard_attached" = true ]; then
|
|
||||||
echo "Keyboard attached — disabling bottom screen"
|
|
||||||
${pkgs.niri}/bin/niri msg output eDP-1 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,0
|
|
||||||
${pkgs.niri}/bin/niri msg output eDP-2 off
|
|
||||||
else
|
else
|
||||||
echo "Normal mode — enabling both screens"
|
echo "[DEBUG] Keyboard NOT detected (0b05:1b2c not found)"
|
||||||
|
echo "[DEBUG] Checking for any ASUS devices..."
|
||||||
|
${pkgs.usbutils}/bin/lsusb | grep -i asus || echo "[DEBUG] No ASUS devices found"
|
||||||
|
echo "Normal mode — both screens"
|
||||||
${zenbook-both}/bin/zenbook-both
|
${zenbook-both}/bin/zenbook-both
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Legacy alias for compatibility
|
||||||
|
zenbook-normal = pkgs.writeShellScriptBin "zenbook-normal" ''
|
||||||
|
${zenbook-detect}/bin/zenbook-detect
|
||||||
|
'';
|
||||||
|
|
||||||
zenbook-toggle = pkgs.writeShellScriptBin "zenbook-toggle" ''
|
zenbook-toggle = pkgs.writeShellScriptBin "zenbook-toggle" ''
|
||||||
# Check current state and toggle
|
# Check current state and toggle
|
||||||
enabled_count=$(${pkgs.niri}/bin/niri msg outputs | grep -c "eDP.*" || echo "0")
|
enabled_count=$(${pkgs.niri}/bin/niri msg outputs | grep -c "eDP.*" || echo "0")
|
||||||
@@ -81,78 +139,50 @@
|
|||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Event-driven display management (from your original script)
|
# Stage 1: Watch service - monitors for changes and triggers detection
|
||||||
zenbook-watch-displays = pkgs.writeShellScriptBin "zenbook-watch-displays" ''
|
zenbook-watch-displays = pkgs.writeShellScriptBin "zenbook-watch-displays" ''
|
||||||
${zenbook-normal}/bin/zenbook-normal
|
echo "[DEBUG] zenbook-watch-displays: Starting"
|
||||||
|
echo "[DEBUG] Running initial detection"
|
||||||
|
# Run initial detection
|
||||||
|
${zenbook-detect}/bin/zenbook-detect
|
||||||
|
|
||||||
|
echo "[DEBUG] Starting USB device monitoring on /dev/bus/usb/*/"
|
||||||
|
# Track last run time to debounce rapid-fire events
|
||||||
|
last_run=0
|
||||||
|
debounce_seconds=3
|
||||||
|
|
||||||
|
# Watch for USB device changes (keyboard attach/detach)
|
||||||
while ${pkgs.inotify-tools}/bin/inotifywait -e attrib /dev/bus/usb/*/; do
|
while ${pkgs.inotify-tools}/bin/inotifywait -e attrib /dev/bus/usb/*/; do
|
||||||
${zenbook-normal}/bin/zenbook-normal
|
current_time=$(date +%s)
|
||||||
|
time_diff=$((current_time - last_run))
|
||||||
|
|
||||||
|
if [ $time_diff -ge $debounce_seconds ]; then
|
||||||
|
echo "[DEBUG] USB device change detected at $(date) (debounced)"
|
||||||
|
sleep 0.5
|
||||||
|
${zenbook-detect}/bin/zenbook-detect
|
||||||
|
last_run=$current_time
|
||||||
|
else
|
||||||
|
echo "[DEBUG] USB device change ignored (debounce: $time_diff < $debounce_seconds seconds)"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Legacy wrapper - calls detect directly
|
||||||
zenbook-set-displays = pkgs.writeShellScriptBin "zenbook-set-displays" ''
|
zenbook-set-displays = pkgs.writeShellScriptBin "zenbook-set-displays" ''
|
||||||
sleep 1
|
sleep 0.5
|
||||||
${zenbook-normal}/bin/zenbook-normal
|
${zenbook-detect}/bin/zenbook-detect
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Enhanced lid monitoring with multiple detection methods
|
# Simplified auto-run display setup on startup (based on original duo approach)
|
||||||
zenbook-lid-monitor = pkgs.writeShellScriptBin "zenbook-lid-monitor" ''
|
|
||||||
echo "Starting comprehensive lid monitoring..."
|
|
||||||
|
|
||||||
# Method 1: Monitor ACPI events
|
|
||||||
(${pkgs.acpi}/bin/acpi_listen | while read event; do
|
|
||||||
if echo "$event" | grep -q "button/lid"; then
|
|
||||||
echo "ACPI lid event detected: $event"
|
|
||||||
sleep 0.5 && ${zenbook-set-displays}/bin/zenbook-set-displays
|
|
||||||
fi
|
|
||||||
done) &
|
|
||||||
|
|
||||||
# Method 2: Poll lid state file directly
|
|
||||||
(while true; do
|
|
||||||
if [ -f /proc/acpi/button/lid/LID0/state ] || [ -f /proc/acpi/button/lid/LID/state ]; then
|
|
||||||
current_state=$(cat /proc/acpi/button/lid/*/state 2>/dev/null | head -1)
|
|
||||||
if [ "$current_state" != "$previous_state" ]; then
|
|
||||||
echo "Lid state changed: $current_state"
|
|
||||||
previous_state="$current_state"
|
|
||||||
sleep 0.5 && ${zenbook-set-displays}/bin/zenbook-set-displays
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
sleep 2
|
|
||||||
done) &
|
|
||||||
|
|
||||||
# Method 3: Monitor systemd logind events
|
|
||||||
(${pkgs.systemd}/bin/journalctl -f --user -u "*" | while read line; do
|
|
||||||
if echo "$line" | grep -i "lid\|suspend\|resume"; then
|
|
||||||
echo "Systemd event: $line"
|
|
||||||
sleep 1 && ${zenbook-set-displays}/bin/zenbook-set-displays
|
|
||||||
fi
|
|
||||||
done) &
|
|
||||||
|
|
||||||
wait
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Auto-run display setup on startup
|
|
||||||
zenbook-autostart = pkgs.writeShellScriptBin "zenbook-autostart" ''
|
zenbook-autostart = pkgs.writeShellScriptBin "zenbook-autostart" ''
|
||||||
# Initial display setup
|
|
||||||
echo "Running initial display setup"
|
echo "Running initial display setup"
|
||||||
${zenbook-set-displays}/bin/zenbook-set-displays
|
sleep 1
|
||||||
|
${zenbook-detect}/bin/zenbook-detect
|
||||||
# Wait a moment for system to stabilize
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# Run display setup again to ensure proper configuration
|
|
||||||
echo "Running secondary display setup"
|
|
||||||
${zenbook-set-displays}/bin/zenbook-set-displays
|
|
||||||
|
|
||||||
# Start USB monitoring in background
|
|
||||||
echo "Starting USB monitoring for display changes"
|
|
||||||
${zenbook-watch-displays}/bin/zenbook-watch-displays &
|
|
||||||
|
|
||||||
# Start enhanced lid monitoring
|
|
||||||
echo "Starting enhanced lid monitoring"
|
|
||||||
${zenbook-lid-monitor}/bin/zenbook-lid-monitor &
|
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
# Zenbook dual-screen display configuration for niri
|
# Zenbook dual-screen display configuration for niri
|
||||||
|
# NOTE: We only configure eDP-1 statically and let scripts manage eDP-2 dynamically
|
||||||
|
# This allows the off command to actually work
|
||||||
programs.niri.settings = {
|
programs.niri.settings = {
|
||||||
outputs = {
|
outputs = {
|
||||||
"eDP-1" = {
|
"eDP-1" = {
|
||||||
@@ -168,62 +198,95 @@ in {
|
|||||||
};
|
};
|
||||||
variable-refresh-rate = true;
|
variable-refresh-rate = true;
|
||||||
};
|
};
|
||||||
"eDP-2" = {
|
# eDP-2 is managed dynamically by zenbook-detect scripts
|
||||||
mode = {
|
|
||||||
width = 2880;
|
|
||||||
height = 1800;
|
|
||||||
refresh = 120.0;
|
|
||||||
};
|
};
|
||||||
scale = 1.5;
|
|
||||||
position = {
|
# Keybind to run zenbook-detect via UWSM
|
||||||
x = 0;
|
binds."Mod+Z".action.spawn = ["uwsm" "app" "--" "${zenbook-detect}/bin/zenbook-detect"];
|
||||||
y = 1200;
|
|
||||||
};
|
};
|
||||||
variable-refresh-rate = true;
|
|
||||||
|
# Migrate to systemd user services for UWSM integration
|
||||||
|
systemd.user.services = {
|
||||||
|
# Initial display setup
|
||||||
|
zenbook-autostart = {
|
||||||
|
Unit = {
|
||||||
|
Description = "ZenBook Duo Initial Display Setup";
|
||||||
|
After = ["graphical-session.target"];
|
||||||
|
PartOf = ["graphical-session.target"];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${zenbook-autostart}/bin/zenbook-autostart";
|
||||||
|
RemainAfterExit = false;
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = ["graphical-session.target"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Auto-start the event-driven display management
|
# Secondary display setup after delay
|
||||||
spawn-at-startup = [
|
zenbook-delayed-setup = {
|
||||||
{
|
Unit = {
|
||||||
command = ["${zenbook-autostart}/bin/zenbook-autostart"];
|
Description = "ZenBook Duo Delayed Display Setup";
|
||||||
}
|
After = ["graphical-session.target" "zenbook-autostart.service"];
|
||||||
{
|
PartOf = ["graphical-session.target"];
|
||||||
command = ["sh" "-c" "sleep 5 && ${zenbook-set-displays}/bin/zenbook-set-displays"];
|
};
|
||||||
}
|
Service = {
|
||||||
{
|
Type = "oneshot";
|
||||||
command = ["sh" "-c" "while ${pkgs.inotify-tools}/bin/inotifywait -e modify /sys/class/drm/*/status 2>/dev/null; do sleep 1 && ${zenbook-set-displays}/bin/zenbook-set-displays; done"];
|
ExecStartPre = "${pkgs.coreutils}/bin/sleep 5";
|
||||||
}
|
ExecStart = "${zenbook-set-displays}/bin/zenbook-set-displays";
|
||||||
{
|
RemainAfterExit = false;
|
||||||
command = ["sh" "-c" "${pkgs.udev}/bin/udevadm monitor --udev --subsystem-match=drm | while read line; do if echo \"$line\" | grep -q \"change\"; then sleep 2 && ${zenbook-set-displays}/bin/zenbook-set-displays; fi; done"];
|
};
|
||||||
}
|
Install = {
|
||||||
];
|
WantedBy = ["graphical-session.target"];
|
||||||
|
};
|
||||||
# Keybind to run zenbook-set-displays
|
|
||||||
binds."Mod+Z".action.spawn = ["${zenbook-set-displays}/bin/zenbook-set-displays"];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Hook into swayidle for unlock/resume events (if using swayidle)
|
# Monitor USB device changes for keyboard attach/detach
|
||||||
services.swayidle.timeouts = lib.mkAfter [
|
zenbook-inotify-monitor = {
|
||||||
{
|
Unit = {
|
||||||
timeout = 1;
|
Description = "ZenBook Duo USB Device Monitor";
|
||||||
command = "${zenbook-set-displays}/bin/zenbook-set-displays";
|
After = ["graphical-session.target"];
|
||||||
resumeCommand = "${zenbook-set-displays}/bin/zenbook-set-displays";
|
PartOf = ["graphical-session.target"];
|
||||||
}
|
};
|
||||||
];
|
Service = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${zenbook-watch-displays}/bin/zenbook-watch-displays";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "5";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = ["graphical-session.target"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# DISABLED: udev monitor - not needed with inotify approach
|
||||||
|
# zenbook-udev-monitor service removed to prevent conflicts
|
||||||
|
};
|
||||||
|
|
||||||
|
# DISABLED: swayidle hook was running zenbook-detect every second, causing conflicts
|
||||||
|
# The zenbook-inotify-monitor service handles USB detection automatically
|
||||||
|
# services.swayidle.timeouts = lib.mkAfter [
|
||||||
|
# {
|
||||||
|
# timeout = 1;
|
||||||
|
# command = "${zenbook-detect}/bin/zenbook-detect";
|
||||||
|
# resumeCommand = "${zenbook-detect}/bin/zenbook-detect";
|
||||||
|
# }
|
||||||
|
# ];
|
||||||
|
|
||||||
# Add the scripts to home packages
|
# Add the scripts to home packages
|
||||||
home.packages = [
|
home.packages = [
|
||||||
|
zenbook-debug
|
||||||
zenbook-top
|
zenbook-top
|
||||||
zenbook-bottom
|
zenbook-bottom
|
||||||
zenbook-both
|
zenbook-both
|
||||||
zenbook-left-up
|
zenbook-left-up
|
||||||
zenbook-right-up
|
zenbook-right-up
|
||||||
|
zenbook-detect
|
||||||
zenbook-normal
|
zenbook-normal
|
||||||
zenbook-toggle
|
zenbook-toggle
|
||||||
zenbook-watch-displays
|
zenbook-watch-displays
|
||||||
zenbook-set-displays
|
zenbook-set-displays
|
||||||
zenbook-autostart
|
zenbook-autostart
|
||||||
zenbook-lid-monitor
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,23 @@
|
|||||||
|
|
||||||
programs.niri.enable = true;
|
programs.niri.enable = true;
|
||||||
|
|
||||||
|
# Enable UWSM (Universal Wayland Session Manager) for better session management
|
||||||
|
# See docs/uwsm-niri-integration.md for usage and migration guide
|
||||||
|
programs.uwsm = {
|
||||||
|
enable = true;
|
||||||
|
waylandCompositors = {
|
||||||
|
niri = {
|
||||||
|
prettyName = "Niri";
|
||||||
|
comment = "Niri scrollable-tiling Wayland compositor managed by UWSM";
|
||||||
|
binPath = "/run/current-system/sw/bin/niri-session";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# UWSM provides better environment variable inheritance and systemd integration
|
||||||
|
# All startup applications are now managed via systemd.user.services with
|
||||||
|
# WantedBy=["graphical-session.target"] in the home-manager configuration
|
||||||
|
|
||||||
# Use KDE portal instead of GNOME for better KDE integration
|
# Use KDE portal instead of GNOME for better KDE integration
|
||||||
xdg.portal = {
|
xdg.portal = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
"hosts/common/optional/services/ollama.nix"
|
"hosts/common/optional/services/ollama.nix"
|
||||||
"hosts/common/optional/services/docker.nix"
|
"hosts/common/optional/services/docker.nix"
|
||||||
"hosts/common/optional/audio.nix" # pipewire and cli controls
|
"hosts/common/optional/audio.nix" # pipewire and cli controls
|
||||||
"hosts/common/optional/gnome.nix"
|
"hosts/common/optional/niri.nix"
|
||||||
"hosts/common/optional/gdm.nix"
|
"hosts/common/optional/gdm.nix"
|
||||||
"hosts/common/optional/flatpak.nix"
|
"hosts/common/optional/flatpak.nix"
|
||||||
"hosts/common/optional/thermal-management.nix"
|
"hosts/common/optional/thermal-management.nix"
|
||||||
|
|||||||
@@ -33,29 +33,31 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.user.services.watchDisplays = {
|
# DISABLED: Old gnome-monitor-config approach - now using niri-native zenbook-screen.nix
|
||||||
description = "set screens on keyboard event";
|
# systemd.user.services.watchDisplays = {
|
||||||
wantedBy = ["default.target"];
|
# description = "set screens on keyboard event";
|
||||||
after = ["graphical-session.target"];
|
# wantedBy = ["default.target"];
|
||||||
|
# after = ["graphical-session.target"];
|
||||||
|
|
||||||
path = [pkgs.gnome-monitor-config pkgs.usbutils pkgs.inotify-tools];
|
# path = [pkgs.gnome-monitor-config pkgs.usbutils pkgs.inotify-tools];
|
||||||
serviceConfig = {
|
# serviceConfig = {
|
||||||
preStart = "${patchedDuoScript} normal";
|
# preStart = "${patchedDuoScript} normal";
|
||||||
ExecStart = "${patchedDuoScript} watch-displays";
|
# ExecStart = "${patchedDuoScript} watch-displays";
|
||||||
Restart = "always";
|
# Restart = "always";
|
||||||
RestartSec = 5;
|
# RestartSec = 5;
|
||||||
};
|
# };
|
||||||
};
|
# };
|
||||||
|
|
||||||
systemd.user.services.watchRotation = {
|
# DISABLED: Old rotation script - conflicts with niri
|
||||||
description = "rotate screens";
|
# systemd.user.services.watchRotation = {
|
||||||
wantedBy = ["default.target"];
|
# description = "rotate screens";
|
||||||
after = ["graphical-session.target"];
|
# wantedBy = ["default.target"];
|
||||||
path = [pkgs.gnome-monitor-config pkgs.iio-sensor-proxy];
|
# after = ["graphical-session.target"];
|
||||||
serviceConfig = {
|
# path = [pkgs.gnome-monitor-config pkgs.iio-sensor-proxy];
|
||||||
ExecStart = "${patchedDuoScript} watch-rotation";
|
# serviceConfig = {
|
||||||
Restart = "always";
|
# ExecStart = "${patchedDuoScript} watch-rotation";
|
||||||
RestartSec = 5;
|
# Restart = "always";
|
||||||
};
|
# RestartSec = 5;
|
||||||
};
|
# };
|
||||||
|
# };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,27 +14,34 @@
|
|||||||
|
|
||||||
boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usbhid"];
|
boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usbhid"];
|
||||||
boot.initrd.kernelModules = [];
|
boot.initrd.kernelModules = [];
|
||||||
boot.kernelPackages = pkgs.linuxPackages_zen;
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
boot.kernelModules = ["kvm-intel" "evdi" "intel_vpu"];
|
boot.kernelModules = ["kvm-intel" "evdi" "intel_vpu"];
|
||||||
boot.kernelParams = [
|
boot.kernelParams = [
|
||||||
"i915.enable_guc=3"
|
"i915.enable_guc=3"
|
||||||
#"i915.enable_psr=0"
|
#"i915.enable_psr=0"
|
||||||
|
# Suppress rfkill/WLAN toggle events from asus-wmi
|
||||||
|
"asus_nb_wmi.wapf=4"
|
||||||
];
|
];
|
||||||
boot.kernelPatches = [
|
boot.kernelPatches = [
|
||||||
/*
|
# Both patches are malformed/outdated and don't apply to current kernel versions
|
||||||
{
|
# Using alternative approach with extraModprobeConfig below
|
||||||
name = "zenbook-asus-wmi";
|
|
||||||
patch = ./zenbook-asus-wmi.patch;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
name = "zenbook-duo-suppress-rfkill-on-kbd-connect";
|
|
||||||
patch = ./zenbook-duo-suppress-rfkill-on-kbd-connect.patch;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Suppress rfkill events from keyboard attach/detach
|
||||||
|
services.udev.extraRules = ''
|
||||||
|
# Zenbook Duo - suppress rfkill/airplane mode key events on keyboard connect/disconnect
|
||||||
|
SUBSYSTEM=="input", ATTRS{name}=="Asus WMI hotkeys", ENV{KEY_RFKILL}="0", ENV{KEY_WLAN}="0"
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Hardware database override to disable rfkill key on ASUS WMI hotkeys
|
||||||
|
services.udev.extraHwdb = ''
|
||||||
|
evdev:name:Asus WMI hotkeys:dmi:*
|
||||||
|
KEYBOARD_KEY_88=unknown
|
||||||
|
KEYBOARD_KEY_5d=unknown
|
||||||
|
KEYBOARD_KEY_5e=unknown
|
||||||
|
KEYBOARD_KEY_5f=unknown
|
||||||
|
'';
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
# still possible to use this option, but it's recommended to use it in conjunction
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
|||||||
Reference in New Issue
Block a user