diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbnativeinterface.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 140 |
1 files changed, 139 insertions, 1 deletions
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index b45bd6a82e..5673d41811 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -60,6 +60,8 @@ #include "qglxintegration.h" #endif +#include <QtPlatformHeaders/qxcbwindowfunctions.h> + #ifdef XCB_USE_XLIB # include <X11/Xlib.h> #else @@ -77,6 +79,8 @@ static int resourceType(const QByteArray &key) QByteArrayLiteral("display"), QByteArrayLiteral("egldisplay"), QByteArrayLiteral("connection"), QByteArrayLiteral("screen"), QByteArrayLiteral("eglcontext"), + QByteArrayLiteral("eglconfig"), + QByteArrayLiteral("glxconfig"), QByteArrayLiteral("glxcontext"), QByteArrayLiteral("apptime"), QByteArrayLiteral("appusertime"), QByteArrayLiteral("hintstyle"), QByteArrayLiteral("startupid"), QByteArrayLiteral("traywindow"), @@ -91,7 +95,9 @@ static int resourceType(const QByteArray &key) } QXcbNativeInterface::QXcbNativeInterface() : - m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t")) + m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t")), + m_sysTraySelectionAtom(XCB_ATOM_NONE), + m_systrayVisualId(XCB_NONE) { } @@ -133,6 +139,82 @@ QRect QXcbNativeInterface::systemTrayWindowGlobalGeometry(const QWindow *window) return QRect(); } +xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const QXcbScreen *screen) +{ + if (m_sysTraySelectionAtom == XCB_ATOM_NONE) { + const QByteArray net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen->screenNumber()).toLatin1(); + xcb_intern_atom_cookie_t intern_c = + xcb_intern_atom_unchecked(conn, true, net_sys_tray.length(), net_sys_tray); + + xcb_intern_atom_reply_t *intern_r = xcb_intern_atom_reply(conn, intern_c, 0); + + if (!intern_r) + return XCB_WINDOW_NONE; + + m_sysTraySelectionAtom = intern_r->atom; + free(intern_r); + } + + xcb_get_selection_owner_cookie_t sel_owner_c = xcb_get_selection_owner_unchecked(conn, m_sysTraySelectionAtom); + xcb_get_selection_owner_reply_t *sel_owner_r = xcb_get_selection_owner_reply(conn, sel_owner_c, 0); + + if (!sel_owner_r) + return XCB_WINDOW_NONE; + + xcb_window_t selection_window = sel_owner_r->owner; + free(sel_owner_r); + + return selection_window; +} + +bool QXcbNativeInterface::systrayVisualHasAlphaChannel() { + const QXcbScreen *screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle()); + + if (m_systrayVisualId == XCB_NONE) { + xcb_connection_t *xcb_conn = screen->xcb_connection(); + xcb_atom_t tray_atom = screen->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL); + + xcb_window_t systray_window = locateSystemTray(xcb_conn, screen); + if (systray_window == XCB_WINDOW_NONE) + return false; + + // Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom + xcb_get_property_cookie_t systray_atom_cookie; + xcb_get_property_reply_t *systray_atom_reply; + + systray_atom_cookie = xcb_get_property_unchecked(xcb_conn, false, systray_window, + tray_atom, XCB_ATOM_VISUALID, 0, 1); + systray_atom_reply = xcb_get_property_reply(xcb_conn, systray_atom_cookie, 0); + + if (!systray_atom_reply) + return false; + + if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply) > 0) { + xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply); + m_systrayVisualId = vids[0]; + } + + free(systray_atom_reply); + } + + if (m_systrayVisualId != XCB_NONE) { + quint8 depth = screen->depthOfVisual(m_systrayVisualId); + return depth == 32; + } else { + return false; + } +} + +void QXcbNativeInterface::clearRegion(const QWindow *qwindow, const QRect& rect) +{ + if (const QPlatformWindow *platformWindow = qwindow->handle()) { + const QXcbWindow *qxwindow = static_cast<const QXcbWindow *>(platformWindow); + xcb_connection_t *xcb_conn = qxwindow->xcb_connection(); + + xcb_clear_area(xcb_conn, false, qxwindow->xcb_window(), rect.x(), rect.y(), rect.width(), rect.height()); + } +} + void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString) { void *result = 0; @@ -160,6 +242,12 @@ void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceSt case EglContext: result = eglContextForContext(context); break; + case EglConfig: + result = eglConfigForContext(context); + break; + case GLXConfig: + result = glxConfigForContext(context); + break; case GLXContext: result = glxContextForContext(context); break; @@ -225,6 +313,14 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr return result; } +QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbNativeInterface::nativeResourceFunctionForIntegration(const QByteArray &resource) +{ + QByteArray lowerCaseResource = resource.toLower(); + if (lowerCaseResource == "setstartupid") + return NativeResourceForIntegrationFunction(setStartupId); + return 0; +} + QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::nativeResourceFunctionForScreen(const QByteArray &resource) { const QByteArray lowerCaseResource = resource.toLower(); @@ -235,6 +331,14 @@ QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::n return 0; } +QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &function) const +{ + if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) { + return QFunctionPointer(QXcbWindow::setWmWindowTypeStatic); + } + return Q_NULLPTR; +} + void *QXcbNativeInterface::appTime(const QXcbScreen *screen) { return reinterpret_cast<void *>(quintptr(screen->connection()->time())); @@ -287,6 +391,15 @@ void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time) static_cast<QXcbScreen *>(screen->handle())->connection()->setNetWmUserTime(time); } +void QXcbNativeInterface::setStartupId(const char *data) +{ + QByteArray startupId(data); + QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbConnection *defaultConnection = integration->defaultConnection(); + if (defaultConnection) + defaultConnection->setStartupId(startupId); +} + QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::nativeResourceFunctionForContext(const QByteArray &resource) { QByteArray lowerCaseResource = resource.toLower(); @@ -353,6 +466,18 @@ void * QXcbNativeInterface::eglContextForContext(QOpenGLContext *context) #endif } +void * QXcbNativeInterface::eglConfigForContext(QOpenGLContext *context) +{ + Q_ASSERT(context); +#if defined(XCB_USE_EGL) + QEGLPlatformContext *eglPlatformContext = static_cast<QEGLPlatformContext *>(context->handle()); + return eglPlatformContext->eglConfig(); +#else + Q_UNUSED(context); + return 0; +#endif +} + void *QXcbNativeInterface::glxContextForContext(QOpenGLContext *context) { Q_ASSERT(context); @@ -366,4 +491,17 @@ void *QXcbNativeInterface::glxContextForContext(QOpenGLContext *context) } +void *QXcbNativeInterface::glxConfigForContext(QOpenGLContext *context) +{ + Q_ASSERT(context); +#if defined(XCB_USE_GLX) + QGLXContext *glxPlatformContext = static_cast<QGLXContext *>(context->handle()); + return glxPlatformContext->glxConfig(); +#else + Q_UNUSED(context); + return 0; +#endif + +} + QT_END_NAMESPACE |