From ef1ca4326d8feec2967e2a8a0e8e94d4423aa854 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 10 May 2014 10:02:20 -0400 Subject: [PATCH] widgets/now_playing_mpris: rewrite Improve render quirks and support configuration-free mpris widget suitable for use with multiple media players. The widget polls for mpris players. When it finds one, it subscribes to events and updates the player status appropriately. If no player name is configured, when the player exits, polling starts again for another player. --- src/widgets/now_playing_mpris.c | 73 ++++++++++++++++++++++++++++----- wscript | 2 +- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/widgets/now_playing_mpris.c b/src/widgets/now_playing_mpris.c index 3da4b2c..d1b051f 100644 --- a/src/widgets/now_playing_mpris.c +++ b/src/widgets/now_playing_mpris.c @@ -1,6 +1,8 @@ #include "widgets.h" #include "now_playing_mpris.h" +static PlayerctlPlayer *widget_player; + static int update_widget (struct widget *widget, PlayerctlPlayer *player) { char *artist = playerctl_player_get_artist(player, NULL); @@ -25,37 +27,86 @@ update_widget (struct widget *widget, PlayerctlPlayer *player) { return 0; } +static int +clear_widget (struct widget *widget) { + struct js_callback_arg args[2] = { + widget_data_arg_string(""), + widget_data_arg_string(""), + }; + + struct js_callback_data data = { + .widget = widget, + .args = args, + 2, + }; + + web_view_callback(&data); + + return 0; +} + static void -on_metadata (PlayerctlPlayer *player, GVariant *e, gpointer user_data) { +player_update_callback (PlayerctlPlayer *player, GVariant *e, gpointer user_data) { struct widget *widget = user_data; update_widget(widget, player); } +static void +player_clear_callback (PlayerctlPlayer *player, gpointer user_data) { + struct widget *widget = user_data; + clear_widget(widget); +} + +static void +player_exit_destroy_callback (PlayerctlPlayer *player, gpointer user_data) { + g_clear_object(&widget_player); +} + void* widget_main (struct widget *widget) { struct widget_config config = widget_config_defaults; widget_init_config_string(widget->config, "player_name", config.player_name); gchar *player_name = (gchar*)config.player_name; - PlayerctlPlayer *player = NULL; + widget_player = NULL; widget_epoll_init(widget); while (true) { - player = playerctl_player_new(player_name, NULL); + if (widget_player == NULL) { + widget_player = playerctl_player_new(player_name, NULL); - if (player) { - g_signal_connect(player, "metadata", G_CALLBACK(on_metadata), widget); + if (widget_player) { + /* update the widget on new metadata, or on play */ + g_signal_connect(widget_player, "metadata", + G_CALLBACK(player_update_callback), widget); + g_signal_connect(widget_player, "play", + G_CALLBACK(player_update_callback), widget); - widget_epoll_wait_goto(widget, -1, cleanup); - } - else { - /* keep trying until we find a player */ - widget_epoll_wait_goto(widget, 1, cleanup); + /* clear the widget on stop and exit */ + g_signal_connect(widget_player, "stop", + G_CALLBACK(player_clear_callback), widget); + g_signal_connect(widget_player, "exit", + G_CALLBACK(player_clear_callback), widget); + + if (player_name != NULL) { + /* if a player name was passed, stick with it */ + widget_epoll_wait_goto(widget, -1, cleanup); + /* not reached */ + } + else { + /* otherwise, remove the player when it exits and start polling again */ + g_signal_connect(widget_player, "exit", + G_CALLBACK(player_exit_destroy_callback), widget); + } + } } + + /* if a player name was not configured, poll for new or different players */ + widget_epoll_wait_goto(widget, 2, cleanup); } cleanup: - g_object_unref(player); + g_clear_object(&widget_player); widget_epoll_cleanup(widget); widget_clean_exit(widget); diff --git a/wscript b/wscript index 8569e16..b9e2c94 100644 --- a/wscript +++ b/wscript @@ -70,7 +70,7 @@ def configure(ctx): ctx.check_cfg(package='dbus-1 dbus-glib-1', uselib_store='DBUS', args=['--cflags', '--libs'], mandatory=False) ctx.check_cfg(package='GraphicsMagickWand', uselib_store='MAGICK', args=['--cflags', '--libs'], mandatory=False) ctx.check_cfg(package='libmpdclient', uselib_store='LIBMPDCLIENT', args=['--cflags', '--libs'], mandatory=False) - ctx.check_cfg(package='playerctl-1.0', uselib_store='PLAYERCTL', args=['--cflags', '--libs'], mandatory=False) + ctx.check_cfg(package='playerctl-1.0 >= 0.3.0', uselib_store='PLAYERCTL', args=['--cflags', '--libs'], mandatory=False) ctx.check_cfg(package='xcb-util xcb-ewmh xcb-icccm', uselib_store='XCB', args=['--cflags', '--libs'], mandatory=False) ctx.check_cfg(package='i3ipc-glib-1.0', uselib_store='I3IPC', args=['--cflags', '--libs'], mandatory=False)