From 80fab202b1ab0a21e8ff7272bd9a18d85ae089b5 Mon Sep 17 00:00:00 2001 From: Sunshine Date: Sat, 24 Oct 2026 11:31:13 -0400 Subject: [PATCH] port Liquid to Qt6 --- .github/workflows/ci.yml | 55 +++++++++++++++++++++++------------ README.md | 16 +++++++++- inc/liquidappwebpage.hpp | 7 ++++- liquid.pro | 8 +++-- src/liquid.cpp | 1 + src/liquidappconfigwindow.cpp | 4 +-- src/liquidappwebpage.cpp | 17 +++++++++++ 7 files changed, 83 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9d1366..640773f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,41 +16,60 @@ jobs: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: include: - - os: ubuntu-18.04 - - os: ubuntu-20.04 - - os: macos-10.15 - - os: macos-11 - - os: windows-2019 + # Qt 5.15 from distro packages + - os: ubuntu-22.04 + qt: 5 + # Qt 6 from distro packages + - os: ubuntu-24.04 + qt: 6 + # Qt 6 from the Qt online repository + - os: macos-14 + qt: 6 - os: windows-2022 - - continue-on-error: true + qt: 6 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + - uses: ilammy/msvc-dev-cmd@v1 + if: runner.os == 'Windows' + + - name: Resolve dependencies (Ubuntu, Qt 5) + run: | + sudo apt-get update + sudo apt-get install -y qtbase5-dev qtwebengine5-dev qt5-qmake + echo "QMAKE=qmake" >> "$GITHUB_ENV" + if: runner.os == 'Linux' && matrix.qt == 5 - - name: Resolve dependencies (Ubuntu) + - name: Resolve dependencies (Ubuntu, Qt 6) run: | - sudo apt-get update && \ - sudo apt-get install qt5-default qtwebengine5-dev - if: contains(matrix.os, 'ubuntu') + sudo apt-get update + sudo apt-get install -y qt6-base-dev qt6-webengine-dev qmake6 libgl-dev + echo "QMAKE=qmake6" >> "$GITHUB_ENV" + if: runner.os == 'Linux' && matrix.qt == 6 - name: Resolve dependencies (macOS and Windows) - uses: jurplel/install-qt-action@v2 + uses: jurplel/install-qt-action@v4 with: - modules: 'qtwebengine' - if: contains(matrix.os, 'macos') || contains(matrix.os, 'windows') + version: '6.8.*' + modules: 'qtwebengine qtwebchannel qtpositioning' + if: runner.os != 'Linux' + + - name: Resolve dependencies (macOS icon tools) + run: brew install imagemagick + if: runner.os == 'macOS' - name: Build (Ubuntu and macOS) run: | - qmake + ${QMAKE:-qmake} make -j - if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') + if: runner.os != 'Windows' - name: Build (Windows) run: | qmake nmake - if: contains(matrix.os, 'windows') + if: runner.os == 'Windows' diff --git a/README.md b/README.md index 74932cf..174e285 100644 --- a/README.md +++ b/README.md @@ -73,13 +73,27 @@ What gets stored (if allowed): cookies. ## Working with the codebase +#### Dependencies + +Liquid is built with Qt 6 (Qt 5.15 is still supported) and Qt WebEngine. + +On Debian/Ubuntu: + +```console +sudo apt install qt6-base-dev qt6-webengine-dev qmake6 build-essential +``` + +On macOS and Windows, install Qt 6 with the Qt WebEngine, Qt WebChannel, and Qt Positioning modules using the [Qt Online Installer](https://www.qt.io/download-qt-installer). + #### Build ```console -qmake +qmake6 make -j ``` +Use `qmake` instead of `qmake6` if it already points to Qt 6 (or to Qt 5.15) on your system. + #### Install ```console diff --git a/inc/liquidappwebpage.hpp b/inc/liquidappwebpage.hpp index 179de1f..545fd5e 100644 --- a/inc/liquidappwebpage.hpp +++ b/inc/liquidappwebpage.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -27,7 +28,11 @@ class LiquidAppWebPage : public QWebEnginePage bool acceptNavigationRequest(const QUrl& reqUrl, const QWebEnginePage::NavigationType navReqType, const bool isMainFrame) override; private: - bool certificateError(const QWebEngineCertificateError& error); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + bool certificateError(const QWebEngineCertificateError& error) override; +#else + void handleCertificateError(const QWebEngineCertificateError& error); +#endif void javaScriptAlert(const QUrl& securityOrigin, const QString& msg) override; bool javaScriptConfirm(const QUrl& securityOrigin, const QString& msg) override; bool javaScriptPrompt(const QUrl& securityOrigin, const QString& msg, const QString& defaultValue, QString* result) override; diff --git a/liquid.pro b/liquid.pro index dbdeae0..d2291b7 100644 --- a/liquid.pro +++ b/liquid.pro @@ -4,8 +4,8 @@ VERSION_PATCH = 11 VERSION = $${VERSION_MAJOR}.$${VERSION_MINOR}.$${VERSION_PATCH} -QT += core gui webenginewidgets -CONFIG += c++11 +QT += core gui network widgets webenginecore webenginewidgets +CONFIG += c++17 TEMPLATE = app DESTDIR = build @@ -85,7 +85,7 @@ unix:!mac { # macOS macx: { HEADERS += inc/SetWindowBackgroundColor.h - OBJECTIVE_SOURCES += src/SetWindowBackgroundColor.mm + SOURCES += src/SetWindowBackgroundColor.mm LIBS += -framework Cocoa @@ -107,5 +107,7 @@ macx: { QMAKE_PRE_LINK += iconutil -c icns $${DESTDIR}/$${TARGET}.iconset } + # Qt 6 no longer creates Contents/Resources inside the app bundle on its own + QMAKE_POST_LINK += mkdir -p $${DESTDIR}/$${TARGET}.app/Contents/Resources && QMAKE_POST_LINK += cp $${DESTDIR}/$${TARGET}.icns $${DESTDIR}/$${TARGET}.app/Contents/Resources/ } diff --git a/src/liquid.cpp b/src/liquid.cpp index 78a907e..3dc0d0a 100644 --- a/src/liquid.cpp +++ b/src/liquid.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/src/liquidappconfigwindow.cpp b/src/liquidappconfigwindow.cpp index f532eb9..c9e0306 100644 --- a/src/liquidappconfigwindow.cpp +++ b/src/liquidappconfigwindow.cpp @@ -379,7 +379,7 @@ LiquidAppConfigDialog::LiquidAppConfigDialog(QWidget* parent, QString liquidAppN customBackgroundColorButtonLayout->addWidget(customBackgroundColorButton); connect(customBackgroundColorButton, &QPushButton::clicked, [&]() { - const QColorDialog::ColorDialogOptions options = QFlag(QColorDialog::ShowAlphaChannel); + const QColorDialog::ColorDialogOptions options = QColorDialog::ShowAlphaChannel; QColor color = QColorDialog::getColor(*backgroundColor, this, tr("Pick custom background color"), options); if (color.isValid()) { @@ -746,7 +746,7 @@ LiquidAppConfigDialog::LiquidAppConfigDialog(QWidget* parent, QString liquidAppN connect(proxyPortInput, QOverload::of(&QSpinBox::valueChanged), [&](){ proxyModeCustomRadioButton->setChecked(true); }); - connect(proxyUseAuthCheckBox, &QCheckBox::stateChanged, [&](){ + connect(proxyUseAuthCheckBox, &QCheckBox::toggled, [&](){ proxyModeCustomRadioButton->setChecked(true); }); connect(proxyUsernameInput, &QLineEdit::textChanged, [&](const QString value){ diff --git a/src/liquidappwebpage.cpp b/src/liquidappwebpage.cpp index d5d858a..cc01e25 100644 --- a/src/liquidappwebpage.cpp +++ b/src/liquidappwebpage.cpp @@ -24,6 +24,11 @@ LiquidAppWebPage::LiquidAppWebPage(QWebEngineProfile* profile, LiquidAppWindow* }); connect(this, &QWebEnginePage::authenticationRequired, this, &LiquidAppWebPage::authenticationRequired); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + // Qt 6 turned QWebEnginePage::certificateError() from a virtual method into a signal + connect(this, &QWebEnginePage::certificateError, this, &LiquidAppWebPage::handleCertificateError); +#endif } void LiquidAppWebPage::addAllowedDomain(const QString domain) { @@ -107,14 +112,26 @@ void LiquidAppWebPage::authenticationRequired(const QUrl& requestUrl, QAuthentic dialogWidget = Q_NULLPTR; } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) bool LiquidAppWebPage::certificateError(const QWebEngineCertificateError& error) { Q_UNUSED(error); emit liquidAppWindow->certificateError(); + // Ignore the error and proceed with loading the page return true; } +#else +void LiquidAppWebPage::handleCertificateError(const QWebEngineCertificateError& error) +{ + // Ignore the error and proceed with loading the page + QWebEngineCertificateError err = error; + err.acceptCertificate(); + + emit liquidAppWindow->certificateError(); +} +#endif void LiquidAppWebPage::closeJsDialog() {