From 7288625c52749f566570a7e7ef047faa8171b18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 25 Apr 2013 15:15:20 +0200 Subject: Moving logic from Qt4 for grabbing the X server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Basically you don't want to grab the X server while your debugging. Also added an environment variable which lets you force to not grab the X server Change-Id: Iba03f11c8f486ce71c55fac7716bffcb7cc8cb98 Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbconnection.cpp | 15 ++++++++++- src/plugins/platforms/xcb/qxcbconnection.h | 5 +++- src/plugins/platforms/xcb/qxcbdrag.cpp | 4 +-- src/plugins/platforms/xcb/qxcbintegration.cpp | 36 ++++++++++++++++++++++++++- 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index de3d487c4b..0597b18679 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -242,8 +242,9 @@ void QXcbConnection::updateScreens() ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded(screen); } -QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName) +QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) : m_connection(0) + , m_canGrabServer(canGrabServer) , m_primaryScreen(0) , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) , m_nativeInterface(nativeInterface) @@ -952,6 +953,18 @@ void QXcbConnection::setFocusWindow(QXcbWindow *w) m_focusWindow = w; } +void QXcbConnection::grabServer() +{ + if (m_canGrabServer) + xcb_grab_server(m_connection); +} + +void QXcbConnection::ungrabServer() +{ + if (m_canGrabServer) + xcb_ungrab_server(m_connection); +} + void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id) { xcb_client_message_event_t event; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 8ab65fc2bc..27de5a4e83 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -306,7 +306,7 @@ class QXcbConnection : public QObject { Q_OBJECT public: - QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName = 0); + QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName = 0); ~QXcbConnection(); QXcbConnection *connection() const { return const_cast(this); } @@ -391,6 +391,8 @@ public: QByteArray startupId() const { return m_startupId; } void clearStartupId() { m_startupId.clear(); } + void grabServer(); + void ungrabServer(); private slots: void processXcbEvents(); @@ -454,6 +456,7 @@ private: xcb_connection_t *m_connection; const xcb_setup_t *m_setup; + bool m_canGrabServer; QList m_screens; int m_primaryScreen; diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 5dbac93fde..dceac09be5 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1160,7 +1160,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on) if (desktop_proxy) // *WE* already have one. return false; - xcb_grab_server(xcb_connection()); + connection()->grabServer(); // As per Xdnd4, use XdndProxy xcb_window_t proxy_id = xdndProxy(connection(), w->xcb_window()); @@ -1176,7 +1176,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on) XCB_ATOM_WINDOW, 32, 1, &proxy_id); } - xcb_ungrab_server(xcb_connection()); + connection()->ungrabServer(); } else { xdnd_widget = w; } diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index f0cabea43d..dd1466d23c 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -91,8 +91,34 @@ #endif #endif +#include + QT_BEGIN_NAMESPACE +#if defined(QT_DEBUG) && defined(Q_OS_LINUX) +// Find out if our parent process is gdb by looking at the 'exe' symlink under /proc,. +// or, for older Linuxes, read out 'cmdline'. +static bool runningUnderDebugger() +{ + const QString parentProc = QLatin1String("/proc/") + QString::number(getppid()); + const QFileInfo parentProcExe(parentProc + QLatin1String("/exe")); + if (parentProcExe.isSymLink()) + return parentProcExe.symLinkTarget().endsWith(QLatin1String("/gdb")); + QFile f(parentProc + QLatin1String("/cmdline")); + if (!f.open(QIODevice::ReadOnly)) + return false; + QByteArray s; + char c; + while (f.getChar(&c) && c) { + if (c == '/') + s.clear(); + else + s += c; + } + return s == "gdb"; +} +#endif + QXcbIntegration::QXcbIntegration(const QStringList ¶meters) : m_eventDispatcher(createUnixEventDispatcher()) , m_services(new QGenericUnixServices) @@ -104,7 +130,15 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters) #endif m_nativeInterface.reset(new QXcbNativeInterface); - m_connections << new QXcbConnection(m_nativeInterface.data()); + bool canGrab = true; + #if defined(QT_DEBUG) && defined(Q_OS_LINUX) + canGrab = !runningUnderDebugger(); + #endif + static bool canNotGrabEnv = qgetenv("QT_XCB_NO_GRAB_SERVER").length(); + if (canNotGrabEnv) + canGrab = false; + + m_connections << new QXcbConnection(m_nativeInterface.data(), canGrab); for (int i = 0; i < parameters.size() - 1; i += 2) { #ifdef Q_XCB_DEBUG -- cgit v1.2.3