diff options
| author | kj-sh604 | 2025-06-06 20:18:26 -0400 |
|---|---|---|
| committer | kj-sh604 | 2025-06-06 20:18:26 -0400 |
| commit | 15cd209a581c2ac9ec63db880cac640cdea3ea04 (patch) | |
| tree | f0f38b54908e5c650ee63d8c2f0abfa724e941e4 /.local/src/python-playerctl_systray | |
| parent | fa7425e3ca53eab2dfc255b3652a7bed8e21283d (diff) | |
refactor: move directory locations
Diffstat (limited to '.local/src/python-playerctl_systray')
| -rw-r--r-- | .local/src/python-playerctl_systray/Makefile | 4 | ||||
| -rw-r--r-- | .local/src/python-playerctl_systray/playerctl_systray.py | 123 |
2 files changed, 127 insertions, 0 deletions
diff --git a/.local/src/python-playerctl_systray/Makefile b/.local/src/python-playerctl_systray/Makefile new file mode 100644 index 0000000..a0ab881 --- /dev/null +++ b/.local/src/python-playerctl_systray/Makefile @@ -0,0 +1,4 @@ +compile: + cython3 --embed -o playerctl_systray.c -X language_level=3 playerctl_systray.py + PYTHON_VERSION=`ls --sort version /usr/include | grep -o 'python[3-9]\+\.[0-9]\+' | tail -1` ; \ + gcc -march=native -O2 -pipe -fno-plt -I /usr/include/$$PYTHON_VERSION -o playerctl_systray playerctl_systray.c -l$$PYTHON_VERSION -lpthread -lm -lutil -ldl `pkg-config --cflags --libs gtk+-3.0 appindicator3-0.1 dbus-1 dbus-glib-1` diff --git a/.local/src/python-playerctl_systray/playerctl_systray.py b/.local/src/python-playerctl_systray/playerctl_systray.py new file mode 100644 index 0000000..79a4c0c --- /dev/null +++ b/.local/src/python-playerctl_systray/playerctl_systray.py @@ -0,0 +1,123 @@ +import gi +import subprocess + +gi.require_version('Gtk', '3.0') +gi.require_version('AppIndicator3', '0.1') +gi.require_version('GLib', '2.0') +from gi.repository import Gtk, AppIndicator3, GLib + +class playerctl_systray: + def __init__(self): + self.last_instances = self.get_player_instances() + self.indicator = AppIndicator3.Indicator.new( + "media-control-app", + "audio-x-generic", + AppIndicator3.IndicatorCategory.APPLICATION_STATUS + ) + self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) + self.indicator.set_menu(self.create_menu()) + + def create_menu(self): + menu = Gtk.Menu() + + instances = self.get_player_instances() + if instances: + for instance in instances: + instance_submenu = Gtk.Menu() + + play_item = Gtk.MenuItem(label="play-pause") + play_item.connect("activate", self.play_pause, instance) + instance_submenu.append(play_item) + + next_item = Gtk.MenuItem(label="next") + next_item.connect("activate", self.next_track, instance) + instance_submenu.append(next_item) + + prev_item = Gtk.MenuItem(label="previous") + prev_item.connect("activate", self.prev_track, instance) + instance_submenu.append(prev_item) + + instance_menu_item = Gtk.MenuItem(label=instance) + instance_menu_item.set_submenu(instance_submenu) + menu.append(instance_menu_item) + + a_submenu = Gtk.Menu() + + a_pause_item = Gtk.MenuItem(label="pause") + a_pause_item.connect("activate", self.a_pause) + a_submenu.append(a_pause_item) + + a_play_item = Gtk.MenuItem(label="play") + a_play_item.connect("activate", self.a_play) + a_submenu.append(a_play_item) + + a_next_item = Gtk.MenuItem(label="next") + a_next_item.connect("activate", self.a_next_track) + a_submenu.append(a_next_item) + + a_prev_item = Gtk.MenuItem(label="previous") + a_prev_item.connect("activate", self.a_prev_track) + a_submenu.append(a_prev_item) + + a_menu_item = Gtk.MenuItem(label="-a") + a_menu_item.set_submenu(a_submenu) + menu.append(a_menu_item) + else: + no_players_item = Gtk.MenuItem(label="no players found") + no_players_item.set_sensitive(False) # greyed out + menu.append(no_players_item) + + menu.append(Gtk.SeparatorMenuItem()) # separator + + quit_item = Gtk.MenuItem(label="quit") + quit_item.connect("activate", self.quit) + menu.append(quit_item) + + menu.show_all() + return menu + + def get_player_instances(self): + result = subprocess.run("playerctl -l", shell=True, capture_output=True, text=True) + return result.stdout.strip().split('\n') if result.stdout.strip() else [] + + def play_pause(self, _, instance): + self.run_command(f"playerctl -p {instance} play-pause") + + def next_track(self, _, instance): + self.run_command(f"playerctl -p {instance} next") + + def prev_track(self, _, instance): + self.run_command(f"playerctl -p {instance} previous") + + def a_play(self, _): + self.run_command("playerctl -a play") + + def a_pause(self, _): + self.run_command("playerctl -a pause") + + def a_next_track(self, _): + self.run_command("playerctl -a next") + + def a_prev_track(self, _): + self.run_command("playerctl -a previous") + + def run_command(self, command): + subprocess.run(command, shell=True) + + def quit(self, _): + Gtk.main_quit() + + def refresh_menu(self): + current_instances = self.get_player_instances() + if current_instances != self.last_instances: + self.indicator.set_menu(self.create_menu()) + self.last_instances = current_instances + return True # returns True so that timeout continues + +def main(): + app = playerctl_systray() + GLib.timeout_add(1024, app.refresh_menu) # probably should be event-based in the future + Gtk.main() + +if __name__ == "__main__": + main() |
