diff --git a/.github/workflows/clang-tidy-review.yml b/.github/workflows/clang-tidy-review.yml index 3c2a494be04a5..e6205207f93c1 100644 --- a/.github/workflows/clang-tidy-review.yml +++ b/.github/workflows/clang-tidy-review.yml @@ -9,14 +9,14 @@ on: jobs: clang-tidy: runs-on: ubuntu-latest - container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-6.8.1-2 + container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-forky-6.9.2-3 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 - name: Prepare compile_commands.json run: | - cmake -G Ninja -B build -DCMAKE_PREFIX_PATH=/opt/qt -DQT_MAJOR_VERSION=6 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DOPENSSL_ROOT_DIR=/usr/local/lib64 + cmake -G Ninja -B build -DQT_MAJOR_VERSION=6 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_UPDATER=ON -DBUILD_TESTING=1 cd build && ninja - name: Create results directory run: | @@ -24,10 +24,11 @@ jobs: - name: Analyze run: | /usr/bin/git config --global --add safe.directory "$GITHUB_WORKSPACE" - /usr/bin/git diff -U0 HEAD^ | clang-tidy-diff-15.py -checks='-*,modernize-use-auto,modernize-use-using,modernize-use-nodiscard,modernize-use-nullptr,modernize-use-override,cppcoreguidelines-pro-type-static-cast-downcast' -p1 -path build -export-fixes clang-tidy-result/fixes.yml + /usr/bin/git diff -U0 HEAD^ | clang-tidy-diff-21.py -checks='-*,modernize-use-auto,modernize-use-using,modernize-use-nodiscard,modernize-use-nullptr,modernize-use-override,cppcoreguidelines-pro-type-static-cast-downcast' -p1 -path build -export-fixes clang-tidy-result/fixes.yml - name: Run clang-tidy-pr-comments action uses: platisd/clang-tidy-pr-comments@28cfb84edafa771c044bde7e4a2a3fae57463818 # v1.6.1 # >1.4.3 switches to composite method w/ a forced python version and breaks things: https://github.com/actions/setup-python/issues/871 with: + python_path: "/usr/bin/python3" # The GitHub token (or a personal access token) github_token: ${{ secrets.GITHUB_TOKEN }} # The path to the clang-tidy fixes generated previously diff --git a/.github/workflows/linux-appimage.yml b/.github/workflows/linux-appimage.yml index 1d2b09df9cbdc..53e4c1ba2cd15 100644 --- a/.github/workflows/linux-appimage.yml +++ b/.github/workflows/linux-appimage.yml @@ -9,7 +9,7 @@ jobs: build: name: Linux Appimage Package runs-on: ubuntu-latest - container: ghcr.io/nextcloud/continuous-integration-client-appimage-qt6:client-appimage-el8-6.9.3-2 + container: ghcr.io/nextcloud/continuous-integration-client-appimage-qt6:client-appimage-el8-6.10.1-1 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/linux-clang-compile-tests.yml b/.github/workflows/linux-clang-compile-tests.yml index 94b6aa72a7c8f..ce963b813e47b 100644 --- a/.github/workflows/linux-clang-compile-tests.yml +++ b/.github/workflows/linux-clang-compile-tests.yml @@ -8,7 +8,7 @@ jobs: build: name: Linux Clang compilation and tests runs-on: ubuntu-latest - container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-forky-6.9.2-1 + container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-forky-6.9.2-3 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/linux-gcc-compile-tests.yml b/.github/workflows/linux-gcc-compile-tests.yml index 4334216e11dc8..7beb6022f30f5 100644 --- a/.github/workflows/linux-gcc-compile-tests.yml +++ b/.github/workflows/linux-gcc-compile-tests.yml @@ -8,7 +8,7 @@ jobs: build: name: Linux GCC compilation and tests runs-on: ubuntu-latest - container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-forky-6.9.2-1 + container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-forky-6.9.2-3 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/macos-craft-ci.yml b/.github/workflows/macos-craft-ci.yml index 4e97a2842dbfd..2c39ea98fa9e3 100644 --- a/.github/workflows/macos-craft-ci.yml +++ b/.github/workflows/macos-craft-ci.yml @@ -66,8 +66,8 @@ jobs: - name: Add required blueprint repositories if: steps.cache-craft-restore.outputs.cache-hit != 'true' run: | - python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --add-blueprint-repository "https://github.com/nextcloud/craft-blueprints-kde.git|next|" - python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --add-blueprint-repository "https://github.com/nextcloud/desktop-client-blueprints.git|next|" + python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --add-blueprint-repository "https://github.com/nextcloud/craft-blueprints-kde.git|master|" + python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --add-blueprint-repository "https://github.com/nextcloud/desktop-client-blueprints.git|master|" - name: Setup Craft if: steps.cache-craft-restore.outputs.cache-hit != 'true' diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 0c80f335ec696..bb11cec923a04 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -8,7 +8,7 @@ jobs: build: name: SonarCloud analysis runs-on: [ubuntu-latest, self-hosted] - container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-6.8.1-2 + container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-forky-6.9.2-3 env: SONAR_SERVER_URL: "https://sonarcloud.io" BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed @@ -27,7 +27,7 @@ jobs: run: | mkdir build cd build - cmake .. -G Ninja -DCMAKE_PREFIX_PATH=/opt/qt -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 -DCMAKE_BUILD_TYPE=Debug -DQUICK_COMPILER=ON -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DQT_MAJOR_VERSION=6 -DCMAKE_CXX_FLAGS=-Werror -DOPENSSL_ROOT_DIR=/usr/local/lib64 -DBUILD_COVERAGE=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + cmake .. -G Ninja -DCMAKE_PREFIX_PATH=/opt/qt -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Debug -DQUICK_COMPILER=ON -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DQT_MAJOR_VERSION=6 -DCMAKE_CXX_FLAGS=-Werror -DOPENSSL_ROOT_DIR=/usr/local/lib64 -DBUILD_COVERAGE=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} ninja - name: Run tests run: | diff --git a/.github/workflows/windows-build-and-test.yml b/.github/workflows/windows-build-and-test.yml index 403e31a8dcdbb..119497e584909 100644 --- a/.github/workflows/windows-build-and-test.yml +++ b/.github/workflows/windows-build-and-test.yml @@ -31,8 +31,8 @@ jobs: if($LASTEXITCODE -ne 0) {exit $LASTEXITCODE} } - craft --add-blueprint-repository "https://github.com/nextcloud/craft-blueprints-kde.git|stable-4.0|" - craft --add-blueprint-repository "https://github.com/nextcloud/desktop-client-blueprints.git|stable-4.0|" + craft --add-blueprint-repository "https://github.com/nextcloud/craft-blueprints-kde.git|master|" + craft --add-blueprint-repository "https://github.com/nextcloud/desktop-client-blueprints.git|master|" craft craft craft --install-deps nextcloud-client diff --git a/CMakeLists.txt b/CMakeLists.txt index c4ad9e37d4293..fb4c3c5b747e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,6 +257,8 @@ if(BUILD_CLIENT) find_package(ZLIB REQUIRED) find_package(SQLite3 3.9.0 REQUIRED) + find_package(KDSingleApplication-qt6 REQUIRED) + if(NOT WIN32 AND NOT APPLE) find_package(PkgConfig REQUIRED) pkg_check_modules(CLOUDPROVIDERS cloudproviders IMPORTED_TARGET) diff --git a/LICENSES/LicenseRef-DigiaCommercialUsage.txt b/LICENSES/LicenseRef-DigiaCommercialUsage.txt deleted file mode 100644 index 57e4dd4ad719a..0000000000000 --- a/LICENSES/LicenseRef-DigiaCommercialUsage.txt +++ /dev/null @@ -1,8 +0,0 @@ -Commercial License Usage - -Licensees holding valid commercial Qt licenses may use this file in -accordance with the commercial license agreement provided with the -Software or, alternatively, in accordance with the terms contained in -a written agreement between you and Digia. For licensing terms and -conditions see http://qt.digia.com/licensing. For further information -use the contact form at http://qt.digia.com/contact-us. diff --git a/LICENSES/LicenseRef-DigiaQtLGPLException-1.1.txt b/LICENSES/LicenseRef-DigiaQtLGPLException-1.1.txt deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/admin/osx/mac-crafter/Sources/Commands/Build.swift b/admin/osx/mac-crafter/Sources/Commands/Build.swift index 36b052121959d..0c589e2228c59 100644 --- a/admin/osx/mac-crafter/Sources/Commands/Build.swift +++ b/admin/osx/mac-crafter/Sources/Commands/Build.swift @@ -34,13 +34,13 @@ struct Build: AsyncParsableCommand { var kdeBlueprintsGitUrl = "https://github.com/nextcloud/craft-blueprints-kde.git" @Option(name: [.long], help: "KDE Craft blueprints git ref/branch") - var kdeBlueprintsGitRef = "next" + var kdeBlueprintsGitRef = "master" @Option(name: [.long], help: "Nextcloud Desktop Client craft blueprints Git URL.") var clientBlueprintsGitUrl = "https://github.com/nextcloud/desktop-client-blueprints.git" @Option(name: [.long], help: "Nextcloud Desktop Client craft blueprints Git ref/branch.") - var clientBlueprintsGitRef = "next" + var clientBlueprintsGitRef = "master" @Option(name: [.long], help: "Nextcloud Desktop Client craft blueprint name.") var craftBlueprintName = "nextcloud-client" diff --git a/craftmaster.ini b/craftmaster.ini index 032f4717b937e..15f407f220983 100644 --- a/craftmaster.ini +++ b/craftmaster.ini @@ -3,7 +3,7 @@ [General] Branch = master # CraftUrl = https://github.com/allexzander/craft.git -CraftRevision = 05fc0f0e7cb6cb5e8ee7eccba400ad4a2b590657 +CraftRevision = 7b73acd32984b67d7e1054c9a02e3d86eca9a030 ShallowClone = False # Variables defined here override the default value @@ -28,7 +28,7 @@ ShortPath/Enabled = False ShortPath/EnableJunctions = False Packager/RepositoryUrl = https://download.nextcloud.com/desktop/development/craftCache/ -Packager/CacheVersion = stable-4.0-qt-6.9.3 +Packager/CacheVersion = master-qt-6.10.1 ContinuousIntegration/Enabled = True Packager/UseCache = ${Variables:UseCache} @@ -38,8 +38,8 @@ Packager/CacheDir = ${Variables:Root}\cache [BlueprintSettings] nextcloud-client.buildTests = True binary/mysql.useMariaDB = False -libs/qt6.version = 6.9.3 -craft/craft-blueprints-kde.revision = stable-4.0 +libs/qt6.version = 6.10.1 +craft/craft-blueprints-kde.revision = master [windows-msvc2022_64-cl] Packager/PackageType = NullsoftInstallerPackager @@ -66,4 +66,4 @@ SIGN_PACKAGE = False [Custom_Variables_for_Brander] qtPath = /root/linux-gcc-x86_64 -dockerImage = ghcr.io/nextcloud/continuous-integration-client-appimage-qt6:client-appimage-el8-6.9.3-2 +dockerImage = ghcr.io/nextcloud/continuous-integration-client-appimage-qt6:client-appimage-el8-6.10.1-1 diff --git a/src/3rdparty/LGPL_EXCEPTION.txt b/src/3rdparty/LGPL_EXCEPTION.txt deleted file mode 100644 index de26b0c041cc6..0000000000000 --- a/src/3rdparty/LGPL_EXCEPTION.txt +++ /dev/null @@ -1,22 +0,0 @@ -Digia Qt LGPL Exception version 1.1 - -As an additional permission to the GNU Lesser General Public License version -2.1, the object code form of a "work that uses the Library" may incorporate -material from a header file that is part of the Library. You may distribute -such object code under terms of your choice, provided that: -(i) the header files of the Library have not been modified; and -(ii) the incorporated material is limited to numerical parameters, data -structure layouts, accessors, macros, inline functions and -templates; and -(iii) you comply with the terms of Section 6 of the GNU Lesser General -Public License version 2.1. - -Moreover, you may apply this exception to a modified version of the Library, -provided that such modification does not involve copying material from the -Library into the modified Library's header files unless such material is -limited to (i) numerical parameters; (ii) data structure layouts; -(iii) accessors; and (iv) small macros, templates and inline functions of -five lines or less in length. - -Furthermore, you are not required to apply this additional permission to a -modified version of the Library. diff --git a/src/3rdparty/LGPL_EXCEPTION.txt.license b/src/3rdparty/LGPL_EXCEPTION.txt.license deleted file mode 100644 index aaa1c76e626d8..0000000000000 --- a/src/3rdparty/LGPL_EXCEPTION.txt.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -SPDX-License-Identifier: LicenseRef-DigiaQtLGPLException-1.1 diff --git a/src/3rdparty/qtlockedfile/README.txt b/src/3rdparty/qtlockedfile/README.txt deleted file mode 100644 index b89401295b180..0000000000000 --- a/src/3rdparty/qtlockedfile/README.txt +++ /dev/null @@ -1,5 +0,0 @@ -This is the src directory of the QtLockedFile -solution integrated over from Qt's Qt Creator. - -It is required by the QtSingleApplication solution. - diff --git a/src/3rdparty/qtlockedfile/README.txt.license b/src/3rdparty/qtlockedfile/README.txt.license deleted file mode 100644 index aaa1c76e626d8..0000000000000 --- a/src/3rdparty/qtlockedfile/README.txt.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -SPDX-License-Identifier: LicenseRef-DigiaQtLGPLException-1.1 diff --git a/src/3rdparty/qtlockedfile/qtlockedfile.cpp b/src/3rdparty/qtlockedfile/qtlockedfile.cpp deleted file mode 100644 index 7adb9abad2aa4..0000000000000 --- a/src/3rdparty/qtlockedfile/qtlockedfile.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qtlockedfile.h" - -namespace SharedTools { - -/*! - \class QtLockedFile - - \brief The QtLockedFile class extends QFile with advisory locking functions. - - A file may be locked in read or write mode. Multiple instances of - \e QtLockedFile, created in multiple processes running on the same - machine, may have a file locked in read mode. Exactly one instance - may have it locked in write mode. A read and a write lock cannot - exist simultaneously on the same file. - - The file locks are advisory. This means that nothing prevents - another process from manipulating a locked file using QFile or - file system functions offered by the OS. Serialization is only - guaranteed if all processes that access the file use - QtLockedFile. Also, while holding a lock on a file, a process - must not open the same file again (through any API), or locks - can be unexpectedly lost. - - The lock provided by an instance of \e QtLockedFile is released - whenever the program terminates. This is true even when the - program crashes and no destructors are called. -*/ - -/*! \enum QtLockedFile::LockMode - - This enum describes the available lock modes. - - \value ReadLock A read lock. - \value WriteLock A write lock. - \value NoLock Neither a read lock nor a write lock. -*/ - -/*! - Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way - as \e QFile::QFile(). - - \sa QFile::QFile() -*/ -QtLockedFile::QtLockedFile() - : QFile() -{ -#ifdef Q_OS_WIN - m_semaphore_hnd = nullptr; - m_mutex_hnd = nullptr; -#endif - m_lock_mode = NoLock; -} - -/*! - Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in - the same way as \e QFile::QFile(const QString&). - - \sa QFile::QFile() -*/ -QtLockedFile::QtLockedFile(const QString &name) - : QFile(name) -{ -#ifdef Q_OS_WIN - m_semaphore_hnd = nullptr; - m_mutex_hnd = nullptr; -#endif - m_lock_mode = NoLock; -} - -/*! - Returns \e true if this object has a in read or write lock; - otherwise returns \e false. - - \sa lockMode() -*/ -bool QtLockedFile::isLocked() const -{ - return m_lock_mode != NoLock; -} - -/*! - Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock. - - \sa isLocked() -*/ -QtLockedFile::LockMode QtLockedFile::lockMode() const -{ - return m_lock_mode; -} - -/*! - \fn bool QtLockedFile::lock(LockMode mode, bool block = true) - - Obtains a lock of type \a mode. - - If \a block is true, this - function will block until the lock is acquired. If \a block is - false, this function returns \e false immediately if the lock cannot - be acquired. - - If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock - is first released and then a new lock is obtained. - - This function returns \e true if, after it executes, the file is locked by this object, - and \e false otherwise. - - \sa unlock(), isLocked(), lockMode() -*/ - -/*! - \fn bool QtLockedFile::unlock() - - Releases a lock. - - If the object has no lock, this function returns immediately. - - This function returns \e true if, after it executes, the file is not locked by - this object, and \e false otherwise. - - \sa lock(), isLocked(), lockMode() -*/ - -/*! - \fn QtLockedFile::~QtLockedFile() - - Destroys the \e QtLockedFile object. If any locks were held, they are released. -*/ - -} // namespace SharedTools diff --git a/src/3rdparty/qtlockedfile/qtlockedfile.h b/src/3rdparty/qtlockedfile/qtlockedfile.h deleted file mode 100644 index 4dd3049f761fe..0000000000000 --- a/src/3rdparty/qtlockedfile/qtlockedfile.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef QTLOCKEDFILE_H -#define QTLOCKEDFILE_H - -#include - -#if defined(Q_OS_WIN) -# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) -# define QT_QTLOCKEDFILE_EXPORT -# elif defined(QT_QTLOCKEDFILE_IMPORT) -# if defined(QT_QTLOCKEDFILE_EXPORT) -# undef QT_QTLOCKEDFILE_EXPORT -# endif -# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) -# elif defined(QT_QTLOCKEDFILE_EXPORT) -# undef QT_QTLOCKEDFILE_EXPORT -# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) -# endif -#else -# define QT_QTLOCKEDFILE_EXPORT -#endif - -namespace SharedTools { - -class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile -{ -public: - enum LockMode { NoLock = 0, ReadLock, WriteLock }; - - QtLockedFile(); - QtLockedFile(const QString &name); - ~QtLockedFile() override; - - bool lock(LockMode mode, bool block = true); - bool unlock(); - [[nodiscard]] bool isLocked() const; - [[nodiscard]] LockMode lockMode() const; - -private: -#ifdef Q_OS_WIN - Qt::HANDLE m_semaphore_hnd; - Qt::HANDLE m_mutex_hnd; -#endif - LockMode m_lock_mode; -}; - -} // namespace SharedTools - -#endif // QTLOCKEDFILE_H diff --git a/src/3rdparty/qtlockedfile/qtlockedfile.pri b/src/3rdparty/qtlockedfile/qtlockedfile.pri deleted file mode 100644 index ad0c2fbabfb03..0000000000000 --- a/src/3rdparty/qtlockedfile/qtlockedfile.pri +++ /dev/null @@ -1,11 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD -HEADERS += $$PWD/qtlockedfile.h -SOURCES += $$PWD/qtlockedfile.cpp - -unix:SOURCES += $$PWD/qtlockedfile_unix.cpp -win32:SOURCES += $$PWD/qtlockedfile_win.cpp - -win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { - DEFINES += QT_QTLOCKEDFILE_EXPORT=__declspec(dllexport) -} diff --git a/src/3rdparty/qtlockedfile/qtlockedfile.pri.license b/src/3rdparty/qtlockedfile/qtlockedfile.pri.license deleted file mode 100644 index aaa1c76e626d8..0000000000000 --- a/src/3rdparty/qtlockedfile/qtlockedfile.pri.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -SPDX-License-Identifier: LicenseRef-DigiaQtLGPLException-1.1 diff --git a/src/3rdparty/qtlockedfile/qtlockedfile_unix.cpp b/src/3rdparty/qtlockedfile/qtlockedfile_unix.cpp deleted file mode 100644 index 427aa3143c52c..0000000000000 --- a/src/3rdparty/qtlockedfile/qtlockedfile_unix.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qtlockedfile.h" - -#include -#include -#include -#include - -namespace SharedTools { - -bool QtLockedFile::lock(LockMode mode, bool block) -{ - if (!isOpen()) { - qWarning("QtLockedFile::lock(): file is not opened"); - return false; - } - - if (mode == NoLock) - return unlock(); - - if (mode == m_lock_mode) - return true; - - if (m_lock_mode != NoLock) - unlock(); - - struct flock fl{}; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; - int cmd = block ? F_SETLKW : F_SETLK; - int ret = fcntl(handle(), cmd, &fl); - - if (ret == -1) { - if (errno != EINTR && errno != EAGAIN) - qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); - return false; - } - - - m_lock_mode = mode; - return true; -} - - -bool QtLockedFile::unlock() -{ - if (!isOpen()) { - qWarning("QtLockedFile::unlock(): file is not opened"); - return false; - } - - if (!isLocked()) - return true; - - struct flock fl{}; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_type = F_UNLCK; - int ret = fcntl(handle(), F_SETLKW, &fl); - - if (ret == -1) { - qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); - return false; - } - - m_lock_mode = NoLock; - remove(); - return true; -} - -QtLockedFile::~QtLockedFile() -{ - if (isOpen()) - unlock(); -} - -} // namespace SharedTools diff --git a/src/3rdparty/qtlockedfile/qtlockedfile_win.cpp b/src/3rdparty/qtlockedfile/qtlockedfile_win.cpp deleted file mode 100644 index d728ecaea51ea..0000000000000 --- a/src/3rdparty/qtlockedfile/qtlockedfile_win.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qtlockedfile.h" - -#include -#include - -namespace SharedTools { - -#define SEMAPHORE_PREFIX "QtLockedFile semaphore " -#define MUTEX_PREFIX "QtLockedFile mutex " -#define SEMAPHORE_MAX 100 - -static QString errorCodeToString(DWORD errorCode) -{ - QString result; - char *data = nullptr; - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - nullptr, errorCode, 0, - (char*)&data, 0, nullptr); - result = QString::fromLocal8Bit(data); - if (data != nullptr) - LocalFree(data); - - if (result.endsWith(QLatin1Char('\n'))) - result.truncate(result.length() - 1); - - return result; -} - -bool QtLockedFile::lock(LockMode mode, bool block) -{ - if (!isOpen()) { - qWarning("QtLockedFile::lock(): file is not opened"); - return false; - } - - if (mode == m_lock_mode) - return true; - - if (m_lock_mode != 0) - unlock(); - - if (m_semaphore_hnd == nullptr) { - QFileInfo fi(*this); - QString sem_name = QString::fromLatin1(SEMAPHORE_PREFIX) - + fi.absoluteFilePath().toLower(); - - m_semaphore_hnd = CreateSemaphoreW(nullptr, SEMAPHORE_MAX, SEMAPHORE_MAX, - (TCHAR*)sem_name.utf16()); - - if (m_semaphore_hnd == nullptr) { - qWarning("QtLockedFile::lock(): CreateSemaphore: %s", - errorCodeToString(GetLastError()).toLatin1().constData()); - return false; - } - } - - bool gotMutex = false; - int decrement = 0; - if (mode == ReadLock) { - decrement = 1; - } else { - decrement = SEMAPHORE_MAX; - if (m_mutex_hnd == nullptr) { - QFileInfo fi(*this); - QString mut_name = QString::fromLatin1(MUTEX_PREFIX) - + fi.absoluteFilePath().toLower(); - - m_mutex_hnd = CreateMutexW(nullptr, FALSE, (TCHAR*)mut_name.utf16()); - - if (m_mutex_hnd == nullptr) { - qWarning("QtLockedFile::lock(): CreateMutex: %s", - errorCodeToString(GetLastError()).toLatin1().constData()); - return false; - } - } - DWORD res = WaitForSingleObject(m_mutex_hnd, block ? INFINITE : 0); - if (res == WAIT_TIMEOUT) - return false; - if (res == WAIT_FAILED) { - qWarning("QtLockedFile::lock(): WaitForSingleObject (mutex): %s", - errorCodeToString(GetLastError()).toLatin1().constData()); - return false; - } - gotMutex = true; - } - - for (int i = 0; i < decrement; ++i) { - DWORD res = WaitForSingleObject(m_semaphore_hnd, block ? INFINITE : 0); - if (res == WAIT_TIMEOUT) { - if (i) { - // A failed nonblocking rw locking. Undo changes to semaphore. - if (ReleaseSemaphore(m_semaphore_hnd, i, nullptr) == 0) { - qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s", - errorCodeToString(GetLastError()).toLatin1().constData()); - // Fall through - } - } - if (gotMutex) - ReleaseMutex(m_mutex_hnd); - return false; - } - if (res != WAIT_OBJECT_0) { - if (gotMutex) - ReleaseMutex(m_mutex_hnd); - qWarning("QtLockedFile::lock(): WaitForSingleObject (semaphore): %s", - errorCodeToString(GetLastError()).toLatin1().constData()); - return false; - } - } - - m_lock_mode = mode; - if (gotMutex) - ReleaseMutex(m_mutex_hnd); - return true; -} - -bool QtLockedFile::unlock() -{ - if (!isOpen()) { - qWarning("QtLockedFile::unlock(): file is not opened"); - return false; - } - - if (!isLocked()) - return true; - - int increment = 0; - if (m_lock_mode == ReadLock) - increment = 1; - else - increment = SEMAPHORE_MAX; - - DWORD ret = ReleaseSemaphore(m_semaphore_hnd, increment, nullptr); - if (ret == 0) { - qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s", - errorCodeToString(GetLastError()).toLatin1().constData()); - return false; - } - - m_lock_mode = QtLockedFile::NoLock; - remove(); - return true; -} - -QtLockedFile::~QtLockedFile() -{ - if (isOpen()) - unlock(); - if (m_mutex_hnd != nullptr) { - DWORD ret = CloseHandle(m_mutex_hnd); - if (ret == 0) { - qWarning("QtLockedFile::~QtLockedFile(): CloseHandle (mutex): %s", - errorCodeToString(GetLastError()).toLatin1().constData()); - } - m_mutex_hnd = nullptr; - } - if (m_semaphore_hnd != nullptr) { - DWORD ret = CloseHandle(m_semaphore_hnd); - if (ret == 0) { - qWarning("QtLockedFile::~QtLockedFile(): CloseHandle (semaphore): %s", - errorCodeToString(GetLastError()).toLatin1().constData()); - } - m_semaphore_hnd = nullptr; - } -} - -} // namespace SharedTools diff --git a/src/3rdparty/qtsingleapplication/README.txt b/src/3rdparty/qtsingleapplication/README.txt deleted file mode 100644 index b5d8869481060..0000000000000 --- a/src/3rdparty/qtsingleapplication/README.txt +++ /dev/null @@ -1,5 +0,0 @@ -This is the src directory of the QtSingleApplication solution -integrated over from Qt's Qt Creator project. - -It additionally requires the QtLockedFile solution. - diff --git a/src/3rdparty/qtsingleapplication/README.txt.license b/src/3rdparty/qtsingleapplication/README.txt.license deleted file mode 100644 index aaa1c76e626d8..0000000000000 --- a/src/3rdparty/qtsingleapplication/README.txt.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -SPDX-License-Identifier: LicenseRef-DigiaQtLGPLException-1.1 diff --git a/src/3rdparty/qtsingleapplication/qtlocalpeer.cpp b/src/3rdparty/qtsingleapplication/qtlocalpeer.cpp deleted file mode 100644 index 293d807fda9ac..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtlocalpeer.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qtlocalpeer.h" - -#include -#include -#include - -#if defined(Q_OS_WIN) -#include -#include -using PProcessIdToSessionId = BOOL (WINAPI*)(DWORD, DWORD*); -static PProcessIdToSessionId pProcessIdToSessionId = nullptr; -#endif - -#if defined(Q_OS_UNIX) -#include -#include -#endif - -namespace SharedTools { - -static const char ack[] = "ack"; - -QString QtLocalPeer::appSessionId(const QString &appId) -{ - const auto idc = appId.toUtf8(); - const auto idNum = qChecksum(idc); - //### could do: two 16bit checksums over separate halves of id, for a 32bit result - improved uniqeness probability. Every-other-char split would be best. - - QString res = QLatin1String("qtsingleapplication-") - + QString::number(idNum, 16); -#if defined(Q_OS_WIN) - if (!pProcessIdToSessionId) { - QLibrary lib(QLatin1String("kernel32")); - pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); - } - if (pProcessIdToSessionId) { - DWORD sessionId = 0; - pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); - res += QLatin1Char('-') + QString::number(sessionId, 16); - } -#else - res += QLatin1Char('-') + QString::number(::getuid(), 16); -#endif - return res; -} - -QtLocalPeer::QtLocalPeer(QObject *parent, const QString &appId) - : QObject(parent), id(appId) -{ - if (id.isEmpty()) - id = QCoreApplication::applicationFilePath(); //### On win, check if this returns .../argv[0] without casefolding; .\MYAPP == .\myapp on Win - - socketName = appSessionId(id); - server = new QLocalServer(this); - QString lockName = QDir(QDir::tempPath()).absolutePath() - + QLatin1Char('/') + socketName - + QLatin1String("-lockfile"); - lockFile.setFileName(lockName); - lockFile.open(QIODevice::ReadWrite); -} - -bool QtLocalPeer::isClient() -{ - if (lockFile.isLocked()) - return false; - - if (!lockFile.lock(QtLockedFile::WriteLock, false)) - return true; - - if (!QLocalServer::removeServer(socketName)) - qWarning("QtSingleCoreApplication: could not cleanup socket"); - bool res = server->listen(socketName); - if (!res) - qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); - QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection); - return false; -} - -bool QtLocalPeer::sendMessage(const QString &message, int timeout, bool block) -{ - if (!isClient()) - return false; - - QLocalSocket socket; - bool connOk = false; - for (int i = 0; i < 2; i++) { - // Try twice, in case the other instance is just starting up - socket.connectToServer(socketName); - connOk = socket.waitForConnected(timeout/2); - if (connOk || i) - break; - int ms = 250; -#if defined(Q_OS_WIN) - Sleep(DWORD(ms)); -#else - struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; - nanosleep(&ts, nullptr); -#endif - } - if (!connOk) - return false; - - QByteArray uMsg(message.toUtf8()); - QDataStream ds(&socket); - ds.writeBytes(uMsg.constData(), uMsg.size()); - bool res = socket.waitForBytesWritten(timeout); - res &= socket.waitForReadyRead(timeout); // wait for ack - res &= (socket.read(qstrlen(ack)) == ack); - if (block) // block until peer disconnects - socket.waitForDisconnected(-1); - return res; -} - -void QtLocalPeer::receiveConnection() -{ - QLocalSocket* socket = server->nextPendingConnection(); - if (!socket) - return; - - // Why doesn't Qt have a blocking stream that takes care of this shait??? - while (socket->bytesAvailable() < static_cast(sizeof(quint32))) { - if (!socket->isValid()) // stale request - return; - socket->waitForReadyRead(1000); - } - QDataStream ds(socket); - QByteArray uMsg; - quint32 remaining = 0; - ds >> remaining; - uMsg.resize(remaining); - int got = 0; - char* uMsgBuf = uMsg.data(); - //qDebug() << "RCV: remaining" << remaining; - do { - got = ds.readRawData(uMsgBuf, remaining); - remaining -= got; - uMsgBuf += got; - //qDebug() << "RCV: got" << got << "remaining" << remaining; - } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); - //### error check: got<0 - if (got < 0) { - qWarning() << "QtLocalPeer: Message reception failed" << socket->errorString(); - delete socket; - return; - } - // ### async this - QString message = QString::fromUtf8(uMsg.constData(), uMsg.size()); - socket->write(ack, qstrlen(ack)); - socket->waitForBytesWritten(1000); - emit messageReceived(message, socket); // ##(might take a long time to return) -} - -} // namespace SharedTools diff --git a/src/3rdparty/qtsingleapplication/qtlocalpeer.h b/src/3rdparty/qtsingleapplication/qtlocalpeer.h deleted file mode 100644 index 75a6a0fa3742a..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtlocalpeer.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#pragma once - -#include - -#include -#include -#include - -namespace SharedTools { - -class QtLocalPeer : public QObject -{ - Q_OBJECT - -public: - explicit QtLocalPeer(QObject *parent = nullptr, const QString &appId = QString()); - bool isClient(); - bool sendMessage(const QString &message, int timeout, bool block); - [[nodiscard]] QString applicationId() const - { return id; } - static QString appSessionId(const QString &appId); - -Q_SIGNALS: - void messageReceived(const QString &message, QObject *socket); - -protected Q_SLOTS: - void receiveConnection(); - -protected: - QString id; - QString socketName; - QLocalServer* server; - QtLockedFile lockFile; -}; - -} // namespace SharedTools diff --git a/src/3rdparty/qtsingleapplication/qtsingleapplication.cpp b/src/3rdparty/qtsingleapplication/qtsingleapplication.cpp deleted file mode 100644 index bab9d9a74c399..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtsingleapplication.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qtsingleapplication.h" -#include "qtlocalpeer.h" - -#include - -#include -#include -#include - -namespace SharedTools { - -static const int instancesSize = 1024; - -static QString instancesLockFilename(const QString &appSessionId) -{ - const QChar slash(QLatin1Char('/')); - QString res = QDir::tempPath(); - if (!res.endsWith(slash)) - res += slash; - return res + appSessionId + QLatin1String("-instances"); -} - -QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) - : QApplication(argc, argv) -{ - this->appId = appId; - - const QString appSessionId = QtLocalPeer::appSessionId(appId); - - // This shared memory holds a zero-terminated array of active (or crashed) instances - instances = new QSharedMemory(appSessionId, this); - actWin = nullptr; - block = false; - - // First instance creates the shared memory, later instances attach to it - const bool created = instances->create(instancesSize); - if (!created) { - if (!instances->attach()) { - qWarning() << "Failed to initialize instances shared memory: " - << instances->errorString(); - delete instances; - instances = nullptr; - return; - } - } - - // QtLockedFile is used to workaround QTBUG-10364 - QtLockedFile lockfile(instancesLockFilename(appSessionId)); - - lockfile.open(QtLockedFile::ReadWrite); - lockfile.lock(QtLockedFile::WriteLock); - auto *pids = static_cast(instances->data()); - if (!created) { - // Find the first instance that it still running - // The whole list needs to be iterated in order to append to it - for (; *pids; ++pids) { - if (firstPeer == -1 && isRunning(*pids)) - firstPeer = *pids; - } - } - // Add current pid to list and terminate it - *pids++ = QCoreApplication::applicationPid(); - *pids = 0; - pidPeer = new QtLocalPeer(this, appId + QLatin1Char('-') + - QString::number(QCoreApplication::applicationPid())); - connect(pidPeer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::messageReceived); - pidPeer->isClient(); - lockfile.unlock(); -} - -QtSingleApplication::~QtSingleApplication() -{ - if (!instances) - return; - const qint64 appPid = QCoreApplication::applicationPid(); - QtLockedFile lockfile(instancesLockFilename(QtLocalPeer::appSessionId(appId))); - lockfile.open(QtLockedFile::ReadWrite); - lockfile.lock(QtLockedFile::WriteLock); - // Rewrite array, removing current pid and previously crashed ones - auto *pids = static_cast(instances->data()); - qint64 *newpids = pids; - for (; *pids; ++pids) { - if (*pids != appPid && isRunning(*pids)) - *newpids++ = *pids; - } - *newpids = 0; - lockfile.unlock(); -} - -bool QtSingleApplication::isRunning(qint64 pid) -{ - if (pid == -1) { - pid = firstPeer; - if (pid == -1) - return false; - } - - QtLocalPeer peer(this, appId + QLatin1Char('-') + QString::number(pid, 10)); - return peer.isClient(); -} - -bool QtSingleApplication::sendMessage(const QString &message, int timeout, qint64 pid) -{ - if (pid == -1) { - pid = firstPeer; - if (pid == -1) - return false; - } - - QtLocalPeer peer(this, appId + QLatin1Char('-') + QString::number(pid, 10)); - return peer.sendMessage(message, timeout, block); -} - -QString QtSingleApplication::applicationId() const -{ - return appId; -} - -void QtSingleApplication::setBlock(bool value) -{ - block = value; -} - -void QtSingleApplication::setActivationWindow(QWidget *aw, bool activateOnMessage) -{ - actWin = aw; - if (!pidPeer) - return; - if (activateOnMessage) - connect(pidPeer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow); - else - disconnect(pidPeer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow); -} - - -QWidget* QtSingleApplication::activationWindow() const -{ - return actWin; -} - - -void QtSingleApplication::activateWindow() -{ - if (actWin) { - actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); - actWin->raise(); - actWin->activateWindow(); - } -} - -} // namespace SharedTools diff --git a/src/3rdparty/qtsingleapplication/qtsingleapplication.h b/src/3rdparty/qtsingleapplication/qtsingleapplication.h deleted file mode 100644 index c714082e243dd..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtsingleapplication.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef QTSINGLEAPPLICATION_H -#define QTSINGLEAPPLICATION_H - -#include - -QT_FORWARD_DECLARE_CLASS(QSharedMemory) - -namespace SharedTools { - -class QtLocalPeer; - -class QtSingleApplication : public QApplication -{ - Q_OBJECT - -public: - QtSingleApplication(const QString &id, int &argc, char **argv); - ~QtSingleApplication() override; - - bool isRunning(qint64 pid = -1); - - void setActivationWindow(QWidget* aw, bool activateOnMessage = true); - [[nodiscard]] QWidget* activationWindow() const; - - [[nodiscard]] QString applicationId() const; - void setBlock(bool value); - -public Q_SLOTS: - bool sendMessage(const QString &message, int timeout = 5000, qint64 pid = -1); - void activateWindow(); - -Q_SIGNALS: - void messageReceived(const QString &message, QObject *socket); - void fileOpenRequest(const QString &file); - -private: - QString instancesFileName(const QString &appId); - - qint64 firstPeer = -1; - QSharedMemory *instances; - QtLocalPeer *pidPeer = nullptr; - QWidget *actWin; - QString appId; - bool block; -}; - -} // namespace SharedTools - -#endif // QTSINGLEAPPLICATION_H diff --git a/src/3rdparty/qtsingleapplication/qtsingleapplication.pri b/src/3rdparty/qtsingleapplication/qtsingleapplication.pri deleted file mode 100644 index c807763dce01e..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtsingleapplication.pri +++ /dev/null @@ -1,15 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD -HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h -SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp - -QT *= network -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -gotqtlockedfile = $$find(HEADERS, .*qtlockedfile.h) -isEmpty(gotqtlockedfile):include(../qtlockedfile/qtlockedfile.pri) - - -win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { - DEFINES += QT_QTSINGLEAPPLICATION_EXPORT=__declspec(dllexport) -} diff --git a/src/3rdparty/qtsingleapplication/qtsingleapplication.pri.license b/src/3rdparty/qtsingleapplication/qtsingleapplication.pri.license deleted file mode 100644 index aaa1c76e626d8..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtsingleapplication.pri.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -SPDX-License-Identifier: LicenseRef-DigiaQtLGPLException-1.1 diff --git a/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp b/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp deleted file mode 100644 index a1767a1de82e4..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qtsinglecoreapplication.h" -#include "qtlocalpeer.h" - -namespace SharedTools { - -QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) - : QCoreApplication(argc, argv) -{ - peer = new QtLocalPeer(this); - block = false; - connect(peer, &QtLocalPeer::messageReceived, this, &QtSingleCoreApplication::messageReceived); -} - - -QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv) - : QCoreApplication(argc, argv) -{ - peer = new QtLocalPeer(this, appId); - connect(peer, &QtLocalPeer::messageReceived, this, &QtSingleCoreApplication::messageReceived); -} - - -bool QtSingleCoreApplication::isRunning() -{ - return peer->isClient(); -} - - -bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout) -{ - return peer->sendMessage(message, timeout, block); -} - - -QString QtSingleCoreApplication::id() const -{ - return peer->applicationId(); -} - -void QtSingleCoreApplication::setBlock(bool value) -{ - block = value; -} - -} // namespace SharedTools diff --git a/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.h b/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.h deleted file mode 100644 index 6195a5e977bf1..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -** SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include - -namespace SharedTools { - -class QtLocalPeer; - -class QtSingleCoreApplication : public QCoreApplication -{ - Q_OBJECT - -public: - QtSingleCoreApplication(int &argc, char **argv); - QtSingleCoreApplication(const QString &id, int &argc, char **argv); - - bool isRunning(); - [[nodiscard]] QString id() const; - void setBlock(bool value); - -public Q_SLOTS: - bool sendMessage(const QString &message, int timeout = 5000); - - -Q_SIGNALS: - void messageReceived(const QString &message); - - -private: - QtLocalPeer* peer; - bool block = false; -}; - -} // namespace SharedTools diff --git a/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.pri b/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.pri deleted file mode 100644 index 3d6301b29c4fd..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.pri +++ /dev/null @@ -1,14 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD -HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h -SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp - -QT *= network - -gotqtlockedfile = $$find(HEADERS, .*qtlockedfile.h) -isEmpty(gotqtlockedfile):include(../qtlockedfile/qtlockedfile.pri) - - -win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { - DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport) -} diff --git a/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.pri.license b/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.pri.license deleted file mode 100644 index 7391f36fcaacc..0000000000000 --- a/src/3rdparty/qtsingleapplication/qtsinglecoreapplication.pri.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: 2014 Digia Plc and/or its subsidiary(-ies) -SPDX-License-Identifier: (LGPL-2.0-or-later AND LicenseRef-DigiaQtLGPLException-1.1) OR LicenseRef-DigiaCommercialUsage diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 0b9097cb152a7..b6d636f47ac1c 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -365,14 +365,6 @@ ENDIF() set(3rdparty_SRC ../3rdparty/QProgressIndicator/QProgressIndicator.h ../3rdparty/QProgressIndicator/QProgressIndicator.cpp - ../3rdparty/qtlockedfile/qtlockedfile.h - ../3rdparty/qtlockedfile/qtlockedfile.cpp - ../3rdparty/qtsingleapplication/qtlocalpeer.h - ../3rdparty/qtsingleapplication/qtlocalpeer.cpp - ../3rdparty/qtsingleapplication/qtsingleapplication.h - ../3rdparty/qtsingleapplication/qtsingleapplication.cpp - ../3rdparty/qtsingleapplication/qtsinglecoreapplication.h - ../3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp ../3rdparty/kmessagewidget/kmessagewidget.h ../3rdparty/kmessagewidget/kmessagewidget.cpp ../3rdparty/kirigami/wheelhandler.h @@ -382,14 +374,6 @@ set(3rdparty_SRC set_property(SOURCE ../3rdparty/kmessagewidget/kmessagewidget.cpp PROPERTY SKIP_UNITY_BUILD_INCLUSION ON) set_property(SOURCE ../3rdparty/kirigami/wheelhandler.cpp PROPERTY SKIP_UNITY_BUILD_INCLUSION ON) -if(NOT WIN32) - list(APPEND 3rdparty_SRC ../3rdparty/qtlockedfile/qtlockedfile_unix.cpp) - set_property(SOURCE ../3rdparty/qtlockedfile/qtlockedfile_unix.cpp PROPERTY SKIP_UNITY_BUILD_INCLUSION ON) -else() - list(APPEND 3rdparty_SRC ../3rdparty/qtlockedfile/qtlockedfile_win.cpp ) - set_property(SOURCE ../3rdparty/qtlockedfile/qtlockedfile_win.cpp PROPERTY SKIP_UNITY_BUILD_INCLUSION ON) -endif() - find_package(Qt${QT_VERSION_MAJOR} ${REQUIRED_QT_VERSION} COMPONENTS LinguistTools) if(Qt${QT_MAJOR_VERSION}LinguistTools_FOUND) qt_add_translation(client_I18N ${TRANSLATIONS}) @@ -549,6 +533,7 @@ target_link_libraries(nextcloudCore Qt::QuickControls2 Qt::QuickWidgets KF6::Archive + KDAB::kdsingleapplication ) if(KF6GuiAddons_FOUND) @@ -583,9 +568,7 @@ set_target_properties(nextcloudCore target_include_directories(nextcloudCore PUBLIC ${CMAKE_SOURCE_DIR}/src/3rdparty/QProgressIndicator - ${CMAKE_SOURCE_DIR}/src/3rdparty/qtlockedfile ${CMAKE_SOURCE_DIR}/src/3rdparty/kirigami - ${CMAKE_SOURCE_DIR}/src/3rdparty/qtsingleapplication ${CMAKE_SOURCE_DIR}/src/3rdparty/kmessagewidget ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 214cda6c0c75e..ae14bc11a3ff5 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -6,9 +6,6 @@ #include "application.h" -#include -#include - #include "account.h" #include "accountmanager.h" #include "accountsetupcommandlinemanager.h" @@ -23,11 +20,8 @@ #include "folderman.h" #include "logger.h" #include "pushnotifications.h" -#include "shellextensionsserver.h" #include "socketapi/socketapi.h" -#include "sslerrordialog.h" #include "theme.h" -#include "updatechannel.h" #if defined(BUILD_UPDATER) #include "updater/ocupdater.h" @@ -42,6 +36,7 @@ #if defined(Q_OS_WIN) #include +#include "shellextensionsserver.h" #elif defined(Q_OS_MACOS) #include "macOS/fileprovider.h" #endif @@ -56,6 +51,11 @@ #include #include #include +#include +#include +#include + +#include class QSocket; @@ -216,7 +216,7 @@ ownCloudGui *Application::gui() const } Application::Application(int &argc, char **argv) - : SharedTools::QtSingleApplication(Theme::instance()->appName(), argc, argv) + : QApplication{argc, argv} , _gui(nullptr) , _theme(Theme::instance()) { @@ -317,7 +317,7 @@ Application::Application(int &argc, char **argv) return; } - if (isRunning()) { + if (!_singleApp.isPrimaryInstance()) { return; } @@ -386,7 +386,7 @@ Application::Application(int &argc, char **argv) _shellExtensionsServer.reset(new ShellExtensionsServer); #endif - connect(this, &SharedTools::QtSingleApplication::messageReceived, this, &Application::slotParseMessage); + connect(&_singleApp, &KDSingleApplication::messageReceived, this, &Application::slotParseMessage); // create accounts and folders from a legacy desktop client or from the current config file setupAccountsAndFolders(); @@ -753,11 +753,12 @@ void Application::setupLogging() qCInfo(lcApplication) << "Arguments:" << qApp->arguments(); } -void Application::slotParseMessage(const QString &msg, QObject *) +void Application::slotParseMessage(const QByteArray &message) { + const auto msg = QString::fromLatin1(message); if (msg.startsWith(QLatin1String("MSG_PARSEOPTIONS:"))) { const int lengthOfMsgPrefix = 17; - QStringList options = msg.mid(lengthOfMsgPrefix).split(QLatin1Char('|')); + const auto options = msg.mid(lengthOfMsgPrefix).split(QLatin1Char{'|'}); _showLogWindow = false; parseOptions(options); setupLogging(); @@ -962,6 +963,16 @@ void Application::showVersion() displayHelpText(Theme::instance()->versionSwitchOutput()); } +bool Application::isRunning() const +{ + return !_singleApp.isPrimaryInstance(); +} + +bool Application::sendMessage(const QString &message) +{ + return _singleApp.sendMessage(message.toLatin1()); +} + void Application::showHint(std::string errorHint) { static QString binName = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); @@ -1164,7 +1175,7 @@ bool Application::event(QEvent *event) qCInfo(lcApplication) << "application palette changed"; emit systemPaletteChanged(); } - return SharedTools::QtSingleApplication::event(event); + return QGuiApplication::event(event); } } // namespace OCC diff --git a/src/gui/application.h b/src/gui/application.h index caba9df0e893f..cd5386b73503a 100644 --- a/src/gui/application.h +++ b/src/gui/application.h @@ -7,6 +7,13 @@ #ifndef APPLICATION_H #define APPLICATION_H +#include "owncloudgui.h" +#include "progressdispatcher.h" +#include "clientproxy.h" +#include "folderman.h" + +#include + #include #include #include @@ -14,16 +21,6 @@ #include #include -#include "qtsingleapplication.h" - -#include "syncresult.h" -#include "logbrowser.h" -#include "owncloudgui.h" -#include "connectionvalidator.h" -#include "progressdispatcher.h" -#include "clientproxy.h" -#include "folderman.h" - class QMessageBox; class QSystemTrayIcon; class QSocket; @@ -41,7 +38,7 @@ class SslErrorDialog; * @brief The Application class * @ingroup gui */ -class Application : public SharedTools::QtSingleApplication +class Application : public QApplication { Q_OBJECT public: @@ -56,6 +53,10 @@ class Application : public SharedTools::QtSingleApplication bool versionOnly(); // only display the version? void showVersion(); + [[nodiscard]] bool isRunning() const; + + bool sendMessage(const QString &message); + void showMainDialog(); [[nodiscard]] ownCloudGui *gui() const; @@ -87,7 +88,7 @@ public slots: void systemPaletteChanged(); protected slots: - void slotParseMessage(const QString &, QObject *); + void slotParseMessage(const QByteArray &msg); void slotCheckConnection(); void slotCleanup(); void slotAccountStateAdded(OCC::AccountState *accountState); @@ -112,6 +113,8 @@ protected slots: QPointer _gui; + KDSingleApplication _singleApp; + Theme *_theme; bool _helpOnly = false; diff --git a/src/gui/networksettings.cpp b/src/gui/networksettings.cpp index 83f4af87fb962..f14b25e014a72 100644 --- a/src/gui/networksettings.cpp +++ b/src/gui/networksettings.cpp @@ -14,6 +14,7 @@ #include "folderman.h" #include "theme.h" +#include #include #include #include