Johan Rong 3 달 전
부모
커밋
1439ffc93d

+ 248 - 0
home/features/application/sway-mui/default.nix

@@ -0,0 +1,248 @@
+{ pkgs, lib, ... }:
+
+let
+  left = "j";
+  up = "k";
+  down = "l";
+  right = "oslash";
+  mod = "Mod1";
+  super = "Super";
+in
+{
+  imports = [
+    ./waybar.nix
+  ];
+
+  home.packages = with pkgs; [
+    
+  ];
+
+  wayland.windowManager.sway = {
+      enable = true;
+      checkConfig = true;
+      config = {
+        bars = [
+          {
+            command = "swaybar_command waybar";
+          }
+        ];
+        modes = {
+          resize = {
+            # Letters
+            ${left} = "resize shrink width 10 px or 10 ppt";
+            ${up} = "resize grow height 10 px or 10 ppt";
+            ${down} = "resize shrink height 10 px or 10 ppt";
+            ${right} = "resize grow width 10 px or 10 ppt";
+
+            # Arrow keys
+            "Left"  = "resize shrink width 10 px or 10 ppt";
+            "Down"  = "resize grow height 10 px or 10 ppt";
+            "Up"    = "resize shrink height 10 px or 10 ppt";
+            "Right" = "resize grow width 10 px or 10 ppt";
+
+            # Exit mode
+            "Escape" = "mode default";
+            "Return" = "mode default";
+          };
+          passthrough = { # Passthrough mode, disables all sway keybinds to let other apps use them, eg. use sway mod in other apps.
+            "${mod}+c" = "mode default";
+          };
+          futhark = {
+            "f" = "exec wtype ᚠ";
+            "u" = "exec wtype ᚢ";
+            "q" = "exec wtype ᚦ";
+            "a" = "exec wtype ᚨ";
+            "r" = "exec wtype ᚱ";
+            "k" = "exec wtype ᚲ";
+            "x" = "exec wtype ᚷ";
+            "v" = "exec wtype ᚹ";
+            "h" = "exec wtype ᚺ";
+            "n" = "exec wtype ᚾ";
+            "i" = "exec wtype ᛁ";
+            "j" = "exec wtype ᛃ";
+            "ae" = "exec wtype ᛇ";
+            "p" = "exec wtype ᛈ";
+            "z" = "exec wtype ᛉ";
+            "s" = "exec wtype ᛊ";
+            "t" = "exec wtype ᛏ";
+            "b" = "exec wtype ᛒ";
+            "e" = "exec wtype ᛖ";
+            "m" = "exec wtype ᛗ";
+            "l" = "exec wtype ᛚ";
+            "g" = "exec wtype ᛝ";
+            "d" = "exec wtype ᛞ";
+            "o" = "exec wtype ᛟ";
+            "Escape" = "mode default";
+          };
+        };
+        keybindings = {
+          "${mod}+Shift+r" = "reload";
+          "${mod}+Shift+q" = "kill";
+          "${mod}+d" = "exec rofi -show drun";
+          "${mod}+Return" = "exec alacritty";
+          "${super}+l" = "exec swaylock";
+          "${mod}+r" = "mode \"resize\"";
+
+          "${mod}+c" = "mode \"passthrough\"";
+          "${mod}+x" = "mode \"futhark\"";
+
+          "${mod}+Shift+e" = "exec /home/johron/.config/rofi/powermenu/type-1/powermenu.sh";
+
+          "${mod}+h" = "split h";
+          "${mod}+v" = "split v";
+          "${mod}+f" = "fullscreen toggle";
+          "${mod}+s" = "layout stacking";
+          "${mod}+t" = "layout tabbed";
+          "${mod}+e" = "layout toggle split";
+
+          "${mod}+Shift+space" = "floating toggle";
+          "${mod}+space" = "focus mode_toggle";
+          "${mod}+a" = "focus parent";
+
+          # Focus movement
+          "${mod}+${left}" = "focus left";
+          "${mod}+${down}" = "focus down";
+          "${mod}+${up}" = "focus up";
+          "${mod}+${right}" = "focus right";
+
+          # Focus movement (arrow keys)
+          "${mod}+Left" = "focus left";
+          "${mod}+Down" = "focus down";
+          "${mod}+Up" = "focus up";
+          "${mod}+Right" = "focus right";
+
+          # Move windows
+          "${mod}+Shift+${left}" = "move left";
+          "${mod}+Shift+${down}" = "move down";
+          "${mod}+Shift+${up}" = "move up";
+          "${mod}+Shift+${right}" = "move right";
+
+          # Move windows (arrow keys)
+          "${mod}+Shift+Left" = "move left";
+          "${mod}+Shift+Down" = "move down";
+          "${mod}+Shift+Up" = "move up";
+          "${mod}+Shift+Right" = "move right";
+
+          # Switch to workspace
+          "${mod}+1" = "workspace number 1";
+          "${mod}+2" = "workspace number 2";
+          "${mod}+3" = "workspace number 3";
+          "${mod}+4" = "workspace number 4";
+          "${mod}+5" = "workspace number 5";
+          "${mod}+6" = "workspace number 6";
+          "${mod}+7" = "workspace number 7";
+          "${mod}+8" = "workspace number 8";
+          "${mod}+9" = "workspace number 9";
+          "${mod}+0" = "workspace number 10";
+
+          ## Switch to secondary workspace
+          "${super}+1" = "workspace number 11";
+          "${super}+2" = "workspace number 12";
+          "${super}+3" = "workspace number 13";
+          "${super}+4" = "workspace number 14";
+          "${super}+5" = "workspace number 15";
+          "${super}+6" = "workspace number 16";
+          "${super}+7" = "workspace number 17";
+          "${super}+8" = "workspace number 18";
+          "${super}+9" = "workspace number 19";
+          "${super}+0" = "workspace number 20";
+
+          # Move to workspace
+          "${mod}+Shift+1" = "move container to workspace number 1";
+          "${mod}+Shift+2" = "move container to workspace number 2";
+          "${mod}+Shift+3" = "move container to workspace number 3";
+          "${mod}+Shift+4" = "move container to workspace number 4";
+          "${mod}+Shift+5" = "move container to workspace number 5";
+          "${mod}+Shift+6" = "move container to workspace number 6";
+          "${mod}+Shift+7" = "move container to workspace number 7";
+          "${mod}+Shift+8" = "move container to workspace number 8";
+          "${mod}+Shift+9" = "move container to workspace number 9";
+          "${mod}+Shift+0" = "move container to workspace number 10";
+
+          ## Move to secondary workspace
+          "${super}+Shift+1" = "move container to workspace number 11";
+          "${super}+Shift+2" = "move container to workspace number 12";
+          "${super}+Shift+3" = "move container to workspace number 13";
+          "${super}+Shift+4" = "move container to workspace number 14";
+          "${super}+Shift+5" = "move container to workspace number 15";
+          "${super}+Shift+6" = "move container to workspace number 16";
+          "${super}+Shift+7" = "move container to workspace number 17";
+          "${super}+Shift+8" = "move container to workspace number 18";
+          "${super}+Shift+9" = "move container to workspace number 19";
+          "${super}+Shift+0" = "move container to workspace number 20";
+
+          # Multimedia
+          XF86AudioMute = "exec wpctl set-mute @DEFAULT_SINK@ toggle";
+          XF86AudioPlay = "exec playerctl play-pause";
+          XF86AudioPause = "exec playerctl pause";
+          XF86AudioNext = "exec playerctl next";
+          XF86AudioPrev = "exec playerctl previous";
+          XF86AudioRaiseVolume = "exec wpctl set-volume @DEFAULT_SINK@ 5%+";
+          XF86AudioLowerVolume = "exec wpctl set-volume @DEFAULT_SINK@ 5%-";
+
+          # Applications
+          "${super}+q" = "exec firefox";
+          "${super}+e" = "exec dolphin";
+          "${super}+s" = "exec spotify";
+          "${super}+d" = "exec discord";
+
+          "${super}+v" = "exec cliphist list | rofi -dmenu | cliphist decode | wl-copy";
+          "${super}+Shift+s" = "exec flameshot gui";
+          "${super}+Shift+c" = "exec hyprpicker --autocopy";
+
+          # Scripts
+          "${mod}+Control+a" = "exec $HOME/.config/waybar/mic-mute.sh";
+          "${mod}+Control+s" = "exec $HOME/.config/waybar/output-mute.sh";
+        };
+
+        window.commands = [
+          { command = "floating enable"; criteria.instance = "spotify"; }
+          #{ command = "floating enable"; criteria.class = "steam"; }
+        ];
+
+        input = {
+          "*" = {
+           xkb_layout = "no";
+           #xkb_variant = "cole";
+        };
+      };
+    };
+    extraConfig = ''
+      output DP-2 pos 0 0 mode 1920x1080@143.981Hz
+      output HDMI-A-1 mode 1920x1080@143.981Hz
+
+      workspace 1 output DP-2
+      workspace 2 output DP-2
+      workspace 3 output DP-2
+
+      workspace 11 output HDMI-A-1
+      workspace 12 output HDMI-A-1
+      workspace 13 output HDMI-A-1
+      workspace 14 output HDMI-A-1
+
+      exec wl-paste --watch cliphist store
+      exec flameshot
+
+      seat seat0 xcursor_theme Notwaita-Black 20
+
+      ## Bind Alt+Shift+e to show a Swaynag exit confirmation
+      #bindsym Mod1+Shift+e exec swaynag -t warning \
+      #  -m "Are you sure you want to exit Sway?" \
+      #  -b "Exit" "swaymsg exit" \
+      #  -b "Reboot" "reboot"
+
+      exec swaybg -i "$HOME/Pictures/Backgrounds/reef-1920x1080-2.png" -m fill
+
+      input * xkb_options compose:rctrl
+
+      exec_always {
+        systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK
+        lxqt-policykit-agent
+        swayidle \
+          timeout 600 'swaylock -f' \
+          timeout 1200 'systemctl suspend' \
+          before-sleep 'swaylock -f'
+      }
+    '';
+  };
+}

+ 132 - 0
home/features/application/sway-mui/scripts.nix

@@ -0,0 +1,132 @@
+{ pkgs, lib, ... }:
+{
+  home = {
+    file = {
+      clock = {
+        target = ".config/waybar/clock.sh";
+        text = ''
+        # Generate the formatted date string
+        formatted_date=$(LC_TIME=nb_NO.UTF-8 date +"%H:%M %A, %b %d" | tr '[:upper:]' '[:lower:]' | sed 's/\.//g')
+
+        # Output as JSON for Waybar
+        printf '{"text": "%s"}\n' "$formatted_date"
+        '';
+        executable = true;
+      };
+      memory = {
+        target = ".config/waybar/memory.sh";
+        text = ''
+          free -m | awk '
+          /^Mem:/ {
+              current_gb = $3 / 1024;
+              total_gb = $2 / 1024;
+              printf "{\"text\": \"%.1fG/%.1fG\"}\n", current_gb, total_gb
+          }'
+        '';
+        executable = true;
+      };
+      volume = {
+        target = ".config/waybar/volume.sh";
+        text = ''
+          VOLUME_INFO=$(wpctl get-volume @DEFAULT_AUDIO_SINK@)
+          VOL_NUM=$(echo "$VOLUME_INFO" | awk '{print $2}')
+          VOL_PERC=$(awk -v n="$VOL_NUM" 'BEGIN {print int(n * 100)}')
+
+          if [[ "$VOLUME_INFO" == *"[MUTED]"* ]]; then
+              RESULT="M($VOL_PERC%)"
+          else
+              RESULT="$VOL_PERC%"
+          fi
+
+          echo "{\"text\": \"$RESULT\"}"
+        '';
+        executable = true;
+      };
+      mic = {
+        target = ".config/waybar/mic.sh";
+        text = ''
+          VOLUME_INFO=$(wpctl get-volume @DEFAULT_AUDIO_SOURCE@)
+          VOL_NUM=$(echo "$VOLUME_INFO" | awk '{print $2}')
+          VOL_PERC=$(awk -v n="$VOL_NUM" 'BEGIN {print int(n * 100)}')
+
+          if [[ "$VOLUME_INFO" == *"[MUTED]"* ]]; then
+              RESULT="M($VOL_PERC%)"
+          else
+              RESULT="$VOL_PERC%"
+          fi
+
+          echo "{\"text\": \"$RESULT\"}"
+        '';
+        executable = true;
+      };
+      net = {
+        target = ".config/waybar/net.sh";
+        executable = true;
+        text = ''
+          #!/usr/bin/env bash
+
+          # Get default network interface
+          DEVICE=$(ip route | awk '/default/ {print $5; exit}')
+
+          if [[ -n "$DEVICE" ]]; then
+              IP=$(ip -4 addr show "$DEVICE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1)
+
+              RESULT="$DEVICE"
+          else
+              RESULT="Disconnected"
+          fi
+
+          echo "{\"text\": \"$RESULT\"}"
+        '';
+      };
+      mic-mute = {
+        target = ".config/waybar/mic-mute.sh";
+        text = ''
+          #!/usr/bin/env bash
+
+          # Toggle mute
+          amixer set 'Capture' toggle
+
+          # Check new state
+          if amixer get Capture | grep -q '\[off\]'; then
+            notify-send "Microphone Muted" "Your mic has been muted." -i microphone-sensitivity-muted-symbolic
+          else
+            notify-send "Microphone Unmuted" "Your mic is live." -i microphone-sensitivity-high-symbolic  
+          fi
+        '';
+        executable = true;
+      };
+      output-mute = {
+        target = ".config/waybar/output-mute.sh";
+        text = ''
+          #!/usr/bin/env bash
+
+          # Toggle mute
+          amixer set 'Master' toggle
+
+          # Check new state
+          if amixer get Master | grep -q '\[off\]'; then
+            notify-send "Master Muted" "You may no longer hear." -i audio-volume-muted-symbolic
+          else
+            notify-send "Master Unmuted" "You may hear now." -i audio-volume-high-symbolic  
+          fi
+        '';
+        executable = true;
+      };
+      #futhark-xkb = {
+      #  target = ".config/xkb/symbols/futhark";
+      #  text = ''
+      #    default partial alphanumeric_keys
+      #    xkb_symbols "basic" {
+#
+      #        name[Group1]= "Futhark";
+#
+      #        key <AD04> { [ U16A0 ] }; // f -> ᚠ
+#
+      #        include "no(basic)"
+      #    };
+      #  '';
+      #};
+    };
+  };
+}

+ 158 - 0
home/features/application/sway-mui/waybar.nix

@@ -0,0 +1,158 @@
+{ pkgs, lib, ... }:
+{
+  programs.waybar = {
+    enable = true;
+    settings = {
+      main = {
+        layer = "top";
+        position = "bottom";
+        height = 32;
+        spacing = 2;
+
+        modules-left = [
+          "sway/workspaces"
+          "mpris"
+        ];
+        modules-center = [
+          "clock"
+        ];
+        modules-right = [
+          "pulseaudio"
+          "network"
+          "battery"
+          "tray"
+        ];
+
+        clock = {
+          format = "󰥔  {:%H:%M}";
+          tooltip = false;
+        };
+
+        battery = {
+          format = "{icon} {capacity}%";
+          format-icons = [
+            "󰁺"
+            "󰁻"
+            "󰁼"
+            "󰁽"
+            "󰁾"
+            "󰁿"
+            "󰂀"
+            "󰂁"
+            "󰂂"
+            "󰁹"
+          ];
+        };
+
+        network = {
+          format-wifi = "";
+          format-ethernet = "";
+          tooltip-format = "{essid}";
+        };
+
+        pulseaudio = {
+          format = "{icon} {volume}%";
+          format-icons = {
+            default = [
+              "󰕿"
+              "󰖀"
+              "󰕾"
+            ];
+          };
+        };
+
+        mpris = {
+          format = "{artist} - {title}";
+          format-paused = "{artist} - {title}";
+          max-length = 25;
+        };
+      };
+    };
+    style = ''
+      * {
+        border: none;
+        font-family: "Roboto", "Material Symbols Rounded";
+        font-size: 14px;
+        min-height: 0;
+      }
+
+      window#waybar {
+        background: rgb(26,28,23);
+        margin-top: 8px;
+        border-radius: 0px;
+      }
+
+      /* Shared module styling */
+      #clock,
+      #battery,
+      #network,
+      #pulseaudio,
+      #tray,
+      #mpris,
+      #workspaces {
+        background: rgb(35,39,29);
+
+        color: #e6e1e5;
+        font-weight: 600;
+
+        min-width: 12px;
+        min-height: 12px;
+        padding: 0 6px;
+        margin: 2px 2px;
+        border-radius: 10px;
+
+        border: 1px solid rgba(255,255,255,0.08);
+      }
+
+      #workspaces {
+        padding: 0;
+      }
+
+      #workspaces button label {
+        padding: 0;
+        margin: 0;
+      }
+
+      #workspaces button {
+        color: #c4c7c5;
+        padding: 0 10px;
+        border-radius: 10px;
+        transition: all 0.2s ease;
+      }
+
+      #workspaces button.active,
+      #workspaces button.focused {
+        background: rgba(103, 80, 164, 0.4);
+        color: white;
+      }
+
+      #workspaces button:hover {
+        background: rgba(255,255,255,0.08);
+      }
+
+      #mpris.playing {
+        background: rgba(139, 188, 255, 0.2);
+      }
+
+      #mpris.spotify.playing {
+        background: rgba(29,185,84,0.2);
+      }
+
+      #mpris.firefox.playing {
+        background: rgba(255,102,42,0.2);
+      }
+
+      #battery {
+      }
+
+      #network {
+      }
+
+      #pulseaudio {
+      }
+
+      #clock {
+      }
+    '';
+  };
+}

+ 1 - 1
home/flavors/desktop/sway/default.nix

@@ -1,7 +1,7 @@
 { pkgs, lib, ... }:
 {
   imports = [
-    ../../../features/application/sway
+    ../../../features/application/sway-mui
     ../../../features/application/mako.nix
     ../../../features/application/rofi.nix
     ../../../features/application/files.nix