summaryrefslogtreecommitdiff
path: root/plugins/gtkui
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gtkui')
-rw-r--r--plugins/gtkui/Makefile.am4
-rw-r--r--plugins/gtkui/callbacks.c6
-rw-r--r--plugins/gtkui/gtkplaylist.c40
-rw-r--r--plugins/gtkui/gtkui.c53
-rw-r--r--plugins/gtkui/gtkui.h4
-rw-r--r--plugins/gtkui/pluginconf.c11
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);