xcb: remove multi-connection code path

This code was introduced in 2011 as an experimental feature
and have been untested/unmaintained ever since. It's time to
remove it for the following reasons:

- It has never been documented in QGuiApplication under
  "Supported Command Line Options". The intended command
  line was: ./app -platform xcb:address:display

- I am not aware of other toolkits that would provide this
  functionality - connecting to several X displays simultaneously.

- XCB plugin respects the "-display" command line and DISPLAY
  envvar which should be sufficient. So the "workaround" to get
  your window on 2 X displays is:

    ./app -display :0
    ./app -display :1

- There are no JIRA bugs where users would complain that this
  feature does not work. AFAICT it has not worked for years.
  Almost all functions care only about the "default" connection,
  and don't attempt to support multi-connection.

- This will stop confusing people who want to contribute to
  the XCB plugin.

[ChangeLog][Platform Specific Changes][X11] Connecting to multiple
X servers simultaneously within the same application is no longer
supported.

Task-number: QTBUG-52408
Change-Id: I61ce23480702bb89b02c6028fa0986fe63481978
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Gatis Paeglis 2020-06-18 16:51:02 +02:00 committed by Tor Arne Vestbø
parent 26a2266304
commit 1e39b39ddb
5 changed files with 51 additions and 64 deletions

View File

@ -107,7 +107,7 @@ QPlatformNativeInterface::NativeResourceForWindowFunction QXcbEglNativeInterface
void *QXcbEglNativeInterfaceHandler::eglDisplay()
{
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbEglIntegration *eglIntegration = static_cast<QXcbEglIntegration *>(integration->defaultConnection()->glIntegration());
QXcbEglIntegration *eglIntegration = static_cast<QXcbEglIntegration *>(integration->connection()->glIntegration());
return eglIntegration->eglDisplay();
}

View File

@ -137,6 +137,8 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
, m_canGrab(true)
, m_defaultVisualId(UINT_MAX)
{
Q_UNUSED(parameters);
m_instance = this;
qApp->setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
@ -196,40 +198,27 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
if (canNotGrabEnv)
m_canGrab = false;
const int numParameters = parameters.size();
m_connections.reserve(1 + numParameters / 2);
auto conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName);
if (!conn->isConnected()) {
delete conn;
m_connection = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName);
if (!m_connection->isConnected()) {
delete m_connection;
m_connection = nullptr;
return;
}
m_connections << conn;
// ### Qt 6 (QTBUG-52408) remove this multi-connection code path
for (int i = 0; i < numParameters - 1; i += 2) {
qCDebug(lcQpaXcb) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData());
if (conn->isConnected())
m_connections << conn;
else
delete conn;
}
m_fontDatabase.reset(new QGenericUnixFontDatabase());
#if QT_CONFIG(xcb_native_painting)
if (nativePaintingEnabled()) {
qCDebug(lcQpaXcb, "QXCB USING NATIVE PAINTING");
qt_xcb_native_x11_info_init(defaultConnection());
qt_xcb_native_x11_info_init(connection());
}
#endif
}
QXcbIntegration::~QXcbIntegration()
{
qDeleteAll(m_connections);
delete m_connection;
m_connection = nullptr;
m_instance = nullptr;
}
@ -249,7 +238,7 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
const bool isTrayIconWindow = QXcbWindow::isTrayIconWindow(window);;
if (window->type() != Qt::Desktop && !isTrayIconWindow) {
if (window->supportsOpenGL()) {
glIntegration = defaultConnection()->glIntegration();
glIntegration = connection()->glIntegration();
if (glIntegration) {
QXcbWindow *xcbWindow = glIntegration->createWindow(window);
xcbWindow->create();
@ -324,7 +313,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
case OpenGL:
case ThreadedOpenGL:
{
if (const auto *integration = defaultConnection()->glIntegration())
if (const auto *integration = connection()->glIntegration())
return cap != ThreadedOpenGL || integration->supportsThreadedOpenGL();
return false;
}
@ -339,8 +328,8 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
case SwitchableWidgetComposition:
{
return m_connections.at(0)->glIntegration()
&& m_connections.at(0)->glIntegration()->supportsSwitchableWidgetComposition();
return m_connection->glIntegration()
&& m_connection->glIntegration()->supportsSwitchableWidgetComposition();
}
default: return QPlatformIntegration::hasCapability(cap);
@ -349,7 +338,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const
{
return QXcbEventDispatcher::createEventDispatcher(defaultConnection());
return QXcbEventDispatcher::createEventDispatcher(connection());
}
void QXcbIntegration::initialize()
@ -364,7 +353,7 @@ void QXcbIntegration::initialize()
if (!m_inputContext && icStr != defaultInputContext && icStr != QLatin1String("none"))
m_inputContext.reset(QPlatformInputContextFactory::create(defaultInputContext));
defaultConnection()->keyboard()->initialize();
connection()->keyboard()->initialize();
}
void QXcbIntegration::moveToScreen(QWindow *window, int screen)
@ -386,7 +375,7 @@ QPlatformNativeInterface * QXcbIntegration::nativeInterface() const
#ifndef QT_NO_CLIPBOARD
QPlatformClipboard *QXcbIntegration::clipboard() const
{
return m_connections.at(0)->clipboard();
return m_connection->clipboard();
}
#endif
@ -402,7 +391,7 @@ QPlatformDrag *QXcbIntegration::drag() const
return simpleDrag;
}
return m_connections.at(0)->drag();
return m_connection->drag();
}
#endif
@ -433,12 +422,12 @@ QPlatformServices *QXcbIntegration::services() const
Qt::KeyboardModifiers QXcbIntegration::queryKeyboardModifiers() const
{
return m_connections.at(0)->queryKeyboardModifiers();
return m_connection->queryKeyboardModifiers();
}
QList<int> QXcbIntegration::possibleKeys(const QKeyEvent *e) const
{
return m_connections.at(0)->keyboard()->possibleKeys(e);
return m_connection->keyboard()->possibleKeys(e);
}
QStringList QXcbIntegration::themeNames() const
@ -469,7 +458,7 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
// The default (in QPlatformTheme::defaultThemeHint) is 10 pixels, but
// on a high-resolution screen it makes sense to increase it.
qreal dpi = 100.0;
if (const QXcbScreen *screen = defaultConnection()->primaryScreen()) {
if (const QXcbScreen *screen = connection()->primaryScreen()) {
if (screen->logicalDpi().first > dpi)
dpi = screen->logicalDpi().first;
if (screen->logicalDpi().second > dpi)
@ -540,9 +529,7 @@ QPlatformSessionManager *QXcbIntegration::createPlatformSessionManager(const QSt
void QXcbIntegration::sync()
{
for (int i = 0; i < m_connections.size(); i++) {
m_connections.at(i)->sync();
}
m_connection->sync();
}
// For QApplication::beep()

View File

@ -102,8 +102,8 @@ public:
QPlatformTheme *createPlatformTheme(const QString &name) const override;
QVariant styleHint(StyleHint hint) const override;
bool hasDefaultConnection() const { return !m_connections.isEmpty(); }
QXcbConnection *defaultConnection() const { return m_connections.first(); }
bool hasConnection() const { return m_connection; }
QXcbConnection *connection() const { return m_connection; }
QByteArray wmClass() const;
@ -124,7 +124,7 @@ public:
static QXcbIntegration *instance() { return m_instance; }
private:
QList<QXcbConnection *> m_connections;
QXcbConnection *m_connection = nullptr;
QScopedPointer<QPlatformFontDatabase> m_fontDatabase;
QScopedPointer<QXcbNativeInterface> m_nativeInterface;

View File

@ -54,7 +54,7 @@ QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const
{
if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive)) {
auto xcbIntegration = new QXcbIntegration(parameters, argc, argv);
if (!xcbIntegration->hasDefaultConnection()) {
if (!xcbIntegration->hasConnection()) {
delete xcbIntegration;
return nullptr;
}

View File

@ -362,27 +362,27 @@ void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen)
void *QXcbNativeInterface::startupId()
{
QXcbIntegration* integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(const_cast<char *>(defaultConnection->startupId().constData()));
QXcbConnection *connection = integration->connection();
if (connection)
return reinterpret_cast<void *>(const_cast<char *>(connection->startupId().constData()));
return nullptr;
}
void *QXcbNativeInterface::x11Screen()
{
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(defaultConnection->primaryScreenNumber());
QXcbConnection *connection = integration->connection();
if (connection)
return reinterpret_cast<void *>(connection->primaryScreenNumber());
return nullptr;
}
void *QXcbNativeInterface::rootWindow()
{
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(defaultConnection->rootWindow());
QXcbConnection *connection = integration->connection();
if (connection)
return reinterpret_cast<void *>(connection->rootWindow());
return nullptr;
}
@ -390,9 +390,9 @@ void *QXcbNativeInterface::display()
{
#if QT_CONFIG(xcb_xlib)
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return defaultConnection->xlib_display();
QXcbConnection *connection = integration->connection();
if (connection)
return connection->xlib_display();
#endif
return nullptr;
}
@ -400,17 +400,17 @@ void *QXcbNativeInterface::display()
void *QXcbNativeInterface::connection()
{
QXcbIntegration *integration = QXcbIntegration::instance();
return integration->defaultConnection()->xcb_connection();
return integration->connection()->xcb_connection();
}
void *QXcbNativeInterface::atspiBus()
{
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection) {
auto atspiBusAtom = defaultConnection->atom(QXcbAtom::AT_SPI_BUS);
auto reply = Q_XCB_REPLY(xcb_get_property, defaultConnection->xcb_connection(),
false, defaultConnection->rootWindow(),
QXcbConnection *connection = integration->connection();
if (connection) {
auto atspiBusAtom = connection->atom(QXcbAtom::AT_SPI_BUS);
auto reply = Q_XCB_REPLY(xcb_get_property, connection->xcb_connection(),
false, connection->rootWindow(),
atspiBusAtom, XCB_ATOM_STRING, 0, 128);
if (!reply)
return nullptr;
@ -440,29 +440,29 @@ void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time)
qint32 QXcbNativeInterface::generatePeekerId()
{
QXcbIntegration *integration = QXcbIntegration::instance();
return integration->defaultConnection()->eventQueue()->generatePeekerId();
return integration->connection()->eventQueue()->generatePeekerId();
}
bool QXcbNativeInterface::removePeekerId(qint32 peekerId)
{
QXcbIntegration *integration = QXcbIntegration::instance();
return integration->defaultConnection()->eventQueue()->removePeekerId(peekerId);
return integration->connection()->eventQueue()->removePeekerId(peekerId);
}
bool QXcbNativeInterface::peekEventQueue(QXcbEventQueue::PeekerCallback peeker, void *peekerData,
QXcbEventQueue::PeekOptions option, qint32 peekerId)
{
QXcbIntegration *integration = QXcbIntegration::instance();
return integration->defaultConnection()->eventQueue()->peekEventQueue(peeker, peekerData, option, peekerId);
return integration->connection()->eventQueue()->peekEventQueue(peeker, peekerData, option, peekerId);
}
void QXcbNativeInterface::setStartupId(const char *data)
{
QByteArray startupId(data);
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
defaultConnection->setStartupId(startupId);
QXcbConnection *connection = integration->connection();
if (connection)
connection->setStartupId(startupId);
}
QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
@ -671,7 +671,7 @@ QString QXcbNativeInterface::dumpConnectionNativeWindows(const QXcbConnection *c
QString QXcbNativeInterface::dumpNativeWindows(WId root) const
{
return dumpConnectionNativeWindows(QXcbIntegration::instance()->defaultConnection(), root);
return dumpConnectionNativeWindows(QXcbIntegration::instance()->connection(), root);
}
QT_END_NAMESPACE