summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h2
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp138
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.h2
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp19
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h3
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp31
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp30
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp6
14 files changed, 210 insertions, 58 deletions
diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h
index 6e841370d8..c6492f02ae 100644
--- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h
+++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h
@@ -14,7 +14,7 @@ class QPlatformOffscreenSurface;
class QOffscreenSurface;
class QXcbNativeInterfaceHandler;
-Q_XCB_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcQpaGl)
+Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcQpaGl, Q_XCB_EXPORT)
class Q_XCB_EXPORT QXcbGlIntegration
{
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp
index 2ab89f07d6..08c34cc495 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp
@@ -6,12 +6,55 @@
#include "qxcbeglcontext.h"
#include <QtGui/QOffscreenSurface>
+#include <QtGui/private/qeglconvenience_p.h>
#include <QtGui/private/qeglstreamconvenience_p.h>
+#include <optional>
#include "qxcbeglnativeinterfacehandler.h"
QT_BEGIN_NAMESPACE
+namespace {
+
+struct VisualInfo
+{
+ xcb_visualtype_t visualType;
+ uint8_t depth;
+};
+
+std::optional<VisualInfo> getVisualInfo(xcb_screen_t *screen,
+ std::optional<xcb_visualid_t> requestedVisualId,
+ std::optional<uint8_t> requestedDepth = std::nullopt)
+{
+ xcb_depth_iterator_t depthIterator = xcb_screen_allowed_depths_iterator(screen);
+
+ while (depthIterator.rem) {
+ xcb_depth_t *depth = depthIterator.data;
+ xcb_visualtype_iterator_t visualTypeIterator = xcb_depth_visuals_iterator(depth);
+
+ while (visualTypeIterator.rem) {
+ xcb_visualtype_t *visualType = visualTypeIterator.data;
+ if (requestedVisualId && visualType->visual_id != *requestedVisualId) {
+ xcb_visualtype_next(&visualTypeIterator);
+ continue;
+ }
+
+ if (requestedDepth && depth->depth != *requestedDepth) {
+ xcb_visualtype_next(&visualTypeIterator);
+ continue;
+ }
+
+ return VisualInfo{ *visualType, depth->depth };
+ }
+
+ xcb_depth_next(&depthIterator);
+ }
+
+ return std::nullopt;
+}
+
+} // namespace
+
QXcbEglIntegration::QXcbEglIntegration()
: m_connection(nullptr)
, m_egl_display(EGL_NO_DISPLAY)
@@ -93,4 +136,99 @@ void *QXcbEglIntegration::xlib_display() const
#endif
}
+xcb_visualid_t QXcbEglIntegration::getCompatibleVisualId(xcb_screen_t *screen, EGLConfig config) const
+{
+ xcb_visualid_t visualId = 0;
+ EGLint eglValue = 0;
+
+ EGLint configRedSize = 0;
+ eglGetConfigAttrib(eglDisplay(), config, EGL_RED_SIZE, &configRedSize);
+
+ EGLint configGreenSize = 0;
+ eglGetConfigAttrib(eglDisplay(), config, EGL_GREEN_SIZE, &configGreenSize);
+
+ EGLint configBlueSize = 0;
+ eglGetConfigAttrib(eglDisplay(), config, EGL_BLUE_SIZE, &configBlueSize);
+
+ EGLint configAlphaSize = 0;
+ eglGetConfigAttrib(eglDisplay(), config, EGL_ALPHA_SIZE, &configAlphaSize);
+
+ eglGetConfigAttrib(eglDisplay(), config, EGL_CONFIG_ID, &eglValue);
+ int configId = eglValue;
+
+ // See if EGL provided a valid VisualID:
+ eglGetConfigAttrib(eglDisplay(), config, EGL_NATIVE_VISUAL_ID, &eglValue);
+ visualId = eglValue;
+ if (visualId) {
+ // EGL has suggested a visual id, so get the rest of the visual info for that id:
+ std::optional<VisualInfo> chosenVisualInfo = getVisualInfo(screen, visualId);
+ if (chosenVisualInfo) {
+ // Skip size checks if implementation supports non-matching visual
+ // and config (QTBUG-9444).
+ if (q_hasEglExtension(eglDisplay(), "EGL_NV_post_convert_rounding"))
+ return visualId;
+ // Skip also for i.MX6 where 565 visuals are suggested for the default 444 configs and it works just fine.
+ const char *vendor = eglQueryString(eglDisplay(), EGL_VENDOR);
+ if (vendor && strstr(vendor, "Vivante"))
+ return visualId;
+
+ int visualRedSize = qPopulationCount(chosenVisualInfo->visualType.red_mask);
+ int visualGreenSize = qPopulationCount(chosenVisualInfo->visualType.green_mask);
+ int visualBlueSize = qPopulationCount(chosenVisualInfo->visualType.blue_mask);
+ int visualAlphaSize = chosenVisualInfo->depth - visualRedSize - visualBlueSize - visualGreenSize;
+
+ const bool visualMatchesConfig = visualRedSize >= configRedSize
+ && visualGreenSize >= configGreenSize
+ && visualBlueSize >= configBlueSize
+ && visualAlphaSize >= configAlphaSize;
+
+ // In some cases EGL tends to suggest a 24-bit visual for 8888
+ // configs. In such a case we have to fall back to getVisualInfo.
+ if (!visualMatchesConfig) {
+ visualId = 0;
+ qCDebug(lcQpaGl,
+ "EGL suggested using X Visual ID %d (%d %d %d %d depth %d) for EGL config %d"
+ "(%d %d %d %d), but this is incompatible",
+ visualId, visualRedSize, visualGreenSize, visualBlueSize, visualAlphaSize, chosenVisualInfo->depth,
+ configId, configRedSize, configGreenSize, configBlueSize, configAlphaSize);
+ }
+ } else {
+ qCDebug(lcQpaGl, "EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID",
+ visualId, configId);
+ visualId = 0;
+ }
+ }
+ else
+ qCDebug(lcQpaGl, "EGL did not suggest a VisualID (EGL_NATIVE_VISUAL_ID was zero) for EGLConfig %d", configId);
+
+ if (visualId) {
+ qCDebug(lcQpaGl, configAlphaSize > 0
+ ? "Using ARGB Visual ID %d provided by EGL for config %d"
+ : "Using Opaque Visual ID %d provided by EGL for config %d", visualId, configId);
+ return visualId;
+ }
+
+ // Finally, try to use getVisualInfo and only use the bit depths to match on:
+ if (!visualId) {
+ uint8_t depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize;
+ std::optional<VisualInfo> matchingVisual = getVisualInfo(screen, std::nullopt, depth);
+ if (!matchingVisual) {
+ // Try again without taking the alpha channel into account:
+ depth = configRedSize + configGreenSize + configBlueSize;
+ matchingVisual = getVisualInfo(screen, std::nullopt, depth);
+ }
+
+ if (matchingVisual)
+ visualId = matchingVisual->visualType.visual_id;
+ }
+
+ if (visualId) {
+ qCDebug(lcQpaGl, "Using Visual ID %d provided by getVisualInfo for EGL config %d", visualId, configId);
+ return visualId;
+ }
+
+ qWarning("Unable to find an X11 visual which matches EGL config %d", configId);
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.h b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.h
index 5ea37c0924..194b6d6e77 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.h
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.h
@@ -39,6 +39,8 @@ public:
EGLDisplay eglDisplay() const { return m_egl_display; }
void *xlib_display() const;
+
+ xcb_visualid_t getCompatibleVisualId(xcb_screen_t *screen, EGLConfig config) const;
private:
QXcbConnection *m_connection;
EGLDisplay m_egl_display;
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp
index e5ca2b4864..4d87b08db8 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp
@@ -6,7 +6,6 @@
#include "qxcbeglintegration.h"
#include <QtGui/private/qeglconvenience_p.h>
-#include <QtGui/private/qxlibeglintegration_p.h>
QT_BEGIN_NAMESPACE
@@ -29,29 +28,15 @@ void QXcbEglWindow::resolveFormat(const QSurfaceFormat &format)
m_format = q_glFormatFromConfig(m_glIntegration->eglDisplay(), m_config, format);
}
-#if QT_CONFIG(xcb_xlib)
const xcb_visualtype_t *QXcbEglWindow::createVisual()
{
QXcbScreen *scr = xcbScreen();
if (!scr)
return QXcbWindow::createVisual();
- Display *xdpy = static_cast<Display *>(m_glIntegration->xlib_display());
- VisualID id = QXlibEglIntegration::getCompatibleVisualId(xdpy, m_glIntegration->eglDisplay(), m_config);
-
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- visualInfoTemplate.visualid = id;
-
- XVisualInfo *visualInfo;
- int matchingCount = 0;
- visualInfo = XGetVisualInfo(xdpy, VisualIDMask, &visualInfoTemplate, &matchingCount);
- const xcb_visualtype_t *xcb_visualtype = scr->visualForId(visualInfo->visualid);
- XFree(visualInfo);
-
- return xcb_visualtype;
+ xcb_visualid_t id = m_glIntegration->getCompatibleVisualId(scr->screen(), m_config);
+ return scr->visualForId(id);
}
-#endif
void QXcbEglWindow::create()
{
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h
index 79f1df0493..935a0c6d43 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.h
@@ -25,10 +25,7 @@ public:
protected:
void create() override;
void resolveFormat(const QSurfaceFormat &format) override;
-
-#if QT_CONFIG(xcb_xlib)
const xcb_visualtype_t *createVisual() override;
-#endif
private:
QXcbEglIntegration *m_glIntegration;
diff --git a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp
index 2a84431cde..186a3cf9d7 100644
--- a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp
+++ b/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp
@@ -1437,22 +1437,16 @@ QPixmap QX11PlatformPixmap::transformed(const QTransform &transform, Qt::Transfo
transform.m21(), transform.m22(), transform.m23(),
0., 0., 1);
bool complex_xform = false;
- qreal scaledWidth;
- qreal scaledHeight;
if (mat.type() <= QTransform::TxScale) {
- scaledHeight = qAbs(mat.m22()) * hs + 0.9999;
- scaledWidth = qAbs(mat.m11()) * ws + 0.9999;
- h = qAbs(int(scaledHeight));
- w = qAbs(int(scaledWidth));
+ h = qRound(qAbs(mat.m22()) * hs);
+ w = qRound(qAbs(mat.m11()) * ws);
} else { // rotation or shearing
QPolygonF a(QRectF(0, 0, ws, hs));
a = mat.map(a);
QRect r = a.boundingRect().toAlignedRect();
w = r.width();
h = r.height();
- scaledWidth = w;
- scaledHeight = h;
complex_xform = true;
}
mat = QPixmap::trueMatrix(mat, ws, hs); // true matrix
@@ -1461,7 +1455,7 @@ QPixmap QX11PlatformPixmap::transformed(const QTransform &transform, Qt::Transfo
mat = mat.inverted(&invertible); // invert matrix
if (h == 0 || w == 0 || !invertible
- || qAbs(scaledWidth) >= 32768 || qAbs(scaledHeight) >= 32768 )
+ || qAbs(h) >= 32768 || qAbs(w) >= 32768 )
// error, return null pixmap
return QPixmap();
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index d6cc0bc2af..f3905dff81 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -866,6 +866,7 @@ void QXcbBackingStore::render(xcb_window_t window, const QRegion &region, const
}
QPlatformBackingStore::FlushResult QXcbBackingStore::rhiFlush(QWindow *window,
+ qreal sourceDevicePixelRatio,
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
@@ -876,7 +877,7 @@ QPlatformBackingStore::FlushResult QXcbBackingStore::rhiFlush(QWindow *window,
m_image->flushScrolledRegion(true);
- QPlatformBackingStore::rhiFlush(window, region, offset, textures, translucentBackground);
+ QPlatformBackingStore::rhiFlush(window, sourceDevicePixelRatio, region, offset, textures, translucentBackground);
QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
if (platformWindow->needsSync()) {
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h
index c3ee4a9e31..979b254326 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.h
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.h
@@ -24,6 +24,7 @@ public:
QPaintDevice *paintDevice() override;
void flush(QWindow *window, const QRegion &region, const QPoint &offset) override;
FlushResult rhiFlush(QWindow *window,
+ qreal sourceDevicePixelRatio,
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index cf2a2af457..51530e0055 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -449,12 +449,12 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
- qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
- message,
- int(error->error_code), xcb_errors[clamped_error_code],
- int(error->sequence), int(error->resource_id),
- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
- int(error->minor_code));
+ qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+ message,
+ int(error->error_code), xcb_errors[clamped_error_code],
+ int(error->sequence), int(error->resource_id),
+ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+ int(error->minor_code));
}
static Qt::MouseButtons translateMouseButtons(int s)
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 893b11c8c3..8b49fb73ca 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -20,6 +20,7 @@
#ifndef QT_NO_SESSIONMANAGER
#include "qxcbsessionmanager.h"
#endif
+#include "qxcbxsettings.h"
#include <xcb/xcb.h>
@@ -48,9 +49,9 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
#include <QtGui/QOffscreenSurface>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include <qpa/qplatformaccessibility.h>
-#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE
+#if QT_CONFIG(accessibility_atspi_bridge)
#include <QtGui/private/qspiaccessiblebridge_p.h>
#endif
#endif
@@ -383,7 +384,7 @@ QPlatformInputContext *QXcbIntegration::inputContext() const
return m_inputContext.data();
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QPlatformAccessibility *QXcbIntegration::accessibility() const
{
#if !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE)
@@ -423,12 +424,30 @@ QPlatformTheme *QXcbIntegration::createPlatformTheme(const QString &name) const
return QGenericUnixTheme::createUnixTheme(name);
}
+#define RETURN_VALID_XSETTINGS(key) { \
+ auto value = connection()->primaryScreen()->xSettings()->setting(key); \
+ if (value.isValid()) return value; \
+}
+
QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
switch (hint) {
- case QPlatformIntegration::CursorFlashTime:
- case QPlatformIntegration::KeyboardInputInterval:
+ case QPlatformIntegration::CursorFlashTime: {
+ bool ok = false;
+ // If cursor blinking is off, returns 0 to keep the cursor awlays display.
+ if (connection()->primaryScreen()->xSettings()->setting(QByteArrayLiteral("Net/CursorBlink")).toInt(&ok) == 0 && ok)
+ return 0;
+
+ RETURN_VALID_XSETTINGS(QByteArrayLiteral("Net/CursorBlinkTime"));
+ break;
+ }
case QPlatformIntegration::MouseDoubleClickInterval:
+ RETURN_VALID_XSETTINGS(QByteArrayLiteral("Net/DoubleClickTime"));
+ break;
+ case QPlatformIntegration::MouseDoubleClickDistance:
+ RETURN_VALID_XSETTINGS(QByteArrayLiteral("Net/DoubleClickDistance"));
+ break;
+ case QPlatformIntegration::KeyboardInputInterval:
case QPlatformIntegration::StartDragTime:
case QPlatformIntegration::KeyboardAutoRepeatRate:
case QPlatformIntegration::PasswordMaskDelay:
@@ -438,6 +457,8 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
// TODO using various xcb, gnome or KDE settings
break; // Not implemented, use defaults
case QPlatformIntegration::StartDragDistance: {
+ RETURN_VALID_XSETTINGS(QByteArrayLiteral("Net/DndDragThreshold"));
+
// The default (in QPlatformTheme::defaultThemeHint) is 10 pixels, but
// on a high-resolution screen it makes sense to increase it.
qreal dpi = 100.0;
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 4553bbe700..abdfe7112c 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -68,7 +68,7 @@ public:
QPlatformInputContext *inputContext() const override;
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QPlatformAccessibility *accessibility() const override;
#endif
@@ -110,7 +110,7 @@ private:
QScopedPointer<QPlatformInputContext> m_inputContext;
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
mutable QScopedPointer<QPlatformAccessibility> m_accessibility;
#endif
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index bb33f393ec..2a538c9b6e 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -499,6 +499,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
, m_crtc(output ? output->crtc : XCB_NONE)
, m_outputName(getOutputName(output))
, m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
+ , m_cursor(std::make_unique<QXcbCursor>(connection, this))
{
if (connection->isAtLeastXRandR12()) {
xcb_randr_select_input(xcb_connection(), screen()->root, true);
@@ -519,8 +520,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
if (m_sizeMillimeters.isEmpty())
m_sizeMillimeters = virtualDesktop->physicalSize();
- m_cursor = new QXcbCursor(connection, this);
-
updateColorSpaceAndEdid();
}
@@ -585,6 +584,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
: QXcbObject(connection)
, m_virtualDesktop(virtualDesktop)
, m_monitor(monitorInfo)
+ , m_cursor(std::make_unique<QXcbCursor>(connection, this))
{
setMonitor(monitorInfo, timestamp);
}
@@ -598,6 +598,7 @@ void QXcbScreen::setMonitor(xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp
m_crtcs.clear();
m_output = XCB_NONE;
m_crtc = XCB_NONE;
+ m_singlescreen = false;
if (!monitorInfo) {
m_monitor = nullptr;
@@ -678,12 +679,11 @@ void QXcbScreen::setMonitor(xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp
m_sizeMillimeters = virtualDesktop()->physicalSize();
m_outputName = getName(monitorInfo);
- if (connection()->primaryScreenNumber() == virtualDesktop()->number() && monitorInfo->primary)
- m_primary = true;
- else
- m_primary = false;
-
- m_cursor = new QXcbCursor(connection(), this);
+ m_primary = false;
+ if (connection()->primaryScreenNumber() == virtualDesktop()->number()) {
+ if (monitorInfo->primary || isPrimaryInXScreen())
+ m_primary = true;
+ }
updateColorSpaceAndEdid();
}
@@ -700,9 +700,19 @@ QString QXcbScreen::defaultName()
return name;
}
+bool QXcbScreen::isPrimaryInXScreen()
+{
+ auto primary = Q_XCB_REPLY(xcb_randr_get_output_primary, connection()->xcb_connection(), root());
+ if (!primary)
+ qWarning("failed to get the primary output of the screen");
+
+ const bool isPrimary = primary ? (m_monitor ? m_outputs.contains(primary->output) : m_output == primary->output) : false;
+
+ return isPrimary;
+}
+
QXcbScreen::~QXcbScreen()
{
- delete m_cursor;
}
QString QXcbScreen::getOutputName(xcb_randr_get_output_info_reply_t *outputInfo)
@@ -869,7 +879,7 @@ QDpi QXcbScreen::logicalDpi() const
QPlatformCursor *QXcbScreen::cursor() const
{
- return m_cursor;
+ return m_cursor.get();
}
void QXcbScreen::setOutput(xcb_randr_output_t outputId,
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 12c13ef80e..49165d3ba4 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -18,6 +18,8 @@
#include <QtGui/private/qedidparser_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QXcbConnection;
@@ -161,6 +163,7 @@ public:
void setCrtc(xcb_randr_crtc_t crtc) { m_crtc = crtc; }
void setMonitor(xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE);
QString defaultName();
+ bool isPrimaryInXScreen();
void windowShown(QXcbWindow *window);
QString windowManagerName() const { return m_virtualDesktop->windowManagerName(); }
@@ -212,7 +215,7 @@ private:
QRect m_availableGeometry;
QColorSpace m_colorSpace;
Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
- QXcbCursor *m_cursor;
+ std::unique_ptr<QXcbCursor> m_cursor;
qreal m_refreshRate = 60.0;
QEdidParser m_edid;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 0162d058a6..a37c03cc60 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -440,10 +440,8 @@ void QXcbWindow::create()
setWindowFlags(window()->flags());
setWindowTitle(window()->title());
-#if QT_CONFIG(xcb_xlib)
// force sync to read outstanding requests - see QTBUG-29106
- XSync(static_cast<Display*>(platformScreen->connection()->xlib_display()), false);
-#endif
+ connection()->sync();
#if QT_CONFIG(draganddrop)
connection()->drag()->dndEnable(this, true);
@@ -515,6 +513,8 @@ void QXcbWindow::destroy()
void QXcbWindow::setGeometry(const QRect &rect)
{
+ setWindowState(Qt::WindowNoState);
+
QPlatformWindow::setGeometry(rect);
propagateSizeHints();