Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • panel-plugins/xfce4-pulseaudio-plugin
  • bobby285271/xfce4-pulseaudio-plugin
  • sgn/xfce4-pulseaudio-plugin
  • bodqhrohro/xfce4-pulseaudio-plugin
  • correctmost/xfce4-pulseaudio-plugin
  • andrzejr/xfce4-pulseaudio-plugin
  • Zetta1_Reid0/xfce4-pulseaudio-plugin
7 results
Show changes
Showing
with 3066 additions and 928 deletions
/* -*- c-basic-offset: 2 -*- vi:set ts=2 sts=2 sw=2:
* * Copyright (C) 2017 Sean Davis <bluesabre@xfce.org>
* * Copyright (C) 2017-2020 Sean Davis <bluesabre@xfce.org>
*
* Licensed under the GNU General Public License Version 2
*
......@@ -59,11 +59,6 @@ struct _MprisMenuItemClass
GType mpris_menu_item_get_type (void) G_GNUC_CONST;
GtkWidget *mpris_menu_item_new_with_player (const gchar *player,
const gchar *title,
const gchar *icon_name,
const gchar *filename);
GtkWidget *mpris_menu_item_new_from_player_name (const gchar *player);
const gchar *mpris_menu_item_get_player (MprisMenuItem *item);
......@@ -89,6 +84,9 @@ void mpris_menu_item_set_can_go_next (MprisMenuItem *item,
void mpris_menu_item_set_can_raise (MprisMenuItem *item,
gboolean can_raise);
void mpris_menu_item_set_can_raise_wnck (MprisMenuItem *item,
gboolean can_raise);
void mpris_menu_item_set_is_running (MprisMenuItem *item,
gboolean running);
......
......@@ -61,6 +61,15 @@ static const char *icons[] = {
NULL
};
/* Icons for different recording levels */
static const char *recording_icons[] = {
"microphone-sensitivity-muted-symbolic",
"microphone-sensitivity-low-symbolic",
"microphone-sensitivity-medium-symbolic",
"microphone-sensitivity-high-symbolic",
NULL
};
static void pulseaudio_button_finalize (GObject *object);
......@@ -68,6 +77,11 @@ static gboolean pulseaudio_button_button_press (GtkWidget
GdkEventButton *event);
static gboolean pulseaudio_button_scroll_event (GtkWidget *widget,
GdkEventScroll *event);
static gboolean pulseaudio_query_tooltip (GtkWidget *widget,
gint x,
gint y,
gboolean keyboard_mode,
GtkTooltip *tooltip);
static void pulseaudio_button_menu_deactivate (PulseaudioButton *button,
GtkMenuShell *menu);
static void pulseaudio_button_update_icons (PulseaudioButton *button);
......@@ -85,16 +99,26 @@ struct _PulseaudioButton
PulseaudioMpris *mpris;
PulseaudioVolume *volume;
GtkWidget *box;
GtkWidget *image;
GtkWidget *recording_indicator;
GtkCssProvider *recording_indicator_style_css_provider;
gboolean recording;
gboolean recording_indicator_persistent;
/* Icon size currently used */
gint icon_size;
const gchar *icon_name;
const gchar *recording_icon_name;
PulseaudioMenu *menu;
gulong connection_changed_id;
gulong volume_changed_id;
gulong recording_volume_changed_id;
gulong recording_changed_id;
gulong deactivate_id;
gulong configuration_changed_id;
};
struct _PulseaudioButtonClass
......@@ -118,6 +142,19 @@ pulseaudio_button_class_init (PulseaudioButtonClass *klass)
gtkwidget_class = GTK_WIDGET_CLASS (klass);
gtkwidget_class->button_press_event = pulseaudio_button_button_press;
gtkwidget_class->scroll_event = pulseaudio_button_scroll_event;
gtkwidget_class->query_tooltip = pulseaudio_query_tooltip;
}
static void pulseaudio_set_recording_indicator_state (PulseaudioButton *button)
{
gtk_css_provider_load_from_data (button->recording_indicator_style_css_provider,
button->recording ? ".recording-indicator { color: @error_color; }" : "",
-1, NULL);
gtk_widget_set_visible (button->recording_indicator,
button->recording || button->recording_indicator_persistent);
}
......@@ -125,6 +162,7 @@ pulseaudio_button_class_init (PulseaudioButtonClass *klass)
static void
pulseaudio_button_init (PulseaudioButton *button)
{
GtkStyleContext *context;
GtkCssProvider *css_provider;
gtk_widget_set_can_focus(GTK_WIDGET(button), FALSE);
......@@ -133,35 +171,42 @@ pulseaudio_button_init (PulseaudioButton *button)
gtk_button_set_use_underline (GTK_BUTTON (button), TRUE);
gtk_widget_set_focus_on_click (GTK_WIDGET (button), FALSE);
gtk_widget_set_name (GTK_WIDGET (button), "pulseaudio-button");
gtk_widget_set_has_tooltip (GTK_WIDGET (button), TRUE);
gtk_widget_set_halign (GTK_WIDGET(button), GTK_ALIGN_START);
gtk_widget_set_valign (GTK_WIDGET(button), GTK_ALIGN_START);
/* Preload icons */
g_signal_connect (G_OBJECT (button), "style-updated", G_CALLBACK (pulseaudio_button_update_icons), button);
/* Setup Gtk style */
context = gtk_widget_get_style_context (GTK_WIDGET (button));
css_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (css_provider, ".xfce4-panel button { padding: 1px; }", -1, NULL);
gtk_style_context_add_provider (GTK_STYLE_CONTEXT (gtk_widget_get_style_context (GTK_WIDGET (button))),
gtk_style_context_add_provider (context,
GTK_STYLE_PROVIDER (css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
/* Intercept scroll events */
gtk_widget_add_events (GTK_WIDGET (button), GDK_SCROLL_MASK);
button->plugin = NULL;
button->config = NULL;
button->volume = NULL;
button->icon_size = 16;
button->icon_name = NULL;
button->menu = NULL;
button->volume_changed_id = 0;
button->deactivate_id = 0;
button->image = gtk_image_new ();
gtk_container_add (GTK_CONTAINER (button), button->image);
gtk_widget_show (button->image);
g_object_set (G_OBJECT (button), "has-tooltip", TRUE, NULL);
button->recording_indicator = gtk_image_new ();
button->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous (GTK_BOX (button->box), TRUE);
gtk_container_add (GTK_CONTAINER (button), button->box);
gtk_box_pack_start (GTK_BOX (button->box), GTK_WIDGET (button->recording_indicator), TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (button->box), GTK_WIDGET (button->image), TRUE, FALSE, 0);
gtk_widget_show_all (button->box);
context = gtk_widget_get_style_context (button->recording_indicator);
button->recording_indicator_style_css_provider = gtk_css_provider_new ();
gtk_style_context_add_provider (context,
GTK_STYLE_PROVIDER (button->recording_indicator_style_css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
gtk_style_context_add_class (context, "recording-indicator");
}
......@@ -178,17 +223,43 @@ pulseaudio_button_finalize (GObject *object)
button->menu = NULL;
}
g_object_unref (button->recording_indicator_style_css_provider);
(*G_OBJECT_CLASS (pulseaudio_button_parent_class)->finalize) (object);
}
static gboolean
pulseaudio_button_mic_icon_under_pointer (PulseaudioButton *button,
gdouble pointer_pos_x,
gdouble pointer_pos_y)
{
GtkOrientation orientation;
if (!gtk_widget_is_visible (button->recording_indicator))
return FALSE;
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (button->box));
/* Microphone icon is on the left/top */
if (orientation == GTK_ORIENTATION_HORIZONTAL)
return (pointer_pos_x / (gdouble) gtk_widget_get_allocated_width (GTK_WIDGET (button))) < 0.5;
else
return (pointer_pos_y / (gdouble) gtk_widget_get_allocated_height (GTK_WIDGET (button))) < 0.5;
}
static gboolean
pulseaudio_button_button_press (GtkWidget *widget,
GdkEventButton *event)
{
PulseaudioButton *button = PULSEAUDIO_BUTTON (widget);
if ((event->type == GDK_2BUTTON_PRESS) || (event->type == GDK_3BUTTON_PRESS))
return TRUE;
if (event->button == 1 && button->menu == NULL) /* left button */
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
......@@ -202,6 +273,10 @@ pulseaudio_button_button_press (GtkWidget *widget,
G_CALLBACK (pulseaudio_button_menu_deactivate), button);
}
#if LIBXFCE4PANEL_CHECK_VERSION (4, 17, 2)
xfce_panel_plugin_popup_menu (XFCE_PANEL_PLUGIN (button->plugin), GTK_MENU (button->menu),
widget, (GdkEvent *) event);
#else
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_menu_popup (GTK_MENU (button->menu),
NULL, NULL,
......@@ -209,13 +284,17 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1,
event->time);
G_GNUC_END_IGNORE_DEPRECATIONS
#endif
return TRUE;
}
if (event->button == 2) /* middle button */
{
pulseaudio_volume_toggle_muted (button->volume);
if (pulseaudio_button_mic_icon_under_pointer (button, event->x, event->y))
pulseaudio_volume_toggle_muted_mic (button->volume);
else
pulseaudio_volume_toggle_muted (button->volume);
return TRUE;
}
......@@ -228,7 +307,8 @@ static gboolean
pulseaudio_button_scroll_event (GtkWidget *widget, GdkEventScroll *event)
{
PulseaudioButton *button = PULSEAUDIO_BUTTON (widget);
gdouble volume = pulseaudio_volume_get_volume (button->volume);
gboolean is_mic = pulseaudio_button_mic_icon_under_pointer (button, event->x, event->y);
gdouble volume = is_mic ? pulseaudio_volume_get_volume_mic (button->volume) : pulseaudio_volume_get_volume (button->volume);
gdouble volume_step = pulseaudio_config_get_volume_step (button->config) / 100.0;
gdouble new_volume;
......@@ -239,7 +319,61 @@ pulseaudio_button_scroll_event (GtkWidget *widget, GdkEventScroll *event)
else
new_volume = volume;
pulseaudio_volume_set_volume (button->volume, new_volume);
if (is_mic)
pulseaudio_volume_set_volume_mic (button->volume, new_volume);
else
pulseaudio_volume_set_volume (button->volume, new_volume);
return TRUE;
}
static gboolean
pulseaudio_query_tooltip (GtkWidget *widget,
gint x,
gint y,
gboolean keyboard_mode,
GtkTooltip *tooltip)
{
PulseaudioButton *button = PULSEAUDIO_BUTTON (widget);
const gchar *format;
gchar *tip_text;
const gchar *dev_name;
gboolean muted;
gdouble volume;
if (keyboard_mode)
return FALSE;
if (!pulseaudio_volume_get_connected (button->volume))
{
tip_text = g_strdup_printf (_("Not connected to the PulseAudio server"));
}
else
{
if (pulseaudio_button_mic_icon_under_pointer (button, x, y))
{
dev_name = pulseaudio_volume_get_input_by_name (button->volume, pulseaudio_volume_get_default_input (button->volume), NULL);
muted = pulseaudio_volume_get_muted_mic (button->volume);
volume = pulseaudio_volume_get_volume_mic (button->volume);
}
else
{
dev_name = pulseaudio_volume_get_output_by_name (button->volume, pulseaudio_volume_get_default_output (button->volume), NULL);
muted = pulseaudio_volume_get_muted (button->volume);
volume = pulseaudio_volume_get_volume (button->volume);
}
if (muted)
format = _("<b>Volume %d%% (muted)</b>\n<small>%s</small>");
else
format = _("<b>Volume %d%%</b>\n<small>%s</small>");
tip_text = g_strdup_printf (format, (gint) round (volume * 100), dev_name);
}
gtk_tooltip_set_markup (tooltip, tip_text);
g_free (tip_text);
return TRUE;
}
......@@ -285,10 +419,13 @@ pulseaudio_button_update (PulseaudioButton *button,
gboolean force_update)
{
gdouble volume;
gdouble recording_volume;
gboolean connected;
gboolean muted;
gchar *tip_text;
gboolean recording_muted;
gboolean recording;
const gchar *icon_name;
const gchar *recording_icon_name;
g_return_if_fail (IS_PULSEAUDIO_BUTTON (button));
g_return_if_fail (IS_PULSEAUDIO_VOLUME (button->volume));
......@@ -296,6 +433,10 @@ pulseaudio_button_update (PulseaudioButton *button,
volume = pulseaudio_volume_get_volume (button->volume);
muted = pulseaudio_volume_get_muted (button->volume);
connected = pulseaudio_volume_get_connected (button->volume);
recording = pulseaudio_volume_get_recording (button->volume);
recording_volume = pulseaudio_volume_get_volume_mic (button->volume);
recording_muted = pulseaudio_volume_get_muted_mic (button->volume);
if (!connected)
icon_name = icons[V_MUTED];
else if (muted)
......@@ -310,13 +451,20 @@ pulseaudio_button_update (PulseaudioButton *button,
icon_name = icons[V_HIGH];
if (!connected)
tip_text = g_strdup_printf (_("Not connected to the PulseAudio server"));
else if (muted)
tip_text = g_strdup_printf (_("Volume %d%% (muted)"), (gint) round (volume * 100));
recording_icon_name = recording_icons[V_MUTED];
else if (recording_muted)
recording_icon_name = recording_icons[V_MUTED];
else if (recording_volume <= 0.0)
recording_icon_name = recording_icons[V_MUTED];
else if (recording_volume <= 0.3)
recording_icon_name = recording_icons[V_LOW];
else if (recording_volume <= 0.7)
recording_icon_name = recording_icons[V_MEDIUM];
else
tip_text = g_strdup_printf (_("Volume %d%%"), (gint) round (volume * 100));
gtk_widget_set_tooltip_text (GTK_WIDGET (button), tip_text);
g_free (tip_text);
recording_icon_name = recording_icons[V_HIGH];
if (!force_update)
gtk_tooltip_trigger_tooltip_query (gdk_display_get_default ());
if (force_update || icon_name != button->icon_name)
{
......@@ -324,6 +472,19 @@ pulseaudio_button_update (PulseaudioButton *button,
gtk_image_set_from_icon_name (GTK_IMAGE (button->image), icon_name, GTK_ICON_SIZE_BUTTON);
gtk_image_set_pixel_size (GTK_IMAGE (button->image), button->icon_size);
}
if (force_update || recording_icon_name != button->recording_icon_name)
{
button->recording_icon_name = recording_icon_name;
gtk_image_set_from_icon_name (GTK_IMAGE (button->recording_indicator), recording_icon_name, GTK_ICON_SIZE_BUTTON);
gtk_image_set_pixel_size (GTK_IMAGE (button->recording_indicator), button->icon_size);
}
if (force_update || button->recording != recording)
{
button->recording = recording;
pulseaudio_set_recording_indicator_state (button);
}
}
......@@ -336,9 +497,27 @@ pulseaudio_button_set_size (PulseaudioButton *button,
g_return_if_fail (IS_PULSEAUDIO_BUTTON (button));
g_return_if_fail (size > 0);
gtk_widget_set_size_request (GTK_WIDGET (button), size, size);
button->icon_size = icon_size;
gtk_image_set_pixel_size (GTK_IMAGE (button->image), button->icon_size);
gtk_image_set_pixel_size (GTK_IMAGE (button->recording_indicator), button->icon_size);
if (size > 0)
{
gtk_widget_set_size_request (button->image, size, size);
gtk_widget_set_size_request (button->recording_indicator, size, size);
}
}
void
pulseaudio_button_set_orientation (PulseaudioButton *button,
GtkOrientation orientation)
{
g_return_if_fail (IS_PULSEAUDIO_BUTTON (button));
gtk_orientable_set_orientation (GTK_ORIENTABLE (button->box), orientation);
}
......@@ -353,6 +532,21 @@ pulseaudio_button_get_menu (PulseaudioButton *button)
static void
pulseaudio_button_recording_changed (PulseaudioButton *button,
gboolean recording,
PulseaudioVolume *volume)
{
g_return_if_fail (IS_PULSEAUDIO_BUTTON (button));
if (button->recording != recording)
{
button->recording = recording;
pulseaudio_set_recording_indicator_state (button);
}
}
static void
pulseaudio_button_volume_changed (PulseaudioButton *button,
gboolean should_notify,
......@@ -360,6 +554,42 @@ pulseaudio_button_volume_changed (PulseaudioButton *button,
{
g_return_if_fail (IS_PULSEAUDIO_BUTTON (button));
if (pulseaudio_volume_get_connected (button->volume))
pulseaudio_button_update (button, FALSE);
}
static void
pulseaudio_button_configuration_changed (PulseaudioButton *button,
PulseaudioConfig *config)
{
gboolean rec_indicator_persistent = pulseaudio_config_get_rec_indicator_persistent (config);
gint width;
if (rec_indicator_persistent != button->recording_indicator_persistent)
{
button->recording_indicator_persistent = rec_indicator_persistent;
pulseaudio_set_recording_indicator_state (button);
if (gtk_orientable_get_orientation (GTK_ORIENTABLE (button->box)) == GTK_ORIENTATION_HORIZONTAL)
gtk_widget_get_size_request (GTK_WIDGET(button), NULL, &width);
else
gtk_widget_get_size_request (GTK_WIDGET(button), &width, NULL);
if (width > 0)
pulseaudio_button_set_size (button, width, button->icon_size);
}
}
static void
pulseaudio_button_update2 (PulseaudioButton *button,
PulseaudioVolume *volume)
{
g_return_if_fail (IS_PULSEAUDIO_BUTTON (button));
pulseaudio_button_update (button, FALSE);
}
......@@ -386,10 +616,23 @@ pulseaudio_button_new (PulseaudioPlugin *plugin,
button->volume = volume;
button->config = config;
button->mpris = mpris;
button->connection_changed_id =
g_signal_connect_swapped (G_OBJECT (button->volume), "connection-changed",
G_CALLBACK (pulseaudio_button_update2), button);
button->volume_changed_id =
g_signal_connect_swapped (G_OBJECT (button->volume), "volume-changed",
G_CALLBACK (pulseaudio_button_volume_changed), button);
button->recording_volume_changed_id =
g_signal_connect_swapped (G_OBJECT (button->volume), "volume-mic-changed",
G_CALLBACK (pulseaudio_button_volume_changed), button);
button->recording_changed_id =
g_signal_connect_swapped (G_OBJECT (button->volume), "recording-changed",
G_CALLBACK (pulseaudio_button_recording_changed), button);
button->configuration_changed_id =
g_signal_connect_swapped (G_OBJECT (button->config), "configuration-changed",
G_CALLBACK (pulseaudio_button_configuration_changed), button);
button->recording_indicator_persistent = pulseaudio_config_get_rec_indicator_persistent (button->config);
pulseaudio_button_update (button, TRUE);
return button;
......
......@@ -50,8 +50,12 @@ void pulseaudio_button_set_size (PulseaudioButton *button,
gint size,
gint icon_size);
void pulseaudio_button_set_orientation (PulseaudioButton *button,
GtkOrientation orientation);
PulseaudioMenu *pulseaudio_button_get_menu (PulseaudioButton *button);
G_END_DECLS
#endif /* !__PULSEAUDIO_BUTTON_H__ */
......@@ -33,7 +33,7 @@
#include <string.h>
#endif
#include <libxfce4panel/xfce-panel-plugin.h>
#include <libxfce4panel/libxfce4panel.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
#include <xfconf/xfconf.h>
......@@ -44,7 +44,9 @@
#define DEFAULT_ENABLE_KEYBOARD_SHORTCUTS TRUE
#define DEFAULT_SHOW_NOTIFICATIONS TRUE
#define DEFAULT_SHOW_NOTIFICATIONS 1
#define DEFAULT_PLAY_SOUND FALSE
#define DEFAULT_REC_INDICATOR_PERSISTENT FALSE
#define DEFAULT_VOLUME_STEP 5
#define DEFAULT_VOLUME_MAX 150
......@@ -55,8 +57,12 @@
#define DEFAULT_ENABLE_MPRIS FALSE
#define DEFAULT_ENABLE_MULTIMEDIA_KEYS FALSE
#endif
#define DEFAULT_MULTIMEDIA_KEYS_TO_ALL FALSE
#define DEFAULT_IGNORED_PLAYERS ""
#define DEFAULT_PERSISTENT_PLAYERS ""
#define DEFAULT_MPRIS_PLAYERS ""
#define DEFAULT_KNOWN_PLAYERS ""
#define DEFAULT_ENABLE_WNCK FALSE
......@@ -81,14 +87,25 @@ struct _PulseaudioConfig
{
GObject __parent__;
const gchar *property_base;
XfconfChannel *channel;
gboolean enable_keyboard_shortcuts;
gboolean enable_multimedia_keys;
gboolean show_notifications;
gboolean multimedia_keys_to_all;
guint show_notifications;
#ifdef HAVE_LIBCANBERRA
gboolean play_sound;
#endif
gboolean rec_indicator_persistent;
guint volume_step;
guint volume_max;
gchar *mixer_command;
gboolean enable_mpris;
gchar *mpris_players;
gchar *known_players;
gchar *ignored_players;
gchar *persistent_players;
gboolean enable_wnck;
};
......@@ -98,12 +115,20 @@ enum
PROP_0,
PROP_ENABLE_KEYBOARD_SHORTCUTS,
PROP_ENABLE_MULTIMEDIA_KEYS,
PROP_MULTIMEDIA_KEYS_TO_ALL,
PROP_SHOW_NOTIFICATIONS,
#ifdef HAVE_LIBCANBERRA
PROP_PLAY_SOUND,
#endif
PROP_REC_INDICATOR_PERSISTENT,
PROP_VOLUME_STEP,
PROP_VOLUME_MAX,
PROP_MIXER_COMMAND,
PROP_ENABLE_MPRIS,
PROP_MPRIS_PLAYERS,
PROP_KNOWN_PLAYERS,
PROP_IGNORED_PLAYERS,
PROP_PERSISTENT_PLAYERS,
PROP_ENABLE_WNCK,
N_PROPERTIES,
};
......@@ -149,14 +174,42 @@ pulseaudio_config_class_init (PulseaudioConfigClass *klass)
g_object_class_install_property (gobject_class,
PROP_MULTIMEDIA_KEYS_TO_ALL,
g_param_spec_boolean ("multimedia-keys-to-all", NULL, NULL,
DEFAULT_MULTIMEDIA_KEYS_TO_ALL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_SHOW_NOTIFICATIONS,
g_param_spec_boolean ("show-notifications", NULL, NULL,
DEFAULT_SHOW_NOTIFICATIONS,
g_param_spec_uint ("show-notifications", NULL, NULL,
VOLUME_NOTIFICATIONS_NONE,
VOLUME_NOTIFICATIONS_COUNT - 1,
DEFAULT_SHOW_NOTIFICATIONS,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
#ifdef HAVE_LIBCANBERRA
g_object_class_install_property (gobject_class,
PROP_PLAY_SOUND,
g_param_spec_boolean ("play-sound", NULL, NULL,
DEFAULT_PLAY_SOUND,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
#endif
g_object_class_install_property (gobject_class,
PROP_REC_INDICATOR_PERSISTENT,
g_param_spec_boolean ("rec-indicator-persistent", NULL, NULL,
DEFAULT_REC_INDICATOR_PERSISTENT,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_VOLUME_STEP,
......@@ -196,14 +249,42 @@ pulseaudio_config_class_init (PulseaudioConfigClass *klass)
g_object_class_install_property (gobject_class,
PROP_MPRIS_PLAYERS,
g_param_spec_string ("mpris-players",
PROP_KNOWN_PLAYERS,
g_param_spec_string ("known-players",
NULL, NULL,
DEFAULT_MPRIS_PLAYERS,
DEFAULT_KNOWN_PLAYERS,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_IGNORED_PLAYERS,
g_param_spec_string ("ignored-players",
NULL, NULL,
DEFAULT_IGNORED_PLAYERS,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_PERSISTENT_PLAYERS,
g_param_spec_string ("persistent-players",
NULL, NULL,
DEFAULT_PERSISTENT_PLAYERS,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_ENABLE_WNCK,
g_param_spec_boolean ("enable-wnck", NULL, NULL,
DEFAULT_ENABLE_WNCK,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
pulseaudio_config_signals[CONFIGURATION_CHANGED] =
g_signal_new (g_intern_static_string ("configuration-changed"),
......@@ -221,12 +302,20 @@ pulseaudio_config_init (PulseaudioConfig *config)
{
config->enable_keyboard_shortcuts = DEFAULT_ENABLE_KEYBOARD_SHORTCUTS;
config->enable_multimedia_keys = DEFAULT_ENABLE_MULTIMEDIA_KEYS;
config->multimedia_keys_to_all = DEFAULT_MULTIMEDIA_KEYS_TO_ALL;
config->show_notifications = DEFAULT_SHOW_NOTIFICATIONS;
#ifdef HAVE_LIBCANBERRA
config->play_sound = DEFAULT_PLAY_SOUND;
#endif
config->rec_indicator_persistent = DEFAULT_REC_INDICATOR_PERSISTENT;
config->volume_step = DEFAULT_VOLUME_STEP;
config->volume_max = DEFAULT_VOLUME_MAX;
config->mixer_command = g_strdup (DEFAULT_MIXER_COMMAND);
config->enable_mpris = DEFAULT_ENABLE_MPRIS;
config->mpris_players = g_strdup (DEFAULT_MPRIS_PLAYERS);
config->known_players = g_strdup (DEFAULT_KNOWN_PLAYERS);
config->ignored_players = g_strdup (DEFAULT_IGNORED_PLAYERS);
config->persistent_players = g_strdup (DEFAULT_PERSISTENT_PLAYERS);
config->enable_wnck = DEFAULT_ENABLE_WNCK;
}
......@@ -262,8 +351,22 @@ pulseaudio_config_get_property (GObject *object,
g_value_set_boolean (value, config->enable_multimedia_keys);
break;
case PROP_MULTIMEDIA_KEYS_TO_ALL:
g_value_set_boolean (value, config->multimedia_keys_to_all);
break;
case PROP_SHOW_NOTIFICATIONS:
g_value_set_boolean (value, config->show_notifications);
g_value_set_uint (value, config->show_notifications);
break;
#ifdef HAVE_LIBCANBERRA
case PROP_PLAY_SOUND:
g_value_set_boolean (value, config->play_sound);
break;
#endif
case PROP_REC_INDICATOR_PERSISTENT:
g_value_set_boolean (value, config->rec_indicator_persistent);
break;
case PROP_VOLUME_STEP:
......@@ -282,8 +385,20 @@ pulseaudio_config_get_property (GObject *object,
g_value_set_boolean (value, config->enable_mpris);
break;
case PROP_MPRIS_PLAYERS:
g_value_set_string (value, config->mpris_players);
case PROP_KNOWN_PLAYERS:
g_value_set_string (value, config->known_players);
break;
case PROP_IGNORED_PLAYERS:
g_value_set_string (value, config->ignored_players);
break;
case PROP_PERSISTENT_PLAYERS:
g_value_set_string (value, config->persistent_players);
break;
case PROP_ENABLE_WNCK:
g_value_set_boolean (value, config->enable_wnck);
break;
default:
......@@ -326,16 +441,48 @@ pulseaudio_config_set_property (GObject *object,
}
break;
case PROP_SHOW_NOTIFICATIONS:
case PROP_MULTIMEDIA_KEYS_TO_ALL:
val_bool = g_value_get_boolean (value);
if (config->show_notifications != val_bool)
if (config->multimedia_keys_to_all != val_bool)
{
config->show_notifications = val_bool;
config->multimedia_keys_to_all = val_bool;
g_object_notify (G_OBJECT (config), "multimedia-keys-to-all");
g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_SHOW_NOTIFICATIONS:
val_uint = g_value_get_uint (value);
if (config->show_notifications != val_uint)
{
config->show_notifications = val_uint;
g_object_notify (G_OBJECT (config), "show-notifications");
g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
#ifdef HAVE_LIBCANBERRA
case PROP_PLAY_SOUND:
val_bool = g_value_get_boolean (value);
if (config->play_sound != val_bool)
{
config->play_sound = val_bool;
g_object_notify (G_OBJECT (config), "play-sound");
g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
#endif
case PROP_REC_INDICATOR_PERSISTENT:
val_bool = g_value_get_boolean (value);
if (config->rec_indicator_persistent != val_bool)
{
config->rec_indicator_persistent = val_bool;
g_object_notify (G_OBJECT (config), "rec-indicator-persistent");
g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_VOLUME_STEP:
val_uint = g_value_get_uint (value);
if (config->volume_step != val_uint)
......@@ -372,19 +519,46 @@ pulseaudio_config_set_property (GObject *object,
{
config->enable_multimedia_keys = FALSE;
g_object_notify(G_OBJECT(config), "enable-multimedia-keys");
config->enable_wnck = FALSE;
g_object_notify(G_OBJECT(config), "enable-wnck");
}
g_signal_emit(G_OBJECT(config), pulseaudio_config_signals[CONFIGURATION_CHANGED], 0);
}
break;
case PROP_MPRIS_PLAYERS:
g_free (config->mpris_players);
config->mpris_players = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "mpris-players");
case PROP_KNOWN_PLAYERS:
g_free (config->known_players);
config->known_players = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "known-players");
g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0);
break;
case PROP_IGNORED_PLAYERS:
g_free (config->ignored_players);
config->ignored_players = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "ignored-players");
g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0);
break;
case PROP_PERSISTENT_PLAYERS:
g_free (config->persistent_players);
config->persistent_players = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "persistent-players");
g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0);
break;
case PROP_ENABLE_WNCK:
val_bool = g_value_get_boolean(value);
if (config->enable_wnck != val_bool)
{
config->enable_wnck = val_bool;
g_object_notify (G_OBJECT (config), "enable-wnck");
g_signal_emit (G_OBJECT (config), pulseaudio_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -414,6 +588,16 @@ pulseaudio_config_get_enable_multimedia_keys (PulseaudioConfig *config)
gboolean
pulseaudio_config_get_multimedia_keys_to_all (PulseaudioConfig *config)
{
g_return_val_if_fail (IS_PULSEAUDIO_CONFIG (config), DEFAULT_MULTIMEDIA_KEYS_TO_ALL);
return config->multimedia_keys_to_all;
}
guint
pulseaudio_config_get_show_notifications (PulseaudioConfig *config)
{
g_return_val_if_fail (IS_PULSEAUDIO_CONFIG (config), DEFAULT_SHOW_NOTIFICATIONS);
......@@ -423,6 +607,28 @@ pulseaudio_config_get_show_notifications (PulseaudioConfig *config)
#ifdef HAVE_LIBCANBERRA
gboolean
pulseaudio_config_get_play_sound (PulseaudioConfig *config)
{
g_return_val_if_fail (IS_PULSEAUDIO_CONFIG (config), DEFAULT_PLAY_SOUND);
return config->play_sound;
}
#endif
gboolean
pulseaudio_config_get_rec_indicator_persistent (PulseaudioConfig *config)
{
g_return_val_if_fail (IS_PULSEAUDIO_CONFIG (config), DEFAULT_REC_INDICATOR_PERSISTENT);
return config->rec_indicator_persistent;
}
guint
pulseaudio_config_get_volume_step (PulseaudioConfig *config)
{
......@@ -464,14 +670,14 @@ pulseaudio_config_get_enable_mpris (PulseaudioConfig *config)
gchar **
pulseaudio_config_get_mpris_players (PulseaudioConfig *config)
pulseaudio_config_get_known_players (PulseaudioConfig *config)
{
if (!IS_PULSEAUDIO_CONFIG (config))
{
return g_strsplit (DEFAULT_MPRIS_PLAYERS, ";", 1);
return g_strsplit (DEFAULT_KNOWN_PLAYERS, ";", 1);
}
return g_strsplit (config->mpris_players, ";", 0);
return g_strsplit (config->known_players, ";", 0);
}
......@@ -494,11 +700,14 @@ pulseaudio_config_set_mpris_players (PulseaudioConfig *config,
guint index = 0;
guint i = 0;
GSList *list = NULL;
guint num_players;
g_return_if_fail (IS_PULSEAUDIO_CONFIG (config));
num_players = g_strv_length (players);
player_array = NULL;
for (i = 0; i < g_strv_length (players); i++)
for (i = 0; i < num_players; i++)
{
player_array = g_slist_prepend (player_array, players[i]);
}
......@@ -518,26 +727,34 @@ pulseaudio_config_set_mpris_players (PulseaudioConfig *config,
g_value_init(&src, G_TYPE_STRING);
g_value_set_static_string(&src, player_string);
pulseaudio_config_set_property (G_OBJECT (config), PROP_MPRIS_PLAYERS, &src, NULL);
pulseaudio_config_set_property (G_OBJECT (config), PROP_KNOWN_PLAYERS, &src, NULL);
g_free (player_string);
}
void
pulseaudio_config_add_mpris_player (PulseaudioConfig *config,
gchar *player)
pulseaudio_config_add_known_player (PulseaudioConfig *config,
const gchar *player)
{
gchar **players;
gchar **player_list;
gchar *players_string;
gchar *player_string;
players = pulseaudio_config_get_mpris_players (config);
players = pulseaudio_config_get_known_players (config);
if (g_strv_contains ((const char * const *) players, player))
return;
{
g_strfreev(players);
return;
}
players_string = g_strjoinv (";", players);
player_string = g_strjoin (";", players_string, player, NULL);
if (g_strv_length (players) > 0)
player_string = g_strjoin (";", players_string, player, NULL);
else
player_string = g_strdup (player);
player_list = g_strsplit(player_string, ";", 0);
pulseaudio_config_set_mpris_players (config, player_list);
......@@ -550,6 +767,282 @@ pulseaudio_config_add_mpris_player (PulseaudioConfig *config,
static gchar **
pulseaudio_config_get_ignored_players (PulseaudioConfig *config)
{
if (!IS_PULSEAUDIO_CONFIG (config))
{
return g_strsplit (DEFAULT_IGNORED_PLAYERS, ";", 1);
}
return g_strsplit (config->ignored_players, ";", 0);
}
static gchar **
pulseaudio_config_get_persistent_players (PulseaudioConfig *config)
{
if (!IS_PULSEAUDIO_CONFIG (config))
{
return g_strsplit (DEFAULT_PERSISTENT_PLAYERS, ";", 1);
}
return g_strsplit (config->persistent_players, ";", 0);
}
static void
pulseaudio_config_set_players (PulseaudioConfig *config,
gchar **players,
gint prop)
{
GSList *player_array;
gchar *player_string;
GValue src = { 0, };
guint index = 0;
guint i = 0;
GSList *list = NULL;
guint num_players;
g_return_if_fail (IS_PULSEAUDIO_CONFIG (config));
num_players = g_strv_length (players);
player_array = NULL;
for (i = 0; i < num_players; i++)
{
player_array = g_slist_prepend (player_array, players[i]);
}
player_array = g_slist_sort (player_array, (GCompareFunc) compare_players);
for (list = player_array; list != NULL; list = g_slist_next (list))
{
players[index] = list->data;
index++;
}
g_slist_free (player_array);
player_string = g_strjoinv (";", players);
g_value_init(&src, G_TYPE_STRING);
g_value_set_static_string(&src, player_string);
pulseaudio_config_set_property (G_OBJECT (config), prop, &src, NULL);
g_free (player_string);
}
static void
pulseaudio_config_player_add (PulseaudioConfig *config,
gchar **players,
const gchar *player,
gint prop)
{
gchar **player_list;
gchar *players_string;
gchar *player_string;
if (g_strv_contains ((const char * const *) players, player))
{
g_strfreev(players);
return;
}
players_string = g_strjoinv (";", players);
if (g_strv_length (players) > 0)
player_string = g_strjoin (";", players_string, player, NULL);
else
player_string = g_strdup (player);
player_list = g_strsplit(player_string, ";", 0);
pulseaudio_config_set_players (config, player_list, prop);
g_strfreev (player_list);
g_free (player_string);
g_free (players_string);
g_strfreev (players);
}
static void
pulseaudio_config_player_remove (PulseaudioConfig *config,
gchar **players_old,
const gchar *player,
gint prop)
{
gchar **players_new;
guint j = 0;
guint len = g_strv_length (players_old);
players_new = g_new (gchar *, len);
for (guint i = 0; i < len; i++)
if (g_strcmp0 (player, players_old[i]) != 0)
players_new[j++] = players_old[i];
if (j < len)
{
players_new[j] = NULL;
pulseaudio_config_set_players (config, players_new, prop);
}
g_free (players_new);
g_strfreev (players_old);
}
void
pulseaudio_config_player_ignored_add (PulseaudioConfig *config,
const gchar *player)
{
pulseaudio_config_player_add (config,
pulseaudio_config_get_ignored_players (config),
player,
PROP_IGNORED_PLAYERS);
}
void
pulseaudio_config_player_ignored_remove (PulseaudioConfig *config,
const gchar *player)
{
pulseaudio_config_player_remove (config,
pulseaudio_config_get_ignored_players (config),
player,
PROP_IGNORED_PLAYERS);
}
gboolean
pulseaudio_config_player_ignored_lookup (PulseaudioConfig *config,
const gchar *player)
{
gchar **players;
gboolean found = FALSE;
players = pulseaudio_config_get_ignored_players (config);
if (g_strv_contains ((const char * const *) players, player))
{
found = TRUE;
}
g_strfreev(players);
return found;
}
void
pulseaudio_config_player_persistent_add (PulseaudioConfig *config,
const gchar *player)
{
pulseaudio_config_player_add (config,
pulseaudio_config_get_persistent_players (config),
player,
PROP_PERSISTENT_PLAYERS);
}
void
pulseaudio_config_player_persistent_remove (PulseaudioConfig *config,
const gchar *player)
{
pulseaudio_config_player_remove (config,
pulseaudio_config_get_persistent_players (config),
player,
PROP_PERSISTENT_PLAYERS);
}
gboolean
pulseaudio_config_player_persistent_lookup (PulseaudioConfig *config,
const gchar *player)
{
gchar **players;
gboolean found = FALSE;
players = pulseaudio_config_get_persistent_players (config);
if (g_strv_contains ((const char * const *) players, player))
{
found = TRUE;
}
g_strfreev(players);
return found;
}
void
pulseaudio_config_clear_known_players (PulseaudioConfig *config)
{
gchar *player_string;
GValue src = { 0, };
gchar *property;
g_return_if_fail (IS_PULSEAUDIO_CONFIG (config));
player_string = g_strdup ("");
g_value_init(&src, G_TYPE_STRING);
g_value_set_static_string(&src, player_string);
/* Remove old properties */
if (G_LIKELY (config->channel))
{
property = g_strconcat (config->property_base, "/mpris-players", NULL);
xfconf_channel_reset_property (config->channel, property, FALSE);
g_free (property);
property = g_strconcat (config->property_base, "/blacklisted-players", NULL);
xfconf_channel_reset_property (config->channel, property, FALSE);
g_free (property);
}
pulseaudio_config_set_property (G_OBJECT (config), PROP_IGNORED_PLAYERS, &src, NULL);
pulseaudio_config_set_property (G_OBJECT (config), PROP_PERSISTENT_PLAYERS, &src, NULL);
pulseaudio_config_set_property (G_OBJECT (config), PROP_KNOWN_PLAYERS, &src, NULL);
g_free (player_string);
}
void
pulseaudio_config_set_can_raise_wnck (PulseaudioConfig *config,
gboolean can_raise)
{
GValue src = { 0, };
g_return_if_fail(IS_PULSEAUDIO_CONFIG(config));
g_value_init (&src, G_TYPE_BOOLEAN);
g_value_set_boolean (&src, can_raise);
pulseaudio_config_set_property(G_OBJECT(config), PROP_ENABLE_WNCK, &src, NULL);
}
gboolean
pulseaudio_config_get_can_raise_wnck (PulseaudioConfig *config)
{
return config->enable_wnck;
}
PulseaudioConfig *
pulseaudio_config_new (const gchar *property_base)
{
......@@ -563,6 +1056,9 @@ pulseaudio_config_new (const gchar *property_base)
{
channel = xfconf_channel_get ("xfce4-panel");
config->property_base = property_base;
config->channel = channel;
property = g_strconcat (property_base, "/enable-keyboard-shortcuts", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "enable-keyboard-shortcuts");
g_free (property);
......@@ -571,8 +1067,22 @@ pulseaudio_config_new (const gchar *property_base)
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "enable-multimedia-keys");
g_free (property);
property = g_strconcat (property_base, "/multimedia-keys-to-all", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "multimedia-keys-to-all");
g_free (property);
property = g_strconcat (property_base, "/show-notifications", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "show-notifications");
xfconf_g_property_bind (channel, property, G_TYPE_UINT, config, "show-notifications");
g_free (property);
#ifdef HAVE_LIBCANBERRA
property = g_strconcat (property_base, "/play-sound", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "play-sound");
g_free (property);
#endif
property = g_strconcat (property_base, "/rec-indicator-persistent", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "rec-indicator-persistent");
g_free (property);
property = g_strconcat (property_base, "/volume-step", NULL);
......@@ -591,8 +1101,20 @@ pulseaudio_config_new (const gchar *property_base)
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "enable-mpris");
g_free (property);
property = g_strconcat (property_base, "/mpris-players", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "mpris-players");
property = g_strconcat (property_base, "/known-players", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "known-players");
g_free (property);
property = g_strconcat (property_base, "/ignored-players", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "ignored-players");
g_free (property);
property = g_strconcat (property_base, "/persistent-players", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "persistent-players");
g_free (property);
property = g_strconcat (property_base, "/enable-wnck", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "enable-wnck");
g_free (property);
g_object_notify (G_OBJECT (config), "enable-keyboard-shortcuts");
......
......@@ -20,7 +20,7 @@
#define __PULSEAUDIO_CONFIG_H__
#include <glib.h>
#include <dbus/dbus-glib.h>
#include <gtk/gtk.h>
G_BEGIN_DECLS
......@@ -34,23 +34,59 @@ typedef struct _PulseaudioConfig PulseaudioConfig;
#define IS_PULSEAUDIO_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PULSEAUDIO_CONFIG))
#define PULSEAUDIO_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PULSEAUDIO_CONFIG, PulseaudioConfigClass))
enum
{
/* First two values keeps the backward compatibility */
VOLUME_NOTIFICATIONS_NONE,
VOLUME_NOTIFICATIONS_ALL,
VOLUME_NOTIFICATIONS_OUTPUT,
VOLUME_NOTIFICATIONS_INPUT,
VOLUME_NOTIFICATIONS_COUNT,
};
GType pulseaudio_config_get_type (void) G_GNUC_CONST;
PulseaudioConfig *pulseaudio_config_new (const gchar *property_base);
gboolean pulseaudio_config_get_enable_keyboard_shortcuts (PulseaudioConfig *config);
gboolean pulseaudio_config_get_enable_multimedia_keys (PulseaudioConfig *config);
gboolean pulseaudio_config_get_show_notifications (PulseaudioConfig *config);
gboolean pulseaudio_config_get_multimedia_keys_to_all (PulseaudioConfig *config);
guint pulseaudio_config_get_show_notifications (PulseaudioConfig *config);
#ifdef HAVE_LIBCANBERRA
gboolean pulseaudio_config_get_play_sound (PulseaudioConfig *config);
#endif
gboolean pulseaudio_config_get_rec_indicator_persistent (PulseaudioConfig *config);
guint pulseaudio_config_get_volume_step (PulseaudioConfig *config);
guint pulseaudio_config_get_volume_max (PulseaudioConfig *config);
const gchar *pulseaudio_config_get_mixer_command (PulseaudioConfig *config);
gchar **pulseaudio_config_get_mpris_players (PulseaudioConfig *config);
gchar **pulseaudio_config_get_known_players (PulseaudioConfig *config);
gboolean pulseaudio_config_get_enable_mpris (PulseaudioConfig *config);
void pulseaudio_config_set_mpris_players (PulseaudioConfig *config,
gchar **players);
void pulseaudio_config_add_mpris_player (PulseaudioConfig *config,
gchar *player);
void pulseaudio_config_add_known_player (PulseaudioConfig *config,
const gchar *player);
void pulseaudio_config_player_ignored_add (PulseaudioConfig *config,
const gchar *player);
void pulseaudio_config_player_ignored_remove (PulseaudioConfig *config,
const gchar *player);
gboolean pulseaudio_config_player_ignored_lookup (PulseaudioConfig *config,
const gchar *player);
void pulseaudio_config_player_persistent_add (PulseaudioConfig *config,
const gchar *player);
void pulseaudio_config_player_persistent_remove (PulseaudioConfig *config,
const gchar *player);
gboolean pulseaudio_config_player_persistent_lookup (PulseaudioConfig *config,
const gchar *player);
void pulseaudio_config_clear_known_players (PulseaudioConfig *config);
void pulseaudio_config_set_can_raise_wnck (PulseaudioConfig *config,
gboolean can_raise);
gboolean pulseaudio_config_get_can_raise_wnck (PulseaudioConfig *config);
G_END_DECLS
......
/*
* Copyright (C) 2015 Andrzej <ndrwrdck@gmail.com>
* Copyright (C) 2015 Andrzej <andrzejr@xfce.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -36,20 +36,13 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <libxfce4panel/xfce-panel-plugin.h>
#include <libxfce4panel/libxfce4panel.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
#include "pulseaudio-dialog.h"
#include "pulseaudio-dialog_ui.h"
#define PLUGIN_WEBSITE "https://docs.xfce.org/apps/pulseaudio-plugin/start"
#ifdef LIBXFCE4UI_CHECK_VERSION
#if LIBXFCE4UI_CHECK_VERSION (4, 9, 0)
#define HAS_ONLINE_HELP
#endif
#endif
#include "pulseaudio-dialog-resources.h"
#include "pulseaudio-mpris.h"
......@@ -73,6 +66,9 @@ struct _PulseaudioDialog
GObject *dialog;
PulseaudioConfig *config;
GtkWidget *treeview;
GtkWidget *revealer;
};
......@@ -102,15 +98,23 @@ pulseaudio_dialog_mixer_command_changed (PulseaudioDialog *dialog)
{
GObject *object;
gchar *path;
gchar **argvp = NULL;
gboolean sensitive = FALSE;
g_return_if_fail (GTK_IS_BUILDER (dialog));
g_return_if_fail (IS_PULSEAUDIO_CONFIG (dialog->config));
object = gtk_builder_get_object (GTK_BUILDER (dialog), "button-run-mixer");
g_return_if_fail (GTK_IS_BUTTON (object));
path = g_find_program_in_path (pulseaudio_config_get_mixer_command (dialog->config));
gtk_widget_set_sensitive (GTK_WIDGET (object), path != NULL);
g_free (path);
if (g_shell_parse_argv (pulseaudio_config_get_mixer_command (dialog->config), NULL, &argvp, NULL))
{
path = g_find_program_in_path (argvp[0]);
if (path)
sensitive = TRUE;
g_free (path);
g_strfreev (argvp);
}
gtk_widget_set_sensitive (GTK_WIDGET (object), sensitive);
}
......@@ -125,9 +129,9 @@ pulseaudio_dialog_run_mixer (PulseaudioDialog *dialog,
g_return_if_fail (IS_PULSEAUDIO_DIALOG (dialog));
g_return_if_fail (GTK_IS_BUTTON (widget));
if (!xfce_spawn_command_line_on_screen (gtk_widget_get_screen (widget),
pulseaudio_config_get_mixer_command (dialog->config),
FALSE, FALSE, &error))
if (!xfce_spawn_command_line (gtk_widget_get_screen (widget),
pulseaudio_config_get_mixer_command (dialog->config),
FALSE, FALSE, TRUE, &error))
{
message_dialog = gtk_message_dialog_new_with_markup (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
......@@ -145,19 +149,102 @@ pulseaudio_dialog_run_mixer (PulseaudioDialog *dialog,
static void
pulseaudio_dialog_persistent_toggled_cb (GtkCellRendererToggle *toggle, gchar *path, gpointer user_data)
{
PulseaudioDialog *dialog = PULSEAUDIO_DIALOG (user_data);
GtkTreeModel *model;
GtkTreePath *treepath;
GtkTreeIter iter;
GValue persistent_val = G_VALUE_INIT, player_val = G_VALUE_INIT;
gboolean persistent;
const gchar *player;
model = GTK_TREE_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(dialog->treeview)));
treepath = gtk_tree_path_new_from_string (path);
gtk_tree_model_get_iter (model, &iter, treepath);
gtk_tree_model_get_value (model, &iter, 4, &player_val);
gtk_tree_model_get_value (model, &iter, 2, &persistent_val);
persistent = !g_value_get_boolean(&persistent_val);
player = g_value_get_string(&player_val);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 2, persistent, -1);
if (persistent)
pulseaudio_config_player_persistent_add (dialog->config, player);
else
pulseaudio_config_player_persistent_remove (dialog->config, player);
}
static void
pulseaudio_dialog_ignored_toggled_cb (GtkCellRendererToggle *toggle, gchar *path, gpointer user_data)
{
PulseaudioDialog *dialog = PULSEAUDIO_DIALOG (user_data);
GtkTreeModel *model;
GtkTreePath *treepath;
GtkTreeIter iter;
GValue ignored_val = G_VALUE_INIT, player_val = G_VALUE_INIT;
gboolean ignored;
const gchar *player;
model = GTK_TREE_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(dialog->treeview)));
treepath = gtk_tree_path_new_from_string (path);
gtk_tree_model_get_iter (model, &iter, treepath);
gtk_tree_model_get_value (model, &iter, 4, &player_val);
gtk_tree_model_get_value (model, &iter, 3, &ignored_val);
ignored = !g_value_get_boolean(&ignored_val);
player = g_value_get_string(&player_val);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 3, ignored, -1);
if (ignored)
pulseaudio_config_player_ignored_add (dialog->config, player);
else
pulseaudio_config_player_ignored_remove (dialog->config, player);
}
static void
pulseaudio_dialog_clear_players_cb (GtkButton *button,
gpointer *user_data)
{
PulseaudioDialog *dialog = PULSEAUDIO_DIALOG (user_data);
GtkListStore *liststore;
pulseaudio_config_clear_known_players (dialog->config);
liststore = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dialog->treeview)));
gtk_list_store_clear (liststore);
gtk_revealer_set_reveal_child (GTK_REVEALER(dialog->revealer), TRUE);
}
static void
pulseaudio_dialog_build (PulseaudioDialog *dialog)
{
GtkBuilder *builder = GTK_BUILDER (dialog);
GObject *object;
GError *error = NULL;
GtkBuilder *builder = GTK_BUILDER (dialog);
GObject *object;
GtkListStore *liststore;
GtkTreeIter iter;
GError *error = NULL;
gchar **players;
guint i;
if (xfce_titled_dialog_get_type () == 0)
return;
/* load the builder data into the object */
if (gtk_builder_add_from_string (builder, pulseaudio_dialog_ui,
pulseaudio_dialog_ui_length, &error))
pulseaudio_dialog_register_resource ();
if (gtk_builder_add_from_resource (builder,
"/org/xfce/pulseaudio-plugin/pulseaudio-dialog.glade",
&error))
{
dialog->dialog = gtk_builder_get_object (builder, "dialog");
g_return_if_fail (XFCE_IS_TITLED_DIALOG (dialog->dialog));
......@@ -180,8 +267,8 @@ pulseaudio_dialog_build (PulseaudioDialog *dialog)
G_OBJECT (object), "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
object = gtk_builder_get_object (builder, "checkbutton-show-notifications");
g_return_if_fail (GTK_IS_CHECK_BUTTON (object));
object = gtk_builder_get_object (builder, "combobox-notifications");
g_return_if_fail (GTK_IS_COMBO_BOX (object));
#ifdef HAVE_LIBNOTIFY
g_object_bind_property (G_OBJECT (dialog->config), "show-notifications",
G_OBJECT (object), "active",
......@@ -190,6 +277,33 @@ pulseaudio_dialog_build (PulseaudioDialog *dialog)
gtk_widget_set_visible (GTK_WIDGET (object), FALSE);
#endif
object = gtk_builder_get_object (builder, "checkbutton-play-sound");
g_return_if_fail (GTK_IS_CHECK_BUTTON (object));
#ifdef HAVE_LIBCANBERRA
g_object_bind_property (G_OBJECT (dialog->config), "play-sound",
G_OBJECT (object), "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
#else
gtk_widget_set_visible (GTK_WIDGET (object), FALSE);
#endif
object = gtk_builder_get_object (builder, "checkbutton-rec-indicator-persistent");
g_object_bind_property (G_OBJECT (dialog->config), "rec-indicator-persistent",
G_OBJECT (object), "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
object = gtk_builder_get_object (builder, "spinbutton-volume-step");
g_return_if_fail (GTK_IS_ENTRY (object));
g_object_bind_property (G_OBJECT (dialog->config), "volume-step",
G_OBJECT (object), "value",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
object = gtk_builder_get_object (builder, "spinbutton-max-volume");
g_return_if_fail (GTK_IS_ENTRY (object));
g_object_bind_property (G_OBJECT (dialog->config), "volume-max",
G_OBJECT (object), "value",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
object = gtk_builder_get_object (builder, "entry-mixer-command");
g_return_if_fail (GTK_IS_ENTRY (object));
g_object_bind_property (G_OBJECT (dialog->config), "mixer-command",
......@@ -206,23 +320,110 @@ pulseaudio_dialog_build (PulseaudioDialog *dialog)
G_CALLBACK (pulseaudio_dialog_run_mixer), dialog);
#ifdef HAVE_MPRIS2
object = gtk_builder_get_object (builder, "checkbutton-mpris-support");
g_return_if_fail (GTK_IS_CHECK_BUTTON (object));
object = gtk_builder_get_object (builder, "switch-mpris-support");
g_return_if_fail (GTK_IS_SWITCH (object));
g_object_bind_property (G_OBJECT (dialog->config), "enable-mpris",
G_OBJECT (object), "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
g_object_bind_property(G_OBJECT(dialog->config), "enable-mpris",
G_OBJECT(gtk_builder_get_object(builder, "checkbutton-multimedia-keys")), "sensitive",
object = gtk_builder_get_object(builder, "checkbutton-multimedia-keys");
g_return_if_fail(GTK_IS_CHECK_BUTTON(object));
g_object_bind_property(G_OBJECT(dialog->config), "enable-multimedia-keys",
G_OBJECT(object), "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
object = gtk_builder_get_object(builder, "checkbutton-multimedia-keys");
object = gtk_builder_get_object(builder, "checkbutton-multimedia-keys-to-all");
g_return_if_fail(GTK_IS_CHECK_BUTTON(object));
g_object_bind_property(G_OBJECT(dialog->config), "multimedia-keys-to-all",
G_OBJECT(object), "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
g_object_bind_property(G_OBJECT(dialog->config), "enable-multimedia-keys",
G_OBJECT(object), "sensitive",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
object = gtk_builder_get_object(builder, "section_mp_content_1");
g_object_bind_property(G_OBJECT(dialog->config), "enable-mpris",
G_OBJECT(object), "sensitive",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
object = gtk_builder_get_object(builder, "section_mp_content_2");
g_object_bind_property(G_OBJECT(dialog->config), "enable-mpris",
G_OBJECT(object), "sensitive",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
/* Populate the liststore */
dialog->treeview = GTK_WIDGET(gtk_builder_get_object(builder, "player_tree_view"));
liststore = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dialog->treeview)));
players = pulseaudio_config_get_known_players (dialog->config);
if (players != NULL)
{
const guint num_players = g_strv_length (players);
for (i = 0; i < num_players; i++)
{
gchar *player_label = NULL;
gchar *icon_name = NULL;
GIcon *icon = NULL;
if (pulseaudio_mpris_get_player_summary (players[i], &player_label, &icon_name, NULL))
{
if (g_file_test (icon_name, G_FILE_TEST_EXISTS) && !g_file_test (icon_name, G_FILE_TEST_IS_DIR))
{
GdkPixbuf *buf = gdk_pixbuf_new_from_file (icon_name, NULL);
if (G_LIKELY (buf != NULL))
icon = G_ICON (buf);
}
if (G_LIKELY (icon == NULL))
{
if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default (), icon_name))
icon = g_themed_icon_new (icon_name);
else
icon = g_themed_icon_new_with_default_fallbacks ("audio-player");
}
gtk_list_store_append (liststore, &iter);
gtk_list_store_set (liststore, &iter,
0, icon,
1, player_label,
2, pulseaudio_config_player_persistent_lookup (dialog->config, players[i]),
3, pulseaudio_config_player_ignored_lookup (dialog->config, players[i]),
4, players[i],
-1);
g_free (player_label);
g_free (icon_name);
if (icon != NULL)
g_object_unref (icon);
}
}
g_strfreev (players);
}
object = gtk_builder_get_object(builder, "col_persistent_renderer");
g_signal_connect (object, "toggled", (GCallback) pulseaudio_dialog_persistent_toggled_cb, dialog);
object = gtk_builder_get_object(builder, "col_ignored_renderer");
g_signal_connect (object, "toggled", (GCallback) pulseaudio_dialog_ignored_toggled_cb, dialog);
object = gtk_builder_get_object(builder, "clear_players");
g_signal_connect (object, "clicked", (GCallback) pulseaudio_dialog_clear_players_cb, dialog);
dialog->revealer = GTK_WIDGET(gtk_builder_get_object(builder, "restart_revealer"));
object = gtk_builder_get_object(builder, "checkbutton-wnck");
g_return_if_fail(GTK_IS_CHECK_BUTTON(object));
#ifdef HAVE_LIBXFCE4WINDOWING
g_object_bind_property(G_OBJECT(dialog->config), "enable-wnck",
G_OBJECT(object), "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
#else
object = gtk_builder_get_object (builder, "media-player-frame");
gtk_widget_set_visible(GTK_WIDGET(object), FALSE);
#endif
#else
object = gtk_builder_get_object (builder, "section_mp_content");
gtk_widget_set_visible (GTK_WIDGET (object), FALSE);
#endif
}
......@@ -240,24 +441,11 @@ static void
pulseaudio_dialog_help_button_clicked (PulseaudioDialog *dialog,
GtkWidget *button)
{
#ifndef HAS_ONLINE_HELP
gboolean result;
#endif
g_return_if_fail (IS_PULSEAUDIO_DIALOG (dialog));
g_return_if_fail (GTK_IS_BUTTON (button));
g_return_if_fail (GTK_IS_WINDOW (dialog->dialog));
#ifdef HAS_ONLINE_HELP
xfce_dialog_show_help (GTK_WINDOW (dialog->dialog), "pulseaudio-plugin", "start", NULL);
#else
result = g_spawn_command_line_async ("exo-open --launch WebBrowser " PLUGIN_WEBSITE, NULL);
if (G_UNLIKELY (result == FALSE))
g_warning ("Unable to open the following url: %s", PLUGIN_WEBSITE);
#endif
}
......
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/xfce/pulseaudio-plugin">
<file>pulseaudio-dialog.glade</file>
</gresource>
</gresources>
/*
* Copyright (C) 2015 Andrzej <ndrwrdck@gmail.com>
* Copyright (C) 2015 Andrzej <andrzejr@xfce.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......
This diff is collapsed.
This diff is collapsed.
/* Copyright (c) 2017 Sean Davis <bluesabre@xfce.org>
/* Copyright (c) 2017-2020 Sean Davis <bluesabre@xfce.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -52,11 +52,16 @@ typedef struct _PulseaudioMprisPlayerClass PulseaudioMpr
PulseaudioMprisPlayer *pulseaudio_mpris_player_new (gchar *name);
gchar *pulseaudio_mpris_player_find_desktop_entry (const gchar *player_name);
gint64 pulseaudio_mpris_player_get_timestamp (PulseaudioMprisPlayer *player);
const gchar *pulseaudio_mpris_player_get_player (PulseaudioMprisPlayer *player);
const gchar *pulseaudio_mpris_player_get_player_title (PulseaudioMprisPlayer *player);
const gchar *pulseaudio_mpris_player_get_player_label (PulseaudioMprisPlayer *player);
const gchar *pulseaudio_mpris_player_get_dbus_name (PulseaudioMprisPlayer *player);
const gchar *pulseaudio_mpris_player_get_icon_name (PulseaudioMprisPlayer *player);
const gchar *pulseaudio_mpris_player_get_title (PulseaudioMprisPlayer *player);
const gchar *pulseaudio_mpris_player_get_artist (PulseaudioMprisPlayer *player);
const gchar *pulseaudio_mpris_player_get_full_path (PulseaudioMprisPlayer *player);
gboolean pulseaudio_mpris_player_is_connected (PulseaudioMprisPlayer *player);
gboolean pulseaudio_mpris_player_is_playing (PulseaudioMprisPlayer *player);
......@@ -68,11 +73,9 @@ gboolean pulseaudio_mpris_player_can_go_previous (PulseaudioMp
gboolean pulseaudio_mpris_player_can_go_next (PulseaudioMprisPlayer *player);
gboolean pulseaudio_mpris_player_can_raise (PulseaudioMprisPlayer *player);
gboolean pulseaudio_mpris_player_is_equal (PulseaudioMprisPlayer *a,
PulseaudioMprisPlayer *b);
void pulseaudio_mpris_player_call_player_method (PulseaudioMprisPlayer *player,
const gchar *method);
const gchar *method,
gboolean update_timestamp);
GList *pulseaudio_mpris_player_get_playlists (PulseaudioMprisPlayer *player);
void pulseaudio_mpris_player_activate_playlist (PulseaudioMprisPlayer *player,
......
This diff is collapsed.
/* Copyright (c) 2017 Sean Davis <bluesabre@xfce.org>
/* Copyright (c) 2017-2020 Sean Davis <bluesabre@xfce.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -39,13 +39,10 @@ typedef struct _PulseaudioMprisClass PulseaudioMprisCl
PulseaudioMpris *pulseaudio_mpris_new (PulseaudioConfig *config);
gchar **pulseaudio_mpris_get_available_players (PulseaudioMpris *mpris);
gboolean pulseaudio_mpris_get_player_snapshot (PulseaudioMpris *mpris,
const gchar *name,
gchar **title,
gchar **artist,
gboolean *is_running,
gboolean *is_playing,
gboolean *is_stopped,
gboolean *can_play,
......@@ -55,6 +52,11 @@ gboolean pulseaudio_mpris_get_player_snapshot (PulseaudioMpris
gboolean *can_raise,
GList **playlists);
gboolean pulseaudio_mpris_get_player_summary (const gchar *player_name,
gchar **player_label,
gchar **icon_name,
gchar **full_path);
gboolean pulseaudio_mpris_notify_player (PulseaudioMpris *mpris,
const gchar *name,
const gchar *message);
......
......@@ -39,9 +39,6 @@
#include <libxfce4util/libxfce4util.h>
#define SYNCHRONOUS "x-canonical-private-synchronous"
#define LAYOUT_ICON_ONLY "x-canonical-private-icon-only"
#include "pulseaudio-notify.h"
#define V_MUTED 0
......@@ -83,7 +80,6 @@ struct _PulseaudioNotify
PulseaudioVolume *volume;
PulseaudioButton *button;
gboolean gauge_notifications;
NotifyNotification *notification;
NotifyNotification *notification_mic;
......@@ -116,10 +112,6 @@ pulseaudio_notify_class_init (PulseaudioNotifyClass *klass)
static void
pulseaudio_notify_init (PulseaudioNotify *notify)
{
GList *caps_list;
GList *node;
notify->gauge_notifications = TRUE;
notify->notification = NULL;
notify->notification_mic = NULL;
notify->volume_changed_id = 0;
......@@ -127,15 +119,6 @@ pulseaudio_notify_init (PulseaudioNotify *notify)
notify_init ("Xfce volume control");
caps_list = notify_get_server_caps ();
if (caps_list)
{
node = g_list_find_custom (caps_list, LAYOUT_ICON_ONLY, (GCompareFunc) g_strcmp0);
if (!node)
notify->gauge_notifications = FALSE;
g_list_free (caps_list);
}
notify->notification = notify_notification_new ("xfce4-pulseaudio-plugin", NULL, NULL);
notify_notification_set_timeout (notify->notification, 2000);
notify_notification_set_hint (notify->notification, "transient", g_variant_new_boolean (TRUE));
......@@ -221,15 +204,9 @@ pulseaudio_notify_notify (PulseaudioNotify *notify, gboolean mic)
icon);
g_free (title);
if (notify->gauge_notifications)
{
notify_notification_set_hint (notification,
"value",
g_variant_new_int32(volume_i));
notify_notification_set_hint (notification,
"x-canonical-private-synchronous",
g_variant_new_string(""));
}
notify_notification_set_hint (notification,
"value",
g_variant_new_int32 (MIN (100, volume_i)));
if (!notify_notification_show (notification, &error))
{
......@@ -240,7 +217,7 @@ pulseaudio_notify_notify (PulseaudioNotify *notify, gboolean mic)
static void
void
pulseaudio_notify_volume_changed (PulseaudioNotify *notify,
gboolean should_notify,
PulseaudioVolume *volume)
......@@ -285,7 +262,7 @@ pulseaudio_notify_new (PulseaudioConfig *config,
notify->volume_changed_id =
g_signal_connect_swapped (G_OBJECT (notify->volume), "volume-changed",
G_CALLBACK (pulseaudio_notify_volume_changed), notify);
notify->volume_changed_id =
notify->volume_mic_changed_id =
g_signal_connect_swapped (G_OBJECT (notify->volume), "volume-mic-changed",
G_CALLBACK (pulseaudio_notify_volume_mic_changed), notify);
......
......@@ -43,6 +43,9 @@ GType pulseaudio_notify_get_type (void) G_GNUC_CONST;
PulseaudioNotify *pulseaudio_notify_new (PulseaudioConfig *config,
PulseaudioVolume *volume,
PulseaudioButton *button);
void pulseaudio_notify_volume_changed (PulseaudioNotify *notify,
gboolean should_notify,
PulseaudioVolume *volume);
G_END_DECLS
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.