[vlc-commits] [Git][videolan/vlc][master] 6 commits: qt: do not signal current item change unnecessarily in `PlaylistController`

Steve Lhomme (@robUx4) gitlab at videolan.org
Sun Nov 16 02:11:21 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
776121f3 by Fatih Uzunoglu at 2025-11-16T01:54:29+00:00
qt: do not signal current item change unnecessarily in `PlaylistController`

If the new current item is the same, there is no need to signal current
item change.

- - - - -
c8a187b4 by Fatih Uzunoglu at 2025-11-16T01:54:29+00:00
qml: introduce `excludeItem` in `FadingEdgeForListView`

- - - - -
ef6bf307 by Fatih Uzunoglu at 2025-11-16T01:54:29+00:00
qml: do not call `itemIntersects()` if not necessary in `FadingEdgeForListView`

- - - - -
45175b6f by Fatih Uzunoglu at 2025-11-16T01:54:29+00:00
qml: disable fading edge effect if playlist current item overlaps

- - - - -
40f0faf2 by Fatih Uzunoglu at 2025-11-16T01:54:29+00:00
qml: do not track current index change in playlist list view

Current index of the view and the current index of the
playlist are not a one-to-one match.

The view, when applicable, may track the playlist
current index. However, when the view current index
changes, such as due to keyboard navigation, it is
fair that the view current index deviates from the
playlist current index. It is also fair to not
change the current index of the view at all, but
rather make the new playlist current item visible,
which is what is the case with this patch.

This fixes the situation of the view scrolling
unwantedly when, for example, playlist current index
changes due to adding or removing items preceding to
the playlist current item while the current item
remains the same.

- - - - -
81191b4c by Fatih Uzunoglu at 2025-11-16T01:54:29+00:00
qml: animate positioning on playlist current item change in `PlaylistPane`

- - - - -


3 changed files:

- modules/gui/qt/playlist/playlist_controller.cpp
- modules/gui/qt/playlist/qml/PlaylistPane.qml
- modules/gui/qt/widgets/qml/FadingEdgeForListView.qml


Changes:

=====================================
modules/gui/qt/playlist/playlist_controller.cpp
=====================================
@@ -220,8 +220,13 @@ on_playlist_items_updated(vlc_playlist_t *playlist, size_t index,
             size_t currentIndex = static_cast<size_t>(that->m_currentIndex);
             if (currentIndex >= index && currentIndex < index + len)
             {
-                that->m_currentItem = vec[currentIndex - index];
-                emit that->q_func()->currentItemChanged();
+                const auto newCurrentItem = vec[currentIndex - index];
+                const auto currentItem = that->m_currentItem.raw();
+                // Even if vlc_playlist_item_t is the same, assign unconditionally to
+                // update the data:
+                that->m_currentItem = newCurrentItem;
+                if (currentItem != newCurrentItem.raw())
+                    emit that->q_func()->currentItemChanged();
             }
         }
     });


=====================================
modules/gui/qt/playlist/qml/PlaylistPane.qml
=====================================
@@ -269,8 +269,36 @@ T.Pane {
                 contextMenu.popup(-1, globalPos)
             }
 
+            Behavior on contentY {
+                id: contentYBehavior
+
+                enabled: false
+
+                // NOTE: Usage of `SmoothedAnimation` is intentional here.
+                SmoothedAnimation {
+                    duration: VLCStyle.duration_veryLong
+                    easing.type: Easing.InOutSine
+                }
+            }
+
             Component.onCompleted: {
-                MainPlaylistController.currentIndexChanged.connect(listView, (index) => { listView.currentIndex = index })
+                // WARNING: Tracking the current item and not the current index is intentional here.
+                MainPlaylistController.currentItemChanged.connect(listView, () => {
+                    // FIXME: Qt does not provide the `contentY` with `positionViewAtIndex()` for us
+                    //        to animate. For that reason, we capture the new `contentY`, adjust
+                    //        `contentY` to it is old value then enable the animation and set `contentY`
+                    //        to its new value.
+                    const oldContentY = listView.contentY
+                    listView.positionViewAtIndex(MainPlaylistController.currentIndex, ListView.Contain)
+                    const newContentY = listView.contentY
+                    if (Math.abs(oldContentY - newContentY) >= Number.EPSILON) {
+                        contentYBehavior.enabled = false
+                        listView.contentY = oldContentY
+                        contentYBehavior.enabled = true
+                        listView.contentY = newContentY
+                        contentYBehavior.enabled = false
+                    }
+                })
             }
 
             Connections {
@@ -301,6 +329,13 @@ T.Pane {
                 acceptDrop: listView.acceptDropFunc
 
                 onContainsDragChanged: listView.updateItemContainsDrag(this, containsDrag)
+
+                onIsCurrentChanged: {
+                    if (isCurrent)
+                        listView.fadingEdge.excludeItem = delegate
+                    else if (listView.fadingEdge.excludeItem === delegate)
+                        listView.fadingEdge.excludeItem = null
+                }
             }
 
             Keys.onDeletePressed: model.removeItems(selectionModel.selectedIndexesFlat)


=====================================
modules/gui/qt/widgets/qml/FadingEdgeForListView.qml
=====================================
@@ -25,6 +25,13 @@ FadingEdge {
 
     required property ListView listView
 
+    // NOTE: In addition to the `currentItem`, `excludeItem`
+    //       may be used to direct the fading edge effect to
+    //       disable the effect if fade region overlaps with
+    //       the `excludeItem`. The behavior is undefined if
+    //       `excludeItem` is not a visual child of `sourceItem`.
+    property Item excludeItem
+
     sourceItem: listView.contentItem
 
     beginningMargin: listView.displayMarginBeginning
@@ -60,17 +67,25 @@ FadingEdge {
                                                                                   listView.currentItem.height)
                                                                         : Qt.rect(-1, -1, -1, -1)
 
+    readonly property rect _excludeItemMappedRect: excludeItem ? Qt.rect(excludeItem.x - sourceX,
+                                                                         excludeItem.y - sourceY,
+                                                                         excludeItem.width,
+                                                                         excludeItem.height)
+                                                                        : Qt.rect(-1, -1, -1, -1)
+
     readonly property bool _disableBeginningFade: (!!listView.headerItem && (listView.headerPositioning !== ListView.InlineHeader)) ||
                                                   !_fadeRectEnoughSize ||
                                                   (orientation === Qt.Vertical ? listView.atYBeginning
                                                                                : listView.atXBeginning) ||
-                                                  !Helpers.itemIntersects(beginningArea, _currentItemMappedRect)
+                                                  (currentItem && !Helpers.itemIntersects(beginningArea, _currentItemMappedRect)) ||
+                                                  (excludeItem && !Helpers.itemIntersects(beginningArea, _excludeItemMappedRect))
 
     readonly property bool _disableEndFade: (!!listView.footerItem && (listView.footerPositioning !== ListView.InlineFooter)) ||
                                             !_fadeRectEnoughSize ||
                                             (orientation === Qt.Vertical ? listView.atYEnd
                                                                          : listView.atXEnd) ||
-                                            !Helpers.itemIntersects(endArea, _currentItemMappedRect)
+                                            (currentItem && !Helpers.itemIntersects(endArea, _currentItemMappedRect)) ||
+                                            (excludeItem && !Helpers.itemIntersects(endArea, _excludeItemMappedRect))
 
     Binding on enableBeginningFade {
         // This explicit binding is to override `enableBeginningFade` when it is not feasible to have fading edge.



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6aab1e0b2b25971eb2e217c93b68a5ca831f5334...81191b4c5eaba0f5158d9f6400810db1622052e3

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6aab1e0b2b25971eb2e217c93b68a5ca831f5334...81191b4c5eaba0f5158d9f6400810db1622052e3
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list