From 8c10086d0a256485a9a513435181e546a1d070d6 Mon Sep 17 00:00:00 2001 From: Haelnorr Date: Mon, 29 Dec 2025 20:35:16 +1100 Subject: [PATCH] updated config for wayland/hyprland --- .config/.gitignore | 14 + .config/alacritty/.gitignore | 1 + .config/bat/.gitignore | 1 + .config/btop/.gitignore | 1 + .config/hypr/.gitignore | 1 + .config/hypr/background | 1453 +++++++++++++++++++++++++ .config/hypr/hyprland.conf | 337 ++++++ .config/hypr/hyprlock.conf | 77 ++ .config/hypr/hyprpaper.conf | 9 + .config/hypr/mocha.conf | 78 ++ .config/hypr/restart_apps.sh | 8 + .config/i3/.gitignore | 1 + .config/neofetch/.gitignore | 1 + .config/picom/.gitignore | 1 + .config/polybar/.gitignore | 1 + .config/rofi/.gitignore | 1 + .config/starship/.gitignore | 1 + .config/tmux/.gitignore | 2 + .config/waybar/.gitignore | 1 + .config/waybar/audio_output_status.sh | 45 + .config/waybar/audio_output_switch.sh | 48 + .config/waybar/config.jsonc | 205 ++++ .config/waybar/mediaplayer.py | 222 ++++ .config/waybar/mocha.css | 26 + .config/waybar/power_menu.xml | 33 + .config/waybar/style.css | 11 + .gitignore | 13 +- .local/.gitignore | 3 + .local/bin/.gitignore | 1 + .local/bin/movie | 10 - .zshrc | 2 +- 31 files changed, 2586 insertions(+), 22 deletions(-) create mode 100644 .config/.gitignore create mode 100644 .config/alacritty/.gitignore create mode 100644 .config/bat/.gitignore create mode 100644 .config/btop/.gitignore create mode 100644 .config/hypr/.gitignore create mode 100644 .config/hypr/background create mode 100644 .config/hypr/hyprland.conf create mode 100644 .config/hypr/hyprlock.conf create mode 100644 .config/hypr/hyprpaper.conf create mode 100644 .config/hypr/mocha.conf create mode 100755 .config/hypr/restart_apps.sh create mode 100644 .config/i3/.gitignore create mode 100644 .config/neofetch/.gitignore create mode 100644 .config/picom/.gitignore create mode 100644 .config/polybar/.gitignore create mode 100644 .config/rofi/.gitignore create mode 100644 .config/starship/.gitignore create mode 100644 .config/tmux/.gitignore create mode 100644 .config/waybar/.gitignore create mode 100755 .config/waybar/audio_output_status.sh create mode 100755 .config/waybar/audio_output_switch.sh create mode 100644 .config/waybar/config.jsonc create mode 100755 .config/waybar/mediaplayer.py create mode 100644 .config/waybar/mocha.css create mode 100644 .config/waybar/power_menu.xml create mode 100644 .config/waybar/style.css create mode 100644 .local/.gitignore create mode 100644 .local/bin/.gitignore delete mode 100755 .local/bin/movie diff --git a/.config/.gitignore b/.config/.gitignore new file mode 100644 index 0000000..27cff54 --- /dev/null +++ b/.config/.gitignore @@ -0,0 +1,14 @@ +* +!.gitignore +!alacritty/ +!bat/ +!btop/ +!i3/ +!neofetch/ +!picom/ +!polybar/ +!rofi/ +!starship/ +!tmux/ +!waybar/ +!hypr/ diff --git a/.config/alacritty/.gitignore b/.config/alacritty/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/alacritty/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/bat/.gitignore b/.config/bat/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/bat/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/btop/.gitignore b/.config/btop/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/btop/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/hypr/.gitignore b/.config/hypr/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/hypr/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/hypr/background b/.config/hypr/background new file mode 100644 index 0000000..d52dae7 --- /dev/null +++ b/.config/hypr/background @@ -0,0 +1,1453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + hyprlock/assets/mocha.webp at main · catppuccin/hyprlock · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ Skip to content + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + +
+
+
+ + + + + + + + + + + + + +
+ +
+ +
+ +
+ + + + / + + hyprlock + + + Public +
+ + +
+ +
+ + +
+
+ +
+
+ + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ +
+
+ +
+ +
+

Footer

+ + + + +
+
+ + + + + © 2025 GitHub, Inc. + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+ + + diff --git a/.config/hypr/hyprland.conf b/.config/hypr/hyprland.conf new file mode 100644 index 0000000..a34e835 --- /dev/null +++ b/.config/hypr/hyprland.conf @@ -0,0 +1,337 @@ +source=~/.config/hypr/mocha.conf +# This is an example Hyprland config file. +# Refer to the wiki for more information. +# https://wiki.hypr.land/Configuring/ + +# Please note not all available settings / options are set here. +# For a full list, see the wiki + +# You can split this configuration into multiple files +# Create your files separately and then link them to this file like this: +# source = ~/.config/hypr/myColors.conf + + +################ +### MONITORS ### +################ + +# See https://wiki.hypr.land/Configuring/Monitors/ +monitor=DP-3,2560x1440@179.96,0x0,1.25 +monitor=HDMI-A-1,1920x1080@60,2048x0,1 +monitor=DP-2,1920x1080@60,-1080x-450,1,transform,1 + +################### +### MY PROGRAMS ### +################### + +# See https://wiki.hypr.land/Configuring/Keywords/ + +# Set programs that you use +$terminal = alacritty +$fileManager = thunar +$menu = wofi --show drun --insensitive --allow-images + + +################# +### AUTOSTART ### +################# + +# Autostart necessary processes (like notifications daemons, status bars, etc.) +# Or execute your favorite apps at launch like this: + +# exec-once = $terminal +# exec-once = nm-applet & +# exec-once = waybar & hyprpaper & firefox +$autostart = "waybar & hyprpaper" +exec-once = sh -c "$autostart" + + +############################# +### ENVIRONMENT VARIABLES ### +############################# + +# See https://wiki.hypr.land/Configuring/Environment-variables/ + +env = XCURSOR_SIZE,24 +env = HYPRCURSOR_SIZE,24 + + +################### +### PERMISSIONS ### +################### + +# See https://wiki.hypr.land/Configuring/Permissions/ +# Please note permission changes here require a Hyprland restart and are not applied on-the-fly +# for security reasons + +# ecosystem { +# enforce_permissions = 1 +# } + +# permission = /usr/(bin|local/bin)/grim, screencopy, allow +# permission = /usr/(lib|libexec|lib64)/xdg-desktop-portal-hyprland, screencopy, allow +# permission = /usr/(bin|local/bin)/hyprpm, plugin, allow + + +##################### +### LOOK AND FEEL ### +##################### + +# Refer to https://wiki.hypr.land/Configuring/Variables/ + +# https://wiki.hypr.land/Configuring/Variables/#general +general { + gaps_in = 5 + gaps_out = 10 + + border_size = 2 + + # https://wiki.hypr.land/Configuring/Variables/#variable-types for info about colors + col.active_border = $blue $green 45deg + col.inactive_border = $surface0 + + # Set to true enable resizing windows by clicking and dragging on borders and gaps + resize_on_border = false + + # Please see https://wiki.hypr.land/Configuring/Tearing/ before you turn this on + allow_tearing = false + + layout = dwindle +} + +# https://wiki.hypr.land/Configuring/Variables/#decoration +decoration { + rounding = 10 + rounding_power = 2 + + # Change transparency of focused and unfocused windows + active_opacity = 1.0 + inactive_opacity = 1.0 + + shadow { + enabled = true + range = 4 + render_power = 3 + color = $crust + } + + # https://wiki.hypr.land/Configuring/Variables/#blur + blur { + enabled = true + size = 3 + passes = 1 + + vibrancy = 0.1696 + } +} + +# https://wiki.hypr.land/Configuring/Variables/#animations +animations { + enabled = yes, please :) + + # Default curves, see https://wiki.hypr.land/Configuring/Animations/#curves + # NAME, X0, Y0, X1, Y1 + bezier = easeOutQuint, 0.23, 1, 0.32, 1 + bezier = easeInOutCubic, 0.65, 0.05, 0.36, 1 + bezier = linear, 0, 0, 1, 1 + bezier = almostLinear, 0.5, 0.5, 0.75, 1 + bezier = quick, 0.15, 0, 0.1, 1 + + # Default animations, see https://wiki.hypr.land/Configuring/Animations/ + # NAME, ONOFF, SPEED, CURVE, [STYLE] + animation = global, 1, 10, default + animation = border, 1, 5.39, easeOutQuint + animation = windows, 1, 4.79, easeOutQuint + animation = windowsIn, 1, 4.1, easeOutQuint, popin 87% + animation = windowsOut, 1, 1.49, linear, popin 87% + animation = fadeIn, 1, 1.73, almostLinear + animation = fadeOut, 1, 1.46, almostLinear + animation = fade, 1, 3.03, quick + animation = layers, 1, 3.81, easeOutQuint + animation = layersIn, 1, 4, easeOutQuint, fade + animation = layersOut, 1, 1.5, linear, fade + animation = fadeLayersIn, 1, 1.79, almostLinear + animation = fadeLayersOut, 1, 1.39, almostLinear + animation = workspaces, 1, 1.94, almostLinear, fade + animation = workspacesIn, 1, 1.21, almostLinear, fade + animation = workspacesOut, 1, 1.94, almostLinear, fade + animation = zoomFactor, 1, 7, quick +} + +# Ref https://wiki.hypr.land/Configuring/Workspace-Rules/ +# "Smart gaps" / "No gaps when only" +# uncomment all if you wish to use that. +# workspace = w[tv1], gapsout:0, gapsin:0 +# workspace = f[1], gapsout:0, gapsin:0 +# windowrule = bordersize 0, floating:0, onworkspace:w[tv1] +# windowrule = rounding 0, floating:0, onworkspace:w[tv1] +# windowrule = bordersize 0, floating:0, onworkspace:f[1] +# windowrule = rounding 0, floating:0, onworkspace:f[1] + +# See https://wiki.hypr.land/Configuring/Dwindle-Layout/ for more +dwindle { + pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below + preserve_split = true # You probably want this +} + +# See https://wiki.hypr.land/Configuring/Master-Layout/ for more +master { + new_status = master +} + +# https://wiki.hypr.land/Configuring/Variables/#misc +misc { + force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers + disable_hyprland_logo = false # If true disables the random hyprland logo / anime girl background. :( +} + + +############# +### INPUT ### +############# + +# https://wiki.hypr.land/Configuring/Variables/#input +input { + kb_layout = us + kb_variant = + kb_model = + kb_options = + kb_rules = + + follow_mouse = 1 + + sensitivity = 0 # -1.0 - 1.0, 0 means no modification. + + touchpad { + natural_scroll = false + } +} + +# See https://wiki.hypr.land/Configuring/Gestures +gesture = 3, horizontal, workspace + +# Example per-device config +# See https://wiki.hypr.land/Configuring/Keywords/#per-device-input-configs for more +device { + name = epic-mouse-v1 + sensitivity = -0.5 +} + + +################### +### KEYBINDINGS ### +################### +num_lock_by_default = true + +# See https://wiki.hypr.land/Configuring/Keywords/ +$mainMod = SUPER # Sets "Windows" key as main modifier + +# Example binds, see https://wiki.hypr.land/Configuring/Binds/ for more +bind = $mainMod, Return, exec, $terminal +bind = $mainMod SHIFT, Q, killactive, +bind = $mainMod SHIFT, E, exit, +bind = $mainMod, E, exec, $fileManager +bind = $mainMod, V, togglefloating, +bind = $mainMod, D, exec, $menu +#bind = $mainMod, P, pseudo, # dwindle +#bind = $mainMod, J, togglesplit, # dwindle + +# Move focus with mainMod + vim bindings +bind = $mainMod, H, movefocus, l +bind = $mainMod, L, movefocus, r +bind = $mainMod, K, movefocus, u +bind = $mainMod, J, movefocus, d + +# Move focused window within the current workspace +bind = $mainMod SHIFT, H, movewindow, l +bind = $mainMod SHIFT, L, movewindow, r +bind = $mainMod SHIFT, K, movewindow, u +bind = $mainMod SHIFT, J, movewindow, d + +# Switch workspaces with mainMod + [0-9] +bind = $mainMod, 1, workspace, 1 +bind = $mainMod, 2, workspace, 2 +bind = $mainMod, 3, workspace, 3 +bind = $mainMod, 4, workspace, 4 +bind = $mainMod, 5, workspace, 5 +bind = $mainMod, 6, workspace, 6 +bind = $mainMod, 7, workspace, 7 +bind = $mainMod, 8, workspace, 8 +bind = $mainMod, 9, workspace, 9 +bind = $mainMod, 0, workspace, 10 + +# Move active window to a workspace with mainMod + SHIFT + [0-9] +bind = $mainMod SHIFT, 1, movetoworkspace, 1 +bind = $mainMod SHIFT, 2, movetoworkspace, 2 +bind = $mainMod SHIFT, 3, movetoworkspace, 3 +bind = $mainMod SHIFT, 4, movetoworkspace, 4 +bind = $mainMod SHIFT, 5, movetoworkspace, 5 +bind = $mainMod SHIFT, 6, movetoworkspace, 6 +bind = $mainMod SHIFT, 7, movetoworkspace, 7 +bind = $mainMod SHIFT, 8, movetoworkspace, 8 +bind = $mainMod SHIFT, 9, movetoworkspace, 9 +bind = $mainMod SHIFT, 0, movetoworkspace, 10 + +# Example special workspace (scratchpad) +bind = $mainMod, S, togglespecialworkspace, magic +bind = $mainMod SHIFT, S, movetoworkspace, special:magic + +# Scroll through existing workspaces with mainMod + scroll +bind = $mainMod, mouse_down, workspace, e+1 +bind = $mainMod, mouse_up, workspace, e-1 + +# Move/resize windows with mainMod + LMB/RMB and dragging +bindm = $mainMod, mouse:272, movewindow +bindm = $mainMod, mouse:273, resizewindow + +# Requires playerctl +bindl = , XF86AudioNext, exec, playerctl next +bindl = , XF86AudioPause, exec, playerctl play-pause +bindl = , XF86AudioPlay, exec, playerctl play-pause +bindl = , XF86AudioPrev, exec, playerctl previous + +# Lockscreen +bind = $mainMod SHIFT, X, exec, hyprlock + +# Sleep / Hibernate +bind = $mainMod SHIFT, Period, exec, systemctl suspend +bind = $mainMod SHIFT, Comma, exec, systemctl hibernate + +# Refresh autostart apps +bind = $mainMod SHIFT, R, exec, $HOME/.config/hypr/restart_apps.sh $autostart + +# Screenshots +bind = , PRINT, exec, hyprshot -m region --clipboard-only +bind = SHIFT, PRINT, exec, hyprshot -m output --clipboard-only + + +############################## +### WINDOWS AND WORKSPACES ### +############################## + +# See https://wiki.hypr.land/Configuring/Window-Rules/ for more +# See https://wiki.hypr.land/Configuring/Workspace-Rules/ for workspace rules + +# Example windowrule +# windowrule = float,class:^(kitty)$,title:^(kitty)$ + +# Ignore maximize requests from apps. You'll probably like this. +windowrule = suppressevent maximize, class:.* + +# Fix some dragging issues with XWayland +windowrule = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0 + +# Monitor 1: DP-3 +workspace = 1, monitor:DP-3 +workspace = 4, monitor:DP-3 +workspace = 7, monitor:DP-3 + +# Monitor 2: HDMI-A-1 +workspace = 2, monitor:HDMI-A-1 +workspace = 5, monitor:HDMI-A-1 +workspace = 8, monitor:HDMI-A-1 + +# Monitor 3: DP-2 +workspace = 3, monitor:DP-2 +workspace = 6, monitor:DP-2 +workspace = 9, monitor:DP-2 diff --git a/.config/hypr/hyprlock.conf b/.config/hypr/hyprlock.conf new file mode 100644 index 0000000..19b75ae --- /dev/null +++ b/.config/hypr/hyprlock.conf @@ -0,0 +1,77 @@ +source = $HOME/.config/hypr/mocha.conf + +$accent = $mauve +$accentAlpha = $mauveAlpha +$font = JetBrainsMono Nerd Font + +# GENERAL +general { + hide_cursor = true +} + +# BACKGROUND +background { + monitor = + path = $HOME/.config/hypr/background + blur_passes = 0 + color = $base +} + +# LAYOUT +label { + monitor = DP-3 + text = Layout: $LAYOUT + color = $text + font_size = 25 + font_family = $font + position = 30, -30 + halign = left + valign = top +} + +# TIME +label { + monitor = DP-3 + text = $TIME + color = $text + font_size = 90 + font_family = $font + position = -30, 0 + halign = right + valign = top +} + +# DATE +label { + monitor = DP-3 + text = cmd[update:43200000] date +"%A, %d %B %Y" + color = $text + font_size = 25 + font_family = $font + position = -30, -150 + halign = right + valign = top +} + +# INPUT FIELD +input-field { + monitor = DP-3 + size = 300, 60 + outline_thickness = 4 + dots_size = 0.2 + dots_spacing = 0.2 + dots_center = true + outer_color = $accent + inner_color = $surface0 + font_color = $text + fade_on_empty = false + placeholder_text = 󰌾 Logged in as $USER + hide_input = false + check_color = $accent + fail_color = $red + fail_text = $FAIL ($ATTEMPTS) + capslock_color = $yellow + position = 0, -47 + halign = center + valign = center +} diff --git a/.config/hypr/hyprpaper.conf b/.config/hypr/hyprpaper.conf new file mode 100644 index 0000000..1fb985a --- /dev/null +++ b/.config/hypr/hyprpaper.conf @@ -0,0 +1,9 @@ +$wallpaper_1 = $HOME/.wallpapers/1.jpg +$wallpaper_2 = $HOME/.wallpapers/2.jpg +$wallpaper_3 = $HOME/.wallpapers/3.jpg +preload = $wallpaper_1 +preload = $wallpaper_2 +preload = $wallpaper_3 +wallpaper = DP-3,$wallpaper_1 +wallpaper = HDMI-A-1,$wallpaper_2 +wallpaper = DP-2,$wallpaper_3 diff --git a/.config/hypr/mocha.conf b/.config/hypr/mocha.conf new file mode 100644 index 0000000..8ccb56a --- /dev/null +++ b/.config/hypr/mocha.conf @@ -0,0 +1,78 @@ + +$rosewater = rgb(f5e0dc) +$rosewaterAlpha = f5e0dc + +$flamingo = rgb(f2cdcd) +$flamingoAlpha = f2cdcd + +$pink = rgb(f5c2e7) +$pinkAlpha = f5c2e7 + +$mauve = rgb(cba6f7) +$mauveAlpha = cba6f7 + +$red = rgb(f38ba8) +$redAlpha = f38ba8 + +$maroon = rgb(eba0ac) +$maroonAlpha = eba0ac + +$peach = rgb(fab387) +$peachAlpha = fab387 + +$yellow = rgb(f9e2af) +$yellowAlpha = f9e2af + +$green = rgb(a6e3a1) +$greenAlpha = a6e3a1 + +$teal = rgb(94e2d5) +$tealAlpha = 94e2d5 + +$sky = rgb(89dceb) +$skyAlpha = 89dceb + +$sapphire = rgb(74c7ec) +$sapphireAlpha = 74c7ec + +$blue = rgb(89b4fa) +$blueAlpha = 89b4fa + +$lavender = rgb(b4befe) +$lavenderAlpha = b4befe + +$text = rgb(cdd6f4) +$textAlpha = cdd6f4 + +$subtext1 = rgb(bac2de) +$subtext1Alpha = bac2de + +$subtext0 = rgb(a6adc8) +$subtext0Alpha = a6adc8 + +$overlay2 = rgb(9399b2) +$overlay2Alpha = 9399b2 + +$overlay1 = rgb(7f849c) +$overlay1Alpha = 7f849c + +$overlay0 = rgb(6c7086) +$overlay0Alpha = 6c7086 + +$surface2 = rgb(585b70) +$surface2Alpha = 585b70 + +$surface1 = rgb(45475a) +$surface1Alpha = 45475a + +$surface0 = rgb(313244) +$surface0Alpha = 313244 + +$base = rgb(1e1e2e) +$baseAlpha = 1e1e2e + +$mantle = rgb(181825) +$mantleAlpha = 181825 + +$crust = rgb(11111b) +$crustAlpha = 11111b diff --git a/.config/hypr/restart_apps.sh b/.config/hypr/restart_apps.sh new file mode 100755 index 0000000..b8b1e59 --- /dev/null +++ b/.config/hypr/restart_apps.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +LOG=$HOME/.config/hypr/temp.log +exec > $LOG 2>&1 + +RUN_STRING=$1 +KILL_STRING=${RUN_STRING//" & "/" "} +killall $KILL_STRING || true +exec sh -c "$RUN_STRING" diff --git a/.config/i3/.gitignore b/.config/i3/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/i3/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/neofetch/.gitignore b/.config/neofetch/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/neofetch/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/picom/.gitignore b/.config/picom/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/picom/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/polybar/.gitignore b/.config/polybar/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/polybar/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/rofi/.gitignore b/.config/rofi/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/rofi/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/starship/.gitignore b/.config/starship/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/starship/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/tmux/.gitignore b/.config/tmux/.gitignore new file mode 100644 index 0000000..5a23f60 --- /dev/null +++ b/.config/tmux/.gitignore @@ -0,0 +1,2 @@ +* +!tmux.conf diff --git a/.config/waybar/.gitignore b/.config/waybar/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/waybar/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/waybar/audio_output_status.sh b/.config/waybar/audio_output_status.sh new file mode 100755 index 0000000..3cdcafa --- /dev/null +++ b/.config/waybar/audio_output_status.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +get_default_sink_label() { + # Get the ID of the default sink (output device) + default_sink=$(wpctl status 2>/dev/null | awk '/Sinks:/,/Sources:/' | awk '/\*/ {print $3}' | tr -d '.') + + if [ -z "$default_sink" ]; then + echo "No default audio output device found" + exit 1 + fi + + # Get the description or fallback to node.name + device_name=$(wpctl inspect "$default_sink" 2>/dev/null | awk -F '"' '/node.description/ {print $2}') + + if [ -z "$device_name" ]; then + device_name=$(wpctl inspect "$default_sink" 2>/dev/null | awk -F '"' '/node.name/ {print $2}') + fi + + # Map known device names to labels + case "$device_name" in + "Starship/Matisse HD Audio Controller Analog Stereo") + label="Speakers" + ;; + "Yeti Stereo Microphone Analog Stereo") + label="Earphones" + ;; + *) + label="$device_name" + ;; + esac + + # Output the label + #echo "{\"text\":\"$label\",\"alt\":\"$device_name\"}" + printf '{"text":"%s","alt":"%s"}\n' "$label" "$device_name" +} + +get_default_sink_label + +pactl subscribe 2>/dev/null | while read -r line; do + # Filter for default sink or node changes + if echo "$line" | grep -qE "Event 'change' on sink #"; then + # Overwrite previous output + get_default_sink_label + fi +done diff --git a/.config/waybar/audio_output_switch.sh b/.config/waybar/audio_output_switch.sh new file mode 100755 index 0000000..7e49e19 --- /dev/null +++ b/.config/waybar/audio_output_switch.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Function to get the ID of the default sink +get_default_sink_id() { + wpctl status | awk '/Sinks:/,/Sources:/' | awk '/\*/ {print $3}' | tr -d '.' +} + +# Function to get the description of a sink by ID +get_sink_description() { + wpctl inspect "$1" | awk -F '"' '/node.description/ {print $2}' +} + +# Get current default sink ID +current_sink_id=$(get_default_sink_id) + +# If no sink found, exit +if [ -z "$current_sink_id" ]; then + echo "No default audio output device found" + exit 1 +fi + +# Get its description +current_description=$(get_sink_description "$current_sink_id") + +# Decide target device name based on current device +case "$current_description" in + "Starship/Matisse HD Audio Controller Analog Stereo") + target_description="Yeti Stereo Microphone Analog Stereo" + ;; + "Yeti Stereo Microphone Analog Stereo") + target_description="Starship/Matisse HD Audio Controller Analog Stereo" + ;; + *) + target_description="Yeti Stereo Microphone Analog Stereo" + ;; +esac + +# Find the sink ID of the target device +target_sink_id=$(wpctl status | awk '/Sinks:/,/Sources:/' | grep "$target_description" | awk '{print $2}' | tr -d '.') + +# If target sink found, switch to it +if [ -n "$target_sink_id" ]; then + wpctl set-default "$target_sink_id" + echo "Switched audio output to: $target_description" +else + echo "Target device '$target_description' not found." + exit 1 +fi diff --git a/.config/waybar/config.jsonc b/.config/waybar/config.jsonc new file mode 100644 index 0000000..dbdd834 --- /dev/null +++ b/.config/waybar/config.jsonc @@ -0,0 +1,205 @@ +// -*- mode: jsonc -*- +[ + { + "output": "!DP-2", + "height": 30, // Waybar height (to be removed for auto height) + "spacing": 4, // Gaps between modules (4px) + "modules-left": [ + "hyprland/workspaces", + "custom/sep", + "custom/media" + ], + "modules-center": [ + "hyprland/window" + ], + "modules-right": [ + "pulseaudio", + "custom/audio_device", + "custom/sep", + "network", + "custom/sep", + "cpu", + "custom/sep", + "memory", + "custom/sep", + "clock", + "custom/sep", + "custom/power" + ], + "custom/sep": { + "format": " | ", + "interval": 0, + "tooltip": false + }, + "hyprland/workspaces": { + "disable-scroll": true, + "all-outputs": false, + "warp-on-scroll": false, + "format": "{name}" + }, + "hyprland/window": { + "max-length": 40, + "separate-outputs": true + }, + "clock": { + "format": " {0:%H:%M:%S} {0:%a %d %b}", + //"format": " {time} {date}", + "tooltip-format": "{:%Y %B}\n{calendar}", + "format-alt": "{:%Y-%m-%d}" + }, + "cpu": { + "format": "{usage}%  ", + "tooltip": false + }, + "memory": { + "format": "{}% ({used}GiB)  " + }, + "network": { + "format-wifi": "{essid} ({signalStrength}%)  ", + "format-ethernet": "{ipaddr}/{cidr} 󱊪 ", + "tooltip-format": "{ifname} via {gwaddr}  ", + "format-disconnected": "Disconnected  " + }, + "pulseaudio": { + "scroll-step": 5, // %, can be a float + "format": "{volume}% {icon}", + "format-muted": "{volume}%  ", + "format-icons": { + "headphone": " ", + "default": [ + " ", + " ", + " " + ] + }, + "on-click": "pactl set-sink-mute @DEFAULT_SINK@ toggle" + }, + "custom/audio_device": { + "format": "{text}", + "tooltip": true, + "tooltip-format": "{alt}", + "return-type": "json", + "max-length": 40, + "escape": true, + "exec": "$HOME/.config/waybar/audio_output_status.sh 2>/dev/null", + "on-click": "$HOME/.config/waybar/audio_output_switch.sh 2>/dev/null" + }, + "custom/media": { + "format": "{icon} {text}", + "return-type": "json", + "max-length": 40, + "format-icons": { + "spotify": "", + "default": "🎜" + }, + "escape": true, + "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder + //"exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name + }, + "custom/power": { + "format": "⏻ ", + "tooltip": false, + "menu": "on-click", + "menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder + "menu-actions": { + "lock": "hyprlock", + "shutdown": "shutdown", + "reboot": "reboot", + "suspend": "systemctl suspend", + "hibernate": "systemctl hibernate" + } + } + }, + { + "output": "DP-2", + "height": 30, // Waybar height (to be removed for auto height) + "spacing": 4, // Gaps between modules (4px) + "modules-left": [ + "hyprland/workspaces", + "custom/sep", + "custom/media" + ], + "modules-center": [ + "hyprland/window" + ], + "modules-right": [ + "pulseaudio", + "custom/sep", + "clock", + "custom/sep", + "custom/power" + ], + "custom/sep": { + "format": " | ", + "interval": 0, + "tooltip": false + }, + "hyprland/workspaces": { + "disable-scroll": true, + "all-outputs": false, + "warp-on-scroll": false, + "format": "{name}" + }, + "hyprland/window": { + "max-length": 40, + "separate-outputs": true + }, + "clock": { + "format": " {0:%H:%M:%S} {0:%a %d %b}", + //"format": " {time} {date}", + "tooltip-format": "{:%Y %B}\n{calendar}", + "format-alt": "{:%Y-%m-%d}" + }, + "cpu": { + "format": "{usage}%  ", + "tooltip": false + }, + "memory": { + "format": "{}% ({used}GiB)  " + }, + "network": { + "format-wifi": "{essid} ({signalStrength}%)  ", + "format-ethernet": "{ipaddr}/{cidr} 󱊪 ", + "tooltip-format": "{ifname} via {gwaddr}  ", + "format-disconnected": "Disconnected  " + }, + "pulseaudio": { + "scroll-step": 5, // %, can be a float + "format": "{volume}% {icon}", + "format-icons": { + "headphone": " ", + "default": [ + " ", + " ", + " " + ] + }, + "on-click": "pwvucontrol" + }, + "custom/media": { + "format": "{icon} {text}", + "return-type": "json", + "max-length": 40, + "format-icons": { + "spotify": "", + "default": "🎜" + }, + "escape": true, + //"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder + "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name + }, + "custom/power": { + "format": "⏻ ", + "tooltip": false, + "menu": "on-click", + "menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder + "menu-actions": { + "lock": "hyprlock", + "shutdown": "shutdown", + "reboot": "reboot", + "suspend": "systemctl suspend", + "hibernate": "systemctl hibernate" + } + } + } +] diff --git a/.config/waybar/mediaplayer.py b/.config/waybar/mediaplayer.py new file mode 100755 index 0000000..9c2dfc9 --- /dev/null +++ b/.config/waybar/mediaplayer.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python3 +import gi + +gi.require_version("Playerctl", "2.0") +import argparse +import json +import logging +import os +import signal +import sys +from typing import List + +import gi +from gi.repository import GLib, Playerctl +from gi.repository.Playerctl import Player + +logger = logging.getLogger(__name__) + + +def signal_handler(sig, frame): + logger.info("Received signal to stop, exiting") + sys.stdout.write("\n") + sys.stdout.flush() + # loop.quit() + sys.exit(0) + + +class PlayerManager: + def __init__(self, selected_player=None, excluded_player=[]): + self.manager = Playerctl.PlayerManager() + self.loop = GLib.MainLoop() + self.manager.connect( + "name-appeared", lambda *args: self.on_player_appeared(*args) + ) + self.manager.connect( + "player-vanished", lambda *args: self.on_player_vanished(*args) + ) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + self.selected_player = selected_player + self.excluded_player = excluded_player.split(",") if excluded_player else [] + + self.init_players() + + def init_players(self): + for player in self.manager.props.player_names: + if player.name in self.excluded_player: + continue + if self.selected_player is not None and self.selected_player != player.name: + logger.debug(f"{player.name} is not the filtered player, skipping it") + continue + self.init_player(player) + + def run(self): + logger.info("Starting main loop") + self.loop.run() + + def init_player(self, player): + logger.info(f"Initialize new player: {player.name}") + player = Playerctl.Player.new_from_name(player) + player.connect("playback-status", self.on_playback_status_changed, None) + player.connect("metadata", self.on_metadata_changed, None) + self.manager.manage_player(player) + self.on_metadata_changed(player, player.props.metadata) + + def get_players(self) -> List[Player]: + return self.manager.props.players + + def write_output(self, text, player): + logger.debug(f"Writing output: {text}") + + output = { + "text": text, + "class": "custom-" + player.props.player_name, + "alt": player.props.player_name, + } + + sys.stdout.write(json.dumps(output) + "\n") + sys.stdout.flush() + + def clear_output(self): + sys.stdout.write("\n") + sys.stdout.flush() + + def on_playback_status_changed(self, player, status, _=None): + logger.debug( + f"Playback status changed for player {player.props.player_name}: {status}" + ) + self.on_metadata_changed(player, player.props.metadata) + + def get_first_playing_player(self): + players = self.get_players() + logger.debug(f"Getting first playing player from {len(players)} players") + if len(players) > 0: + # if any are playing, show the first one that is playing + # reverse order, so that the most recently added ones are preferred + for player in players[::-1]: + if player.props.status == "Playing": + return player + # if none are playing, show the first one + return players[0] + else: + logger.debug("No players found") + return None + + def show_most_important_player(self): + logger.debug("Showing most important player") + # show the currently playing player + # or else show the first paused player + # or else show nothing + current_player = self.get_first_playing_player() + if current_player is not None: + self.on_metadata_changed(current_player, current_player.props.metadata) + else: + self.clear_output() + + def on_metadata_changed(self, player, metadata, _=None): + logger.debug(f"Metadata changed for player {player.props.player_name}") + player_name = player.props.player_name + artist = player.get_artist() + artist = artist.replace("&", "&") + title = player.get_title() + title = title.replace("&", "&") + + track_info = "" + if ( + player_name == "spotify" + and "mpris:trackid" in metadata.keys() + and ":ad:" in player.props.metadata["mpris:trackid"] + ): + track_info = "Advertisement" + elif artist is not None and title is not None: + track_info = f"{artist} - {title}" + else: + track_info = title + + if track_info: + if player.props.status == "Playing": + track_info = " " + track_info + else: + track_info = " " + track_info + # only print output if no other player is playing + current_playing = self.get_first_playing_player() + if ( + current_playing is None + or current_playing.props.player_name == player.props.player_name + ): + self.write_output(track_info, player) + else: + logger.debug( + f"Other player {current_playing.props.player_name} is playing, skipping" + ) + + def on_player_appeared(self, _, player): + logger.info(f"Player has appeared: {player.name}") + if player.name in self.excluded_player: + logger.debug( + "New player appeared, but it's in exclude player list, skipping" + ) + return + if player is not None and ( + self.selected_player is None or player.name == self.selected_player + ): + self.init_player(player) + else: + logger.debug( + "New player appeared, but it's not the selected player, skipping" + ) + + def on_player_vanished(self, _, player): + logger.info(f"Player {player.props.player_name} has vanished") + self.show_most_important_player() + + +def parse_arguments(): + parser = argparse.ArgumentParser() + + # Increase verbosity with every occurrence of -v + parser.add_argument("-v", "--verbose", action="count", default=0) + + parser.add_argument("-x", "--exclude", "- Comma-separated list of excluded player") + + # Define for which player we"re listening + parser.add_argument("--player") + + parser.add_argument("--enable-logging", action="store_true") + + return parser.parse_args() + + +def main(): + arguments = parse_arguments() + + # Initialize logging + if arguments.enable_logging: + logfile = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "media-player.log" + ) + logging.basicConfig( + filename=logfile, + level=logging.DEBUG, + format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s", + ) + + # Logging is set by default to WARN and higher. + # With every occurrence of -v it's lowered by one + logger.setLevel(max((3 - arguments.verbose) * 10, 0)) + + logger.info("Creating player manager") + if arguments.player: + logger.info(f"Filtering for player: {arguments.player}") + if arguments.exclude: + logger.info(f"Exclude player {arguments.exclude}") + + player = PlayerManager(arguments.player, arguments.exclude) + player.run() + + +if __name__ == "__main__": + main() diff --git a/.config/waybar/mocha.css b/.config/waybar/mocha.css new file mode 100644 index 0000000..0eb6a82 --- /dev/null +++ b/.config/waybar/mocha.css @@ -0,0 +1,26 @@ +@define-color rosewater #f5e0dc; +@define-color flamingo #f2cdcd; +@define-color pink #f5c2e7; +@define-color mauve #cba6f7; +@define-color red #f38ba8; +@define-color maroon #eba0ac; +@define-color peach #fab387; +@define-color yellow #f9e2af; +@define-color green #a6e3a1; +@define-color teal #94e2d5; +@define-color sky #89dceb; +@define-color sapphire #74c7ec; +@define-color blue #89b4fa; +@define-color lavender #b4befe; +@define-color text #cdd6f4; +@define-color subtext1 #bac2de; +@define-color subtext0 #a6adc8; +@define-color overlay2 #9399b2; +@define-color overlay1 #7f849c; +@define-color overlay0 #6c7086; +@define-color surface2 #585b70; +@define-color surface1 #45475a; +@define-color surface0 #313244; +@define-color base #1e1e2e; +@define-color mantle #181825; +@define-color crust #11111b; diff --git a/.config/waybar/power_menu.xml b/.config/waybar/power_menu.xml new file mode 100644 index 0000000..3704573 --- /dev/null +++ b/.config/waybar/power_menu.xml @@ -0,0 +1,33 @@ + + + + + + Lock + + + + + Suspend + + + + + Hibernate + + + + + Shutdown + + + + + + + + Reboot + + + + diff --git a/.config/waybar/style.css b/.config/waybar/style.css new file mode 100644 index 0000000..42070a1 --- /dev/null +++ b/.config/waybar/style.css @@ -0,0 +1,11 @@ +@import "mocha.css"; +* { + /* reference the color by using @color-name */ + color: @text; +} + +window#waybar { + /* you can also GTK3 CSS functions! */ + background-color: shade(@base, 0.9); + border: 2px solid alpha(@crust, 0.3); +} diff --git a/.gitignore b/.gitignore index 217f8a2..5de8ae7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,14 +3,5 @@ !.gitignore !.gitmodules !.zshrc -!.local/bin -!.config/alacritty -!.config/bat -!.config/btop -!.config/i3 -!.config/neofetch -!.config/picom -!.config/polybar -!.config/rofi -!.config/starship -!.config/tmux +!.config/ +!.local/ diff --git a/.local/.gitignore b/.local/.gitignore new file mode 100644 index 0000000..dc9c7bf --- /dev/null +++ b/.local/.gitignore @@ -0,0 +1,3 @@ +* +!bin/ +!.gitignore diff --git a/.local/bin/.gitignore b/.local/bin/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.local/bin/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.local/bin/movie b/.local/bin/movie deleted file mode 100755 index 4cb8390..0000000 --- a/.local/bin/movie +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -MOVIE_DIR=/media-storage/Movies -SELECTED=`fd . $MOVIE_DIR -e avi -e m4v -e mkv -e mp4 | fzf` -if [ -z "$SELECTED" ]; then - echo "No movie selected. Exiting." - exit 1 -fi -vlc "$SELECTED" & -exit 0 diff --git a/.zshrc b/.zshrc index c3b8557..0600454 100644 --- a/.zshrc +++ b/.zshrc @@ -25,7 +25,7 @@ alias vi=nvim alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles --work-tree=$HOME' alias top=btop alias movies="movie; exit" -alias ccp='xclip -selection clipboard <' +alias ccp='wl-copy<' eval "$(fzf --zsh)"