diff --git a/.github/workflows/qt5platform-plugins-archlinux-build.yml b/.github/workflows/qt5platform-plugins-archlinux-build.yml new file mode 100644 index 00000000..b6404e33 --- /dev/null +++ b/.github/workflows/qt5platform-plugins-archlinux-build.yml @@ -0,0 +1,94 @@ +name: Build qt5platform-plugins on Arch Linux + +on: + push: + + pull_request: + +jobs: + container: + runs-on: ubuntu-latest + container: archlinux:latest + 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 qt5platform-plugins system dependencies + run: | + pacman -S --noconfirm --noprogressbar \ + qt5-base qt5-xcb-private-headers qt5-x11extras qt5-wayland \ + extra-cmake-modules \ + gtest \ + libxcb xcb-util xcb-util-image xcb-util-keysyms \ + xcb-util-renderutil xcb-util-wm xcb-util-cursor \ + libxkbcommon libxkbcommon-x11 \ + libxi libxrender libsm libice cairo \ + dbus libglvnd fontconfig glib2 mtdev systemd \ + kwayland5 \ + dtkcommon + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Print Qt5 version and available xcb private headers + run: | + qmake --version + echo "--- qtxcb-private headers ---" + ls /usr/include/qtxcb-private/ | cat + echo "--- QXcbBackingStore m_image check ---" + grep -n "m_image" /usr/include/qtxcb-private/qxcbbackingstore.h 2>/dev/null || echo "NOT FOUND" + echo "--- QXcbCursor m_cursorHash check ---" + grep -n "m_cursorHash\|CursorHash" /usr/include/qtxcb-private/qxcbcursor.h 2>/dev/null || echo "NOT FOUND" + echo "--- QXcbDrag members check ---" + grep -n "currentWindow\|currentPosition\|m_dropData\|accepted_drop_action\|xdnd_dragsource\|target_time\|waiting_for_status\|current_proxy_target" /usr/include/qtxcb-private/qxcbdrag.h 2>/dev/null || echo "NOT FOUND" + + - name: Configure and build qt5platform-plugins + run: | + set -o pipefail + cmake -B build \ + -GNinja \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DCMAKE_BUILD_TYPE=Release \ + -DQT_XCB_PRIVATE_HEADERS=/usr/include/qtxcb-private \ + -DDTK5=ON 2>&1 | tee /tmp/cmake-configure.log + cmake --build build -j$(nproc) 2>&1 | tee /tmp/cmake-build.log + echo "✅ qt5platform-plugins built successfully!" + echo "=== Built .so files ===" + find build -name "*.so" | head -20 + + - name: Print build logs on failure + if: failure() + run: | + echo "=== cmake-configure.log ===" + cat /tmp/cmake-configure.log 2>/dev/null || echo "(not found)" + echo "=== cmake-build.log (last 100 lines) ===" + tail -100 /tmp/cmake-build.log 2>/dev/null || echo "(not found)" + + - name: Install qt5platform-plugins to staging directory + run: | + DESTDIR=/tmp/qt5platform-plugins-install cmake --install build --verbose + echo "Total: $(find /tmp/qt5platform-plugins-install -type f | wc -l) files" + find /tmp/qt5platform-plugins-install -type f | head -20 + + - name: Create installation package + run: | + ls -la /tmp/qt5platform-plugins-install/ || { echo "Install dir missing!"; exit 1; } + tar -czf /tmp/qt5platform-plugins-archlinux-$(date +%Y%m%d-%H%M%S).tar.gz -C /tmp/qt5platform-plugins-install . + ls -la /tmp/qt5platform-plugins-archlinux-*.tar.gz + + - name: Upload qt5platform-plugins Arch Linux build artifacts + if: ${{ !env.ACT }} + uses: actions/upload-artifact@v4 + with: + name: qt5platform-plugins-archlinux-build + path: "/tmp/qt5platform-plugins-archlinux-*.tar.gz" + if-no-files-found: error + retention-days: 30 diff --git a/.github/workflows/qt5platform-plugins-deepin-build.yml b/.github/workflows/qt5platform-plugins-deepin-build.yml new file mode 100644 index 00000000..080a20a4 --- /dev/null +++ b/.github/workflows/qt5platform-plugins-deepin-build.yml @@ -0,0 +1,71 @@ +name: Build qt5platform-plugins 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 + 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: Install qt5platform-plugins 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 qt5platform-plugins deb packages + run: | + dpkg-buildpackage -uc -us -b 2>&1 | tee /tmp/build.log + if [ ${PIPESTATUS[0]} -ne 0 ]; then + echo "❌ Build failed!" + exit 1 + fi + echo "✅ qt5platform-plugins deb packages built successfully!" + ls -la ../ + + - name: Upload build log on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: qt5platform-plugins-deepin-build-log + path: /tmp/build.log + if-no-files-found: warn + retention-days: 7 + + - name: Collect deb artifacts + run: | + mkdir -p dist + mv ../*.deb dist/ + ls -la dist + + - name: Upload qt5platform-plugins deb packages as artifacts + uses: actions/upload-artifact@v4 + with: + name: qt5platform-plugins-deepin-deb-packages + path: dist/*.deb + if-no-files-found: error + retention-days: 30 diff --git a/src/dnativesettings.cpp b/src/dnativesettings.cpp index 87809324..6e45f6ca 100644 --- a/src/dnativesettings.cpp +++ b/src/dnativesettings.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -21,6 +21,9 @@ #define IN_DXCB_PLUGIN #endif +#include "util/dprivateaccessor_p.h" +D_DECLARE_PRIVATE_CONST_METHOD(QObject_senderSignalIndex, QObject, senderSignalIndex, int); + #include #include #include @@ -439,7 +442,7 @@ int DNativeSettings::metaCall(QMetaObject::Call _c, int _id, void ** _a) break; } - int signal = m_base->senderSignalIndex(); + int signal = D_PRIVATE_CALL(*m_base, QObject_senderSignalIndex{}); QByteArray signal_name; qint32 data1 = 0, data2 = 0; diff --git a/src/dnativesettings.h b/src/dnativesettings.h index 39da1716..82abb546 100644 --- a/src/dnativesettings.h +++ b/src/dnativesettings.h @@ -1,13 +1,11 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later #ifndef DNATIVESETTINGS_H #define DNATIVESETTINGS_H -#define protected public #include -#undef protected #include "global.h" diff --git a/src/src.cmake b/src/src.cmake index 6fb56993..bc07e199 100644 --- a/src/src.cmake +++ b/src/src.cmake @@ -3,6 +3,7 @@ # SPDX-License-Identifier: LGPL-3.0-or-later list(APPEND GLOBAL_HEADERS + ${CMAKE_CURRENT_LIST_DIR}/util/dprivateaccessor_p.h ${CMAKE_CURRENT_LIST_DIR}/dbackingstoreproxy.h ${CMAKE_CURRENT_LIST_DIR}/dnativesettings.h ${CMAKE_CURRENT_LIST_DIR}/dopenglpaintdevice.h diff --git a/src/util/dprivateaccessor_p.h b/src/util/dprivateaccessor_p.h new file mode 100644 index 00000000..479abb43 --- /dev/null +++ b/src/util/dprivateaccessor_p.h @@ -0,0 +1,114 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#pragma once + +#include + +// 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: These helper structs must be in the SAME namespace as the Tag structs +// (global namespace, since the macros expand at file scope). If they were in a +// sub-namespace, the friend definition would create a different function than +// the friend declaration in the Tag struct, causing undefined-reference errors. + +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wnon-template-friend") + +template +struct Qt5PlatformPrivateAccessor +{ + using MemberPtr = typename Tag::MemberPtr; + friend MemberPtr get(Tag) noexcept; +}; + +template +struct Qt5PlatformPrivateAccessorImpl : Qt5PlatformPrivateAccessor +{ + friend typename Tag::MemberPtr get(Tag) noexcept { return Ptr; } +}; + +QT_WARNING_POP + +#define D_DECLARE_PRIVATE_MEMBER(TagName, ClassName, Member, MemberType) \ + struct TagName { \ + using MemberPtr = MemberType ClassName::*; \ + friend MemberPtr get(TagName) noexcept; \ + }; \ + template struct Qt5PlatformPrivateAccessorImpl + +#define D_DECLARE_PRIVATE_METHOD(TagName, ClassName, MethodName, RetType, ...) \ + struct TagName { \ + using MemberPtr = RetType (ClassName::*)(__VA_ARGS__); \ + friend MemberPtr get(TagName) noexcept; \ + }; \ + template struct Qt5PlatformPrivateAccessorImpl + +#define D_DECLARE_PRIVATE_CONST_METHOD(TagName, ClassName, MethodName, RetType, ...) \ + struct TagName { \ + using MemberPtr = RetType (ClassName::*)(__VA_ARGS__) const; \ + friend MemberPtr get(TagName) noexcept; \ + }; \ + template struct Qt5PlatformPrivateAccessorImpl + +// 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 + inline typename Tag::MemberPtr access(Tag t) noexcept { return get(t); } + + // For auto-type tags (D_DECLARE_AUTO_PRIVATE_MEMBER_TAG) that don't define MemberPtr. + template + inline auto access_auto(Tag t) noexcept -> decltype(get(t)) { return get(t); } +} + +#define D_PRIVATE_MEMBER(obj, tag) ((obj).*dtk_private_detail::access(tag)) +#define D_PRIVATE_CALL(obj, tag, ...) ((obj).*dtk_private_detail::access(tag))(__VA_ARGS__) + +// For member types that involve private enum/type names that can't be spelled +// outside the class: use a C++17 auto non-type template parameter so the +// member pointer type is deduced without naming the private type explicitly. +template +struct Qt5PlatformAutoPrivateAccessor +{ + template + static decltype(auto) access(T &obj) noexcept { return obj.*Ptr; } +}; + +// Explicit instantiation to bypass access control at the instantiation point. +// After this, callers can reference Qt5PlatformAutoPrivateAccessor::access() +// without re-triggering access checks. +#define D_DECLARE_AUTO_PRIVATE_MEMBER(ClassName, Member) \ + template struct Qt5PlatformAutoPrivateAccessor<&ClassName::Member> + +// Alternative auto accessor using the same get(Tag{}) pattern as D_DECLARE_PRIVATE_MEMBER, +// but without needing to name the member's type. Use this for members whose type involves +// private nested types (e.g., private enums) that cannot be spelled at the call site. +// +// The friend declaration MUST be in TagName itself so ADL can find get() when +// called as get(TagName{}) -- ADL only searches TagName's associated classes, not TagName##Impl. +// +// Usage: +// D_DECLARE_AUTO_PRIVATE_MEMBER_TAG(MyTag, ClassName, myMember); +// auto &ref = obj.*get(MyTag{}); // no access check needed here +#define D_DECLARE_AUTO_PRIVATE_MEMBER_TAG(TagName, ClassName, Member) \ + struct TagName { \ + friend auto get(TagName) noexcept; \ + }; \ + template \ + struct TagName##Impl { \ + friend auto get(TagName) noexcept { return Ptr; } \ + }; \ + template struct TagName##Impl<&ClassName::Member> + +#define D_AUTO_PRIVATE_MEMBER(obj, tag) ((obj).*dtk_private_detail::access_auto(tag{})) diff --git a/wayland/dwayland/dnotitlebarwindowhelper_wl.cpp b/wayland/dwayland/dnotitlebarwindowhelper_wl.cpp index b8a7281a..931177ad 100644 --- a/wayland/dwayland/dnotitlebarwindowhelper_wl.cpp +++ b/wayland/dwayland/dnotitlebarwindowhelper_wl.cpp @@ -4,10 +4,10 @@ #include "dnotitlebarwindowhelper_wl.h" #include "vtablehook.h" - -#define protected public #include -#undef protected +#include "util/dprivateaccessor_p.h" +D_DECLARE_PRIVATE_METHOD(QWindow_event_wl, QWindow, event, bool, QEvent *); + #include #include #include @@ -17,12 +17,10 @@ #include #include -#define private public #include "QtWaylandClient/private/qwaylandintegration_p.h" #include "QtWaylandClient/private/qwaylandshellsurface_p.h" #include "QtWaylandClient/private/qwaylandwindow_p.h" #include "QtWaylandClient/private/qwaylandcursor_p.h" -#undef private #include @@ -141,9 +139,9 @@ void DNoTitlebarWlWindowHelper::updateEnableSystemMoveFromProperty() m_enableSystemMove = !v.isValid() || v.toBool(); if (m_enableSystemMove) { - HookOverride(m_window, &QWindow::event, &DNoTitlebarWlWindowHelper::windowEvent); + HookOverride(m_window, get(QWindow_event_wl{}), &DNoTitlebarWlWindowHelper::windowEvent); } else if (VtableHook::hasVtable(m_window)) { - HookReset(m_window, &QWindow::event); + HookReset(m_window, get(QWindow_event_wl{})); } } @@ -152,7 +150,7 @@ bool DNoTitlebarWlWindowHelper::windowEvent(QWindow *w, QEvent *event) DNoTitlebarWlWindowHelper *self = mapped.value(w); if (!self) - return VtableHook::callOriginalFun(w, &QWindow::event, event); + return VtableHook::callOriginalFun(w, get(QWindow_event_wl{}), event); // m_window 的 event 被 override 以后,在 windowEvent 里面获取到的 this 就成 m_window 了, // 而不是 DNoTitlebarWlWindowHelper,所以此处 windowEvent 改为 static 并传 self 进来 { @@ -173,7 +171,7 @@ bool DNoTitlebarWlWindowHelper::windowEvent(QWindow *w, QEvent *event) QPointF currentPos = static_cast(event)->globalPos(); QPointF delta = touchBeginPosition - currentPos; if (delta.manhattanLength() < QGuiApplication::styleHints()->startDragDistance()) { - return VtableHook::callOriginalFun(w, &QWindow::event, event); + return VtableHook::callOriginalFun(w, get(QWindow_event_wl{}), event); } } } @@ -184,7 +182,7 @@ bool DNoTitlebarWlWindowHelper::windowEvent(QWindow *w, QEvent *event) self->m_windowMoving = false; } - if (!HookCall(w, &QWindow::event, event)) + if (!HookCall(w, get(QWindow_event_wl{}), event)) return false; // workaround for kwin: Qt receives no release event when kwin finishes MOVE operation, diff --git a/wayland/dwayland/dwaylandintegration.cpp b/wayland/dwayland/dwaylandintegration.cpp index e90d8815..12f5cd9d 100644 --- a/wayland/dwayland/dwaylandintegration.cpp +++ b/wayland/dwayland/dwaylandintegration.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -9,14 +9,23 @@ #include -#define private public #include #include #include #include -#undef private #include +#include "util/dprivateaccessor_p.h" +#if QTWAYLANDCLIENT_VERSION < QT_VERSION_CHECK(5, 13, 0) +using QWaylandDisplay_mCursorThemesBySize_type = QMap; +D_DECLARE_PRIVATE_MEMBER(QWaylandDisplay_mCursorThemesBySize, QtWaylandClient::QWaylandDisplay, mCursorThemesBySize, QWaylandDisplay_mCursorThemesBySize_type); +#elif QTWAYLANDCLIENT_VERSION < QT_VERSION_CHECK(5, 16, 0) +using QWaylandDisplay_mCursorThemes_type = QMap, QtWaylandClient::QWaylandCursorTheme *>; +D_DECLARE_PRIVATE_MEMBER(QWaylandDisplay_mCursorThemes, QtWaylandClient::QWaylandDisplay, mCursorThemes, QWaylandDisplay_mCursorThemes_type); +D_DECLARE_PRIVATE_MEMBER(QWaylandCursorTheme_m_theme, QtWaylandClient::QWaylandCursorTheme, m_theme, struct ::wl_cursor_theme *); +D_DECLARE_AUTO_PRIVATE_MEMBER_TAG(QWaylandCursorTheme_m_cursors, QtWaylandClient::QWaylandCursorTheme, m_cursors); +#endif + #include #include @@ -71,9 +80,9 @@ static void onXSettingsChanged(xcb_connection_t *connection, const QByteArray &n const QByteArray &cursor_name = dXSettings->globalSettings()->setting(name).toByteArray(); #if QTWAYLANDCLIENT_VERSION < QT_VERSION_CHECK(5, 13, 0) - const auto &cursor_map = DWaylandIntegration::instance()->display()->mCursorThemesBySize; + const auto &cursor_map = D_PRIVATE_MEMBER(*DWaylandIntegration::instance()->display(), QWaylandDisplay_mCursorThemesBySize{}); #elif QTWAYLANDCLIENT_VERSION < QT_VERSION_CHECK(5, 16, 0) - const auto &cursor_map = DWaylandIntegration::instance()->display()->mCursorThemes; + const auto &cursor_map = D_PRIVATE_MEMBER(*DWaylandIntegration::instance()->display(), QWaylandDisplay_mCursorThemes{}); #endif // 处理光标主题变化 for (auto cursor = cursor_map.constBegin(); cursor != cursor_map.constEnd(); ++cursor) { @@ -90,13 +99,13 @@ static void onXSettingsChanged(xcb_connection_t *connection, const QByteArray &n continue; // 先尝试销毁旧主题 - if (ct->m_theme) { - wl_cursor_theme_destroy(ct->m_theme); + if (D_PRIVATE_MEMBER(*ct, QWaylandCursorTheme_m_theme{})) { + wl_cursor_theme_destroy(D_PRIVATE_MEMBER(*ct, QWaylandCursorTheme_m_theme{})); } // 清理缓存数据 - ct->m_cursors.clear(); - ct->m_theme = theme; + D_AUTO_PRIVATE_MEMBER(*ct, QWaylandCursorTheme_m_cursors).clear(); + D_PRIVATE_MEMBER(*ct, QWaylandCursorTheme_m_theme{}) = theme; } // 更新窗口光标 diff --git a/wayland/dwayland/dwaylandinterfacehook.cpp b/wayland/dwayland/dwaylandinterfacehook.cpp index 9a2b7885..be7abec2 100755 --- a/wayland/dwayland/dwaylandinterfacehook.cpp +++ b/wayland/dwayland/dwaylandinterfacehook.cpp @@ -1,10 +1,8 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later -#define private public #include "QtWaylandClient/private/qwaylandnativeinterface_p.h" -#undef private #include "dwaylandinterfacehook.h" #include "dhighdpi.h" diff --git a/wayland/wayland-shell/dwaylandshellmanager.cpp b/wayland/wayland-shell/dwaylandshellmanager.cpp index ebcb6017..d0607f21 100644 --- a/wayland/wayland-shell/dwaylandshellmanager.cpp +++ b/wayland/wayland-shell/dwaylandshellmanager.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -7,9 +7,7 @@ #include "global.h" #include "../xcb/utility.h" -#define protected public #include -#undef protected #include #include diff --git a/wayland/wayland-shell/dwaylandshellmanager.h b/wayland/wayland-shell/dwaylandshellmanager.h index ad1675f1..a1198862 100644 --- a/wayland/wayland-shell/dwaylandshellmanager.h +++ b/wayland/wayland-shell/dwaylandshellmanager.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -7,7 +7,6 @@ #include "vtablehook.h" -#define private public #include "QtWaylandClient/private/qwaylandintegration_p.h" #include "QtWaylandClient/private/qwaylandshellintegrationplugin_p.h" #include "QtWaylandClient/private/qwaylandshellintegration_p.h" @@ -15,7 +14,6 @@ #include "QtWaylandClient/private/qwaylandwindow_p.h" #include "QtWaylandClient/private/qwaylandcursor_p.h" #include "QtWaylandClient/private/qwaylandscreen_p.h" -#undef private #ifndef D_DEEPIN_IS_DWAYLAND #include diff --git a/wayland/wayland-shell/main.cpp b/wayland/wayland-shell/main.cpp index 1f7e88a5..0ae4433e 100644 --- a/wayland/wayland-shell/main.cpp +++ b/wayland/wayland-shell/main.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -25,13 +25,14 @@ class QKWaylandShellIntegrationPlugin : public QWaylandShellIntegrationPlugin #include "vtablehook.h" #include "dwaylandshellmanager.h" -#define private public #include "QtWaylandClient/private/qwaylandintegration_p.h" #include "QtWaylandClient/private/qwaylandshellintegrationplugin_p.h" #include "QtWaylandClient/private/qwaylandshellintegration_p.h" #include "QtWaylandClient/private/qwaylandshellsurface_p.h" #include "QtWaylandClient/private/qwaylandwindow_p.h" -#undef private + +#include "util/dprivateaccessor_p.h" +D_DECLARE_PRIVATE_METHOD(QWaylandIntegration_createShellIntegration, QtWaylandClient::QWaylandIntegration, createShellIntegration, QtWaylandClient::QWaylandShellIntegration *, const QString &); #ifndef D_DEEPIN_IS_DWAYLAND #include @@ -125,7 +126,7 @@ QWaylandShellIntegration *QKWaylandShellIntegrationPlugin::create(const QString auto wayland_integration = static_cast(QGuiApplicationPrivate::platformIntegration()); QString shellVersion = registry->hasInterface(Registry::Interface::XdgShellUnstableV6) ? "xdg-shell-v6" : "xdg-shell"; - QWaylandShellIntegration *shell = wayland_integration->createShellIntegration(shellVersion); + QWaylandShellIntegration *shell = D_PRIVATE_CALL(*wayland_integration, QWaylandIntegration_createShellIntegration{}, shellVersion); if (!shell) { qInfo() << "Failed to create kwayland-shell and the shell is nullptr."; diff --git a/xcb/dforeignplatformwindow.h b/xcb/dforeignplatformwindow.h index b32ea0a7..4e1617a9 100644 --- a/xcb/dforeignplatformwindow.h +++ b/xcb/dforeignplatformwindow.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -13,10 +13,8 @@ #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) #include #endif -#define private public #include "qxcbwindow.h" typedef QXcbWindow QNativeWindow; -#undef private #elif defined(Q_OS_WIN) #include "qwindowswindow.h" typedef QWindowsWindow QNativeWindow; diff --git a/xcb/dnotitlebarwindowhelper.cpp b/xcb/dnotitlebarwindowhelper.cpp index 5fc311f4..35b80825 100644 --- a/xcb/dnotitlebarwindowhelper.cpp +++ b/xcb/dnotitlebarwindowhelper.cpp @@ -2,10 +2,12 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#define protected public #include -#undef protected #include "dnotitlebarwindowhelper.h" +#include "util/dprivateaccessor_p.h" + +D_DECLARE_PRIVATE_METHOD(QWindow_event, QWindow, event, bool, QEvent *); + #include "vtablehook.h" #include "utility.h" #include "dwmsupport.h" @@ -435,9 +437,9 @@ void DNoTitlebarWindowHelper::updateEnableSystemMoveFromProperty() m_enableSystemMove = !v.isValid() || v.toBool(); if (m_enableSystemMove) { - VtableHook::overrideVfptrFun(m_window, &QWindow::event, this, &DNoTitlebarWindowHelper::windowEvent); + VtableHook::overrideVfptrFun(m_window, get(QWindow_event{}), this, &DNoTitlebarWindowHelper::windowEvent); } else if (VtableHook::hasVtable(m_window)) { - VtableHook::resetVfptrFun(m_window, &QWindow::event); + VtableHook::resetVfptrFun(m_window, get(QWindow_event{})); } } @@ -526,7 +528,7 @@ bool DNoTitlebarWindowHelper::windowEvent(QEvent *event) // TODO Crashed when delete by Vtable. if (event->type() == QEvent::DeferredDelete) { VtableHook::resetVtable(w); - return w->event(event); + return D_PRIVATE_CALL(*w, QWindow_event{}, event); } DNoTitlebarWindowHelper *self = mapped.value(w); @@ -574,7 +576,7 @@ bool DNoTitlebarWindowHelper::windowEvent(QEvent *event) #endif QPointF delta = touchBeginPosition - currentPos; if (delta.manhattanLength() < QGuiApplication::styleHints()->startDragDistance()) { - return VtableHook::callOriginalFun(w, &QWindow::event, event); + return VtableHook::callOriginalFun(w, get(QWindow_event{}), event); } } @@ -591,7 +593,7 @@ bool DNoTitlebarWindowHelper::windowEvent(QEvent *event) updateMoveWindow(winId); } - bool ret = VtableHook::callOriginalFun(w, &QWindow::event, event); + bool ret = VtableHook::callOriginalFun(w, get(QWindow_event{}), event); // workaround for kwin: Qt receives no release event when kwin finishes MOVE operation, // which makes app hang in windowMoving state. when a press happens, there's no sense of diff --git a/xcb/dplatformbackingstore.h b/xcb/dplatformbackingstore.h index 8acc9eb1..12b2733b 100644 --- a/xcb/dplatformbackingstore.h +++ b/xcb/dplatformbackingstore.h @@ -1,13 +1,11 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later #ifndef DXCBBACKINGSTORE_H #define DXCBBACKINGSTORE_H -#define private public #include -#undef private #include #include diff --git a/xcb/dplatformbackingstorehelper.cpp b/xcb/dplatformbackingstorehelper.cpp index d42384ca..0819a380 100644 --- a/xcb/dplatformbackingstorehelper.cpp +++ b/xcb/dplatformbackingstorehelper.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -9,11 +9,9 @@ #include "dwmsupport.h" #ifdef Q_OS_LINUX -#define private public -#define protected public #include "qxcbbackingstore.h" -#undef protected -#undef private +#include "util/dprivateaccessor_p.h" +D_DECLARE_PRIVATE_MEMBER(QXcbBackingStore_m_image, QXcbBackingStore, m_image, QXcbBackingStoreImage *); #endif #include @@ -160,7 +158,7 @@ void DPlatformBackingStoreHelper::resize(const QSize &size, const QRegion &stati VtableHook::callOriginalFun(this->backingStore(), &QPlatformBackingStore::resize, size, staticContents); QXcbBackingStore *bs = static_cast(backingStore()); - QXcbShmImage *shm_image = reinterpret_cast(bs->m_image); + QXcbShmImage *shm_image = reinterpret_cast(D_PRIVATE_MEMBER(*bs, QXcbBackingStore_m_image{})); if (shm_image->m_shm_info.shmaddr) { DPlatformWindowHelper *window_helper = DPlatformWindowHelper::mapped.value(bs->window()->handle()); diff --git a/xcb/dplatformintegration.cpp b/xcb/dplatformintegration.cpp index 0e1c0691..db936cdb 100644 --- a/xcb/dplatformintegration.cpp +++ b/xcb/dplatformintegration.cpp @@ -1,10 +1,8 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later -#define private public #include -#undef private #include "dplatformintegration.h" #include "global.h" @@ -28,10 +26,8 @@ #endif #ifdef Q_OS_LINUX -#define private public #include "qxcbcursor.h" #include "qxcbdrag.h" -#undef private #include "windoweventhook.h" #include "xcbnativeeventfilter.h" @@ -54,9 +50,7 @@ #include #include -#define protected public #include -#undef protected #include #include #include @@ -70,6 +64,23 @@ #define XSETTINGS_CURSOR_BLINK_TIME QByteArrayLiteral("Net/CursorBlinkTime") #define XSETTINGS_DOUBLE_CLICK_TIME QByteArrayLiteral("Net/DoubleClickTime") +#ifdef Q_OS_LINUX +#include "util/dprivateaccessor_p.h" +D_DECLARE_PRIVATE_MEMBER(QXcbIntegration_m_wmClass, QXcbIntegration, m_wmClass, QByteArray); +D_DECLARE_PRIVATE_MEMBER(QXcbCursor_m_screen, QXcbCursor, m_screen, QXcbScreen *); +D_DECLARE_AUTO_PRIVATE_MEMBER_TAG(QXcbCursor_m_cursorHash, QXcbCursor, m_cursorHash); +D_DECLARE_PRIVATE_MEMBER(QXcbCursor_m_gtkCursorThemeInitialized, QXcbCursor, m_gtkCursorThemeInitialized, bool); +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) +D_DECLARE_PRIVATE_MEMBER(QXcbCursor_m_callbackForPropertyRegistered, QXcbCursor, m_callbackForPropertyRegistered, bool); +#endif +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +D_DECLARE_PRIVATE_MEMBER(QXcbCursor_m_cursorContext, QXcbCursor, m_cursorContext, xcb_cursor_context_t *); +#endif +#include "qxcbclipboard.h" +D_DECLARE_PRIVATE_MEMBER(QXcbClipboard_m_owner, QXcbClipboard, m_owner, xcb_window_t); +D_DECLARE_PRIVATE_MEMBER(QXcbClipboard_m_requestor, QXcbClipboard, m_requestor, xcb_window_t); +#endif + Q_LOGGING_CATEGORY(lcDxcb, "dtk.qpa.dxcb", QtInfoMsg) class DQPaintEngine : public QPaintEngine @@ -281,7 +292,7 @@ void DPlatformIntegration::clearNativeSettings(quint32 settingWindow) void DPlatformIntegration::setWMClassName(const QByteArray &name) { if (auto self = instance()) - self->m_wmClass = name; + D_PRIVATE_MEMBER(*self, QXcbIntegration_m_wmClass{}) = name; } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -804,9 +815,9 @@ static xcb_cursor_t overrideCreateNonStandardCursor(QXcbCursor *xcb_cursor, Qt:: switch (cshape) { case Qt::BlankCursor: { - xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(conn, xcb_cursor->m_screen->root(), cur_blank_bits, 16, 16, + xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(conn, D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_screen{})->root(), cur_blank_bits, 16, 16, 1, 0, 0, 0); - xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(conn, xcb_cursor->m_screen->root(), cur_blank_bits, 16, 16, + xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(conn, D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_screen{})->root(), cur_blank_bits, 16, 16, 1, 0, 0, 0); cursor = xcb_generate_id(conn); xcb_create_cursor(conn, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8); @@ -856,7 +867,7 @@ static xcb_cursor_t overrideCreateNonStandardCursor(QXcbCursor *xcb_cursor, Qt:: if (!image.isNull()) { image = image.scaledToWidth(24 * window->devicePixelRatio()); - cursor = qt_xcb_createCursorXRender(xcb_cursor->m_screen, image, QPoint(8, 8) * window->devicePixelRatio()); + cursor = qt_xcb_createCursorXRender(D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_screen{}), image, QPoint(8, 8) * window->devicePixelRatio()); } return cursor; @@ -888,9 +899,9 @@ static bool updateCursorTheme(void *dpy) cursor = loadCursor(dpy, cshape); #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) - if (!cursor && !xcb_cursor->m_callbackForPropertyRegistered) { + if (!cursor && !D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_callbackForPropertyRegistered{})) { #else - if (!cursor && !xcb_cursor->m_gtkCursorThemeInitialized) { + if (!cursor && !D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_gtkCursorThemeInitialized{})) { #endif VtableHook::callOriginalFun(xcb_cursor, &QPlatformCursor::changeCursor, c, window); @@ -957,9 +968,9 @@ static void overrideChangeCursor(QPlatformCursor *cursorHandle, QCursor * cursor xcb_cursor_t c = XCB_CURSOR_NONE; if (cursor && cursor->shape() != Qt::BitmapCursor) { const QXcbCursorCacheKey key(cursor->shape()); - QXcbCursor::CursorHash::iterator it = xcb_cursor->m_cursorHash.find(key); - if (it == xcb_cursor->m_cursorHash.end()) { - it = xcb_cursor->m_cursorHash.insert(key, overrideCreateFontCursor(xcb_cursor, cursor, widget)); + auto it = D_AUTO_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorHash).find(key); + if (it == D_AUTO_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorHash).end()) { + it = D_AUTO_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorHash).insert(key, overrideCreateFontCursor(xcb_cursor, cursor, widget)); } c = it.value(); #if QT_VERSION < QT_VERSION_CHECK(5, 7, 1) @@ -1051,11 +1062,11 @@ static void startDrag(QXcbDrag *drag) // if (support_actions.size() < 2) // return; #if QT_VERSION <= QT_VERSION_CHECK(6, 2, 4) - xcb_change_property(drag->xcb_connection(), XCB_PROP_MODE_REPLACE, drag->connection()->clipboard()->m_owner, + xcb_change_property(drag->xcb_connection(), XCB_PROP_MODE_REPLACE, D_PRIVATE_MEMBER(*drag->connection()->clipboard(), QXcbClipboard_m_owner{}), drag->atom(QXcbAtom::D_QXCBATOM_WRAPPER(XdndActionList)), XCB_ATOM_ATOM, sizeof(xcb_atom_t) * 8, support_actions.size(), support_actions.constData()); #else - xcb_change_property(drag->xcb_connection(), XCB_PROP_MODE_REPLACE, drag->connection()->clipboard()->m_requestor, //TODO: m_ower deleted, replaced by m_requestor ? + xcb_change_property(drag->xcb_connection(), XCB_PROP_MODE_REPLACE, D_PRIVATE_MEMBER(*drag->connection()->clipboard(), QXcbClipboard_m_requestor{}), //TODO: m_ower deleted, replaced by m_requestor ? drag->atom(QXcbAtom::D_QXCBATOM_WRAPPER(XdndActionList)), XCB_ATOM_ATOM, sizeof(xcb_atom_t) * 8, support_actions.size(), support_actions.constData()); #endif @@ -1077,19 +1088,19 @@ static void cursorThemePropertyChanged(xcb_connection_t *connection, const QByte if (xcb_cursor == nullptr) { continue; } - xcb_cursor->m_cursorHash.clear(); + D_AUTO_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorHash).clear(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) // source from: QXCBCursor::updateContext() // Note: m_cursorContext only exists in Qt6 - if (xcb_cursor->m_cursorContext) { - xcb_cursor_context_free(xcb_cursor->m_cursorContext); + if (D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorContext{})) { + xcb_cursor_context_free(D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorContext{})); } - xcb_cursor->m_cursorContext = nullptr; + D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorContext{}) = nullptr; xcb_connection_t *conn = xcb_cursor->xcb_connection(); - if (xcb_cursor_context_new(conn, xcb_cursor->m_screen->screen(), &xcb_cursor->m_cursorContext) < 0) { - xcb_cursor->m_cursorContext = nullptr; + if (xcb_cursor_context_new(conn, D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_screen{})->screen(), &D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorContext{})) < 0) { + D_PRIVATE_MEMBER(*xcb_cursor, QXcbCursor_m_cursorContext{}) = nullptr; } #endif } @@ -1169,7 +1180,7 @@ void DPlatformIntegration::initialize() VtableHook::overrideVfptrFun(xcbConnection()->drag(), &QXcbDrag::startDrag, &startDrag); #endif - VtableHook::overrideVfptrFun(qApp->d_func(), &QGuiApplicationPrivate::isWindowBlocked, + VtableHook::overrideVfptrFun(static_cast(QObjectPrivate::get(qApp)), &QGuiApplicationPrivate::isWindowBlocked, this, &DPlatformIntegration::isWindowBlockedHandle); // FIXME(zccrs): 修复启动drag后鼠标从一块屏幕移动到另一块后图标窗口位置不对 @@ -1287,7 +1298,7 @@ DXcbXSettings *DPlatformIntegration::xSettings(QXcbConnection *connection) bool DPlatformIntegration::isWindowBlockedHandle(QWindow *window, QWindow **blockingWindow) { if (DFrameWindow *frame = qobject_cast(window)) { - bool blocked = VtableHook::callOriginalFun(qApp->d_func(), &QGuiApplicationPrivate::isWindowBlocked, frame->m_contentWindow, blockingWindow); + bool blocked = VtableHook::callOriginalFun(static_cast(QObjectPrivate::get(qApp)), &QGuiApplicationPrivate::isWindowBlocked, frame->m_contentWindow, blockingWindow); // NOTE(zccrs): 将内容窗口的blocked状态转移到frame窗口,否则会被QXcbWindow::relayFocusToModalWindow重复调用requestActivate而引起死循环 if (blockingWindow && frame->m_contentWindow.data() == *blockingWindow) { @@ -1297,7 +1308,7 @@ bool DPlatformIntegration::isWindowBlockedHandle(QWindow *window, QWindow **bloc return blocked; } - return VtableHook::callOriginalFun(qApp->d_func(), &QGuiApplicationPrivate::isWindowBlocked, window, blockingWindow); + return VtableHook::callOriginalFun(static_cast(QObjectPrivate::get(qApp)), &QGuiApplicationPrivate::isWindowBlocked, window, blockingWindow); } void DPlatformIntegration::inputContextHookFunc() diff --git a/xcb/dplatformintegration.h b/xcb/dplatformintegration.h index 2810e4d1..6b65e763 100644 --- a/xcb/dplatformintegration.h +++ b/xcb/dplatformintegration.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -10,9 +10,7 @@ #include #ifdef Q_OS_LINUX -#define private protected #include "qxcbintegration.h" -#undef private typedef QXcbIntegration DPlatformIntegrationParent; class QXcbVirtualDesktop; #elif defined(Q_OS_WIN) diff --git a/xcb/dplatformwindowhelper.h b/xcb/dplatformwindowhelper.h index ace4692c..94e879d9 100644 --- a/xcb/dplatformwindowhelper.h +++ b/xcb/dplatformwindowhelper.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -11,11 +11,8 @@ #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) #include #endif -#define private public #include "qxcbwindow.h" -#include "qxcbclipboard.h" typedef QXcbWindow QNativeWindow; -#undef private #elif defined(Q_OS_WIN) #include "qwindowswindow.h" typedef QWindowsWindow QNativeWindow; diff --git a/xcb/dplatformwindowhook.h b/xcb/dplatformwindowhook.h index 0f0ec759..5e849a24 100644 --- a/xcb/dplatformwindowhook.h +++ b/xcb/dplatformwindowhook.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -8,11 +8,8 @@ #include #ifdef Q_OS_LINUX -#define private public #include "qxcbwindow.h" -#include "qxcbclipboard.h" typedef QXcbWindow QNativeWindow; -#undef private #elif defined(Q_OS_WIN) #include "qwindowswindow.h" typedef QWindowsWindow QNativeWindow; diff --git a/xcb/dxcbwmsupport.cpp b/xcb/dxcbwmsupport.cpp index b2c7c569..b2bba072 100644 --- a/xcb/dxcbwmsupport.cpp +++ b/xcb/dxcbwmsupport.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -8,12 +8,13 @@ #include "dframewindow.h" #include "qxcbconnection.h" -#define private public #include "qxcbscreen.h" -#undef private #include "qxcbwindow.h" #include "3rdparty/clientwin.h" +#include "util/dprivateaccessor_p.h" +D_DECLARE_PRIVATE_MEMBER(QXcbVirtualDesktop_m_compositingActive, QXcbVirtualDesktop, m_compositingActive, bool); + DPP_BEGIN_NAMESPACE class _DXcbWMSupport : public DXcbWMSupport {}; @@ -194,7 +195,7 @@ void DXcbWMSupport::updateHasComposite() // 及时更新Qt中记录的值,KWin在关闭窗口合成的一段时间内(2S)并未释放相关的selection owner // 因此会导致Qt中的值在某个阶段与真实状态不匹配,用到QX11Info::isCompositingManagerRunning() // 的地方会出现问题,如drag窗口 - DPlatformIntegration::xcbConnection()->primaryVirtualDesktop()->m_compositingActive = hasComposite; + D_PRIVATE_MEMBER(*DPlatformIntegration::xcbConnection()->primaryVirtualDesktop(), QXcbVirtualDesktop_m_compositingActive{}) = hasComposite; } else { //stage2: fallback to check selection owner xcb_get_selection_owner_cookie_t cookit = xcb_get_selection_owner(xcb_connection, DPlatformIntegration::xcbConnection()->atom(QXcbAtom::D_QXCBATOM_WRAPPER(_NET_WM_CM_S0))); diff --git a/xcb/windoweventhook.cpp b/xcb/windoweventhook.cpp index 6249b4f1..fdde71af 100644 --- a/xcb/windoweventhook.cpp +++ b/xcb/windoweventhook.cpp @@ -19,12 +19,20 @@ QT_END_NAMESPACE #include "dplatformwindowhelper.h" #include "dhighdpi.h" -#define private public -#define protected public #include "qxcbdrag.h" #include "qxcbkeyboard.h" -#undef private -#undef protected + +#include "util/dprivateaccessor_p.h" +D_DECLARE_PRIVATE_MEMBER(QXcbDrag_currentWindow, QXcbDrag, currentWindow, QPointer); +D_DECLARE_PRIVATE_MEMBER(QXcbDrag_currentPosition, QXcbDrag, currentPosition, QPoint); +D_DECLARE_PRIVATE_MEMBER(QXcbDrag_m_dropData, QXcbDrag, m_dropData, QXcbDropData *); +D_DECLARE_PRIVATE_MEMBER(QXcbDrag_accepted_drop_action, QXcbDrag, accepted_drop_action, Qt::DropAction); +D_DECLARE_PRIVATE_MEMBER(QXcbDrag_xdnd_dragsource, QXcbDrag, xdnd_dragsource, xcb_atom_t); +D_DECLARE_PRIVATE_MEMBER(QXcbDrag_target_time, QXcbDrag, target_time, xcb_timestamp_t); +D_DECLARE_PRIVATE_MEMBER(QXcbDrag_waiting_for_status, QXcbDrag, waiting_for_status, bool); +D_DECLARE_AUTO_PRIVATE_MEMBER_TAG(QXcbKeyboard_rmod_masks, QXcbKeyboard, rmod_masks); +D_DECLARE_PRIVATE_MEMBER(QXcbDrag_current_proxy_target, QXcbDrag, current_proxy_target, xcb_window_t); +D_DECLARE_PRIVATE_METHOD(QBasicDrag_setExecutedDropAction, QBasicDrag, setExecutedDropAction, void, Qt::DropAction); #include #include @@ -181,7 +189,7 @@ void WindowEventHook::handleClientMessageEvent(QXcbWindowEventListener *el, cons Qt::DropActions support_actions = Qt::IgnoreAction; do { - xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection, false, drag->xdnd_dragsource, + xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection, false, D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{}), window->connection()->atom(QXcbAtom::D_QXCBATOM_WRAPPER(XdndActionList)), XCB_ATOM_ATOM, offset, 1024); xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection, cookie, NULL); @@ -213,7 +221,7 @@ void WindowEventHook::handleClientMessageEvent(QXcbWindowEventListener *el, cons QMimeData *dropData = drag->platformDropData(); #else //FIXME(zccrs): must use the drop data object - QMimeData *dropData = reinterpret_cast(drag->m_dropData); + QMimeData *dropData = reinterpret_cast(D_PRIVATE_MEMBER(*drag, QXcbDrag_m_dropData{})); #endif if (!dropData) { @@ -227,8 +235,8 @@ void WindowEventHook::handleClientMessageEvent(QXcbWindowEventListener *el, cons QXcbDrag *drag = window->connection()->drag(); DEBUG("xdndHandleDrop"); - if (!drag->currentWindow) { - drag->xdnd_dragsource = 0; + if (!D_PRIVATE_MEMBER(*drag, QXcbDrag_currentWindow{})) { + D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{}) = 0; return; // sanity } @@ -236,14 +244,14 @@ void WindowEventHook::handleClientMessageEvent(QXcbWindowEventListener *el, cons DEBUG("xdnd drop"); - if (l[0] != drag->xdnd_dragsource) { - DEBUG("xdnd drop from unexpected source (%x not %x", l[0], drag->xdnd_dragsource); + if (l[0] != D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{})) { + DEBUG("xdnd drop from unexpected source (%x not %x", l[0], D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{})); return; } // update the "user time" from the timestamp in the event. if (l[2] != 0) - drag->target_time = /*X11->userTime =*/ l[2]; + D_PRIVATE_MEMBER(*drag, QXcbDrag_target_time{}) = /*X11->userTime =*/ l[2]; Qt::DropActions supported_drop_actions; QMimeData *dropData = 0; @@ -255,9 +263,9 @@ void WindowEventHook::handleClientMessageEvent(QXcbWindowEventListener *el, cons dropData = drag->platformDropData(); #else //FIXME(zccrs): must use the drop data object - dropData = reinterpret_cast(drag->m_dropData); + dropData = reinterpret_cast(D_PRIVATE_MEMBER(*drag, QXcbDrag_m_dropData{})); #endif - supported_drop_actions = drag->accepted_drop_action; + supported_drop_actions = D_PRIVATE_MEMBER(*drag, QXcbDrag_accepted_drop_action{}); // Drop coming from another app? Update keyboard modifiers. QGuiApplicationPrivate::modifier_buttons = QGuiApplication::queryKeyboardModifiers(); @@ -280,27 +288,27 @@ void WindowEventHook::handleClientMessageEvent(QXcbWindowEventListener *el, cons if (!drag->currentDrag()) QGuiApplicationPrivate::mouse_buttons = window->connection()->queryMouseButtons(); - QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(drag->currentWindow.data(), - dropData, drag->currentPosition, + QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(D_PRIVATE_MEMBER(*drag, QXcbDrag_currentWindow{}).data(), + dropData, D_PRIVATE_MEMBER(*drag, QXcbDrag_currentPosition{}), supported_drop_actions, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); #else - QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(drag->currentWindow.data(), - dropData, drag->currentPosition, + QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(D_PRIVATE_MEMBER(*drag, QXcbDrag_currentWindow{}).data(), + dropData, D_PRIVATE_MEMBER(*drag, QXcbDrag_currentPosition{}), supported_drop_actions); #endif - drag->setExecutedDropAction(response.acceptedAction()); + D_PRIVATE_CALL(*drag, QBasicDrag_setExecutedDropAction{}, response.acceptedAction()); if (directSaveMode) { const QUrl &url = dropData->property("DirectSaveUrl").toUrl(); - if (url.isValid() && drag->xdnd_dragsource) { + if (url.isValid() && D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{})) { xcb_atom_t XdndDirectSaveAtom = Utility::internAtom("XdndDirectSave0"); xcb_atom_t textAtom = Utility::internAtom("text/plain"); - QByteArray basename = Utility::windowProperty(drag->xdnd_dragsource, XdndDirectSaveAtom, textAtom, 1024); + QByteArray basename = Utility::windowProperty(D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{}), XdndDirectSaveAtom, textAtom, 1024); QByteArray fileUri = url.toString().toLocal8Bit() + "/" + basename; - Utility::setWindowProperty(drag->xdnd_dragsource, XdndDirectSaveAtom, + Utility::setWindowProperty(D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{}), XdndDirectSaveAtom, textAtom, fileUri.constData(), fileUri.length()); Q_UNUSED(dropData->data("XdndDirectSave0")); @@ -310,26 +318,26 @@ void WindowEventHook::handleClientMessageEvent(QXcbWindowEventListener *el, cons xcb_client_message_event_t finished; finished.response_type = XCB_CLIENT_MESSAGE; finished.sequence = 0; - finished.window = drag->xdnd_dragsource; + finished.window = D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{}); finished.format = 32; finished.type = drag->atom(QXcbAtom::D_QXCBATOM_WRAPPER(XdndFinished)); - finished.data.data32[0] = drag->currentWindow ? xcb_window(drag->currentWindow.data()) : XCB_NONE; + finished.data.data32[0] = D_PRIVATE_MEMBER(*drag, QXcbDrag_currentWindow{}) ? xcb_window(D_PRIVATE_MEMBER(*drag, QXcbDrag_currentWindow{}).data()) : XCB_NONE; finished.data.data32[1] = response.isAccepted(); // flags finished.data.data32[2] = toXdndAction(drag, response.acceptedAction()); #ifdef Q_XCB_CALL - Q_XCB_CALL(xcb_send_event(drag->xcb_connection(), false, drag->current_proxy_target, + Q_XCB_CALL(xcb_send_event(drag->xcb_connection(), false, D_PRIVATE_MEMBER(*drag, QXcbDrag_current_proxy_target{}), XCB_EVENT_MASK_NO_EVENT, (char *)&finished)); #else - xcb_send_event(drag->xcb_connection(), false, drag->current_proxy_target, + xcb_send_event(drag->xcb_connection(), false, D_PRIVATE_MEMBER(*drag, QXcbDrag_current_proxy_target{}), XCB_EVENT_MASK_NO_EVENT, (char *)&finished); #endif - drag->xdnd_dragsource = 0; - drag->currentWindow.clear(); - drag->waiting_for_status = false; + D_PRIVATE_MEMBER(*drag, QXcbDrag_xdnd_dragsource{}) = 0; + D_PRIVATE_MEMBER(*drag, QXcbDrag_currentWindow{}).clear(); + D_PRIVATE_MEMBER(*drag, QXcbDrag_waiting_for_status{}) = false; // reset - drag->target_time = XCB_CURRENT_TIME; + D_PRIVATE_MEMBER(*drag, QXcbDrag_target_time{}) = XCB_CURRENT_TIME; } else { window->QXcbWindow::handleClientMessageEvent(event); } @@ -400,7 +408,8 @@ void WindowEventHook::handlePropertyNotifyEvent(QXcbWindowEventListener *el, con } #ifdef XCB_USE_XINPUT22 -static Qt::KeyboardModifiers translateModifiers(const QXcbKeyboard::_mod_masks &rmod_masks, int s) +template +static Qt::KeyboardModifiers translateModifiers(const T &rmod_masks, int s) { Qt::KeyboardModifiers ret = Qt::KeyboardModifiers(); if (s & XCB_MOD_MASK_SHIFT) @@ -447,7 +456,7 @@ void WindowEventHook::handleXIEnterLeave(QXcbWindowEventListener *el, xcb_ge_eve #else Qt::MouseButtons buttons = me->connection()->buttonState(); #endif - const Qt::KeyboardModifiers modifiers = translateModifiers(me->connection()->keyboard()->rmod_masks, ev->mods.effective_mods); + const Qt::KeyboardModifiers modifiers = translateModifiers(D_AUTO_PRIVATE_MEMBER(*me->connection()->keyboard(), QXcbKeyboard_rmod_masks), ev->mods.effective_mods); unsigned char *buttonMask = (unsigned char *) &ev[1]; for (int i = 1; i <= 15; ++i) { Qt::MouseButton b = me->connection()->translateMouseButton(i); diff --git a/xcb/xcb.cmake b/xcb/xcb.cmake index ddf5929a..3dd7e67b 100644 --- a/xcb/xcb.cmake +++ b/xcb/xcb.cmake @@ -28,3 +28,4 @@ endif() set(xcb_SRC ${XCB_HEADER} ${XCB_SOURCE} ${XCB_RCC_QRCS} ${DBUS_INTERFACE_XMLS}) include_directories(${CMAKE_CURRENT_LIST_DIR}) +include_directories(${CMAKE_SOURCE_DIR}/src) diff --git a/xcb/xcbnativeeventfilter.cpp b/xcb/xcbnativeeventfilter.cpp index 09132e1c..02a3549b 100644 --- a/xcb/xcbnativeeventfilter.cpp +++ b/xcb/xcbnativeeventfilter.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2022 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2017 - 2026 Uniontech Software Technology Co.,Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -7,15 +7,21 @@ #include "dplatformwindowhelper.h" #include "dframewindow.h" -#define private public #include "qxcbconnection.h" #include "qxcbclipboard.h" -#undef private +#include "qxcbconnection_basic.h" #include "dplatformintegration.h" #include "dxcbwmsupport.h" #include "dxcbxsettings.h" +#include "util/dprivateaccessor_p.h" +D_DECLARE_PRIVATE_MEMBER(QXcbBasicConnection_m_xfixesFirstEvent, QXcbBasicConnection, m_xfixesFirstEvent, uint32_t); +D_DECLARE_PRIVATE_MEMBER(QXcbBasicConnection_m_xiOpCode, QXcbBasicConnection, m_xiOpCode, int); +D_DECLARE_PRIVATE_MEMBER(QXcbBasicConnection_m_xrandrFirstEvent, QXcbBasicConnection, m_xrandrFirstEvent, uint32_t); +D_DECLARE_PRIVATE_CONST_METHOD(QXcbConnection_findScreenForOutput, QXcbConnection, findScreenForOutput, QXcbScreen*, xcb_window_t, xcb_randr_output_t); +D_DECLARE_PRIVATE_METHOD(QXcbConnection_updateScreens, QXcbConnection, updateScreens, void, const xcb_randr_notify_event_t *); + #include #include #include @@ -89,7 +95,7 @@ bool XcbNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void * if (Q_UNLIKELY(response_type == m_connection->xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY)) { #else // cannot use isXFixesType because symbols from QXcbBasicConnection are not exported - if (response_type == m_connection->m_xfixesFirstEvent + XCB_XFIXES_SELECTION_NOTIFY) { + if (response_type == D_PRIVATE_MEMBER(*m_connection, QXcbBasicConnection_m_xfixesFirstEvent{}) + XCB_XFIXES_SELECTION_NOTIFY) { #endif xcb_xfixes_selection_notify_event_t *xsn = (xcb_xfixes_selection_notify_event_t *)event; @@ -103,7 +109,7 @@ bool XcbNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void * // here we care only about the xfixes events that come from non Qt processes if (xsn->owner == XCB_NONE && xsn->subtype == XCB_XFIXES_SELECTION_EVENT_SET_SELECTION_OWNER) { - QXcbClipboard *xcbClipboard = m_connection->m_clipboard; + QXcbClipboard *xcbClipboard = m_connection->clipboard(); xcbClipboard->emitChanged(mode); } } else if (Q_UNLIKELY(response_type == m_damageFirstEvent + XCB_DAMAGE_NOTIFY)) { @@ -156,7 +162,7 @@ bool XcbNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void * case XCB_GE_GENERIC: { QXcbConnection *xcb_connect = DPlatformIntegration::xcbConnection(); - if (Q_LIKELY(xcb_connect->m_xi2Enabled) && isXIEvent(event, xcb_connect->m_xiOpCode)) { + if (Q_LIKELY(xcb_connect->hasXInput2()) && isXIEvent(event, D_PRIVATE_MEMBER(*xcb_connect, QXcbBasicConnection_m_xiOpCode{}))) { xXIGenericDeviceEvent *xiEvent = reinterpret_cast(event); { @@ -248,17 +254,17 @@ bool XcbNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void * #else // cannot use isXRandrType because symbols from QXcbBasicConnection are not exported if (Q_UNLIKELY(updateScaleLogcailDpi) && DPlatformIntegration::xcbConnection()->hasXRender() - && response_type == DPlatformIntegration::xcbConnection()->m_xrandrFirstEvent + XCB_RANDR_NOTIFY) { + && response_type == D_PRIVATE_MEMBER(*DPlatformIntegration::xcbConnection(), QXcbBasicConnection_m_xrandrFirstEvent{}) + XCB_RANDR_NOTIFY) { #endif xcb_randr_notify_event_t *e = reinterpret_cast(event); xcb_randr_output_change_t output = e->u.oc; if (e->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) { - QXcbScreen *screen = DPlatformIntegration::xcbConnection()->findScreenForOutput(output.window, output.output); + QXcbScreen *screen = D_PRIVATE_CALL(*DPlatformIntegration::xcbConnection(), QXcbConnection_findScreenForOutput{}, output.window, output.output); if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED && output.crtc != XCB_NONE && output.mode != XCB_NONE) { - DPlatformIntegration::xcbConnection()->updateScreens(e); + D_PRIVATE_CALL(*DPlatformIntegration::xcbConnection(), QXcbConnection_updateScreens{}, e); // 通知deepin platform插件重设缩放后的dpi值 reinterpret_cast(updateScaleLogcailDpi)();