From 7265a9ec1fff1528ad3ee5d5e9eae928213d99b3 Mon Sep 17 00:00:00 2001 From: retrozinndev Date: Sun, 3 Aug 2025 12:54:53 -0300 Subject: [PATCH] :sparkles: feat(arg-handler): add support for media management within the cli --- ags/scripts/arg-handler.ts | 105 +++++++++++++++++++++++++++++++++++-- hypr/shell/bindings.conf | 6 +-- 2 files changed, 104 insertions(+), 7 deletions(-) diff --git a/ags/scripts/arg-handler.ts b/ags/scripts/arg-handler.ts index 8bb9a04..988c786 100644 --- a/ags/scripts/arg-handler.ts +++ b/ags/scripts/arg-handler.ts @@ -6,10 +6,12 @@ import { Runner } from "../runner/Runner"; import { showWorkspaceNumber } from "../widget/bar/Workspaces"; import { playSystemBell } from "./utils"; import { Config } from "./config"; +import { player, setPlayer } from "../widget/bar/Media"; import AstalIO from "gi://AstalIO"; import GLib from "gi://GLib?version=2.0"; import App from "ags/gtk4/app"; +import AstalMpris from "gi://AstalMpris"; let wsTimeout: (AstalIO.Time|undefined); @@ -18,6 +20,10 @@ export function handleArguments(request: string): any { const args: Array = GLib.shell_parse_argv(request)[1]!; switch(args[0]) { + case "help": + case "h": + return getHelp(); + case "open": case "close": case "toggle": @@ -25,13 +31,12 @@ export function handleArguments(request: string): any { case "reopen": return handleWindowArgs(args); - case "help": - case "h": - return getHelp(); - case "volume": return handleVolumeArgs(args); + case "media": + return handleMediaArgs(args); + case "reload": restartInstance(); return `Restarting instance with name: ${App.instanceName ?? "astal"}`; @@ -59,6 +64,95 @@ export function handleArguments(request: string): any { } } +function handleMediaArgs(args: Array): string { + if(/h|help/.test(args[1])) + return ` +Manage colorshell's active player + +Options: + play: resume/start active player's media. + pause: pause the active player. + play-pause: toggle play/pause on active player. + stop: stop the active player's media. + previous: go back to previous media if player supports it. + next: jump to next media if player supports it. + bus-name: get active player's mpris bus name. + list: show available players with their bus name. + select bus_name: change the active player, where bus_name is + the desired player's mpris bus name(with the mediaplayer2 prefix). +`.trim(); + + const activePlayer: AstalMpris.Player|undefined = player.get().available ? + player.get() + : undefined; + const players = AstalMpris.get_default().players.filter(pl => pl.available); + + if(!activePlayer) + return `Error: no active player found! try playing some media first` + + switch(args[1]) { + case "play": + activePlayer.play(); + return "Playing"; + + case "list": + return `Available players:\n${players.map(pl => { + let playbackStatusStr: string; + switch(pl.playbackStatus) { + case AstalMpris.PlaybackStatus.PAUSED: + playbackStatusStr = "paused"; + break; + case AstalMpris.PlaybackStatus.PLAYING: + playbackStatusStr = "playing"; + break; + default: + playbackStatusStr = "stopped"; + break; + } + + return ` ${pl.busName}: ${playbackStatusStr}`; + }).join('\n')}`; + + case "pause": + activePlayer.pause(); + return "Paused"; + + case "play-pause": + activePlayer.play_pause(); + return activePlayer?.playbackStatus === AstalMpris.PlaybackStatus.PAUSED ? + "Toggled play" + : "Toggled pause"; + + case "stop": + activePlayer.stop(); + return "Stopped!"; + + case "previous": + activePlayer.canGoPrevious && activePlayer.previous(); + return activePlayer.canGoPrevious ? + "Back to previous" + : "Player does not support this command"; + + case "next": + activePlayer.canGoNext && activePlayer.next(); + return activePlayer.canGoNext ? + "Jump to next" + : "Player does not support this command"; + + case "bus-name": + return activePlayer.busName; + + case "select": + if(!args[2] || !players.filter(pl => pl.busName == args[2])?.[0]) + return `Error: either no player was specified or the player with specified bus name does not exist/is not available!`; + + setPlayer(players.filter(pl => pl.busName === args[2])[0]); + return `Done setting player to \`${args[2]}\`!` + } + + return "Error: couldn't handle media arguments, try checking `media help`"; +} + function handleWindowArgs(args: Array): string { switch(args[0]) { case "reopen": @@ -186,6 +280,9 @@ made using Astal Libraries, AGS and Gnim by Aylur. Audio Controls: volume: speaker and microphone volume controller, see "volume help". + + Media Controls: + media: manage colorshell's active player, see "media help". Other options: runner [initial_text]: open the application runner, optionally add an initial search. diff --git a/hypr/shell/bindings.conf b/hypr/shell/bindings.conf index 1cba533..553cd9e 100644 --- a/hypr/shell/bindings.conf +++ b/hypr/shell/bindings.conf @@ -30,9 +30,9 @@ bind = $mainMod, $mainMod_l, exec, astal peek-workspace-num binde = , XF86AudioLowerVolume, exec, astal volume sink-decrease 5 || wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- # Decrease volume binde = , XF86AudioRaiseVolume, exec, astal volume sink-increase 5 || wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+ # Increase volume bind = , XF86AudioMute, exec, astal volume sink-mute || wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle # Mute -bind = , XF86AudioPrev, exec, playerctl previous # Previous media -bind = , XF86AudioNext, exec, playerctl next # Next media -bind = , XF86AudioPlay, exec, playerctl play-pause # Toggle Play/Pause media +bind = , XF86AudioPrev, exec, astal media previous || playerctl previous # Previous media +bind = , XF86AudioNext, exec, astal media next || playerctl next # Next media +bind = , XF86AudioPlay, exec, astal media play-pause || playerctl play-pause # Toggle Play/Pause media bind = , XF86MonBrightnessDown, exec, brightnessctl s 5%- # Lower monitor brightness bind = , XF86MonBrightnessUp, exec, brightnessctl s +5% # Increase monitor brightness