diff --git a/apply-theme.sh b/apply-theme.sh index 981ac91..4a60be7 100755 --- a/apply-theme.sh +++ b/apply-theme.sh @@ -55,6 +55,7 @@ USER_FILES=( "qt-themes/cyberqueer/cyberqueer.conf|$HOME/.config/qt6ct/colors/cyberqueer.conf" "qt-themes/cyberqueer/style-plugin/CyberQueerStyle.cpp|$DOTFILES/qt-themes/cyberqueer/style-plugin/CyberQueerStyle.cpp" "qt-themes/cyberqueer/hyprpolkitagent-qt.conf|$HOME/.config/systemd/user/hyprpolkitagent.service.d/qt-theme.conf" + "desktopenvs/niri/niri/config.kdl|$HOME/.config/niri/config.kdl" ) # System-owned paths — sed is run via sudo diff --git a/desktopenvs/niri/CRT b/desktopenvs/niri/CRT new file mode 120000 index 0000000..b431cd8 --- /dev/null +++ b/desktopenvs/niri/CRT @@ -0,0 +1 @@ +../hyprlua/CRT \ No newline at end of file diff --git a/desktopenvs/niri/Vencord b/desktopenvs/niri/Vencord new file mode 120000 index 0000000..69fc2b7 --- /dev/null +++ b/desktopenvs/niri/Vencord @@ -0,0 +1 @@ +../hyprlua/Vencord \ No newline at end of file diff --git a/desktopenvs/niri/alacritty b/desktopenvs/niri/alacritty new file mode 120000 index 0000000..9df6d1e --- /dev/null +++ b/desktopenvs/niri/alacritty @@ -0,0 +1 @@ +../hyprlua/alacritty \ No newline at end of file diff --git a/desktopenvs/niri/btop b/desktopenvs/niri/btop new file mode 120000 index 0000000..f8ed453 --- /dev/null +++ b/desktopenvs/niri/btop @@ -0,0 +1 @@ +../hyprlua/btop \ No newline at end of file diff --git a/desktopenvs/niri/config-updater/update-configs.sh b/desktopenvs/niri/config-updater/update-configs.sh new file mode 120000 index 0000000..bdd49f1 --- /dev/null +++ b/desktopenvs/niri/config-updater/update-configs.sh @@ -0,0 +1 @@ +../../hyprlua/config-updater/update-configs.sh \ No newline at end of file diff --git a/desktopenvs/niri/config-updater/updater.conf b/desktopenvs/niri/config-updater/updater.conf new file mode 100644 index 0000000..6e2dfed --- /dev/null +++ b/desktopenvs/niri/config-updater/updater.conf @@ -0,0 +1,37 @@ +# Config updater — defines which dotfiles configs are deployed to ~/.config +# +# SOURCE_BASE base directory containing all configs in the dotfiles +# +# config copy SOURCE_BASE/ to ~/.config/ +# flat copy contents of SOURCE_BASE/ directly into ~/.config/ +# ignore present in source but intentionally not managed here + +SOURCE_BASE = ~/Dotfiles/desktopenvs/niri + +# ── deployed as ~/.config/ ───────────────────────────────────────────── +config alacritty +config btop +config dunst +config gtk-3.0 +config kitty +config mimeapps.list +config niri +config nwg-drawer +config nwg-panel +config scripts +config ulauncher +config vicinae +config walker +config waybar +config wofi +config xfce4 + +# ── intentionally not managed here ─────────────────────────────────────────── +ignore config-updater # the updater itself +ignore CRT # referenced from dotfiles path directly +ignore eww # eww bar variant selected and installed separately +ignore eww-nobattery +ignore eww-touch +ignore greetd-tuigreet # deployed to /etc/greetd/ at install time +ignore spicetify # managed separately +ignore Vencord # managed separately diff --git a/desktopenvs/niri/dunst b/desktopenvs/niri/dunst new file mode 120000 index 0000000..21cc558 --- /dev/null +++ b/desktopenvs/niri/dunst @@ -0,0 +1 @@ +../hyprlua/dunst \ No newline at end of file diff --git a/desktopenvs/niri/eww-nobattery/eww.scss b/desktopenvs/niri/eww-nobattery/eww.scss new file mode 120000 index 0000000..63fda1e --- /dev/null +++ b/desktopenvs/niri/eww-nobattery/eww.scss @@ -0,0 +1 @@ +../../hyprlua/eww/eww.scss \ No newline at end of file diff --git a/desktopenvs/niri/eww-nobattery/eww.yuck b/desktopenvs/niri/eww-nobattery/eww.yuck new file mode 100644 index 0000000..b90d1dc --- /dev/null +++ b/desktopenvs/niri/eww-nobattery/eww.yuck @@ -0,0 +1,92 @@ +(defwindow bar [monitor] + :monitor monitor + :class "ewwbar" + :windowtype "dock" + :geometry (geometry :x "0%" + :y "1%" + :width "99%" + :height "20px" + :anchor "top center") + :exclusive true + (bar :monitor_ monitor)) + +(defwidget bar [monitor_] + (centerbox :orientation "h" + (winsworks :monitor monitor_) + (music) + (sidestuff))) + +(defwidget winsworks [monitor] + (box :orientation "h" :space-evenly false :halign "start" + (workspaceWidget) + (button :onclick "~/.config/scripts/drawer.sh" :class "music" {" ${activewindow}"}) + ) +) + +(defwidget sidestuff [] + (box :class "sidestuff" :orientation "h" :space-evenly false :halign "end" + (box :class "music" {"󰛳 ${IP}"}) + (metric :label "󰓃" + :value volume + :onchange "pactl set-sink-volume @DEFAULT_SINK@ {}%" + :onclick "killall pavucontrol || pavucontrol") + (box + :tooltip {disks} + (metric :label "" + :value {round((1 - (EWW_DISK["/"].free / EWW_DISK["/"].total)) * 100, 0)} + :onchange "" + :onclick "")) + (clock) + (systray :class "music" :orientation "h" :spacing 2 :space-evenly true) + )) + +(defwidget music [] + (button :class "music" + :orientation "h" + :space-evenly false + :halign "center" + :onclick "~/.config/scripts/playpause.sh" + {music != "" ? " ${music}" : " None"})) + +(defwidget metric [label value onchange onclick] + (box :orientation "h" + :class "metric" + :space-evenly false + (button :class "label" :onclick onclick label) + (scale :min 0 + :max 101 + :active {onchange != ""} + :value value + :onchange onchange))) + +(deflisten workspace-niri "~/.config/scripts/workspace") +(defwidget workspaceWidget [] + (eventbox + :onscroll "niri msg action $(echo {} | sed 's/up/focus-workspace-up/;s/down/focus-workspace-down/')" + (literal :content workspace-niri))) + +(defpoll music :interval "0.5s" + "~/.config/scripts/playerget") + +(defpoll activewindow :interval "0.5s" + "~/.config/scripts/activewindow") + +(defpoll IP :interval "5s" + "~/.config/scripts/ip") + +(defpoll volume :interval "0.5s" + "~/.config/scripts/getvol") + +(defpoll time :interval "1s" + "date '+%H:%M:%S|%d.%m.%Y'") + +(defwidget clock [] + (box :class "clock" + :tooltip {calender} + (label :text {"${time}"}))) + +(defpoll calender :interval "600s" + "~/.config/scripts/calender-fix.sh") + +(defpoll disks :interval "600s" + "~/.config/scripts/dysk-phydisks.sh") diff --git a/desktopenvs/niri/eww-touch/eww.scss b/desktopenvs/niri/eww-touch/eww.scss new file mode 120000 index 0000000..9827344 --- /dev/null +++ b/desktopenvs/niri/eww-touch/eww.scss @@ -0,0 +1 @@ +../../hyprlua/eww-touch/eww.scss \ No newline at end of file diff --git a/desktopenvs/niri/eww-touch/eww.yuck b/desktopenvs/niri/eww-touch/eww.yuck new file mode 100644 index 0000000..2fda86c --- /dev/null +++ b/desktopenvs/niri/eww-touch/eww.yuck @@ -0,0 +1,104 @@ +(defwindow bar [monitor] + :monitor monitor + :class "ewwbar" + :windowtype "dock" + :geometry (geometry :x "0%" + :y "1%" + :width "99%" + :height "5%" + :anchor "top center") + :exclusive true + (bar :monitor_ monitor)) + +(defpoll battery :interval "2s" + "~/.config/scripts/batteryperc") + +(defwidget bar [monitor_] + (centerbox :orientation "h" + (winsworks :monitor monitor_) + (screenrotate) + (sidestuff))) + +(defwidget winsworks [monitor] + (box :orientation "h" :space-evenly false :halign "start" + (osk) + (button :onclick "~/.config/scripts/drawer.sh" :class "music" {"󱂬"}) + (metric :label "󰓃" + :value volume + :onchange "pactl set-sink-volume @DEFAULT_SINK@ {}%" + :onclick "killall pavucontrol || pavucontrol") + ) +) + +(defwidget screenrotate [] + (box :orientation "h" :space-evenly false :halign "center" + (button :class "music" :onclick "~/.config/scripts/screenrotationwcw.sh" "↻") + (workspaceWidget) + (button :class "music" :onclick "~/.config/scripts/screenrotationacw.sh" "↺") + ) +) + +(defwidget osk [] + (button :class "music" :onclick "~/.config/scripts/onscreenkb.sh" "⌨")) + +(defwidget sidestuff [] + (box :class "sidestuff" :orientation "h" :space-evenly false :halign "end" + (box :class "music" {"${battery}"}) + (box :class "music" {"󰛳 ${IP}"}) + (box + :tooltip {disks} + (metric :label "" + :value {round((1 - (EWW_DISK["/"].free / EWW_DISK["/"].total)) * 100, 0)} + :onchange "" + :onclick "")) + (clock) + (systray :class "music" :orientation "h" :spacing 2 :space-evenly true) + )) + +(defwidget music [] + (button :class "music" + :orientation "h" + :space-evenly false + :halign "center" + :onclick "~/.config/scripts/playpause.sh" + {music != "" ? " ${music}" : " None"})) + +(defwidget metric [label value onchange onclick] + (box :orientation "h" + :class "metric" + :space-evenly false + (button :class "label" :onclick onclick label) + (scale :min 0 + :max 101 + :active {onchange != ""} + :value value + :onchange onchange))) + +(deflisten workspace-niri "~/.config/scripts/workspace") +(defwidget workspaceWidget [] + (eventbox + :onscroll "niri msg action $(echo {} | sed 's/up/focus-workspace-up/;s/down/focus-workspace-down/')" + (literal :content workspace-niri))) + +(defpoll music :interval "0.5s" + "~/.config/scripts/playerget") + +(defpoll IP :interval "5s" + "~/.config/scripts/ip") + +(defpoll volume :interval "0.5s" + "~/.config/scripts/getvol") + +(defpoll time :interval "1s" + "date '+%H:%M:%S|%d.%m.%Y'") + +(defwidget clock [] + (box :class "clock" + :tooltip {calender} + (label :text {"${time}"}))) + +(defpoll calender :interval "600s" + "~/.config/scripts/calender-fix.sh") + +(defpoll disks :interval "600s" + "~/.config/scripts/dysk-phydisks.sh") diff --git a/desktopenvs/niri/eww/eww.scss b/desktopenvs/niri/eww/eww.scss new file mode 120000 index 0000000..63fda1e --- /dev/null +++ b/desktopenvs/niri/eww/eww.scss @@ -0,0 +1 @@ +../../hyprlua/eww/eww.scss \ No newline at end of file diff --git a/desktopenvs/niri/eww/eww.yuck b/desktopenvs/niri/eww/eww.yuck new file mode 100644 index 0000000..bd59d20 --- /dev/null +++ b/desktopenvs/niri/eww/eww.yuck @@ -0,0 +1,93 @@ +(defwindow bar [monitor] + :monitor monitor + :class "ewwbar" + :windowtype "dock" + :geometry (geometry :x "0%" + :y "1%" + :width "99%" + :height "20px" + :anchor "top center") + :exclusive true + (bar :monitor_ monitor)) + +(defwidget bar [monitor_] + (centerbox :orientation "h" + (winsworks :monitor monitor_) + (music) + (sidestuff))) + +(defwidget winsworks [monitor] + (box :orientation "h" :space-evenly false :halign "start" + (workspaceWidget) + (button :onclick "~/.config/scripts/drawer.sh" :class "music" {" ${activewindow}"}) + ) +) + +(defwidget sidestuff [] + (box :class "sidestuff" :orientation "h" :space-evenly false :halign "end" + (box :class "music" {"󰛳 ${IP}"}) + (metric :label "󰓃" + :value volume + :onchange "pactl set-sink-volume @DEFAULT_SINK@ {}%" + :onclick "killall pavucontrol || pavucontrol") + (box + :tooltip {disks} + (metric :label "" + :value {round((1 - (EWW_DISK["/"].free / EWW_DISK["/"].total)) * 100, 0)} + :onchange "" + :onclick "")) + (clock) + (systray :class "music" :orientation "h" :spacing 2 :space-evenly true) + )) + +(defwidget music [] + (button :class "music" + :orientation "h" + :space-evenly false + :halign "center" + :onclick "~/.config/scripts/playpause.sh" + {music != "" ? " ${music}" : " None"})) + +(defwidget metric [label value onchange onclick] + (box :orientation "h" + :class "metric" + :space-evenly false + (button :class "label" :onclick onclick label) + (scale :min 0 + :max 101 + :active {onchange != ""} + :value value + :onchange onchange))) + +// Niri workspace widget — polls via niri IPC event-stream script +(deflisten workspace-niri "~/.config/scripts/workspace") +(defwidget workspaceWidget [] + (eventbox + :onscroll "niri msg action $(echo {} | sed 's/up/focus-workspace-up/;s/down/focus-workspace-down/')" + (literal :content workspace-niri))) + +(defpoll music :interval "0.5s" + "~/.config/scripts/playerget") + +(defpoll activewindow :interval "0.5s" + "~/.config/scripts/activewindow") + +(defpoll IP :interval "5s" + "~/.config/scripts/ip") + +(defpoll volume :interval "0.5s" + "~/.config/scripts/getvol") + +(defpoll time :interval "1s" + "date '+%H:%M:%S|%d.%m.%Y'") + +(defwidget clock [] + (box :class "clock" + :tooltip {calender} + (label :text {"${time}"}))) + +(defpoll calender :interval "600s" + "~/.config/scripts/calender-fix.sh") + +(defpoll disks :interval "600s" + "~/.config/scripts/dysk-phydisks.sh") diff --git a/desktopenvs/niri/greetd-tuigreet/config.toml b/desktopenvs/niri/greetd-tuigreet/config.toml new file mode 100644 index 0000000..8a8c407 --- /dev/null +++ b/desktopenvs/niri/greetd-tuigreet/config.toml @@ -0,0 +1,6 @@ +[terminal] +vt = 1 + +[default_session] +command = "tuigreet --cmd niri" +user = "greeter" diff --git a/desktopenvs/niri/gtk-3.0 b/desktopenvs/niri/gtk-3.0 new file mode 120000 index 0000000..20066c3 --- /dev/null +++ b/desktopenvs/niri/gtk-3.0 @@ -0,0 +1 @@ +../hyprlua/gtk-3.0 \ No newline at end of file diff --git a/desktopenvs/niri/kitty b/desktopenvs/niri/kitty new file mode 120000 index 0000000..cb61345 --- /dev/null +++ b/desktopenvs/niri/kitty @@ -0,0 +1 @@ +../hyprlua/kitty \ No newline at end of file diff --git a/desktopenvs/niri/mimeapps.list b/desktopenvs/niri/mimeapps.list new file mode 120000 index 0000000..fea5803 --- /dev/null +++ b/desktopenvs/niri/mimeapps.list @@ -0,0 +1 @@ +../hyprlua/mimeapps.list \ No newline at end of file diff --git a/desktopenvs/niri/niri/config.kdl b/desktopenvs/niri/niri/config.kdl new file mode 100644 index 0000000..ab52852 --- /dev/null +++ b/desktopenvs/niri/niri/config.kdl @@ -0,0 +1,421 @@ +// ~/.config/niri/config.kdl +// Niri scrollable-tiling Wayland compositor — CyberQueer config +// Translated from hyprlua setup: https://github.com/the_miro/Dotfiles +// https://github.com/YaLTeR/niri/wiki/Configuration:-Overview + +// ── Input ───────────────────────────────────────────────────────────────────── +input { + keyboard { + xkb { + layout "de" + options "caps:swapescape" + } + repeat-delay 300 + repeat-rate 50 + track-layout "window" + } + + touchpad { + tap + natural-scroll + accel-speed 0.0 + accel-profile "flat" + } + + mouse { + left-handed + accel-speed 0.0 + accel-profile "flat" + } + + warp-mouse-to-focus + focus-follows-mouse max-scroll-amount="0%" +} + +// ── Outputs ─────────────────────────────────────────────────────────────────── +// Niri auto-detects monitors. Uncomment and adjust for fixed setups: +// output "eDP-1" { +// scale 2.0 +// position x=0 y=0 +// } +// output "HDMI-A-1" { +// scale 1.0 +// position x=1920 y=0 +// } + +// ── Layout ──────────────────────────────────────────────────────────────────── +layout { + gaps 6 + + center-focused-column "never" + + // Preset widths cycled by Mod+Backspace + preset-column-widths { + proportion 0.333 + proportion 0.5 + proportion 0.667 + proportion 1.0 + } + + default-column-width { proportion 0.5; } + + // CyberQueer focus ring + focus-ring { + width 4 + active-color "#E40046" + inactive-color "#5018DD" + active-gradient from="#E40046" to="#f50505" angle=35 relative-to="window" + inactive-gradient from="#5018DD" to="#5018DD" angle=35 relative-to="window" + } + + border { + off + } + + shadow { + on + softness 30 + spread 5 + offset x=0 y=5 + color "#00000080" + } + + // Reserve space for the eww bar + struts { + top 30 + } +} + +// ── Animations ──────────────────────────────────────────────────────────────── +animations { + window-open { + spring damping-ratio=0.9 stiffness=800 epsilon=0.0001 + } + window-close { + spring damping-ratio=0.9 stiffness=800 epsilon=0.0001 + } + window-movement { + spring damping-ratio=0.9 stiffness=800 epsilon=0.0001 + } + horizontal-view-movement { + spring damping-ratio=0.9 stiffness=800 epsilon=0.0001 + } + workspace-switch { + spring damping-ratio=0.9 stiffness=800 epsilon=0.0001 + } + config-notification-open-close { + spring damping-ratio=0.9 stiffness=800 epsilon=0.0001 + } + screenshot-ui-open { + duration-ms 200 + curve "ease-out-cubic" + } +} + +// ── Environment Variables ───────────────────────────────────────────────────── +environment { + GTK_THEME "cyberqueer" + XCURSOR_SIZE "40" + XCURSOR_THEME "Nordzy-cursors-lefthand" + QT_QPA_PLATFORMTHEME "gtk3" + QT_WAYLAND_DISABLE_WINDOWDECORATION "1" + MOZ_ENABLE_WAYLAND "1" + ELECTRON_OZONE_PLATFORM_HINT "auto" + NIXOS_OZONE_WL "1" + GDK_SCALE "2" +} + +// ── Cursor ──────────────────────────────────────────────────────────────────── +cursor { + xcursor-theme "Nordzy-cursors-lefthand" + xcursor-size 40 + hide-after-inactive-ms 5000 + hide-when-typing +} + +// ── Prefer no client-side decorations ───────────────────────────────────────── +prefer-no-csd + +// ── Screenshot path ─────────────────────────────────────────────────────────── +screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" + +// ── Autostart ───────────────────────────────────────────────────────────────── +spawn-at-startup "bash" "-c" "~/.config/scripts/monitorhandler.sh" +spawn-at-startup "bash" "-c" "vicinae server" +spawn-at-startup "bash" "-c" "~/.config/scripts/bluetooth-applet.sh" +spawn-at-startup "bash" "-c" "~/.config/scripts/ulwatchdog.sh" +spawn-at-startup "udiskie" "-t" "-m" "nested" "-n" +spawn-at-startup "xfce-polkit" +spawn-at-startup "bash" "-c" "gammastep -O 4500" +spawn-at-startup "nm-applet" +spawn-at-startup "dunst" +spawn-at-startup "bash" "-c" "swayidle -w timeout 300 'swaylock -f' timeout 600 'systemctl suspend' before-sleep 'swaylock -f'" +spawn-at-startup "blueman-applet" + +// ── Window Rules ────────────────────────────────────────────────────────────── + +// Launcher / utility floating windows +window-rule { + match app-id=r"^ulauncher$" + open-floating true +} + +window-rule { + match app-id=r"^vicinae$" + open-floating true +} + +window-rule { + match app-id=r"^org\.gnome\.Calculator$" + open-floating true + default-column-width { fixed 400; } +} + +window-rule { + match app-id=r"^qalculate-gtk$" + open-floating true + default-column-width { fixed 600; } +} + +// Mixer — top-right float (approximating tag+mixer behavior) +window-rule { + match app-id=r"^pavucontrol$" + open-floating true + default-column-width { fixed 800; } +} + +window-rule { + match app-id=r"^nm-connection-editor$" + open-floating true + default-column-width { fixed 800; } +} + +window-rule { + match app-id=r"^blueman-manager$" + open-floating true + default-column-width { fixed 700; } +} + +// File manager dialogs +window-rule { + match app-id=r"^thunar$" title=r"^(Copy|Move|Rename|Delete|Progress)" + open-floating true +} + +window-rule { + match app-id=r"^xfce4-terminal$" + open-floating true + default-column-width { fixed 900; } +} + +// Firefox — no transparency +window-rule { + match app-id=r"^firefox$" + opacity 1.0 +} + +window-rule { + match app-id=r"^zen$" + opacity 1.0 +} + +// Global inactive window dimming +window-rule { + min-opacity 0.85 +} + +// Screen sharing / video — exclude from dimming +window-rule { + match app-id=r"^vesktop$" + min-opacity 1.0 +} + +// ── Keybindings ─────────────────────────────────────────────────────────────── +binds { + // ── Applications ────────────────────────────────────────────────────────── + Mod+T { spawn "kitty"; } + Mod+Shift+T { spawn "bash" "-c" "cool-retro-term -p ~/Dotfiles/desktopenvs/niri/CRT"; } + Mod+M { spawn "bash" "-c" "kitty -e nvim"; } + Mod+E { spawn "thunar"; } + Mod+Alt+E { spawn "pcmanfm-qt"; } + Mod+X { spawn "bash" "-c" "wofi --show=run"; } + Mod+N { spawn "nextcloud"; } + Mod+I { spawn "bash" "-c" "iwmenu --launcher walker"; } + Mod+Alt+I { spawn "bash" "-c" "bzmenu --launcher walker"; } + Mod+Shift+I { spawn "nm-connection-editor"; } + Mod+R { spawn "bash" "-c" "vicinae toggle"; } + Mod+Return { spawn "bash" "-c" "vicinae toggle"; } + Mod+Shift+R { spawn "bash" "-c" "wofi --show drun"; } + Ctrl+Shift+R { spawn "bash" "-c" "vicinae toggle"; } + + Mod+F { spawn "bash" "-c" "~/.config/scripts/wofi-file-search.sh"; } + Mod+Shift+F { spawn "bash" "-c" "~/.config/scripts/foldersearch.sh"; } + Mod+Alt+F { spawn "wofi-calc"; } + + Mod+S { spawn "pavucontrol"; } + Mod+U { spawn "bash" "-c" "kitty -e btop"; } + Mod+W { spawn "bash" "-c" "kitty -e ~/.config/scripts/wallpaper-picker ~/Pictures"; } + Mod+Ctrl+R { spawn "bash" "-c" "kitty -e ~/.config/scripts/amssh"; } + Mod+F1 { spawn "bash" "-c" "kitty -e ~/.config/scripts/helpmenu.sh"; } + Mod+Ctrl+T { spawn "bash" "-c" "kitty -e ~/.config/scripts/timer-pick"; } + // Edit niri config directly: + Mod+Shift+F1 { spawn "bash" "-c" "kitty -e nvim ~/.config/niri/config.kdl"; } + + Mod+Ctrl+P { spawn "bash" "-c" "~/.config/scripts/screenrec.sh"; } + + // App drawer + Mod+D { spawn "bash" "-c" "~/.config/scripts/drawer.sh"; } + Mod+Shift+A { spawn "bash" "-c" "~/.config/scripts/drawer.sh"; } + + // ── Screenshots ─────────────────────────────────────────────────────────── + Print { screenshot; } + Mod+P { screenshot; } + Mod+Shift+P { screenshot-screen; } + // Mod+Ctrl+P is screenrec (defined above) + + // ── Window Management ───────────────────────────────────────────────────── + Mod+Q { close-window; } + Mod+Shift+Q { close-window; } + + Mod+V { toggle-window-floating; } + Mod+Shift+V { center-column; } + Mod+C { center-column; } + + // ── Niri-native layout actions ───────────────────────────────────────────── + Mod+Backspace { switch-preset-column-width; } + Mod+Shift+Backspace { maximize-column; } + Mod+Ctrl+Backspace { fullscreen-window; } + + // Consume/expel from column (Niri's grouping analog) + Mod+A { consume-window-into-column; } + Mod+Y { expel-window-from-column; } + Mod+Alt+C { consume-or-expel-window-left; } + Mod+Alt+V { consume-or-expel-window-right; } + + // ── Focus ───────────────────────────────────────────────────────────────── + Mod+H { focus-column-left; } + Mod+L { focus-column-right; } + Mod+J { focus-window-down; } + Mod+K { focus-window-up; } + Mod+Left { focus-column-left; } + Mod+Right { focus-column-right; } + Mod+Down { focus-window-down; } + Mod+Up { focus-window-up; } + + Mod+Tab { focus-window-down-or-column-right; } + Mod+Shift+Tab { focus-window-up-or-column-left; } + + // ── Move Window ─────────────────────────────────────────────────────────── + Mod+Shift+H { move-column-left; } + Mod+Shift+L { move-column-right; } + Mod+Shift+J { move-window-down; } + Mod+Shift+K { move-window-up; } + Mod+Shift+Left { move-column-left; } + Mod+Shift+Right { move-column-right; } + Mod+Shift+Down { move-window-down; } + Mod+Shift+Up { move-window-up; } + + // ── Resize ──────────────────────────────────────────────────────────────── + Mod+Alt+L { set-column-width "+10%"; } + Mod+Alt+H { set-column-width "-10%"; } + Mod+Alt+K { set-window-height "-10%"; } + Mod+Alt+J { set-window-height "+10%"; } + Mod+Alt+Right { set-column-width "+10%"; } + Mod+Alt+Left { set-column-width "-10%"; } + Mod+Alt+Up { set-window-height "-10%"; } + Mod+Alt+Down { set-window-height "+10%"; } + + // ── Workspaces ──────────────────────────────────────────────────────────── + // Note: Niri workspaces are vertical (stacked top-to-bottom per output) + Mod+1 { focus-workspace 1; } + Mod+2 { focus-workspace 2; } + Mod+3 { focus-workspace 3; } + Mod+4 { focus-workspace 4; } + Mod+5 { focus-workspace 5; } + Mod+6 { focus-workspace 6; } + Mod+7 { focus-workspace 7; } + Mod+8 { focus-workspace 8; } + Mod+9 { focus-workspace 9; } + + Mod+Shift+1 { move-column-to-workspace 1; } + Mod+Shift+2 { move-column-to-workspace 2; } + Mod+Shift+3 { move-column-to-workspace 3; } + Mod+Shift+4 { move-column-to-workspace 4; } + Mod+Shift+5 { move-column-to-workspace 5; } + Mod+Shift+6 { move-column-to-workspace 6; } + Mod+Shift+7 { move-column-to-workspace 7; } + Mod+Shift+8 { move-column-to-workspace 8; } + Mod+Shift+9 { move-column-to-workspace 9; } + + // Relative workspace navigation (Ctrl+L/R → down/up in vertical stack) + Mod+Ctrl+Right { focus-workspace-down; } + Mod+Ctrl+Left { focus-workspace-up; } + Mod+Ctrl+L { focus-workspace-down; } + Mod+Ctrl+H { focus-workspace-up; } + + Mod+Ctrl+Shift+Right { move-column-to-workspace-down; } + Mod+Ctrl+Shift+Left { move-column-to-workspace-up; } + Mod+Ctrl+Shift+L { move-column-to-workspace-down; } + Mod+Ctrl+Shift+H { move-column-to-workspace-up; } + + // Scroll workspaces + Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } + Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } + Mod+Shift+WheelScrollDown { move-column-to-workspace-down; } + Mod+Shift+WheelScrollUp { move-column-to-workspace-up; } + + // Horizontal scroll → horizontal column navigation + Mod+WheelScrollRight { focus-column-right; } + Mod+WheelScrollLeft { focus-column-left; } + + // Volume keys as workspace nav (when Mod held) + Mod+XF86AudioRaiseVolume { focus-workspace-down; } + Mod+XF86AudioLowerVolume { focus-workspace-up; } + Mod+Shift+XF86AudioRaiseVolume { move-column-to-workspace-down; } + Mod+Shift+XF86AudioLowerVolume { move-column-to-workspace-up; } + + // Scratchpad-equivalent: focus the most recently visited workspace + Mod+Space { focus-workspace-with-recent-window; } + Mod+Shift+Space { move-column-to-workspace-with-recent-window; } + + // ── Bar / UI ────────────────────────────────────────────────────────────── + Mod+Z { spawn "bash" "-c" "~/.config/scripts/togglebar.sh"; } + Mod+Ctrl+B { spawn "bash" "-c" "eww reload"; } + + // ── Audio ───────────────────────────────────────────────────────────────── + XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "-l" "1.4" "@DEFAULT_AUDIO_SINK@" "5%+"; } + XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "-l" "1.4" "@DEFAULT_AUDIO_SINK@" "5%-"; } + XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; } + XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; } + XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause" "-p" "spotify,vlc"; } + + // ── Brightness ──────────────────────────────────────────────────────────── + XF86MonBrightnessUp allow-when-locked=true { spawn "bri" "--up"; } + XF86MonBrightnessDown allow-when-locked=true { spawn "bri" "--down"; } + + // ── Color temperature (gammastep presets) ───────────────────────────────── + Mod+Ctrl+X { spawn "bash" "-c" "killall gammastep; gammastep -O 6500"; } // neutral / reset + Mod+Ctrl+W { spawn "bash" "-c" "killall gammastep; gammastep -O 5000"; } // warm + Mod+Ctrl+A { spawn "bash" "-c" "killall gammastep; gammastep -O 4000"; } // warmer + Mod+Ctrl+Q { spawn "bash" "-c" "killall gammastep; gammastep -O 3000"; } // very warm + Mod+Ctrl+S { spawn "bash" "-c" "killall gammastep; gammastep -O 2700"; } // night mode + + // ── Misc ────────────────────────────────────────────────────────────────── + Mod+Ctrl+I { spawn "chamel" "toggle"; } + Mod+Ctrl+U { spawn "chamel" "clear"; } + Mod+Ctrl+Z { spawn "chamel" "clear-and-deactivate"; } + Mod+Ctrl+C { spawn "dunstctl" "close-all"; } + Mod+Ctrl+G { spawn "bash" "-c" "~/.config/scripts/onscreenkb.sh"; } + Mod+Shift+C { spawn "bash" "-c" "~/.config/scripts/caffeine.sh"; } + Mod+Shift+X { spawn "bash" "-c" "~/.config/scripts/niri-toggle-touchpad.sh"; } + + Mod+Ctrl+E { spawn "bash" "-c" "~/.config/scripts/screenrotationwcw.sh"; } + Mod+Ctrl+D { spawn "bash" "-c" "~/.config/scripts/screenrotationacw.sh"; } + + // ── Lock / Exit ─────────────────────────────────────────────────────────── + Mod+O { spawn "swaylock" "-f"; } + Mod+Shift+O { quit; } + Mod+Ctrl+O { spawn "systemctl" "poweroff"; } + Mod+Alt+O { spawn "bash" "-c" "~/.config/scripts/pwr-dmenu.sh"; } + Mod+Alt+Ctrl+Shift+End { quit; } +} diff --git a/desktopenvs/niri/nwg-drawer b/desktopenvs/niri/nwg-drawer new file mode 120000 index 0000000..9284c46 --- /dev/null +++ b/desktopenvs/niri/nwg-drawer @@ -0,0 +1 @@ +../hyprlua/nwg-drawer \ No newline at end of file diff --git a/desktopenvs/niri/nwg-panel b/desktopenvs/niri/nwg-panel new file mode 120000 index 0000000..5069d63 --- /dev/null +++ b/desktopenvs/niri/nwg-panel @@ -0,0 +1 @@ +../hyprlua/nwg-panel \ No newline at end of file diff --git a/desktopenvs/niri/scripts/_toggle_Template.tmplsh b/desktopenvs/niri/scripts/_toggle_Template.tmplsh new file mode 120000 index 0000000..e2a6b6d --- /dev/null +++ b/desktopenvs/niri/scripts/_toggle_Template.tmplsh @@ -0,0 +1 @@ +../../hyprlua/scripts/_toggle_Template.tmplsh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/activewindow b/desktopenvs/niri/scripts/activewindow new file mode 100755 index 0000000..4e2e249 --- /dev/null +++ b/desktopenvs/niri/scripts/activewindow @@ -0,0 +1,13 @@ +#!/bin/bash +trunc=16 +sample=$(niri msg -j focused-window 2>/dev/null | jq -r '.title // ""' 2>/dev/null) + +if [ ${#sample} -gt $trunc ]; then + echo "$sample" | head -c $trunc | sed 's/$/…/' +else + if [ ${#sample} -ne 0 ]; then + echo "$sample" + else + echo "None" + fi +fi diff --git a/desktopenvs/niri/scripts/amssh b/desktopenvs/niri/scripts/amssh new file mode 120000 index 0000000..ea5b6c9 --- /dev/null +++ b/desktopenvs/niri/scripts/amssh @@ -0,0 +1 @@ +../../hyprlua/scripts/amssh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/batteryperc b/desktopenvs/niri/scripts/batteryperc new file mode 120000 index 0000000..fe17fd7 --- /dev/null +++ b/desktopenvs/niri/scripts/batteryperc @@ -0,0 +1 @@ +../../hyprlua/scripts/batteryperc \ No newline at end of file diff --git a/desktopenvs/niri/scripts/bluetooth-applet.sh b/desktopenvs/niri/scripts/bluetooth-applet.sh new file mode 100755 index 0000000..d177441 --- /dev/null +++ b/desktopenvs/niri/scripts/bluetooth-applet.sh @@ -0,0 +1,2 @@ +#!/bin/bash +blueman-applet diff --git a/desktopenvs/niri/scripts/caffeine.sh b/desktopenvs/niri/scripts/caffeine.sh new file mode 100755 index 0000000..6fb2c12 --- /dev/null +++ b/desktopenvs/niri/scripts/caffeine.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +statecon=$(pidof swayidle | grep "[1234567890]") + +if [ "$statecon" != "" ]; then + notify-send -t 1000 "Caffeine mode ON — idle inhibited" + killall swayidle +else + notify-send -t 1000 "Caffeine mode OFF — idle active" + swayidle -w \ + timeout 300 'swaylock -f' \ + timeout 600 'systemctl suspend' \ + before-sleep 'swaylock -f' & +fi diff --git a/desktopenvs/niri/scripts/calender-fix.sh b/desktopenvs/niri/scripts/calender-fix.sh new file mode 120000 index 0000000..3ec0451 --- /dev/null +++ b/desktopenvs/niri/scripts/calender-fix.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/calender-fix.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/date.sh b/desktopenvs/niri/scripts/date.sh new file mode 120000 index 0000000..58c0365 --- /dev/null +++ b/desktopenvs/niri/scripts/date.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/date.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/drawer.sh b/desktopenvs/niri/scripts/drawer.sh new file mode 100755 index 0000000..2f86800 --- /dev/null +++ b/desktopenvs/niri/scripts/drawer.sh @@ -0,0 +1,9 @@ +#!/bin/bash +nwg-drawer \ + -fm "kitty -e yazi" \ + -term kitty \ + -mb 20 -ml 20 -mr 20 -mt 20 \ + -pblock "swaylock -f" \ + -pbpoweroff poweroff \ + -pbexit "niri msg action quit" \ + -pbreboot reboot diff --git a/desktopenvs/niri/scripts/dysk-phydisks.sh b/desktopenvs/niri/scripts/dysk-phydisks.sh new file mode 120000 index 0000000..9c2d7ed --- /dev/null +++ b/desktopenvs/niri/scripts/dysk-phydisks.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/dysk-phydisks.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/ewwstart.sh b/desktopenvs/niri/scripts/ewwstart.sh new file mode 100755 index 0000000..e6be45c --- /dev/null +++ b/desktopenvs/niri/scripts/ewwstart.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +killall eww 2>/dev/null || true +/usr/bin/eww daemon + +GTK_THEME=cyberqueer + +monitorsum=$(niri msg outputs | grep -c "Scale:" || echo 1) + +for i in $(seq 1 "$monitorsum"); do + declare -i curmon=$i-1 + /usr/bin/eww open bar --id "bar$curmon" --arg monitor=$curmon +done diff --git a/desktopenvs/niri/scripts/foldersearch.sh b/desktopenvs/niri/scripts/foldersearch.sh new file mode 120000 index 0000000..c177681 --- /dev/null +++ b/desktopenvs/niri/scripts/foldersearch.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/foldersearch.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/frequentcommands.list b/desktopenvs/niri/scripts/frequentcommands.list new file mode 120000 index 0000000..41f6a51 --- /dev/null +++ b/desktopenvs/niri/scripts/frequentcommands.list @@ -0,0 +1 @@ +../../hyprlua/scripts/frequentcommands.list \ No newline at end of file diff --git a/desktopenvs/niri/scripts/getispeed.sh b/desktopenvs/niri/scripts/getispeed.sh new file mode 120000 index 0000000..9661855 --- /dev/null +++ b/desktopenvs/niri/scripts/getispeed.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/getispeed.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/getvol b/desktopenvs/niri/scripts/getvol new file mode 120000 index 0000000..8f08b54 --- /dev/null +++ b/desktopenvs/niri/scripts/getvol @@ -0,0 +1 @@ +../../hyprlua/scripts/getvol \ No newline at end of file diff --git a/desktopenvs/niri/scripts/helpmenu.sh b/desktopenvs/niri/scripts/helpmenu.sh new file mode 120000 index 0000000..bf46817 --- /dev/null +++ b/desktopenvs/niri/scripts/helpmenu.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/helpmenu.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/ip b/desktopenvs/niri/scripts/ip new file mode 120000 index 0000000..216a85e --- /dev/null +++ b/desktopenvs/niri/scripts/ip @@ -0,0 +1 @@ +../../hyprlua/scripts/ip \ No newline at end of file diff --git a/desktopenvs/niri/scripts/journal.sh b/desktopenvs/niri/scripts/journal.sh new file mode 120000 index 0000000..49b474f --- /dev/null +++ b/desktopenvs/niri/scripts/journal.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/journal.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/menu.sh b/desktopenvs/niri/scripts/menu.sh new file mode 100755 index 0000000..f124829 --- /dev/null +++ b/desktopenvs/niri/scripts/menu.sh @@ -0,0 +1,9 @@ +#!/bin/bash +nwg-menu \ + -term kitty \ + --ml 15 -mb 15 -mr 15 -mt 15 \ + -cmd-lock "swaylock -f" \ + -cmd-logout "niri msg action quit" \ + -cmd-restart reboot \ + -cmd-shutdown poweroff \ + -fm "kitty -e yazi" diff --git a/desktopenvs/niri/scripts/monitorhandler.sh b/desktopenvs/niri/scripts/monitorhandler.sh new file mode 100755 index 0000000..7f542b9 --- /dev/null +++ b/desktopenvs/niri/scripts/monitorhandler.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# Start the wallpaper daemon and eww bar for niri. +# swaybg replaces hyprpaper; one instance per output. + +WALLPAPER="${HOME}/Pictures/background.jpg" + +if [ -f "$WALLPAPER" ]; then + swaybg -m fill -i "$WALLPAPER" & +fi + +mkdir -p ~/Pictures/Screenshots + +~/.config/scripts/ewwstart.sh diff --git a/desktopenvs/niri/scripts/niri-toggle-touchpad.sh b/desktopenvs/niri/scripts/niri-toggle-touchpad.sh new file mode 100755 index 0000000..3f0d911 --- /dev/null +++ b/desktopenvs/niri/scripts/niri-toggle-touchpad.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Toggle touchpad on/off. Niri doesn't expose a direct IPC for this; +# we fall back to libinput xinput if available, or notify with instructions. + +STATUS_FILE="$XDG_RUNTIME_DIR/touchpad.status" + +TOUCHPAD_ID=$(xinput --list --id-only "$(xinput --list --name-only 2>/dev/null | grep -i touchpad | head -1)" 2>/dev/null || echo "") + +enable_touchpad() { + printf "true" > "$STATUS_FILE" + notify-send -u normal "Touchpad Enabled" + if [ -n "$TOUCHPAD_ID" ]; then + xinput enable "$TOUCHPAD_ID" + fi +} + +disable_touchpad() { + printf "false" > "$STATUS_FILE" + notify-send -u normal "Touchpad Disabled" + if [ -n "$TOUCHPAD_ID" ]; then + xinput disable "$TOUCHPAD_ID" + fi +} + +if [ -z "$TOUCHPAD_ID" ]; then + notify-send -u normal "Touchpad" "No touchpad found via xinput.\nAdjust device name in niri-toggle-touchpad.sh" + exit 0 +fi + +if [ ! -f "$STATUS_FILE" ]; then + enable_touchpad +else + if [ "$(cat "$STATUS_FILE")" = "true" ]; then + disable_touchpad + else + enable_touchpad + fi +fi diff --git a/desktopenvs/niri/scripts/playerget b/desktopenvs/niri/scripts/playerget new file mode 120000 index 0000000..fd4f46e --- /dev/null +++ b/desktopenvs/niri/scripts/playerget @@ -0,0 +1 @@ +../../hyprlua/scripts/playerget \ No newline at end of file diff --git a/desktopenvs/niri/scripts/playpause.sh b/desktopenvs/niri/scripts/playpause.sh new file mode 120000 index 0000000..5759832 --- /dev/null +++ b/desktopenvs/niri/scripts/playpause.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/playpause.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/pwr-dmenu.sh b/desktopenvs/niri/scripts/pwr-dmenu.sh new file mode 100755 index 0000000..b58fd48 --- /dev/null +++ b/desktopenvs/niri/scripts/pwr-dmenu.sh @@ -0,0 +1,2 @@ +#!/bin/zsh +cat ~/.config/scripts/frequentcommands.list | wofi --show=dmenu | zsh diff --git a/desktopenvs/niri/scripts/python/python b/desktopenvs/niri/scripts/python/python new file mode 120000 index 0000000..17e029d --- /dev/null +++ b/desktopenvs/niri/scripts/python/python @@ -0,0 +1 @@ +../../hyprlua/scripts/python \ No newline at end of file diff --git a/desktopenvs/niri/scripts/screenrec.sh b/desktopenvs/niri/scripts/screenrec.sh new file mode 120000 index 0000000..a69efe5 --- /dev/null +++ b/desktopenvs/niri/scripts/screenrec.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/screenrec.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/screenrotationacw.sh b/desktopenvs/niri/scripts/screenrotationacw.sh new file mode 100755 index 0000000..642615d --- /dev/null +++ b/desktopenvs/niri/scripts/screenrotationacw.sh @@ -0,0 +1,2 @@ +#!/bin/bash +~/.config/scripts/unified-rotate.sh ccw diff --git a/desktopenvs/niri/scripts/screenrotationwcw.sh b/desktopenvs/niri/scripts/screenrotationwcw.sh new file mode 100755 index 0000000..56b120e --- /dev/null +++ b/desktopenvs/niri/scripts/screenrotationwcw.sh @@ -0,0 +1,2 @@ +#!/bin/bash +~/.config/scripts/unified-rotate.sh cw diff --git a/desktopenvs/niri/scripts/screenshot.sh b/desktopenvs/niri/scripts/screenshot.sh new file mode 120000 index 0000000..0f1ab70 --- /dev/null +++ b/desktopenvs/niri/scripts/screenshot.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/screenshot.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/time.sh b/desktopenvs/niri/scripts/time.sh new file mode 120000 index 0000000..c78d162 --- /dev/null +++ b/desktopenvs/niri/scripts/time.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/time.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/timer-notify.sh.old b/desktopenvs/niri/scripts/timer-notify.sh.old new file mode 120000 index 0000000..18cda0f --- /dev/null +++ b/desktopenvs/niri/scripts/timer-notify.sh.old @@ -0,0 +1 @@ +../../hyprlua/scripts/timer-notify.sh.old \ No newline at end of file diff --git a/desktopenvs/niri/scripts/timer-pick b/desktopenvs/niri/scripts/timer-pick new file mode 120000 index 0000000..a655ac0 --- /dev/null +++ b/desktopenvs/niri/scripts/timer-pick @@ -0,0 +1 @@ +../../hyprlua/scripts/timer-pick \ No newline at end of file diff --git a/desktopenvs/niri/scripts/timer-run b/desktopenvs/niri/scripts/timer-run new file mode 120000 index 0000000..dc5541f --- /dev/null +++ b/desktopenvs/niri/scripts/timer-run @@ -0,0 +1 @@ +../../hyprlua/scripts/timer-run \ No newline at end of file diff --git a/desktopenvs/niri/scripts/timer.sh.old b/desktopenvs/niri/scripts/timer.sh.old new file mode 120000 index 0000000..dfbfc0c --- /dev/null +++ b/desktopenvs/niri/scripts/timer.sh.old @@ -0,0 +1 @@ +../../hyprlua/scripts/timer.sh.old \ No newline at end of file diff --git a/desktopenvs/niri/scripts/toggle-layout.sh b/desktopenvs/niri/scripts/toggle-layout.sh new file mode 100755 index 0000000..3a7f668 --- /dev/null +++ b/desktopenvs/niri/scripts/toggle-layout.sh @@ -0,0 +1,3 @@ +#!/bin/bash +# Niri uses a single scrollable-tiling layout — no layout toggle available. +notify-send -t 2000 "Niri" "Scrollable tiling — no layout toggle in niri." diff --git a/desktopenvs/niri/scripts/togglebar.sh b/desktopenvs/niri/scripts/togglebar.sh new file mode 100755 index 0000000..73babea --- /dev/null +++ b/desktopenvs/niri/scripts/togglebar.sh @@ -0,0 +1,25 @@ +#!/bin/bash +GTK_THEME=cyberqueer + +monitorsum=$(niri msg outputs | grep -c "Scale:" || echo 1) + +# niri doesn't expose a simple "focused output index" via IPC — default to 0 +actmon=0 + +statecon=$(eww active-windows 2>/dev/null | grep "bar$actmon" || true) + +if [ "$statecon" != '' ]; then + for i in $(seq 1 "$monitorsum"); do + declare -i curmon=$i-1 + if [ "$curmon" -eq "$actmon" ]; then + /usr/bin/eww open --toggle "bar$curmon" + fi + done +else + for i in $(seq 1 "$monitorsum"); do + declare -i curmon=$i-1 + if [ "$curmon" -eq "$actmon" ]; then + /usr/bin/eww open bar --id "bar$curmon" --arg monitor=$curmon + fi + done +fi diff --git a/desktopenvs/niri/scripts/ulwatchdog.sh b/desktopenvs/niri/scripts/ulwatchdog.sh new file mode 100755 index 0000000..ca95d2d --- /dev/null +++ b/desktopenvs/niri/scripts/ulwatchdog.sh @@ -0,0 +1,9 @@ +#!/bin/bash +zoxide import --from z ~/.z --merge 2>/dev/null || true +while true; do + statecon=$(pgrep ulauncher) + if [ "$statecon" != '' ]; then + ulauncher + fi + sleep 5 +done diff --git a/desktopenvs/niri/scripts/unified-rotate.sh b/desktopenvs/niri/scripts/unified-rotate.sh new file mode 100755 index 0000000..a3b3a0b --- /dev/null +++ b/desktopenvs/niri/scripts/unified-rotate.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Screen rotation for niri using niri IPC. +# Usage: unified-rotate.sh [cw|ccw|0|90|180|270] + +direction="$1" + +if [[ "$direction" != "cw" && "$direction" != "ccw" && \ + "$direction" != "0" && "$direction" != "90" && \ + "$direction" != "180" && "$direction" != "270" ]]; then + echo "Usage: $0 [cw|ccw|0|90|180|270]" + exit 1 +fi + +# Get focused output name +outputs_json=$(niri msg -j outputs 2>/dev/null) +curmon=$(echo "$outputs_json" | jq -r 'to_entries[] | select(.value.is_active == true) | .key' 2>/dev/null | head -1) + +if [ -z "$curmon" ]; then + # Fallback: use first output + curmon=$(echo "$outputs_json" | jq -r 'keys[0]' 2>/dev/null) +fi + +if [ -z "$curmon" ]; then + notify-send -u critical "Screen Rotation" "Could not detect current output" + exit 1 +fi + +# Niri transform values: "normal" | "90" | "180" | "270" | "flipped" | "flipped-90" | "flipped-180" | "flipped-270" +currot=$(echo "$outputs_json" | jq -r ".\"$curmon\".transform // \"normal\"" 2>/dev/null) + +declare -A rot_to_deg=([normal]="0" [90]="90" [180]="180" [270]="270") +declare -A deg_to_rot=([0]="normal" [90]="90" [180]="180" [270]="270") + +curdeg="${rot_to_deg[$currot]:-0}" + +if [[ "$direction" == "cw" ]]; then + newdeg=$(( (curdeg + 90) % 360 )) +elif [[ "$direction" == "ccw" ]]; then + newdeg=$(( (curdeg + 270) % 360 )) +else + newdeg="$direction" +fi + +newrot="${deg_to_rot[$newdeg]:-normal}" + +echo "Rotating '$curmon' from ${curdeg}° to ${newdeg}° (${newrot})" +niri msg action set-output-transform "$curmon" "$newrot" + +eww reload 2>/dev/null || true diff --git a/desktopenvs/niri/scripts/uptime.sh b/desktopenvs/niri/scripts/uptime.sh new file mode 120000 index 0000000..1a166cd --- /dev/null +++ b/desktopenvs/niri/scripts/uptime.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/uptime.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/wallpaper-picker b/desktopenvs/niri/scripts/wallpaper-picker new file mode 100755 index 0000000..eab9b1f --- /dev/null +++ b/desktopenvs/niri/scripts/wallpaper-picker @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# Wallpaper picker for niri using swaybg. +# Usage: wallpaper-picker [directory] + +set -u + +DIR="${1:-$HOME/Pictures}" +STATE_FILE="${HOME}/.config/niri-wallpaper" + +IMAGES=() +while IFS= read -r -d '' f; do + IMAGES+=("$f") +done < <(find "$DIR" -maxdepth 1 -type f \ + \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \ + -o -iname '*.webp' -o -iname '*.bmp' -o -iname '*.avif' \) \ + -print0 | sort -z) + +[[ ${#IMAGES[@]} -eq 0 ]] && { echo "No images found in $DIR"; exit 1; } + +INDEX=0 + +icat() { kitty +kitten icat --stdin=no --silent --transfer-mode=memory "$@" 2>/dev/null; } +clear_images() { icat --clear; } + +draw() { + local cols rows + cols=$(tput cols); rows=$(tput lines) + local n=${#IMAGES[@]} + local prev=$(( (INDEX - 1 + n) % n )) + local next=$(( (INDEX + 1) % n )) + local header_h=2 + local footer_h=4 + local img_h=$(( rows - header_h - footer_h )) + (( img_h < 5 )) && img_h=5 + local side_w=$(( cols * 18 / 100 )) + local center_w=$(( cols - 2 * (side_w + 2) )) + local center_x=$(( side_w + 2 )) + local next_x=$(( center_x + center_w + 2 )) + + printf '\033[2J\033[H' + clear_images + tput cup 0 0 + printf ' Wallpaper Picker (niri/swaybg) [%d/%d] %s' \ + $(( INDEX + 1 )) "$n" "$(basename "${IMAGES[$INDEX]}")" + icat --place "${side_w}x${img_h}@0x${header_h}" "${IMAGES[$prev]}" + icat --place "${center_w}x${img_h}@${center_x}x${header_h}" "${IMAGES[$INDEX]}" + icat --place "${side_w}x${img_h}@${next_x}x${header_h}" "${IMAGES[$next]}" + local row=$(( header_h + img_h )) + tput cup "$row" 0 + printf ' h/←: prev l/→: next Enter/Space: apply q: quit\n' +} + +apply() { + local path="$1" + killall swaybg 2>/dev/null || true + swaybg -m fill -i "$path" & + printf '%s\n' "$path" > "$STATE_FILE" + tput cup $(( $(tput lines) - 1 )) 0 + printf '\033[2K Applied: %s' "$(basename "$path")" +} + +KEY="" +read_key() { + KEY="" + IFS= read -rsn1 KEY + if [[ $KEY == $'\x1b' ]]; then + local rest="" + IFS= read -rsn2 -t 0.1 rest || true + KEY+="$rest" + fi +} + +old_stty=$(stty -g) +trap 'stty "$old_stty"; clear_images; tput cnorm; printf "\033[2J\033[H"' EXIT +stty -echo -icanon -icrnl min 1 time 0 +tput civis + +draw + +while true; do + read_key + case "$KEY" in + h|$'\x1b[D') INDEX=$(( (INDEX - 1 + ${#IMAGES[@]}) % ${#IMAGES[@]} )); draw ;; + l|$'\x1b[C') INDEX=$(( (INDEX + 1) % ${#IMAGES[@]} )); draw ;; + $'\r'|$'\n'|' ') apply "${IMAGES[$INDEX]}" ;; + q|Q) break ;; + esac +done diff --git a/desktopenvs/niri/scripts/windowswitcher b/desktopenvs/niri/scripts/windowswitcher new file mode 100755 index 0000000..329a73b --- /dev/null +++ b/desktopenvs/niri/scripts/windowswitcher @@ -0,0 +1,12 @@ +#!/bin/bash +# Window switcher for niri using wofi dmenu +focused=$(niri msg -j focused-window 2>/dev/null | jq -r '.id // ""') + +selection=$(niri msg -j windows 2>/dev/null \ + | jq -r '.[] | "\(.id) ┇ \(.app_id // "?") ┇ \(.title // "?")"' \ + | wofi -dO alphabetical --prompt "Switch to:" \ + | awk '{print $1}') + +if [ -n "$selection" ]; then + niri msg action focus-window --id "$selection" +fi diff --git a/desktopenvs/niri/scripts/wofi-file-search.sh b/desktopenvs/niri/scripts/wofi-file-search.sh new file mode 120000 index 0000000..766753f --- /dev/null +++ b/desktopenvs/niri/scripts/wofi-file-search.sh @@ -0,0 +1 @@ +../../hyprlua/scripts/wofi-file-search.sh \ No newline at end of file diff --git a/desktopenvs/niri/scripts/workspace b/desktopenvs/niri/scripts/workspace new file mode 100755 index 0000000..78190e8 --- /dev/null +++ b/desktopenvs/niri/scripts/workspace @@ -0,0 +1,29 @@ +#!/bin/bash +# EWW workspace widget for niri (literal/listen mode). +# Outputs an eww Yuck literal widget, updates on workspace changes. + +render() { + local ws_json + ws_json=$(niri msg -j workspaces 2>/dev/null) || ws_json="[]" + + local out="(box :class \"workspaces\" :space-evenly false" + while IFS= read -r ws; do + local idx is_active + idx=$(echo "$ws" | jq -r '.idx') + is_active=$(echo "$ws" | jq -r '.is_focused') + local id + id=$(echo "$ws" | jq -r '.id') + local class="workspace-button" + [ "$is_active" = "true" ] && class="workspace-button workspace-active" + out+=" (button :class \"$class\" :width 20 :onclick \"niri msg action focus-workspace $idx\" \"$idx\")" + done < <(echo "$ws_json" | jq -c '.[]') + out+=")" + echo "$out" +} + +render + +# Watch for workspace changes via event-stream +niri msg event-stream 2>/dev/null | while IFS= read -r line; do + echo "$line" | grep -qE '"WorkspacesChanged"|"WorkspaceActivated"' && render +done diff --git a/desktopenvs/niri/scripts/workspacefocus/focusleft.sh b/desktopenvs/niri/scripts/workspacefocus/focusleft.sh new file mode 100755 index 0000000..78c9355 --- /dev/null +++ b/desktopenvs/niri/scripts/workspacefocus/focusleft.sh @@ -0,0 +1,2 @@ +#!/bin/bash +niri msg action focus-workspace-up diff --git a/desktopenvs/niri/scripts/workspacefocus/focusright.sh b/desktopenvs/niri/scripts/workspacefocus/focusright.sh new file mode 100755 index 0000000..35085b3 --- /dev/null +++ b/desktopenvs/niri/scripts/workspacefocus/focusright.sh @@ -0,0 +1,2 @@ +#!/bin/bash +niri msg action focus-workspace-down diff --git a/desktopenvs/niri/spicetify b/desktopenvs/niri/spicetify new file mode 120000 index 0000000..e942cb7 --- /dev/null +++ b/desktopenvs/niri/spicetify @@ -0,0 +1 @@ +../hyprlua/spicetify \ No newline at end of file diff --git a/desktopenvs/niri/ulauncher b/desktopenvs/niri/ulauncher new file mode 120000 index 0000000..f45e2f9 --- /dev/null +++ b/desktopenvs/niri/ulauncher @@ -0,0 +1 @@ +../hyprlua/ulauncher \ No newline at end of file diff --git a/desktopenvs/niri/vicinae b/desktopenvs/niri/vicinae new file mode 120000 index 0000000..5bad497 --- /dev/null +++ b/desktopenvs/niri/vicinae @@ -0,0 +1 @@ +../hyprlua/vicinae \ No newline at end of file diff --git a/desktopenvs/niri/walker b/desktopenvs/niri/walker new file mode 120000 index 0000000..34b4382 --- /dev/null +++ b/desktopenvs/niri/walker @@ -0,0 +1 @@ +../hyprlua/walker \ No newline at end of file diff --git a/desktopenvs/niri/waybar b/desktopenvs/niri/waybar new file mode 120000 index 0000000..86a8008 --- /dev/null +++ b/desktopenvs/niri/waybar @@ -0,0 +1 @@ +../hyprlua/waybar \ No newline at end of file diff --git a/desktopenvs/niri/wofi b/desktopenvs/niri/wofi new file mode 120000 index 0000000..5b66875 --- /dev/null +++ b/desktopenvs/niri/wofi @@ -0,0 +1 @@ +../hyprlua/wofi \ No newline at end of file diff --git a/desktopenvs/niri/xfce4 b/desktopenvs/niri/xfce4 new file mode 120000 index 0000000..acf8d79 --- /dev/null +++ b/desktopenvs/niri/xfce4 @@ -0,0 +1 @@ +../hyprlua/xfce4 \ No newline at end of file diff --git a/setup/modules/Desktop-Environments/niri.sh b/setup/modules/Desktop-Environments/niri.sh new file mode 100755 index 0000000..f7a9d46 --- /dev/null +++ b/setup/modules/Desktop-Environments/niri.sh @@ -0,0 +1,151 @@ +#!/bin/bash +set -e +source "$(dirname "${BASH_SOURCE[0]}")/../lib/logging.sh" + +log "Starting Niri installer (scrollable-tiling Wayland compositor)..." + +# 1. Update system and install Flatpak +log "Updating system and installing Flatpak..." +sudo pacman -Syu --noconfirm --needed flatpak + +# 2. Install required packages +log "Installing required packages..." +sudo pacman -Syu --noconfirm --needed \ + niri xdg-desktop-portal-gnome wl-clipboard swaybg swaylock swayidle \ + xfce-polkit gammastep \ + wofi kitty dunst \ + nwg-drawer nwg-menu nwg-look \ + python cmake meson cpio pkgconf ruby-pkg-config \ + nm-connection-editor network-manager-applet blueman bluez \ + pipewire alsa-utils firefox greetd-tuigreet \ + grim slurp gst-plugin-pipewire imagemagick \ + nerd-fonts otf-font-awesome \ + pipewire-alsa pipewire-jack pipewire-pulse \ + qt5-wayland qt6-wayland swww ttf-jetbrains-mono wireplumber \ + xdg-utils xorg-xinit papirus-icon-theme \ + cool-retro-term qalculate-gtk iwd dbus \ + thunar tumbler thunar-archive-plugin thunar-shares-plugin thunar-volman \ + pcmanfm-qt udisks2 ly kew \ + pavucontrol playerctl wf-recorder sound-theme-freedesktop \ + xinput jq + +# 3. Enable essential services +log "Enabling essential services..." +sudo systemctl enable NetworkManager.service +sudo systemctl disable getty@tty1.service || true +sudo systemctl enable ly@tty1.service +sudo systemctl enable udisks2.service + +# 4. Install AUR packages +log "Installing AUR packages..." +rustup default stable +yay -Syu --answerdiff None --answerclean All --noconfirm --needed \ + vicinae-bin bluetuith wvkbd iwmenu pinta \ + walker-bin ulauncher bzmenu udiskie \ + wofi-calc bri chamel + +# 5. EWW bar selection and compilation +log "Setting up EWW bar..." +rm -rf ~/.config/eww +read -n1 -p "Install eww bar for PC, Notebook or Tablet [P/N/T]: " doit +echo +case $doit in + n|N) cp -rf ~/Dotfiles/desktopenvs/niri/eww/ ~/.config/ ;; + p|P) cp -rf ~/Dotfiles/desktopenvs/niri/eww-nobattery/ ~/.config/eww ;; + t|T) cp -rf ~/Dotfiles/desktopenvs/niri/eww-touch/ ~/.config/eww ;; + *) warn "No valid choice — skipping EWW copy. Run manually later." ;; +esac + +log "Compiling EWW..." +mkdir -p ~/install-tmp +cd ~/install-tmp +git clone https://github.com/elkowar/eww +cd eww +cargo build --release --no-default-features --features=wayland +chmod +x target/release/eww +sudo cp target/release/eww /usr/bin/ +cd ~ + +# 6. Theme and icon setup +log "Installing themes and icons..." +sudo cp -r ~/Dotfiles/gtk-themes/cyberqueer /usr/share/themes +sudo cp ~/Dotfiles/desktopenvs/niri/btop/themes/cyberqueer.theme /usr/share/btop/themes +sudo cp -f ~/Dotfiles/etc-ly-config.ini /etc/ly/config.ini +sudo ln -sf /usr/bin/kitty /usr/bin/xdg-terminal-exec +gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' + +# 7. Cursor setup +log "Installing cursor theme..." +mkdir -p ~/.icons +wget -O ~/install-tmp/Nordzy-cursors-lefthand.tar.gz \ + https://github.com/guillaumeboehm/Nordzy-cursors/releases/download/v2.3.0/Nordzy-cursors-lefthand.tar.gz +tar -zxf ~/install-tmp/Nordzy-cursors-lefthand.tar.gz -C ~/.icons/ + +# 8. Enable Bluetooth and wireless services +log "Enabling Bluetooth and wireless services..." +sudo systemctl enable bluez +sudo systemctl enable bluetooth.service +sudo systemctl enable iwd.service + +# 9. Copy configs +log "Copying configs..." +CONFIGS=(kitty mimeapps.list vicinae walker ulauncher niri nwg-drawer nwg-panel wofi dunst alacritty scripts btop gtk-3.0 waybar xfce4) +for cfg in "${CONFIGS[@]}"; do + rm -rf ~/.config/"$cfg" + cp -rL ~/Dotfiles/desktopenvs/niri/"$cfg" ~/.config/ +done + +cp ~/Dotfiles/colors.conf ~/.config/colors.conf + +# 10. greetd — deploy niri session config +log "Deploying greetd config for niri..." +sudo mkdir -p /etc/greetd +sudo cp -f ~/Dotfiles/desktopenvs/niri/greetd-tuigreet/config.toml /etc/greetd/config.toml +sudo systemctl enable greetd.service + +# 11. Wallpaper and resources +log "Copying wallpaper and resources..." +mkdir -p ~/Pictures ~/Pictures/Screenshots +cp ~/Dotfiles/resources/fflogo.svg ~/Pictures/fflogo.svg +wget "https://cloud.abdelbaki.eu/apps/theming/image/background?v=15" -O ~/Pictures/background.jpg + +# 12. Python venv for scripts +log "Setting up Python venv for scripts..." +python -m venv ~/.config/python-script +~/.config/python-script/bin/pip install speedtest-cli requests pint simpleeval parsedatetime + +# 13. Udiskie icon fix +log "Applying Udiskie icon fix..." +PAPIRUS_DIR="/usr/share/icons/Papirus-Dark/status" +HICOLOR_DIR="/usr/share/icons/hicolor/scalable/status" +if [ -d "$PAPIRUS_DIR" ]; then + sudo ln -sf "$PAPIRUS_DIR/checkbox-checked.svg" "$HICOLOR_DIR/udiskie-checkbox-checked.svg" + sudo ln -sf "$PAPIRUS_DIR/checkbox-unchecked.svg" "$HICOLOR_DIR/udiskie-checkbox-unchecked.svg" + sudo gtk-update-icon-cache -f -t /usr/share/icons/hicolor +else + warn "Papirus-Dark not found — skipping udiskie icon fix." +fi + +# 14. Enable udiskie +log "Enabling udiskie service..." +sudo systemctl enable udiskie.service +sudo systemctl start udiskie.service + +# 15. Make scripts executable +log "Setting script permissions..." +chmod +x ~/.config/scripts/*.sh ~/.config/scripts/activewindow \ + ~/.config/scripts/wallpaper-picker ~/.config/scripts/windowswitcher \ + ~/.config/scripts/workspace ~/.config/scripts/workspacefocus/*.sh \ + ~/.config/scripts/toggle-layout.sh ~/.config/scripts/timer-pick \ + ~/.config/scripts/timer-run ~/.config/scripts/ulwatchdog.sh \ + 2>/dev/null || true + +# 16. Install config updater and theme script +log "Installing config updater and theme script..." +mkdir -p ~/.config/config-updater +ln -sf ~/Dotfiles/desktopenvs/niri/config-updater/updater.conf ~/.config/config-updater/updater.conf +ln -sf ~/Dotfiles/desktopenvs/niri/config-updater/update-configs.sh ~/update-configs.sh +cp ~/Dotfiles/apply-theme.sh ~/apply-theme.sh +chmod +x ~/apply-theme.sh + +log "Niri installation complete. Reboot to start." diff --git a/setup/tui-install.sh b/setup/tui-install.sh index 27e5bbe..e3c9d1c 100755 --- a/setup/tui-install.sh +++ b/setup/tui-install.sh @@ -312,8 +312,9 @@ if $ANSWERFILE_MODE; then else DE=$(dialog --backtitle "$BACKTITLE" \ --title " Desktop Environment " \ - --menu "Select a desktop environment · Esc / none to skip:" 22 72 10 \ + --menu "Select a desktop environment · Esc / none to skip:" 24 72 11 \ "hyprlua" "HyprLua — Hyprland with Lua config (recommended)" \ + "niri" "Niri — scrollable-tiling Wayland compositor" \ "hyprland" "Hyprland — Wayland WM, hyprlang config (legacy)" \ "sway" "Sway — Wayland tiling WM" \ "kde-plasma" "KDE Plasma — feature-rich Wayland/X11 DE" \ @@ -421,7 +422,7 @@ if ! $ANSWERFILE_MODE; then [[ "$COMPONENTS" == *"core"* ]] && SUMMARY+=" ✦ Core packages\n" [[ "$COMPONENTS" == *"svc"* ]] && SUMMARY+=" ✦ Core services\n" [[ "$COMPONENTS" == *"shell"* ]] && SUMMARY+=" ✦ Shell setup\n" - [[ "$DE" != "none" ]] && SUMMARY+=" ✦ Desktop environment: $DE\n" + [[ "$DE" != "none" && "$DE" != "" ]] && SUMMARY+=" ✦ Desktop environment: $DE\n" if [[ -n "$SELECTED_APPS" ]]; then SUMMARY+="\n Applications:\n" @@ -518,6 +519,7 @@ count_steps "$COMPONENTS" "$DE" "$SELECTED_APPS" if [[ "$DE" != "none" ]]; then case "$DE" in hyprlua) run_module "HyprLua" "$MODULES/Desktop-Environments/hyprlua.sh" ;; + niri) run_module "Niri" "$MODULES/Desktop-Environments/niri.sh" ;; hyprland) run_module "Hyprland" "$MODULES/Desktop-Environments/hyprland.sh" ;; sway) run_module "Sway" "$MODULES/Desktop-Environments/sway.sh" ;; kde-plasma) run_module "KDE Plasma" "$MODULES/Desktop-Environments/kde-plasma.sh" ;;