From 9d71baffd17677a94b4cd686f7593adf3c0b67b0 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Wed, 4 May 2022 15:07:30 +0800 Subject: [PATCH] remove the last piece of Qt internal classes Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- src/core/CMakeLists.txt | 6 +- src/core/qtx11extras.cpp | 575 --------------------------------------- src/core/qtx11extras_p.h | 122 --------- src/core/utils_linux.cpp | 146 +++++++++- 4 files changed, 140 insertions(+), 709 deletions(-) delete mode 100644 src/core/qtx11extras.cpp delete mode 100644 src/core/qtx11extras_p.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ec1c299..14e84b2 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -54,11 +54,7 @@ if(WIN32) elseif(APPLE) list(APPEND SOURCES utils_mac.mm) elseif(UNIX) - list(APPEND SOURCES - qtx11extras_p.h - qtx11extras.cpp - utils_linux.cpp - ) + list(APPEND SOURCES utils_linux.cpp) endif() if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC) diff --git a/src/core/qtx11extras.cpp b/src/core/qtx11extras.cpp deleted file mode 100644 index 696d666..0000000 --- a/src/core/qtx11extras.cpp +++ /dev/null @@ -1,575 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2022 The Qt Company Ltd. -** Copyright (C) 2022 Richard Moore -** Copyright (C) 2022 David Faure -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtx11extras_p.h" -#if (QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) -#include -#include -#include -#include -#include -#include -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) -# include -# include -#else -# include -#endif - -QT_BEGIN_NAMESPACE - -[[nodiscard]] static inline QScreen *findScreenForVirtualDesktop(const int virtualDesktopNumber) -{ - if (virtualDesktopNumber == -1) { - return QGuiApplication::primaryScreen(); - } - const QList screens = QGuiApplication::screens(); - if (screens.isEmpty()) { - return nullptr; - } - for (auto &&screen : qAsConst(screens)) { -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) - const auto qxcbScreen = dynamic_cast(screen->handle()); - if (qxcbScreen && (qxcbScreen->virtualDesktopNumber() == virtualDesktopNumber)) { - return screen; - } -#else - if (QXcbScreenFunctions::virtualDesktopNumber(screen) == virtualDesktopNumber) { - return screen; - } -#endif - } - return nullptr; -} - -/*! - \class QX11Info - \inmodule QtGui - \since 6.2 - \internal - - \brief Provides information about the X display configuration. - - The class provides two APIs: a set of non-static functions that - provide information about a specific widget or pixmap, and a set - of static functions that provide the default information for the - application. - - \warning This class is only available on X11. For querying - per-screen information in a portable way, use QDesktopWidget. -*/ - -/*! - Constructs an empty QX11Info object. -*/ -QX11Info::QX11Info() -{ -} - -/*! - Destructor of QX11Info object. -*/ -QX11Info::~QX11Info() = default; - -/*! - Returns true if the application is currently running on X11. - - \since 6.2 - */ -bool QX11Info::isPlatformX11() -{ - return QGuiApplication::platformName() == QLatin1String("xcb"); -} - -/*! - Returns the horizontal resolution of the given \a screen in terms of the - number of dots per inch. - - The \a screen argument is an X screen number. Be aware that if - the user's system uses Xinerama (as opposed to traditional X11 - multiscreen), there is only one X screen. Use QDesktopWidget to - query for information about Xinerama screens. - - \sa appDpiY() -*/ -int QX11Info::appDpiX(const int screen) -{ - if (screen == -1) { - const QScreen *scr = QGuiApplication::primaryScreen(); - if (!scr) - return 75; - return qRound(scr->logicalDotsPerInchX()); - } - - QScreen *scr = findScreenForVirtualDesktop(screen); - if (!scr) - return 0; - - return scr->logicalDotsPerInchX(); -} - -/*! - Returns the vertical resolution of the given \a screen in terms of the - number of dots per inch. - - The \a screen argument is an X screen number. Be aware that if - the user's system uses Xinerama (as opposed to traditional X11 - multiscreen), there is only one X screen. Use QDesktopWidget to - query for information about Xinerama screens. - - \sa appDpiX() -*/ -int QX11Info::appDpiY(const int screen) -{ - if (screen == -1) { - const QScreen *scr = QGuiApplication::primaryScreen(); - if (!scr) - return 75; - return qRound(scr->logicalDotsPerInchY()); - } - - QScreen *scr = findScreenForVirtualDesktop(screen); - if (!scr) - return 0; - - return scr->logicalDotsPerInchY(); -} - -/*! - Returns a handle for the applications root window on the given \a screen. - - The \a screen argument is an X screen number. Be aware that if - the user's system uses Xinerama (as opposed to traditional X11 - multiscreen), there is only one X screen. Use QDesktopWidget to - query for information about Xinerama screens. -*/ -#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) -unsigned long QX11Info::appRootWindow(const int screen) -#else -quint32 QX11Info::appRootWindow(const int screen) -#endif -{ - if (!qApp) - return 0; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return 0; - QScreen *scr = screen == -1 ? QGuiApplication::primaryScreen() : findScreenForVirtualDesktop(screen); - if (!scr) - return 0; - return static_cast(reinterpret_cast(native->nativeResourceForScreen(QByteArrayLiteral("rootwindow"), scr))); -} - -/*! - Returns the number of the screen where the application is being - displayed. - - This method refers to screens in the original X11 meaning with a - different DISPLAY environment variable per screen. - This information is only useful if your application needs to know - on which X screen it is running. - - In a typical multi-head configuration, multiple physical monitors - are combined in one X11 screen. This means this method returns the - same number for each of the physical monitors. In such a setup you - are interested in the monitor information as provided by the X11 - RandR extension. This is available through QDesktopWidget and QScreen. - - \sa display() -*/ -int QX11Info::appScreen() -{ - if (!qApp) - return 0; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return 0; - return reinterpret_cast(native->nativeResourceForIntegration(QByteArrayLiteral("x11screen"))); -} - -/*! - Returns the X11 time. - - \sa setAppTime(), appUserTime() -*/ -quint32 QX11Info::appTime() -{ - if (!qApp) - return 0; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return 0; - QScreen* screen = QGuiApplication::primaryScreen(); - return static_cast(reinterpret_cast(native->nativeResourceForScreen("apptime", screen))); -} - -/*! - Returns the X11 user time. - - \sa setAppUserTime(), appTime() -*/ -quint32 QX11Info::appUserTime() -{ - if (!qApp) - return 0; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return 0; - QScreen* screen = QGuiApplication::primaryScreen(); - return static_cast(reinterpret_cast(native->nativeResourceForScreen("appusertime", screen))); -} - -/*! - Sets the X11 time to the value specified by \a time. - - \sa appTime(), setAppUserTime() -*/ -void QX11Info::setAppTime(const quint32 time) -{ - if (!qApp) - return; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return; - using SetAppTimeFunc = void(*)(QScreen *, xcb_timestamp_t); - QScreen* screen = QGuiApplication::primaryScreen(); - auto func = reinterpret_cast(reinterpret_cast(native->nativeResourceFunctionForScreen("setapptime"))); - if (func) - func(screen, time); - else - qWarning("Internal error: QPA plugin doesn't implement setAppTime"); -} - -/*! - Sets the X11 user time as specified by \a time. - - \sa appUserTime(), setAppTime() -*/ -void QX11Info::setAppUserTime(const quint32 time) -{ - if (!qApp) - return; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return; - using SetAppUserTimeFunc = void(*)(QScreen *, xcb_timestamp_t); - QScreen* screen = QGuiApplication::primaryScreen(); - auto func = reinterpret_cast(reinterpret_cast(native->nativeResourceFunctionForScreen("setappusertime"))); - if (func) - func(screen, time); - else - qWarning("Internal error: QPA plugin doesn't implement setAppUserTime"); -} - -/*! - Fetches the current X11 time stamp from the X Server. - - This method creates a property notify event and blocks till it is - received back from the X Server. -*/ -quint32 QX11Info::getTimestamp() -{ - if (!qApp) - return 0; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return 0; - QScreen* screen = QGuiApplication::primaryScreen(); - return static_cast(reinterpret_cast(native->nativeResourceForScreen("gettimestamp", screen))); -} - -/*! - Returns the startup ID that will be used for the next window to be shown by this process. - - After the next window is shown, the next startup ID will be empty. - - http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt - - \sa setNextStartupId() -*/ -QByteArray QX11Info::nextStartupId() -{ - if (!qApp) - return QByteArray(); - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return QByteArray(); - return static_cast(native->nativeResourceForIntegration("startupid")); -} - -/*! - Sets the next startup ID to \a id. - - This is the startup ID that will be used for the next window to be shown by this process. - - The startup ID of the first window comes from the environment variable DESKTOP_STARTUP_ID. - This method is useful for subsequent windows, when the request comes from another process - (e.g. via DBus). - - \sa nextStartupId() -*/ -void QX11Info::setNextStartupId(const QByteArray &id) -{ - if (!qApp) - return; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return; - using SetStartupIdFunc = void(*)(const char*); - auto func = reinterpret_cast(reinterpret_cast(native->nativeResourceFunctionForIntegration("setstartupid"))); - if (func) - func(id.constData()); - else - qWarning("Internal error: QPA plugin doesn't implement setStartupId"); -} - -/*! - Returns the default display for the application. - - \sa appScreen() -*/ -Display *QX11Info::display() -{ - if (!qApp) - return nullptr; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return nullptr; - - void *display = native->nativeResourceForIntegration(QByteArray("display")); - return reinterpret_cast(display); -} - -/*! - Returns the default XCB connection for the application. - - \sa display() -*/ -xcb_connection_t *QX11Info::connection() -{ - if (!qApp) - return nullptr; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return nullptr; - - void *connection = native->nativeResourceForIntegration(QByteArray("connection")); - return reinterpret_cast(connection); -} - -/*! - Returns true if there is a compositing manager running for the connection - attached to \a screen. - - If \a screen equals -1, the application's primary screen is used. -*/ -bool QX11Info::isCompositingManagerRunning(const int screen) -{ - if (!qApp) - return false; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return false; - - QScreen *scr = screen == -1 ? QGuiApplication::primaryScreen() : findScreenForVirtualDesktop(screen); - if (!scr) { - qWarning() << "isCompositingManagerRunning: Could not find screen number" << screen; - return false; - } - - return native->nativeResourceForScreen(QByteArray("compositingEnabled"), scr); -} - -/*! - Returns a new peeker id or -1 if some interal error has occurred. - Each peeker id is associated with an index in the buffered native - event queue. - - For more details see QX11Info::PeekOption and peekEventQueue(). - - \sa peekEventQueue(), removePeekerId() -*/ -qint32 QX11Info::generatePeekerId() -{ - if (!qApp) - return -1; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return -1; - - using GeneratePeekerIdFunc = qint32(*)(void); - auto generatepeekerid = reinterpret_cast( - reinterpret_cast(native->nativeResourceFunctionForIntegration("generatepeekerid"))); - if (!generatepeekerid) { - qWarning("Internal error: QPA plugin doesn't implement generatePeekerId"); - return -1; - } - - return generatepeekerid(); -} - -/*! - Removes \a peekerId, which was earlier obtained via generatePeekerId(). - - Returns \c true on success or \c false if unknown peeker id was - provided or some interal error has occurred. - - \sa generatePeekerId() -*/ -bool QX11Info::removePeekerId(const qint32 peekerId) -{ - if (!qApp) - return false; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return false; - - using RemovePeekerIdFunc = bool(*)(qint32); - auto removePeekerId = reinterpret_cast( - reinterpret_cast(native->nativeResourceFunctionForIntegration("removepeekerid"))); - if (!removePeekerId) { - qWarning("Internal error: QPA plugin doesn't implement removePeekerId"); - return false; - } - - return removePeekerId(peekerId); -} - -/*! - \enum QX11Info::PeekOption - \brief An enum to tune the behavior of QX11Info::peekEventQueue(). - - \value PeekDefault - Peek from the beginning of the buffered native event queue. A peeker - id is optional with PeekDefault. If a peeker id is provided to - peekEventQueue() when using PeekDefault, then peeking starts from - the beginning of the queue, not from the cached index; thus, this - can be used to manually reset a cached index to peek from the start - of the queue. When this operation completes, the associated index - will be updated to the new position in the queue. - - \value PeekFromCachedIndex - QX11Info::peekEventQueue() can optimize the peeking algorithm by - skipping events that it already has seen in earlier calls to - peekEventQueue(). When control returns to the main event loop, - which causes the buffered native event queue to be flushed to Qt's - event queue, the cached indices are marked invalid and will be - reset on the next access. The same is true if the program - explicitly flushes the buffered native event queue by - QCoreApplication::processEvents(). -*/ - -/*! - \typedef QX11Info::PeekerCallback - Typedef for a pointer to a function with the following signature: - - \code - bool (*PeekerCallback)(xcb_generic_event_t *event, void *peekerData); - \endcode - - The \a event is a native XCB event. - The \a peekerData is a pointer to data, passed in via peekEventQueue(). - - Return \c true from this function to stop examining the buffered - native event queue or \c false to continue. - - \note A non-capturing lambda can serve as a PeekerCallback. -*/ - -/*! - \brief Peek into the buffered XCB event queue. - - You can call peekEventQueue() periodically, when your program is busy - performing a long-running operation, to peek into the buffered native - event queue. The more time the long-running operation blocks the - program from returning control to the main event loop, the more - events will accumulate in the buffered XCB event queue. Once control - returns to the main event loop these events will be flushed to Qt's - event queue, which is a separate event queue from the queue this - function is peeking into. - - \note It is usually better to run CPU-intensive operations in a - non-GUI thread, instead of blocking the main event loop. - - The buffered XCB event queue is populated from a non-GUI thread and - therefore might be ahead of the current GUI state. To handle native - events as they are processed by the GUI thread, see - QAbstractNativeEventFilter::nativeEventFilter(). - - The \a peeker is a callback function as documented in PeekerCallback. - The \a peekerData can be used to pass in arbitrary data to the \a - peeker callback. - The \a option is an enum that tunes the behavior of peekEventQueue(). - The \a peekerId is used to track an index in the queue, for more - details see QX11Info::PeekOption. There can be several indices, - each tracked individually by a peeker id obtained via generatePeekerId(). - - This function returns \c true when the peeker has stopped the event - proccesing by returning \c true from the callback. If there were no - events in the buffered native event queue to peek at or all the - events have been processed by the peeker, this function returns \c - false. - - \sa generatePeekerId(), QAbstractNativeEventFilter::nativeEventFilter() -*/ -bool QX11Info::peekEventQueue(PeekerCallback peeker, void *peekerData, - const PeekOptions option, const qint32 peekerId) -{ - if (!peeker || !qApp) - return false; - QPlatformNativeInterface *native = qApp->platformNativeInterface(); - if (!native) - return false; - - using PeekEventQueueFunc = bool(*)(PeekerCallback, void *, const PeekOptions, const qint32); - auto peekeventqueue = reinterpret_cast( - reinterpret_cast(native->nativeResourceFunctionForIntegration("peekeventqueue"))); - if (!peekeventqueue) { - qWarning("Internal error: QPA plugin doesn't implement peekEventQueue"); - return false; - } - - return peekeventqueue(peeker, peekerData, option, peekerId); -} - -QT_END_NAMESPACE - -#endif // (QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) diff --git a/src/core/qtx11extras_p.h b/src/core/qtx11extras_p.h deleted file mode 100644 index 79d9060..0000000 --- a/src/core/qtx11extras_p.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "framelesshelpercore_global.h" -#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) -#include -#else // (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) -#include - -using Display = struct _XDisplay; - -QT_BEGIN_NAMESPACE - -class FRAMELESSHELPER_CORE_API QX11Info -{ - Q_GADGET - Q_DISABLE_COPY_MOVE(QX11Info) - -public: - enum class PeekOption - { - Default = 0x0000, - FromCachedIndex = 0x0001 - }; - Q_ENUM(PeekOption) - Q_DECLARE_FLAGS(PeekOptions, PeekOption) - Q_FLAG(PeekOptions) - - [[nodiscard]] static bool isPlatformX11(); - - [[nodiscard]] static int appDpiX(const int screen = -1); - [[nodiscard]] static int appDpiY(const int screen = -1); - -#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) - [[nodiscard]] static unsigned long appRootWindow(const int screen = -1); -#else - [[nodiscard]] static quint32 appRootWindow(const int screen = -1); -#endif - [[nodiscard]] static int appScreen(); - - [[nodiscard]] static quint32 appTime(); - [[nodiscard]] static quint32 appUserTime(); - - static void setAppTime(const quint32 time); - static void setAppUserTime(const quint32 time); - - [[nodiscard]] static quint32 getTimestamp(); - - [[nodiscard]] static QByteArray nextStartupId(); - static void setNextStartupId(const QByteArray &id); - - [[nodiscard]] static Display *display(); - [[nodiscard]] static xcb_connection_t *connection(); - - [[nodiscard]] static bool isCompositingManagerRunning(const int screen = -1); - - [[nodiscard]] static qint32 generatePeekerId(); - [[nodiscard]] static bool removePeekerId(const qint32 peekerId); - - using PeekerCallback = bool(*)(xcb_generic_event_t *, void *); - [[nodiscard]] static bool peekEventQueue(PeekerCallback peeker, void *peekerData = nullptr, - const PeekOptions option = PeekOption::Default, const qint32 peekerId = -1); - -private: - explicit QX11Info(); - ~QX11Info(); -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QX11Info::PeekOptions) - -QT_END_NAMESPACE - -#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) diff --git a/src/core/utils_linux.cpp b/src/core/utils_linux.cpp index 61eed3b..5a809f2 100644 --- a/src/core/utils_linux.cpp +++ b/src/core/utils_linux.cpp @@ -23,10 +23,19 @@ */ #include "utils.h" -#include "qtx11extras_p.h" #include #include #include +#include +#include +#include +#include +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include +# include +#else +# include +#endif #include #include @@ -34,6 +43,8 @@ FRAMELESSHELPER_BEGIN_NAMESPACE using namespace Global; +using Display = struct _XDisplay; + [[maybe_unused]] static constexpr const auto _NET_WM_MOVERESIZE_SIZE_TOPLEFT = 0; [[maybe_unused]] static constexpr const auto _NET_WM_MOVERESIZE_SIZE_TOP = 1; [[maybe_unused]] static constexpr const auto _NET_WM_MOVERESIZE_SIZE_TOPRIGHT = 2; @@ -113,6 +124,127 @@ template return -1; } +[[maybe_unused]] [[nodiscard]] static inline + QScreen *x11_findScreenForVirtualDesktop(const int virtualDesktopNumber) +{ + if (virtualDesktopNumber == -1) { + return QGuiApplication::primaryScreen(); + } + const QList screens = QGuiApplication::screens(); + if (screens.isEmpty()) { + return nullptr; + } + for (auto &&screen : qAsConst(screens)) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + const auto qxcbScreen = dynamic_cast(screen->handle()); + if (qxcbScreen && (qxcbScreen->virtualDesktopNumber() == virtualDesktopNumber)) { + return screen; + } +#else + if (QXcbScreenFunctions::virtualDesktopNumber(screen) == virtualDesktopNumber) { + return screen; + } +#endif + } + return nullptr; +} + +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +[[maybe_unused]] [[nodiscard]] static inline + unsigned long x11_appRootWindow(const int screen) +#else +[[maybe_unused]] [[nodiscard]] static inline + quint32 x11_appRootWindow(const int screen) +#endif +{ + if (!qApp) + return 0; + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + if (!native) + return 0; + QScreen *scr = screen == -1 ? QGuiApplication::primaryScreen() : x11_findScreenForVirtualDesktop(screen); + if (!scr) + return 0; + return static_cast(reinterpret_cast(native->nativeResourceForScreen(QByteArrayLiteral("rootwindow"), scr))); +} + +[[maybe_unused]] [[nodiscard]] static inline int x11_appScreen() +{ + if (!qApp) + return 0; + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + if (!native) + return 0; + return reinterpret_cast(native->nativeResourceForIntegration(QByteArrayLiteral("x11screen"))); +} + +[[maybe_unused]] [[nodiscard]] static inline quint32 x11_appTime() +{ + if (!qApp) + return 0; + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + if (!native) + return 0; + QScreen* screen = QGuiApplication::primaryScreen(); + return static_cast(reinterpret_cast(native->nativeResourceForScreen("apptime", screen))); +} + +[[maybe_unused]] [[nodiscard]] static inline quint32 x11_appUserTime() +{ + if (!qApp) + return 0; + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + if (!native) + return 0; + QScreen* screen = QGuiApplication::primaryScreen(); + return static_cast(reinterpret_cast(native->nativeResourceForScreen("appusertime", screen))); +} + +[[maybe_unused]] [[nodiscard]] static inline quint32 x11_getTimestamp() +{ + if (!qApp) + return 0; + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + if (!native) + return 0; + QScreen* screen = QGuiApplication::primaryScreen(); + return static_cast(reinterpret_cast(native->nativeResourceForScreen("gettimestamp", screen))); +} + +[[maybe_unused]] [[nodiscard]] static inline QByteArray x11_nextStartupId() +{ + if (!qApp) + return QByteArray(); + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + if (!native) + return QByteArray(); + return static_cast(native->nativeResourceForIntegration("startupid")); +} + +[[maybe_unused]] [[nodiscard]] static inline Display *x11_display() +{ + if (!qApp) + return nullptr; + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + if (!native) + return nullptr; + + void *display = native->nativeResourceForIntegration(QByteArray("display")); + return reinterpret_cast(display); +} + +[[maybe_unused]] [[nodiscard]] static inline xcb_connection_t *x11_connection() +{ + if (!qApp) + return nullptr; + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + if (!native) + return nullptr; + + void *connection = native->nativeResourceForIntegration(QByteArray("connection")); + return reinterpret_cast(connection); +} + static inline void emulateMouseButtonRelease(const WId windowId, const QPoint &globalPos, const QPoint &localPos) { @@ -120,14 +252,14 @@ static inline void if (!windowId) { return; } - xcb_connection_t * const connection = QX11Info::connection(); + xcb_connection_t * const connection = x11_connection(); Q_ASSERT(connection); - const quint32 rootWindow = QX11Info::appRootWindow(QX11Info::appScreen()); + const quint32 rootWindow = x11_appRootWindow(x11_appScreen()); Q_ASSERT(rootWindow); xcb_button_release_event_t xev; memset(&xev, 0, sizeof(xev)); xev.response_type = XCB_BUTTON_RELEASE; - xev.time = QX11Info::appTime(); + xev.time = x11_appTime(); xev.root = rootWindow; xev.root_x = globalPos.x(); xev.root_y = globalPos.y(); @@ -148,7 +280,7 @@ static inline void if (!windowId || (edges < 0)) { return; } - xcb_connection_t * const connection = QX11Info::connection(); + xcb_connection_t * const connection = x11_connection(); Q_ASSERT(connection); static const xcb_atom_t netMoveResize = [connection]() -> xcb_atom_t { const xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, false, @@ -160,7 +292,7 @@ static inline void std::free(reply); return atom; }(); - const quint32 rootWindow = QX11Info::appRootWindow(QX11Info::appScreen()); + const quint32 rootWindow = x11_appRootWindow(x11_appScreen()); Q_ASSERT(rootWindow); xcb_client_message_event_t xev; memset(&xev, 0, sizeof(xev)); @@ -174,7 +306,7 @@ static inline void xev.data.data32[3] = XCB_BUTTON_INDEX_1; // First we need to ungrab the pointer that may have been // automatically grabbed by Qt on ButtonPressEvent. - xcb_ungrab_pointer(connection, QX11Info::appTime()); + xcb_ungrab_pointer(connection, x11_appTime()); xcb_send_event(connection, false, rootWindow, (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), reinterpret_cast(&xev));