plugins/zoom: Port to CursorItem

This commit is contained in:
Vlad Zahorodnii 2024-01-20 23:54:28 +02:00
parent fe45c99e99
commit e40f632c9b
2 changed files with 24 additions and 71 deletions

View file

@ -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<CursorItem>(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()

View file

@ -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<GLTexture> m_cursorTexture;
bool m_cursorTextureDirty = false;
bool isMouseHidden;
std::unique_ptr<CursorItem> m_cursorItem;
bool m_cursorHidden = false;
QTimeLine timeline;
int xMove, yMove;
double moveFactor;