[pitivi] timeline: Fix scrollToPlayhead



commit e670184cc69223355bdc487cd1ecf89f87e7a15c
Author: Alexandru Băluț <alexandru balut gmail com>
Date:   Thu Apr 18 03:17:30 2019 +0200

    timeline: Fix scrollToPlayhead
    
    The logic in the scrollToPlayhead is good, but it acts on obsolete data.
    The fix consists in delaying the scroll until the data is available,
    which is when the layers box is allocated a size.
    
    Fixes #2184

 pitivi/timeline/timeline.py | 26 ++++++++++++++++++++++++--
 pitivi/utils/widgets.py     | 10 ++++++----
 2 files changed, 30 insertions(+), 6 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 56727740..11054e04 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -191,6 +191,9 @@ class Marquee(Gtk.Box, Loggable):
 class LayersLayout(Gtk.Layout, Zoomable, Loggable):
     """Layout for displaying scrollable layers, the playhead, snap indicator.
 
+    The layers are actual widgets in a vertical Gtk.Box.
+    The playhead and the snap indicator are drawn on top in do_draw().
+
     Args:
         timeline (Timeline): The timeline indirectly containing the layout.
 
@@ -357,6 +360,9 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         self.__last_position = 0
         self._scrubbing = False
         self._scrolling = False
+        # The parameters for the delayed scroll to be performed after
+        # the layers box is allocated a size.
+        self.delayed_scroll = {}
         self.__next_seek_position = None
 
         # Clip selection.
@@ -414,6 +420,13 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         self.app.settings.connect("edgeSnapDeadbandChanged",
                                   self.__snap_distance_changed_cb)
 
+        self.layout.layers_vbox.connect_after("size-allocate", self.__size_allocate_cb)
+
+    def __size_allocate_cb(self, unused_widget, unused_allocation):
+        """Handles the layers vbox size allocations."""
+        if self.delayed_scroll:
+            self.scrollToPlayhead(**self.delayed_scroll)
+
     @property
     def media_types(self):
         """Gets the media types present in the layers.
@@ -492,7 +505,7 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
     def _durationChangedCb(self, ges_timeline, pspec):
         self.layout.update_width()
 
-    def scrollToPlayhead(self, align=None, when_not_in_view=False):
+    def scrollToPlayhead(self, align=None, when_not_in_view=False, delayed=False):
         """Scrolls so that the playhead is in view.
 
         Args:
@@ -500,8 +513,17 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
                 post-scroll.
             when_not_in_view (Optional[bool]): When True, scrolls only if
                 the playhead is not in view.
+            delayed (Optional[bool]): When True, the scroll will be done only
+                after the layers box size allocation is updated.
         """
-        self.debug("Scrolling to playhead")
+        self.debug("Scrolling to playhead, delayed=%s", delayed)
+        if delayed:
+            self.delayed_scroll = {"align": align, "when_not_in_view": when_not_in_view}
+            return
+
+        # If a scroll is forced, forget about the delayed scroll, if any.
+        self.delayed_scroll = {}
+
         layout_width = self.layout.get_allocation().width
         if when_not_in_view:
             x = self.nsToPixel(self.__last_position) - self.hadj.get_value()
diff --git a/pitivi/utils/widgets.py b/pitivi/utils/widgets.py
index 3d916f4e..c80b62d3 100644
--- a/pitivi/utils/widgets.py
+++ b/pitivi/utils/widgets.py
@@ -1272,8 +1272,8 @@ class ZoomBox(Gtk.Grid, Zoomable):
                                        level=adjustment.get_value(),
                                        optional_action_type=True)
 
-        if self._manual_set is False:
-            self.timeline.timeline.scrollToPlayhead()
+        if not self._manual_set:
+            self.timeline.timeline.scrollToPlayhead(delayed=True)
 
     def _zoomFitCb(self, unused_button):
         self.timeline.timeline.set_best_zoom_ratio(allow_zoom_in=True)
@@ -1297,8 +1297,10 @@ class ZoomBox(Gtk.Grid, Zoomable):
         zoomLevel = self.getCurrentZoomLevel()
         if int(self._zoomAdjustment.get_value()) != zoomLevel:
             self._manual_set = True
-            self._zoomAdjustment.set_value(zoomLevel)
-            self._manual_set = False
+            try:
+                self._zoomAdjustment.set_value(zoomLevel)
+            finally:
+                self._manual_set = False
 
     def _sliderTooltipCb(self, unused_slider, unused_x, unused_y, unused_keyboard_mode, tooltip):
         # We assume the width of the ruler is exactly the width of the


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]