File indexing completed on 2024-11-10 04:57:42
0001 /* 0002 SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "cursorsource.h" 0008 #include "cursor.h" 0009 #include "wayland/surface.h" 0010 0011 namespace KWin 0012 { 0013 0014 CursorSource::CursorSource(QObject *parent) 0015 : QObject(parent) 0016 { 0017 } 0018 0019 QSizeF CursorSource::size() const 0020 { 0021 return m_size; 0022 } 0023 0024 QPointF CursorSource::hotspot() const 0025 { 0026 return m_hotspot; 0027 } 0028 0029 ShapeCursorSource::ShapeCursorSource(QObject *parent) 0030 : CursorSource(parent) 0031 { 0032 m_delayTimer.setSingleShot(true); 0033 connect(&m_delayTimer, &QTimer::timeout, this, &ShapeCursorSource::selectNextSprite); 0034 } 0035 0036 QImage ShapeCursorSource::image() const 0037 { 0038 return m_image; 0039 } 0040 0041 QByteArray ShapeCursorSource::shape() const 0042 { 0043 return m_shape; 0044 } 0045 0046 void ShapeCursorSource::setShape(const QByteArray &shape) 0047 { 0048 if (m_shape != shape) { 0049 m_shape = shape; 0050 refresh(); 0051 } 0052 } 0053 0054 void ShapeCursorSource::setShape(Qt::CursorShape shape) 0055 { 0056 setShape(CursorShape(shape).name()); 0057 } 0058 0059 KXcursorTheme ShapeCursorSource::theme() const 0060 { 0061 return m_theme; 0062 } 0063 0064 void ShapeCursorSource::setTheme(const KXcursorTheme &theme) 0065 { 0066 if (m_theme != theme) { 0067 m_theme = theme; 0068 refresh(); 0069 } 0070 } 0071 0072 void ShapeCursorSource::refresh() 0073 { 0074 m_currentSprite = -1; 0075 m_delayTimer.stop(); 0076 0077 m_sprites = m_theme.shape(m_shape); 0078 if (m_sprites.isEmpty()) { 0079 const auto alternativeNames = CursorShape::alternatives(m_shape); 0080 for (const QByteArray &alternativeName : alternativeNames) { 0081 m_sprites = m_theme.shape(alternativeName); 0082 if (!m_sprites.isEmpty()) { 0083 break; 0084 } 0085 } 0086 } 0087 0088 if (!m_sprites.isEmpty()) { 0089 selectSprite(0); 0090 } 0091 } 0092 0093 void ShapeCursorSource::selectNextSprite() 0094 { 0095 selectSprite((m_currentSprite + 1) % m_sprites.size()); 0096 } 0097 0098 void ShapeCursorSource::selectSprite(int index) 0099 { 0100 if (m_currentSprite == index) { 0101 return; 0102 } 0103 const KXcursorSprite &sprite = m_sprites[index]; 0104 m_currentSprite = index; 0105 m_image = sprite.data(); 0106 m_size = QSizeF(m_image.size()) / m_image.devicePixelRatio(); 0107 m_hotspot = sprite.hotspot(); 0108 if (sprite.delay().count() && m_sprites.size() > 1) { 0109 m_delayTimer.start(sprite.delay()); 0110 } 0111 Q_EMIT changed(); 0112 } 0113 0114 SurfaceCursorSource::SurfaceCursorSource(QObject *parent) 0115 : CursorSource(parent) 0116 { 0117 } 0118 0119 SurfaceInterface *SurfaceCursorSource::surface() const 0120 { 0121 return m_surface; 0122 } 0123 0124 void SurfaceCursorSource::refresh() 0125 { 0126 m_size = m_surface->size(); 0127 m_hotspot -= m_surface->offset(); 0128 Q_EMIT changed(); 0129 } 0130 0131 void SurfaceCursorSource::reset() 0132 { 0133 m_size = QSizeF(0, 0); 0134 m_hotspot = QPointF(0, 0); 0135 m_surface = nullptr; 0136 Q_EMIT changed(); 0137 } 0138 0139 void SurfaceCursorSource::update(SurfaceInterface *surface, const QPointF &hotspot) 0140 { 0141 bool dirty = false; 0142 0143 if (m_hotspot != hotspot) { 0144 dirty = true; 0145 m_hotspot = hotspot; 0146 } 0147 0148 if (m_surface != surface) { 0149 dirty = true; 0150 0151 if (m_surface) { 0152 disconnect(m_surface, &SurfaceInterface::committed, this, &SurfaceCursorSource::refresh); 0153 disconnect(m_surface, &SurfaceInterface::destroyed, this, &SurfaceCursorSource::reset); 0154 } 0155 0156 m_surface = surface; 0157 0158 if (m_surface) { 0159 m_size = surface->size(); 0160 0161 connect(m_surface, &SurfaceInterface::committed, this, &SurfaceCursorSource::refresh); 0162 connect(m_surface, &SurfaceInterface::destroyed, this, &SurfaceCursorSource::reset); 0163 } else { 0164 m_size = QSizeF(0, 0); 0165 } 0166 } 0167 0168 if (dirty) { 0169 Q_EMIT changed(); 0170 } 0171 } 0172 0173 } // namespace KWin 0174 0175 #include "moc_cursorsource.cpp"