Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/qt5integration-archlinux-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: LGPL-3.0-or-later

name: Build qt5integration on Arch Linux

on:
push:

pull_request:

jobs:
container:
runs-on: ubuntu-latest
container: archlinux:latest
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arch Linux is a rolling release; pinning to a timestamped image causes partial-upgrade breakage (pacman does not support partial upgrades). archlinux:latest ensures a consistent package state, which is the correct approach for Arch CI.

steps:
- name: Initialize pacman and system update
run: |
pacman-key --init
pacman --noconfirm --noprogressbar -Syu

- name: Install base build tools
run: |
pacman -S --noconfirm --noprogressbar base-devel git cmake ninja pkgconf

- name: Install qt5integration system dependencies
run: |
pacman -S --noconfirm --noprogressbar \
qt5-base qt5-tools qt5-svg qt5-x11extras \
qt5-wayland qt5-imageformats \
extra-cmake-modules \
gtest \
libqtxdg xcb-util-renderutil \
fontconfig libglvnd mtdev libxrender \
icu uchardet dbus spdlog gsettings-qt \
libxext libxi cups startup-notification systemd xcb-util \
librsvg libraw kwayland \
dtkcommon dtklog \
treeland-protocols dtkcore dtkgui dtkwidget

- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Configure and build qt5integration
run: |
cmake -B build \
-GNinja \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_BUILD_TYPE=Release \
-DDTK5=ON
cmake --build build -j$(nproc)
echo "✅ qt5integration built successfully!"

- name: Install qt5integration to staging directory
run: |
DESTDIR=/tmp/qt5integration-install cmake --install build
echo "Total: $(find /tmp/qt5integration-install -type f | wc -l) files"

- name: Create installation package
run: |
tar -czf /tmp/qt5integration-archlinux-$(date +%Y%m%d-%H%M%S).tar.gz -C /tmp/qt5integration-install .
ls -la /tmp/qt5integration-archlinux-*.tar.gz

- name: Upload qt5integration Arch Linux build artifacts
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v4
with:
name: qt5integration-archlinux-build
path: "/tmp/qt5integration-archlinux-*.tar.gz"
if-no-files-found: error
retention-days: 30
119 changes: 119 additions & 0 deletions .github/workflows/qt5integration-deepin-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: LGPL-3.0-or-later

name: Build qt5integration on Deepin crimson

on:
push:

pull_request:

jobs:
container:
runs-on: ubuntu-latest
container: linuxdeepin/deepin:crimson
steps:
- uses: actions/checkout@v4

- name: Setup apt sources and build tools
run: |
set -euxo pipefail
echo "deb [trusted=yes] http://mirrors.kernel.org/deepin/beige/ crimson main commercial community" > /etc/apt/sources.list
echo "deb-src [trusted=yes] http://mirrors.kernel.org/deepin/beige/ crimson main commercial community" >> /etc/apt/sources.list
rm -rf /etc/apt/sources.list.d
Comment on lines +21 to +24
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Deepin crimson repository does not distribute a GPG signing key publicly, so [trusted=yes] is required. This only affects the isolated CI sandbox environment and has no impact on production deployments.

apt-get update
apt-get install -y devscripts equivs git

- name: Build and install dtkcommon from source
run: |
set -euxo pipefail
cd /tmp
git clone --depth=1 https://github.com/linuxdeepin/dtkcommon.git
cd dtkcommon
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
dpkg-buildpackage -uc -us -b
dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y
echo "✅ dtkcommon installed"

- name: Build and install dtklog from source
run: |
set -euxo pipefail
cd /tmp
git clone --depth=1 https://github.com/linuxdeepin/dtklog.git
cd dtklog
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
dpkg-buildpackage -uc -us -b -Pnodtk6
dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y
echo "✅ dtklog installed"

- name: Build and install treeland-protocols from source
run: |
set -euxo pipefail
apt-get install -y --allow-unauthenticated wlr-protocols || true
cd /tmp
git clone --depth=1 https://github.com/linuxdeepin/treeland-protocols.git
cd treeland-protocols
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
dpkg-buildpackage -uc -us -b
dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y
echo "✅ treeland-protocols installed"

- name: Build and install dtkcore from source
run: |
set -euxo pipefail
cd /tmp
git clone --depth=1 https://github.com/linuxdeepin/dtkcore.git
cd dtkcore
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
dpkg-buildpackage -uc -us -b -Pnodtk6
dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y
echo "✅ dtkcore installed"

- name: Build and install dtkgui from source
run: |
set -euxo pipefail
cd /tmp
git clone --depth=1 https://github.com/linuxdeepin/dtkgui.git
cd dtkgui
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
dpkg-buildpackage -uc -us -b -Pnodtk6
dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y
echo "✅ dtkgui installed"

- name: Build and install dtkwidget from source
run: |
set -euxo pipefail
cd /tmp
git clone --depth=1 https://github.com/linuxdeepin/dtkwidget.git
cd dtkwidget
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
dpkg-buildpackage -uc -us -b -Pnodtk6
dpkg -i ../*.deb 2>/dev/null || apt-get install -f -y
echo "✅ dtkwidget installed"

- name: Install qt5integration build dependencies
run: |
set -euxo pipefail
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control

- name: Build qt5integration deb packages
run: |
set -euxo pipefail
dpkg-buildpackage -uc -us -b -Pnodtk6
echo "✅ qt5integration deb packages built successfully!"
ls -la ../

- name: Collect deb artifacts
run: |
mkdir -p dist
mv ../*.deb dist/
ls -la dist

- name: Upload qt5integration deb packages as artifacts
uses: actions/upload-artifact@v4
with:
name: qt5integration-deepin-deb-packages
path: dist/*.deb
if-no-files-found: error
retention-days: 30
3 changes: 2 additions & 1 deletion platformthemeplugin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
# SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: LGPL-3.0-or-later

Expand Down Expand Up @@ -55,6 +55,7 @@ dtk_add_plugin(
main.cpp
${DBUS_INTERFACES}
HEADERS
dprivateaccessor_p.h
dthemesettings.h
qdeepinfiledialoghelper.h
qdeepintheme.h
Expand Down
79 changes: 79 additions & 0 deletions platformthemeplugin/dprivateaccessor_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: LGPL-3.0-or-later

#pragma once

#include <QtCore/qcompilerdetection.h>

Check warning on line 6 in platformthemeplugin/dprivateaccessor_p.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QtCore/qcompilerdetection.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 6 in platformthemeplugin/dprivateaccessor_p.h

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QtCore/qcompilerdetection.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

// Private member accessor using the explicit template instantiation technique.
//
// C++ Standard [temp.explicit]/12 states:
// "The usual access checking rules do not apply to names used to
// specify explicit instantiation definitions."
//
// This allows passing pointers to private/protected data members and
// member functions as template arguments in explicit instantiations,
// bypassing normal access control — without modifying the class definition
// and without the UB caused by "#define private public".
//
// NOTE: The friend declaration must live inside the Tag struct so the friend
// function is findable via ADL when calling get(TagName{}).

QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wnon-template-friend")

template<typename Tag>
struct Qt5IntegrationPrivateAccessor
Comment thread
zccrs marked this conversation as resolved.
{
using MemberPtr = typename Tag::MemberPtr;
friend MemberPtr get(Tag) noexcept;
};

template<typename Tag, typename Tag::MemberPtr Ptr>
struct Qt5IntegrationPrivateAccessorImpl : Qt5IntegrationPrivateAccessor<Tag>
{
friend typename Tag::MemberPtr get(Tag) noexcept { return Ptr; }
};

QT_WARNING_POP

// Non-static data member access
// Usage: D_PRIVATE_MEMBER(obj, TagName{}) → gives the member value (copy/ref)
// Usage: &D_PRIVATE_MEMBER(obj, TagName{}) → gives address of member
#define D_DECLARE_PRIVATE_MEMBER(TagName, ClassName, MemberName, MemberType) \
struct TagName { \
using MemberPtr = MemberType ClassName::*; \
friend MemberPtr get(TagName) noexcept; \
}; \
template struct Qt5IntegrationPrivateAccessorImpl<TagName, &ClassName::MemberName>

// Trampoline: ensures get(tag) is called from a context with no class-scope
// get() member that might suppress ADL (C++ [basic.lookup.argdep] para 3).
namespace dtk_private_detail {
template<typename Tag>
inline typename Tag::MemberPtr access(Tag t) noexcept { return get(t); }
}

#define D_PRIVATE_MEMBER(obj, tag) ((obj).*dtk_private_detail::access(tag))

// Non-static member function call
// Usage: D_PRIVATE_CALL(obj, TagName{}, arg1, arg2)
#define D_DECLARE_PRIVATE_FUNCTION(TagName, ClassName, FuncName, RetType, ...) \
struct TagName { \
using MemberPtr = RetType (ClassName::*)(__VA_ARGS__); \
friend MemberPtr get(TagName) noexcept; \
}; \
template struct Qt5IntegrationPrivateAccessorImpl<TagName, &ClassName::FuncName>

#define D_PRIVATE_CALL(obj, tag, ...) ((obj).*dtk_private_detail::access(tag))(__VA_ARGS__)

// Static data member access
// get(TagName{}) returns MemberType*, so D_PRIVATE_STATIC_MEMBER dereferences it
#define D_DECLARE_PRIVATE_STATIC_MEMBER(TagName, ClassName, MemberName, MemberType) \
struct TagName { \
using MemberPtr = MemberType*; \
friend MemberPtr get(TagName) noexcept; \
}; \
template struct Qt5IntegrationPrivateAccessorImpl<TagName, &ClassName::MemberName>

#define D_PRIVATE_STATIC_MEMBER(tag) (*dtk_private_detail::access(tag))
32 changes: 21 additions & 11 deletions platformthemeplugin/qdeepintheme.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd.
* SPDX-FileCopyrightText: 2017 - 2026 UnionTech Software Technology Co., Ltd.
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "qdeepintheme.h"
Expand All @@ -16,23 +16,33 @@
#include <QGuiApplication>
#include <QIconEnginePlugin>

#include <private/qicon_p.h>

Check warning on line 19 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <private/qicon_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 19 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <private/qicon_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <private/qiconloader_p.h>

Check warning on line 20 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <private/qiconloader_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 20 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <private/qiconloader_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#define private public
#include <private/qhighdpiscaling_p.h>

Check warning on line 21 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <private/qhighdpiscaling_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 21 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <private/qhighdpiscaling_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#undef private
#include <private/qwindow_p.h>

Check warning on line 22 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <private/qwindow_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 22 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <private/qwindow_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <private/qguiapplication_p.h>

Check warning on line 23 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <private/qguiapplication_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 23 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <private/qguiapplication_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <private/qfactoryloader_p.h>

Check warning on line 24 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <private/qfactoryloader_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 24 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <private/qfactoryloader_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <qpa/qwindowsysteminterface_p.h>

Check warning on line 25 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qpa/qwindowsysteminterface_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 25 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <qpa/qwindowsysteminterface_p.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <qpa/qplatformscreen.h>

Check warning on line 26 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qpa/qplatformscreen.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 26 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <qpa/qplatformscreen.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <qpa/qplatformcursor.h>

Check warning on line 27 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qpa/qplatformcursor.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 27 in platformthemeplugin/qdeepintheme.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <qpa/qplatformcursor.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include "dprivateaccessor_p.h"

#undef signals
#include <X11/Xlib.h>

DGUI_USE_NAMESPACE

#if QT_VERSION < QT_VERSION_CHECK(5,14,0)
using QHighDpiScaling_m_logicalDpi_type = QPair<qreal, qreal>;
D_DECLARE_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_logicalDpi_tag, QHighDpiScaling, m_logicalDpi, QHighDpiScaling_m_logicalDpi_type);
#elif QT_VERSION < QT_VERSION_CHECK(6,0,0)
D_DECLARE_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_usePixelDensity_tag, QHighDpiScaling, m_usePixelDensity, bool);
#else
D_DECLARE_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_usePlatformPluginDpi_tag, QHighDpiScaling, m_usePlatformPluginDpi, bool);
#endif
D_DECLARE_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_factor_tag, QHighDpiScaling, m_factor, qreal);
D_DECLARE_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_screenFactorSet_tag, QHighDpiScaling, m_screenFactorSet, bool);

#ifdef XDG_ICON_VERSION_MAR
#include <XdgIcon>
extern void updateXdgIconSystemTheme();
Expand Down Expand Up @@ -275,7 +285,7 @@
value = 1.0;
}

if (qFuzzyCompare(QHighDpiScaling::m_factor, value)) {
if (qFuzzyCompare(D_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_factor_tag{}), value)) {
return false;
}

Expand Down Expand Up @@ -386,20 +396,20 @@
bool ok = dpi.first >= 0 && dpi.second >= 0;
#if QT_VERSION < QT_VERSION_CHECK(5,14,0)
if (dpi.first > 0) {
QHighDpiScaling::m_logicalDpi.first = dpi.first;
D_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_logicalDpi_tag{}).first = dpi.first;
} else if (qIsNull(dpi.first)) {
QHighDpiScaling::m_logicalDpi.first = qGuiApp->primaryScreen()->handle()->logicalDpi().first;
D_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_logicalDpi_tag{}).first = qGuiApp->primaryScreen()->handle()->logicalDpi().first;
}

if (dpi.second > 0) {
QHighDpiScaling::m_logicalDpi.second = dpi.second;
D_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_logicalDpi_tag{}).second = dpi.second;
} else if (qIsNull(dpi.second)) {
QHighDpiScaling::m_logicalDpi.second = qGuiApp->primaryScreen()->handle()->logicalDpi().second;
D_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_logicalDpi_tag{}).second = qGuiApp->primaryScreen()->handle()->logicalDpi().second;
}
#elif QT_VERSION < QT_VERSION_CHECK(6,0,0)
QHighDpiScaling::m_usePixelDensity = false; // Do not use dpi from platform plugin
D_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_usePixelDensity_tag{}) = false; // Do not use dpi from platform plugin
#else
QHighDpiScaling::m_usePlatformPluginDpi = false; // Do not use dpi from platform plugin
D_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_usePlatformPluginDpi_tag{}) = false; // Do not use dpi from platform plugin
#endif
return ok;
}
Expand Down Expand Up @@ -753,7 +763,7 @@
}

static void onScreenAdded(QScreen *s) {
if (QHighDpiScaling::m_screenFactorSet) {
if (D_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_screenFactorSet_tag{})) {
auto setting = QDeepinTheme::getSettings();
auto value = setting->screenScaleFactors();

Expand Down
Loading