-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement per application volume control (#253)
- Loading branch information
1 parent
8d21993
commit b425b91
Showing
10 changed files
with
352 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<schemalist> | ||
<schema id="io.elementary.switchboard.sound" path="/io/elementary/switchboard/sound/"> | ||
<key name="show-unknown-apps" type="b"> | ||
<default>false</default> | ||
<summary>Show apps for which no info could be found</summary> | ||
<description>Show apps that are found by PulseAudio but misbehave in a way that no app info can be found. This setting may cause apps to appear that have wrong names or icons or none at all.</description> | ||
</key> | ||
</schema> | ||
</schemalist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* SPDX-License-Identifier: LGPL-3.0-or-later | ||
* SPDX-FileCopyrightText: 2023 elementary, Inc. (https://elementary.io) | ||
* | ||
* Authored by: Leonhard Kargl <leo.kargl@proton.me> | ||
*/ | ||
|
||
public class Sound.App : Object { | ||
public signal void changed (); | ||
|
||
public uint32 index { get; private set; } | ||
public string name { get; private set; } | ||
public string display_name { get; private set; } | ||
public Icon icon { get; private set; } | ||
|
||
public string media_name { get; set; } | ||
public double volume { get; set; } | ||
public bool muted { get; set; } | ||
public PulseAudio.ChannelMap channel_map { get; set; } | ||
|
||
public bool hidden { get; set; default = false; } | ||
|
||
private static Settings settings; | ||
|
||
static construct { | ||
settings = new Settings ("io.elementary.switchboard.sound"); | ||
} | ||
|
||
public App.from_sink_input_info (PulseAudio.SinkInputInfo sink_input) { | ||
index = sink_input.index; | ||
name = sink_input.proplist.gets (PulseAudio.Proplist.PROP_APPLICATION_NAME); | ||
|
||
string app_id; | ||
if (sink_input.proplist.contains (PulseAudio.Proplist.PROP_APPLICATION_ID) == 1) { | ||
app_id = sink_input.proplist.gets (PulseAudio.Proplist.PROP_APPLICATION_ID); | ||
} else { | ||
app_id = name; | ||
} | ||
|
||
var app_info = new DesktopAppInfo (app_id + ".desktop"); | ||
|
||
if (app_info == null) { | ||
settings.bind ("show-unknown-apps", this, "hidden", GET | INVERT_BOOLEAN); | ||
} | ||
|
||
if (app_info != null) { | ||
display_name = app_info.get_name (); | ||
icon = app_info.get_icon (); | ||
} else { | ||
display_name = name; | ||
|
||
if (sink_input.proplist.contains (PulseAudio.Proplist.PROP_APPLICATION_ICON_NAME) == 1) { | ||
icon = new ThemedIcon (sink_input.proplist.gets (PulseAudio.Proplist.PROP_APPLICATION_ICON_NAME)); | ||
} else { | ||
icon = new ThemedIcon ("application-default-icon"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/* | ||
* SPDX-License-Identifier: LGPL-3.0-or-later | ||
* SPDX-FileCopyrightText: 2023 elementary, Inc. (https://elementary.io) | ||
* | ||
* Authored by: Leonhard Kargl <leo.kargl@proton.me> | ||
*/ | ||
|
||
public class Sound.AppRow : Gtk.Grid { | ||
private App? app; | ||
private Gtk.Label app_name_label; | ||
private Gtk.Label media_name_label; | ||
private Gtk.Image image; | ||
private Gtk.Button icon_button; | ||
private Gtk.Scale volume_scale; | ||
private Gtk.Switch mute_switch; | ||
|
||
construct { | ||
image = new Gtk.Image () { | ||
icon_size = LARGE | ||
}; | ||
|
||
app_name_label = new Gtk.Label ("") { | ||
ellipsize = END, | ||
xalign = 0 | ||
}; | ||
app_name_label.add_css_class (Granite.STYLE_CLASS_H3_LABEL); | ||
|
||
media_name_label = new Gtk.Label ("") { | ||
ellipsize = END, | ||
xalign = 0 | ||
}; | ||
media_name_label.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); | ||
media_name_label.add_css_class (Granite.STYLE_CLASS_SMALL_LABEL); | ||
|
||
var label_box = new Gtk.Box (HORIZONTAL, 6); | ||
label_box.append (app_name_label); | ||
label_box.append (media_name_label); | ||
|
||
icon_button = new Gtk.Button.from_icon_name ("audio-volume-muted"); | ||
|
||
volume_scale = new Gtk.Scale.with_range (HORIZONTAL, 0, 1, 0.01) { | ||
hexpand = true | ||
}; | ||
|
||
mute_switch = new Gtk.Switch () { | ||
valign = CENTER | ||
}; | ||
|
||
hexpand = true; | ||
column_spacing = 6; | ||
|
||
attach (image, 0, 0, 1, 2); | ||
attach (label_box, 1, 0, 2); | ||
attach (icon_button, 1, 1); | ||
attach (volume_scale, 2, 1); | ||
attach (mute_switch, 3, 0, 1, 2); | ||
|
||
volume_scale.change_value.connect ((type, new_value) => { | ||
if (app != null) { | ||
PulseAudioManager.get_default ().change_application_volume (app, new_value.clamp (0, 1)); | ||
} | ||
|
||
return true; | ||
}); | ||
|
||
icon_button.clicked.connect (() => toggle_mute_application ()); | ||
|
||
mute_switch.state_set.connect ((state) => { | ||
toggle_mute_application (!state); | ||
return true; | ||
}); | ||
} | ||
|
||
private void toggle_mute_application (bool? custom = null) { | ||
if (app == null) { | ||
return; | ||
} | ||
|
||
PulseAudioManager.get_default ().mute_application (app, custom != null ? custom : !app.muted); | ||
} | ||
|
||
private void update () { | ||
media_name_label.label = media_name_label.tooltip_text = app.media_name; | ||
volume_scale.set_value (app.volume); | ||
mute_switch.state = !app.muted; | ||
volume_scale.sensitive = !app.muted; | ||
|
||
if (app.muted) { | ||
icon_button.icon_name = "audio-volume-muted"; | ||
} else if (volume_scale.get_value () < 0.33) { | ||
icon_button.icon_name = "audio-volume-low"; | ||
} else if (volume_scale.get_value () > 0.66) { | ||
icon_button.icon_name = "audio-volume-high"; | ||
} else { | ||
icon_button.icon_name = "audio-volume-medium"; | ||
} | ||
|
||
if (app.muted) { | ||
icon_button.tooltip_text = _("Unmute"); | ||
} else { | ||
icon_button.tooltip_text = _("Mute"); | ||
} | ||
} | ||
|
||
public void bind_app (App app) { | ||
this.app = app; | ||
|
||
app_name_label.label = app.display_name; | ||
image.set_from_gicon (app.icon); | ||
|
||
app.changed.connect (update); | ||
app.notify["hidden"].connect (() => { | ||
visible = app.hidden; | ||
}); | ||
|
||
visible = app.hidden; | ||
|
||
volume_scale.set_value (app.volume); | ||
} | ||
|
||
public void unbind_app () { | ||
app.changed.disconnect (update); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* SPDX-License-Identifier: LGPL-3.0-or-later | ||
* SPDX-FileCopyrightText: 2023 elementary, Inc. (https://elementary.io) | ||
* | ||
* Authored by: Leonhard Kargl <leo.kargl@proton.me> | ||
*/ | ||
|
||
public class Sound.ApplicationsPanel : Gtk.Box { | ||
construct { | ||
var pulse_audio_manager = PulseAudioManager.get_default (); | ||
|
||
var placeholder = new Granite.Placeholder (_("No applications currently emittings sounds")) { | ||
description = _("Applications emitting sounds will automatically appear here") | ||
}; | ||
|
||
var list_box = new Gtk.ListBox () { | ||
selection_mode = NONE, | ||
}; | ||
list_box.bind_model (pulse_audio_manager.apps, widget_create_func); | ||
list_box.set_placeholder (placeholder); | ||
list_box.add_css_class (Granite.STYLE_CLASS_RICH_LIST); | ||
|
||
var scrolled_window = new Gtk.ScrolledWindow () { | ||
child = list_box, | ||
vexpand = true | ||
}; | ||
|
||
var frame = new Gtk.Frame (null) { | ||
child = scrolled_window | ||
}; | ||
|
||
var reset_button = new Gtk.Button.with_label (_("Reset all apps to default")) { | ||
halign = END | ||
}; | ||
|
||
orientation = VERTICAL; | ||
spacing = 12; | ||
append (frame); | ||
append (reset_button); | ||
|
||
// TODO: Reset also non active applications | ||
reset_button.clicked.connect (() => { | ||
for (int i = 0; i < pulse_audio_manager.apps.get_n_items (); i++) { | ||
pulse_audio_manager.change_application_volume ((App) pulse_audio_manager.apps.get_item (i), 1); | ||
} | ||
}); | ||
} | ||
|
||
private Gtk.Widget widget_create_func (Object item) { | ||
var app = (App) item; | ||
var app_row = new AppRow (); | ||
app_row.bind_app (app); | ||
return app_row; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.