diff --git a/waybar/config.jsonc b/waybar/config.jsonc index 1cbb67e..a9bdaaa 100644 --- a/waybar/config.jsonc +++ b/waybar/config.jsonc @@ -6,8 +6,13 @@ // "width": 1280, // Waybar width "spacing": 8, // Gaps between modules (4px) // Choose the order of the modules - "modules-left": ["hyprland/workspaces", "tray", "hyprland/window"], - "modules-center": ["custom/spotify"], + "modules-left": [ + "custom/os", + "hyprland/workspaces", + "tray", + "hyprland/window", + ], + "modules-center": ["mpris"], "modules-right": [ "custom/swww", "wireplumber", @@ -19,6 +24,10 @@ "clock", "custom/swaync", ], + "custom/os": { + "format": "󱄅", + "on-click": "~/.config/rofi/scripts/powermenu_t1", + }, "idle_inhibitor": { "format": "{icon}", "tooltip-format-activated": "On", @@ -73,6 +82,7 @@ "wireplumber": { "format": " {volume}%", "format-mute": " {volume}%", + "on-click": "~/.config/rofi/applets/bin/volume.sh", }, "network": { // "interface": "wlp2*", // (Optional) To force the use of this interface @@ -83,16 +93,19 @@ "format-disconnected": "󰖪", //"format-alt": "{ifname}: {ipaddr}/{cidr}" }, - "custom/spotify": { - "format": "{}", - "on-click": "playerctl --player=spotify play-pause", - "exec": "python3 $HOME/.config/waybar/modules/mediaplayer.py --player spotify", - "return-type": "json", - "max-length": 40, - "format-icons": { - "spotify": " ", - "default": "🎜 ", + "mpris": { + "format": "{player_icon} {dynamic}", + "format-paused": "{status_icon} {dynamic}", + "player-icons": { + "default": "▶", + "mpv": "🎵", }, + "interval": 1, + "status-icons": { + "paused": "⏸", + }, + "dynamic-len": 72, + // "ignored-players": ["firefox"] }, "custom/swaync": { "format": "{icon}", @@ -112,7 +125,7 @@ "tooltip-format": "Change Wallpaper", "on-click": "pywal", "format-icons": { - "default": " ", + "default": "", }, }, } diff --git a/waybar/modules/mediaplayer.py b/waybar/modules/mediaplayer.py deleted file mode 100644 index e473697..0000000 --- a/waybar/modules/mediaplayer.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python3 -import gi -gi.require_version("Playerctl", "2.0") -from gi.repository import Playerctl, GLib -from gi.repository.Playerctl import Player -import argparse -import logging -import sys -import signal -import gi -import json -import os -from typing import List - -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() - title = player.get_title() - - 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 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/waybar/style.css b/waybar/style.css index d0bb862..9bd8fe4 100644 --- a/waybar/style.css +++ b/waybar/style.css @@ -1,37 +1,42 @@ +/* +* Color Palette +*/ +@import url("../../.cache/wal/colors-waybar.css"); + * { /* `otf-font-awesome` is required to be installed for icons */ - font-family: "JetBrains Mono", "Iosevka Nerd Font", FontAwesome, Roboto, Helvetica, Arial, sans-serif; + font-family: "JetBrains Mono", "Iosevka Nerd Font", FontAwesome, Roboto, + Helvetica, Arial, sans-serif; text-shadow: none; transition: color 0.5s ease-in-out; transition: background-color 0.5s ease-in-out; } -/* -* Color Palette -*/ -@import url('../../.cache/wal/colors-waybar.css'); +@define-color button @color4; +@define-color button-hover @color5; +@define-color button-active @color6; /* * General */ -@import url('./styles/module-groups.css'); -@import url('./styles/modules.css'); -@import url('./styles/waybar.css'); +@import url("./styles/module-groups.css"); +@import url("./styles/modules.css"); +@import url("./styles/waybar.css"); /* * Modules */ -@import url('./styles/modules/clock.css'); -@import url('./styles/modules/cpu.css'); -@import url('./styles/modules/idle.css'); -@import url('./styles/modules/memory.css'); -@import url('./styles/modules/network.css'); -@import url('./styles/modules/spotify.css'); -@import url('./styles/modules/swaync.css'); -@import url('./styles/modules/swww.css'); -@import url('./styles/modules/temperature.css'); -@import url('./styles/modules/tray.css'); -@import url('./styles/modules/window.css'); -@import url('./styles/modules/wireplumber.css'); -@import url('./styles/modules/workspaces.css'); - +@import url("./styles/modules/os.css"); +@import url("./styles/modules/clock.css"); +@import url("./styles/modules/cpu.css"); +@import url("./styles/modules/idle.css"); +@import url("./styles/modules/memory.css"); +@import url("./styles/modules/network.css"); +@import url("./styles/modules/mpris.css"); +@import url("./styles/modules/swaync.css"); +@import url("./styles/modules/swww.css"); +@import url("./styles/modules/temperature.css"); +@import url("./styles/modules/tray.css"); +@import url("./styles/modules/window.css"); +@import url("./styles/modules/wireplumber.css"); +@import url("./styles/modules/workspaces.css"); diff --git a/waybar/styles/modules/clock.css b/waybar/styles/modules/clock.css index 4c0ebfd..d49fb49 100644 --- a/waybar/styles/modules/clock.css +++ b/waybar/styles/modules/clock.css @@ -1,4 +1,7 @@ #clock { - background: @color5; + background: @button; } +#clock:hover { + background: @button-hover; +} diff --git a/waybar/styles/modules/cpu.css b/waybar/styles/modules/cpu.css index bbb1f04..ea24d51 100644 --- a/waybar/styles/modules/cpu.css +++ b/waybar/styles/modules/cpu.css @@ -1,4 +1,2 @@ #cpu { - color: #bf616a; } - diff --git a/waybar/styles/modules/idle.css b/waybar/styles/modules/idle.css index d3a7f61..fbe225b 100644 --- a/waybar/styles/modules/idle.css +++ b/waybar/styles/modules/idle.css @@ -1,9 +1,12 @@ #idle_inhibitor { padding: 0 16px 0 12px; - background-color: @color5; + background-color: @button; +} + +#idle_inhibitor:hover { + background-color: @button-hover; } #idle_inhibitor.activated { - background-color: @color6; + background-color: @button-active; } - diff --git a/waybar/styles/modules/memory.css b/waybar/styles/modules/memory.css index 6be9e4e..8427d7a 100644 --- a/waybar/styles/modules/memory.css +++ b/waybar/styles/modules/memory.css @@ -1,4 +1,2 @@ #memory { - color: #b48ead; } - diff --git a/waybar/styles/modules/mpris.css b/waybar/styles/modules/mpris.css new file mode 100644 index 0000000..161b04b --- /dev/null +++ b/waybar/styles/modules/mpris.css @@ -0,0 +1,7 @@ +#mpris { + background-color: @button; +} + +#mpris:hover { + background-color: @button-hover; +} diff --git a/waybar/styles/modules/network.css b/waybar/styles/modules/network.css index 4869cba..1bdaaa5 100644 --- a/waybar/styles/modules/network.css +++ b/waybar/styles/modules/network.css @@ -1,8 +1,6 @@ #network { - color: #5e81ac; } #network.disconnected { - background-color: #f53c3c; + color: #f53c3c; } - diff --git a/waybar/styles/modules/os.css b/waybar/styles/modules/os.css new file mode 100644 index 0000000..51bbe4c --- /dev/null +++ b/waybar/styles/modules/os.css @@ -0,0 +1,9 @@ +#custom-os { + padding: 0 12px 0 6px; + font-size: 24px; + background: @button; +} + +#custom-os:hover { + background: @button-hover; +} diff --git a/waybar/styles/modules/spotify.css b/waybar/styles/modules/spotify.css deleted file mode 100644 index 20f67cc..0000000 --- a/waybar/styles/modules/spotify.css +++ /dev/null @@ -1,5 +0,0 @@ -.custom-spotify { - color: #333; - background-color: #1db954; - font-style: italic; -} diff --git a/waybar/styles/modules/swaync.css b/waybar/styles/modules/swaync.css index 5dfa28a..160ab12 100644 --- a/waybar/styles/modules/swaync.css +++ b/waybar/styles/modules/swaync.css @@ -1,4 +1,7 @@ -.custom-swaync { - background-color: white; +#custom-swaync { + background-color: @button; } +#custom-swaync:hover { + background-color: @button-hover; +} diff --git a/waybar/styles/modules/swww.css b/waybar/styles/modules/swww.css index 370db9c..ca0d859 100644 --- a/waybar/styles/modules/swww.css +++ b/waybar/styles/modules/swww.css @@ -1,4 +1,9 @@ -.custom-swww { - color: @color9; +#custom-swww { + padding: 0 16px 0 8px; + font-size: 18px; + background-color: @button; } +#custom-swww:hover { + background-color: @button-hover; +} diff --git a/waybar/styles/modules/temperature.css b/waybar/styles/modules/temperature.css index 51860da..ac5e70f 100644 --- a/waybar/styles/modules/temperature.css +++ b/waybar/styles/modules/temperature.css @@ -1,8 +1,6 @@ #temperature { - color: #d08770; } #temperature.critical { color: #bf616a; } - diff --git a/waybar/styles/modules/tray.css b/waybar/styles/modules/tray.css index 9389d9d..e19ae76 100644 --- a/waybar/styles/modules/tray.css +++ b/waybar/styles/modules/tray.css @@ -1,4 +1,5 @@ #tray { + background-color: @button; padding: 0 10px; } @@ -19,4 +20,3 @@ #tray button:hover { box-shadow: inset 0 -3px #5e81ac; } - diff --git a/waybar/styles/modules/window.css b/waybar/styles/modules/window.css index 3ea826b..3849841 100644 --- a/waybar/styles/modules/window.css +++ b/waybar/styles/modules/window.css @@ -1,5 +1,4 @@ #window { - color: @color6; border-radius: 20px; padding-left: 10px; padding-right: 10px; diff --git a/waybar/styles/modules/wireplumber.css b/waybar/styles/modules/wireplumber.css index 935393d..925ab2d 100644 --- a/waybar/styles/modules/wireplumber.css +++ b/waybar/styles/modules/wireplumber.css @@ -1,8 +1,7 @@ #wireplumber { - background: @color4; + background: @button; } #wireplumber.muted { color: #f53c3c; } - diff --git a/waybar/styles/modules/workspaces.css b/waybar/styles/modules/workspaces.css index eaa9f04..d7832b4 100644 --- a/waybar/styles/modules/workspaces.css +++ b/waybar/styles/modules/workspaces.css @@ -1,4 +1,3 @@ - #workspaces { padding: 0; /* border: 2px solid @color4; */ @@ -9,23 +8,22 @@ box-shadow: none; border: none; border-radius: 9999px; - color: @color2; + color: @button; } #workspaces button.active { - color: @color5; + color: @button-active; } #workspaces button:hover { background: transparent; - color: @color5; + color: @button-hover; } #workspaces button.focused { - color: @color4; + color: @button-active; } #workspaces button.urgent { color: #bf616a; } -