From 302eb99efe400e9d79acad12060ee3efd3b0f867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 3 May 2016 10:18:38 +0200 Subject: Only call into xcb on platform xcb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This caused a crash in case the desktop mode was being used on e.g. platform wayland. There the native platform also provides a pointer for "connection", but it's a wl_connection_t* and not an xcb_connection_t*. Change-Id: Icb07486fb94d2971c05aed6f56fd09a16e7c34cf Reviewed-by: Martin Gräßlin Reviewed-by: Mitch Curtis --- src/virtualkeyboard/desktopinputpanel.cpp | 78 ++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/src/virtualkeyboard/desktopinputpanel.cpp b/src/virtualkeyboard/desktopinputpanel.cpp index 402aa831..cb901957 100644 --- a/src/virtualkeyboard/desktopinputpanel.cpp +++ b/src/virtualkeyboard/desktopinputpanel.cpp @@ -40,19 +40,34 @@ namespace QtVirtualKeyboard { class DesktopInputPanelPrivate : public AppInputPanelPrivate { public: + enum WindowingSystem { + Windows, + Xcb, + Other, + }; + DesktopInputPanelPrivate() : AppInputPanelPrivate(), view(), keyboardRect(), previewRect(), previewVisible(false), - previewBindingActive(false) {} + previewBindingActive(false), + windowingSystem(Other) + { + const QString platformName = QGuiApplication::platformName(); + if (platformName == QLatin1String("windows")) + windowingSystem = Windows; + else if (platformName == QLatin1String("xcb")) + windowingSystem = Xcb; + } QScopedPointer view; QRectF keyboardRect; QRectF previewRect; bool previewVisible; bool previewBindingActive; + WindowingSystem windowingSystem; }; /*! @@ -119,13 +134,14 @@ void DesktopInputPanel::createView() work in all environments. The purpose of this flag is to avoid the window from capturing focus, as well as hiding it from the task bar. */ -#if defined(Q_OS_WIN32) - d->view->setFlags(d->view->flags() | Qt::Tool); -#elif defined(QT_VIRTUALKEYBOARD_HAVE_XCB) - d->view->setFlags(d->view->flags() | Qt::Window | Qt::BypassWindowManagerHint); -#else - d->view->setFlags(d->view->flags() | Qt::ToolTip); -#endif + switch (d->windowingSystem) { + case DesktopInputPanelPrivate::Xcb: + d->view->setFlags(d->view->flags() | Qt::Window | Qt::BypassWindowManagerHint); + break; + default: + d->view->setFlags(d->view->flags() | Qt::Tool); + break; + } d->view->setColor(QColor(Qt::transparent)); d->view->setSource(QUrl("qrc:///QtQuick/Enterprise/VirtualKeyboard/content/InputPanel.qml")); connect(qGuiApp, SIGNAL(aboutToQuit()), SLOT(destroyView())); @@ -219,26 +235,36 @@ void DesktopInputPanel::updateInputRegion() if (!d->view->handle()) d->view->create(); + switch (d->windowingSystem) { + case DesktopInputPanelPrivate::Xcb: #if defined(QT_VIRTUALKEYBOARD_HAVE_XCB) - QVector rects; - rects.push_back(qRectToXCBRectangle(d->keyboardRect.toRect())); - if (d->previewVisible && !d->previewRect.isEmpty()) - rects.push_back(qRectToXCBRectangle(d->previewRect.toRect())); - - QWindow *window = d->view.data(); - QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface(); - xcb_connection_t *xbcConnection = static_cast(platformNativeInterface->nativeResourceForWindow("connection", window)); - xcb_xfixes_region_t xbcRegion = xcb_generate_id(xbcConnection); - xcb_xfixes_create_region(xbcConnection, xbcRegion, rects.size(), rects.constData()); - xcb_xfixes_set_window_shape_region(xbcConnection, window->winId(), XCB_SHAPE_SK_INPUT, 0, 0, xbcRegion); - xcb_xfixes_destroy_region(xbcConnection, xbcRegion); -#else - QRegion inputRegion(d->keyboardRect.toRect()); - if (d->previewVisible && !d->previewRect.isEmpty()) - inputRegion += d->previewRect.toRect(); - - d->view->setMask(inputRegion); + { + QVector rects; + rects.push_back(qRectToXCBRectangle(d->keyboardRect.toRect())); + if (d->previewVisible && !d->previewRect.isEmpty()) + rects.push_back(qRectToXCBRectangle(d->previewRect.toRect())); + + QWindow *window = d->view.data(); + QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface(); + xcb_connection_t *xbcConnection = static_cast(platformNativeInterface->nativeResourceForWindow("connection", window)); + xcb_xfixes_region_t xbcRegion = xcb_generate_id(xbcConnection); + xcb_xfixes_create_region(xbcConnection, xbcRegion, rects.size(), rects.constData()); + xcb_xfixes_set_window_shape_region(xbcConnection, window->winId(), XCB_SHAPE_SK_INPUT, 0, 0, xbcRegion); + xcb_xfixes_destroy_region(xbcConnection, xbcRegion); + } #endif + break; + + default: + { + QRegion inputRegion(d->keyboardRect.toRect()); + if (d->previewVisible && !d->previewRect.isEmpty()) + inputRegion += d->previewRect.toRect(); + + d->view->setMask(inputRegion); + break; + } + } } } // namespace QtVirtualKeyboard -- cgit v1.2.3