├── 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 | 
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 |
--------------------------------------------------------------------------------