diff options
Diffstat (limited to 'plugins/gtkui')
-rw-r--r-- | plugins/gtkui/Makefile.am | 4 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.c | 6 | ||||
-rw-r--r-- | plugins/gtkui/gtkplaylist.c | 40 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.c | 53 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.h | 4 | ||||
-rw-r--r-- | plugins/gtkui/pluginconf.c | 11 |
6 files changed, 101 insertions, 17 deletions
diff --git a/plugins/gtkui/Makefile.am b/plugins/gtkui/Makefile.am index aaf9c56a..146e76db 100644 --- a/plugins/gtkui/Makefile.am +++ b/plugins/gtkui/Makefile.am @@ -13,6 +13,6 @@ gtkui_la_SOURCES = gtkui.c gtkui.h\ gtkui_la_LDFLAGS = -module -gtkui_la_LIBADD = $(LDADD) $(GTKUI_DEPS_LIBS) -AM_CFLAGS = -std=c99 $(GTKUI_DEPS_CFLAGS) +gtkui_la_LIBADD = $(LDADD) $(GTKUI_DEPS_LIBS) $(NOTIFY_DEPS_LIBS) +AM_CFLAGS = -std=c99 $(GTKUI_DEPS_CFLAGS) $(NOTIFY_DEPS_CFLAGS) endif diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index 3e9e8538..393a1b27 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -881,6 +881,9 @@ void save_playlist_as (void) { GtkWidget *dlg = gtk_file_chooser_dialog_new ("Save Playlist As", GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dlg), TRUE); + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dlg), "untitled.dbpl"); + GtkFileFilter* flt; flt = gtk_file_filter_new (); gtk_file_filter_set_name (flt, "DeaDBeeF playlist files (*.dbpl)"); @@ -893,6 +896,8 @@ save_playlist_as (void) { gtk_widget_destroy (dlg); if (fname) { +// the code below cannot be used, because it breaks gtk overwrite confirmation +#if 0 // check extension and append .dbpl if none size_t sz = strlen (fname); char ext[] = ".dbpl"; @@ -908,6 +913,7 @@ save_playlist_as (void) { g_free (fname); fname = n; } +#endif int res = deadbeef->pl_save (fname); if (res >= 0 && strlen (fname) < 1024) { strcpy (last_playlist_save_name, fname); diff --git a/plugins/gtkui/gtkplaylist.c b/plugins/gtkui/gtkplaylist.c index 7b0912b9..868e26a2 100644 --- a/plugins/gtkui/gtkplaylist.c +++ b/plugins/gtkui/gtkplaylist.c @@ -16,7 +16,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H -# include <config.h> +# include "../../config.h" +#endif +#if HAVE_NOTIFY +#include <libnotify/notify.h> #endif #include <gtk/gtk.h> @@ -40,6 +43,7 @@ #include "../../session.h" #include "../../deadbeef.h" #include "parser.h" +#include "gtkui.h" #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) @@ -349,7 +353,9 @@ gtkpl_draw_pl_row_back (gtkplaylist_t *ps, int row, DB_playItem_t *it) { int x = -ps->hscrollpos; int w = ps->totalwidth; // clear area -- workaround for New Wave theme - gdk_draw_rectangle (ps->backbuf, treeview->style->bg_gc[GTK_STATE_NORMAL], TRUE, x, row * rowheight - ps->scrollpos * rowheight, w, rowheight); + if (ps->playlist->style->bg_gc[GTK_STATE_NORMAL]) { + gdk_draw_rectangle (ps->backbuf, ps->playlist->style->bg_gc[GTK_STATE_NORMAL], TRUE, 0, row * rowheight - ps->scrollpos * rowheight, ps->playlist->allocation.width, rowheight); + } gtk_paint_flat_box (treeview->style, ps->backbuf, (it && SELECTED(it)) ? GTK_STATE_SELECTED : GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, treeview, (row & 1) ? "cell_even_ruled" : "cell_odd_ruled", x, row * rowheight - ps->scrollpos * rowheight, w, rowheight); if (row == deadbeef->pl_get_cursor (ps->iterator)) { // not all gtk engines/themes render focus rectangle in treeviews @@ -381,7 +387,7 @@ gtkpl_draw_pl_row (gtkplaylist_t *ps, int row, DB_playItem_t *it) { int x = -ps->hscrollpos; gtkpl_column_t *c; for (c = ps->columns; c; c = c->next) { - if (it == deadbeef->pl_getcurrent () && c->id == DB_COLUMN_PLAYING) { + if (it == deadbeef->streamer_get_playing_track () && c->id == DB_COLUMN_PLAYING) { int paused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED; int buffering = !deadbeef->streamer_ok_to_read (-1); uintptr_t pixbuf; @@ -875,7 +881,7 @@ gtkpl_songchanged (gtkplaylist_t *ps, int from, int to) { gtk_range_set_value (GTK_RANGE (ps->scrollbar), to - ps->nvisiblerows/2); } } - if (deadbeef->conf_get_int ("playlist.scroll.cursorfollowplayback", 1)) { + if (deadbeef->conf_get_int ("playlist.scroll.cursorfollowplayback", 0)) { gtkpl_set_cursor (PL_MAIN, to); } } @@ -1832,12 +1838,38 @@ struct fromto_t { int to; }; +#if HAVE_NOTIFY +static NotifyNotification* notification; +#endif + static gboolean update_win_title_idle (gpointer data) { struct fromto_t *ft = (struct fromto_t *)data; int from = ft->from; int to = ft->to; free (ft); + + // show notification +#if HAVE_NOTIFY + if (to != -1 && deadbeef->conf_get_int ("gtkui.notify.enable", 0)) { + DB_playItem_t *track = deadbeef->pl_get_for_idx (to); + if (track) { + char cmd [1024]; + deadbeef->pl_format_title (track, -1, cmd, sizeof (cmd), -1, deadbeef->conf_get_str ("gtkui.notify.format", NOTIFY_DEFAULT_FORMAT)); + if (notify_is_initted ()) { + if (notification) { + notify_notification_close (notification, NULL); + } + notification = notify_notification_new ("DeaDBeeF", cmd, NULL, NULL); + if (notification) { + notify_notification_set_timeout (notification, NOTIFY_EXPIRES_DEFAULT); + notify_notification_show (notification, NULL); + } + } + } + } +#endif + // update window title if (from >= 0 || to >= 0) { if (to >= 0) { diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index c05cbdad..954a7781 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -18,9 +18,16 @@ */ #include "../../deadbeef.h" #include <gtk/gtk.h> +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif +#if HAVE_NOTIFY +#include <libnotify/notify.h> +#endif #include <string.h> #include <stdlib.h> #include <math.h> +#include <sys/time.h> #include "gtkui.h" #include "gtkplaylist.h" #include "search.h" @@ -51,6 +58,8 @@ gtkplaylist_t search_playlist; static int sb_context_id = -1; static char sb_text[512]; static float last_songpos = -1; +static char sbitrate[20] = ""; +static struct timeval last_br_update; static gboolean update_songinfo (gpointer ctx) { @@ -83,7 +92,6 @@ update_songinfo (gpointer ctx) { songpos = 0; } else { -// codec_lock (); DB_fileinfo_t *c = deadbeef->streamer_get_current_decoder (); if (c) { float playpos = deadbeef->streamer_get_playpos (); @@ -106,13 +114,18 @@ update_songinfo (gpointer ctx) { strcpy (t, "-:--"); } - char sbitrate[20] = ""; -#if 1 - int bitrate = deadbeef->streamer_get_apx_bitrate (); - if (bitrate > 0) { - snprintf (sbitrate, sizeof (sbitrate), "| %d kbps ", bitrate); + struct timeval tm; + gettimeofday (&tm, NULL); + if (tm.tv_sec - last_br_update.tv_sec + (tm.tv_usec - last_br_update.tv_usec) / 1000000.0 >= 0.3) { + memcpy (&last_br_update, &tm, sizeof (tm)); + int bitrate = deadbeef->streamer_get_apx_bitrate (); + if (bitrate > 0) { + snprintf (sbitrate, sizeof (sbitrate), "| %4d kbps ", bitrate); + } + else { + sbitrate[0] = 0; + } } -#endif const char *spaused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED ? "Paused | " : ""; snprintf (sbtext_new, sizeof (sbtext_new), "%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d tracks | %s total playtime", spaused, track->filetype ? track->filetype:"-", sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, deadbeef->pl_getcount (PL_MAIN), totaltime_str); } @@ -367,9 +380,17 @@ gtkui_thread (void *ctx) { gdk_threads_init (); gdk_threads_enter (); gtk_set_locale (); - int argc = 1; - const char **argv = alloca (sizeof (char *)); +#if HAVE_NOTIFY + notify_init ("DeaDBeeF"); +#endif + + int argc = 2; + const char **argv = alloca (sizeof (char *) * argc); argv[0] = "deadbeef"; + argv[1] = "--sync"; + if (!deadbeef->conf_get_int ("gtkui.sync", 0)) { + argc = 1; + } gtk_init (&argc, (char ***)&argv); // system tray icon @@ -441,6 +462,9 @@ gtkui_thread (void *ctx) { gtk_widget_show (mainwin); gtk_main (); +#if HAVE_NOTIFY + notify_uninit (); +#endif gdk_threads_leave (); } @@ -497,6 +521,14 @@ gtkui_load (DB_functions_t *api) { return DB_PLUGIN (&plugin); } +static const char settings_dlg[] = + "property \"Run gtk_init with --sync (debug mode)\" checkbox gtkui.sync 0;\n" +#if HAVE_NOTIFY + "property \"Enable OSD notifications\" checkbox gtkui.notify.enable 0;\n" + "property \"Notification format\" entry gtkui.notify.format \"" NOTIFY_DEFAULT_FORMAT "\";\n" +#endif +; + // define plugin interface static DB_gui_t plugin = { DB_PLUGIN_SET_API_VERSION @@ -510,5 +542,6 @@ static DB_gui_t plugin = { .plugin.email = "waker@users.sourceforge.net", .plugin.website = "http://deadbeef.sf.net", .plugin.start = gtkui_start, - .plugin.stop = gtkui_stop + .plugin.stop = gtkui_stop, + .plugin.configdialog = settings_dlg, }; diff --git a/plugins/gtkui/gtkui.h b/plugins/gtkui/gtkui.h index fd8e1166..2031b502 100644 --- a/plugins/gtkui/gtkui.h +++ b/plugins/gtkui/gtkui.h @@ -19,6 +19,10 @@ #ifndef __GTKUI_H #define __GTKUI_H +#if HAVE_NOTIFY +#define NOTIFY_DEFAULT_FORMAT "%a - %t" +#endif + extern DB_functions_t *deadbeef; struct _GSList; diff --git a/plugins/gtkui/pluginconf.c b/plugins/gtkui/pluginconf.c index cc96e71b..6b96244f 100644 --- a/plugins/gtkui/pluginconf.c +++ b/plugins/gtkui/pluginconf.c @@ -117,12 +117,17 @@ static void apply_conf (GtkWidget *w, DB_plugin_t *p) { deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); } +static void +prop_changed (GtkWidget *editable, gpointer user_data) { + gtk_dialog_set_response_sensitive (GTK_DIALOG (user_data), GTK_RESPONSE_APPLY, TRUE); +} + void plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { // create window char title[200]; snprintf (title, sizeof (title), "Setup %s", p->name); - GtkWidget *win = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parentwin), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, NULL); + GtkWidget *win = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parentwin), GTK_DIALOG_MODAL, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_window_set_type_hint (GTK_WINDOW (win), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_container_set_border_width (GTK_CONTAINER(win), 12); @@ -183,11 +188,13 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { label = gtk_label_new (labeltext); gtk_widget_show (label); prop = gtk_entry_new (); + g_signal_connect (G_OBJECT (prop), "changed", G_CALLBACK (prop_changed), win); gtk_widget_show (prop); gtk_entry_set_text (GTK_ENTRY (prop), deadbeef->conf_get_str (key, def)); } else if (!strcmp (type, "checkbox")) { prop = gtk_check_button_new_with_label (labeltext); + g_signal_connect (G_OBJECT (prop), "toggled", G_CALLBACK (prop_changed), win); gtk_widget_show (prop); int val = deadbeef->conf_get_int (key, atoi (def)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop), val); @@ -198,6 +205,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { cont = gtk_hbox_new (FALSE, 2); gtk_widget_show (cont); prop = gtk_entry_new (); + g_signal_connect (G_OBJECT (prop), "changed", G_CALLBACK (prop_changed), win); gtk_widget_show (prop); gtk_editable_set_editable (GTK_EDITABLE (prop), FALSE); gtk_entry_set_text (GTK_ENTRY (prop), deadbeef->conf_get_str (key, def)); @@ -231,6 +239,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { int response; do { + gtk_dialog_set_response_sensitive (GTK_DIALOG (win), GTK_RESPONSE_APPLY, FALSE); response = gtk_dialog_run (GTK_DIALOG (win)); if (response == GTK_RESPONSE_APPLY || response == GTK_RESPONSE_OK) { apply_conf (win, p); |