After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 772628 - Make progress scale move smoothly
Make progress scale move smoothly
Status: RESOLVED FIXED
Product: gnome-music
Classification: Applications
Component: general
unspecified
Other All
: Normal enhancement
: ---
Assigned To: gnome-music-maint
gnome-music-maint
Depends on:
Blocks:
 
 
Reported: 2016-10-08 20:59 UTC by Clayton G. Hobbs
Modified: 2016-11-21 14:37 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch to make the progress scale move smoothly (4.83 KB, patch)
2016-10-08 20:59 UTC, Clayton G. Hobbs
needs-work Details | Review
player: Make progress scale move smoothly (7.21 KB, patch)
2016-10-11 21:08 UTC, Clayton G. Hobbs
none Details | Review
player: Make progress scale move smoothly (7.08 KB, patch)
2016-11-12 03:56 UTC, Clayton G. Hobbs
none Details | Review
player: Make progress scale move smoothly (7.77 KB, patch)
2016-11-14 01:09 UTC, Clayton G. Hobbs
committed Details | Review

Description Clayton G. Hobbs 2016-10-08 20:59:42 UTC
Created attachment 337255 [details] [review]
Patch to make the progress scale move smoothly

The progress scale currently updates once every second, which doesn't look
very nice when shorter songs are playing.  This patch makes it update
once per second, or once per amount of time represented by one pixel of
the scale, whichever is shorter.  This makes the slider move smoothly
from left to right regardless the length of the song being played.

The update period is always rounded down to 1/n seconds, where n is an
integer, to ensure that the seconds shown on the song playback time
label always tick smoothly at 1 Hz.  (Had it been able to be, say,
2/3 s, the label would be "0:01" for 2/3 s, then "0:02" for 4/3 s, and
so on.  In testing, this made Music look very nervous.)
Comment 1 Marinus Schraal 2016-10-10 21:20:04 UTC
Review of attachment 337255 [details] [review]:

Thanks for the patch. The code quality is good except for some minor nitpicks.

The only issue I'm having is that in some testing I can see the slider stutter slightly, like its waiting slightly longer every few ticks. And I had one crash tracing back to this patch (I didn't copy the trace -  my bad). I'll try and get some more substantial feedback.

A tick per second may not be smooth, but at least it is reliable and predictable, this patch needs to be as good or even better to be viable.

::: gnomemusic/player.py
@@ +876,3 @@
+        width = self.progressScale.get_allocated_width()
+        duration = self.get_current_media().get_duration()
+        self.timeout_period = min(1000//math.ceil(width/duration), 1000)

pep8 spacing please

@@ +976,3 @@
         if position > 0:
             self.progressScale.set_value(position * 60)
+            self.played_seconds += self.timeout_period/1000

spacing
Comment 2 Marinus Schraal 2016-10-10 21:32:04 UTC
Another issue I noticed is that when hovering over the slider dragpoint, it actually stops moving until you stop moving the mouse/touchpad resulting in heavy stutter.

I'm not sure of the reason, maybe b/c the patch disconnects the size-allocate signal at times?
Comment 3 Clayton G. Hobbs 2016-10-10 22:04:19 UTC
Thanks for reviewing this.  I took a look at the problems you noted, and I must admit I'm puzzled by the last one.  It doesn't seem to be because of disconnecting size-allocate, as removing the code to disable it doesn't fix the problem.  I'll try removing other parts of the patch to isolate the problem.

The slight stuttering might be simply an artifact of the tick rate not being an exact multiple of the time of one pixel, making it occasionally not move after one tick.  It could probably be fixed by making the scale update independently from the playback time label, allowing the scale to update at the correct rate without making the label update wrong.

I haven't experienced any crashes from this myself, but if I get one I'll post the trace.
Comment 4 Clayton G. Hobbs 2016-10-11 21:00:42 UTC
I found one crash, which may or may not be the one you mentioned.  When playing a song from the favorites playlist, if the current song is removed from the favorites, the patch caused the following crash:

Traceback (most recent call last):
  • File "/home/clay/jhbuild/install/lib/python3.5/site-packages/gnomemusic/player.py", line 864 in _on_progress_size_allocate
    self.update_timeout()
  • File "/home/clay/jhbuild/install/lib/python3.5/site-packages/gnomemusic/player.py", line 876 in update_timeout
    duration = self.get_current_media().get_duration()
AttributeError: 'NoneType' object has no attribute 'get_duration'

I'll submit another patch momentarily that, among other things, gets the duration of the current song from Player.player rather than Player.get_current_media(), fixing this crash.
Comment 5 Clayton G. Hobbs 2016-10-11 21:08:03 UTC
Created attachment 337468 [details] [review]
player: Make progress scale move smoothly

The progress scale used to update once every second, which didn't look
very nice when shorter songs were playing.  This patch makes it update
once per second, or once per amount of time represented by one pixel of
the scale, whichever is shorter.  This makes the slider move smoothly
from left to right regardless the length of the song being played.  The
song position label updates once per second and every time the slider
moves, making it tick smoothly and update quickly when the user drags
the slider.

This fixes the problems pointed out by Marinus Schraal in the previous
patch: moving the cursor over the scale no longer freezes the scale,
and the slider moves more evenly as well.
Comment 6 Marinus Schraal 2016-11-03 07:52:16 UTC
Review of attachment 337468 [details] [review]:

Looks ok to me, some small issues left.

Regarding the git comment: keep it just about the issue (short 'n sweet), not the road to getting there (the bug is reference for that).

::: gnomemusic/player.py
@@ +80,3 @@
     nextTrack = None
     timeout = None
+    seconds_timeout = None

this is an internal state var, so prepend with _

See README, the last bit.

@@ +844,3 @@
+        return False
+
+    def update_timeout(self):

internal

@@ +859,3 @@
+        # starts moving.
+        if width == 1:
+            width = self._parent_window.get_allocated_width()

Is this really needed, when should I see this?

@@ +882,3 @@
+            self.seconds_timeout = None
+
+    def progress_scale_zero(self):

this should be marked as an internal function (prepend with _)

@@ +985,3 @@
+        self._on_progress_value_changed(None)
+
+        position = self.player.query_position(Gst.Format.TIME)[1] / 1000000000

Maybe use 10**9 here, a long line of zeros is unreadable.
Comment 7 Clayton G. Hobbs 2016-11-12 03:49:13 UTC
Thanks for the review, again.  I'll add a new patch momentarily fixing the issues you pointed out.

@@ +859,3 @@
+        # starts moving.
+        if width == 1:
+            width = self._parent_window.get_allocated_width()

This really is needed, so I'll change the comment before it to explain a bit better.  When that function is first run (i.e. when playing the first song after starting Music), the scale doesn't have the correct area yet.  Without this block, the timeout_period calculation would cause the slider to stay still for one second even if it really shouldn't.  Using the window's width makes the timeout_period somewhat less than it should be, which keeps the slider moving smoothly and gets fixed the next time it moves.
Comment 8 Clayton G. Hobbs 2016-11-12 03:56:43 UTC
Created attachment 339677 [details] [review]
player: Make progress scale move smoothly

The progress scale used to update once every second, which didn't look
very nice when shorter songs were playing.  This patch makes it update
once per second, or once per amount of time represented by one pixel of
the scale, whichever is shorter.  This makes the slider move smoothly
from left to right regardless the length of the song being played.  The
song position label updates once per second and every time the slider
moves, making it tick smoothly and update quickly when the user drags
the slider.
Comment 9 Marinus Schraal 2016-11-13 01:14:34 UTC
(In reply to Clayton G. Hobbs from comment #7)
> @@ +859,3 @@
> +        # starts moving.
> +        if width == 1:
> +            width = self._parent_window.get_allocated_width()
> 
> This really is needed, so I'll change the comment before it to explain a bit
<snip>

Ok, I can see what you mean now, but getting the parents width is not really correct either.

I'm not sure I like that much better than having a (near unnoticeable) stutter at the start of the first song.

I wonder where it comes from anyway, the widget is already realized, so the size should be available.

And this is not the actual size of the sliderbar itself (that one should be slightly smaller with some padding involved).
Comment 10 Clayton G. Hobbs 2016-11-14 01:09:41 UTC
Created attachment 339776 [details] [review]
player: Make progress scale move smoothly

Thinking about what you said, I decided to look into this further and fix the `width == 1` hack.  It turns out the scale really hadn't been realized yet, which was causing the problem.  Some defensive coding to make sure _update_timeout isn't run when progressScale hasn't been realized, plus a signal handler to make sure _update_timeout is run the first time progressScale is drawn, fixed the problem entirely.

While I was at it, I also corrected the width calculation to subtract the scale's left and right padding.
Comment 11 Marinus Schraal 2016-11-21 14:37:37 UTC
Nothing much left to fault here, thanks for the work.

Attachment 339776 [details] pushed as d72c2d4 - player: Make progress scale move smoothly