rhythmbox r5781 - in trunk: . shell widgets
- From: jmatthew svn gnome org
- To: svn-commits-list gnome org
- Subject: rhythmbox r5781 - in trunk: . shell widgets
- Date: Sat, 28 Jun 2008 04:30:57 +0000 (UTC)
Author: jmatthew
Date: Sat Jun 28 04:30:56 2008
New Revision: 5781
URL: http://svn.gnome.org/viewvc/rhythmbox?rev=5781&view=rev
Log:
2008-06-28 Jonathan Matthew <jonathan d14n org>
* shell/rb-shell-player.c: (rb_shell_player_constructor),
(rb_shell_player_handle_eos_unlocked),
(rb_shell_player_slider_dragging_cb),
(rb_shell_player_set_playing_time), (tick_cb):
If the seek slider is still being dragged when we reach EOS, wait
until it's released; if a seek occurs before then, forget about it.
Fixes #140020.
* widgets/rb-header.c: (rb_header_class_init),
(rb_header_set_playing_entry_internal), (rb_header_set_property),
(rb_header_get_property), (rb_header_sync), (rb_header_sync_time),
(slider_press_callback), (slider_moved_timeout),
(slider_moved_callback), (apply_slider_position),
(slider_release_callback), (slider_changed_callback):
Add the 'slider-dragging' property used above. Rearrange various
bits of code to behave a little bit better, most importantly removing
the idle handler that just screwed things up. Set the upper bound on
the slider unconditionally when the playing entry changes, fixing
#496816.
Modified:
trunk/ChangeLog
trunk/shell/rb-shell-player.c
trunk/widgets/rb-header.c
Modified: trunk/shell/rb-shell-player.c
==============================================================================
--- trunk/shell/rb-shell-player.c (original)
+++ trunk/shell/rb-shell-player.c Sat Jun 28 04:30:56 2008
@@ -202,6 +202,9 @@
gboolean from_eos,
gboolean allow_stop,
GError **error);
+static void rb_shell_player_slider_dragging_cb (GObject *header,
+ GParamSpec *pspec,
+ RBShellPlayer *player);
@@ -639,6 +642,10 @@
player->priv->header_widget = rb_header_new (player, player->priv->db);
gtk_widget_show (GTK_WIDGET (player->priv->header_widget));
gtk_box_pack_start (GTK_BOX (player), GTK_WIDGET (player->priv->header_widget), TRUE, TRUE, 0);
+ g_signal_connect_object (player->priv->header_widget,
+ "notify::slider-dragging",
+ G_CALLBACK (rb_shell_player_slider_dragging_cb),
+ player, 0);
gtk_action_group_add_actions (player->priv->actiongroup,
rb_shell_player_actions,
@@ -785,6 +792,7 @@
RhythmDBEntry *playing_entry;
RBSource *source;
gboolean update_stats;
+ gboolean dragging;
source = player->priv->current_playing_source;
@@ -806,6 +814,14 @@
return;
}
+ /* defer EOS handling while the position slider is being dragged */
+ g_object_get (player->priv->header_widget, "slider-dragging", &dragging, NULL);
+ if (dragging) {
+ rb_debug ("slider is dragging, will handle EOS (if applicable) on release");
+ player->priv->playing_entry_eos = TRUE;
+ return;
+ }
+
update_stats = FALSE;
switch (rb_source_handle_eos (source)) {
case RB_SOURCE_EOF_ERROR:
@@ -891,6 +907,22 @@
}
static void
+rb_shell_player_slider_dragging_cb (GObject *header, GParamSpec *pspec, RBShellPlayer *player)
+{
+ gboolean drag;
+
+ g_object_get (player->priv->header_widget, "slider-dragging", &drag, NULL);
+ rb_debug ("slider dragging? %d", drag);
+
+ /* if an EOS occurred while dragging, process it now */
+ if (drag == FALSE && player->priv->playing_entry_eos) {
+ rb_debug ("processing EOS delayed due to slider dragging");
+ player->priv->playing_entry_eos = FALSE;
+ rb_shell_player_handle_eos_unlocked (player, rb_shell_player_get_playing_entry (player), FALSE);
+ }
+}
+
+static void
rb_shell_player_handle_eos (RBPlayer *player,
RhythmDBEntry *entry,
RBShellPlayer *shell_player)
@@ -3308,6 +3340,10 @@
GError **error)
{
if (rb_player_seekable (player->priv->mmplayer)) {
+ if (player->priv->playing_entry_eos) {
+ rb_debug ("forgetting that playing entry had EOS'd due to seek");
+ player->priv->playing_entry_eos = FALSE;
+ }
rb_player_set_time (player->priv->mmplayer, (long) time);
return TRUE;
} else {
@@ -3589,7 +3625,7 @@
duration,
duration_from_player);
- if (rb_player_playing (mmplayer)) {
+ if (TRUE /* rb_player_playing (mmplayer)*/) { /* why do we care whether it's playing or not? */
if (elapsed < 0)
elapsed = 0;
Modified: trunk/widgets/rb-header.c
==============================================================================
--- trunk/widgets/rb-header.c (original)
+++ trunk/widgets/rb-header.c Sat Jun 28 04:30:56 2008
@@ -74,6 +74,7 @@
static void rb_header_set_show_timeline (RBHeader *header,
gboolean show);
static void rb_header_update_elapsed (RBHeader *header);
+static void apply_slider_position (RBHeader *header);
static gboolean slider_press_callback (GtkWidget *widget, GdkEventButton *event, RBHeader *header);
static gboolean slider_moved_callback (GtkWidget *widget, GdkEventMotion *event, RBHeader *header);
static gboolean slider_release_callback (GtkWidget *widget, GdkEventButton *event, RBHeader *header);
@@ -101,7 +102,6 @@
gboolean slider_locked;
guint slider_moved_timeout;
long latest_set_time;
- guint value_changed_update_handler;
GtkWidget *elapsed;
guint elapsed_time;
@@ -116,6 +116,7 @@
PROP_SHELL_PLAYER,
PROP_ENTRY,
PROP_SEEKABLE,
+ PROP_SLIDER_DRAGGING
};
#define TITLE_MARKUP(xTITLE) g_markup_printf_escaped ("<big><b>%s</b></big>", xTITLE)
@@ -185,6 +186,19 @@
TRUE,
G_PARAM_READWRITE));
+ /**
+ * RBHeader:slider-dragging:
+ *
+ * Whether the song position slider is currently being dragged.
+ */
+ g_object_class_install_property (object_class,
+ PROP_SLIDER_DRAGGING,
+ g_param_spec_boolean ("slider-dragging",
+ "slider dragging",
+ "slider dragging",
+ FALSE,
+ G_PARAM_READABLE));
+
g_type_class_add_private (klass, sizeof (RBHeaderPrivate));
}
@@ -277,6 +291,24 @@
}
static void
+rb_header_set_playing_entry_internal (RBHeader *header, RhythmDBEntry *entry)
+{
+ if (header->priv->entry == entry)
+ return;
+
+ header->priv->entry = entry;
+ if (header->priv->entry) {
+ header->priv->duration = rhythmdb_entry_get_ulong (header->priv->entry,
+ RHYTHMDB_PROP_DURATION);
+ } else {
+ header->priv->duration = 0;
+ }
+
+ header->priv->adjustment->upper = header->priv->duration;
+ gtk_adjustment_changed (header->priv->adjustment);
+}
+
+static void
rb_header_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -289,13 +321,7 @@
header->priv->db = g_value_get_object (value);
break;
case PROP_ENTRY:
- header->priv->entry = g_value_get_boxed (value);
- if (header->priv->entry) {
- header->priv->duration = rhythmdb_entry_get_ulong (header->priv->entry,
- RHYTHMDB_PROP_DURATION);
- } else {
- header->priv->duration = 0;
- }
+ rb_header_set_playing_entry_internal (header, g_value_get_boxed (value));
break;
case PROP_SHELL_PLAYER:
header->priv->shell_player = g_value_get_object (value);
@@ -334,6 +360,9 @@
case PROP_SEEKABLE:
g_value_set_boolean (value, header->priv->seekable);
break;
+ case PROP_SLIDER_DRAGGING:
+ g_value_set_boolean (value, header->priv->slider_dragging);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -415,8 +444,12 @@
rb_header_sync (RBHeader *header)
{
char *label_text;
+ const char *location = "<null>";
- rb_debug ("syncing with entry = %p", header->priv->entry);
+ if (header->priv->entry != NULL) {
+ location = rhythmdb_entry_get_string (header->priv->entry, RHYTHMDB_PROP_LOCATION);
+ }
+ rb_debug ("syncing with entry = %s", location);
if (header->priv->entry != NULL) {
const char *title;
@@ -566,14 +599,7 @@
seconds = header->priv->elapsed_time;
if (header->priv->duration > 0) {
- double progress = 0.0;
-
- if (seconds > 0) {
- progress = (double) seconds;
- } else {
- header->priv->adjustment->upper = header->priv->duration;
- g_signal_emit_by_name (G_OBJECT (header->priv->adjustment), "changed");
- }
+ double progress = (double) seconds;
header->priv->slider_locked = TRUE;
gtk_adjustment_set_value (header->priv->adjustment, progress);
@@ -596,24 +622,25 @@
{
header->priv->slider_dragging = TRUE;
header->priv->latest_set_time = -1;
+ g_object_notify (G_OBJECT (header), "slider-dragging");
+
+ /* HACK: we want the behaviour you get with the middle button, so we
+ * mangle the event. clicking with other buttons moves the slider in
+ * step increments, clicking with the middle button moves the slider to
+ * the location of the click.
+ */
+ event->button = 2;
+
+
return FALSE;
}
static gboolean
slider_moved_timeout (RBHeader *header)
{
- double progress;
- long new;
-
GDK_THREADS_ENTER ();
- progress = gtk_adjustment_get_value (gtk_range_get_adjustment (GTK_RANGE (header->priv->scale)));
- new = (long) (progress+0.5);
-
- rb_debug ("setting time to %ld", new);
- rb_shell_player_set_playing_time (header->priv->shell_player, new, NULL);
-
- header->priv->latest_set_time = new;
+ apply_slider_position (header);
header->priv->slider_moved_timeout = 0;
GDK_THREADS_LEAVE ();
@@ -626,7 +653,6 @@
GdkEventMotion *event,
RBHeader *header)
{
- GtkAdjustment *adjustment;
double progress;
if (header->priv->slider_dragging == FALSE) {
@@ -634,9 +660,7 @@
return FALSE;
}
- adjustment = gtk_range_get_adjustment (GTK_RANGE (widget));
-
- progress = gtk_adjustment_get_value (adjustment);
+ progress = gtk_adjustment_get_value (header->priv->adjustment);
header->priv->elapsed_time = (guint) (progress+0.5);
rb_header_update_elapsed (header);
@@ -652,52 +676,43 @@
return FALSE;
}
-static gboolean
-slider_release_callback (GtkWidget *widget,
- GdkEventButton *event,
- RBHeader *header)
+static void
+apply_slider_position (RBHeader *header)
{
double progress;
long new;
- GtkAdjustment *adjustment;
-
- if (header->priv->slider_dragging == FALSE) {
- rb_debug ("slider is not dragging");
- return FALSE;
- }
-
- adjustment = gtk_range_get_adjustment (GTK_RANGE (widget));
- progress = gtk_adjustment_get_value (adjustment);
+ progress = gtk_adjustment_get_value (header->priv->adjustment);
new = (long) (progress+0.5);
if (new != header->priv->latest_set_time) {
rb_debug ("setting time to %ld", new);
rb_shell_player_set_playing_time (header->priv->shell_player, new, NULL);
+ header->priv->latest_set_time = new;
}
-
- header->priv->slider_dragging = FALSE;
-
- if (header->priv->slider_moved_timeout != 0) {
- g_source_remove (header->priv->slider_moved_timeout);
- header->priv->slider_moved_timeout = 0;
- }
-
- return FALSE;
}
static gboolean
-changed_idle_callback (RBHeader *header)
+slider_release_callback (GtkWidget *widget,
+ GdkEventButton *event,
+ RBHeader *header)
{
- GDK_THREADS_ENTER ();
+ /* HACK: see slider_press_callback */
+ event->button = 2;
- slider_release_callback (header->priv->scale, NULL, header);
-
- header->priv->value_changed_update_handler = 0;
- rb_debug ("in changed_idle_callback");
+ if (header->priv->slider_dragging == FALSE) {
+ rb_debug ("slider is not dragging");
+ return FALSE;
+ }
- GDK_THREADS_LEAVE ();
+ if (header->priv->slider_moved_timeout != 0) {
+ g_source_remove (header->priv->slider_moved_timeout);
+ header->priv->slider_moved_timeout = 0;
+ }
+ apply_slider_position (header);
+ header->priv->slider_dragging = FALSE;
+ g_object_notify (G_OBJECT (header), "slider-dragging");
return FALSE;
}
@@ -705,12 +720,13 @@
slider_changed_callback (GtkWidget *widget,
RBHeader *header)
{
+ /* if the slider isn't being dragged, and nothing else is happening,
+ * this indicates the position was adjusted with a keypress (page up/page down etc.),
+ * so we should directly apply the change.
+ */
if (header->priv->slider_dragging == FALSE &&
- header->priv->slider_locked == FALSE &&
- header->priv->value_changed_update_handler == 0) {
- header->priv->slider_dragging = TRUE;
- header->priv->value_changed_update_handler =
- g_idle_add ((GSourceFunc) changed_idle_callback, header);
+ header->priv->slider_locked == FALSE) {
+ apply_slider_position (header);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]