Open Zren opened 2 years ago
I think I can help answer how to fix this the "correct" way without having to access private headers that could go away at any time.
These places you mention all need access to the xcb_connection_t *
for the Display. QX11Info
had an accessor to get that directly, but in Qt 6, the only thing that is provided is access to the Display *
. However the means to access the Display *
is substantially different from Qt 5:
QNativeInterface::QX11Application *x11App = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11App->display();
To get the xcb_connection_t *
, I think you follow https://xcb.freedesktop.org/MixingCalls/ like so (this is untested - I'm just going from the aforementioned page:
#include <X11/Xlib-xcb.h>
[...]
QNativeInterface::QX11Application *x11App = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11App->display();
xcb_connection_t *c;
c = XGetXCBConnection(dpy);
[do your stuff that needs xcb_connection_t]
There's a connection()
function. Do I need display() => Display
then XGetXCBConnection(Display) => xcb_connection_t
? There shouldn't be multiple connections for each display right?
Here's how QX11Info::connection()
works:
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);
}
The new Qt6 API:
Note, this is not backwards compatible, as QGuiApplication::nativeInterface()
is not in Qt5? In Qt5 there is QGuiApplication::platformNativeInterface()
but it's even less documented.
Looks like I'll need to have separate logic for Qt5 + Qt6.
QXcbBasicConnection::QXcbBasicConnection(const char *displayName)
: m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
{
#if QT_CONFIG(xcb_xlib)
Display *dpy = XOpenDisplay(m_displayName.constData());
if (dpy) {
m_primaryScreenNumber = DefaultScreen(dpy);
m_xcbConnection = XGetXCBConnection(dpy);
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
XSetErrorHandler(nullErrorHandler);
XSetIOErrorHandler(ioErrorHandler);
m_xlibDisplay = dpy;
}
#else
m_xcbConnection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
#endif
Hmm Not sure where I had in my head that there was no connection method... I see now that it's there...
You're definitely right that in Qt5 QGuiApplication::platformNativeInterface() is severely undocumented (but at least they show it exists in the docs!).
Here is the header for it: https://github.com/qt/qtbase/blob/v5.15.5-lts-lgpl/src/gui/kernel/qplatformnativeinterface.h
And here's the XCB implementation. https://github.com/qt/qtbase/blob/v5.15.5-lts-lgpl/src/plugins/platforms/xcb/qxcbnativeinterface.h
in a #if Q_OS_LINUX
block, you can use qobject_cast<QXcbNativeInterface *>
and then access the methods there.
You'll need to have separate Qt5 and Qt6 implementations for this to work, as far as I understand - but it'll be using stable APIs that won't change on you. I think there's a good chance that the QX11Info private APIs will be removed at some point in the near future.
TODO: I need to add #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
check to use #include <private/qtx11extras_p.h>
.
#if BREEZE_HAVE_QTX11EXTRAS
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <private/qtx11extras_p.h>
#else
#include <QX11Info>
#endif
#endif
You can do this, but it is kicking the can down the road. In Qt 7, qtx11extras_p.h
won't exist.
Are there any instructions for compiling it with Qt6?
i tried to build with Qt6 but i receive this error:
CMake Error at CMakeLists.txt:24 (find_package):
Found package configuration file:
/usr/lib/cmake/Qt6/Qt6Config.cmake
but it set Qt6_FOUND to FALSE so package "Qt6" is considered to be NOT
FOUND. Reason given by package:
Failed to find required Qt component "GuiPrivate".
Expected Config file at
"/usr/lib/cmake/Qt6GuiPrivate/Qt6GuiPrivateConfig.cmake" does NOT exist
Configuring with --debug-find-pkg=Qt6GuiPrivate might reveal details why
the package was not found.
Configuring with -DQT_DEBUG_FIND_PACKAGE=ON will print the values of some
of the path variables that find_package uses to try and find the package.
We use this class in:
Decoration::sendMoveEvent()
andDecoration::windowPos()
to get the global cursor pos for a dragAppMenuModel::onWinIdChanged()
to get the x11 window properties to know the dbus interfaceAppMenuButtonGroup