feat: audio mixer, Audio app, fix Installer crash

This commit is contained in:
2026-05-19 07:48:09 +02:00
parent 77a536bcc3
commit c6ca17984b
26 changed files with 1272 additions and 373 deletions
+25 -7
View File
@@ -311,12 +311,13 @@ void gui::desktop_init(DesktopState* ds) {
ds->vol_popup_open = false;
ds->vol_icon_rect = {0, 0, 0, 0};
int vol = montauk::audio_get_volume(0);
int vol = montauk::audio_get_master_volume();
ds->vol_level = vol >= 0 ? vol : 80;
ds->vol_muted = false;
ds->vol_muted = montauk::audio_get_master_mute() == 1;
ds->vol_pre_mute = ds->vol_level;
ds->vol_dragging = false;
ds->vol_last_poll = montauk::get_milliseconds();
ds->vol_serial = montauk::audio_wait(0, 0);
ds->closing_ext_count = 0;
@@ -393,11 +394,28 @@ static bool desktop_refresh_panel_state(DesktopState* ds, uint64_t now) {
ds->net_cfg_last_poll = now;
}
if (now - ds->vol_last_poll > 5000) {
int v = montauk::audio_get_volume(0);
if (v >= 0 && !ds->vol_muted && v != ds->vol_level) {
ds->vol_level = v;
changed = true;
// Event-driven sync: the kernel mixer bumps a serial on every state
// change. Reading it is one cheap syscall; refresh only when the serial
// moved since we last looked. The audio app (and any other client) will
// bump this serial when they change volume/mute, so the popup and the
// panel speaker icon stay in sync without polling them blindly.
//
// Skip the refresh while our own slider is being dragged so a kernel
// snapshot mid-drag can't clobber the in-flight value.
if (!ds->vol_dragging) {
uint64_t serial = montauk::audio_wait(ds->vol_serial, 0);
if (serial != ds->vol_serial) {
ds->vol_serial = serial;
int v = montauk::audio_get_master_volume();
bool muted = montauk::audio_get_master_mute() == 1;
if (v >= 0 && v != ds->vol_level) {
ds->vol_level = v;
changed = true;
}
if (muted != ds->vol_muted) {
ds->vol_muted = muted;
changed = true;
}
}
ds->vol_last_poll = now;
}