xcb: fix missing initialization of m_cursor

Regression introduced in 9a4c98e55659b32db984612e6247ac193812a502:

m_cursor is not initialized and never set when monitorInfo is not
available in QXcbScreen::setMonitor. This seems to happen when running
in VNC, e.g. on a Raspberry Pi.

This usually results in crashing the application pretty soon.

Using a unique_ptr solves both the initialization and a possible leak
when setMonitor is called multiple times.

[ChangeLog][Linux/XCB] Fixed crash when no monitorInfo is available (e.g. VNC).

Fixes: QTBUG-104443
Change-Id: If13493c177121a1994b5d00dfbd64f1da694df2e
Reviewed-by: Liang Qi <liang.qi@qt.io>
(cherry picked from commit 03e76ac23d3f9892c5853cab8760ca46c9117229)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Nils Jeisecke 2022-06-20 12:42:06 +02:00 committed by Qt Cherry-pick Bot
parent f298d347f5
commit 91cb059e3d
2 changed files with 6 additions and 7 deletions

View File

@ -499,6 +499,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
, m_crtc(output ? output->crtc : XCB_NONE) , m_crtc(output ? output->crtc : XCB_NONE)
, m_outputName(getOutputName(output)) , m_outputName(getOutputName(output))
, m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize()) , m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
, m_cursor(std::make_unique<QXcbCursor>(connection, this))
{ {
if (connection->isAtLeastXRandR12()) { if (connection->isAtLeastXRandR12()) {
xcb_randr_select_input(xcb_connection(), screen()->root, true); xcb_randr_select_input(xcb_connection(), screen()->root, true);
@ -519,8 +520,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
if (m_sizeMillimeters.isEmpty()) if (m_sizeMillimeters.isEmpty())
m_sizeMillimeters = virtualDesktop->physicalSize(); m_sizeMillimeters = virtualDesktop->physicalSize();
m_cursor = new QXcbCursor(connection, this);
updateColorSpaceAndEdid(); updateColorSpaceAndEdid();
} }
@ -585,6 +584,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
: QXcbObject(connection) : QXcbObject(connection)
, m_virtualDesktop(virtualDesktop) , m_virtualDesktop(virtualDesktop)
, m_monitor(monitorInfo) , m_monitor(monitorInfo)
, m_cursor(std::make_unique<QXcbCursor>(connection, this))
{ {
setMonitor(monitorInfo, timestamp); setMonitor(monitorInfo, timestamp);
} }
@ -685,8 +685,6 @@ void QXcbScreen::setMonitor(xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp
m_primary = true; m_primary = true;
} }
m_cursor = new QXcbCursor(connection(), this);
updateColorSpaceAndEdid(); updateColorSpaceAndEdid();
} }
@ -715,7 +713,6 @@ bool QXcbScreen::isPrimaryInXScreen()
QXcbScreen::~QXcbScreen() QXcbScreen::~QXcbScreen()
{ {
delete m_cursor;
} }
QString QXcbScreen::getOutputName(xcb_randr_get_output_info_reply_t *outputInfo) QString QXcbScreen::getOutputName(xcb_randr_get_output_info_reply_t *outputInfo)
@ -882,7 +879,7 @@ QDpi QXcbScreen::logicalDpi() const
QPlatformCursor *QXcbScreen::cursor() const QPlatformCursor *QXcbScreen::cursor() const
{ {
return m_cursor; return m_cursor.get();
} }
void QXcbScreen::setOutput(xcb_randr_output_t outputId, void QXcbScreen::setOutput(xcb_randr_output_t outputId,

View File

@ -18,6 +18,8 @@
#include <QtGui/private/qedidparser_p.h> #include <QtGui/private/qedidparser_p.h>
#include <memory>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QXcbConnection; class QXcbConnection;
@ -213,7 +215,7 @@ private:
QRect m_availableGeometry; QRect m_availableGeometry;
QColorSpace m_colorSpace; QColorSpace m_colorSpace;
Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation; Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
QXcbCursor *m_cursor; std::unique_ptr<QXcbCursor> m_cursor;
qreal m_refreshRate = 60.0; qreal m_refreshRate = 60.0;
QEdidParser m_edid; QEdidParser m_edid;