diff --git a/nixosModules/ags/config/configurations/binto.ts b/nixosModules/ags/config/configurations/binto.ts
index 0dae2a28..3c6da082 100644
--- a/nixosModules/ags/config/configurations/binto.ts
+++ b/nixosModules/ags/config/configurations/binto.ts
@@ -4,6 +4,7 @@ import { App } from 'astal/gtk3';
import style from '../style/main.scss';
import AppLauncher from '../widgets/applauncher/main';
+import AudioWindow from '../widgets/audio/binto';
import Bar from '../widgets/bar/binto';
import BgLayer from '../widgets/bg-layer/main';
import Calendar from '../widgets/date/binto';
@@ -52,6 +53,7 @@ export default () => {
perMonitor((monitor) => BgLayer(monitor, false));
AppLauncher();
+ AudioWindow();
Bar();
Calendar();
Clipboard();
diff --git a/nixosModules/ags/config/configurations/wim.ts b/nixosModules/ags/config/configurations/wim.ts
index c4be9d55..b7b44f56 100644
--- a/nixosModules/ags/config/configurations/wim.ts
+++ b/nixosModules/ags/config/configurations/wim.ts
@@ -4,6 +4,7 @@ import { App } from 'astal/gtk3';
import style from '../style/main.scss';
import AppLauncher from '../widgets/applauncher/main';
+import AudioWindow from '../widgets/audio/wim';
import Bar from '../widgets/bar/wim';
import BgLayer from '../widgets/bg-layer/main';
import BluetoothWindow from '../widgets/bluetooth/wim';
@@ -55,6 +56,7 @@ export default () => {
perMonitor((monitor) => BgLayer(monitor, true));
AppLauncher();
+ AudioWindow();
Bar();
BluetoothWindow();
Calendar();
diff --git a/nixosModules/ags/config/style/common.scss b/nixosModules/ags/config/style/common.scss
index b89ec0ea..4d20f311 100644
--- a/nixosModules/ags/config/style/common.scss
+++ b/nixosModules/ags/config/style/common.scss
@@ -30,6 +30,14 @@ progressbar {
}
}
+scale {
+ contents {
+ trough {
+ min-height: 10px;
+ }
+ }
+}
+
circular-progress {
background: #363847;
min-height: 35px;
diff --git a/nixosModules/ags/config/style/main.scss b/nixosModules/ags/config/style/main.scss
index d31e20cd..39045afb 100644
--- a/nixosModules/ags/config/style/main.scss
+++ b/nixosModules/ags/config/style/main.scss
@@ -1,6 +1,7 @@
@use 'common';
@use '../widgets/applauncher';
+@use '../widgets/audio';
@use '../widgets/bar';
@use '../widgets/bluetooth';
@use '../widgets/clipboard';
diff --git a/nixosModules/ags/config/widgets/audio/_index.scss b/nixosModules/ags/config/widgets/audio/_index.scss
new file mode 100644
index 00000000..49fe8ab4
--- /dev/null
+++ b/nixosModules/ags/config/widgets/audio/_index.scss
@@ -0,0 +1,11 @@
+@use 'sass:color';
+@use '../../style/colors';
+
+.widget.audio {
+ .stream {
+ margin: 5px;
+ padding: 10px;
+ border-radius: 8px;
+ background-color: color.adjust(colors.$window_bg_color, $lightness: -3%);
+ }
+}
diff --git a/nixosModules/ags/config/widgets/audio/binto.tsx b/nixosModules/ags/config/widgets/audio/binto.tsx
new file mode 100644
index 00000000..4be56ddf
--- /dev/null
+++ b/nixosModules/ags/config/widgets/audio/binto.tsx
@@ -0,0 +1,18 @@
+import { Astal } from 'astal/gtk3';
+
+import PopupWindow from '../misc/popup-window';
+import { get_gdkmonitor_from_desc } from '../../lib';
+
+import AudioWidget from './main';
+
+
+export default () => (
+
+
+
+);
diff --git a/nixosModules/ags/config/widgets/audio/main.tsx b/nixosModules/ags/config/widgets/audio/main.tsx
new file mode 100644
index 00000000..277f481e
--- /dev/null
+++ b/nixosModules/ags/config/widgets/audio/main.tsx
@@ -0,0 +1,111 @@
+import { bind } from 'astal';
+import { Gtk, Widget } from 'astal/gtk3';
+
+import AstalWp from 'gi://AstalWp';
+
+import { RadioButton, ToggleButton } from '../misc/subclasses';
+import Separator from '../misc/separator';
+
+
+export default () => {
+ const audio = AstalWp.get_default()?.get_audio();
+
+ if (!audio) {
+ throw new Error('Could not find default audio devices.');
+ }
+
+ // TODO: make a stack to have outputs, inputs and currently playing apps
+ // TODO: figure out ports and profiles
+
+ const defaultGroup = new RadioButton();
+
+ return (
+
+ {bind(audio, 'speakers').as((speakers) => speakers.map((speaker) => (
+
+
+ {
+ speaker.connect('notify::isDefault', () => {
+ self.active = speaker.isDefault;
+ });
+ }}
+
+ onToggled={(self) => {
+ speaker.isDefault = self.active;
+ }}
+ />
+
+
+
+
+
+
+
+
+
+ {
+ speaker.set_mute(self.active);
+
+ (self.get_child() as Widget.Icon).icon = self.active ?
+ 'audio-volume-muted-symbolic' :
+ 'audio-speakers-symbolic';
+ }}
+ >
+
+
+
+
+
+ {/*
+ FIXME: lockChannels not working
+ TODO: have two sliders when lockChannels === false
+ */}
+ {
+ speaker.set_lock_channels(self.active);
+
+ (self.get_child() as Widget.Icon).icon = self.active ?
+ 'channel-secure-symbolic' :
+ 'channel-insecure-symbolic';
+ }}
+ >
+
+
+
+ {
+ speaker.set_volume(self.value);
+ }}
+ />
+
+
+ )))}
+
+ );
+};
diff --git a/nixosModules/ags/config/widgets/audio/wim.tsx b/nixosModules/ags/config/widgets/audio/wim.tsx
new file mode 100644
index 00000000..b3327738
--- /dev/null
+++ b/nixosModules/ags/config/widgets/audio/wim.tsx
@@ -0,0 +1,15 @@
+import { Astal } from 'astal/gtk3';
+
+import PopupWindow from '../misc/popup-window';
+
+import AudioWidget from './main';
+
+
+export default () => (
+
+
+
+);
diff --git a/nixosModules/ags/config/widgets/bar/items/audio.tsx b/nixosModules/ags/config/widgets/bar/items/audio.tsx
index 63b3fcc6..a3e2a619 100644
--- a/nixosModules/ags/config/widgets/bar/items/audio.tsx
+++ b/nixosModules/ags/config/widgets/bar/items/audio.tsx
@@ -1,7 +1,11 @@
import { bind } from 'astal';
+import { App } from 'astal/gtk3';
import AstalWp from 'gi://AstalWp';
+import PopupWindow from '../../misc/popup-window';
+
+
export default () => {
const speaker = AstalWp.get_default()?.audio.default_speaker;
@@ -10,8 +14,22 @@ export default () => {
}
return (
-
-
+
+
);
};
diff --git a/nixosModules/ags/config/widgets/misc/subclasses.tsx b/nixosModules/ags/config/widgets/misc/subclasses.tsx
index 626448fc..59c5b596 100644
--- a/nixosModules/ags/config/widgets/misc/subclasses.tsx
+++ b/nixosModules/ags/config/widgets/misc/subclasses.tsx
@@ -13,6 +13,17 @@ export class ToggleButton extends astalify(Gtk.ToggleButton) {
}
}
+@register()
+export class RadioButton extends astalify(Gtk.RadioButton) {
+ constructor(props: ConstructProps<
+ RadioButton,
+ Gtk.RadioButton.ConstructorProps
+ > = {}) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ super(props as any);
+ }
+}
+
@register()
export class ListBox extends astalify(Gtk.ListBox) {
override get_children() {
@@ -22,7 +33,18 @@ export class ListBox extends astalify(Gtk.ListBox) {
constructor(props: ConstructProps<
ListBox,
Gtk.ListBox.ConstructorProps
- >) {
+ > = {}) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ super(props as any);
+ }
+}
+
+@register()
+export class ProgressBar extends astalify(Gtk.ProgressBar) {
+ constructor(props: ConstructProps<
+ ProgressBar,
+ Gtk.ProgressBar.ConstructorProps
+ > = {}) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
super(props as any);
}
diff --git a/nixosModules/ags/config/widgets/on-screen-display/main.tsx b/nixosModules/ags/config/widgets/on-screen-display/main.tsx
index d0f161ba..23fbf15d 100644
--- a/nixosModules/ags/config/widgets/on-screen-display/main.tsx
+++ b/nixosModules/ags/config/widgets/on-screen-display/main.tsx
@@ -1,9 +1,9 @@
import { bind, timeout } from 'astal';
-import { register } from 'astal/gobject';
-import { App, Astal, astalify, Gtk, Widget, type ConstructProps } from 'astal/gtk3';
+import { App, Astal, Gtk, Widget } from 'astal/gtk3';
import AstalWp from 'gi://AstalWp';
+import { ProgressBar } from '../misc/subclasses';
import PopupWindow from '../misc/popup-window';
import Brightness from '../../services/brightness';
@@ -12,17 +12,6 @@ declare global {
function popup_osd(osd: string): void;
}
-@register()
-class ProgressBar extends astalify(Gtk.ProgressBar) {
- constructor(props: ConstructProps<
- ProgressBar,
- Gtk.ProgressBar.ConstructorProps
- >) {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- super(props as any);
- }
-}
-
const HIDE_DELAY = 2000;
const transition_duration = 300;