remove the last piece of Qt internal classes
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
a97b1782ae
commit
9d71baffd1
|
@ -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)
|
||||
|
|
|
@ -1,575 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Copyright (C) 2022 Richard Moore <rich@kde.org>
|
||||
** Copyright (C) 2022 David Faure <david.faure@kdab.com>
|
||||
** 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 <QtCore/qdebug.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtGui/qpa/qplatformnativeinterface.h>
|
||||
#include <QtGui/qpa/qplatformwindow.h>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
# include <QtGui/qpa/qplatformscreen_p.h>
|
||||
# include <QtGui/qpa/qplatformscreen.h>
|
||||
#else
|
||||
# include <QtPlatformHeaders/qxcbscreenfunctions.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
[[nodiscard]] static inline QScreen *findScreenForVirtualDesktop(const int virtualDesktopNumber)
|
||||
{
|
||||
if (virtualDesktopNumber == -1) {
|
||||
return QGuiApplication::primaryScreen();
|
||||
}
|
||||
const QList<QScreen *> 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<QNativeInterface::Private::QXcbScreen *>(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<xcb_window_t>(reinterpret_cast<quintptr>(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<qintptr>(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<xcb_timestamp_t>(reinterpret_cast<quintptr>(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<xcb_timestamp_t>(reinterpret_cast<quintptr>(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<SetAppTimeFunc>(reinterpret_cast<void *>(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<SetAppUserTimeFunc>(reinterpret_cast<void *>(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<xcb_timestamp_t>(reinterpret_cast<quintptr>(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<char *>(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<SetStartupIdFunc>(reinterpret_cast<void *>(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 *>(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<xcb_connection_t *>(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<GeneratePeekerIdFunc>(
|
||||
reinterpret_cast<void *>(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<RemovePeekerIdFunc>(
|
||||
reinterpret_cast<void *>(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<PeekEventQueueFunc>(
|
||||
reinterpret_cast<void *>(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))
|
|
@ -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 <QtGui/private/qtx11extras_p.h>
|
||||
#else // (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0))
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
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))
|
|
@ -23,10 +23,19 @@
|
|||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "qtx11extras_p.h"
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qregularexpression.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtGui/qpa/qplatformnativeinterface.h>
|
||||
#include <QtGui/qpa/qplatformwindow.h>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
# include <QtGui/qpa/qplatformscreen_p.h>
|
||||
# include <QtGui/qpa/qplatformscreen.h>
|
||||
#else
|
||||
# include <QtPlatformHeaders/qxcbscreenfunctions.h>
|
||||
#endif
|
||||
#include <gtk/gtk.h>
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
|
@ -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<typename T>
|
|||
return -1;
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] static inline
|
||||
QScreen *x11_findScreenForVirtualDesktop(const int virtualDesktopNumber)
|
||||
{
|
||||
if (virtualDesktopNumber == -1) {
|
||||
return QGuiApplication::primaryScreen();
|
||||
}
|
||||
const QList<QScreen *> 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<QNativeInterface::Private::QXcbScreen *>(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<xcb_window_t>(reinterpret_cast<quintptr>(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<qintptr>(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<xcb_timestamp_t>(reinterpret_cast<quintptr>(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<xcb_timestamp_t>(reinterpret_cast<quintptr>(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<xcb_timestamp_t>(reinterpret_cast<quintptr>(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<char *>(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 *>(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<xcb_connection_t *>(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<const char *>(&xev));
|
||||
|
|
Loading…
Reference in New Issue