diff --git a/CMakeLists.txt b/CMakeLists.txt
index 46431f2212f9f392b72f95f4e264682c5739751e..017fdb359e34ef0176e0aa14b48b3711be12d000 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,8 +31,11 @@ set(CMAKE_AUTORCC ON)
 set(THREADS_PREFER_PTHREAD_FLAG ON)
 
 # Find Qt dependencies
-find_package(QT NAMES Qt6 Qt5      COMPONENTS Widgets Core REQUIRED)
-find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Core REQUIRED)
+find_package(Qt6 REQUIRED COMPONENTS
+    Widgets
+    OpenGL
+    OpenGLWidgets
+)
 
 # Find others dependencies
 find_library(AVCODEC_LIBRARY    avcodec     4.0 REQUIRED)
@@ -50,23 +53,17 @@ endif()
 set(PROJECT_SOURCES ${Vivy_SRC} ${Vivy_INC} ${Vivy_APPLE_SRC})
 
 # Add the Vivy executable
-if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
-    qt_add_executable(Vivy
-        MANUAL_FINALIZATION
-        ${PROJECT_SOURCES}
-        rsc/VivyRessources.qrc
-    )
-else()
-    add_executable(Vivy
-        ${PROJECT_SOURCES}
-        rsc/VivyRessources.qrc
-    )
-endif()
+qt_add_executable(Vivy
+    MANUAL_FINALIZATION
+    ${PROJECT_SOURCES}
+    rsc/VivyRessources.qrc
+)
 
 # Link dependencies to Vivy
 target_link_libraries(Vivy PRIVATE
-    Qt${QT_VERSION_MAJOR}::Widgets
-    Qt${QT_VERSION_MAJOR}::Core
+    Qt6::Widgets
+    Qt6::OpenGL
+    Qt6::OpenGLWidgets
 )
 target_link_libraries(Vivy PRIVATE ${AVCODEC_LIBRARY})
 target_link_libraries(Vivy PRIVATE ${AVUTIL_LIBRARY})
@@ -158,9 +155,7 @@ set_target_properties(Vivy PROPERTIES
     MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
 )
 
-if(QT_VERSION_MAJOR EQUAL 6)
-    qt_finalize_executable(Vivy)
-endif()
+qt_finalize_executable(Vivy)
 
 # Set ASAN
 if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug")
diff --git a/PreCompiledHeaders.cmake b/PreCompiledHeaders.cmake
index 06a206334fe954200ac2a4ccb9c09ade8a7bbcca..6219edca865370d502604cbfc2749d46bfa2f4c7 100644
--- a/PreCompiledHeaders.cmake
+++ b/PreCompiledHeaders.cmake
@@ -40,7 +40,6 @@ set(QT_STRUCT_INC
     <QtGlobal>
     <QObject>
     <QRegularExpression>
-    <QRegExp>
     <QString>
     <QVariant>
     <QFile>
@@ -141,7 +140,6 @@ set(QT_WIDGET_INC
     <QDialogButtonBox>
     <QFileIconProvider>
     <QFontDatabase>
-    <QTextCodec>
     <QListWidget>
 )
 
diff --git a/src/Lib/Ass/AssFactory.cc b/src/Lib/Ass/AssFactory.cc
index 354c50d8ce4b7fca4b3bfb6d68924c93cfb3fd32..494df3a9a69dc3dd696efef2db773ad22570fee8 100644
--- a/src/Lib/Ass/AssFactory.cc
+++ b/src/Lib/Ass/AssFactory.cc
@@ -30,8 +30,8 @@ AssFactory::initFromStorage() noexcept
         }
 
         else if (!currentSection.isEmpty()) {
-            const int separatorIndex = line.indexOf(": ");
-            const int baseValueIndex = separatorIndex + 2;
+            const qsizetype separatorIndex = line.indexOf(": ");
+            const qsizetype baseValueIndex = separatorIndex + 2;
 
             // Easy way to see if the line was invalid
             if (separatorIndex < 0)
diff --git a/src/Lib/Ass/Line.cc b/src/Lib/Ass/Line.cc
index 9e215edf10ed30057d0a6a277369c26b694f3dfc..3e518632f5d03df7b4aeff6e1639f8fa1fe57408 100644
--- a/src/Lib/Ass/Line.cc
+++ b/src/Lib/Ass/Line.cc
@@ -70,11 +70,11 @@ Line::Line(AssFactory *const factory, const QString &lineString)
 }
 
 void
-Line::updateContent() noexcept
+Line::sylsChanged() noexcept
 {
     ___contentAsText = "";
     for (const auto &syl : content)
-        ___contentAsText.append(syl.getAssText());
+        ___contentAsText.append(syl->getAssText());
 }
 
 void
@@ -92,7 +92,7 @@ Line::initSylFromString(const QString &line) noexcept
 
         while (it.hasNext()) {
             QRegularExpressionMatch match = it.next();
-            content.append(Syl(this, match.captured(1)));
+            content.append(new Syl(this, match.captured(1)));
             once |= true;
         }
     } catch (const std::runtime_error &e) {
@@ -103,7 +103,7 @@ Line::initSylFromString(const QString &line) noexcept
 
     if (!once) {
         content.clear();
-        content.append(Syl(this, line, Syl::ConstructMode::Raw));
+        content.append(new Syl(this, line, Syl::ConstructMode::Raw));
     }
 }
 
@@ -141,13 +141,13 @@ Line::getStyle() const noexcept
     return lineStyle;
 }
 
-const QVector<Syl> &
+const QVector<Syl*> &
 Line::getContent() const noexcept
 {
     return content;
 }
 
-QVector<Syl> *
+QVector<Syl*> *
 Line::getContentPtr() noexcept
 {
     return &content;
@@ -189,10 +189,3 @@ Line::getLineAsText() const noexcept
                              styleProperties.marginR, styleProperties.marginV, "karaoke") +
            ___contentAsText;
 }
-
-void
-Line::setContent(const QVector<Syl> syls) noexcept
-{
-    content = syls;
-    updateContent();
-}
diff --git a/src/Lib/Ass/Line.hh b/src/Lib/Ass/Line.hh
index 9d84bc2a88576ad50a147b844bf7f49c27a1a30c..5c8e176db99462b99c2a1cbab235537501c2ff56 100644
--- a/src/Lib/Ass/Line.hh
+++ b/src/Lib/Ass/Line.hh
@@ -19,7 +19,7 @@ class Line final {
     int layer{ 0 };
     bool isComment{ true };
 
-    QVector<Syl> content{};
+    QVector<Syl*> content{};
     StyleProperties styleProperties{};
     QString effect{};
     QString nameOrActor{};
@@ -45,18 +45,19 @@ public:
 
     StyleProperties getStyleProperties() const noexcept;
     StyleWeakPtr getStyle() const noexcept;
-    const QVector<Syl> &getContent() const noexcept;
-    void setContent(const QVector<Syl>) noexcept;
+    const QVector<Syl*> &getContent() const noexcept;
+    void setContent(const QVector<Syl*>) noexcept;
 
-    QVector<Syl> *getContentPtr() noexcept; // FIXME: remove me
+    QVector<Syl*> *getContentPtr() noexcept; // FIXME: remove me
 
     quint64 getStart() const noexcept;
     quint64 getEnd() const noexcept;
     QString getContentAsText() const noexcept;
     QString getLineAsText() const noexcept;
 
+    void sylsChanged() noexcept;
+
 private:
     void initSylFromString(const QString &) noexcept;
-    void updateContent() noexcept;
 };
 }
diff --git a/src/Lib/Ass/Syl.cc b/src/Lib/Ass/Syl.cc
index dd8ba4737def942592d5304e3459204bdaf8870a..f7f39841652107756f2aeb98bf02d33e30a3095a 100644
--- a/src/Lib/Ass/Syl.cc
+++ b/src/Lib/Ass/Syl.cc
@@ -12,7 +12,7 @@ Syl::Syl(Line *const line, const QString &lineString, ConstructMode mode) noexce
 {
     // Will override the `content`, but will be heavy anyway
     if (mode == ConstructMode::ReadAssTags) {
-        const int textBegin = lineString.lastIndexOf('}') + 1;
+        const int textBegin = int(lineString.lastIndexOf('}')) + 1;
         content             = (textBegin >= lineString.size()) ? "" : lineString.mid(textBegin);
         duration            = getDurationFromString(lineString);
     }
diff --git a/src/Lib/Utils.cc b/src/Lib/Utils.cc
index 408a13a9d0edb749fffcd470e016b64d27d6a6f0..1372c1dd93b77ad49c1b66c28a5244765bcecbe8 100644
--- a/src/Lib/Utils.cc
+++ b/src/Lib/Utils.cc
@@ -60,7 +60,7 @@ QString
 Utils::OsSpecificAspects::pathWithNativeSeparators(OsType osType, const QString &pathName)
 {
     if (osType == OsTypeWindows) {
-        const int pos = pathName.indexOf('/');
+        const qsizetype pos = pathName.indexOf('/');
         if (pos >= 0) {
             QString n = pathName;
             std::replace(std::begin(n) + pos, std::end(n), '/', '\\');
@@ -133,14 +133,15 @@ Utils::decodeLineToFloating(const QString &item, const QString &error)
 Utils::Time
 Utils::Time::fromString(const QString &str)
 {
-    QRegExp re("^(\\d+):(\\d\\d):(\\d\\d)\\.(\\d\\d)$");
+    QRegularExpression re("^(\\d+):(\\d\\d):(\\d\\d)\\.(\\d\\d)$");
 
     // Here the toUint is safe because the RegExp is OK
-    if (re.indexIn(str) != -1)
-        return { .hour        = re.cap(1).toUInt(),
-                 .minute      = re.cap(2).toUInt(),
-                 .second      = re.cap(3).toUInt(),
-                 .centisecond = re.cap(4).toUInt() };
+    QRegularExpressionMatch match = re.match(str);
+    if (match.hasMatch())
+        return { .hour        = match.captured(1).toUInt(),
+                 .minute      = match.captured(2).toUInt(),
+                 .second      = match.captured(3).toUInt(),
+                 .centisecond = match.captured(4).toUInt() };
 
     else
         throw std::runtime_error("The string is not of the format `H:MM:SS.cs`");
diff --git a/src/Lib/Utils.hh b/src/Lib/Utils.hh
index d80030d0aae5ea7e1043a540ab64c297de89b429..1aa2d5e45b914bb2228cf1f8e622a50bcbe5d87c 100644
--- a/src/Lib/Utils.hh
+++ b/src/Lib/Utils.hh
@@ -59,7 +59,7 @@ using chrono::duration_cast;
     explicit classname(classname &&) noexcept = default; /* Move  */
 
 // QStringLiteral but for regexes
-#define QRegExpLiteral(str) QRegExp(QStringLiteral(str))
+#define QRegularExpressionLiteral(str) QRegularExpression(QStringLiteral(str))
 
 namespace Vivy
 {
diff --git a/src/PreCompiledHeaders.hh b/src/PreCompiledHeaders.hh
index e39b970f195aa0697806625c68e465f0efb5d653..da752cf322b757709e9434a8c26f9d17ad89e48c 100644
--- a/src/PreCompiledHeaders.hh
+++ b/src/PreCompiledHeaders.hh
@@ -39,7 +39,6 @@
 #include <QtGlobal>
 #include <QObject>
 #include <QRegularExpression>
-#include <QRegExp>
 #include <QString>
 #include <QVariant>
 #include <QFile>
@@ -139,5 +138,4 @@
 #include <QDialogButtonBox>
 #include <QFileIconProvider>
 #include <QFontDatabase>
-#include <QTextCodec>
 #include <QListWidget>
diff --git a/src/UI/DocumentViews/AssLinesModel.cc b/src/UI/DocumentViews/AssLinesModel.cc
index f7641ccf885f68e577ab267b7410f2f01e4bfd9c..009854449e6be195f2c3225c3a7fd34f90f2e1e4 100644
--- a/src/UI/DocumentViews/AssLinesModel.cc
+++ b/src/UI/DocumentViews/AssLinesModel.cc
@@ -20,14 +20,14 @@ AssLinesModel::Item::getLineText() const noexcept
     QString ret;
     if (auto ptr = line.get()) {
         for (const auto &syl : ptr->getContent()) {
-            ret.append(syl.getContent());
+            ret.append(syl->getContent());
             ret.append("(");
-            ret.append(QString::number(syl.getDuration()));
+            ret.append(QString::number(syl->getDuration()));
             ret.append(")");
             ret.append("|");
         }
     }
-    ret.remove(ret.size() - 1);
+    ret.chop(1);
     return ret;
 }
 
@@ -138,7 +138,7 @@ AssLinesModel::index(int row, int column, const QModelIndex &parent) const noexc
 int
 AssLinesModel::rowCount(const QModelIndex & /* parent */) const noexcept
 {
-    return childs.size();
+    return int(childs.size());
 }
 
 int
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingAxis.cc b/src/UI/DocumentViews/AudioVisualizer/TimingAxis.cc
index 5dd4d5fd58e5d4b56161fc24270a3389f29ba4f4..1186dfddffa7ebd6b3b8df677d2432dd5741a394 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingAxis.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingAxis.cc
@@ -21,10 +21,10 @@ TimingAxis::boundingRect() const
 void
 TimingAxis::onParamsChanged()
 {
-    int nbAvailableTicks = availableTicks.size();
-    int minorTicksIndex  = 0;
-    int length           = getTimingParam()->audioLength();
-    int width            = getTimingParam()->audioWidth();
+    qsizetype nbAvailableTicks  = availableTicks.size();
+    int minorTicksIndex         = 0;
+    int length                  = getTimingParam()->audioLength();
+    int width                   = getTimingParam()->audioWidth();
     if (width != 0 && length != 0) {
         for (minorTicksIndex = 0; minorTicksIndex < nbAvailableTicks; minorTicksIndex++) {
             if (width * availableTicks[minorTicksIndex] / length >= minBetweenMinor) {
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc b/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
index c64a40e1c0b039970ea6d535e525e954fe004aa3..10df7f489732c959b024810096b136c59e27f846 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
@@ -66,8 +66,8 @@ TimingLine::sepExitPress(int sepIndex)
 qreal
 TimingLine::requestMove(int sepIndex, qreal x)
 {
-    QRectF sceneRect       = mapRectFromScene(scene()->sceneRect());
-    QVector<Ass::Syl> syls = line.getContent();
+    QRectF sceneRect        = mapRectFromScene(scene()->sceneRect());
+    QVector<Ass::Syl*> syls = line.getContent();
 
     qreal given = x;
     qreal mini, maxi;
@@ -83,7 +83,7 @@ TimingLine::requestMove(int sepIndex, qreal x)
         tempOffset = given;
 
         quint64 dur1 = quint64(getTimingParam()->msFromPos(int(seps[1]->pos().x() - given)) / 10);
-        syls[0].setDuration(dur1);
+        syls[0]->setDuration(dur1);
         timingSyls[0]->setLen(dur1);
         timingSyls[0]->setPos(given, 0);
         line.setStart(quint64(getTimingParam()->msFromPos(mapToScene(seps[0]->pos().x(), 0).x()) / 10));
@@ -98,7 +98,7 @@ TimingLine::requestMove(int sepIndex, qreal x)
 
         quint64 dur2 =
             quint64(getTimingParam()->msFromPos(int(given - timingSyls[sepIndex - 1]->pos().x())) / 10);
-        syls[sepIndex - 1].setDuration(dur2);
+        syls[sepIndex - 1]->setDuration(dur2);
         timingSyls[sepIndex - 1]->setLen(dur2);
         line.setEnd(line.getStart() + quint64(getTimingParam()->msFromPos(int(given)) / 10));
     }
@@ -109,22 +109,21 @@ TimingLine::requestMove(int sepIndex, qreal x)
                                            : getTimingParam()->posFromMs(int(line.getDuration() * 10));
         given = qBound(mini, given, maxi);
 
-        quint64 sumDur = syls[sepIndex].getDuration() + syls[sepIndex - 1].getDuration();
+        quint64 sumDur = syls[sepIndex]->getDuration() + syls[sepIndex - 1]->getDuration();
         quint64 dur1   = quint64(
               getTimingParam()->msFromPos(int(given) - int(timingSyls[sepIndex - 1]->pos().x())) / 10);
         dur1         = qMin(dur1, sumDur);
         quint64 dur2 = sumDur - dur1;
 
-        syls[sepIndex - 1].setDuration(dur1);
-        syls[sepIndex].setDuration(dur2);
+        syls[sepIndex - 1]->setDuration(dur1);
+        syls[sepIndex]->setDuration(dur2);
 
         timingSyls[sepIndex - 1]->setLen(dur1);
         timingSyls[sepIndex]->setPos(given, 0);
         timingSyls[sepIndex]->setLen(dur2);
     }
 
-    line.setContent(syls);
-
+    line.sylsChanged();
     emit lineChanged(lineIndex);
 
     return given;
@@ -149,11 +148,11 @@ TimingLine::onParamsChanged()
     seps.append(timingSeparatorStart);
     CONNECT_SEP(timingSeparatorStart);
 
-    QVector<Ass::Syl> syls = line.getContent();
+    QVector<Ass::Syl*> syls = line.getContent();
     for (i = 0; i < syls.size(); ++i) {
-        endSyl = currentTime + 10 * int(syls.at(i).getDuration());
+        endSyl = currentTime + 10 * int(syls.at(i)->getDuration());
 
-        TimingSyl *timingSyl = new TimingSyl(syls.at(i), currentTime, this);
+        TimingSyl *timingSyl = new TimingSyl(*syls.at(i), currentTime, this);
         timingSyls.append(timingSyl);
 
         if (i != 0) {
diff --git a/src/UI/FakeVim/FakeVimHandler.cc b/src/UI/FakeVim/FakeVimHandler.cc
index 999f865b4374c8a415eebe24539c76e6590947aa..17f564f2a71a233d3e53f6b87fdda9675304ab10 100644
--- a/src/UI/FakeVim/FakeVimHandler.cc
+++ b/src/UI/FakeVim/FakeVimHandler.cc
@@ -526,11 +526,11 @@ searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat
     QString line     = block.text();
 
     QRegularExpressionMatch match;
-    int i = line.indexOf(needleExp, 0, &match);
+    int i = int(line.indexOf(needleExp, 0, &match));
     while (i != -1 && i < tc->positionInBlock()) {
         --*repeat;
-        const int offset = i + qMax(1, match.capturedLength());
-        i                = line.indexOf(needleExp, offset, &match);
+        const int offset = i + qMax(1, int(match.capturedLength()));
+        i                = int(line.indexOf(needleExp, offset, &match));
         if (i == line.size())
             i = -1;
     }
@@ -543,11 +543,11 @@ searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat
         if (!block.isValid())
             break;
         line = block.text();
-        i    = line.indexOf(needleExp, 0, &match);
+        i    = int(line.indexOf(needleExp, 0, &match));
         while (i != -1) {
             --*repeat;
-            const int offset = i + qMax(1, match.capturedLength());
-            i                = line.indexOf(needleExp, offset, &match);
+            const int offset = i + qMax(1, int(match.capturedLength()));
+            i                = int(line.indexOf(needleExp, offset, &match));
             if (i == line.size())
                 i = -1;
         }
@@ -558,14 +558,14 @@ searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat
         return;
     }
 
-    i = line.indexOf(needleExp, 0, &match);
+    i = int(line.indexOf(needleExp, 0, &match));
     while (*repeat < 0) {
-        const int offset = i + qMax(1, match.capturedLength());
-        i                = line.indexOf(needleExp, offset, &match);
+        const int offset = i + qMax(1, int(match.capturedLength()));
+        i                = int(line.indexOf(needleExp, offset, &match));
         ++*repeat;
     }
     tc->setPosition(block.position() + i);
-    tc->setPosition(tc->position() + match.capturedLength(), QTextCursor::KeepAnchor);
+    tc->setPosition(tc->position() + int(match.capturedLength()), QTextCursor::KeepAnchor);
 }
 
 // Commands [[, []
@@ -659,8 +659,8 @@ substituteText(QString *text, const QRegularExpression &pattern, const QString &
                bool global)
 {
     bool substituted = false;
-    int pos          = 0;
-    int right        = -1;
+    qsizetype pos    = 0;
+    qsizetype right  = -1;
     while (true) {
         const QRegularExpressionMatch match = pattern.match(*text, pos);
         if (!match.hasMatch())
@@ -950,7 +950,7 @@ static QString
 quoteUnprintable(const QString &ba)
 {
     QString res;
-    for (int i = 0, n = ba.size(); i != n; ++i) {
+    for (qsizetype i = 0, n = ba.size(); i != n; ++i) {
         const QChar c = ba.at(i);
         const int cc  = c.unicode();
         if (c.isPrint())
@@ -1276,7 +1276,7 @@ parseVimKeyName(const QString &keyName)
         return Input(keyName.at(0));
 
     const QStringList keys = keyName.split('-');
-    const int len          = keys.length();
+    const qsizetype len    = keys.length();
 
     if (len == 1 && keys.at(0).toUpper() == "NOP")
         return Nop;
@@ -1312,11 +1312,11 @@ parseVimKeyName(const QString &keyName)
 void
 Inputs::parseFrom(const QString &str)
 {
-    const int n = str.size();
-    for (int i = 0; i < n; ++i) {
+    const qsizetype n = str.size();
+    for (qsizetype i = 0; i < n; ++i) {
         const QChar c = str.at(i);
         if (c == '<') {
-            int j = str.indexOf('>', i);
+            qsizetype j = str.indexOf('>', i);
             Input input;
             if (j != -1) {
                 const QString key = str.mid(i + 1, j - i - 1);
@@ -1345,7 +1345,7 @@ public:
     const QString &move(QStringView prefix, int skip);
     const QString &current() const { return m_items[m_index]; }
     const QStringList &items() const { return m_items; }
-    void restart() { m_index = m_items.size() - 1; }
+    void restart() { m_index = int(m_items.size()) - 1; }
 
 private:
     // Last item is always empty or current search prefix.
@@ -1390,7 +1390,7 @@ public:
     void setContents(const QString &s)
     {
         m_buffer = s;
-        m_anchor = m_pos = s.size();
+        m_anchor = m_pos = int(s.size());
     }
 
     void setContents(const QString &s, int pos, int anchor = -1)
@@ -1416,7 +1416,7 @@ public:
     void insertText(const QString &s)
     {
         m_buffer.insert(m_pos, s);
-        m_anchor = m_userPos = m_pos = m_pos + s.size();
+        m_anchor = m_userPos = m_pos = m_pos + int(s.size());
     }
     void deleteChar()
     {
@@ -1436,7 +1436,7 @@ public:
             m_userPos = ++m_pos;
     }
     void moveStart() { m_userPos = m_pos = 0; }
-    void moveEnd() { m_userPos = m_pos = m_buffer.size(); }
+    void moveEnd() { m_userPos = m_pos = int(m_buffer.size()); }
 
     void setHistoryAutoSave(bool autoSave) { m_historyAutoSave = autoSave; }
     bool userContentsValid() const { return m_userPos >= 0 && m_userPos <= m_buffer.size(); }
@@ -1611,7 +1611,7 @@ public:
         }
 
         if (!it->value().isEmpty())
-            m_lastValid = size();
+            m_lastValid = int(size());
         append(it);
 
         return true;
@@ -2669,7 +2669,7 @@ FakeVimHandler::Private::commitInsertState()
     lastInsertion = textAt(insertState.pos1, insertState.pos2);
 
     // Escape special characters and spaces inserted by user (not by auto-indentation).
-    for (int i = lastInsertion.size() - 1; i >= 0; --i) {
+    for (int i = int(lastInsertion.size()) - 1; i >= 0; --i) {
         const int pos = insertState.pos1 + i;
         const QChar c = characterAt(pos);
         if (c == '<')
@@ -2916,7 +2916,7 @@ FakeVimHandler::Private::handleCurrentMapAsDefault()
 void
 FakeVimHandler::Private::prependInputs(const QVector<Input> &inputs)
 {
-    for (int i = inputs.size() - 1; i >= 0; --i)
+    for (qsizetype i = inputs.size() - 1; i >= 0; --i)
         g.pendingInput.prepend(inputs[i]);
 }
 
@@ -2925,7 +2925,7 @@ FakeVimHandler::Private::prependMapping(const Inputs &inputs)
 {
     // FIXME: Implement Vim option maxmapdepth (default value is 1000).
     if (g.mapDepth >= 1000) {
-        const int i                    = qMax(0, g.pendingInput.lastIndexOf(Input()));
+        const int i                    = qMax(0, int(g.pendingInput.lastIndexOf(Input())));
         const QList<Input> inputsLocal = g.pendingInput.mid(i);
         clearPendingInput();
         g.pendingInput.append(inputsLocal);
@@ -5420,7 +5420,7 @@ FakeVimHandler::Private::handleInsertMode(const Input &input)
                     const QString prefix = tabExpand(newl);
                     setLineContents(line, prefix + data.mid(col.physical));
                     moveToStartOfLine();
-                    moveRight(prefix.size());
+                    moveRight(int(prefix.size()));
                 } else {
                     setAnchor();
                     m_cursor.deletePreviousChar();
@@ -5911,7 +5911,7 @@ FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
             int pos1              = findUnescaped(separator, line, 1);
             if (pos1 == -1)
                 return false;
-            int pos2 = findUnescaped(separator, line, pos1 + 1);
+            qsizetype pos2 = findUnescaped(separator, line, pos1 + 1);
             if (pos2 == -1)
                 pos2 = line.size();
 
@@ -6196,7 +6196,7 @@ FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd)
 
     if (cmd.args.contains('=')) {
         // Non-boolean config to set.
-        int p         = cmd.args.indexOf('=');
+        qsizetype p         = cmd.args.indexOf('=');
         QString error = s.trySetValue(cmd.args.left(p), cmd.args.mid(p + 1));
         if (!error.isEmpty())
             showMessage(MessageError, error);
@@ -6495,7 +6495,7 @@ FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :!
         setPosition(targetPosition);
         endEditBlock();
         leaveVisualMode();
-        showMessage(MessageInfo, Tr::tr("%n lines filtered.", nullptr, input.count('\n')));
+        showMessage(MessageInfo, Tr::tr("%n lines filtered.", nullptr, int(input.count('\n'))));
     } else if (!result.isEmpty()) {
         q->extraInformationChanged(result);
     }
@@ -6630,7 +6630,7 @@ FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd)
         QByteArray nextline = !file.atEnd() ? file.readLine() : QByteArray();
 
         //  remove comment
-        int i = nextline.lastIndexOf('"');
+        qsizetype i = nextline.lastIndexOf('"');
         if (i != -1)
             nextline = nextline.remove(i, nextline.size() - i);
 
@@ -7734,11 +7734,11 @@ FakeVimHandler::Private::toggleComment(const Range &range)
                 if (firstLineIsComment) {
                     const bool hasSpaceAfterCommentString =
                         line.contains(QRegularExpression(checkForComment.pattern() + "\\s"));
-                    const int sizeToReplace = hasSpaceAfterCommentString ? commentString.size() + 1
+                    const qsizetype sizeToReplace = hasSpaceAfterCommentString ? commentString.size() + 1
                                                                          : commentString.size();
                     line.replace(line.indexOf(commentString), sizeToReplace, "");
                 } else {
-                    const int indexOfFirstNonSpace = line.indexOf(QRegularExpression("[^\\s]"));
+                    const qsizetype indexOfFirstNonSpace = line.indexOf(QRegularExpression("[^\\s]"));
                     line = line.left(indexOfFirstNonSpace) + commentString + " " +
                            line.right(line.size() - indexOfFirstNonSpace);
                 }
@@ -8108,22 +8108,22 @@ FakeVimHandler::Private::blockBoundary(const QString &left, const QString &right
     QTextCursor tc1 = m_cursor;
     int pos         = tc1.position();
     int max         = document()->characterCount();
-    int sz          = left.size();
+    int sz          = int(left.size());
     int from        = qMax(pos - sz + 1, 0);
     int to          = qMin(pos + sz, max);
     tc1.setPosition(from);
     tc1.setPosition(to, QTextCursor::KeepAnchor);
-    int i = tc1.selectedText().indexOf(left);
+    int i = int(tc1.selectedText().indexOf(left));
     if (i != -1) {
         // - on opening string:
         tc1.setPosition(from + i + sz);
     } else {
-        sz   = right.size();
+        sz   = int(right.size());
         from = qMax(pos - sz + 1, 0);
         to   = qMin(pos + sz, max);
         tc1.setPosition(from);
         tc1.setPosition(to, QTextCursor::KeepAnchor);
-        i = tc1.selectedText().indexOf(right);
+        i = int(tc1.selectedText().indexOf(right));
         if (i != -1) {
             // - on closing string:
             tc1.setPosition(from + i);
@@ -8162,7 +8162,7 @@ FakeVimHandler::Private::blockBoundary(const QString &left, const QString &right
         }
     }
 
-    return tc2.position() - end.size();
+    return tc2.position() - int(end.size());
 }
 
 int
@@ -8445,7 +8445,7 @@ FakeVimHandler::Private::onUndoCommandAdded()
     if (m_buffer->lastRevision >= revision()) {
         UNDO_DEBUG("UNDO REMOVED!");
         const int removed = m_buffer->lastRevision - revision();
-        for (int i = m_buffer->undo.size() - 1; i >= 0; --i) {
+        for (qsizetype i = m_buffer->undo.size() - 1; i >= 0; --i) {
             if ((m_buffer->undo[i].revision -= removed) < 0) {
                 m_buffer->undo.remove(0, i + 1);
                 break;
@@ -8716,9 +8716,9 @@ FakeVimHandler::Private::enterExMode(const QString &contents)
     g.currentMessage.clear();
     g.commandBuffer.clear();
     if (isVisualMode())
-        g.commandBuffer.setContents(QString("'<,'>") + contents, contents.size() + 5);
+        g.commandBuffer.setContents(QString("'<,'>") + contents, int(contents.size()) + 5);
     else
-        g.commandBuffer.setContents(contents, contents.size());
+        g.commandBuffer.setContents(contents, int(contents.size()));
     g.mode       = ExMode;
     g.submode    = NoSubMode;
     g.subsubmode = NoSubSubMode;
@@ -8743,7 +8743,7 @@ FakeVimHandler::Private::jump(int distance)
 {
     QStack<CursorPosition> &from = (distance > 0) ? m_buffer->jumpListRedo : m_buffer->jumpListUndo;
     QStack<CursorPosition> &to   = (distance > 0) ? m_buffer->jumpListUndo : m_buffer->jumpListRedo;
-    int len                      = qMin(qAbs(distance), from.size());
+    int len                      = qMin(qAbs(distance), int(from.size()));
     CursorPosition m(m_cursor);
     setMark('\'', m);
     setMark('`', m);
@@ -8761,7 +8761,7 @@ FakeVimHandler::Private::indentation(const QString &line) const
     int ts       = static_cast<int>(s.tabStop.value());
     int physical = 0;
     int logical  = 0;
-    int n        = line.size();
+    qsizetype n  = line.size();
     while (physical < n) {
         QChar c = line.at(physical);
         if (c == ' ')
@@ -8798,7 +8798,7 @@ FakeVimHandler::Private::insertAutomaticIndentation(bool goingDown, bool forceAu
         QTextBlock bl = goingDown ? block().previous() : block().next();
         QString text  = bl.text();
         int pos       = 0;
-        int n         = text.size();
+        qsizetype n   = text.size();
         while (pos < n && text.at(pos).isSpace())
             ++pos;
         text.truncate(pos);
@@ -9095,8 +9095,8 @@ FakeVimHandler::Private::changeNumberTextObject(int count)
         if (match.capturedEnd() >= posMin)
             break;
     }
-    int pos           = match.capturedStart();
-    int len           = match.capturedLength();
+    int pos           = int(match.capturedStart());
+    int len           = int(match.capturedLength());
     QString prefix    = match.captured(1) + match.captured(3);
     bool hex          = prefix.length() >= 2 && (prefix[1].toLower() == 'x');
     bool octal        = !hex && !prefix.isEmpty();
@@ -9132,7 +9132,7 @@ FakeVimHandler::Private::changeNumberTextObject(int count)
 
     // convert hexadecimal number to upper-case if last letter was upper-case
     if (hex) {
-        const int lastLetter = num.lastIndexOf(QRegularExpression("[a-fA-F]"));
+        const qsizetype lastLetter = num.lastIndexOf(QRegularExpression("[a-fA-F]"));
         if (lastLetter != -1 && num[lastLetter].isUpper())
             repl = repl.toUpper();
     }
@@ -9146,7 +9146,7 @@ FakeVimHandler::Private::changeNumberTextObject(int count)
     pushUndoState();
     setAnchorAndPosition(pos, pos + len);
     replaceText(currentRange(), repl);
-    setPosition(pos + repl.size() - 1);
+    setPosition(pos + int(repl.size()) - 1);
 
     return true;
 }
@@ -9155,7 +9155,7 @@ bool
 FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, const QString &quote)
 {
     QTextCursor tc = m_cursor;
-    int sz         = quote.size();
+    int sz         = int(quote.size());
 
     QTextCursor tc1;
     QTextCursor tc2(document());
diff --git a/src/UI/PropertyModel.cc b/src/UI/PropertyModel.cc
index e45f224464a192e37fb58ee7e44adbb4b1fa6f27..7ea24a332c4a1ea64a5aa0a8db5be1bf80a04633 100644
--- a/src/UI/PropertyModel.cc
+++ b/src/UI/PropertyModel.cc
@@ -31,14 +31,14 @@ PropertyModel::Item::getParent() const noexcept
 int
 PropertyModel::Item::getChildCount() const noexcept
 {
-    return childs.count();
+    return int(childs.count());
 }
 
 // Can't be const because of indexOf...
 int
 PropertyModel::Item::getRow() noexcept
 {
-    return parent ? parent->childs.indexOf(this) : 0;
+    return parent ? int(parent->childs.indexOf(this)) : 0;
 }
 
 void
diff --git a/src/UI/ScriptViews/EditorProxy.cc b/src/UI/ScriptViews/EditorProxy.cc
index de96e991f7aac0d6e12a9da6b47c3d3887b08728..4232b8f081b783a0ed61bb768bcf02804c216508 100644
--- a/src/UI/ScriptViews/EditorProxy.cc
+++ b/src/UI/ScriptViews/EditorProxy.cc
@@ -74,7 +74,7 @@ EditorProxy::highlightMatches(const QString &pattern) noexcept
     selection.format.setForeground(Qt::black);
 
     // Highlight matches.
-    QRegExp re(pattern);
+    QRegularExpression re(pattern);
     QTextCursor cur = doc->find(re);
     searchSelection.clear();
 
@@ -241,13 +241,10 @@ EditorProxy::indentRegion(int beginBlock, int endBlock, QChar typedChar) noexcep
     const int indentSize  = static_cast<int>(fakeVimSettings()->shiftWidth.value());
     QTextBlock startBlock = doc->findBlockByNumber(beginBlock);
 
-    // Record line lenghts for mark adjustments
-    QVector<int> lineLengths(endBlock - beginBlock + 1);
     QTextBlock block = startBlock;
 
     for (int i = beginBlock; i <= endBlock; ++i) {
         const QString line          = block.text();
-        lineLengths[i - beginBlock] = line.length();
 
         if (typedChar.unicode() == 0 && line.simplified().isEmpty()) {
             // clear empty lines
diff --git a/src/UI/ScriptViews/ScriptHighlighter.cc b/src/UI/ScriptViews/ScriptHighlighter.cc
index 29e665e88f8552c5a554958b674f0cd59bb41f2b..c3ecb3497a74233c5f74b268934cc50424048bbc 100644
--- a/src/UI/ScriptViews/ScriptHighlighter.cc
+++ b/src/UI/ScriptViews/ScriptHighlighter.cc
@@ -6,7 +6,7 @@
 
 using namespace Vivy;
 
-ScriptHighlighter::HighlightingRule::HighlightingRule(QRegExp pttrn, QTextCharFormat frmt)
+ScriptHighlighter::HighlightingRule::HighlightingRule(QRegularExpression pttrn, QTextCharFormat frmt)
     : pattern(pttrn)
     , format(frmt)
 {
@@ -20,16 +20,16 @@ ScriptHighlighter::resetHighlightingRule() noexcept
 
     // function calls
     functionFormat.setForeground(theme.functionForeground);
-    highlightingRules.emplace_back(QRegExpLiteral("\\b[A-Za-z0-9_]+[ ]*(?=\\()"), functionFormat);
-    highlightingRules.emplace_back(QRegExpLiteral("\\b[A-Za-z0-9_]+[ ]*(?=\\{)"), functionFormat);
+    highlightingRules.emplace_back(QRegularExpressionLiteral("\\b[A-Za-z0-9_]+[ ]*(?=\\()"), functionFormat);
+    highlightingRules.emplace_back(QRegularExpressionLiteral("\\b[A-Za-z0-9_]+[ ]*(?=\\{)"), functionFormat);
 
     // Member and enum members
     enumFormat.setForeground(theme.enumForeground);
     enumFormat.setFontWeight(QFont::Bold);
     memberFormat.setForeground(theme.memberForeground);
     memberFormat.setFontWeight(QFont::StyleItalic);
-    highlightingRules.emplace_back(QRegExpLiteral("\\.[a-z][\\dA-Za-z]*\\b"), memberFormat);
-    highlightingRules.emplace_back(QRegExpLiteral("\\b[A-Z][\\dA-Z_]*\\b"), enumFormat);
+    highlightingRules.emplace_back(QRegularExpressionLiteral("\\.[a-z][\\dA-Za-z]*\\b"), memberFormat);
+    highlightingRules.emplace_back(QRegularExpressionLiteral("\\b[A-Z][\\dA-Z_]*\\b"), enumFormat);
 
     // keywords
     const QStringList keywordPatterns = {
@@ -51,7 +51,7 @@ ScriptHighlighter::resetHighlightingRule() noexcept
     keywordFormat.setFontWeight(QFont::Bold);
 
     for (QString const &pattern : keywordPatterns)
-        highlightingRules.emplace_back(QRegExp(pattern), keywordFormat);
+        highlightingRules.emplace_back(QRegularExpression(pattern), keywordFormat);
 
     // numbers, boolean, nil
     const QStringList valuePatterns = {
@@ -68,20 +68,20 @@ ScriptHighlighter::resetHighlightingRule() noexcept
     valueFormat.setFontWeight(QFont::Normal);
 
     for (QString const &pattern : valuePatterns)
-        highlightingRules.emplace_back(QRegExp(pattern), valueFormat);
+        highlightingRules.emplace_back(QRegularExpression(pattern), valueFormat);
 
     // strings
     quotationFormat.setForeground(theme.valueForeground);
-    highlightingRules.emplace_back(QRegExpLiteral("\"[^\"]*\""), quotationFormat);
-    highlightingRules.emplace_back(QRegExpLiteral("\'[^\']*\'"), quotationFormat);
-    quoteStartExpression = QRegExpLiteral("\\[\\[");
-    quoteEndExpression   = QRegExpLiteral("\\]\\]");
+    highlightingRules.emplace_back(QRegularExpressionLiteral("\"[^\"]*\""), quotationFormat);
+    highlightingRules.emplace_back(QRegularExpressionLiteral("\'[^\']*\'"), quotationFormat);
+    quoteStartExpression = QRegularExpressionLiteral("\\[\\[");
+    quoteEndExpression   = QRegularExpressionLiteral("\\]\\]");
 
     // comments
     singleLineCommentFormat.setForeground(theme.commentForeground);
-    highlightingRules.emplace_back(QRegExpLiteral("--[^\n]*"), singleLineCommentFormat);
-    commentStartExpression = QRegExpLiteral("--\\[\\[");
-    commentEndExpression   = QRegExpLiteral("\\]\\]");
+    highlightingRules.emplace_back(QRegularExpressionLiteral("--[^\n]*"), singleLineCommentFormat);
+    commentStartExpression = QRegularExpressionLiteral("--\\[\\[");
+    commentEndExpression   = QRegularExpressionLiteral("\\]\\]");
 }
 
 ScriptHighlighter::ScriptHighlighter(QTextDocument *parent) noexcept
@@ -111,12 +111,15 @@ void
 ScriptHighlighter::highlightBlock(const QString &text) noexcept
 {
     for (const HighlightingRule &rule : highlightingRules) {
-        QRegExp expression(rule.pattern);
-        int index = expression.indexIn(text);
+        QRegularExpression expression(rule.pattern);
+        QRegularExpressionMatch matchStart = expression.match(text);
+        int index = int(matchStart.capturedStart(0));
         while (index >= 0) {
-            const int length = expression.matchedLength();
+            const int length = int(matchStart.capturedLength(0));
             setFormat(index, length, rule.format);
-            index = expression.indexIn(text, index + length);
+            // FIXME: unused, can delete?
+            QRegularExpressionMatch matchEnd = expression.match(text, index + length);
+            index = int(matchEnd.capturedStart(0));
         }
     }
 
@@ -129,29 +132,31 @@ ScriptHighlighter::highlightBlock(const QString &text) noexcept
 
 void
 ScriptHighlighter::highlightBlock(const QString &text, const BlockState previousState,
-                                  const BlockState toHighlight, const QRegExp &startExpr,
-                                  const QRegExp &endExpr, const QTextCharFormat &format) noexcept
+                                  const BlockState toHighlight, const QRegularExpression &startExpr,
+                                  const QRegularExpression &endExpr, const QTextCharFormat &format) noexcept
 {
     int start = -1;
     if (previousState == toHighlight) {
         start = 0;
     } else if (previousState == BlockState::None) {
-        start = startExpr.indexIn(text);
+        QRegularExpressionMatch match = startExpr.match(text);
+        start = int(startExpr.match(text).capturedStart(0));
     }
 
     while (start >= 0) {
-        const int end = endExpr.indexIn(text, start);
+        const int end = int(endExpr.match(text, start).capturedStart(0));
         int length;
 
         if (end == -1) {
             setCurrentBlockState(toHighlight);
-            length = text.length() - start;
+            length = int(text.length()) - start;
         } else {
-            length = end - start + endExpr.matchedLength();
+            length = end - start + int(endExpr.match(text).capturedLength(0));
         }
 
         setFormat(start, length, format);
-        start = startExpr.indexIn(text, start + length);
+        // FIXME: unused, can delete? or expected as startExpr reference?
+        start = int(startExpr.match(text, start + length).capturedStart(0));
     }
 }
 
diff --git a/src/UI/ScriptViews/ScriptHighlighter.hh b/src/UI/ScriptViews/ScriptHighlighter.hh
index 3d30a3409e46eedad78f3b071da887b590dea2d6..d2bc60e9b83a2eff1e1d5588ab21912170332800 100644
--- a/src/UI/ScriptViews/ScriptHighlighter.hh
+++ b/src/UI/ScriptViews/ScriptHighlighter.hh
@@ -13,9 +13,9 @@ class ScriptHighlighter final : public QSyntaxHighlighter {
     Q_OBJECT
 
     struct HighlightingRule {
-        HighlightingRule(QRegExp pttrn, QTextCharFormat frmt);
+        HighlightingRule(QRegularExpression pttrn, QTextCharFormat frmt);
 
-        QRegExp pattern;
+        QRegularExpression pattern;
         QTextCharFormat format;
     };
 
@@ -35,17 +35,17 @@ private:
     void highlightCommentBlock(const QString &text, const BlockState) noexcept;
 
     void highlightBlock(const QString &text, const BlockState previous,
-                        const BlockState toHighlight, const QRegExp &start, const QRegExp &end,
+                        const BlockState toHighlight, const QRegularExpression &start, const QRegularExpression &end,
                         const QTextCharFormat &format) noexcept;
 
     void resetHighlightingRule() noexcept;
 
     std::vector<HighlightingRule> highlightingRules;
 
-    QRegExp commentStartExpression;
-    QRegExp commentEndExpression;
-    QRegExp quoteStartExpression;
-    QRegExp quoteEndExpression;
+    QRegularExpression commentStartExpression;
+    QRegularExpression commentEndExpression;
+    QRegularExpression quoteStartExpression;
+    QRegularExpression quoteEndExpression;
 
     QTextCharFormat keywordFormat;
     QTextCharFormat valueFormat;
diff --git a/src/VivyApplication.cc b/src/VivyApplication.cc
index 6143ef257d1a313cae00f1877600a0d0c277bfc7..ad6711521fb21ddf46ca80de7cdcbb52ed32bdc9 100644
--- a/src/VivyApplication.cc
+++ b/src/VivyApplication.cc
@@ -45,7 +45,6 @@ int
 VivyApplication::exec() noexcept
 {
     // For MPV & Qt
-    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
     std::setlocale(LC_NUMERIC, "C");
 
     // Add fonts