summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2020-12-17 11:23:30 +0100
committerLiang Qi <liang.qi@qt.io>2022-09-06 11:21:43 +0200
commit012132c60d625b2de0039bdda3c22a0a8fe2dfe5 (patch)
treee74b40db7ed2046e4280931819fefa8c5d78bab9 /src/plugins/platforms
parente6d3657f7f90a6a184b391d74a9542ef0acf072c (diff)
xcb: use libxcb-cursor to replace Xlib/libXcursor
[ChangeLog][Linux/XCB] Used libxcb-cursor to replace Xlib/libXcursor Fixes: QTBUG-67373 Change-Id: I04a30e401467e48b431a5cc63984f7b70a09faf0 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Liang Qi <liang.qi@qt.io>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/xcb/CMakeLists.txt1
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp141
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h10
3 files changed, 48 insertions, 104 deletions
diff --git a/src/plugins/platforms/xcb/CMakeLists.txt b/src/plugins/platforms/xcb/CMakeLists.txt
index 76d16ee555..fc50666d40 100644
--- a/src/plugins/platforms/xcb/CMakeLists.txt
+++ b/src/plugins/platforms/xcb/CMakeLists.txt
@@ -47,6 +47,7 @@ qt_internal_add_module(XcbQpaPrivate
PkgConfig::XKB_COMMON_X11
Qt::CorePrivate
Qt::GuiPrivate
+ XCB::CURSOR
XCB::ICCCM
XCB::IMAGE
XCB::KEYSYMS
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 2cc39f1e85..5aee1cbe02 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qxcbcursor.h"
@@ -7,13 +7,14 @@
#include "qxcbimage.h"
#include "qxcbxsettings.h"
-#if QT_CONFIG(library)
-#include <QtCore/QLibrary>
-#endif
#include <QtGui/QWindow>
#include <QtGui/QBitmap>
#include <QtGui/private/qguiapplication_p.h>
+
+#if QT_CONFIG(xcb_xlib)
#include <X11/cursorfont.h>
+#endif
+
#include <xcb/xfixes.h>
#include <xcb/xcb_image.h>
@@ -21,24 +22,6 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-typedef int (*PtrXcursorLibraryLoadCursor)(void *, const char *);
-typedef char *(*PtrXcursorLibraryGetTheme)(void *);
-typedef int (*PtrXcursorLibrarySetTheme)(void *, const char *);
-typedef int (*PtrXcursorLibraryGetDefaultSize)(void *);
-
-#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
-#include <X11/Xlib.h>
-enum {
- XCursorShape = CursorShape
-};
-#undef CursorShape
-
-static PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor = nullptr;
-static PtrXcursorLibraryGetTheme ptrXcursorLibraryGetTheme = nullptr;
-static PtrXcursorLibrarySetTheme ptrXcursorLibrarySetTheme = nullptr;
-static PtrXcursorLibraryGetDefaultSize ptrXcursorLibraryGetDefaultSize = nullptr;
-#endif
-
static xcb_font_t cursorFont = 0;
static int cursorCount = 0;
@@ -266,7 +249,7 @@ QXcbCursorCacheKey::QXcbCursorCacheKey(const QCursor &c)
#endif // !QT_NO_CURSOR
QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen)
- : QXcbObject(conn), m_screen(screen), m_gtkCursorThemeInitialized(false)
+ : QXcbObject(conn), m_screen(screen), m_cursorContext(nullptr), m_callbackForPropertyRegistered(false)
{
#if QT_CONFIG(cursor)
// see NUM_BITMAPS in libXcursor/src/xcursorint.h
@@ -280,36 +263,14 @@ QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen)
const char *cursorStr = "cursor";
xcb_open_font(xcb_connection(), cursorFont, strlen(cursorStr), cursorStr);
-#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
- static bool function_ptrs_not_initialized = true;
- if (function_ptrs_not_initialized) {
- QLibrary xcursorLib("Xcursor"_L1, 1);
- bool xcursorFound = xcursorLib.load();
- if (!xcursorFound) { // try without the version number
- xcursorLib.setFileName("Xcursor"_L1);
- xcursorFound = xcursorLib.load();
- }
- if (xcursorFound) {
- ptrXcursorLibraryLoadCursor =
- (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
- ptrXcursorLibraryGetTheme =
- (PtrXcursorLibraryGetTheme) xcursorLib.resolve("XcursorGetTheme");
- ptrXcursorLibrarySetTheme =
- (PtrXcursorLibrarySetTheme) xcursorLib.resolve("XcursorSetTheme");
- ptrXcursorLibraryGetDefaultSize =
- (PtrXcursorLibraryGetDefaultSize) xcursorLib.resolve("XcursorGetDefaultSize");
- }
- function_ptrs_not_initialized = false;
- }
-
-#endif
+ updateContext();
}
QXcbCursor::~QXcbCursor()
{
xcb_connection_t *conn = xcb_connection();
- if (m_gtkCursorThemeInitialized) {
+ if (m_callbackForPropertyRegistered) {
m_screen->xSettings()->removeCallbackForHandle(this);
}
@@ -320,6 +281,23 @@ QXcbCursor::~QXcbCursor()
for (xcb_cursor_t cursor : qAsConst(m_cursorHash))
xcb_free_cursor(conn, cursor);
#endif
+
+ if (m_cursorContext)
+ xcb_cursor_context_free(m_cursorContext);
+}
+
+void QXcbCursor::updateContext()
+{
+ if (m_cursorContext)
+ xcb_cursor_context_free(m_cursorContext);
+
+ m_cursorContext = nullptr;
+
+ xcb_connection_t *conn = xcb_connection();
+ if (xcb_cursor_context_new(conn, m_screen->screen(), &m_cursorContext) < 0) {
+ qWarning() << "xcb: Could not initialize xcb-cursor";
+ m_cursorContext = nullptr;
+ }
}
#ifndef QT_NO_CURSOR
@@ -482,76 +460,39 @@ xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
return cursor;
}
-#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
-bool updateCursorTheme(void *dpy, const QByteArray &theme) {
- if (!ptrXcursorLibraryGetTheme
- || !ptrXcursorLibrarySetTheme)
- return false;
- QByteArray oldTheme = ptrXcursorLibraryGetTheme(dpy);
- if (oldTheme == theme)
- return false;
-
- int setTheme = ptrXcursorLibrarySetTheme(dpy,theme.constData());
- return setTheme;
-}
-
- void QXcbCursor::cursorThemePropertyChanged(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &property, void *handle)
+void QXcbCursor::cursorThemePropertyChanged(QXcbVirtualDesktop *screen, const QByteArray &name, const QVariant &property, void *handle)
{
Q_UNUSED(screen);
Q_UNUSED(name);
+ Q_UNUSED(property);
QXcbCursor *self = static_cast<QXcbCursor *>(handle);
self->m_cursorHash.clear();
-
- updateCursorTheme(self->connection()->xlib_display(),property.toByteArray());
-}
-
-static xcb_cursor_t loadCursor(void *dpy, int cshape)
-{
- xcb_cursor_t cursor = XCB_NONE;
- if (!ptrXcursorLibraryLoadCursor || !dpy)
- return cursor;
-
- for (const char *cursorName: cursorNames[cshape]) {
- cursor = ptrXcursorLibraryLoadCursor(dpy, cursorName);
- if (cursor != XCB_NONE)
- break;
- }
-
- return cursor;
+ self->updateContext();
}
-#endif // QT_CONFIG(xcb_xlib) / QT_CONFIG(library)
xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
{
+ if (!m_cursorContext)
+ return XCB_NONE;
+
xcb_connection_t *conn = xcb_connection();
int cursorId = cursorIdForShape(cshape);
xcb_cursor_t cursor = XCB_NONE;
-#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
- if (m_screen->xSettings()->initialized())
- m_screen->xSettings()->registerCallbackForProperty("Gtk/CursorThemeName",cursorThemePropertyChanged,this);
+ if (!m_callbackForPropertyRegistered && m_screen->xSettings()->initialized()) {
+ m_screen->xSettings()->registerCallbackForProperty("Gtk/CursorThemeName", cursorThemePropertyChanged, this);
+
+ m_callbackForPropertyRegistered = true;
+ }
- // Try Xcursor first
+ // Try xcb-cursor first
if (cshape >= 0 && cshape <= Qt::LastCursor) {
- void *dpy = connection()->xlib_display();
- cursor = loadCursor(dpy, cshape);
- if (!cursor && !m_gtkCursorThemeInitialized && m_screen->xSettings()->initialized()) {
- QByteArray gtkCursorTheme = m_screen->xSettings()->setting("Gtk/CursorThemeName").toByteArray();
- if (updateCursorTheme(dpy,gtkCursorTheme)) {
- cursor = loadCursor(dpy, cshape);
- }
- m_gtkCursorThemeInitialized = true;
+ for (const char *cursorName : cursorNames[cshape]) {
+ cursor = xcb_cursor_load_cursor(m_cursorContext, cursorName);
+ if (cursor != XCB_NONE)
+ return cursor;
}
}
- if (cursor)
- return cursor;
- if (!cursor && cursorId) {
- cursor = XCreateFontCursor(static_cast<Display *>(connection()->xlib_display()), cursorId);
- if (cursor)
- return cursor;
- }
-
-#endif
// Non-standard X11 cursors are created from bitmaps
cursor = createNonStandardCursor(cshape);
diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h
index 83438321ef..14958f824b 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.h
+++ b/src/plugins/platforms/xcb/qxcbcursor.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QXCBCURSOR_H
@@ -6,6 +6,7 @@
#include <qpa/qplatformcursor.h>
#include "qxcbscreen.h"
+#include <xcb/xcb_cursor.h>
#include <QtCore/QCache>
@@ -47,6 +48,8 @@ public:
QPoint pos() const override;
void setPos(const QPoint &pos) override;
+ void updateContext();
+
static void queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask = nullptr);
#ifndef QT_NO_CURSOR
@@ -75,17 +78,16 @@ private:
#endif
QXcbScreen *m_screen;
+ xcb_cursor_context_t *m_cursorContext;
#ifndef QT_NO_CURSOR
CursorHash m_cursorHash;
BitmapCursorCache m_bitmapCache;
#endif
-#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
static void cursorThemePropertyChanged(QXcbVirtualDesktop *screen,
const QByteArray &name,
const QVariant &property,
void *handle);
-#endif
- bool m_gtkCursorThemeInitialized;
+ bool m_callbackForPropertyRegistered;
};
QT_END_NAMESPACE