[vlc-commits] [Git][videolan/vlc][master] 3 commits: qt: introduce `PlayerHighResolutionTimeUpdater`

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Fri May 29 09:46:29 UTC 2026



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
3441d327 by Fatih Uzunoglu at 2026-05-29T11:07:59+02:00
qt: introduce `PlayerHighResolutionTimeUpdater`

- - - - -
490219dc by Fatih Uzunoglu at 2026-05-29T11:07:59+02:00
qt: register qml type `PlayerHighResolutionTimeUpdater`

- - - - -
860c6bbd by Fatih Uzunoglu at 2026-05-29T11:07:59+02:00
qml: use `PlayerHighResolutionTimeUpdater` in `HighResolutionTimeWidget`

This moves sampling from JS to C++.

- - - - -


3 changed files:

- modules/gui/qt/maininterface/mainui.cpp
- modules/gui/qt/player/player_controller.hpp
- modules/gui/qt/player/qml/controlbarcontrols/HighResolutionTimeWidget.qml


Changes:

=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -290,6 +290,7 @@ void MainUI::registerQMLTypes()
         qmlRegisterUncreatableType<ProgramListModel>(uri, versionMajor, versionMinor, "ProgramListModel", "available programs of a media" );
         assert(m_intf->p_mainPlayerController);
         qmlRegisterSingletonInstance<PlayerController>(uri, versionMajor, versionMinor, "Player", m_intf->p_mainPlayerController);
+        qmlRegisterType<PlayerHighResolutionTimeUpdater>(uri, versionMajor, versionMinor, "HighResolutionTimeUpdater");
 
         qmlRegisterType<QmlBookmarkMenu>( uri, versionMajor, versionMinor, "QmlBookmarkMenu" );
         qmlRegisterType<QmlProgramMenu>( uri, versionMajor, versionMinor, "QmlProgramMenu" );


=====================================
modules/gui/qt/player/player_controller.hpp
=====================================
@@ -29,6 +29,10 @@
 #include <QEvent>
 #include <QScopedPointer>
 #include <QUrl>
+#include <QPointer>
+#include <QQuickWindow>
+#include <QQuickItem>
+#include <QQmlProperty>
 #include "player/input_models.hpp"
 #include "util/audio_device_model.hpp"
 #include "util/varchoicemodel.hpp"
@@ -489,4 +493,93 @@ private:
     QScopedPointer<PlayerControllerPrivate> d_ptr;
 };
 
+
+// This class updates the target property per frame with the return
+// value of `PlayerController::highResolutionTime()`. In order to disable
+// updating, set `window` property to null.
+class PlayerHighResolutionTimeUpdater : public QObject, public QQmlPropertyValueSource
+{
+    Q_OBJECT
+    Q_INTERFACES(QQmlPropertyValueSource)
+
+    Q_PROPERTY(PlayerController* playerController MEMBER m_playerController NOTIFY playerControllerChanged FINAL)
+    Q_PROPERTY(QQuickWindow* window MEMBER m_window WRITE setWindow NOTIFY windowChanged FINAL)
+    Q_PROPERTY(bool constantUpdates MEMBER m_constantUpdates NOTIFY constantUpdatesChanged FINAL)
+
+    QML_ELEMENT
+
+public:
+    explicit PlayerHighResolutionTimeUpdater(QObject *parent = nullptr)
+        : QObject(parent)
+    {
+
+    }
+
+    void setWindow(QQuickWindow* window)
+    {
+        if (m_window == window)
+            return;
+
+        if (m_window)
+            disconnect(m_window, nullptr, this, nullptr);
+
+        m_window = window;
+
+        if (m_window)
+            connect(m_window, &QQuickWindow::afterAnimating, this, &PlayerHighResolutionTimeUpdater::update); // emitted from GUI thread
+
+        emit windowChanged();
+    }
+
+    void setTarget(const QQmlProperty &prop) override
+    {
+        m_item = qobject_cast<QQuickItem*>(prop.object());
+        assert(m_item);
+        m_property = prop;
+        assert(prop.isValid() && (prop.propertyType() == QMetaType::QString) && prop.isWritable());
+    }
+
+public slots:
+    bool update()
+    {
+        if (!m_item || !m_playerController)
+            return false;
+
+        // Constantly update the item, so that the window
+        // prepares new frames and we make sure that this
+        // function is also called in the very next frame.
+        // This is similar to animations:
+        if (m_constantUpdates)
+            m_item->update();
+
+        // Sample the high resolution time:
+        const QString hrt = m_playerController->highResolutionTime();
+
+        if (!m_property.write(hrt))
+            return false;
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
+        // Item would like re-polishing after value change.
+        // We should have this because `afterAnimating()` is
+        // signalled after the items are polished. This may
+        // not be necessary, but it is better to have it:
+        m_item->ensurePolished();
+#endif
+
+        return true;
+    }
+
+signals:
+    void playerControllerChanged();
+    void windowChanged();
+    void constantUpdatesChanged();
+
+private:
+    QPointer<PlayerController> m_playerController;
+    QPointer<QQuickWindow> m_window;
+    QPointer<QQuickItem> m_item;
+    QQmlProperty m_property;
+    bool m_constantUpdates = true;
+};
+
 #endif


=====================================
modules/gui/qt/player/qml/controlbarcontrols/HighResolutionTimeWidget.qml
=====================================
@@ -89,30 +89,10 @@ Control {
 
             property string timeText
 
-            Connections {
-                target: label.Window.window
-                enabled: label.visible
-
-                function onAfterAnimating() {
-                    // Sampling point
-                    // Emitted from the GUI thread
-
-                    // Constantly update the label, so that the window
-                    // prepares new frames as we don't know when the
-                    // timecode changes. This is similar to animations:
-                    label.update()
-
-                    if (label.timeText === Player.highResolutionTime)
-                        return
-
-                    label.timeText = Player.highResolutionTime
-
-                    // Text would like polishing after text change.
-                    // We need this because `afterAnimating()` is
-                    // signalled after the items are polished:
-                    if (label.ensurePolished)
-                        label.ensurePolished()
-                }
+            HighResolutionTimeUpdater on timeText {
+                window: (label.visible && Player.isStarted && !highResolutionTimeWidget.paintOnly) ? label.Window.window
+                                                                                                   : null
+                playerController: Player
             }
         }
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/44246eed7bed3bbad1a35edfdf208f7050736e2a...860c6bbdb35a4d4d0dfcc1fd38dc8726e9715f3e

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/44246eed7bed3bbad1a35edfdf208f7050736e2a...860c6bbdb35a4d4d0dfcc1fd38dc8726e9715f3e
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list