From 059b01b496e9e259aad6e6d8ae3da8488613b6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 3 Aug 2021 23:09:27 +0200 Subject: 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()) qDebug() << x11App->display() << x11App->connection(); To avoid type clashes one of the enum values of QXcbNativeInterface's ResourceType had to be renamed. Task-number: QTBUG-93633 Change-Id: I2e366a2bb88bd3965ac6172ad000ae32209f43e7 Reviewed-by: Lars Knoll (cherry picked from commit f5203eeada83bbe8e316a5188e24636af3e83b09) Reviewed-by: Qt Cherry-pick Bot --- src/gui/CMakeLists.txt | 2 +- src/gui/configure.cmake | 2 +- src/gui/kernel/qguiapplication.cpp | 17 ++++++ src/gui/kernel/qguiapplication.h | 2 + src/gui/kernel/qguiapplication_platform.h | 71 +++++++++++++++++++++++ src/gui/platform/unix/qunixnativeinterface.cpp | 30 ++++++++++ src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 15 +++-- src/plugins/platforms/xcb/qxcbnativeinterface.h | 11 +++- 8 files changed, 137 insertions(+), 13 deletions(-) create mode 100644 src/gui/kernel/qguiapplication_platform.h diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 5bc5d0151c..905afd4038 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -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 diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake index de05f5e0f1..ea6752806e 100644 --- a/src/gui/configure.cmake +++ b/src/gui/configure.cmake @@ -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 diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 5ba579895f..dcfc53290a 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -4212,8 +4212,22 @@ QInputDeviceManager *QGuiApplicationPrivate::inputDeviceManager() return m_inputDeviceManager; } +/*! + \fn template 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(); @@ -4222,6 +4236,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); } diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 795a88f2b0..3d4534aabf 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -219,4 +219,6 @@ private: QT_END_NAMESPACE +#include + #endif // QGUIAPPLICATION_H diff --git a/src/gui/kernel/qguiapplication_platform.h b/src/gui/kernel/qguiapplication_platform.h new file mode 100644 index 0000000000..66cdf10814 --- /dev/null +++ b/src/gui/kernel/qguiapplication_platform.h @@ -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 + +#include +#include + +#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 diff --git a/src/gui/platform/unix/qunixnativeinterface.cpp b/src/gui/platform/unix/qunixnativeinterface.cpp index 4febe69d91..22bbc555f1 100644 --- a/src/gui/platform/unix/qunixnativeinterface.cpp +++ b/src/gui/platform/unix/qunixnativeinterface.cpp @@ -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) diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 95c552a468..55633aade7 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -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(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(connection->xlib_display()); #endif return nullptr; } -void *QXcbNativeInterface::connection() +xcb_connection_t *QXcbNativeInterface::connection() const { QXcbIntegration *integration = QXcbIntegration::instance(); return integration->connection()->xcb_connection(); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 4656f46be5..5508d57679 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -45,6 +45,8 @@ #include +#include + #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); -- cgit v1.2.3