qt5-wayland-animate-cursor.patch 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. From 36974955d13578071387695adb13a47be33e4d32 Mon Sep 17 00:00:00 2001
  2. From: David Edmundson <davidedmundson@kde.org>
  3. Date: Thu, 28 Nov 2019 02:31:17 +0100
  4. Subject: Avoid animating single frame cursors
  5. Currently to determine if a cursor is animated or not we check the
  6. cursor theme delay.
  7. This doesn't work in practice as by default many cursor themes have a
  8. delay of 50 set even if they don't animate.
  9. This comes from xcursorgen which specifies a delay of 50ms if there
  10. isn't anything set in the config.
  11. (https://github.com/freedesktop/xcursorgen/blob/master/xcursorgen.c#L92)
  12. Given many themes will have a delay we should also check the number of
  13. images in a given cursor.
  14. In order to do that without a double lookup QWaylandCursor needed to
  15. return the native wl_cursor, not wl_cursor_image and move the relevant
  16. logic.
  17. Change-Id: Ie782ace8054910ae76e61cab33ceca0377194929
  18. Reviewed-by: Johan Helsing <johan.helsing@qt.io>
  19. ---
  20. src/client/qwaylandcursor.cpp | 12 ++----------
  21. src/client/qwaylandcursor_p.h | 3 +--
  22. src/client/qwaylandinputdevice.cpp | 16 ++++++++++++----
  23. 3 files changed, 15 insertions(+), 16 deletions(-)
  24. diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp
  25. index 4356b23a..1d3d88be 100644
  26. --- a/src/client/qwaylandcursor.cpp
  27. +++ b/src/client/qwaylandcursor.cpp
  28. @@ -219,7 +219,7 @@ wl_cursor *QWaylandCursorTheme::requestCursor(WaylandCursor shape)
  29. return nullptr;
  30. }
  31. -::wl_cursor_image *QWaylandCursorTheme::cursorImage(Qt::CursorShape shape, uint millisecondsIntoAnimation)
  32. +::wl_cursor *QWaylandCursorTheme::cursor(Qt::CursorShape shape)
  33. {
  34. struct wl_cursor *waylandCursor = nullptr;
  35. @@ -237,15 +237,7 @@ wl_cursor *QWaylandCursorTheme::requestCursor(WaylandCursor shape)
  36. return nullptr;
  37. }
  38. - int frame = wl_cursor_frame(waylandCursor, millisecondsIntoAnimation);
  39. - ::wl_cursor_image *image = waylandCursor->images[frame];
  40. - ::wl_buffer *buffer = wl_cursor_image_get_buffer(image);
  41. - if (!buffer) {
  42. - qCWarning(lcQpaWayland) << "Could not find buffer for cursor";
  43. - return nullptr;
  44. - }
  45. -
  46. - return image;
  47. + return waylandCursor;
  48. }
  49. QWaylandCursor::QWaylandCursor(QWaylandDisplay *display)
  50. diff --git a/src/client/qwaylandcursor_p.h b/src/client/qwaylandcursor_p.h
  51. index a4605f3d..751ffa68 100644
  52. --- a/src/client/qwaylandcursor_p.h
  53. +++ b/src/client/qwaylandcursor_p.h
  54. @@ -75,7 +75,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandCursorTheme
  55. public:
  56. static QWaylandCursorTheme *create(QWaylandShm *shm, int size, const QString &themeName);
  57. ~QWaylandCursorTheme();
  58. - ::wl_cursor_image *cursorImage(Qt::CursorShape shape, uint millisecondsIntoAnimation = 0);
  59. + ::wl_cursor *cursor(Qt::CursorShape shape);
  60. private:
  61. enum WaylandCursor {
  62. @@ -129,7 +129,6 @@ public:
  63. void setPos(const QPoint &pos) override;
  64. static QSharedPointer<QWaylandBuffer> cursorBitmapBuffer(QWaylandDisplay *display, const QCursor *cursor);
  65. - struct wl_cursor_image *cursorImage(Qt::CursorShape shape);
  66. private:
  67. QWaylandDisplay *mDisplay = nullptr;
  68. diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
  69. index a4098edd..d812918e 100644
  70. --- a/src/client/qwaylandinputdevice.cpp
  71. +++ b/src/client/qwaylandinputdevice.cpp
  72. @@ -283,8 +283,8 @@ void QWaylandInputDevice::Pointer::updateCursorTheme()
  73. if (!mCursor.theme)
  74. return; // A warning has already been printed in loadCursorTheme
  75. - if (auto *arrow = mCursor.theme->cursorImage(Qt::ArrowCursor)) {
  76. - int arrowPixelSize = qMax(arrow->width, arrow->height); // Not all cursor themes are square
  77. + if (auto *arrow = mCursor.theme->cursor(Qt::ArrowCursor)) {
  78. + int arrowPixelSize = qMax(arrow->images[0]->width, arrow->images[0]->height); // Not all cursor themes are square
  79. while (scale > 1 && arrowPixelSize / scale < cursorSize())
  80. --scale;
  81. } else {
  82. @@ -326,12 +326,20 @@ void QWaylandInputDevice::Pointer::updateCursor()
  83. // Set from shape using theme
  84. uint time = seat()->mCursor.animationTimer.elapsed();
  85. - if (struct ::wl_cursor_image *image = mCursor.theme->cursorImage(shape, time)) {
  86. +
  87. + if (struct ::wl_cursor *waylandCursor = mCursor.theme->cursor(shape)) {
  88. + int frame = wl_cursor_frame(waylandCursor, time);
  89. + ::wl_cursor_image *image = waylandCursor->images[frame];
  90. +
  91. struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
  92. + if (!buffer) {
  93. + qCWarning(lcQpaWayland) << "Could not find buffer for cursor" << shape;
  94. + return;
  95. + }
  96. int bufferScale = mCursor.themeBufferScale;
  97. QPoint hotspot = QPoint(image->hotspot_x, image->hotspot_y) / bufferScale;
  98. QSize size = QSize(image->width, image->height) / bufferScale;
  99. - bool animated = image->delay > 0;
  100. + bool animated = waylandCursor->image_count > 1 && image->delay > 0;
  101. getOrCreateCursorSurface()->update(buffer, hotspot, size, bufferScale, animated);
  102. return;
  103. }
  104. --
  105. cgit v1.2.1