diff --git a/src/plugins/zoom/zoom.cpp b/src/plugins/zoom/zoom.cpp index cd6b1f561a..897d5a5986 100644 --- a/src/plugins/zoom/zoom.cpp +++ b/src/plugins/zoom/zoom.cpp @@ -26,8 +26,11 @@ #include "core/rendertarget.h" #include "core/renderviewport.h" +#include "cursor.h" #include "effect/effecthandler.h" #include "opengl/glutils.h" +#include "scene/cursoritem.h" +#include "scene/workspacescene.h" namespace KWin { @@ -41,7 +44,6 @@ ZoomEffect::ZoomEffect() , mouseTracking(MouseTrackingProportional) , mousePointer(MousePointerScale) , focusDelay(350) // in milliseconds - , isMouseHidden(false) , xMove(0) , yMove(0) , moveFactor(20.0) @@ -157,36 +159,12 @@ bool ZoomEffect::isTextCaretTrackingEnabled() const #endif } -GLTexture *ZoomEffect::ensureCursorTexture() -{ - if (!m_cursorTexture || m_cursorTextureDirty) { - m_cursorTexture.reset(); - m_cursorTextureDirty = false; - const auto cursor = effects->cursorImage(); - if (!cursor.image().isNull()) { - m_cursorTexture = GLTexture::upload(cursor.image()); - if (!m_cursorTexture) { - return nullptr; - } - m_cursorTexture->setWrapMode(GL_CLAMP_TO_EDGE); - } - } - return m_cursorTexture.get(); -} - -void ZoomEffect::markCursorTextureDirty() -{ - m_cursorTextureDirty = true; -} - void ZoomEffect::showCursor() { - if (isMouseHidden) { - disconnect(effects, &EffectsHandler::cursorShapeChanged, this, &ZoomEffect::markCursorTextureDirty); - // show the previously hidden mouse-pointer again and free the loaded texture/picture. + if (m_cursorHidden) { + m_cursorItem.reset(); + m_cursorHidden = false; effects->showCursor(); - m_cursorTexture.reset(); - isMouseHidden = false; } } @@ -195,16 +173,18 @@ void ZoomEffect::hideCursor() if (mouseTracking == MouseTrackingProportional && mousePointer == MousePointerKeep) { return; // don't replace the actual cursor by a static image for no reason. } - if (!isMouseHidden) { - // try to load the cursor-theme into a OpenGL texture and if successful then hide the mouse-pointer - GLTexture *texture = nullptr; - if (effects->isOpenGLCompositing()) { - texture = ensureCursorTexture(); - } - if (texture) { - effects->hideCursor(); - connect(effects, &EffectsHandler::cursorShapeChanged, this, &ZoomEffect::markCursorTextureDirty); - isMouseHidden = true; + if (!m_cursorHidden) { + effects->hideCursor(); + m_cursorHidden = true; + + if (mousePointer == MousePointerKeep || mousePointer == MousePointerScale) { + Cursor *cursor = Cursors::self()->mouse(); + m_cursorItem = std::make_unique(effects->scene()); + m_cursorItem->setParentItem(effects->scene()->overlayItem()); + m_cursorItem->setPosition(cursor->pos()); + connect(cursor, &Cursor::posChanged, m_cursorItem.get(), [this, cursor]() { + m_cursorItem->setPosition(cursor->pos()); + }); } } } @@ -264,6 +244,9 @@ void ZoomEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseco showCursor(); } else { hideCursor(); + if (mousePointer == MousePointerScale) { + m_cursorItem->setTransform(QTransform::fromScale(zoom, zoom)); + } } effects->prePaintScreen(data, presentTime); @@ -402,34 +385,6 @@ void ZoomEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewp offscreen.texture->render(offscreen.viewport.size() * scale); } ShaderManager::instance()->popShader(); - - if (mousePointer != MousePointerHide) { - // Draw the mouse-texture at the position matching to zoomed-in image of the desktop. Hiding the - // previous mouse-cursor and drawing our own fake mouse-cursor is needed to be able to scale the - // mouse-cursor up and to re-position those mouse-cursor to match to the chosen zoom-level. - - GLTexture *cursorTexture = ensureCursorTexture(); - if (cursorTexture) { - const auto cursor = effects->cursorImage(); - QSizeF cursorSize = QSizeF(cursor.image().size()) / cursor.image().devicePixelRatio(); - if (mousePointer == MousePointerScale) { - cursorSize *= zoom; - } - - const QPointF p = (effects->cursorPos() - cursor.hotSpot()) * zoom + QPoint(xTranslation, yTranslation); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - auto s = ShaderManager::instance()->pushShader(ShaderTrait::MapTexture | ShaderTrait::TransformColorspace); - s->setColorspaceUniformsFromSRGB(renderTarget.colorDescription()); - QMatrix4x4 mvp = viewport.projectionMatrix(); - mvp.translate(p.x() * scale, p.y() * scale); - s->setUniform(GLShader::Mat4Uniform::ModelViewProjectionMatrix, mvp); - cursorTexture->render(cursorSize * scale); - ShaderManager::instance()->popShader(); - glDisable(GL_BLEND); - } - } } void ZoomEffect::postPaintScreen() diff --git a/src/plugins/zoom/zoom.h b/src/plugins/zoom/zoom.h index 94dff2c7f9..6bd1544c41 100644 --- a/src/plugins/zoom/zoom.h +++ b/src/plugins/zoom/zoom.h @@ -23,6 +23,7 @@ namespace KWin class ZoomAccessibilityIntegration; #endif +class CursorItem; class GLFramebuffer; class GLTexture; class GLVertexBuffer; @@ -96,9 +97,7 @@ private: QRect viewport; }; - GLTexture *ensureCursorTexture(); OffscreenData *ensureOffscreenData(const RenderTarget &renderTarget, const RenderViewport &viewport, Output *screen); - void markCursorTextureDirty(); #if HAVE_ACCESSIBILITY ZoomAccessibilityIntegration *m_accessibilityIntegration = nullptr; @@ -127,9 +126,8 @@ private: QPoint prevPoint; QTime lastMouseEvent; QTime lastFocusEvent; - std::unique_ptr m_cursorTexture; - bool m_cursorTextureDirty = false; - bool isMouseHidden; + std::unique_ptr m_cursorItem; + bool m_cursorHidden = false; QTimeLine timeline; int xMove, yMove; double moveFactor;