🔧 chore: better implementation of the arg-handler, supporting exit codes
also remade the `reload` command, so it supports the new implementation, removed unnecessary stylesheet
This commit is contained in:
+29
-7
@@ -16,7 +16,6 @@ import { Runner } from "./runner/Runner";
|
|||||||
import { Windows } from "./windows";
|
import { Windows } from "./windows";
|
||||||
import { Notifications } from "./scripts/notifications";
|
import { Notifications } from "./scripts/notifications";
|
||||||
import { Wallpaper } from "./scripts/wallpaper";
|
import { Wallpaper } from "./scripts/wallpaper";
|
||||||
|
|
||||||
import { Stylesheet } from "./scripts/stylesheet";
|
import { Stylesheet } from "./scripts/stylesheet";
|
||||||
import { Clipboard } from "./scripts/clipboard";
|
import { Clipboard } from "./scripts/clipboard";
|
||||||
import { Config } from "./scripts/config";
|
import { Config } from "./scripts/config";
|
||||||
@@ -30,6 +29,7 @@ import GObject, { register } from "ags/gobject";
|
|||||||
import AstalNotifd from "gi://AstalNotifd";
|
import AstalNotifd from "gi://AstalNotifd";
|
||||||
import GLib from "gi://GLib?version=2.0";
|
import GLib from "gi://GLib?version=2.0";
|
||||||
import Gio from "gi://Gio?version=2.0";
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
import Adw from "gi://Adw?version=1";
|
||||||
|
|
||||||
|
|
||||||
const runnerPlugins: Array<Runner.Plugin> = [
|
const runnerPlugins: Array<Runner.Plugin> = [
|
||||||
@@ -43,6 +43,8 @@ const runnerPlugins: Array<Runner.Plugin> = [
|
|||||||
|
|
||||||
const defaultWindows: Array<string> = [];
|
const defaultWindows: Array<string> = [];
|
||||||
|
|
||||||
|
Adw.init();
|
||||||
|
|
||||||
@register({ GTypeName: "Shell" })
|
@register({ GTypeName: "Shell" })
|
||||||
export class Shell extends Gtk.Application {
|
export class Shell extends Gtk.Application {
|
||||||
private static instance: Shell;
|
private static instance: Shell;
|
||||||
@@ -100,18 +102,33 @@ export class Shell extends Gtk.Application {
|
|||||||
|
|
||||||
vfunc_command_line(cmd: Gio.ApplicationCommandLine): number {
|
vfunc_command_line(cmd: Gio.ApplicationCommandLine): number {
|
||||||
const args = cmd.get_arguments();
|
const args = cmd.get_arguments();
|
||||||
|
args.splice(0, 1); // remove executable
|
||||||
|
|
||||||
if(cmd.isRemote) {
|
if(cmd.isRemote) {
|
||||||
cmd.print_literal(handleArguments(args));
|
try {
|
||||||
|
const res = handleArguments(cmd, args);
|
||||||
cmd.done();
|
cmd.done();
|
||||||
|
cmd.set_exit_status(res);
|
||||||
|
return res;
|
||||||
|
} catch(_e) {
|
||||||
|
const e = _e as Error;
|
||||||
|
cmd.printerr_literal(`Error: something went wrong! Stderr: ${e.message}\n${e.stack}`);
|
||||||
|
cmd.done();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(args[1]) {
|
||||||
|
printerr("Error: colorshell not running. Try to clean-run before using arguments");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.main();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.main(args);
|
private main(): void {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private main(_args: Array<string>): void {
|
|
||||||
this.#loop = GLib.MainLoop.new(null, false);
|
this.#loop = GLib.MainLoop.new(null, false);
|
||||||
const connections = new Map<GObject.Object, Array<number> | number>();
|
const connections = new Map<GObject.Object, Array<number> | number>();
|
||||||
|
|
||||||
@@ -157,6 +174,11 @@ export class Shell extends Gtk.Application {
|
|||||||
|
|
||||||
this.#loop.run();
|
this.#loop.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quit(): void {
|
||||||
|
this.#loop.is_running() && this.#loop.quit();
|
||||||
|
super.quit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+326
-253
@@ -6,264 +6,15 @@ import { Runner } from "../runner/Runner";
|
|||||||
import { showWorkspaceNumber } from "../widget/bar/Workspaces";
|
import { showWorkspaceNumber } from "../widget/bar/Workspaces";
|
||||||
import { playSystemBell } from "./utils";
|
import { playSystemBell } from "./utils";
|
||||||
import { player, setPlayer } from "../widget/bar/Media";
|
import { player, setPlayer } from "../widget/bar/Media";
|
||||||
import { generalConfig } from "../app";
|
import { generalConfig, Shell } from "../app";
|
||||||
|
|
||||||
import AstalIO from "gi://AstalIO";
|
import AstalIO from "gi://AstalIO";
|
||||||
import AstalMpris from "gi://AstalMpris";
|
import AstalMpris from "gi://AstalMpris";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
let wsTimeout: (AstalIO.Time|undefined);
|
let wsTimeout: AstalIO.Time|undefined;
|
||||||
|
const help = `Manage Astal Windows and do more stuff. From retrozinndev's colorshell,
|
||||||
export function handleArguments(args: Array<string>): any {
|
|
||||||
switch(args[0]) {
|
|
||||||
case "help":
|
|
||||||
case "h":
|
|
||||||
return getHelp();
|
|
||||||
|
|
||||||
case "open":
|
|
||||||
case "close":
|
|
||||||
case "toggle":
|
|
||||||
case "windows":
|
|
||||||
case "reopen":
|
|
||||||
return handleWindowArgs(args);
|
|
||||||
|
|
||||||
case "volume":
|
|
||||||
return handleVolumeArgs(args);
|
|
||||||
|
|
||||||
case "media":
|
|
||||||
return handleMediaArgs(args);
|
|
||||||
|
|
||||||
case "reload":
|
|
||||||
restartInstance();
|
|
||||||
return "Restarting instance...";
|
|
||||||
|
|
||||||
case "runner":
|
|
||||||
!Runner.instance ?
|
|
||||||
Runner.openDefault(args[1] || undefined)
|
|
||||||
: Runner.close();
|
|
||||||
|
|
||||||
return `Opening runner${args[1] ? ` with predefined text: "${args[1]}"` : ""}`;
|
|
||||||
|
|
||||||
case "peek-workspace-num":
|
|
||||||
if(wsTimeout)
|
|
||||||
return "Workspace numbers are already showing";
|
|
||||||
|
|
||||||
showWorkspaceNumber(true);
|
|
||||||
wsTimeout = timeout(Number.parseInt(args[1]) || 2200, () => {
|
|
||||||
showWorkspaceNumber(false);
|
|
||||||
wsTimeout = undefined;
|
|
||||||
});
|
|
||||||
return "Toggled workspace numbers";
|
|
||||||
|
|
||||||
default:
|
|
||||||
return "Error: command not found! try checking help";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMediaArgs(args: Array<string>): 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>): string {
|
|
||||||
switch(args[0]) {
|
|
||||||
case "reopen":
|
|
||||||
Windows.getDefault().reopen();
|
|
||||||
return "Reopening all open windows";
|
|
||||||
|
|
||||||
case "windows":
|
|
||||||
return Object.keys(Windows.getDefault().windows).map(name =>
|
|
||||||
`${name}: ${Windows.getDefault().isOpen(name) ? "open" : "closed" }`).join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
const specifiedWindow: string = args[1];
|
|
||||||
|
|
||||||
if(!specifiedWindow)
|
|
||||||
return "Error: window argument not specified!";
|
|
||||||
|
|
||||||
if(!Windows.getDefault().hasWindow(specifiedWindow))
|
|
||||||
return `Error: "${specifiedWindow}" not found on window list! Make sure to add new windows to the system before using them`;
|
|
||||||
|
|
||||||
switch(args[0]) {
|
|
||||||
case "open":
|
|
||||||
if(!Windows.getDefault().isOpen(specifiedWindow)) {
|
|
||||||
Windows.getDefault().open(specifiedWindow);
|
|
||||||
return `Opening window with name "${args[1]}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `Window is already open, ignored`;
|
|
||||||
|
|
||||||
case "close":
|
|
||||||
if(Windows.getDefault().isOpen(specifiedWindow)) {
|
|
||||||
Windows.getDefault().close(specifiedWindow);
|
|
||||||
return `Closing window with name "${args[1]}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `Window is already closed, ignored`;
|
|
||||||
|
|
||||||
case "toggle":
|
|
||||||
if(!Windows.getDefault().isOpen(specifiedWindow)) {
|
|
||||||
Windows.getDefault().open(specifiedWindow);
|
|
||||||
return `Toggle opening window "${args[1]}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
Windows.getDefault().close(specifiedWindow);
|
|
||||||
return `Toggle closing window "${args[1]}"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Couldn't handle window management arguments";
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleVolumeArgs(args: Array<string>) {
|
|
||||||
if(!args[1])
|
|
||||||
return `Please specify what you want to do!\n\n${volumeHelp()}`;
|
|
||||||
|
|
||||||
if(/^(sink|source)(\-increase|\-decrease|\-set)$/.test(args[1]) && !args[2])
|
|
||||||
return `You forgot to add a value to be set!`;
|
|
||||||
|
|
||||||
if(Number.isNaN(Number.parseFloat(args[2])) && Number.isSafeInteger(Number.parseFloat(args[2])))
|
|
||||||
return `Argument "${args[2]} is not a valid number! Please use integers"`;
|
|
||||||
|
|
||||||
const command: Array<string> = args[1].split('-');
|
|
||||||
|
|
||||||
if(args[1] === "help")
|
|
||||||
return volumeHelp();
|
|
||||||
|
|
||||||
switch(command[1]) {
|
|
||||||
case "set":
|
|
||||||
command[0] === "sink" ?
|
|
||||||
Wireplumber.getDefault().setSinkVolume(Number.parseInt(args[2]))
|
|
||||||
: Wireplumber.getDefault().setSourceVolume(Number.parseInt(args[2]))
|
|
||||||
return `Done! Set ${command[0]} volume to ${args[2]}`;
|
|
||||||
|
|
||||||
case "mute":
|
|
||||||
command[0] === "sink" ?
|
|
||||||
Wireplumber.getDefault().toggleMuteSink()
|
|
||||||
: Wireplumber.getDefault().toggleMuteSource()
|
|
||||||
|
|
||||||
return `Done toggling mute!`;
|
|
||||||
|
|
||||||
case "increase":
|
|
||||||
command[0] === "sink" ?
|
|
||||||
Wireplumber.getDefault().increaseSinkVolume(Number.parseInt(args[2]))
|
|
||||||
: Wireplumber.getDefault().increaseSourceVolume(Number.parseInt(args[2]))
|
|
||||||
|
|
||||||
generalConfig.getProperty("misc.play_bell_on_volume_change", "boolean") === true &&
|
|
||||||
playSystemBell();
|
|
||||||
|
|
||||||
return `Done increasing volume by ${args[2]}`;
|
|
||||||
|
|
||||||
case "decrease":
|
|
||||||
command[0] === "sink" ?
|
|
||||||
Wireplumber.getDefault().decreaseSinkVolume(Number.parseInt(args[2]))
|
|
||||||
: Wireplumber.getDefault().decreaseSourceVolume(Number.parseInt(args[2]))
|
|
||||||
|
|
||||||
generalConfig.getProperty("misc.play_bell_on_volume_change", "boolean") === true &&
|
|
||||||
playSystemBell();
|
|
||||||
|
|
||||||
return `Done decreasing volume to ${args[2]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `Couldn't resolve arguments! "${args.join(' ').replace(new RegExp(`^${args[0]}`), "")}"`;
|
|
||||||
|
|
||||||
function volumeHelp(): string {
|
|
||||||
return `
|
|
||||||
Control speaker and microphone volumes
|
|
||||||
Options:
|
|
||||||
(sink|source)-set [number]: set speaker/microphone volume.
|
|
||||||
(sink|source)-mute: toggle mute for the speaker/microphone device.
|
|
||||||
(sink|source)-increase [number]: increases speaker/microphone volume.
|
|
||||||
(sink|source)-decrease [number]: decreases speaker/microphone volume.
|
|
||||||
`.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHelp(): string {
|
|
||||||
return `Manage Astal Windows and do more stuff. From retrozinndev's colorshell,
|
|
||||||
made using Astal Libraries, AGS and Gnim by Aylur.
|
made using Astal Libraries, AGS and Gnim by Aylur.
|
||||||
|
|
||||||
Window Management:
|
Window Management:
|
||||||
@@ -273,6 +24,7 @@ made using Astal Libraries, AGS and Gnim by Aylur.
|
|||||||
windows: list shell windows and their respective status.
|
windows: list shell windows and their respective status.
|
||||||
reload: quit this instance and start a new one.
|
reload: quit this instance and start a new one.
|
||||||
reopen: restart all open-windows.
|
reopen: restart all open-windows.
|
||||||
|
quit: exit the main instance of the shell.
|
||||||
|
|
||||||
Audio Controls:
|
Audio Controls:
|
||||||
volume: speaker and microphone volume controller, see "volume help".
|
volume: speaker and microphone volume controller, see "volume help".
|
||||||
@@ -288,4 +40,325 @@ made using Astal Libraries, AGS and Gnim by Aylur.
|
|||||||
2025 (c) retrozinndev's colorshell, licensed under the MIT License.
|
2025 (c) retrozinndev's colorshell, licensed under the MIT License.
|
||||||
https://github.com/retrozinndev/colorshell
|
https://github.com/retrozinndev/colorshell
|
||||||
`.split('\n').map(l => l.replace(/^ {8}/, "")).join('\n');
|
`.split('\n').map(l => l.replace(/^ {8}/, "")).join('\n');
|
||||||
|
|
||||||
|
export function handleArguments(cmd: Gio.ApplicationCommandLine, args: Array<string>): number {
|
||||||
|
switch(args[0]) {
|
||||||
|
case "help":
|
||||||
|
case "h":
|
||||||
|
cmd.print_literal(help);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "open":
|
||||||
|
case "close":
|
||||||
|
case "toggle":
|
||||||
|
case "windows":
|
||||||
|
case "reopen":
|
||||||
|
return handleWindowArgs(cmd, args);
|
||||||
|
|
||||||
|
case "volume":
|
||||||
|
return handleVolumeArgs(cmd, args);
|
||||||
|
|
||||||
|
case "media":
|
||||||
|
return handleMediaArgs(cmd, args);
|
||||||
|
|
||||||
|
case "reload":
|
||||||
|
restartInstance();
|
||||||
|
cmd.print_literal("Restarting instance...");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "quit":
|
||||||
|
try {
|
||||||
|
Shell.getDefault().quit();
|
||||||
|
cmd.print_literal("Quitting main instance...");
|
||||||
|
} catch(_e) {
|
||||||
|
const e = _e as Error;
|
||||||
|
cmd.printerr_literal(`Error: couldn't quit instance. Stderr: ${e.message}\n${e.stack}`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "runner":
|
||||||
|
!Runner.instance ?
|
||||||
|
Runner.openDefault(args[1] || undefined)
|
||||||
|
: Runner.close();
|
||||||
|
|
||||||
|
cmd.print_literal(`Opening runner${args[1] ? ` with predefined text: "${args[1]}"` : ""}`);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "peek-workspace-num":
|
||||||
|
if(wsTimeout) {
|
||||||
|
cmd.print_literal("Workspace numbers are already showing");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
showWorkspaceNumber(true);
|
||||||
|
wsTimeout = timeout(Number.parseInt(args[1]) || 2200, () => {
|
||||||
|
showWorkspaceNumber(false);
|
||||||
|
wsTimeout = undefined;
|
||||||
|
});
|
||||||
|
cmd.print_literal("Toggled workspace numbers");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.printerr_literal("Error: command not found! try checking help");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMediaArgs(cmd: Gio.ApplicationCommandLine, args: Array<string>): number {
|
||||||
|
if(/h|help/.test(args[1])) {
|
||||||
|
const mediaHelp = `
|
||||||
|
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();
|
||||||
|
cmd.print_literal(mediaHelp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const activePlayer: AstalMpris.Player|undefined = player.get().available ?
|
||||||
|
player.get()
|
||||||
|
: undefined;
|
||||||
|
const players = AstalMpris.get_default().players.filter(pl => pl.available);
|
||||||
|
|
||||||
|
if(!activePlayer) {
|
||||||
|
cmd.printerr_literal(`Error: no active player found! try playing some media first`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(args[1]) {
|
||||||
|
case "play":
|
||||||
|
activePlayer.play();
|
||||||
|
cmd.print_literal("Playing");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "list":
|
||||||
|
cmd.print_literal(`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')}`);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "pause":
|
||||||
|
activePlayer.pause();
|
||||||
|
cmd.print_literal("Paused");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "play-pause":
|
||||||
|
activePlayer.play_pause();
|
||||||
|
cmd.print_literal(
|
||||||
|
activePlayer?.playbackStatus === AstalMpris.PlaybackStatus.PAUSED ?
|
||||||
|
"Toggled play"
|
||||||
|
: "Toggled pause"
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "stop":
|
||||||
|
activePlayer.stop();
|
||||||
|
cmd.print_literal("Stopped!");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "previous":
|
||||||
|
activePlayer.canGoPrevious && activePlayer.previous();
|
||||||
|
cmd.print_literal(
|
||||||
|
activePlayer.canGoPrevious ?
|
||||||
|
"Back to previous"
|
||||||
|
: "Player does not support this command"
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "next":
|
||||||
|
activePlayer.canGoNext && activePlayer.next();
|
||||||
|
cmd.print_literal(
|
||||||
|
activePlayer.canGoNext ?
|
||||||
|
"Jump to next"
|
||||||
|
: "Player does not support this command"
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "bus-name":
|
||||||
|
cmd.print_literal(activePlayer.busName);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "select":
|
||||||
|
if(!args[2] || !players.filter(pl => pl.busName == args[2])?.[0]) {
|
||||||
|
cmd.printerr_literal(`Error: either no player was specified or the player with \
|
||||||
|
specified bus name does not exist/is not available!`);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setPlayer(players.filter(pl => pl.busName === args[2])[0]);
|
||||||
|
cmd.print_literal(`Done setting player to \`${args[2]}\`!`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.printerr_literal("Error: couldn't handle media arguments, try checking `media help`");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleWindowArgs(cmd: Gio.ApplicationCommandLine, args: Array<string>): number {
|
||||||
|
switch(args[0]) {
|
||||||
|
case "reopen":
|
||||||
|
Windows.getDefault().reopen();
|
||||||
|
cmd.print_literal("Reopening all open windows");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "windows":
|
||||||
|
cmd.print_literal(
|
||||||
|
Object.keys(Windows.getDefault().windows).map(name =>
|
||||||
|
`${name}: ${Windows.getDefault().isOpen(name) ?
|
||||||
|
"open"
|
||||||
|
: "closed"}`
|
||||||
|
).join('\n')
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const specifiedWindow: string = args[1];
|
||||||
|
|
||||||
|
if(!specifiedWindow) {
|
||||||
|
cmd.printerr_literal("Error: window argument not specified!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Windows.getDefault().hasWindow(specifiedWindow)) {
|
||||||
|
cmd.printerr_literal(
|
||||||
|
`Error: "${specifiedWindow}" not found on window list! Make sure to add new windows to the system before using them`
|
||||||
|
);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(args[0]) {
|
||||||
|
case "open":
|
||||||
|
if(!Windows.getDefault().isOpen(specifiedWindow)) {
|
||||||
|
Windows.getDefault().open(specifiedWindow);
|
||||||
|
cmd.print_literal(`Opening window with name "${args[1]}"`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.print_literal(`Window is already open, ignored`);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "close":
|
||||||
|
if(Windows.getDefault().isOpen(specifiedWindow)) {
|
||||||
|
Windows.getDefault().close(specifiedWindow);
|
||||||
|
cmd.print_literal(`Closing window with name "${args[1]}"`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.print_literal(`Window is already closed, ignored`);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "toggle":
|
||||||
|
if(!Windows.getDefault().isOpen(specifiedWindow)) {
|
||||||
|
Windows.getDefault().open(specifiedWindow);
|
||||||
|
cmd.print_literal(`Toggle opening window "${args[1]}"`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Windows.getDefault().close(specifiedWindow);
|
||||||
|
cmd.print_literal(`Toggle closing window "${args[1]}"`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.printerr_literal("Couldn't handle window management arguments");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleVolumeArgs(cmd: Gio.ApplicationCommandLine, args: Array<string>): number {
|
||||||
|
if(!args[1]) {
|
||||||
|
cmd.printerr_literal(`Error: please specify what to do! see \`volume help\``);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(/^(sink|source)[-](increase|decrease|set)$/.test(args[1]) && !args[2]) {
|
||||||
|
cmd.printerr_literal(`Error: you forgot to set a value`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Number.isNaN(Number.parseFloat(args[2]))) {
|
||||||
|
cmd.printerr_literal(`Error: argument "${args[2]} is not a valid number! Please use integers"`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const command: Array<string> = args[1].split('-');
|
||||||
|
|
||||||
|
if(/h|help/.test(args[1])) {
|
||||||
|
cmd.print_literal(`
|
||||||
|
Control speaker and microphone volumes
|
||||||
|
Options:
|
||||||
|
(sink|source)-set [number]: set speaker/microphone volume.
|
||||||
|
(sink|source)-mute: toggle mute for the speaker/microphone device.
|
||||||
|
(sink|source)-increase [number]: increases speaker/microphone volume.
|
||||||
|
(sink|source)-decrease [number]: decreases speaker/microphone volume.
|
||||||
|
`.trim());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(command[1]) {
|
||||||
|
case "set":
|
||||||
|
command[0] === "sink" ?
|
||||||
|
Wireplumber.getDefault().setSinkVolume(Number.parseInt(args[2]))
|
||||||
|
: Wireplumber.getDefault().setSourceVolume(Number.parseInt(args[2]))
|
||||||
|
cmd.print_literal(`Done! Set ${command[0]} volume to ${args[2]}`);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "mute":
|
||||||
|
command[0] === "sink" ?
|
||||||
|
Wireplumber.getDefault().toggleMuteSink()
|
||||||
|
: Wireplumber.getDefault().toggleMuteSource()
|
||||||
|
|
||||||
|
cmd.print_literal(`Done toggling mute!`);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "increase":
|
||||||
|
command[0] === "sink" ?
|
||||||
|
Wireplumber.getDefault().increaseSinkVolume(Number.parseInt(args[2]))
|
||||||
|
: Wireplumber.getDefault().increaseSourceVolume(Number.parseInt(args[2]))
|
||||||
|
|
||||||
|
generalConfig.getProperty("misc.play_bell_on_volume_change", "boolean") === true &&
|
||||||
|
playSystemBell();
|
||||||
|
|
||||||
|
cmd.print_literal(`Done increasing volume by ${args[2]}`);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case "decrease":
|
||||||
|
command[0] === "sink" ?
|
||||||
|
Wireplumber.getDefault().decreaseSinkVolume(Number.parseInt(args[2]))
|
||||||
|
: Wireplumber.getDefault().decreaseSourceVolume(Number.parseInt(args[2]))
|
||||||
|
|
||||||
|
generalConfig.getProperty("misc.play_bell_on_volume_change", "boolean") === true &&
|
||||||
|
playSystemBell();
|
||||||
|
|
||||||
|
cmd.print_literal(`Done decreasing volume to ${args[2]}`);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.printerr_literal(`Error: couldn't resolve arguments! "${args.join(' ')
|
||||||
|
.replace(new RegExp(`^${args[0]}`), "")}"`);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,15 @@
|
|||||||
import { monitorFile } from "ags/file";
|
|
||||||
import { execAsync } from "ags/process";
|
|
||||||
import { uwsmIsActive } from "./apps";
|
import { uwsmIsActive } from "./apps";
|
||||||
|
|
||||||
import Gio from "gi://Gio?version=2.0";
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
import { Shell } from "../app";
|
||||||
|
|
||||||
|
|
||||||
const monitoringPaths = [ "./scripts", "./window", "./app.ts", "env.d.ts" ];
|
|
||||||
|
|
||||||
export function restartInstance(): void {
|
export function restartInstance(): void {
|
||||||
execAsync(`astal -q "colorshell"`);
|
|
||||||
Gio.Subprocess.new(
|
Gio.Subprocess.new(
|
||||||
( uwsmIsActive ?
|
( uwsmIsActive ?
|
||||||
[ "uwsm", "app", "--", "ags", "run" ]
|
[ "uwsm", "app", "--", "colorshell" ]
|
||||||
: [ "ags", "run" ]),
|
: [ "colorshell" ]),
|
||||||
Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE
|
Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE
|
||||||
);
|
);
|
||||||
}
|
Shell.getDefault().quit();
|
||||||
|
|
||||||
export function monitorPaths(): void {
|
|
||||||
monitoringPaths.map((path: string) => {
|
|
||||||
monitorFile(
|
|
||||||
path,
|
|
||||||
() => restartInstance()
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
@use "sass:color";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GTK3 only supports sRGB color space, unfortunately
|
|
||||||
*/
|
|
||||||
@function toRGB($color) {
|
|
||||||
@return rgba(
|
|
||||||
color.channel($color, "red"),
|
|
||||||
color.channel($color, "green"),
|
|
||||||
color.channel($color, "blue"),
|
|
||||||
color.alpha($color)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user