15#include "plugins/shakecursor/shakecursorconfig.h"
22 : m_cursor(
Cursors::self()->mouse())
26 m_resetCursorScaleTimer.setSingleShot(
true);
27 connect(&m_resetCursorScaleTimer, &QTimer::timeout,
this, [
this]() {
28 m_resetCursorScaleAnimation.setStartValue(m_cursorMagnification);
29 m_resetCursorScaleAnimation.setEndValue(1.0);
31 m_resetCursorScaleAnimation.setEasingCurve(QEasingCurve::InOutCubic);
32 m_resetCursorScaleAnimation.start();
35 connect(&m_resetCursorScaleAnimation, &QVariantAnimation::valueChanged,
this, [
this]() {
37 .position = m_cursor->
pos(),
40 .magnification = m_resetCursorScaleAnimation.currentValue().toReal(),
63 ShakeCursorConfig::self()->read();
65 m_shakeDetector.
setInterval(ShakeCursorConfig::timeInterval());
71 return m_cursorMagnification != 1.0;
76 if (event->type() != QEvent::MouseMove || event->buttons() != Qt::NoButton) {
80 if (
input()->pointer()->isConstrained()) {
84 if (
const auto shakeFactor = m_shakeDetector.
update(event)) {
86 .position = m_cursor->
pos(),
89 .magnification = std::max(m_cursorMagnification, 1.0 + ShakeCursorConfig::magnification() * shakeFactor.value()),
92 m_resetCursorScaleAnimation.stop();
93 }
else if (m_cursorMagnification != 1.0) {
95 .position = m_cursor->
pos(),
98 .magnification = m_cursorMagnification,
103GLTexture *ShakeCursorEffect::ensureCursorTexture()
105 if (!m_cursorTexture || m_cursorTextureDirty) {
106 m_cursorTexture.reset();
107 m_cursorTextureDirty =
false;
109 if (!cursor.image().isNull()) {
111 if (!m_cursorTexture) {
114 m_cursorTexture->setWrapMode(GL_CLAMP_TO_EDGE);
115 m_cursorTexture->setFilter(GL_LINEAR);
118 return m_cursorTexture.get();
121void ShakeCursorEffect::markCursorTextureDirty()
123 m_cursorTextureDirty =
true;
126 .position = m_cursor->
pos(),
127 .hotspot = m_cursor->
hotspot(),
128 .size = m_cursor->
geometry().size(),
129 .magnification = m_cursorMagnification,
134void ShakeCursorEffect::showCursor()
139 if (m_cursorTexture) {
141 m_cursorTexture.reset();
143 m_cursorTextureDirty =
false;
144 m_mouseHidden =
false;
148void ShakeCursorEffect::hideCursor()
150 if (!m_mouseHidden) {
153 m_mouseHidden =
true;
157void ShakeCursorEffect::update(
const Transaction &transaction)
159 if (transaction.magnification == 1.0) {
160 if (m_cursorMagnification == 1.0) {
164 const QRectF oldCursorGeometry = m_cursorGeometry;
167 m_cursorGeometry = QRectF();
168 m_cursorMagnification = 1.0;
172 const QRectF oldCursorGeometry = m_cursorGeometry;
175 m_cursorMagnification = transaction.magnification;
176 m_cursorGeometry = QRectF(transaction.position - transaction.hotspot * transaction.magnification, transaction.size * transaction.magnification);
178 if (transaction.damaged || oldCursorGeometry != m_cursorGeometry) {
188 if (
GLTexture *texture = ensureCursorTexture()) {
192 glEnable(GL_SCISSOR_TEST);
196 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
200 mvp.translate(m_cursorGeometry.x() * viewport.
scale(), m_cursorGeometry.y() * viewport.
scale());
202 texture->render(clipRegion, m_cursorGeometry.size() * viewport.
scale(), clipping);
207 glDisable(GL_SCISSOR_TEST);
214#include "moc_shakecursor.cpp"
Display * waylandDisplay() const
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, Output *screen)
Q_SCRIPTABLE void addRepaint(const QRectF &r)
bool makeOpenGLContextCurrent()
Makes the OpenGL compositing context current.
bool isOpenGLCompositing() const
Whether the Compositor is OpenGL based (either GL 1 or 2).
void cursorShapeChanged()
PlatformCursorImage cursorImage() const
KSharedConfigPtr config() const
bool setColorspaceUniformsFromSRGB(const ColorDescription &dst)
@ ModelViewProjectionMatrix
static std::unique_ptr< GLTexture > upload(const QImage &image)
const ColorDescription & colorDescription() const
QMatrix4x4 projectionMatrix() const
QRectF mapToRenderTarget(const QRectF &logicalGeometry) const
static ShaderManager * instance()
GLShader * pushShader(ShaderTraits traits)
void pointerEvent(MouseEvent *event) override
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, Output *screen) override
void reconfigure(ReconfigureFlags flags) override
bool isActive() const override
~ShakeCursorEffect() override
void setSensitivity(qreal sensitivity)
std::optional< qreal > update(QMouseEvent *event)
void setInterval(quint64 interval)
static double animationTime(const KConfigGroup &cfg, const QString &key, int defaultTime)
KWIN_EXPORT QRect infiniteRegion()
InputRedirection * input()