summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp24
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp22
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h3
3 files changed, 38 insertions, 11 deletions
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index b321ed95dc..4646ced954 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -353,17 +353,27 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget)
return;
xcb_cursor_t c = XCB_CURSOR_NONE;
+ bool isBitmapCursor = false;
+
if (cursor) {
- const QXcbCursorCacheKey key(*cursor);
- CursorHash::iterator it = m_cursorHash.find(key);
- if (it == m_cursorHash.end()) {
- const Qt::CursorShape shape = cursor->shape();
- it = m_cursorHash.insert(key, shape == Qt::BitmapCursor ? createBitmapCursor(cursor) : createFontCursor(shape));
+ const Qt::CursorShape shape = cursor->shape();
+ isBitmapCursor = shape == Qt::BitmapCursor;
+
+ if (!isBitmapCursor) {
+ const QXcbCursorCacheKey key(*cursor);
+ CursorHash::iterator it = m_cursorHash.find(key);
+ if (it == m_cursorHash.end()) {
+ it = m_cursorHash.insert(key, createFontCursor(shape));
+ }
+ c = it.value();
+ } else {
+ // Do not cache bitmap cursors, as otherwise they have unclear
+ // lifetime (we effectively leak xcb_cursor_t).
+ c = createBitmapCursor(cursor);
}
- c = it.value();
}
- w->setCursor(c);
+ w->setCursor(c, isBitmapCursor);
}
static int cursorIdForShape(int cshape)
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index d46228cf8a..5f402b6eca 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -302,6 +302,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_lastWindowStateEvent(-1)
, m_syncState(NoSyncNeeded)
, m_pendingSyncRequest(0)
+ , m_currentBitmapCursor(XCB_CURSOR_NONE)
{
setConnection(xcbScreen()->connection());
}
@@ -620,6 +621,9 @@ void QXcbWindow::create()
QXcbWindow::~QXcbWindow()
{
+ if (m_currentBitmapCursor != XCB_CURSOR_NONE) {
+ xcb_free_cursor(xcb_connection(), m_currentBitmapCursor);
+ }
if (window()->type() != Qt::ForeignWindow)
destroy();
else {
@@ -2665,10 +2669,22 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
return result;
}
-void QXcbWindow::setCursor(xcb_cursor_t cursor)
+void QXcbWindow::setCursor(xcb_cursor_t cursor, bool isBitmapCursor)
{
- xcb_change_window_attributes(xcb_connection(), m_window, XCB_CW_CURSOR, &cursor);
- xcb_flush(xcb_connection());
+ xcb_connection_t *conn = xcb_connection();
+
+ xcb_change_window_attributes(conn, m_window, XCB_CW_CURSOR, &cursor);
+ xcb_flush(conn);
+
+ if (m_currentBitmapCursor != XCB_CURSOR_NONE) {
+ xcb_free_cursor(conn, m_currentBitmapCursor);
+ }
+
+ if (isBitmapCursor) {
+ m_currentBitmapCursor = cursor;
+ } else {
+ m_currentBitmapCursor = XCB_CURSOR_NONE;
+ }
}
void QXcbWindow::windowEvent(QEvent *event)
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index b8bcf4428a..f2b690416f 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -97,7 +97,7 @@ public:
bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE;
bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
- void setCursor(xcb_cursor_t cursor);
+ void setCursor(xcb_cursor_t cursor, bool isBitmapCursor);
QSurfaceFormat format() const Q_DECL_OVERRIDE;
@@ -263,6 +263,7 @@ protected:
SyncState m_syncState;
QXcbSyncWindowRequest *m_pendingSyncRequest;
+ xcb_cursor_t m_currentBitmapCursor;
};
QT_END_NAMESPACE