Add native interface for X11 application, exposing display and connection

The major use-case of the now private QX11Info from Qt X11 Extras was
getting hold of the Xlib display and XCB connection, for example in KDE:

  https://lxr.kde.org/search?%21v=kf5-qt5&_filestring=&_string=QX11Info

A new native interface for QGuiApplication has now been added that
exposes these two properties, e.g.:

  if (auto *x11App = app.nativeInterface<QX11Application>())
      qDebug() << x11App->display() << x11App->connection();

To avoid type clashes one of the enum values of QXcbNativeInterface's
ResourceType had to be renamed.

Pick-to: 6.2
Task-number: QTBUG-93633
Change-Id: I2e366a2bb88bd3965ac6172ad000ae32209f43e7
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
bb10
Tor Arne Vestbø 2021-08-03 23:09:27 +02:00
parent e158502e33
commit f5203eeada
8 changed files with 137 additions and 13 deletions

View File

@ -87,7 +87,7 @@ qt_internal_add_module(Gui
kernel/qevent.cpp kernel/qevent.h kernel/qevent_p.h
kernel/qgenericplugin.cpp kernel/qgenericplugin.h
kernel/qgenericpluginfactory.cpp kernel/qgenericpluginfactory.h
kernel/qguiapplication.cpp kernel/qguiapplication.h kernel/qguiapplication_p.h
kernel/qguiapplication.cpp kernel/qguiapplication.h kernel/qguiapplication_p.h kernel/qguiapplication_platform.h
kernel/qguivariant.cpp
kernel/qhighdpiscaling.cpp kernel/qhighdpiscaling_p.h
kernel/qinputdevice.cpp kernel/qinputdevice.h kernel/qinputdevice_p.h

View File

@ -870,7 +870,7 @@ qt_feature("tuiotouch" PRIVATE
PURPOSE "Provides the TuioTouch input plugin."
CONDITION QT_FEATURE_network AND QT_FEATURE_udpsocket
)
qt_feature("xcb" PRIVATE
qt_feature("xcb" PUBLIC
SECTION "Platform plugins"
LABEL "XCB"
AUTODETECT NOT APPLE

View File

@ -4208,8 +4208,22 @@ QInputDeviceManager *QGuiApplicationPrivate::inputDeviceManager()
return m_inputDeviceManager;
}
/*!
\fn template <typename QNativeInterface> QNativeInterface *QGuiApplication::nativeInterface() const
Returns a native interface of the given type for the application.
This function provides access to platform specific functionality
of QGuiApplication, as defined in the QNativeInterface namespace:
\annotatedlist native-interfaces-qguiapplication
If the requested interface is not available a \nullptr is returned.
*/
void *QGuiApplication::resolveInterface(const char *name, int revision) const
{
using namespace QNativeInterface;
using namespace QNativeInterface::Private;
auto *platformIntegration = QGuiApplicationPrivate::platformIntegration();
@ -4218,6 +4232,9 @@ void *QGuiApplication::resolveInterface(const char *name, int revision) const
#if defined(Q_OS_WIN)
QT_NATIVE_INTERFACE_RETURN_IF(QWindowsApplication, platformIntegration);
#endif
#if QT_CONFIG(xcb)
QT_NATIVE_INTERFACE_RETURN_IF(QX11Application, platformNativeInterface());
#endif
return QCoreApplication::resolveInterface(name, revision);
}

View File

@ -219,4 +219,6 @@ private:
QT_END_NAMESPACE
#include <QtGui/qguiapplication_platform.h>
#endif // QGUIAPPLICATION_H

View File

@ -0,0 +1,71 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore 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$
**
****************************************************************************/
#ifndef QGUIAPPLICATION_PLATFORM_H
#define QGUIAPPLICATION_PLATFORM_H
#include <QtGui/qtguiglobal.h>
#include <QtCore/qnativeinterface.h>
#include <QtGui/qguiapplication.h>
#if QT_CONFIG(xcb)
typedef struct _XDisplay Display;
struct xcb_connection_t;
#endif
QT_BEGIN_NAMESPACE
namespace QNativeInterface
{
#if QT_CONFIG(xcb) || defined(Q_CLANG_QDOC)
struct Q_GUI_EXPORT QX11Application
{
QT_DECLARE_NATIVE_INTERFACE(QX11Application, 1, QGuiApplication)
virtual Display *display() const = 0;
virtual xcb_connection_t *connection() const = 0;
};
#endif
} // QNativeInterface
QT_END_NAMESPACE
#endif // QGUIAPPLICATION_PLATFORM_H

View File

@ -179,6 +179,36 @@ QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QXcbScreen);
QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QXcbWindow);
/*!
\class QNativeInterface::QX11Application
\since 6.0
\brief Native interface to an X11 application.
Accessed through QGuiApplication::nativeInterface().
\inmodule QtGui
\ingroup native-interfaces
\ingroup native-interfaces-qguiapplication
*/
/*!
\fn Display *QNativeInterface::QX11Application::display() const
\return the X display of the application, for use with Xlib.
\sa connection()
*/
/*!
\fn xcb_connection_t *QNativeInterface::QX11Application::connection() const
\return the X connection of the application, for use with XCB.
\sa display()
*/
QT_DEFINE_NATIVE_INTERFACE(QX11Application);
#endif // QT_CONFIG(xcb)
#if QT_CONFIG(vsp2)

View File

@ -118,7 +118,7 @@ void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resour
case RootWindow:
result = rootWindow();
break;
case Display:
case XDisplay:
result = display();
break;
case AtspiBus:
@ -155,7 +155,7 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resourceStr
const QXcbScreen *xcbScreen = static_cast<QXcbScreen *>(screen->handle());
switch (resourceType(lowerCaseResource)) {
case Display:
case XDisplay:
#if QT_CONFIG(xcb_xlib)
result = xcbScreen->connection()->xlib_display();
#endif
@ -203,7 +203,7 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr
return result;
switch (resourceType(lowerCaseResource)) {
case Display:
case XDisplay:
result = displayForWindow(window);
break;
case Connection:
@ -365,18 +365,17 @@ void *QXcbNativeInterface::rootWindow()
return nullptr;
}
void *QXcbNativeInterface::display()
Display *QXcbNativeInterface::display() const
{
#if QT_CONFIG(xcb_xlib)
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *connection = integration->connection();
if (connection)
return connection->xlib_display();
if (QXcbConnection *connection = integration->connection())
return reinterpret_cast<Display *>(connection->xlib_display());
#endif
return nullptr;
}
void *QXcbNativeInterface::connection()
xcb_connection_t *QXcbNativeInterface::connection() const
{
QXcbIntegration *integration = QXcbIntegration::instance();
return integration->connection()->xcb_connection();

View File

@ -45,6 +45,8 @@
#include <QtCore/QRect>
#include <QtGui/qguiapplication.h>
#include "qxcbexport.h"
#include "qxcbconnection.h"
@ -54,11 +56,12 @@ class QXcbScreen;
class QXcbNativeInterfaceHandler;
class Q_XCB_EXPORT QXcbNativeInterface : public QPlatformNativeInterface
, public QNativeInterface::QX11Application
{
Q_OBJECT
public:
enum ResourceType {
Display,
XDisplay,
Connection,
Screen,
AppTime,
@ -109,9 +112,11 @@ public:
void *startupId();
void *x11Screen();
void *rootWindow();
void *display();
Display *display() const override;
xcb_connection_t *connection() const override;
void *atspiBus();
void *connection();
static void setStartupId(const char *);
static void setAppTime(QScreen *screen, xcb_timestamp_t time);
static void setAppUserTime(QScreen *screen, xcb_timestamp_t time);