diff --git a/.config/sway/config b/.config/sway/config index 0a089b7..d2aff2b 100644 --- a/.config/sway/config +++ b/.config/sway/config @@ -26,7 +26,7 @@ set $lock swaylock # Note: pass the final command to swaymsg so that the resulting window can be opened # on the original workspace that the command was run on. #set $menu dmenu_path | dmenu | xargs swaymsg exec -- -set $menu j4-dmenu-desktop --dmenu='bemenu -i -w -H 25 --nb "#161320" --nf "#F5E0DC" --hf "#DDB6F2" --tf "#DDB6F2" --hb "#1E1E2E" --fn "Fira Code 12"' --term='kitty' +set $menu j4-dmenu-desktop --dmenu='bemenu -i -w -H 35 --nb "#161320" --nf "#F5E0DC" --hf "#DDB6F2" --tf "#DDB6F2" --hb "#1E1E2E" --fn "Fira Code 12"' --term='kitty' ### Output configuration # @@ -232,40 +232,50 @@ bindsym $mod+r mode "resize" # Status Bar: # # Read `man 5 sway-bar` for more information about this section. -bar { - position top +#bar { +# position top - # When the status_command prints a new line to stdout, swaybar updates. - # The default just shows the current date and time. - #status_command while date +'%Y-%m-%d %l:%M %p'; do sleep 1; done - status_command swaystatus; +# # When the status_command prints a new line to stdout, swaybar updates. +# # The default just shows the current date and time. +# #status_command while date +'%Y-%m-%d %l:%M %p'; do sleep 1; done +# status_command swaystatus; - font "Fira Code" 11 - height 20 - workspace_min_width 25 +# font "Fira Code" 11 +# height 20 +# workspace_min_width 25 - colors { - statusline #F5E0DC - background #1A1826 - inactive_workspace #32323200 #32323200 #5c5c5c - separator #988BA2 - focused_workspace #DDB6F2 #575268 #F5E0DC - } +# colors { +# statusline #F5E0DC +# background #1A1826 +# inactive_workspace #32323200 #32323200 #5c5c5c +# separator #988BA2 +# focused_workspace #DDB6F2 #575268 #F5E0DC +# } - tray_padding 2 - tray_bindsym button1 Activate - tray_bindsym button2 ContextMenu -} +# tray_padding 2 +# tray_bindsym button1 Activate +# tray_bindsym button2 ContextMenu +#} # Window decorating +for_window [class=".*"] border pixel 0 client.focused #DDB6F2 #1A1826 #F5E0DC #F2CDCD client.unfocused #302D41 #1E1E2E #C9CBFF font "Fira Code" 11 titlebar_border_thickness 2 hide_edge_borders none +gaps inner 5 +gaps outer 5 + +# assign some windows to workspaces +assign [app_id="firefox"] 2 +assign [class="nheko"] 3 +assign [class="dino"] 3 +assign [class="lollypop"] 5 include /etc/sway/config.d/* +bar swaybar_command waybar #exec mpvpaper -o "no-audio --loop-playlist=inf" eDP-1 ~/Videos/space\ man\ live\ wallpaper\ \[Rldut_Ysncs\].webm exec swaybg -i ~/Pictures/art/Stargazer.png exec pipewire diff --git a/.config/waybar/config b/.config/waybar/config new file mode 100644 index 0000000..166c2f9 --- /dev/null +++ b/.config/waybar/config @@ -0,0 +1,120 @@ +{ + "height": 37, // Waybar height (to be removed for auto height) + "modules-left": ["sway/workspaces", "custom/media"], + "modules-center": ["clock"], + "modules-right": ["cpu", "memory", "temperature", "sway/language", "pulseaudio", "backlight", "battery", "network", "tray"], + + // Modules configuration + "sway/workspaces": { + "disable-scroll": false, + "all-outputs": true, + "format": "{icon}", + "format-icons": { + "1": " ", + "2": " ", + "3": " ", + "4": " ", + "5": " ", + "6": " ", + "7": " ", + "8": " ", + "9": " ", + "10": " ", + "urgent": " ", + "focused": " ", + "default": " " + } + }, + "sway/mode": { + "format": "{}" + }, + "sway/language": { + "format": "{short} ⠀⠀" + }, + "tray": { + "spacing": 10 + }, + "clock": { + "tooltip-format": "{:%Y %B}\n{calendar}", + "format": "{:%l:%M %p}  ", + "format-alt": "{:%A, %B %d, %Y}  " + }, + "cpu": { + "format": "{usage}%  ", + "tooltip": false + }, + "memory": { + "format": "{}%  " + }, + "temperature": { + "critical-threshold": 80, + "format": "{temperatureC}°C {icon}", + "format-icons": [" ", " ", " "] + }, + "backlight": { + "format": "{icon} {percent}%", + "format-icons": [" ", " "], + "on-scroll-up": "light -A 1", + "on-scroll-down": "light -U 1" + }, + "battery": { + "states": { + "warning": 30, + "critical": 15 + }, + "format": "{icon} {capacity}%", + "tooltip-format": "{timeTo}, {capacity}%", + "format-charging": " {capacity}%", + "format-plugged": " ", + "format-alt": "{time} {icon}", + "format-icons": ["", "", "", "", ""] + }, + "network": { + "format-wifi": "直 ", + "format-ethernet": "{ifname}: {ipaddr}/{cidr}  ", + "format-linked": "{ifname} (No IP)  ", + "format-disconnected": "睊 ", + "format-alt": "{ifname}: {ipaddr}/{cidr}", + "tooltip-format": "{essid} {signalStrength}%" + }, + "pulseaudio": { + "format": "{icon} {volume}% {format_source}", + "format-bluetooth": "{icon} {volume}% {format_source}", + "format-bluetooth-muted": "  {volume}% {format_source}", + "format-muted": " {format_source}", + "format-source": " ", + "format-source-muted": " ", + "format-icons": { + "headphone": " ", + "hands-free": " ", + "headset": " ", + "phone": " ", + "portable": " ", + "car": " ", + "default": [" ", " ", " "] + }, + "tooltip-format": "{desc}, {volume}%", + "on-click": "pactl set-sink-mute @DEFAULT_SINK@ toggle", + "on-click-right": "pactl set-source-mute @DEFAULT_SOURCE@ toggle", + "on-click-middle": "pavucontrol" + }, + "custom/media": { + "format": "{icon} {}", + "return-type": "json", + "max-length": 40, + "format-icons": { + "spotify": " ", + "default": " " + }, + "escape": true, + "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null", + "on-click": "playerctl play-pause", + }, + "custom/fans": { + "format": "{}", + "exec": "$HOME/.config/waybar/fans.sh", + "escape": true, + "restart-interval": 10, + } +} + diff --git a/.config/waybar/mediaplayer.py b/.config/waybar/mediaplayer.py new file mode 100755 index 0000000..b2706dc --- /dev/null +++ b/.config/waybar/mediaplayer.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +import argparse +import logging +import sys +import signal +import gi +import json +gi.require_version('Playerctl', '2.0') +from gi.repository import Playerctl, GLib + +logger = logging.getLogger(__name__) + + +def write_output(text, player): + logger.info('Writing output') + + 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 on_play(player, status, manager): + logger.info('Received new playback status') + on_metadata(player, player.props.metadata, manager) + + +def on_metadata(player, metadata, manager): + logger.info('Received new metadata') + track_info = '' + + if player.props.player_name == 'spotify' and \ + 'mpris:trackid' in metadata.keys() and \ + ':ad:' in player.props.metadata['mpris:trackid']: + track_info = 'AD PLAYING' + elif player.get_artist() != '' and player.get_title() != '': + track_info = '{artist} - {title}'.format(artist=player.get_artist(), + title=player.get_title()) + else: + track_info = player.get_title() + + if player.props.status != 'Playing' and track_info: + track_info = ' ' + track_info + write_output(track_info, player) + + +def on_player_appeared(manager, player, selected_player=None): + if player is not None and (selected_player is None or player.name == selected_player): + init_player(manager, player) + else: + logger.debug("New player appeared, but it's not the selected player, skipping") + + +def on_player_vanished(manager, player): + logger.info('Player has vanished') + sys.stdout.write('\n') + sys.stdout.flush() + + +def init_player(manager, name): + logger.debug('Initialize player: {player}'.format(player=name.name)) + player = Playerctl.Player.new_from_name(name) + player.connect('playback-status', on_play, manager) + player.connect('metadata', on_metadata, manager) + manager.manage_player(player) + on_metadata(player, player.props.metadata, manager) + + +def signal_handler(sig, frame): + logger.debug('Received signal to stop, exiting') + sys.stdout.write('\n') + sys.stdout.flush() + # loop.quit() + sys.exit(0) + + +def parse_arguments(): + parser = argparse.ArgumentParser() + + # Increase verbosity with every occurence of -v + parser.add_argument('-v', '--verbose', action='count', default=0) + + # Define for which player we're listening + parser.add_argument('--player') + + return parser.parse_args() + + +def main(): + arguments = parse_arguments() + + # Initialize logging + logging.basicConfig(stream=sys.stderr, level=logging.DEBUG, + format='%(name)s %(levelname)s %(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)) + + # Log the sent command line arguments + logger.debug('Arguments received {}'.format(vars(arguments))) + + manager = Playerctl.PlayerManager() + loop = GLib.MainLoop() + + manager.connect('name-appeared', lambda *args: on_player_appeared(*args, arguments.player)) + manager.connect('player-vanished', on_player_vanished) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + for player in manager.props.player_names: + if arguments.player is not None and arguments.player != player.name: + logger.debug('{player} is not the filtered player, skipping it' + .format(player=player.name) + ) + continue + + init_player(manager, player) + + loop.run() + + +if __name__ == '__main__': + main() diff --git a/.config/waybar/style.css b/.config/waybar/style.css new file mode 100644 index 0000000..d70eef2 --- /dev/null +++ b/.config/waybar/style.css @@ -0,0 +1,142 @@ +* { + border: none; + font-family: Iosevka Nerd Font, sans-serif; + font-size: 13px; +} + +window#waybar { + /* background-color: rgba(18, 21, 29, 0.98); */ + background-color: #161320; + /* background-color: rgba(0, 0, 0, 0); */ + border-bottom: 3px solid #1A1826; + color: #D9E0EE; + transition-property: background-color; + transition-duration: .5s; +} + +window#waybar.hidden { + opacity: 0.2; +} + +#workspaces, +#mode, +#cpu, +#memory, +#temperature, +#custom-media, +#custom-fans, +#clock, +#idle_inhibitor, +#language, +#pulseaudio, +#backlight, +#battery, +#network, +#tray { + background-color: #1E1E2E; + padding: 0 10px; + margin: 2px 4px 5px 4px; + border: 3px solid rgba(0, 0, 0, 0); + border-radius: 90px; + background-clip: padding-box; +} + +#workspaces button { + padding: 0 5px; + min-width: 20px; + color: #96CDFB; +} + +#workspaces button:hover { + background-color: rgba(0, 0, 0, 0.2) +} + +#workspaces button.focused { + color: #DDB6F2; +} + +#workspaces button.urgent { + color: #F28FAD; +} + +#cpu { + color: #F2CDCD; +} + +#memory { + color: #F5C2E7; +} + +#temperature { + color: #F8BD96; +} + +#temperature.critical { + background-color: #F28FAD; + color: #1A1826; +} + +#custom-media { + background-color: #c678dd; + color: #1e222a; +} + +#custom-fans { + color: #98c379; +} + +#clock { + color: #D9E0EE; +} + +#language { + color: #988BA2; +} + +#pulseaudio { + color: #FAE3B0; +} + +#pulseaudio.muted { + background-color: #E8A2AF; + color: #1e222a; +} + +#backlight { + color: #89DCEB; +} + +#battery { + color: #ABE9B3; +} + +#battery.charging, #battery.plugged { + background-color: #ABE9B3; + color: #1e222a; +} + +@keyframes blink { + to { + background-color: #1e222a; + color: #F28FAD; + } +} + +#battery.critical:not(.charging) { + background-color: #F28FAD; + color: #1e222a; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +#network { + color: #DDB6F2; +} + +#network.disconnected { + background-color: #F28FAD; + color: #1e222a; +}