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() void *QXcbEglNativeInterfaceHandler::eglDisplay()
{ {
QXcbIntegration *integration = QXcbIntegration::instance(); QXcbIntegration *integration = QXcbIntegration::instance();
QXcbEglIntegration *eglIntegration = static_cast<QXcbEglIntegration *>(integration->defaultConnection()->glIntegration()); QXcbEglIntegration *eglIntegration = static_cast<QXcbEglIntegration *>(integration->connection()->glIntegration());
return eglIntegration->eglDisplay(); return eglIntegration->eglDisplay();
} }

View File

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

View File

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

View File

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

View File

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