├── README.md ├── .config ├── hypr │ ├── wal.png │ ├── hyprpaper.conf │ ├── hyprshade.toml │ ├── hypridle.conf │ ├── hyprstart.conf │ ├── hyprplugins.conf │ ├── hyprlock.conf │ ├── hyprbinds.conf │ └── hyprland.conf ├── kitty │ └── kitty.conf └── waybar │ ├── style.css │ ├── config │ └── modules │ └── mediaplayer.py └── images └── screenshot.png /README.md: -------------------------------------------------------------------------------- 1 | # publicdots 2 | 3 | ![Screenshot](images/screenshot.png) 4 | -------------------------------------------------------------------------------- /.config/hypr/wal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmdickey/publicdots/HEAD/.config/hypr/wal.png -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmdickey/publicdots/HEAD/images/screenshot.png -------------------------------------------------------------------------------- /.config/hypr/hyprpaper.conf: -------------------------------------------------------------------------------- 1 | preload = ~/Pictures/gradient/blobs-d.png 2 | wallpaper = ,~/Pictures/gradient/blobs-d.png 3 | 4 | splash = false 5 | -------------------------------------------------------------------------------- /.config/hypr/hyprshade.toml: -------------------------------------------------------------------------------- 1 | [[shades]] 2 | name = "vibrance" 3 | default = true 4 | 5 | [[shades]] 6 | name = "blue-light-filter" 7 | start_time = 19:00:00 8 | end_time = 06:00:00 9 | -------------------------------------------------------------------------------- /.config/hypr/hypridle.conf: -------------------------------------------------------------------------------- 1 | general { 2 | lock_cmd = pidof hyprlock || hyprlock 3 | before_sleep_cmd = loginctl lock-session 4 | after_sleep_cmd = hyprctl dispatch dpms on 5 | } 6 | 7 | listener { 8 | timeout = 300 9 | on-timeout = loginctl lock-session 10 | on-resume = notify-send "Welcome back!" 11 | } 12 | 13 | listener { 14 | timeout = 330 15 | on-timeout = hyprctl dispatch dpms off 16 | on-resume = hyprctl dispatch dpms on 17 | } 18 | -------------------------------------------------------------------------------- /.config/kitty/kitty.conf: -------------------------------------------------------------------------------- 1 | font_family Jetbrains Mono Nerd Font Mono 2 | bold_font auto 3 | italic_font auto 4 | bold_italic_font auto 5 | 6 | font_size 12 7 | 8 | remember_window_size no 9 | initial_window_width 845 10 | initial_window_height 550 11 | 12 | confirm_os_window_close 0 13 | 14 | window_padding_width 20 15 | 16 | include ~/.cache/wal/colors-kitty.conf 17 | 18 | hide_window_decorations no 19 | 20 | linux_display_server auto 21 | 22 | background_opacity 1 23 | dynamic_background_opacity yes 24 | 25 | wayland_titlebar_color #242424 26 | -------------------------------------------------------------------------------- /.config/hypr/hyprstart.conf: -------------------------------------------------------------------------------- 1 | exec-once = systemctl --user start hyprland-session.target 2 | exec-once = wl-clipboard 3 | exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 4 | exec-once = sudo mount -a 5 | exec-once = ~/Documents/Scripts/hyprportal.sh 6 | exec-once = hypridle 7 | #exec-once = hyprpaper 8 | exec-once = swww-daemon 9 | exec-once = swww-daemon 10 | #exec-once = hyprpaper 11 | exec-once = hyprshade on vibrance 12 | exec-once = hyprpm enable hyprbars 13 | exec-once = hyprpm disable hyprexpo 14 | #exec-once = hyprpm enable hyprtrails 15 | #exec-once = hyprpm enable hyprexpo 16 | #exec-once = sleep 0.1 && ~/Documents/Scripts/hyprwal.sh 17 | exec = killall waybar 18 | exec = waybar 19 | exec = killall ags 20 | #exec = ags 21 | exec = brightnessctl s 75% 22 | exec = brightnessctl --device='tpacpi::kbd_backlight' set 1 23 | exec = ~/Documents/Scripts/swayncreload.sh 24 | exec = swaync 25 | -------------------------------------------------------------------------------- /.config/waybar/style.css: -------------------------------------------------------------------------------- 1 | @import url("/home/justin/.cache/wal/colors-waybar.css"); 2 | 3 | * { 4 | border: none; 5 | font-family: 'Jetbrains Mono', 'Font Awesome 6 Brands', 'Font Awesome 6 Free Solid'; 6 | font-size: 16px; 7 | font-weight: 600; 8 | } 9 | 10 | #waybar { 11 | background-color: @background; 12 | color: @background; 13 | font-weight: 800; 14 | } 15 | 16 | .module { 17 | padding: 4px; 18 | margin: 3px; 19 | color: @color15; 20 | } 21 | 22 | .module:hover { 23 | } 24 | 25 | label.module { 26 | border-radius: 10px; 27 | margin: 3px; 28 | padding: 2px 4px; 29 | min-width: 30px; 30 | } 31 | 32 | #window { 33 | background-color: @color3; 34 | color: @background; 35 | padding: 4px; 36 | margin: 3px; 37 | border-radius: 10px; 38 | font-size: 14px; 39 | min-width: 40px; 40 | } 41 | 42 | window#waybar.empty #window { 43 | } 44 | 45 | #temperature { 46 | } 47 | 48 | #temperature.critical { 49 | } 50 | 51 | #custom-gputemp { 52 | } 53 | 54 | #custom-gputemp.critical { 55 | } 56 | 57 | #image { 58 | margin: 3px; 59 | border-radius: 10px; 60 | } 61 | 62 | #network { 63 | background-color: @color1; 64 | color: @background; 65 | } 66 | 67 | #custom-mullvad { 68 | background-color: @color4; 69 | color: @background; 70 | } 71 | 72 | #pulseaudio { 73 | background-color: @color5; 74 | color: @background; 75 | } 76 | 77 | #clock { 78 | background-color: @color2; 79 | color: @background; 80 | margin-right: 15px; 81 | } 82 | 83 | #custom-notification { 84 | background-color: @color3; 85 | color: @background; 86 | } 87 | 88 | #tray { 89 | padding: 4px 10px; 90 | margin: 3px; 91 | border-radius: 10px; 92 | font-size: 14px; 93 | } 94 | 95 | #battery { 96 | background-color: @color6; 97 | color: @background; 98 | } 99 | 100 | #battery#bat1 { 101 | background-color: @color6; 102 | color: @background; 103 | } 104 | 105 | #battery.charging { 106 | } 107 | 108 | #battery#bat1.charging { 109 | } 110 | 111 | #battery.critical { 112 | } 113 | 114 | #battery#bat1.critical { 115 | } 116 | 117 | #battery.warning { 118 | } 119 | 120 | #battery#bat1.warning { 121 | } 122 | 123 | #custom-hostname { 124 | background-color: @color1; 125 | color: @background; 126 | } 127 | 128 | #custom-spotify { 129 | background-color: @color2; 130 | color: @background; 131 | } 132 | 133 | #workspaces { 134 | background-color: @color2; 135 | color: @background; 136 | border-radius: 10px; 137 | margin: 3px; 138 | padding: 4px; 139 | } 140 | 141 | #workspaces button { 142 | color: @background; 143 | } 144 | 145 | #workspaces button.active { 146 | background-color: @background; 147 | color: @foreground; 148 | border-radius: 10px; 149 | } 150 | 151 | #workspaces button:hover { 152 | } 153 | -------------------------------------------------------------------------------- /.config/hypr/hyprplugins.conf: -------------------------------------------------------------------------------- 1 | plugin { 2 | hyprtrails { 3 | color = $color4 4 | } 5 | hyprbars { 6 | bar_height = 38 7 | bar_color = rgb(1e1e1e) 8 | col.text = $color2 9 | bar_text_size = 12 10 | bar_text_font = Jetbrains Mono Nerd Font Mono Bold 11 | bar_button_padding = 12 12 | bar_padding = 10 13 | bar_precedence_over_border = true 14 | hyprbars-button = $color1, 20, , hyprctl dispatch killactive 15 | hyprbars-button = $color3, 20, , hyprctl dispatch fullscreen 2 16 | #hyprbars-button = $color2, 20, , hyprctl dispatch togglefloating 17 | hyprbars-button = $color2, 20, , hyprctl dispatch togglefloating 18 | } 19 | hyprexpo { 20 | columns = 2 21 | gap_size = 15 22 | bg_col = rgb(111111) 23 | workspace_method = center first 24 | enable_gesture = true # laptop touchpad, 4 fingers 25 | gesture_distance = 300 # how far is the "max" 26 | gesture_positive = true # positive = swipe down. Negative = swipe up. 27 | } 28 | 29 | hycov { 30 | overview_gappo = 20 # gaps width from screen edge 31 | overview_gappi = 10 # gaps width from clients 32 | enable_hotarea = 0 # enable mouse cursor hotarea, when cursor enter hotarea, it will toggle overview 33 | enable_click_action = 1 # enable mouse left button jump and right button kill in overview mode 34 | hotarea_monitor = all # monitor name which hotarea is in, default is all 35 | hotarea_pos = 1 # position of hotarea (1: bottom left, 2: bottom right, 3: top left, 4: top right) 36 | hotarea_size = 10 # hotarea size, 10x10 37 | swipe_fingers = 4 # finger number of gesture,move any directory 38 | move_focus_distance = 100 # distance for movefocus,only can use 3 finger to move 39 | enable_gesture = 0 # enable gesture 40 | auto_exit = 1 # enable auto exit when no client in overview 41 | auto_fullscreen = 0 # auto make active window maximize after exit overview 42 | only_active_workspace = 0 # only overview the active workspace 43 | only_active_monitor = 0 # only overview the active monitor 44 | enable_alt_release_exit = 0 # alt swith mode arg,see readme for detail 45 | alt_replace_key = Alt_L # alt swith mode arg,see readme for detail 46 | alt_toggle_auto_next = 0 # auto focus next window when toggle overview in alt swith mode 47 | click_in_cursor = 1 # when click to jump,the target windwo is find by cursor, not the current foucus window. 48 | hight_of_titlebar = 0 # height deviation of title bar height 49 | show_special = 0 # show windwos in special workspace in overview. 50 | raise_float_to_top = 1 # raise the window that is floating before to top after leave overview mode 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.config/hypr/hyprlock.conf: -------------------------------------------------------------------------------- 1 | source = /home/justin/.cache/wal/colors-hyprland.conf 2 | 3 | # BACKGROUND 4 | background { 5 | monitor = 6 | #path = screenshot 7 | path = /home/justin/Pictures/wal.png 8 | #color = $background 9 | blur_passes = 2 10 | contrast = 1 11 | brightness = 0.5 12 | vibrancy = 0.2 13 | vibrancy_darkness = 0.2 14 | } 15 | 16 | # GENERAL 17 | general { 18 | no_fade_in = true 19 | no_fade_out = true 20 | hide_cursor = false 21 | grace = 0 22 | disable_loading_bar = true 23 | } 24 | 25 | # INPUT FIELD 26 | input-field { 27 | monitor = 28 | size = 250, 60 29 | outline_thickness = 2 30 | dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8 31 | dots_spacing = 0.35 # Scale of dots' absolute size, 0.0 - 1.0 32 | dots_center = true 33 | outer_color = rgba(0, 0, 0, 0) 34 | inner_color = rgba(0, 0, 0, 0.2) 35 | font_color = $foreground 36 | fade_on_empty = false 37 | rounding = -1 38 | check_color = rgb(204, 136, 34) 39 | placeholder_text = Input Password... 40 | hide_input = false 41 | position = 0, -200 42 | halign = center 43 | valign = center 44 | } 45 | 46 | # DATE 47 | label { 48 | monitor = 49 | text = cmd[update:1000] echo "$(date +"%A, %B %d")" 50 | color = rgba(242, 243, 244, 0.75) 51 | font_size = 22 52 | font_family = JetBrains Mono 53 | position = 0, 300 54 | halign = center 55 | valign = center 56 | } 57 | 58 | # TIME 59 | label { 60 | monitor = 61 | text = cmd[update:1000] echo "$(date +"%-I:%M")" 62 | color = rgba(242, 243, 244, 0.75) 63 | font_size = 95 64 | font_family = JetBrains Mono Extrabold 65 | position = 0, 200 66 | halign = center 67 | valign = center 68 | } 69 | 70 | 71 | 72 | # Profile Picture 73 | image { 74 | monitor = 75 | path = /home/justin/Pictures/profile_pictures/justin_square.png 76 | size = 100 77 | border_size = 2 78 | border_color = $foreground 79 | position = 0, -100 80 | halign = center 81 | valign = center 82 | } 83 | 84 | # Desktop Environment 85 | image { 86 | monitor = 87 | path = /home/justin/Pictures/profile_pictures/hypr.png 88 | size = 75 89 | border_size = 2 90 | border_color = $foreground 91 | position = -50, 50 92 | halign = right 93 | valign = bottom 94 | } 95 | 96 | # CURRENT SONG 97 | label { 98 | monitor = 99 | text = cmd[update:1000] echo "$(/home/justin/Documents/Scripts/whatsong.sh)" 100 | color = $foreground 101 | #color = rgba(255, 255, 255, 0.6) 102 | font_size = 18 103 | font_family = Metropolis Light, Font Awesome 6 Free Solid 104 | position = 0, 50 105 | halign = center 106 | valign = bottom 107 | } 108 | 109 | label { 110 | monitor = 111 | text = cmd[update:1000] echo "$(/home/justin/Documents/Scripts/whoami.sh)" 112 | color = $foreground 113 | font_size = 14 114 | font_family = JetBrains Mono 115 | position = 0, -10 116 | halign = center 117 | valign = top 118 | } 119 | 120 | label { 121 | monitor = 122 | text = cmd[update:1000] echo "$(/home/justin/Documents/Scripts/battery.sh)" 123 | color = $foreground 124 | font_size = 24 125 | font_family = JetBrains Mono 126 | position = -90, -10 127 | halign = right 128 | valign = top 129 | } 130 | 131 | label { 132 | monitor = 133 | text = cmd[update:1000] echo "$(/home/justin/Documents/Scripts/network-status.sh)" 134 | color = $foreground 135 | font_size = 24 136 | font_family = JetBrains Mono 137 | position = -20, -10 138 | halign = right 139 | valign = top 140 | } 141 | -------------------------------------------------------------------------------- /.config/hypr/hyprbinds.conf: -------------------------------------------------------------------------------- 1 | $mainMod = SUPER 2 | 3 | bind = $mainMod, RETURN ,exec, [tile] kitty 4 | bind = $mainMod SHIFT, RETURN, exec, [float;centerwindow] kitty 5 | bind = $mainMod, Q, killactive 6 | #bind = $mainMod SHIFT, W, exec,~/Documents/Scripts/hyprwal.sh 7 | bind = $mainMod SHIFT, W, exec,~/Documents/Scripts/wal2.sh 8 | bind = $mainMod, E, exec,nautilus 9 | bind = $mainMod SHIFT, SPACE, togglefloating 10 | bind = $mainMod, T, togglefloating 11 | bind = $mainMod, F,fullscreen 12 | bind = $mainMod, D, exec, rofi -show drun -icon-theme "Kora" -theme /home/justin/.config/rofi/launchers/type-3/style-2.rasi 13 | bind = $mainMod SHIFT, F, exec, firefox 14 | bind = $mainMod, N, exec, swaync-client -t -sw 15 | bind = $mainMod, P, exec,hyprctl dispatch pin 16 | bind = $mainMod, J, togglesplit, # dwindle 17 | bind = $mainMod, L, exec,~/Documents/Scripts/lock.sh 18 | bind = $mainMod, G, exec,~/Documents/Scripts/gaps.sh 19 | bind = $mainMod SHIFT, s, exec, ~/Documents/Scripts/grim.sh 20 | bind = $mainMod, S, exec, ~/Documents/Scripts/grimfull.sh 21 | #bind = $mainMod SHIFT, G, exec, 22 | #bind = $mainMod SHIFT, Q,exec,~/.config/rofi/scripts/powermenu_t3 23 | bindel = $mainMod SHIFT, Q,exec,systemctl restart gdm.service 24 | bind = $mainMod SHIFT ,R, exec,hyprctl reload 25 | 26 | bind = $mainMod, left, movefocus, l 27 | bind = $mainMod, right, movefocus, r 28 | bind = $mainMod, up, movefocus, u 29 | bind = $mainMod, down, movefocus, d 30 | 31 | bind = $mainMod, 1, workspace, 1 32 | bind = $mainMod, 2, workspace, 2 33 | bind = $mainMod, 3, workspace, 3 34 | bind = $mainMod, 4, workspace, 4 35 | bind = $mainMod, 5, workspace, 5 36 | bind = $mainMod, 6, workspace, 6 37 | bind = $mainMod, 7, workspace, 7 38 | bind = $mainMod, 8, workspace, 8 39 | bind = $mainMod, 9, workspace, 9 40 | bind = $mainMod, 0, workspace, 10 41 | bind = $mainMod, TAB, workspace, e+1 42 | bind = $mainMod SHIFT, C, movetoworkspace, special 43 | bind = $mainMod, C, workspace, special 44 | bind = $mainMod, slash, togglespecialworkspace 45 | 46 | bind = $mainMod SHIFT, 1, movetoworkspacesilent, 1 47 | bind = $mainMod SHIFT, 2, movetoworkspacesilent, 2 48 | bind = $mainMod SHIFT, 3, movetoworkspacesilent, 3 49 | bind = $mainMod SHIFT, 4, movetoworkspacesilent, 4 50 | bind = $mainMod SHIFT, 5, movetoworkspacesilent, 5 51 | bind = $mainMod SHIFT, 6, movetoworkspacesilent, 6 52 | bind = $mainMod SHIFT, 7, movetoworkspacesilent, 7 53 | bind = $mainMod SHIFT, 8, movetoworkspacesilent, 8 54 | bind = $mainMod SHIFT, 9, movetoworkspacesilent, 9 55 | bind = $mainMod SHIFT, 0, movetoworkspacesilent, 10 56 | 57 | bind = $mainMod, mouse_down, workspace, e+1 58 | bind = $mainMod, mouse_up, workspace, e-1 59 | 60 | bind = $mainMod SHIFT, left, resizeactive, -100 0 61 | bind = $mainMod SHIFT, right, resizeactive, 100 0 62 | bind = $mainMod SHIFT, down, resizeactive, 0 100 63 | bind = $mainMod SHIFT, up, resizeactive, 0 -100 64 | 65 | bind = $mainMod CTRL, left, swapsplit 66 | bind = $mainMod CTRL, right, swapsplit 67 | bind = $mainMod CTRL, up, swapsplit 68 | bind = $mainMod CTRL, down, swapsplit 69 | 70 | bind = $mainMod CTRL SHIFT, left, layoutmsg, preselect left 71 | bind = $mainMod CTRL SHIFT, right, layoutmsg, preselect right 72 | bind = $mainMod CTRL SHIFT, up, layoutmsg, preselect up 73 | bind = $mainMod CTRL SHIFT, down, layoutmsg, preselect down 74 | 75 | bindel = ,XF86AudioRaiseVolume, exec, ~/Documents/Scripts/volup.sh 76 | bindel = ,XF86AudioMute, exec, ~/Documents/Scripts/volume.sh mute 77 | bindel = ,XF86AudioLowerVolume, exec, ~/Documents/Scripts/voldown.sh 78 | 79 | bindel = ,XF86AudioNext, exec, playerctl next 80 | bindel = ,XF86AudioPrev, exec, playerctl previous 81 | bindel = ,XF86AudioPlay, exec, playerctl play-pause 82 | 83 | bind = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+ 84 | bind = ,XF86MonBrightnessDown, exec, brightnessctl s 10%- 85 | 86 | bind = $mainMod,grave,hycov:toggleoverview,forceall 87 | 88 | 89 | bindm = $mainMod, mouse:272, movewindow 90 | bindm = $mainMod, mouse:273, resizewindow 91 | 92 | # PLUGINS 93 | 94 | #bind = $mainMod, grave, hyprexpo:expo, toggle 95 | 96 | -------------------------------------------------------------------------------- /.config/hypr/hyprland.conf: -------------------------------------------------------------------------------- 1 | # MONITORS 2 | monitor=,preferred,auto,1 3 | monitor=eDP-1, 1920x1080@60,0x0,1 4 | monitor=DP-1, 3440x1440@120, 2160x850,1 5 | monitor=DP-2, 3840x2160@60, 0x0,1,transform,1 6 | monitor=HDMI-A-1, 1920x1080@144, 0x0,1 7 | monitor=HEADLESS-2, 1920x1080@60, 3440x0,1 8 | monitor=Unknown-1,disable 9 | 10 | # SOURCES 11 | source = ~/.cache/wal/colors-hyprland.conf 12 | source = ~/.config/hypr/hyprbinds.conf 13 | source = ~/.config/hypr/hyprplugins.conf 14 | source = ~/.config/hypr/hyprstart.conf 15 | 16 | # ENV VARIABLES 17 | env = LIBVA_DRIVER_NAME,nvidia 18 | env = XDG_SESSION_TYPE,wayland 19 | env = GBM_BACKEND,nvidia-drm 20 | env = __GLX_VENDOR_LIBRARY_NAME,nvidia 21 | env = WLR_NO_HARDWARE_CURSORS,1 22 | env = GTK_THEME,Adw-dark 23 | env = HYPRCURSOR_THEME,DeppinWhite-cursors 24 | env = HYPRCURSOR_SIZE,24 25 | 26 | # INPUT 27 | input { 28 | kb_layout = us 29 | kb_variant = 30 | kb_model = 31 | kb_options = 32 | kb_rules = 33 | follow_mouse = 1 34 | accel_profile = flat 35 | touchpad { 36 | natural_scroll = no 37 | } 38 | sensitivity = 0 # -1.0 - 1.0, 0 means no modification. 39 | } 40 | 41 | # STYLES 42 | general { 43 | gaps_in = 6 44 | gaps_out = 12 45 | border_size = 1 46 | col.active_border = $color8 47 | #col.active_border = $color1 $color6 48 | col.inactive_border = rgb(1e1e1e) 49 | allow_tearing = false 50 | layout = dwindle 51 | resize_on_border = true 52 | hover_icon_on_border = true 53 | } 54 | 55 | decoration { 56 | rounding = 10 57 | active_opacity = 1 58 | inactive_opacity = 1 59 | blur { 60 | enabled = yes 61 | size = 2 62 | passes = 2 # more passes = more resources 63 | ignore_opacity = 1 64 | new_optimizations = true 65 | popups = false 66 | contrast = 1 # range 0 - 2 67 | vibrancy = 0.2 68 | vibrancy_darkness = 0.2 69 | brightness = 0.5 # range 0 - 2 70 | #special = 0.5 71 | } 72 | drop_shadow = true 73 | shadow_range = 40 74 | col.shadow = 0x70000000 75 | col.shadow_inactive = 0x10000000 76 | dim_around = 2 77 | } 78 | 79 | animations { 80 | enabled=1 81 | bezier=mybezier,0.68, 0.6, 0.32, 1.3 82 | bezier=linear,1,1,1,1 83 | animation=windows,1,2,mybezier,popin 84 | animation=workspaces,1,3,mybezier,slidefadevert 85 | animation=borderangle,1,40,linear,loop 86 | } 87 | 88 | dwindle { 89 | pseudotile = yes 90 | preserve_split = yes 91 | force_split = 2 92 | smart_split = false 93 | no_gaps_when_only = 0 94 | default_split_ratio = 1.22 95 | } 96 | 97 | gestures { 98 | workspace_swipe = on 99 | } 100 | 101 | misc { 102 | font_family = "JetBrains Mono" 103 | disable_hyprland_logo = true 104 | allow_session_lock_restore = true 105 | focus_on_activate = true 106 | } 107 | 108 | # RULES 109 | windowrule = float, ^(nemo)$ 110 | windowrule = float, ^(zoom)$ 111 | windowrule = float, ^(org.gnome.Calculator)$ 112 | windowrule = float, ^(Waydroid)$ 113 | windowrule = float, ^(pavucontrol)$ 114 | windowrule = float, ^(file-roller)$ 115 | windowrule = float, ^(org.gnome.Nautilus)$ 116 | windowrule = float, ^(org.prismlauncher.PrismLauncher)$ 117 | windowrule = float, ^(org.pulseaudio.pavucontrol)$ 118 | windowrule = size 1000 650, ^(org.gnome.Nautilus)$ 119 | windowrule = center, ^(org.gnome.Nautilus)$ 120 | windowrule = center, ^(kitty)$ 121 | windowrule = center, ^(org.gnome.Calendar)$ 122 | windowrule = center, ^(polkit-gnome-authentication-agent-1)$ 123 | windowrule = dimaround, ^(polkit-gnome-authentication-agent-1)$ 124 | #windowrule = plugin:hyprbars:nobar, ^(org.gnome.*)$ 125 | 126 | workspace = 1, monitor:DP-1, persistent: true, default: true 127 | workspace = 2, monitor:DP-1, persistent: true 128 | workspace = 3, monitor:DP-1, persistent: true 129 | workspace = 4, monitor:DP-1, persistent: true 130 | workspace = 5, monitor:DP-1, persistent: true 131 | 132 | workspace = 10,name:Left, monitor:DP-2, default: true 133 | 134 | layerrule = blur, 5efe46862ff0 135 | layerrule = blur, waybar 136 | #layerrule = blur, bar-0 137 | layerrule = blur, rofi 138 | layerrule = blur, swaync-control-center 139 | -------------------------------------------------------------------------------- /.config/waybar/config: -------------------------------------------------------------------------------- 1 | { 2 | "layer": "top", 3 | "position": "bottom", 4 | "height": 40, 5 | "spacing": 6, 6 | "modules-left": ["hyprland/workspaces", "hyprland/window"], 7 | "modules-center": ["custom/spotify", "custom/hostname"], 8 | "modules-right": ["tray", "pulseaudio", "custom/power", "battery", "battery#bat1", "custom/mullvad", "network", "custom/notification", "clock"], 9 | 10 | "hyprland/window": { 11 | "max-length": 45, 12 | "separate-outputs": true, 13 | }, 14 | 15 | "hyprland/workspaces": { 16 | "active-only": false, 17 | "on-scroll-up": "hyprctl dispatch workspace e+1", 18 | "on-scroll-down": "hyprctl dispatch workspace e-1", 19 | "format": "{icon}", 20 | "icon-size": 20, 21 | "format-icons": { 22 | "1": "", 23 | "2": "", 24 | "3": "", 25 | "4": "", 26 | "5": "", 27 | "default": "" 28 | }, 29 | "persistent-workspaces": { 30 | "*": 5, 31 | }, 32 | }, 33 | 34 | "custom/spacer": { 35 | "format": " " 36 | }, 37 | 38 | "custom/hostname": { 39 | "exec": "/home/justin/Documents/Scripts/whoami.sh", 40 | "format": "{}", 41 | "on-click": "hyprctl dispatch exec [float] 'kitty'" 42 | }, 43 | 44 | "temperature": { 45 | "interval": 10, 46 | // "thermal-zone": 4, 47 | "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", 48 | "critical-threshold": 80, 49 | "format-critical": " {temperatureC}°C", 50 | "format": " {temperatureC}°C" 51 | }, 52 | 53 | "temperature#temp2": { 54 | "interval": 10, 55 | // "thermal-zone": 4, 56 | "hwmon-path": "/sys/class/hwmon/hwmon3/temp1_input", 57 | "critical-threshold": 80, 58 | "format-critical": " {temperatureC}°C", 59 | "format": " {temperatureC}°C", 60 | "on-click": "hyprctl dispatch exec [float] 'kitty -e nvidia-smi'" 61 | }, 62 | 63 | "custom/notification": { 64 | "format": "{icon}", 65 | "format-icons": { 66 | "notification": "", 67 | "none": "", 68 | "dnd-notification": "", 69 | "dnd-none": "", 70 | "inhibited-notification": "", 71 | "inhibited-none": "", 72 | "dnd-inhibited-notification": "", 73 | "dnd-inhibited-none": "" 74 | }, 75 | "return-type": "json", 76 | "exec-if": "which swaync-client", 77 | "exec": "swaync-client -swb", 78 | "on-click": "swaync-client -t -sw", 79 | "on-click-right": "swaync-client -d -sw", 80 | "escape": true 81 | }, 82 | 83 | "network": { 84 | "format-wifi": "", 85 | "format-ethernet": "", 86 | "format-disconnected": "", 87 | "max-length": 50, 88 | "on-click": "hyprctl dispatch exec [float] 'kitty -e nmtui'", 89 | }, 90 | 91 | "custom/mullvad": { 92 | "exec": "/home/justin/Documents/Scripts/mullvad-status.sh", 93 | "format": "{}", 94 | "on-click": "/home/justin/Documents/Scripts/mullvad-toggle.sh" 95 | }, 96 | 97 | "custom/spotify": { 98 | "exec": "/usr/bin/python3 /home/justin/.config/waybar/modules/mediaplayer.py --player spotify", 99 | "format": "{}", 100 | "return-type": "json", 101 | "on-click": "playerctl play-pause", 102 | "on-click-right": "playerctl next", 103 | "spacing": 0, 104 | "margin": 0, 105 | "max-length": 45 106 | }, 107 | 108 | "image": { 109 | "exec":"~/Documents/Scripts/album_art.sh", 110 | "size": 40, 111 | "interval": 5 112 | }, 113 | 114 | "tray": { 115 | "icon-size": 20, 116 | "spacing": 10 117 | }, 118 | 119 | "clock": { 120 | "interval": 1, 121 | "timezone": "America/Indianapolis", 122 | "format": "{:%a %b %d %I:%M%p}", 123 | "on-click": "hyprctl dispatch exec [float] 'gnome-calendar'", 124 | "tooltip": true, 125 | "tooltip-format": "{:%a %b %d %I:%M%p}" 126 | }, 127 | 128 | "pulseaudio": { 129 | "format": " {icon} {volume}%", 130 | "format-bluetooth": "{volume}% {icon} {format_source}", 131 | "format-bluetooth-muted": " {icon} {format_source}", 132 | "format-muted": "0% {icon} ", 133 | "format-source": "{volume}% ", 134 | "format-source-muted": "", 135 | "format-icons": { 136 | "headphone": "", 137 | "hands-free": "", 138 | "headset": "", 139 | "phone": "", 140 | "portable": "", 141 | "car": "", 142 | "default": ["", "", "", ""] 143 | }, 144 | "on-click": "pavucontrol" 145 | }, 146 | 147 | "battery": { 148 | "bat": "BAT0", 149 | "interval": 60, 150 | "states": { 151 | "warning": 30, 152 | "critical": 15 153 | }, 154 | "format": "{icon} {capacity}%", 155 | "format-icons": ["", "", "", "", ""], 156 | "max-length": 25 157 | }, 158 | 159 | "battery#bat1": { 160 | "bat": "BAT1", 161 | "interval": 60, 162 | "states": { 163 | "warning": 30, 164 | "critical": 15 165 | }, 166 | "format": "{icon} {capacity}%", 167 | "format-icons": ["", "", "", "", ""], 168 | "max-length": 25 169 | }, 170 | } 171 | -------------------------------------------------------------------------------- /.config/waybar/modules/mediaplayer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import gi 3 | gi.require_version("Playerctl", "2.0") 4 | from gi.repository import Playerctl, GLib 5 | from gi.repository.Playerctl import Player 6 | import argparse 7 | import logging 8 | import sys 9 | import signal 10 | import gi 11 | import json 12 | import os 13 | from typing import List 14 | 15 | logger = logging.getLogger(__name__) 16 | 17 | def signal_handler(sig, frame): 18 | logger.info("Received signal to stop, exiting") 19 | sys.stdout.write("\n") 20 | sys.stdout.flush() 21 | # loop.quit() 22 | sys.exit(0) 23 | 24 | 25 | class PlayerManager: 26 | def __init__(self, selected_player=None): 27 | self.manager = Playerctl.PlayerManager() 28 | self.loop = GLib.MainLoop() 29 | self.manager.connect( 30 | "name-appeared", lambda *args: self.on_player_appeared(*args)) 31 | self.manager.connect( 32 | "player-vanished", lambda *args: self.on_player_vanished(*args)) 33 | 34 | signal.signal(signal.SIGINT, signal_handler) 35 | signal.signal(signal.SIGTERM, signal_handler) 36 | signal.signal(signal.SIGPIPE, signal.SIG_DFL) 37 | self.selected_player = selected_player 38 | 39 | self.init_players() 40 | 41 | def init_players(self): 42 | for player in self.manager.props.player_names: 43 | if self.selected_player is not None and self.selected_player != player.name: 44 | logger.debug(f"{player.name} is not the filtered player, skipping it") 45 | continue 46 | self.init_player(player) 47 | 48 | def run(self): 49 | logger.info("Starting main loop") 50 | self.loop.run() 51 | 52 | def init_player(self, player): 53 | logger.info(f"Initialize new player: {player.name}") 54 | player = Playerctl.Player.new_from_name(player) 55 | player.connect("playback-status", 56 | self.on_playback_status_changed, None) 57 | player.connect("metadata", self.on_metadata_changed, None) 58 | self.manager.manage_player(player) 59 | self.on_metadata_changed(player, player.props.metadata) 60 | 61 | def get_players(self) -> List[Player]: 62 | return self.manager.props.players 63 | 64 | def write_output(self, text, player): 65 | logger.debug(f"Writing output: {text}") 66 | 67 | output = {"text": text, 68 | "class": "custom-" + player.props.player_name, 69 | "alt": player.props.player_name} 70 | 71 | sys.stdout.write(json.dumps(output) + "\n") 72 | sys.stdout.flush() 73 | 74 | def clear_output(self): 75 | sys.stdout.write("\n") 76 | sys.stdout.flush() 77 | 78 | def on_playback_status_changed(self, player, status, _=None): 79 | logger.debug(f"Playback status changed for player {player.props.player_name}: {status}") 80 | self.on_metadata_changed(player, player.props.metadata) 81 | 82 | def get_first_playing_player(self): 83 | players = self.get_players() 84 | logger.debug(f"Getting first playing player from {len(players)} players") 85 | if len(players) > 0: 86 | # if any are playing, show the first one that is playing 87 | # reverse order, so that the most recently added ones are preferred 88 | for player in players[::-1]: 89 | if player.props.status == "Playing": 90 | return player 91 | # if none are playing, show the first one 92 | return players[0] 93 | else: 94 | logger.debug("No players found") 95 | return None 96 | 97 | def show_most_important_player(self): 98 | logger.debug("Showing most important player") 99 | # show the currently playing player 100 | # or else show the first paused player 101 | # or else show nothing 102 | current_player = self.get_first_playing_player() 103 | if current_player is not None: 104 | self.on_metadata_changed(current_player, current_player.props.metadata) 105 | else: 106 | self.clear_output() 107 | 108 | def on_metadata_changed(self, player, metadata, _=None): 109 | logger.debug(f"Metadata changed for player {player.props.player_name}") 110 | player_name = player.props.player_name 111 | artist = player.get_artist() 112 | title = player.get_title() 113 | 114 | track_info = "" 115 | if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]: 116 | track_info = "Advertisement" 117 | elif artist is not None and title is not None: 118 | track_info = f"{artist} - {title}" 119 | else: 120 | track_info = title 121 | 122 | if track_info: 123 | if player.props.status == "Playing": 124 | track_info = " " + track_info 125 | else: 126 | track_info = " " + track_info 127 | # only print output if no other player is playing 128 | current_playing = self.get_first_playing_player() 129 | if current_playing is None or current_playing.props.player_name == player.props.player_name: 130 | self.write_output(track_info, player) 131 | else: 132 | logger.debug(f"Other player {current_playing.props.player_name} is playing, skipping") 133 | 134 | def on_player_appeared(self, _, player): 135 | logger.info(f"Player has appeared: {player.name}") 136 | if player is not None and (self.selected_player is None or player.name == self.selected_player): 137 | self.init_player(player) 138 | else: 139 | logger.debug( 140 | "New player appeared, but it's not the selected player, skipping") 141 | 142 | def on_player_vanished(self, _, player): 143 | logger.info(f"Player {player.props.player_name} has vanished") 144 | self.show_most_important_player() 145 | 146 | def parse_arguments(): 147 | parser = argparse.ArgumentParser() 148 | 149 | # Increase verbosity with every occurrence of -v 150 | parser.add_argument("-v", "--verbose", action="count", default=0) 151 | 152 | # Define for which player we"re listening 153 | parser.add_argument("--player") 154 | 155 | parser.add_argument("--enable-logging", action="store_true") 156 | 157 | return parser.parse_args() 158 | 159 | 160 | def main(): 161 | arguments = parse_arguments() 162 | 163 | # Initialize logging 164 | if arguments.enable_logging: 165 | logfile = os.path.join(os.path.dirname( 166 | os.path.realpath(__file__)), "media-player.log") 167 | logging.basicConfig(filename=logfile, level=logging.DEBUG, 168 | format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s") 169 | 170 | # Logging is set by default to WARN and higher. 171 | # With every occurrence of -v it's lowered by one 172 | logger.setLevel(max((3 - arguments.verbose) * 10, 0)) 173 | 174 | logger.info("Creating player manager") 175 | if arguments.player: 176 | logger.info(f"Filtering for player: {arguments.player}") 177 | player = PlayerManager(arguments.player) 178 | player.run() 179 | 180 | 181 | if __name__ == "__main__": 182 | main() 183 | --------------------------------------------------------------------------------