diff --git a/.dockerignore b/.dockerignore index df18595..28e9b21 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,4 +6,5 @@ aria2/src/.libs build* Dockerfile* !build-aria.sh +!build-qt.sh diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..34ddfb6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,150 @@ +cmake_minimum_required(VERSION 3.21) + +project(updater LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# triggers in QML generated files +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized") + +# important for quazip +set(BUILD_SHARED_LIBS OFF) + +set(CMAKE_AUTORCC ON) + +set(ARIA2_LIBS "${CMAKE_CURRENT_SOURCE_DIR}/aria2/src/.libs/libaria2.a" CACHE STRING "aria2 libraries") +set(ARIA2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/aria2/include" CACHE STRING "aria2 include directory") + +find_package(Qt6 REQUIRED COMPONENTS Core Qml Quick QuickControls2 QuickDialogs2 Network Gui Widgets) + +if (WIN32) + set(CMAKE_C_FLAGS "-static -static-libgcc ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-static -static-libgcc ${CMAKE_CXX_FLAGS}") +endif() + +qt_standard_project_setup(REQUIRES 6.8) + +option(FLUID_INSTALL_ICONS "" OFF) +option(FLUID_WITH_DOCUMENTATION "" OFF) +option(FLUID_WITH_GALLERY "" OFF) +option(FLUID_WITH_QML_MODULES "" ON) +function(add_fluid) # Use function to emulate the new scope created by add_subdirectory + find_package(Qt6 6.8 + REQUIRED + COMPONENTS + Core + Core5Compat + Gui + #GuiPrivate + Svg + Qml + Quick + QuickControls2 + ) + set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml_modules") + include(fluid.cmake) +endfunction() +add_fluid() + +set(QUAZIP_BZIP2 OFF) +set(QUAZIP_ENABLE_TESTS OFF) +set(QUAZIP_FETCH_LIBS OFF) +if (WIN32) + set(QUAZIP_USE_QT_ZLIB ON) +endif() +add_subdirectory(quazip) + +set(SOURCES + ariadownloader.cpp ariadownloader.h + currentversionfetcher.cpp currentversionfetcher.h + downloadtimecalculator.cpp downloadtimecalculator.h + downloadworker.cpp downloadworker.h + gamelauncher.cpp gamelauncher.h + main.cpp + qmldownloader.cpp qmldownloader.h + settings.cpp settings.h + splashcontroller.cpp splashcontroller.h + system.h +) +set(QML_SOURCES + DownloadInfo.qml + main.qml + News.qml + NewsCard.qml + Settings.qml + splash.qml + UpdateFailed.qml + utils.js +) + +if(APPLE) + list(APPEND SOURCES osx.cpp) +elseif(WIN32) + list(APPEND SOURCES win.cpp ExecInExplorer.cpp) +else() + list(APPEND SOURCES linux.cpp) +endif() + +qt_add_executable(updater WIN32 + ${SOURCES} + qml.qrc +) + +qt_add_qml_module(updater + URI UnvUpdater + QML_FILES ${QML_SOURCES} + RESOURCE_PREFIX "/" +) + +target_link_libraries(updater PRIVATE + Qt6::Network + Qt6::Widgets + QuaZip::QuaZip + Fluid + ${ARIA2_LIBS} +) + +target_link_libraries(updater PRIVATE + Qt6::Qml + Qt6::Quick + Qt6::QuickControls2 + Qt6::QuickDialogs2 +) + + +# Platform-specific linking +if(WIN32) + target_link_libraries(updater PRIVATE + crypt32 + secur32 + ole32 + ) + # + target_sources(updater PRIVATE updater.rc) +elseif(UNIX) + target_link_libraries(updater PRIVATE + z + ) +endif() + +# Turn on warning errors since the warnings are hard to see in Docker +if(NOT APPLE) + target_compile_options(updater PRIVATE -Werror) +endif() + +# macOS app bundle icon +# UNTESTED, AISLOP +if(APPLE) + set_target_properties(updater PROPERTIES + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_ICON_FILE Unvanquished.icns + ) + set(MACOSX_BUNDLE_ICON_FILE resources/Unvanquished.icns) + set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE} PROPERTIES + MACOSX_PACKAGE_LOCATION Resources + ) + target_sources(updater PRIVATE ${MACOSX_BUNDLE_ICON_FILE}) +endif() + + diff --git a/Dockerfile b/Dockerfile index 7d1a8a9..5b3d00b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,37 @@ # See Dockerfile.win for an explanation of some aspects of this file. FROM docker.io/debian:bullseye-slim + +# Prevents warning spam from Qt 6's rcc +ENV LANG=C.UTF-8 + # OpenSSL build requires perl # Qt tarball requires xz-utils -# Qt build requires libgl1-mesa-dev, libxkbcommon-dev, python, zlib1g-dev -# Qt configuration additionally finds libxcb-glx0-dev/libx11-xcb-dev/libxext-dev. Without them, the -# updater builds but icons (gear, download, etc.) are mysteriously missing, when built in the -# Bullseye environment. It may be that not all are necessary. +# Qt build requires libgl1-mesa-dev, libxkbcommon-dev, python, zlib1g-dev................ # aria2 build requires autoconf, autopoint, gettext # git is used for cleaning unwanted files + +# For Qt's xcb_syslibs compile test +ENV XCB_MINIMUM_PACKAGES=' \ + libxcb-cursor-dev \ + libxcb-icccm4-dev \ + libxcb-image0-dev \ + libxcb-keysyms1-dev \ + libxcb-randr0-dev \ + libxcb-render0-dev \ + libxcb-render-util0-dev \ + libxcb-shape0-dev \ + libxcb-shm0-dev \ + libxcb-sync-dev \ + libxcb-xfixes0-dev \ + libxcb-xkb-dev \ + libxcb-util-dev \ +' +RUN echo 'deb http://archive.debian.org/debian bullseye-backports main' > /etc/apt/sources.list.d/backports.list RUN apt-get update && apt-get install -y \ autoconf \ autopoint \ + cmake/bullseye-backports \ + cmake-data/bullseye-backports \ curl \ gettext \ git \ @@ -19,39 +40,39 @@ RUN apt-get update && apt-get install -y \ libtool \ libx11-xcb-dev \ libxcb-glx0-dev \ - libxext-dev \ - libxkbcommon-dev \ + libxkbcommon-x11-dev \ make \ + ninja-build \ perl \ p7zip-full \ pkg-config \ python \ xz-utils \ - zlib1g-dev + zlib1g-dev \ + $XCB_MINIMUM_PACKAGES +RUN rm /usr/lib/x86_64-linux-gnu/libxcb-*.so ################# # Build OpenSSL # ################# WORKDIR /build-ssl -RUN curl -LO https://github.com/openssl/openssl/releases/download/openssl-3.6.0/openssl-3.6.0.tar.gz && \ - curl -L https://github.com/openssl/openssl/releases/download/openssl-3.6.0/openssl-3.6.0.tar.gz.sha256 | sha256sum --check +COPY sha256sums-openssl.txt /build-ssl/ +RUN curl -LO http://github.com/openssl/openssl/releases/download/openssl-3.6.0/openssl-3.6.0.tar.gz && \ + sha256sum --check sha256sums-openssl.txt RUN tar -xzf openssl-3.6.0.tar.gz WORKDIR /build-ssl/openssl-3.6.0 -RUN ./config --prefix=/openssl --openssldir=/dev/null no-shared no-apps no-autoload-config no-capieng no-dso no-dynamic-engine no-engine no-loadereng no-module -Os +RUN ./config --prefix=/openssl --openssldir=/dev/null no-shared no-apps no-autoload-config no-capieng no-dso no-dynamic-engine no-engine no-loadereng no-module -Os no-pic -fno-pic RUN make -j`nproc` && make install_sw && rm -rf /build-ssl ############ # Build Qt # ############ WORKDIR /build-qt -ENV UPDATER_MODULES=qtbase,qtquickcontrols,qtquickcontrols2,qtsvg,qtgraphicaleffects -RUN curl -LO https://download.qt.io/archive/qt/5.14/5.14.2/single/qt-everywhere-src-5.14.2.tar.xz && \ - curl -L https://download.qt.io/archive/qt/5.14/5.14.2/single/md5sums.txt | md5sum --check --ignore-missing && \ - tar -xJf qt-everywhere-src-5.14.2.tar.xz && \ - cd qt-everywhere-src-5.14.2 && \ - OPENSSL_LIBS='-L/openssl/lib64 -lssl -lcrypto -lpthread -ldl' ./configure -opensource -confirm-license -release -optimize-size -no-shared -static --c++std=14 -nomake tests -nomake tools -nomake examples -no-gif -no-icu -no-glib -no-qml-debug -opengl desktop -no-eglfs -no-opengles3 -no-angle -no-egl -qt-xcb -xkbcommon -dbus-runtime -qt-freetype -qt-pcre -qt-harfbuzz -qt-libpng -qt-libjpeg -system-zlib -I /openssl/include -openssl-linked -prefix /qt && \ - bash -c "make -j`nproc` module-{$UPDATER_MODULES} && make module-{$UPDATER_MODULES}-install_subtargets" && \ - rm -rf /build-qt +COPY md5sums-qt.txt build-qt.sh qt*.patch /build-qt/ +ARG release +# Note: {foo:+bar} here is a syntax of the Dockerfile, not the shell! +ENV IPO_ARG=${release:+-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON} +RUN BUILDQT_CMAKE_ARGS="${IPO_ARG} -DCMAKE_POSITION_INDEPENDENT_CODE=OFF -DFEATURE_reduce_relocations=OFF" CXXFLAGS='-fno-pic -no-pie' CFLAGS='-fno-pic -no-pie' PKG_CONFIG_PATH=/openssl/lib64/pkgconfig ./build-qt.sh linux && mv qt_linux /qt && rm -rf /build-qt ############### # Build aria2 # @@ -61,7 +82,7 @@ COPY .git/modules/aria2 /updater/.git/modules/aria2 COPY build-aria.sh /updater/ WORKDIR /updater/aria2 RUN OPENSSL_LIBS='-L/openssl/lib64 -lssl -lcrypto -lpthread -ldl' OPENSSL_CFLAGS='-I /openssl/include' \ - CFLAGS=-Os CXXFLAGS=-Os ../build-aria.sh --with-openssl + CFLAGS='-Os -fno-pic -no-pie' CXXFLAGS='-Os -fno-pic -no-pie' ../build-aria.sh --with-openssl ################# # Build updater # @@ -69,14 +90,13 @@ RUN OPENSSL_LIBS='-L/openssl/lib64 -lssl -lcrypto -lpthread -ldl' OPENSSL_CFLAGS COPY . /updater RUN set -e; for D in . quazip fluid; do cd /updater/$D && git clean -dXff; done WORKDIR /build -RUN /qt/bin/qmake -config release QMAKE_LFLAGS+="-no-pie" /updater && make -j`nproc` +RUN PKG_CONFIG_PATH=/openssl/lib64/pkgconfig CXXFLAGS='-no-pie -fno-pic' CFLAGS='-no-pie -fno-pic' cmake -G Ninja -DCMAKE_POSITION_INDEPENDENT_CODE=OFF -DCMAKE_FIND_ROOT_PATH=/qt -DCMAKE_BUILD_TYPE=MinSizeRel ${IPO_ARG} /updater && ninja RUN mv updater updater-nonstripped && strip updater-nonstripped -o updater # Version check: do not depend on glibc > 2.31 RUN echo GLIBC_2.31 > target_version && \ grep -aoE 'GLIBC_[0-9.]+' updater > symbol_versions && \ cat target_version symbol_versions | sort -V | tail -1 | tee max_version && \ diff -q target_version max_version -ARG release RUN if [ -n "$release" ]; then cp updater UnvanquishedUpdater && 7z -tzip -mx=9 a UnvUpdaterLinux.zip UnvanquishedUpdater; fi ENV zipfile=${release:+UnvUpdaterLinux.zip} CMD cp updater updater-nonstripped $zipfile /build-docker diff --git a/Dockerfile.win b/Dockerfile.win index 3d1600a..3683b3e 100644 --- a/Dockerfile.win +++ b/Dockerfile.win @@ -10,38 +10,45 @@ # from .git since a checked-in file will not be ignored. For aria2 it is assumed that the data # is stored in the updater/.git/modules directory. -FROM docker.io/debian:bullseye-slim +FROM docker.io/debian:trixie-slim + +# Prevents warning spam from Qt 6's rcc +ENV LANG=C.UTF-8 + RUN apt-get update && apt-get install -y \ autoconf \ autopoint \ + cmake \ curl \ gettext \ g++ \ - g++-mingw-w64-i686 \ + g++-mingw-w64-i686-posix \ git \ libtool \ make \ + ninja-build \ p7zip-full \ pkg-config \ - python \ + python3 \ xz-utils -# The Schannel dependencies are spelled with capital letters which causes them not to be found -RUN ln -s libsecur32.a /usr/i686-w64-mingw32/lib/libSecur32.a && \ - ln -s libcrypt32.a /usr/i686-w64-mingw32/lib/libCrypt32.a - ############ # Build Qt # ############ WORKDIR /build-qt -ENV UPDATER_MODULES=qtbase,qtquickcontrols,qtquickcontrols2,qtsvg,qtgraphicaleffects -RUN curl -LO https://download.qt.io/archive/qt/5.14/5.14.2/single/qt-everywhere-src-5.14.2.tar.xz && \ - curl -L https://download.qt.io/archive/qt/5.14/5.14.2/single/md5sums.txt | md5sum --check --ignore-missing && \ - tar -xJf qt-everywhere-src-5.14.2.tar.xz && \ - cd qt-everywhere-src-5.14.2 && \ - ./configure -release -static -prefix /qt -qt-zlib -qt-libjpeg -qt-libpng -qt-freetype -qt-pcre -qt-harfbuzz -opengl desktop -opensource -confirm-license -no-qml-debug -no-icu -xplatform win32-g++ -device-option CROSS_COMPILE=i686-w64-mingw32- -optimize-size --c++std=14 -nomake tests -nomake tools -nomake examples -schannel -no-feature-d3d12 && \ - bash -c "make -j`nproc` module-{$UPDATER_MODULES} && make module-{$UPDATER_MODULES}-install_subtargets" && \ - rm -rf /build-qt + +# Build host-mode tools and remove everything apart from the installed bin/ and lib/cmake/ +COPY md5sums-qt.txt build-qt.sh qt*.patch cross-toolchain-mingw32.cmake /build-qt/ +RUN ./build-qt.sh tools qtbase qtdeclarative qtshadertools && \ + rm -r build_tools && \ + find qt_tools -mindepth 1 -maxdepth 1 ! -name bin ! -name lib ! -name libexec -exec rm -r {} + && \ + find qt_tools/lib -mindepth 1 -maxdepth 1 ! -name cmake -exec rm -r {} + + +ARG release +# Note: {foo:+bar} here is a syntax of the Dockerfile, not the shell! +ENV IPO_ARG=${release:+-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON} +RUN BUILDQT_CMAKE_ARGS="${IPO_ARG}" +RUN ./build-qt.sh windows && rm -r build_windows ############### # Build aria2 # @@ -59,7 +66,8 @@ RUN CFLAGS=-Os CXXFLAGS=-Os ../build-aria.sh ARIA2_STATIC=yes --host i686-w64-mi COPY . /updater RUN set -e; for D in . quazip fluid; do cd /updater/$D && git clean -dXff; done WORKDIR /build -RUN /qt/bin/qmake -config release QMAKE_LFLAGS+="-static" INCLUDEPATH+=/qt/include/QtZlib /updater && make -j`nproc` +RUN cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=/build-qt/cross-toolchain-mingw32.cmake -DCMAKE_FIND_ROOT_PATH=/build-qt/qt_windows -DCMAKE_BUILD_TYPE=MinSizeRel ${IPO_ARG} /updater && ninja +RUN mv updater.exe updater-nonstripped.exe && i686-w64-mingw32-strip updater-nonstripped.exe -o updater.exe WORKDIR /release-win ARG release -RUN if [ -n "$release" ]; then cp /build/release/updater.exe UnvanquishedUpdater.exe && 7z -tzip -mx=9 a UnvUpdaterWin.zip UnvanquishedUpdater.exe; fi +RUN if [ -n "$release" ]; then cp /build/updater.exe UnvanquishedUpdater.exe && 7z -tzip -mx=9 a UnvUpdaterWin.zip UnvanquishedUpdater.exe; fi diff --git a/DownloadInfo.qml b/DownloadInfo.qml index 65a8943..283bd3d 100644 --- a/DownloadInfo.qml +++ b/DownloadInfo.qml @@ -15,12 +15,11 @@ * along with this program. If not, see . */ -import QtQuick 2.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 -import Fluid.Controls 1.0 as FluidControls -import Fluid.Material 1.0 as FluidMaterial -import QmlDownloader 1.0 +import Fluid 2.0 as Fluid +import QmlDownloader +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material import "utils.js" as Utils Item { @@ -33,7 +32,7 @@ Item { bottomMargin: 60 } - FluidControls.Card { + Fluid.Card { anchors { right: parent.right } @@ -50,7 +49,7 @@ Item { width: parent.width height: parent.height - FluidControls.BodyLabel { + Fluid.BodyLabel { id: instruction anchors { @@ -85,70 +84,70 @@ Item { visible: false - FluidControls.BodyLabel { + Fluid.BodyLabel { width: 5 } - FluidControls.BodyLabel { + Fluid.BodyLabel { id: completedDownload text: Utils.humanSize(downloader.completedSize) font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { text: " / " font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { id: totalDownload text: Utils.humanSize(downloader.totalSize) font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { width: 20 } - FluidControls.BodyLabel { + Fluid.BodyLabel { id: eta text: Utils.humanTime(downloader.eta) font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { width: 20 } - FluidControls.BodyLabel { + Fluid.BodyLabel { text: "DL: " font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { id: downloadSpeed text: Utils.humanSize(downloader.downloadSpeed) font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { width: 20 text: "/s" font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { text: "UL: " font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { id: uploadSpeed text: Utils.humanSize(downloader.uploadSpeed) font.pixelSize: 17 } - FluidControls.BodyLabel { + Fluid.BodyLabel { text: "/s" font.pixelSize: 17 } @@ -156,7 +155,7 @@ Item { } } - FluidMaterial.ActionButton { + Fluid.FloatingActionButton { id: downloadAction anchors { @@ -169,7 +168,8 @@ Item { height: 70 width: 70 - iconName: "file/file_download" + icon.source: Fluid.Utils.iconUrl("file/file_download") + icon.color: "white" scale: 1.2 Material.elevation: 1 @@ -192,13 +192,13 @@ Item { function onStateChanged(state) { downloadInfo.visible = state !== QmlDownloader.COMPLETED; if (state === QmlDownloader.DOWNLOADING) { - downloadAction.iconName = "av/pause"; + downloadAction.icon.source = Fluid.Utils.iconUrl("av/pause"); instruction.visible = false; } else if (state === QmlDownloader.PAUSED) { - downloadAction.iconName = "file/file_download"; + downloadAction.icon.source = Fluid.Utils.iconUrl("file/file_download"); instruction.visible = false; } else if (state === QmlDownloader.COMPLETED) { - downloadAction.iconName = "av/play_arrow"; + downloadAction.icon.source = Fluid.Utils.iconUrl("av/play_arrow"); instruction.visible = true; instruction.text = "Press the button to play the game"; root.alert(0); diff --git a/News.qml b/News.qml index dff5163..daa7d9c 100644 --- a/News.qml +++ b/News.qml @@ -15,11 +15,10 @@ * along with this program. If not, see . */ -import QtQuick 2.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 -import Fluid.Controls 1.0 as FluidControls -import Fluid.Material 1.0 as FluidMaterial +import Fluid 2.0 as Fluid +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material Item { width: parent.width @@ -64,7 +63,7 @@ Item { } } - var component = Qt.createComponent("qrc:/NewsCard.qml"); + var component = Qt.createComponent("qrc:/UnvUpdater/NewsCard.qml"); for (var i = 0; i < newsObj['posts'].length; ++i) { var object = component.createObject(swipe); @@ -112,6 +111,10 @@ Item { Component.onCompleted: { fetchNews('https://unvanquished.net/api/get_recent_posts/'); + + // the button becomes invisible when disabled otherwise + leftButton.background.color = leftButton.Material.background; + rightButton.background.color = rightButton.Material.background; } } @@ -142,7 +145,7 @@ Item { } } - FluidMaterial.ActionButton { + Fluid.FloatingActionButton { id: leftButton anchors.left: parent.left @@ -151,13 +154,14 @@ Item { Material.background: Material.Teal - iconName: "navigation/chevron_left" + icon.source: Fluid.Utils.iconUrl("navigation/chevron_left") + icon.color: "white" onClicked: swipe.decrementCurrentIndex() enabled: swipe.currentIndex > 0 opacity: enabled ? 1 : 0.38 } - FluidMaterial.ActionButton { + Fluid.FloatingActionButton { id: rightButton anchors.right: parent.right @@ -166,7 +170,8 @@ Item { Material.background: Material.Teal - iconName: "navigation/chevron_right" + icon.source: Fluid.Utils.iconUrl("navigation/chevron_right") + icon.color: "white" onClicked: swipe.incrementCurrentIndex() enabled: swipe.currentIndex + 1 < swipe.count opacity: enabled ? 1 : 0.38 diff --git a/NewsCard.qml b/NewsCard.qml index 8264352..7d3e547 100644 --- a/NewsCard.qml +++ b/NewsCard.qml @@ -15,11 +15,11 @@ * along with this program. If not, see . */ -import QtQuick 2.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 -import Fluid.Controls 1.0 as FluidControls -import QtQuick.Layouts 1.3 +import Fluid 2.0 as Fluid +import QtQuick.Layouts +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material Flickable { id: item @@ -110,7 +110,7 @@ Flickable { } } - FluidControls.Card { + Fluid.Card { anchors { right: parent.right top: parent.top @@ -140,9 +140,9 @@ Flickable { width: parent.width height: parent.height - spacing: FluidControls.Units.smallSpacing * 2 + spacing: Fluid.Units.smallSpacing * 2 - FluidControls.TitleLabel { + Fluid.TitleLabel { id: title width: parent.width @@ -155,7 +155,7 @@ Flickable { font.bold: true } - FluidControls.BodyLabel { + Fluid.BodyLabel { id: summary width: parent.width @@ -188,9 +188,9 @@ Flickable { width: parent.width height: parent.height - spacing: FluidControls.Units.smallSpacing * 2 + spacing: Fluid.Units.smallSpacing * 2 - FluidControls.BodyLabel { + Fluid.BodyLabel { id: link width: parent.width diff --git a/README.md b/README.md index ba76c6d..d71b2cd 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ Autoupdates Unvanquished using Unvanquished's CDN git submodule update --init ``` -Note: Fluid has submodules of its own, but they are not used, so the above command is intentionally not recursive. - ## Build for Linux (without Docker) ### Build aria2 @@ -19,10 +17,12 @@ cd .. ``` ### Build updater -Note: you need Qt 5.8 at least. +You need at least Qt 6.8. + ``` -QT_SELECT=5 qmake -config release -make -j4 +mkdir build; cd build +cmake -GNinja .. -DCMAKE_BUILD_TYPE=Release +ninja ``` ## Build Linux version in docker @@ -47,7 +47,7 @@ The first line below runs the Docker build for Windows. The last 3 lines are to ``` docker build -t unvlauncher-win -f Dockerfile.win . docker create --name unvlauncher-win unvlauncher-win -docker cp unvlauncher-win:/build/release/updater.exe ./build-docker +docker cp unvlauncher-win:/build/updater.exe ./build-docker docker rm unvlauncher-win ``` diff --git a/Settings.qml b/Settings.qml index a8fe83e..5a46f48 100644 --- a/Settings.qml +++ b/Settings.qml @@ -15,14 +15,13 @@ * along with this program. If not, see . */ -import QtQuick 2.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 -import QtQuick.Dialogs 1.2 -import QtQuick.Layouts 1.3 -import Fluid.Controls 1.0 as FluidControls -import Fluid.Material 1.0 as FluidMaterial -import QmlDownloader 1.0 +import Fluid 2.0 as Fluid +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Dialogs +import QtQuick.Layouts +import QmlDownloader Item { id: settingsItem @@ -32,29 +31,29 @@ Item { Pane { width: parent.width padding: 16 - FluidControls.DisplayLabel { + Fluid.DisplayLabel { text: "Settings" } } - FluidControls.ThinDivider {} + Fluid.ThinDivider {} GridLayout { columns: 3 rows: 2 - FluidControls.TitleLabel { + Fluid.TitleLabel { text: "Installation Directory:" padding: 16 } - FluidControls.Subheader { + Fluid.Subheader { text: selectedInstallPath } - FluidMaterial.ActionButton { + Fluid.FloatingActionButton { Material.elevation: 1 - iconName: "file/folder" + icon.source: Fluid.Utils.iconUrl("file/folder") onClicked: fileDialog.open() enabled: downloader.state === QmlDownloader.IDLE opacity: enabled ? 1 : 0.38 } - FluidControls.TitleLabel { + Fluid.TitleLabel { text: "Command Line:" padding: 16 } @@ -66,7 +65,7 @@ Item { } } - FileDialog { + FolderDialog { id: fileDialog title: "Please choose a folder" onAccepted: { @@ -75,7 +74,7 @@ Item { if (Qt.platform.os === "windows") { clipRegex = /^file:(\/\/\/)?/; } - var url = fileDialog.fileUrl.toString(); + var url = fileDialog.selectedFolder.toString(); console.log("file URL from dialog: " + url); var path = url + '/Unvanquished'; path = path.replace(clipRegex, '').replace(/\/\/Unvanquished$/, '/Unvanquished'); @@ -84,7 +83,6 @@ Item { } selectedInstallPath = path; } - selectFolder: true } } diff --git a/UpdateFailed.qml b/UpdateFailed.qml index bc0baef..6332059 100644 --- a/UpdateFailed.qml +++ b/UpdateFailed.qml @@ -15,10 +15,10 @@ * along with this program. If not, see . */ -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 -import Fluid.Controls 1.0 as FluidControls +import Fluid 2.0 as Fluid +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material import "utils.js" as Utils Popup { @@ -32,7 +32,7 @@ Popup { property string errorDetail property string failedOperation - FluidControls.BodyLabel { + Fluid.BodyLabel { id: errorPopupBody width: parent.width text: ('

' + failedOperation + ' failed.

' + @@ -55,7 +55,7 @@ Popup { } } - FluidControls.BodyLabel { + Fluid.BodyLabel { text: errorPopupBody.hoveredLink anchors.bottom: parent.bottom } diff --git a/build-qt.sh b/build-qt.sh new file mode 100755 index 0000000..3dfe2ad --- /dev/null +++ b/build-qt.sh @@ -0,0 +1,355 @@ +#!/usr/bin/env bash + +# Usage: [EXTRA_CMAKE_ARGS=] build-qt.sh [...] +# installs to ./qt_/ + +set -e +set -u +set -o pipefail + +prefix_output() { + prefix="${1}" + shift + "$@" 2>&1 | sed "s/^/${prefix}/" +} + +module_vars() { + url="https://download.qt.io/archive/qt/6.8/6.8.3/submodules/${1}-everywhere-src-6.8.3.tar.xz" + archive="${url##*/}" + dirname="build_${sysname}/${archive%.tar.*}" +} + + +build_module() { + module="${1}" + module_vars "${module}" + cd "${WORK_DIR}/${dirname}" + options_var="options_${module}" + if [[ "${module}" = qtbase ]]; then + patch -p1 < "${SCRIPT_DIR}/qtbase.patch" + ./configure ${!options_var} ${common_options_cmake} + else + if [[ "${module}" = qtdeclarative ]]; then + patch -p1 < "${SCRIPT_DIR}/qtdeclarative-Propagate-modality-to-the-non-native-quick-dialogs.patch" + fi + "${INSTALL_DIR}/bin/qt-configure-module" . ${!options_var} ${common_options_cmake} + fi + ninja + cmake --install . +} + +sysname="${1}" +shift + +WORK_DIR="${PWD}" +SCRIPT_DIR=$(realpath "$(dirname "$0")") +INSTALL_DIR="${WORK_DIR}/qt_${sysname}" + +#FIXME bad warning in qtdeclarative-everywhere-src-6.8.3/src/quickwidgets/qquickwidget.cpp + +common_options_cmake=" + -DQT_GENERATE_SBOM=OFF + ${BUILDQT_CMAKE_ARGS:-} +" + +base_features=' + -DFEATURE_accessibility=OFF + -DFEATURE_androiddeployqt=OFF + -DFEATURE_animation=ON + -DFEATURE_cborstreamwriter=OFF + -DFEATURE_clipboard=ON + -DFEATURE_columnview=OFF + -DFEATURE_commandlinkbutton=OFF + -DFEATURE_completer=OFF + -DFEATURE_concatenatetablesproxy=OFF + -DFEATURE_concurrent=OFF + -DFEATURE_contextmenu=OFF + -DFEATURE_cssparser=ON + -DFEATURE_cursor=ON + -DFEATURE_datawidgetmapper=OFF + -DFEATURE_datetimeedit=OFF + -DFEATURE_dial=OFF + -DFEATURE_dialogbuttonbox=ON + -DFEATURE_dockwidget=OFF + -DFEATURE_draganddrop=OFF + -DFEATURE_dtls=OFF + -DFEATURE_easingcurve=ON + -DFEATURE_evdev=OFF + -DFEATURE_filedialog=OFF + -DFEATURE_filesystemmodel=OFF + -DFEATURE_filesystemwatcher=OFF + -DFEATURE_fontcombobox=OFF + -DFEATURE_fontdialog=OFF + -DFEATURE_formlayout=OFF + -DFEATURE_fscompleter=OFF + -DFEATURE_future=OFF + -DFEATURE_gestures=OFF + -DFEATURE_graphicsview=OFF + -DFEATURE_groupbox=OFF + -DFEATURE_hijricalendar=OFF + -DFEATURE_identityproxymodel=OFF + -DFEATURE_imageformat_bmp=OFF + -DFEATURE_imageformat_jpeg=ON + -DFEATURE_imageformat_png=ON + -DFEATURE_imageformat_ppm=OFF + -DFEATURE_imageformat_xbm=OFF + -DFEATURE_imageformat_xpm=OFF + -DFEATURE_imageformatplugin=ON + -DFEATURE_imageio_text_loading=OFF + -DFEATURE_inputdialog=OFF + -DFEATURE_islamiccivilcalendar=OFF + -DFEATURE_itemmodel=ON + -DFEATURE_itemviews=OFF + -DFEATURE_jalalicalendar=OFF + -DFEATURE_keysequenceedit=OFF + -DFEATURE_label=ON + -DFEATURE_lcdnumber=OFF + -DFEATURE_library=OFF + -DFEATURE_lineedit=OFF + -DFEATURE_listview=OFF + -DFEATURE_listwidget=OFF + -DFEATURE_localserver=OFF + -DFEATURE_mdiarea=OFF + -DFEATURE_menu=OFF + -DFEATURE_menubar=OFF + -DFEATURE_messagebox=ON + -DFEATURE_mimetype=OFF + -DFEATURE_mimetype_database=OFF + -DFEATURE_movie=OFF + -DFEATURE_networkdiskcache=OFF + -DFEATURE_pdf=OFF + -DFEATURE_picture=OFF + -DFEATURE_printsupport=OFF + -DFEATURE_progressbar=OFF + -DFEATURE_proxymodel=OFF + -DFEATURE_publicsuffix_qt=OFF + -DFEATURE_publicsuffix_system=OFF + -DFEATURE_pushbutton=ON + -DFEATURE_qmake=OFF + -DFEATURE_radiobutton=OFF + -DFEATURE_rubberband=OFF + -DFEATURE_scrollarea=OFF + -DFEATURE_scrollbar=OFF + -DFEATURE_scroller=OFF + -DFEATURE_sessionmanager=OFF + -DFEATURE_settings=ON + -DFEATURE_shortcut=ON + -DFEATURE_sizegrip=OFF + -DFEATURE_slider=OFF + -DFEATURE_socks5=OFF + -DFEATURE_sortfilterproxymodel=OFF + -DFEATURE_spinbox=OFF + -DFEATURE_splitter=OFF + -DFEATURE_sql=OFF + -DFEATURE_stackedwidget=OFF + -DFEATURE_standarditemmodel=OFF + -DFEATURE_statusbar=OFF + -DFEATURE_statustip=OFF + -DFEATURE_stringlistmodel=OFF + -DFEATURE_style_fusion=OFF + -DFEATURE_style_stylesheet=OFF + -DFEATURE_style_windows=ON + -DFEATURE_style_windows11=OFF + -DFEATURE_style_windowsvista=OFF + -DFEATURE_syntaxhighlighter=OFF + -DFEATURE_systemtrayicon=OFF + -DFEATURE_tabbar=OFF + -DFEATURE_tabletevent=OFF + -DFEATURE_tableview=OFF + -DFEATURE_tabwidget=OFF + -DFEATURE_testlib=OFF + -DFEATURE_textbrowser=OFF + -DFEATURE_textedit=OFF + -DFEATURE_textmarkdownreader=OFF + -DFEATURE_textmarkdownwriter=OFF + -DFEATURE_textodfwriter=OFF + -DFEATURE_timezonelocale=ON + -DFEATURE_toolbar=OFF + -DFEATURE_toolbox=OFF + -DFEATURE_toolbutton=OFF + -DFEATURE_tooltip=OFF + -DFEATURE_topleveldomain=OFF + -DFEATURE_translation=OFF + -DFEATURE_transposeproxymodel=OFF + -DFEATURE_treeview=OFF + -DFEATURE_treewidget=OFF + -DFEATURE_tuiotouch=OFF + -DFEATURE_udpsocket=OFF + -DFEATURE_undocommand=OFF + -DFEATURE_undogroup=OFF + -DFEATURE_undostack=OFF + -DFEATURE_undoview=OFF + -DFEATURE_validator=OFF + -DFEATURE_vkgen=OFF + -DFEATURE_vnc=OFF + -DFEATURE_whatsthis=OFF + -DFEATURE_widgettextcontrol=ON + -DFEATURE_wizard=OFF + -DFEATURE_xml=OFF + -DFEATURE_xmlstream=ON +' + +options_qtbase=" + -opensource + -confirm-license + -release + -optimize-size + -no-shared + -static + --c++std=17 + -disable-deprecated-up-to 0x060800 + -reduce-exports + -gc-binaries + -nomake tests + -nomake examples + -no-gif + -no-icu + -no-glib + -opengl desktop + -no-eglfs + -no-opengles3 + -no-egl + -qt-freetype + -qt-pcre + -qt-harfbuzz + -qt-libpng + -qt-libjpeg + -prefix ${INSTALL_DIR} + -- + ${base_features} + -DFEATURE_opengl_desktop=ON + -DQT_BUILD_DOCS=OFF +" +options_qt5compat='--' +options_qtsvg='--' +options_qtshadertools='--' +options_qtdeclarative=' + -- + -DBUILD_WITH_PCH=OFF + -DFEATURE_qml_animation=ON + -DFEATURE_qml_debug=OFF + -DFEATURE_qml_jit=OFF + -DFEATURE_qml_locale=ON + -DFEATURE_qml_profiler=OFF + -DFEATURE_qml_xml_http_request=ON + -DFEATURE_qml_xmllistmodel=OFF + -DFEATURE_quick_designer=OFF + -DFEATURE_quick_particles=OFF + -DFEATURE_quick_tableview=OFF + -DFEATURE_quick_treeview=OFF + -DFEATURE_quickcontrols2_fluentwinui3=OFF + -DFEATURE_quickcontrols2_fusion=OFF + -DFEATURE_quickcontrols2_imagine=OFF + -DFEATURE_quickcontrols2_universal=OFF + -DFEATURE_quickcontrols2_windows=OFF + -DFEATURE_quicktemplates2_calendar=OFF + -DFEATURE_quicktemplates2_container=ON + -DFEATURE_quicktemplates2_hover=OFF + -DFEATURE_quicktemplates2_multitouch=OFF +' + +case "${sysname}" in +linux) + options_qtbase=" + -dbus-runtime + -openssl-linked + -qpa xcb + -system-zlib + -xkbcommon + ${options_qtbase} + -DFEATURE_xcb=ON + -DFEATURE_xcb_glx_plugin=ON + " + ;; +macos) + ;; +windows) + options_qtbase=" + -device-option CROSS_COMPILE=i686-w64-mingw32- + -xplatform win32-g++ + -schannel + ${options_qtbase} + -DFEATURE_imageformat_xpm=ON + -DFEATURE_library=ON + -DCMAKE_TOOLCHAIN_FILE=${SCRIPT_DIR}/cross-toolchain-mingw32.cmake + -DQT_HOST_PATH=${WORK_DIR}/qt_tools + " + # -no-feature-d3d12 + + ;; +tools) + options_qtbase=" + --c++std=17 + -release + -static + -qpa none + -no-opengl + -no-harfbuzz + -no-freetype + -no-ico + -no-gif + -no-xkbcommon + -no-openssl + -prefix ${INSTALL_DIR} + -- + ${base_features} + -DFEATURE_widgets=OFF + -DFEATURE_network=OFF + -DFEATURE_harfbuzz=OFF + -DFEATURE_evdev=OFF + -DFEATURE_cursor=OFF + -DFEATURE_linuxfb=OFF + -DFEATURE_freetype=OFF + -DxxxFEATURE_pcre2=OFF + -DFEATURE_libinput=OFF + -DFEATURE_imageformat_jpeg=OFF + -DFEATURE_imageformat_png=OFF + -DFEATURE_imageformatplugin=OFF + " + options_qtdeclarative=' + -- + ' + ;; +*) + echo 'arg 1 should be linux|macos|windows' + exit 1 +esac + +# qt5compat depends on qtdeclarative +# qtdeclarative depends on qtshadertools +# qtdeclarative optionally depends on qtsvg but we don't actually want that? +# Also in the tools build we strategically build qtdeclarative before qtshadertools to disable +# the bulk of QML targets (TODO: disable them explicitly with options?) + +MODULES=${@:-qtbase qtshadertools qtdeclarative qt5compat qtsvg} + +# for bloaty +# options_qtbase="-force-debug-info ${options_qtbase}" + +#FIXME +options_qtbase+=' -DFEATURE_dbus=OFF -DQT_FEATURE_dbus=OFF' + +# Download in parallel +for module in $MODULES; do + module_vars "${module}" + if [[ ! -e "${archive}" ]]; then + curl -LO "${url}" & + fi +done +wait + +md5sum --check --ignore-missing "${SCRIPT_DIR}/md5sums-qt.txt" + +mkdir -p "${WORK_DIR}/build_${sysname}" + +# Nuke old dir; extract in parallel +for module in $MODULES; do + module_vars "${module}" + rm -rf "${dirname}" + tar -C "${WORK_DIR}/build_${sysname}" -xJf "${archive}" & +done +wait + +for module in $MODULES; do + prefix_output "${module}| " build_module "${module}" +done diff --git a/cross-toolchain-mingw32.cmake b/cross-toolchain-mingw32.cmake new file mode 100644 index 0000000..c333402 --- /dev/null +++ b/cross-toolchain-mingw32.cmake @@ -0,0 +1,14 @@ +# Target operating system and architecture +set( CMAKE_SYSTEM_NAME Windows ) +set( CMAKE_SYSTEM_PROCESSOR x86 ) + +# C/C++ compilers +set( CMAKE_C_COMPILER i686-w64-mingw32-gcc ) +set( CMAKE_CXX_COMPILER i686-w64-mingw32-g++ ) +set( CMAKE_RC_COMPILER i686-w64-mingw32-windres ) + +# Find programs using host paths and headers/libraries using target paths +# FIXME: not respected when cmake invokes pkg-config +set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) +set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) +set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) diff --git a/fluid b/fluid index 60ff2cf..c8fbf46 160000 --- a/fluid +++ b/fluid @@ -1 +1 @@ -Subproject commit 60ff2cfa5eee9eba4ce3824669c2094fa7116920 +Subproject commit c8fbf46c4afc882b2d4a3dc4908b643f85feb3e1 diff --git a/fluid.cmake b/fluid.cmake new file mode 100644 index 0000000..23bd8ce --- /dev/null +++ b/fluid.cmake @@ -0,0 +1,122 @@ +# This file was created the same as fluid/src/controls/CMakeLists.txt in the +# fluid submodule commit, with a few changes: +# - rejigger QML module structure (rebased to upstream at https://github.com/lirios/fluid/pull/362) +# - make the library static +# - remove an install command +# - make it work regardless of CMAKE_CURRENT_SOURCE_DIR (i.e. without add_subdirectory) +# - remove the custom plugin class (controlsplugin.cpp) and use the auto-generated one. Thes +# custom plugin class registers the image provider, which +# we no longer use. Using a custom plugin class disables a ton of helpful Qt infrastructure for +# automatic registration, and with the aggressive linker flags we are using, which don't follow +# the C++ standard and remove things even from referenced translation units, it's very difficult +# to get it to stop removing the plugin registration code. + +set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/fluid/src/controls") + +set(LIBNAME Fluid) + +# Source files +set(_sources + # cpp/controlsplugin.cpp cpp/controlsplugin.h + cpp/core/clipboard.cpp cpp/core/clipboard.h + cpp/core/controlsutils.cpp cpp/core/controlsutils.h + cpp/core/device.cpp cpp/core/device.h + cpp/core/inputregion.cpp cpp/core/inputregion.h + cpp/core/standardpaths.cpp cpp/core/standardpaths.h + cpp/datetime/datepicker.cpp cpp/datetime/datepicker.h + cpp/datetime/dateselector.cpp cpp/datetime/dateselector.h + cpp/datetime/datetimepicker.cpp cpp/datetime/datetimepicker.h + cpp/datetime/dateutils.cpp cpp/datetime/dateutils.h + cpp/datetime/picker.cpp cpp/datetime/picker.h + cpp/datetime/timepicker.cpp cpp/datetime/timepicker.h + cpp/datetime/timeselector.cpp cpp/datetime/timeselector.h + cpp/datetime/yearmodel.cpp cpp/datetime/yearmodel.h + cpp/datetime/yearselector.cpp cpp/datetime/yearselector.h + cpp/iconthemeimageprovider.cpp cpp/iconthemeimageprovider.h + cpp/style/color.cpp cpp/style/color.h + cpp/style/style.cpp cpp/style/style.h +) + +# QML files +file(GLOB_RECURSE _qml CONFIGURE_DEPENDS + RELATIVE "${SOURCE_DIR}" + "${SOURCE_DIR}/qml/*.qml" "${SOURCE_DIR}/qml/**/*.qml" +) +foreach(_qmlfile ${_qml}) + set_source_files_properties("${SOURCE_DIR}/${_qmlfile}" PROPERTIES QT_RESOURCE_ALIAS "${_qmlfile}") +endforeach() + +string(REGEX REPLACE cpp/ "${SOURCE_DIR}/cpp/" _sources "${_sources}") +string(REGEX REPLACE qml/ "${SOURCE_DIR}/qml/" _qml "${_qml}") + +# ------------------------------------------------------------ +# Define the QML module +# ------------------------------------------------------------ +set_source_files_properties("${SOURCE_DIR}/qml/core/Units.qml" PROPERTIES + QT_QML_SINGLETON_TYPE TRUE +) + +qt_add_qml_module(${LIBNAME} STATIC + URI Fluid + VERSION 2.0 + SOURCES ${_sources} + QML_FILES ${_qml} + IMPORTS + QtQuick.Layouts + DEPENDENCIES + QtQuick + QtQuick.Templates + #Fluid.Private + PLUGIN_TARGET ${LIBNAME} + CLASS_NAME FluidPlugin + NO_PLUGIN_OPTIONAL +) + +set_target_properties(${LIBNAME} PROPERTIES + AUTOMOC ON + AUTORCC ON + AUTOUIC ON +) +target_include_directories(${LIBNAME} + PUBLIC + ${SOURCE_DIR}/cpp/core + ${SOURCE_DIR}/cpp/datetime + ${SOURCE_DIR}/cpp/style +) +target_link_libraries(${LIBNAME} + PRIVATE + Qt6::Core + Qt6::Gui + Qt6::GuiPrivate + Qt6::Qml + Qt6::Quick + Qt6::QuickControls2 + Qt6::Svg +) +target_compile_definitions(${LIBNAME} + PRIVATE + FLUID_INSTALL_ICONS=$,1,0> +) + +install(TARGETS ${LIBNAME} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +# qt_install_qml_module(${LIBNAME}) + +if(FLUID_INSTALL_ICONS) + file(GLOB icons "${SOURCE_DIR}/icons/*/*.svg") + foreach(source_path IN LISTS icons) + string(REPLACE "${SOURCE_DIR}/icons/" "" icon_basename "${source_path}") + get_filename_component(_category "${icon_basename}" DIRECTORY) + install(FILES "${source_path}" DESTINATION "${QML_INSTALL_DIR}/Fluid/icons/${_category}") + endforeach() +else() + file(GLOB_RECURSE _icons CONFIGURE_DEPENDS + "${SOURCE_DIR}/icons/*/*.svg" + ) + qt_add_resources(${LIBNAME} FluidIcons + PREFIX "/liri.io/fluid" + BASE "${SOURCE_DIR}" + FILES ${_icons} + ) +endif() diff --git a/main.cpp b/main.cpp index 9ae9a89..640e846 100644 --- a/main.cpp +++ b/main.cpp @@ -28,9 +28,6 @@ #include #include -#include "iconsimageprovider.h" -#include "iconthemeimageprovider.h" - #include "gamelauncher.h" #include "qmldownloader.h" #include "settings.h" @@ -162,7 +159,6 @@ int main(int argc, char *argv[]) Sys::initApplicationName(); QCoreApplication::setApplicationVersion(updaterAppVersion()); QCoreApplication::setOrganizationDomain("unvanquished.net"); - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); // The font is already needed to display our arg parsing error on Linux @@ -208,14 +204,14 @@ int main(int argc, char *argv[]) return 0; } + // Needed to fetch disconnect_posts.json + qputenv("QML_XHR_ALLOW_FILE_READ", "1"); + SplashController splashController( options.relaunchCommand, options.updateUpdaterVersion, options.connectUrl, settings); splashController.checkForUpdate(); QmlDownloader downloader(options.ariaLogFilename, options.connectUrl, settings); QQmlApplicationEngine engine; - engine.addImportPath(QLatin1String("qrc:/")); - engine.addImageProvider(QLatin1String("fluidicons"), new IconsImageProvider()); - engine.addImageProvider(QLatin1String("fluidicontheme"), new IconThemeImageProvider()); // Top-level windows can be attached to this so that they aren't QObject-children of the // splash screen. Must destruct before engine. @@ -233,6 +229,6 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType( "QmlDownloader", 1, 0, "QmlDownloader", "QmlDownloader not constructible"); - engine.load(QUrl(QLatin1String("qrc:/splash.qml"))); + engine.load(QUrl(QLatin1String("qrc:/UnvUpdater/splash.qml"))); return app.exec(); } diff --git a/main.qml b/main.qml index 5c83b9e..60d53b7 100644 --- a/main.qml +++ b/main.qml @@ -15,11 +15,10 @@ * along with this program. If not, see . */ -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 -import Fluid.Controls 1.0 as FluidControls -import Fluid.Material 1.0 as FluidMaterial +import Fluid 2.0 as Fluid +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material import "utils.js" as Utils ApplicationWindow { @@ -103,12 +102,13 @@ ApplicationWindow { source: "qrc:/resources/logo.png" } - FluidMaterial.ActionButton { + Fluid.FloatingActionButton { id: settingsAction scale: 0.55 anchors.top: parent.top anchors.right: parent.right - iconName: "action/settings" + icon.source: Fluid.Utils.iconUrl("action/settings") + icon.color: "white" Material.elevation: 1 Material.background: Material.Teal onClicked: settingsBottomSheet.open() @@ -119,23 +119,24 @@ ApplicationWindow { DownloadInfo { id: downloadInfo } - FluidMaterial.BottomSheet { + Fluid.BottomSheet { id: settingsBottomSheet width: parent.width maxHeight: parent.height * 0.30 height: maxHeight Settings {} - FluidMaterial.ActionButton { + Fluid.FloatingActionButton { scale: 0.55 anchors.top: parent.top anchors.right: parent.right - iconName: "navigation/cancel" + icon.source: Fluid.Utils.iconUrl("navigation/cancel") + icon.color: "white" Material.elevation: 1 Material.background: Material.Red onClicked: settingsBottomSheet.close() } } - FluidControls.InfoBar { + Fluid.SnackBar { id: infoBar duration: 3000 onClicked: { diff --git a/md5sums-qt.txt b/md5sums-qt.txt new file mode 100644 index 0000000..fe8edd9 --- /dev/null +++ b/md5sums-qt.txt @@ -0,0 +1,78 @@ +9ccf44f7452b8cd3070873134ed3267b qt3d-everywhere-src-6.8.3.tar.xz +fb56d494d51d4a39bc3a93b9ccd3737c qt3d-everywhere-src-6.8.3.zip +78368f6f80e5c54056fd41a9a28f1fdf qt5compat-everywhere-src-6.8.3.tar.xz +baf7361b29093185991ca6d797716a6f qt5compat-everywhere-src-6.8.3.zip +e810d97949083717491040b9e8297ae3 qtactiveqt-everywhere-src-6.8.3.tar.xz +f3c1ce2f4fe3d0f059c54f3346339fa9 qtactiveqt-everywhere-src-6.8.3.zip +540e9665dbfd9a2cf98e6e4b4aa4bb98 qtbase-everywhere-src-6.8.3.tar.xz +4ca5367b3c38a2acdfe562d4eb0a731f qtbase-everywhere-src-6.8.3.zip +4bdd1b1c80f360f9e92540799c16f3bf qtcharts-everywhere-src-6.8.3.tar.xz +af34b191fe6f19c75edb026f2fdb47e4 qtcharts-everywhere-src-6.8.3.zip +3d80e6794aea4c630c8158aeb4b79489 qtconnectivity-everywhere-src-6.8.3.tar.xz +b25369bfb3b29d197414b61d4ddef536 qtconnectivity-everywhere-src-6.8.3.zip +7bde9c32c152f38bb396105d5a9ff5d1 qtdatavis3d-everywhere-src-6.8.3.tar.xz +bd8db1dca7b076f0fdc866ed72b3dfd8 qtdatavis3d-everywhere-src-6.8.3.zip +eaa93a309823ec6f75edde418df8f2d1 qtdeclarative-everywhere-src-6.8.3.tar.xz +b7c0d093112bd1f63a19c49bb0295e04 qtdeclarative-everywhere-src-6.8.3.zip +497e653d8fc841a711c31d3d066eed56 qtdoc-everywhere-src-6.8.3.tar.xz +83e00370ca94098d8bff23ced1f9db9a qtdoc-everywhere-src-6.8.3.zip +0d1c1a2d2f6e44a14564c362c263e31c qtgraphs-everywhere-src-6.8.3.tar.xz +daf3234003ba7abe2bfb8e8e3a165775 qtgraphs-everywhere-src-6.8.3.zip +80db499605b0536b58a320a37141b160 qtgrpc-everywhere-src-6.8.3.tar.xz +6b831de63bb6955c0004ba91f09dc540 qtgrpc-everywhere-src-6.8.3.zip +c26a03f93707c10184ac2c4033b56311 qthttpserver-everywhere-src-6.8.3.tar.xz +4398dab44ab3d194df119817c6461a75 qthttpserver-everywhere-src-6.8.3.zip +2f4c280e717cffaa3fc7ac06c1c3c316 qtimageformats-everywhere-src-6.8.3.tar.xz +1ff007f1bd2e985dcf476345e2051c0f qtimageformats-everywhere-src-6.8.3.zip +09c079a47f3c4ba51770ecb8669f885e qtlanguageserver-everywhere-src-6.8.3.tar.xz +fcf40a7e4d5020aafeff15b852ad5556 qtlanguageserver-everywhere-src-6.8.3.zip +6d547d2fef64ac7561a1331326027655 qtlocation-everywhere-src-6.8.3.tar.xz +005bd0070ecd0cb89fac0a0b556a3b5e qtlocation-everywhere-src-6.8.3.zip +6bb947a82d72a3456abd58810abd7746 qtlottie-everywhere-src-6.8.3.tar.xz +d38d7af7bffb7095c0cef0774a8a7a40 qtlottie-everywhere-src-6.8.3.zip +0039c6617bf106aa49fc5df2bf280caa qtmultimedia-everywhere-src-6.8.3.tar.xz +1778ee4d0962660ccd542ad4f7630b46 qtmultimedia-everywhere-src-6.8.3.zip +90c15e23cede02e657a439204183c94a qtnetworkauth-everywhere-src-6.8.3.tar.xz +5cf94176dd5ecb49d283801c1c959794 qtnetworkauth-everywhere-src-6.8.3.zip +43432266469361daab3bf69025a58d25 qtpositioning-everywhere-src-6.8.3.tar.xz +8a068f8a93e8442e487db77baa49c0a9 qtpositioning-everywhere-src-6.8.3.zip +74ea76b919cb0c0cca405bad305fd333 qtquick3d-everywhere-src-6.8.3.tar.xz +5f82afb4de74b4edc235d255f48172b6 qtquick3d-everywhere-src-6.8.3.zip +9fd4df4b0dcd072667d2252501cab183 qtquick3dphysics-everywhere-src-6.8.3.tar.xz +453003a340bbc52cf38528f33891d1a5 qtquick3dphysics-everywhere-src-6.8.3.zip +39254c57278a5bafaf75ffa95d8b9ce3 qtquickeffectmaker-everywhere-src-6.8.3.tar.xz +4659a1991535c627d16d94ffb97da85a qtquickeffectmaker-everywhere-src-6.8.3.zip +8db9445dd162d9dab48fcdee0c60b9e9 qtquicktimeline-everywhere-src-6.8.3.tar.xz +085e42c566d211e8747bc6e5cddd0ad4 qtquicktimeline-everywhere-src-6.8.3.zip +38082db1842dd98002642a37db8229c4 qtremoteobjects-everywhere-src-6.8.3.tar.xz +47dfade94063bf464340c2edfd68d40a qtremoteobjects-everywhere-src-6.8.3.zip +f78b14aaf3bf4fa6728bbc0d38d01246 qtscxml-everywhere-src-6.8.3.tar.xz +8a11e81e8c8b557eb27150f7261bb9ae qtscxml-everywhere-src-6.8.3.zip +036aa04b92d184a3bd065db39ee0c2b3 qtsensors-everywhere-src-6.8.3.tar.xz +35f4aa48f9e1fb43acac307097d9b8ba qtsensors-everywhere-src-6.8.3.zip +978243ea226eee29ed65f3a8d692a437 qtserialbus-everywhere-src-6.8.3.tar.xz +57faaa3aab121c49eeb91fd39ebcc0c9 qtserialbus-everywhere-src-6.8.3.zip +538777b87feb5a7d7e8ba7312d212c56 qtserialport-everywhere-src-6.8.3.tar.xz +12941084cf09a9d30fb869e830f2545f qtserialport-everywhere-src-6.8.3.zip +55c09bd5b6d7584a2f6b3ef0f160bcf9 qtshadertools-everywhere-src-6.8.3.tar.xz +223528f716607652b3626eb96807bc5d qtshadertools-everywhere-src-6.8.3.zip +3c5f2d1aea1a9ef342c590a2ce5b855a qtspeech-everywhere-src-6.8.3.tar.xz +ec899505e629ff9a4cc97407e8318c39 qtspeech-everywhere-src-6.8.3.zip +4748ec76af552d21f2bf2acce45b39af qtsvg-everywhere-src-6.8.3.tar.xz +5e3dc7c9954b817951e26eafaca61a84 qtsvg-everywhere-src-6.8.3.zip +afb1f85b61ad2955f4b3656fc5fbb4a6 qttools-everywhere-src-6.8.3.tar.xz +427f75b188ca60a3ff81974084f91069 qttools-everywhere-src-6.8.3.zip +20be680c1effcebc64fc78090f4e41b7 qttranslations-everywhere-src-6.8.3.tar.xz +24038598b49ee6076d2c58aa8c556dd5 qttranslations-everywhere-src-6.8.3.zip +74fe353ec4ea71f5e9b74886cfa221a4 qtvirtualkeyboard-everywhere-src-6.8.3.tar.xz +988bdd5b169b6c67a3226d0db608c853 qtvirtualkeyboard-everywhere-src-6.8.3.zip +5215ab60ea5f8fcafb35c7709b4eb386 qtwayland-everywhere-src-6.8.3.tar.xz +44891da4779d68ac67f054df883b2f52 qtwayland-everywhere-src-6.8.3.zip +b8a5320eab406aca6a9c40150efcc90b qtwebchannel-everywhere-src-6.8.3.tar.xz +16481f17e1c7bf854fb1189d3f50e586 qtwebchannel-everywhere-src-6.8.3.zip +0c1c72b141b4ba24ce6ac9c1d149c3ce qtwebengine-everywhere-src-6.8.3.tar.xz +73877ec61c8a75ae2b744ccc837ec9f1 qtwebengine-everywhere-src-6.8.3.zip +630424e9ff8827ad2a76f005907d3d35 qtwebsockets-everywhere-src-6.8.3.tar.xz +5f610765c28cfc457d1f2c122d4799c0 qtwebsockets-everywhere-src-6.8.3.zip +c563b0077e28873e65b969978b37c13f qtwebview-everywhere-src-6.8.3.tar.xz +ad0bc97136e11f68b121914343d3e2d8 qtwebview-everywhere-src-6.8.3.zip diff --git a/qml.qrc b/qml.qrc index 0778d24..d917d05 100644 --- a/qml.qrc +++ b/qml.qrc @@ -1,17 +1,9 @@ - main.qml qtquickcontrols2.conf resources/Roboto-Regular.ttf resources/updater.png - News.qml - NewsCard.qml - DownloadInfo.qml - UpdateFailed.qml resources/splash.jpg - splash.qml - Settings.qml - utils.js resources/unvanquished.png resources/background.jpg resources/header.jpg diff --git a/qtbase.patch b/qtbase.patch new file mode 100644 index 0000000..f8dd5b9 --- /dev/null +++ b/qtbase.patch @@ -0,0 +1,71 @@ +diff -u -r qtbase.old/cmake/3rdparty/extra-cmake-modules/find-modules/FindXCB.cmake qtbase.new/cmake/3rdparty/extra-cmake-modules/find-modules/FindXCB.cmake +--- qtbase.old/cmake/3rdparty/extra-cmake-modules/find-modules/FindXCB.cmake 2025-02-13 11:45:28.000000000 -0600 ++++ qtbase.new/cmake/3rdparty/extra-cmake-modules/find-modules/FindXCB.cmake 2025-11-13 19:57:31.987415796 -0600 +@@ -145,7 +145,7 @@ + set(XCB_XCB_component_deps) + set(XCB_COMPOSITE_component_deps XCB XFIXES) + set(XCB_DAMAGE_component_deps XCB XFIXES) +-set(XCB_IMAGE_component_deps XCB SHM) ++set(XCB_IMAGE_component_deps XCB SHM UTIL) + set(XCB_RENDERUTIL_component_deps XCB RENDER) + set(XCB_XFIXES_component_deps XCB RENDER SHAPE) + set(XCB_XVMC_component_deps XCB XV) +diff -u -r qtbase.old/cmake/QtBuildHelpers.cmake qtbase.new/cmake/QtBuildHelpers.cmake +--- qtbase.old/cmake/QtBuildHelpers.cmake 2025-02-13 11:45:28.000000000 -0600 ++++ qtbase.new/cmake/QtBuildHelpers.cmake 2025-11-15 00:50:19.933641770 -0600 +@@ -414,7 +414,6 @@ + # Depends on qt_internal_set_cmake_build_type + qt_internal_setup_cmake_config_postfix() + +- qt_internal_setup_position_independent_code() + qt_internal_set_link_depends_no_shared() + qt_internal_setup_default_install_prefix() + qt_internal_set_qt_source_tree_var() +diff -u -r qtbase.old/src/plugins/platforms/xcb/qxcbconnection_basic.cpp qtbase.new/src/plugins/platforms/xcb/qxcbconnection_basic.cpp +--- qtbase.old/src/plugins/platforms/xcb/qxcbconnection_basic.cpp 2025-02-13 11:45:28.000000000 -0600 ++++ qtbase.new/src/plugins/platforms/xcb/qxcbconnection_basic.cpp 2025-11-23 02:23:12.697507021 -0600 +@@ -361,6 +361,9 @@ + + void QXcbBasicConnection::initializeXKB() + { ++ // Disable the xkb extension. This prevents a dependency on libx11-xkbcommon.so. ++ // Drawback: text can't be selected by shift + arrow keys ++ return; + const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_xkb_id); + if (!reply || !reply->present) { + qCWarning(lcQpaXcb, "XKeyboard extension not present on the X server"); +diff -u -r qtbase.old/src/plugins/platforms/xcb/qxcbconnection_basic.h qtbase.new/src/plugins/platforms/xcb/qxcbconnection_basic.h +--- qtbase.old/src/plugins/platforms/xcb/qxcbconnection_basic.h 2025-02-13 11:45:28.000000000 -0600 ++++ qtbase.new/src/plugins/platforms/xcb/qxcbconnection_basic.h 2025-11-23 01:31:27.807403222 -0600 +@@ -48,7 +48,7 @@ + bool hasXShape() const { return m_hasXhape; } + bool hasXRandr() const { return m_hasXRandr; } + bool hasInputShape() const { return m_hasInputShape; } +- bool hasXKB() const { return m_hasXkb; } ++ bool hasXKB() const { return false; } + bool hasXRender(int major = -1, int minor = -1) const { + if (m_hasXRender && major != -1 && minor != -1) + return m_xrenderVersion >= std::pair(major, minor); +diff -u -r qtbase.old/src/tools/rcc/rcc.cpp qtbase.new/src/tools/rcc/rcc.cpp +--- qtbase.old/src/tools/rcc/rcc.cpp 2025-02-13 11:45:28.000000000 -0600 ++++ qtbase.new/src/tools/rcc/rcc.cpp 2025-11-23 02:47:34.103288435 -0600 +@@ -32,7 +32,7 @@ + CONSTANT_COMPRESSLEVEL_DEFAULT = -1, + CONSTANT_ZSTDCOMPRESSLEVEL_CHECK = 1, // Zstd level to check if compressing is a good idea + CONSTANT_ZSTDCOMPRESSLEVEL_STORE = 14, // Zstd level to actually store the data +- CONSTANT_COMPRESSTHRESHOLD_DEFAULT = 70 ++ CONSTANT_COMPRESSTHRESHOLD_DEFAULT = 1 // compress if savings are at least 1% + }; + + void RCCResourceLibrary::write(const char *str, int len) +diff -u -r qtbase.old/src/tools/uic/CMakeLists.txt qtbase.new/src/tools/uic/CMakeLists.txt +--- qtbase.old/src/tools/uic/CMakeLists.txt 2025-02-13 11:45:28.000000000 -0600 ++++ qtbase.new/src/tools/uic/CMakeLists.txt 2025-11-23 02:24:23.896939637 -0600 +@@ -4,6 +4,7 @@ + ##################################################################### + ## uic Tool: + ##################################################################### ++return() # prevent build error + + qt_get_tool_target_name(target_name uic) + qt_internal_add_tool(${target_name} diff --git a/qtdeclarative-Propagate-modality-to-the-non-native-quick-dialogs.patch b/qtdeclarative-Propagate-modality-to-the-non-native-quick-dialogs.patch new file mode 100644 index 0000000..f22ffc4 --- /dev/null +++ b/qtdeclarative-Propagate-modality-to-the-non-native-quick-dialogs.patch @@ -0,0 +1,253 @@ +From b60cfd52ddc3892a3af860425ee9858598e668d7 Mon Sep 17 00:00:00 2001 +From: Santhosh Kumar +Date: Wed, 21 Aug 2024 18:42:55 +0200 +Subject: [PATCH] Propagate modality to the non-native quick dialogs + +[slipher: rebased it to 6.8.3 and removed tests/ changes] + +The non-native quick dialogs don't block input to the windows even after +setting the modality as ApplicationModal/WindowModal. This is because +non-native platform dialogs (QuickPlaform*Dialogs) didn't set modal to +its respective window (QQuickPopupWindow). + +This patch fixes that issue by setting the modality to the non-native +platform dialogs. + +Task-number: QTBUG-127605 +Pick-to: 6.10 6.9 6.8 +Change-Id: Idb3374e881766ae92adc0360c9b9af5c498dd6df +Reviewed-by: Oliver Eftevaag +--- + .../qquickplatformcolordialog.cpp | 3 ++- + .../qquickplatformfiledialog.cpp | 3 ++- + .../qquickplatformfolderdialog.cpp | 3 ++- + .../qquickplatformfontdialog.cpp | 3 ++- + .../qquickplatformmessagedialog.cpp | 3 ++- + src/quicktemplates/qquickdialog.cpp | 2 ++ + src/quicktemplates/qquickpopup.cpp | 19 ++++++++++++++++--- + src/quicktemplates/qquickpopup_p.h | 2 ++ + src/quicktemplates/qquickpopup_p_p.h | 1 + + src/quicktemplates/qquickpopupwindow.cpp | 7 +++++-- + 10 files changed, 36 insertions(+), 10 deletions(-) + +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformcolordialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformcolordialog.cpp +index 205b4e0b1b..a7f2fdab73 100644 +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformcolordialog.cpp ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformcolordialog.cpp +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -108,7 +109,7 @@ bool QQuickPlatformColorDialog::show(Qt::WindowFlags flags, Qt::WindowModality m + + m_dialog->setTitle(options->windowTitle()); + m_dialog->setOptions(options); +- ++ m_dialog->setWindowModality(modality); + m_dialog->open(); + return true; + } +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfiledialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfiledialog.cpp +index 1c9174a8e4..367f229414 100644 +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfiledialog.cpp ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfiledialog.cpp +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -194,7 +195,7 @@ bool QQuickPlatformFileDialog::show(Qt::WindowFlags flags, Qt::WindowModality mo + m_dialog->setCurrentFolder(QUrl::fromLocalFile(QDir().absolutePath())); + } + } +- ++ m_dialog->setWindowModality(modality); + m_dialog->open(); + return true; + } +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfolderdialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfolderdialog.cpp +index d0ccea353e..dd41ed1ce3 100644 +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfolderdialog.cpp ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfolderdialog.cpp +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -153,7 +154,7 @@ bool QQuickPlatformFolderDialog::show(Qt::WindowFlags flags, Qt::WindowModality + ? options->labelText(QFileDialogOptions::Accept) : QString()); + m_dialog->setRejectLabel(options->isLabelExplicitlySet(QFileDialogOptions::Reject) + ? options->labelText(QFileDialogOptions::Reject) : QString()); +- ++ m_dialog->setWindowModality(modality); + m_dialog->open(); + return true; + } +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfontdialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfontdialog.cpp +index 4ef0b1bec6..e5a8c2ed78 100644 +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformfontdialog.cpp ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformfontdialog.cpp +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -124,7 +125,7 @@ bool QQuickPlatformFontDialog::show(Qt::WindowFlags flags, Qt::WindowModality mo + m_dialog->setOptions(options); + + m_dialog->init(); +- ++ m_dialog->setWindowModality(modality); + m_dialog->open(); + return true; + } +diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickplatformmessagedialog.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickplatformmessagedialog.cpp +index a9f1e858ed..4f2d4df7d4 100644 +--- a/src/quickdialogs/quickdialogsquickimpl/qquickplatformmessagedialog.cpp ++++ b/src/quickdialogs/quickdialogsquickimpl/qquickplatformmessagedialog.cpp +@@ -3,6 +3,7 @@ + + #include "qquickplatformmessagedialog_p.h" + ++#include + #include + #include + +@@ -86,7 +87,7 @@ bool QQuickPlatformMessageDialog::show(Qt::WindowFlags flags, Qt::WindowModality + QSharedPointer options = QPlatformMessageDialogHelper::options(); + m_dialog->setTitle(options->windowTitle()); + m_dialog->setOptions(options); +- ++ m_dialog->setWindowModality(modality); + m_dialog->open(); + return true; + } +diff --git a/src/quicktemplates/qquickdialog.cpp b/src/quicktemplates/qquickdialog.cpp +index 458c3e6ba3..4bb1c3f0d6 100644 +--- a/src/quicktemplates/qquickdialog.cpp ++++ b/src/quicktemplates/qquickdialog.cpp +@@ -7,6 +7,8 @@ + #include "qquickabstractbutton_p.h" + #include "qquickpopupitem_p_p.h" + #include "qquickpopupwindow_p_p.h" ++#include ++#include + + QT_BEGIN_NAMESPACE + +diff --git a/src/quicktemplates/qquickpopup.cpp b/src/quicktemplates/qquickpopup.cpp +index 60806701d4..4c1faf5a45 100644 +--- a/src/quicktemplates/qquickpopup.cpp ++++ b/src/quicktemplates/qquickpopup.cpp +@@ -1098,15 +1098,21 @@ void QQuickPopupPrivate::adjustPopupItemParentAndWindow() + popupWindow = new QQuickPopupWindow(q, window); + popupWindow->setWidth(popupItem->width() + windowInsets().left() + windowInsets().right()); + popupWindow->setHeight(popupItem->height() + windowInsets().top() + windowInsets().bottom()); +- popupWindow->setModality(modal ? Qt::ApplicationModal : Qt::NonModal); ++ if (popupWndModality != Qt::NonModal) ++ popupWindow->setModality(popupWndModality); ++ else ++ popupWindow->setModality(modal ? Qt::ApplicationModal : Qt::NonModal); + popupItem->resetTitle(); + popupWindow->setTitle(m_title); + } + popupItem->setParentItem(popupWindow->contentItem()); + popupItem->forceActiveFocus(Qt::PopupFocusReason); + } +- if (popupWindow) +- popupWindow->setVisible(visible); ++ if (popupWindow && popupWindow->transientParent()) { ++ auto *transientParentPriv = QQuickWindowPrivate::get(qobject_cast(popupWindow->transientParent())); ++ if (!transientParentPriv->inDestructor) ++ popupWindow->setVisible(visible); ++ } + } else { + if (visible) { + popupItem->setParentItem(overlay); +@@ -1129,6 +1135,7 @@ void QQuickPopupPrivate::adjustPopupItemParentAndWindow() + if (!hasZ) + popupItem->setZ(qMax(topPopupItem->z(), popupItem->z())); + } ++ q->setModal((popupWndModality != Qt::NonModal) || modal); + } + + popupItem->setTitle(m_title); +@@ -3378,6 +3385,12 @@ bool QQuickPopup::setAccessibleProperty(const char *propertyName, const QVariant + return d->popupItem->setAccessibleProperty(propertyName, value); + } + ++void QQuickPopup::setWindowModality(const Qt::WindowModality modality) ++{ ++ Q_D(QQuickPopup); ++ d->popupWndModality = modality; ++} ++ + QT_END_NAMESPACE + + #include "moc_qquickpopup_p.cpp" +diff --git a/src/quicktemplates/qquickpopup_p.h b/src/quicktemplates/qquickpopup_p.h +index 089d86ba29..5909ef36e4 100644 +--- a/src/quicktemplates/qquickpopup_p.h ++++ b/src/quicktemplates/qquickpopup_p.h +@@ -312,6 +312,8 @@ public: + void setBottomInset(qreal inset); + void resetBottomInset(); + ++ void setWindowModality(const Qt::WindowModality modality); ++ + enum PopupType { + Item, + Window, +diff --git a/src/quicktemplates/qquickpopup_p_p.h b/src/quicktemplates/qquickpopup_p_p.h +index a8cc14ee33..88ebb7d9f4 100644 +--- a/src/quicktemplates/qquickpopup_p_p.h ++++ b/src/quicktemplates/qquickpopup_p_p.h +@@ -202,6 +202,7 @@ public: + qreal prevScale = 0; + QString m_title; + QQuickPopup::PopupType m_popupType = QQuickPopup::Item; ++ Qt::WindowModality popupWndModality = Qt::NonModal; + + friend class QQuickPopupTransitionManager; + }; +diff --git a/src/quicktemplates/qquickpopupwindow.cpp b/src/quicktemplates/qquickpopupwindow.cpp +index 890c609684..e1e763908d 100644 +--- a/src/quicktemplates/qquickpopupwindow.cpp ++++ b/src/quicktemplates/qquickpopupwindow.cpp +@@ -23,7 +23,7 @@ QT_BEGIN_NAMESPACE + Q_LOGGING_CATEGORY(lcPopupWindow, "qt.quick.controls.popup.window") + + static bool s_popupGrabOk = false; +-static QWindow *s_grabbedWindow = nullptr; ++static QPointer s_grabbedWindow; + + class QQuickPopupWindowPrivate : public QQuickWindowQmlImplPrivate + { +@@ -132,7 +132,10 @@ void QQuickPopupWindow::resizeEvent(QResizeEvent *e) + + void QQuickPopupWindowPrivate::setVisible(bool visible) + { +- if (m_inHideEvent) ++ Q_Q(QQuickPopupWindow); ++ const bool isTransientParentDestroyed = !q->transientParent() ? true : ++ QQuickWindowPrivate::get(qobject_cast(q->transientParent()))->inDestructor; ++ if (m_inHideEvent || isTransientParentDestroyed) + return; + + const bool visibleChanged = QWindowPrivate::visible != visible; +-- +2.47.3 + diff --git a/quazip b/quazip index fc17260..3fd3b29 160000 --- a/quazip +++ b/quazip @@ -1 +1 @@ -Subproject commit fc1726066e21f5b9cf94d374b133a4084a53c601 +Subproject commit 3fd3b299b875fbd2beac4894b8a870d80022cad7 diff --git a/sha256sums-openssl.txt b/sha256sums-openssl.txt new file mode 100644 index 0000000..4be5a5a --- /dev/null +++ b/sha256sums-openssl.txt @@ -0,0 +1 @@ +b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9 *openssl-3.6.0.tar.gz diff --git a/splash.qml b/splash.qml index d944ac8..d10fcf1 100644 --- a/splash.qml +++ b/splash.qml @@ -15,11 +15,10 @@ * along with this program. If not, see . */ -import QtQuick 2.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 -import Fluid.Controls 1.0 as FluidControls -import Fluid.Material 1.0 as FluidMaterial +import Fluid 2.0 as Fluid +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material ApplicationWindow { visible: true @@ -108,7 +107,7 @@ ApplicationWindow { source: "qrc:/resources/splash.jpg" } - FluidControls.BodyLabel { + Fluid.BodyLabel { id: updaterUpdateLabel Material.theme: Material.Dark text: "Updating launcher..." @@ -119,7 +118,7 @@ ApplicationWindow { font.pixelSize: 17 } - FluidMaterial.ActionButton { + Fluid.FloatingActionButton { id: settingsAction anchors { @@ -135,13 +134,16 @@ ApplicationWindow { height: 48 width: 48 - iconName: "action/settings" + icon.source: Fluid.Utils.iconUrl("action/settings") + icon.color: "white" + scale: 1.35 opacity: enabled ? 1 : 0.38 Material.elevation: 0 Material.background: Material.Teal + Material.theme: Material.Light onClicked: { timer.stop();