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();