summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm7
-rw-r--r--src/plugins/platforms/directfb/qdirectfbcursor.cpp5
-rw-r--r--src/plugins/platforms/eglfs/qeglfscursor.cpp7
-rw-r--r--src/plugins/platforms/kms/qkmscursor.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp31
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp24
8 files changed, 73 insertions, 28 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index a584e22e59..238a900c08 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -61,8 +61,9 @@ void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window)
{
Q_UNUSED(window);
+ const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
// Check for a suitable built-in NSCursor first:
- switch (cursor->shape()) {
+ switch (newShape) {
case Qt::ArrowCursor:
[[NSCursor arrowCursor] set];
break;
@@ -99,14 +100,14 @@ void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window)
default : {
// No suitable OS cursor exist, use cursors provided
// by Qt for the rest. Check for a cached cursor:
- NSCursor *cocoaCursor = m_cursors.value(cursor->shape());
+ NSCursor *cocoaCursor = m_cursors.value(newShape);
if (cocoaCursor == 0) {
cocoaCursor = createCursorData(cursor);
if (cocoaCursor == 0) {
[[NSCursor arrowCursor] set];
return;
}
- m_cursors.insert(cursor->shape(), cocoaCursor);
+ m_cursors.insert(newShape, cocoaCursor);
}
[cocoaCursor set];
diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.cpp b/src/plugins/platforms/directfb/qdirectfbcursor.cpp
index b04848ec40..23f115e313 100644
--- a/src/plugins/platforms/directfb/qdirectfbcursor.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbcursor.cpp
@@ -59,8 +59,9 @@ void QDirectFBCursor::changeCursor(QCursor *cursor, QWindow *)
int ySpot;
QPixmap map;
- if (cursor->shape() != Qt::BitmapCursor) {
- m_image->set(cursor->shape());
+ const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
+ if (newShape != Qt::BitmapCursor) {
+ m_image->set(newShape);
xSpot = m_image->hotspot().x();
ySpot = m_image->hotspot().y();
QImage *i = m_image->image();
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp
index b29849226f..88da8d7f42 100644
--- a/src/plugins/platforms/eglfs/qeglfscursor.cpp
+++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp
@@ -196,15 +196,16 @@ void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
{
- if (m_cursor.shape == cursor->shape() && cursor->shape() != Qt::BitmapCursor)
+ const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
+ if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor)
return false;
if (m_cursor.shape == Qt::BitmapCursor) {
m_cursor.customCursorImage = QImage(); // in case render() never uploaded it
}
- m_cursor.shape = cursor->shape();
- if (cursor->shape() != Qt::BitmapCursor) { // standard cursor
+ m_cursor.shape = newShape;
+ if (newShape != Qt::BitmapCursor) { // standard cursor
const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width,
hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height;
m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow),
diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp
index 9a86d6c7cb..5101b4c7e2 100644
--- a/src/plugins/platforms/kms/qkmscursor.cpp
+++ b/src/plugins/platforms/kms/qkmscursor.cpp
@@ -85,8 +85,9 @@ void QKmsCursor::changeCursor(QCursor *widgetCursor, QWindow *window)
if (!m_moved)
drmModeMoveCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0);
- if (widgetCursor->shape() != Qt::BitmapCursor) {
- m_cursorImage->set(widgetCursor->shape());
+ const Qt::CursorShape newShape = widgetCursor ? widgetCursor->shape() : Qt::ArrowCursor;
+ if (newShape != Qt::BitmapCursor) {
+ m_cursorImage->set(newShape);
} else {
m_cursorImage->set(widgetCursor->pixmap().toImage(),
widgetCursor->hotSpot().x(),
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index ac4070a93b..84c82dca45 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -405,8 +405,12 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
if (QWindowsContext::verboseWindows > 1)
qDebug() << __FUNCTION__ << cursorIn << window;
- if (!cursorIn || !window)
+ if (!window)
return;
+ if (!cursorIn) {
+ QWindowsWindow::baseWindowOf(window)->setCursor(QWindowsWindowCursor());
+ return;
+ }
const QWindowsWindowCursor wcursor =
cursorIn->shape() == Qt::BitmapCursor ?
QWindowsWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape());
@@ -448,6 +452,7 @@ void QWindowsCursor::setPos(const QPoint &pos)
class QWindowsWindowCursorData : public QSharedData
{
public:
+ QWindowsWindowCursorData() : m_cursor(Qt::ArrowCursor), m_handle(0) {}
explicit QWindowsWindowCursorData(const QCursor &c);
~QWindowsWindowCursorData();
@@ -463,7 +468,13 @@ QWindowsWindowCursorData::QWindowsWindowCursorData(const QCursor &c) :
QWindowsWindowCursorData::~QWindowsWindowCursorData()
{
- DestroyCursor(m_handle);
+ if (m_handle)
+ DestroyCursor(m_handle);
+}
+
+QWindowsWindowCursor::QWindowsWindowCursor() :
+ m_data(new QWindowsWindowCursorData)
+{
}
QWindowsWindowCursor::QWindowsWindowCursor(const QCursor &c) :
@@ -487,6 +498,11 @@ QWindowsWindowCursor & QWindowsWindowCursor::operator =(const QWindowsWindowCurs
return *this;
}
+bool QWindowsWindowCursor::isNull() const
+{
+ return m_data->m_handle == 0;
+}
+
QCursor QWindowsWindowCursor::cursor() const
{
return m_data->m_cursor;
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index 2d415c04ce..b4026f00bc 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -55,11 +55,13 @@ class QWindowsWindowCursorData;
class QWindowsWindowCursor
{
public:
+ QWindowsWindowCursor();
explicit QWindowsWindowCursor(const QCursor &c);
~QWindowsWindowCursor();
QWindowsWindowCursor(const QWindowsWindowCursor &c);
QWindowsWindowCursor &operator=(const QWindowsWindowCursor &c);
+ bool isNull() const;
QCursor cursor() const;
HCURSOR handle() const;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 23ebd6bd9e..21cd3f7d17 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -739,7 +739,6 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
m_hdc(0),
m_windowState(Qt::WindowNoState),
m_opacity(1.0),
- m_cursor(QWindowsScreen::screenOf(aWindow)->windowsCursor()->standardWindowCursor()),
m_dropTarget(0),
m_savedStyle(0),
m_format(aWindow->format()),
@@ -1668,18 +1667,40 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
void QWindowsWindow::applyCursor()
{
- SetCursor(m_cursor.handle());
+ if (m_cursor.isNull()) { // Recurse up to parent with non-null cursor.
+ if (const QWindow *p = window()->parent())
+ QWindowsWindow::baseWindowOf(p)->applyCursor();
+ } else {
+ SetCursor(m_cursor.handle());
+ }
+}
+
+// Check whether to apply a new cursor. Either the window in question is
+// currently under mouse, or it is the parent of the window under mouse and
+// there is no other window with an explicitly set cursor in-between.
+static inline bool applyNewCursor(const QWindow *w)
+{
+ const QWindow *underMouse = QWindowsContext::instance()->windowUnderMouse();
+ if (underMouse == w)
+ return true;
+ for (const QWindow *p = underMouse; p ; p = p->parent()) {
+ if (p == w)
+ return true;
+ if (!QWindowsWindow::baseWindowOf(p)->cursor().isNull())
+ return false;
+ }
+ return false;
}
void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
{
if (c.handle() != m_cursor.handle()) {
- const bool underMouse = QWindowsContext::instance()->windowUnderMouse() == window();
+ const bool apply = applyNewCursor(window());
if (QWindowsContext::verboseWindows)
qDebug() << window() << __FUNCTION__ << "Shape=" << c.cursor().shape()
- << " isWUM=" << underMouse;
+ << " doApply=" << apply;
m_cursor = c;
- if (underMouse)
+ if (apply)
applyCursor();
}
}
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index e2843d04dc..0704ab6205 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -301,17 +301,19 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget)
// No X11 cursor control when there is no widget under the cursor
return;
- xcb_cursor_t c;
- if (cursor->shape() == Qt::BitmapCursor) {
- qint64 id = cursor->pixmap().cacheKey();
- if (!m_bitmapCursorMap.contains(id))
- m_bitmapCursorMap.insert(id, createBitmapCursor(cursor));
- c = m_bitmapCursorMap.value(id);
- } else {
- int id = cursor->shape();
- if (!m_shapeCursorMap.contains(id))
- m_shapeCursorMap.insert(id, createFontCursor(cursor->shape()));
- c = m_shapeCursorMap.value(id);
+ xcb_cursor_t c = XCB_CURSOR_NONE;
+ if (cursor) {
+ if (cursor->shape() == Qt::BitmapCursor) {
+ qint64 id = cursor->pixmap().cacheKey();
+ if (!m_bitmapCursorMap.contains(id))
+ m_bitmapCursorMap.insert(id, createBitmapCursor(cursor));
+ c = m_bitmapCursorMap.value(id);
+ } else {
+ int id = cursor->shape();
+ if (!m_shapeCursorMap.contains(id))
+ m_shapeCursorMap.insert(id, createFontCursor(cursor->shape()));
+ c = m_shapeCursorMap.value(id);
+ }
}
w->setCursor(c);