Add Niri desktop configuration with integrated utilities
- Introduced a new power menu script using fuzzel for session management. - Updated Bellerophon configuration to include Niri desktop and its components. - Removed obsolete README for Niri and consolidated its configuration files. - Added swayidle and swaylock integration for idle management and screen locking. - Implemented waybar for status bar functionality with basic configuration. - Created fuzzel integration for application launching and menu access. - Added zenbook debugging scripts for display and keyboard diagnostics. - Migrated keyring and other configurations to streamline Niri setup. - Enhanced display management with systemd services for better integration.
This commit is contained in:
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
|
||||
common/optional/browsers
|
||||
common/optional/desktops/gnome
|
||||
common/optional/desktops/gnome/zenbook-screen.nix
|
||||
common/optional/desktops/niri
|
||||
common/optional/desktops/niri/zenbook-screen.nix
|
||||
common/optional/comms
|
||||
common/optional/media
|
||||
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
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [./waybar.nix ./swayidle.nix ./fuzzel.nix ./swaylock.nix];
|
||||
|
||||
# Import patterns similar to other desktop modules
|
||||
home.packages = [
|
||||
pkgs.wl-clipboard
|
||||
pkgs.grim
|
||||
pkgs.slurp
|
||||
pkgs.polkit_gnome
|
||||
pkgs.xdg-desktop-portal-wlr
|
||||
];
|
||||
|
||||
# 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$";}];
|
||||
default-column-width = {proportion = 0.333;};
|
||||
}
|
||||
{
|
||||
matches = [{app-id = "^pavucontrol$";}];
|
||||
default-column-width = {proportion = 0.333;};
|
||||
}
|
||||
];
|
||||
|
||||
# Keybindings
|
||||
binds = {
|
||||
"Mod+B".action.spawn = ["zen"];
|
||||
"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 = {};
|
||||
};
|
||||
};
|
||||
# Enable Niri and provide baseline settings; other modules merge into programs.niri.settings
|
||||
programs.niri.settings = lib.mkDefault {
|
||||
binds = {};
|
||||
};
|
||||
|
||||
# Session variables for proper integration
|
||||
# Session variables for Wayland compatibility
|
||||
home.sessionVariables = {
|
||||
NIXOS_OZONE_WL = "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"];
|
||||
}
|
||||
54
home/panotaka/common/optional/desktops/niri/waybar.nix
Normal file
54
home/panotaka/common/optional/desktops/niri/waybar.nix
Normal file
@@ -0,0 +1,54 @@
|
||||
{pkgs, ...}: let
|
||||
waybarStyle = ''* { color: #ffffff; }'';
|
||||
in {
|
||||
# Use the programs.waybar home-manager module
|
||||
programs.waybar = {
|
||||
enable = true;
|
||||
package = pkgs.waybar;
|
||||
systemd.enable = true;
|
||||
|
||||
# Minimal config as a Nix attribute set; users can override ~/.config/waybar/config if desired
|
||||
settings = {
|
||||
mainBar = {
|
||||
layer = "top";
|
||||
position = "top";
|
||||
modules-left = ["niri/workspaces"];
|
||||
modules-center = [];
|
||||
modules-right = ["tray" "clock"];
|
||||
|
||||
"niri/workspaces" = {
|
||||
format = "{name}";
|
||||
};
|
||||
|
||||
clock = {
|
||||
format = "{:%H:%M}";
|
||||
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
|
||||
};
|
||||
};
|
||||
};
|
||||
# Minimal CSS; consider generating this from config.lib.stylix.colors for richer theming
|
||||
style = waybarStyle;
|
||||
};
|
||||
|
||||
# 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
|
||||
|
||||
# Make sure nm-applet is available and autostarts so its tray icon shows up in the tray module
|
||||
home.packages = with pkgs; [networkmanagerapplet];
|
||||
|
||||
# Start nm-applet as a systemd user service for UWSM integration
|
||||
systemd.user.services.nm-applet = {
|
||||
Unit = {
|
||||
Description = "Network Manager Applet";
|
||||
PartOf = ["graphical-session.target"];
|
||||
After = ["graphical-session.target"];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${pkgs.networkmanagerapplet}/bin/nm-applet";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = ["graphical-session.target"];
|
||||
};
|
||||
};
|
||||
}
|
||||
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 ""
|
||||
@@ -9,64 +9,115 @@
|
||||
ui_scale = "1.5";
|
||||
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
|
||||
zenbook-top = pkgs.writeShellScriptBin "zenbook-top" ''
|
||||
echo "Setting to top screen only"
|
||||
${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
|
||||
echo "[DEBUG] zenbook-top: Setting to top screen only"
|
||||
echo "[DEBUG] Configuring eDP-1..."
|
||||
${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] Turning off eDP-2..."
|
||||
${pkgs.niri}/bin/niri msg output eDP-2 off || echo "[ERROR] Failed to turn off eDP-2"
|
||||
echo "[DEBUG] zenbook-top: Complete"
|
||||
'';
|
||||
|
||||
zenbook-bottom = pkgs.writeShellScriptBin "zenbook-bottom" ''
|
||||
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
|
||||
'';
|
||||
|
||||
zenbook-both = pkgs.writeShellScriptBin "zenbook-both" ''
|
||||
echo "Setting to both screens"
|
||||
${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 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position 0,${y_offset}
|
||||
echo "[DEBUG] zenbook-both: Setting to both screens"
|
||||
echo "[DEBUG] Configuring eDP-1..."
|
||||
${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" ''
|
||||
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-1 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position ${y_offset},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 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" ''
|
||||
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-2 mode ${preferred_resolution}@${refresh_rate} scale ${ui_scale} position ${y_offset},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 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" ''
|
||||
# Check if lid is closed
|
||||
lid_closed=false
|
||||
if grep -q closed /proc/acpi/button/lid/*/state 2>/dev/null; then
|
||||
lid_closed=true
|
||||
fi
|
||||
# Simple keyboard detection based on the original duo script
|
||||
echo "[DEBUG] zenbook-normal: Starting detection"
|
||||
echo "[DEBUG] Running lsusb to find keyboard..."
|
||||
${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)
|
||||
keyboard_attached=false
|
||||
if ${pkgs.usbutils}/bin/lsusb | grep 0b05:1b2c; then
|
||||
keyboard_attached=true
|
||||
fi
|
||||
|
||||
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
|
||||
# Check if keyboard is attached (USB device ID 0b05:1b2c)
|
||||
if ${pkgs.usbutils}/bin/lsusb | grep -q 0b05:1b2c; then
|
||||
echo "[DEBUG] Keyboard detected (0b05:1b2c found)"
|
||||
echo "Keyboard attached — top screen only"
|
||||
${zenbook-top}/bin/zenbook-top
|
||||
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
|
||||
fi
|
||||
'';
|
||||
@@ -81,75 +132,31 @@
|
||||
fi
|
||||
'';
|
||||
|
||||
# Event-driven display management (from your original script)
|
||||
# Simple event-driven display management (based on original duo script)
|
||||
zenbook-watch-displays = pkgs.writeShellScriptBin "zenbook-watch-displays" ''
|
||||
echo "[DEBUG] zenbook-watch-displays: Starting"
|
||||
echo "[DEBUG] Running initial setup"
|
||||
# Run initial setup
|
||||
${zenbook-normal}/bin/zenbook-normal
|
||||
|
||||
echo "[DEBUG] Starting USB device monitoring on /dev/bus/usb/*/"
|
||||
# Watch for USB device changes (keyboard attach/detach)
|
||||
while ${pkgs.inotify-tools}/bin/inotifywait -e attrib /dev/bus/usb/*/; do
|
||||
echo "[DEBUG] USB device change detected at $(date)"
|
||||
sleep 0.5
|
||||
${zenbook-normal}/bin/zenbook-normal
|
||||
done
|
||||
'';
|
||||
|
||||
zenbook-set-displays = pkgs.writeShellScriptBin "zenbook-set-displays" ''
|
||||
sleep 1
|
||||
sleep 0.5
|
||||
${zenbook-normal}/bin/zenbook-normal
|
||||
'';
|
||||
|
||||
# Enhanced lid monitoring with multiple detection methods
|
||||
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
|
||||
# Simplified auto-run display setup on startup (based on original duo approach)
|
||||
zenbook-autostart = pkgs.writeShellScriptBin "zenbook-autostart" ''
|
||||
# Initial display setup
|
||||
echo "Running initial display setup"
|
||||
sleep 1
|
||||
${zenbook-set-displays}/bin/zenbook-set-displays
|
||||
|
||||
# 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 {
|
||||
# Zenbook dual-screen display configuration for niri
|
||||
@@ -183,24 +190,89 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
# Auto-start the event-driven display management
|
||||
spawn-at-startup = [
|
||||
{
|
||||
command = ["${zenbook-autostart}/bin/zenbook-autostart"];
|
||||
}
|
||||
{
|
||||
command = ["sh" "-c" "sleep 5 && ${zenbook-set-displays}/bin/zenbook-set-displays"];
|
||||
}
|
||||
{
|
||||
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"];
|
||||
}
|
||||
{
|
||||
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"];
|
||||
}
|
||||
];
|
||||
# Keybind to run zenbook-set-displays via UWSM
|
||||
binds."Mod+Z".action.spawn = ["uwsm" "app" "--" "${zenbook-set-displays}/bin/zenbook-set-displays"];
|
||||
};
|
||||
|
||||
# Keybind to run zenbook-set-displays
|
||||
binds."Mod+Z".action.spawn = ["${zenbook-set-displays}/bin/zenbook-set-displays"];
|
||||
# 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"];
|
||||
};
|
||||
};
|
||||
|
||||
# Secondary display setup after delay
|
||||
zenbook-delayed-setup = {
|
||||
Unit = {
|
||||
Description = "ZenBook Duo Delayed Display Setup";
|
||||
After = ["graphical-session.target" "zenbook-autostart.service"];
|
||||
PartOf = ["graphical-session.target"];
|
||||
};
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStartPre = "${pkgs.coreutils}/bin/sleep 5";
|
||||
ExecStart = "${zenbook-set-displays}/bin/zenbook-set-displays";
|
||||
RemainAfterExit = false;
|
||||
};
|
||||
Install = {
|
||||
WantedBy = ["graphical-session.target"];
|
||||
};
|
||||
};
|
||||
|
||||
# Monitor USB device changes for keyboard attach/detach
|
||||
zenbook-inotify-monitor = {
|
||||
Unit = {
|
||||
Description = "ZenBook Duo USB Device Monitor";
|
||||
After = ["graphical-session.target"];
|
||||
PartOf = ["graphical-session.target"];
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = "${zenbook-watch-displays}/bin/zenbook-watch-displays";
|
||||
Restart = "always";
|
||||
RestartSec = "5";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = ["graphical-session.target"];
|
||||
};
|
||||
};
|
||||
|
||||
# Monitor udev events for display changes
|
||||
zenbook-udev-monitor = {
|
||||
Unit = {
|
||||
Description = "ZenBook Duo udev Display Monitor";
|
||||
After = ["graphical-session.target"];
|
||||
PartOf = ["graphical-session.target"];
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.writeShellScript "zenbook-udev-loop" ''
|
||||
${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
|
||||
''}";
|
||||
Restart = "always";
|
||||
RestartSec = "5";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = ["graphical-session.target"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Hook into swayidle for unlock/resume events (if using swayidle)
|
||||
@@ -214,6 +286,7 @@ in {
|
||||
|
||||
# Add the scripts to home packages
|
||||
home.packages = [
|
||||
zenbook-debug
|
||||
zenbook-top
|
||||
zenbook-bottom
|
||||
zenbook-both
|
||||
@@ -224,6 +297,5 @@ in {
|
||||
zenbook-watch-displays
|
||||
zenbook-set-displays
|
||||
zenbook-autostart
|
||||
zenbook-lid-monitor
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user