KWin
Loading...
Searching...
No Matches
zoom.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
6 SPDX-FileCopyrightText: 2010 Sebastian Sauer <sebsauer@kdab.com>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10
11#include "zoom.h"
12// KConfigSkeleton
13#include "zoomconfig.h"
14
15#if HAVE_ACCESSIBILITY
17#endif
18
19#include <KConfigGroup>
20#include <KGlobalAccel>
21#include <KLocalizedString>
22#include <QAction>
23#include <QStyle>
24#include <QVector2D>
25#include <kstandardaction.h>
26
27#include "core/rendertarget.h"
28#include "core/renderviewport.h"
30#include "opengl/glutils.h"
31
32namespace KWin
33{
34
36 : Effect()
37 , zoom(1)
38 , target_zoom(1)
39 , polling(false)
40 , zoomFactor(1.25)
41 , mouseTracking(MouseTrackingProportional)
42 , mousePointer(MousePointerScale)
43 , focusDelay(350) // in milliseconds
44 , isMouseHidden(false)
45 , xMove(0)
46 , yMove(0)
47 , moveFactor(20.0)
48 , lastPresentTime(std::chrono::milliseconds::zero())
49{
50 ZoomConfig::instance(effects->config());
51 QAction *a = nullptr;
52 a = KStandardAction::zoomIn(this, SLOT(zoomIn()), this);
53 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_Plus) << (Qt::META | Qt::Key_Equal));
54 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_Plus) << (Qt::META | Qt::Key_Equal));
55 effects->registerAxisShortcut(Qt::ControlModifier | Qt::MetaModifier, PointerAxisDown, a);
56
57 a = KStandardAction::zoomOut(this, SLOT(zoomOut()), this);
58 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_Minus));
59 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_Minus));
60 effects->registerAxisShortcut(Qt::ControlModifier | Qt::MetaModifier, PointerAxisUp, a);
61
62 a = KStandardAction::actualSize(this, SLOT(actualSize()), this);
63 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_0));
64 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_0));
65
66 a = new QAction(this);
67 a->setObjectName(QStringLiteral("MoveZoomLeft"));
68 a->setText(i18n("Move Zoomed Area to Left"));
69 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>());
70 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>());
71 connect(a, &QAction::triggered, this, &ZoomEffect::moveZoomLeft);
72
73 a = new QAction(this);
74 a->setObjectName(QStringLiteral("MoveZoomRight"));
75 a->setText(i18n("Move Zoomed Area to Right"));
76 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>());
77 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>());
78 connect(a, &QAction::triggered, this, &ZoomEffect::moveZoomRight);
79
80 a = new QAction(this);
81 a->setObjectName(QStringLiteral("MoveZoomUp"));
82 a->setText(i18n("Move Zoomed Area Upwards"));
83 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>());
84 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>());
85 connect(a, &QAction::triggered, this, &ZoomEffect::moveZoomUp);
86
87 a = new QAction(this);
88 a->setObjectName(QStringLiteral("MoveZoomDown"));
89 a->setText(i18n("Move Zoomed Area Downwards"));
90 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>());
91 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>());
92 connect(a, &QAction::triggered, this, &ZoomEffect::moveZoomDown);
93
94 // TODO: these two actions don't belong into the effect. They need to be moved into KWin core
95 a = new QAction(this);
96 a->setObjectName(QStringLiteral("MoveMouseToFocus"));
97 a->setText(i18n("Move Mouse to Focus"));
98 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_F5));
99 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_F5));
100 connect(a, &QAction::triggered, this, &ZoomEffect::moveMouseToFocus);
101
102 a = new QAction(this);
103 a->setObjectName(QStringLiteral("MoveMouseToCenter"));
104 a->setText(i18n("Move Mouse to Center"));
105 KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_F6));
106 KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_F6));
107 connect(a, &QAction::triggered, this, &ZoomEffect::moveMouseToCenter);
108
109 timeline.setDuration(350);
110 timeline.setFrameRange(0, 100);
111 connect(&timeline, &QTimeLine::frameChanged, this, &ZoomEffect::timelineFrameChanged);
112 connect(effects, &EffectsHandler::mouseChanged, this, &ZoomEffect::slotMouseChanged);
113 connect(effects, &EffectsHandler::windowAdded, this, &ZoomEffect::slotWindowAdded);
114 connect(effects, &EffectsHandler::screenRemoved, this, &ZoomEffect::slotScreenRemoved);
115
116#if HAVE_ACCESSIBILITY
117 if (!effects->waylandDisplay()) {
118 // on Wayland, the accessibility integration can cause KWin to hang
119 m_accessibilityIntegration = new ZoomAccessibilityIntegration(this);
120 connect(m_accessibilityIntegration, &ZoomAccessibilityIntegration::focusPointChanged, this, &ZoomEffect::moveFocus);
121 }
122#endif
123
124 const auto windows = effects->stackingOrder();
125 for (EffectWindow *w : windows) {
126 slotWindowAdded(w);
127 }
128
129 source_zoom = -1; // used to trigger initialZoom reading
131}
132
134{
135 // switch off and free resources
136 showCursor();
137 // Save the zoom value.
138 ZoomConfig::setInitialZoom(target_zoom);
139 ZoomConfig::self()->save();
140}
141
143{
144#if HAVE_ACCESSIBILITY
145 return m_accessibilityIntegration && m_accessibilityIntegration->isFocusTrackingEnabled();
146#else
147 return false;
148#endif
149}
150
152{
153#if HAVE_ACCESSIBILITY
154 return m_accessibilityIntegration && m_accessibilityIntegration->isTextCaretTrackingEnabled();
155#else
156 return false;
157#endif
158}
159
160GLTexture *ZoomEffect::ensureCursorTexture()
161{
162 if (!m_cursorTexture || m_cursorTextureDirty) {
163 m_cursorTexture.reset();
164 m_cursorTextureDirty = false;
165 const auto cursor = effects->cursorImage();
166 if (!cursor.image().isNull()) {
167 m_cursorTexture = GLTexture::upload(cursor.image());
168 if (!m_cursorTexture) {
169 return nullptr;
170 }
171 m_cursorTexture->setWrapMode(GL_CLAMP_TO_EDGE);
172 }
173 }
174 return m_cursorTexture.get();
175}
176
177void ZoomEffect::markCursorTextureDirty()
178{
179 m_cursorTextureDirty = true;
180}
181
182void ZoomEffect::showCursor()
183{
184 if (isMouseHidden) {
185 disconnect(effects, &EffectsHandler::cursorShapeChanged, this, &ZoomEffect::markCursorTextureDirty);
186 // show the previously hidden mouse-pointer again and free the loaded texture/picture.
188 m_cursorTexture.reset();
189 isMouseHidden = false;
190 }
191}
192
193void ZoomEffect::hideCursor()
194{
195 if (mouseTracking == MouseTrackingProportional && mousePointer == MousePointerKeep) {
196 return; // don't replace the actual cursor by a static image for no reason.
197 }
198 if (!isMouseHidden) {
199 // try to load the cursor-theme into a OpenGL texture and if successful then hide the mouse-pointer
200 GLTexture *texture = nullptr;
202 texture = ensureCursorTexture();
203 }
204 if (texture) {
206 connect(effects, &EffectsHandler::cursorShapeChanged, this, &ZoomEffect::markCursorTextureDirty);
207 isMouseHidden = true;
208 }
209 }
210}
211
212void ZoomEffect::reconfigure(ReconfigureFlags)
213{
214 ZoomConfig::self()->read();
215 // On zoom-in and zoom-out change the zoom by the defined zoom-factor.
216 zoomFactor = std::max(0.1, ZoomConfig::zoomFactor());
217 // Visibility of the mouse-pointer.
218 mousePointer = MousePointerType(ZoomConfig::mousePointer());
219 // Track moving of the mouse.
220 mouseTracking = MouseTrackingType(ZoomConfig::mouseTracking());
221#if HAVE_ACCESSIBILITY
222 if (m_accessibilityIntegration) {
223 // Enable tracking of the focused location.
224 m_accessibilityIntegration->setFocusTrackingEnabled(ZoomConfig::enableFocusTracking());
225 // Enable tracking of the text caret.
226 m_accessibilityIntegration->setTextCaretTrackingEnabled(ZoomConfig::enableTextCaretTracking());
227 }
228#endif
229 // The time in milliseconds to wait before a focus-event takes away a mouse-move.
230 focusDelay = std::max(uint(0), ZoomConfig::focusDelay());
231 // The factor the zoom-area will be moved on touching an edge on push-mode or using the navigation KAction's.
232 moveFactor = std::max(0.1, ZoomConfig::moveFactor());
233 if (source_zoom < 0) {
234 // Load the saved zoom value.
235 source_zoom = 1.0;
236 target_zoom = ZoomConfig::initialZoom();
237 if (target_zoom > 1.0) {
238 zoomIn(target_zoom);
239 }
240 } else {
241 source_zoom = 1.0;
242 }
243}
244
245void ZoomEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
246{
247 if (zoom != target_zoom) {
248 int time = 0;
249 if (lastPresentTime.count()) {
250 time = (presentTime - lastPresentTime).count();
251 }
252 lastPresentTime = presentTime;
253
254 const float zoomDist = std::abs(target_zoom - source_zoom);
255 if (target_zoom > zoom) {
256 zoom = std::min(zoom + ((zoomDist * time) / animationTime(150 * zoomFactor)), target_zoom);
257 } else {
258 zoom = std::max(zoom - ((zoomDist * time) / animationTime(150 * zoomFactor)), target_zoom);
259 }
260 }
261
262 if (zoom == 1.0) {
263 showCursor();
264 } else {
265 hideCursor();
266 }
267
268 effects->prePaintScreen(data, presentTime);
269}
270
271ZoomEffect::OffscreenData *ZoomEffect::ensureOffscreenData(const RenderTarget &renderTarget, const RenderViewport &viewport, Output *screen)
272{
273 const QRect rect = viewport.renderRect().toRect();
274 const qreal devicePixelRatio = viewport.scale();
275 const QSize nativeSize = (viewport.renderRect().size() * devicePixelRatio).toSize();
276
277 OffscreenData &data = m_offscreenData[effects->waylandDisplay() ? screen : nullptr];
278 data.viewport = rect;
279
280 const GLenum textureFormat = renderTarget.colorDescription() == ColorDescription::sRGB ? GL_RGBA8 : GL_RGBA16F;
281 if (!data.texture || data.texture->size() != nativeSize || data.texture->internalFormat() != textureFormat) {
282 data.texture = GLTexture::allocate(textureFormat, nativeSize);
283 if (!data.texture) {
284 return nullptr;
285 }
286 data.texture->setFilter(GL_LINEAR);
287 data.texture->setWrapMode(GL_CLAMP_TO_EDGE);
288 data.framebuffer = std::make_unique<GLFramebuffer>(data.texture.get());
289 }
290
291 return &data;
292}
293
294void ZoomEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
295{
296 OffscreenData *offscreenData = ensureOffscreenData(renderTarget, viewport, screen);
297 if (!offscreenData) {
298 return;
299 }
300
301 // Render the scene in an offscreen texture and then upscale it.
302 RenderTarget offscreenRenderTarget(offscreenData->framebuffer.get(), renderTarget.colorDescription());
303 RenderViewport offscreenViewport(viewport.renderRect(), viewport.scale(), offscreenRenderTarget);
304 GLFramebuffer::pushFramebuffer(offscreenData->framebuffer.get());
305 effects->paintScreen(offscreenRenderTarget, offscreenViewport, mask, region, screen);
307
308 const QSize screenSize = effects->virtualScreenSize();
309 const auto scale = viewport.scale();
310
311 // mouse-tracking allows navigation of the zoom-area using the mouse.
312 qreal xTranslation = 0;
313 qreal yTranslation = 0;
314 switch (mouseTracking) {
315 case MouseTrackingProportional:
316 xTranslation = -int(cursorPoint.x() * (zoom - 1.0));
317 yTranslation = -int(cursorPoint.y() * (zoom - 1.0));
318 prevPoint = cursorPoint;
319 break;
320 case MouseTrackingCentred:
321 prevPoint = cursorPoint;
322 // fall through
323 case MouseTrackingDisabled:
324 xTranslation = std::min(0, std::max(int(screenSize.width() - screenSize.width() * zoom), int(screenSize.width() / 2 - prevPoint.x() * zoom)));
325 yTranslation = std::min(0, std::max(int(screenSize.height() - screenSize.height() * zoom), int(screenSize.height() / 2 - prevPoint.y() * zoom)));
326 break;
327 case MouseTrackingPush: {
328 // touching an edge of the screen moves the zoom-area in that direction.
329 int x = cursorPoint.x() * zoom - prevPoint.x() * (zoom - 1.0);
330 int y = cursorPoint.y() * zoom - prevPoint.y() * (zoom - 1.0);
331 int threshold = 4;
332 xMove = yMove = 0;
333 if (x < threshold) {
334 xMove = (x - threshold) / zoom;
335 } else if (x + threshold > screenSize.width()) {
336 xMove = (x + threshold - screenSize.width()) / zoom;
337 }
338 if (y < threshold) {
339 yMove = (y - threshold) / zoom;
340 } else if (y + threshold > screenSize.height()) {
341 yMove = (y + threshold - screenSize.height()) / zoom;
342 }
343 if (xMove) {
344 prevPoint.setX(std::max(0, std::min(screenSize.width(), prevPoint.x() + xMove)));
345 }
346 if (yMove) {
347 prevPoint.setY(std::max(0, std::min(screenSize.height(), prevPoint.y() + yMove)));
348 }
349 xTranslation = -int(prevPoint.x() * (zoom - 1.0));
350 yTranslation = -int(prevPoint.y() * (zoom - 1.0));
351 break;
352 }
353 }
354
355 // use the focusPoint if focus tracking is enabled
357 bool acceptFocus = true;
358 if (mouseTracking != MouseTrackingDisabled && focusDelay > 0) {
359 // Wait some time for the mouse before doing the switch. This serves as threshold
360 // to prevent the focus from jumping around to much while working with the mouse.
361 const int msecs = lastMouseEvent.msecsTo(lastFocusEvent);
362 acceptFocus = msecs > focusDelay;
363 }
364 if (acceptFocus) {
365 xTranslation = -int(focusPoint.x() * (zoom - 1.0));
366 yTranslation = -int(focusPoint.y() * (zoom - 1.0));
367 prevPoint = focusPoint;
368 }
369 }
370
371 // Render transformed offscreen texture.
372 glClearColor(0.0, 0.0, 0.0, 0.0);
373 glClear(GL_COLOR_BUFFER_BIT);
374
376 for (auto &[screen, offscreen] : m_offscreenData) {
377 QMatrix4x4 matrix;
378 matrix.translate(xTranslation * scale, yTranslation * scale);
379 matrix.scale(zoom, zoom);
380 matrix.translate(offscreen.viewport.x() * scale, offscreen.viewport.y() * scale);
381
383
384 offscreen.texture->render(offscreen.viewport.size() * scale);
385 }
387
388 if (mousePointer != MousePointerHide) {
389 // Draw the mouse-texture at the position matching to zoomed-in image of the desktop. Hiding the
390 // previous mouse-cursor and drawing our own fake mouse-cursor is needed to be able to scale the
391 // mouse-cursor up and to re-position those mouse-cursor to match to the chosen zoom-level.
392
393 GLTexture *cursorTexture = ensureCursorTexture();
394 if (cursorTexture) {
395 const auto cursor = effects->cursorImage();
396 QSizeF cursorSize = QSizeF(cursor.image().size()) / cursor.image().devicePixelRatio();
397 if (mousePointer == MousePointerScale) {
398 cursorSize *= zoom;
399 }
400
401 const QPointF p = (effects->cursorPos() - cursor.hotSpot()) * zoom + QPoint(xTranslation, yTranslation);
402
403 glEnable(GL_BLEND);
404 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
407 QMatrix4x4 mvp = viewport.projectionMatrix();
408 mvp.translate(p.x() * scale, p.y() * scale);
410 cursorTexture->render(cursorSize * scale);
412 glDisable(GL_BLEND);
413 }
414 }
415}
416
418{
419 if (zoom == target_zoom) {
420 lastPresentTime = std::chrono::milliseconds::zero();
421 }
422
423 if (zoom == 1.0 || zoom != target_zoom) {
424 // Either animation is running or the zoom effect has stopped.
426 }
427
429}
430
431void ZoomEffect::zoomIn(double to)
432{
433 source_zoom = zoom;
434 if (to < 0.0) {
435 target_zoom *= zoomFactor;
436 } else {
437 target_zoom = to;
438 }
439 if (!polling) {
440 polling = true;
442 }
443 cursorPoint = effects->cursorPos().toPoint();
444 if (mouseTracking == MouseTrackingDisabled) {
445 prevPoint = cursorPoint;
446 }
448}
449
450void ZoomEffect::zoomOut()
451{
452 source_zoom = zoom;
453 target_zoom /= zoomFactor;
454 if ((zoomFactor > 1 && target_zoom < 1.01) || (zoomFactor < 1 && target_zoom > 0.99)) {
455 target_zoom = 1;
456 if (polling) {
457 polling = false;
459 }
460 }
461 if (mouseTracking == MouseTrackingDisabled) {
462 prevPoint = effects->cursorPos().toPoint();
463 }
465}
466
467void ZoomEffect::actualSize()
468{
469 source_zoom = zoom;
470 target_zoom = 1;
471 if (polling) {
472 polling = false;
474 }
476}
477
478void ZoomEffect::timelineFrameChanged(int /* frame */)
479{
480 const QSize screenSize = effects->virtualScreenSize();
481 prevPoint.setX(std::max(0, std::min(screenSize.width(), prevPoint.x() + xMove)));
482 prevPoint.setY(std::max(0, std::min(screenSize.height(), prevPoint.y() + yMove)));
483 cursorPoint = prevPoint;
485}
486
487void ZoomEffect::moveZoom(int x, int y)
488{
489 if (timeline.state() == QTimeLine::Running) {
490 timeline.stop();
491 }
492
493 const QSize screenSize = effects->virtualScreenSize();
494 if (x < 0) {
495 xMove = -std::max(1.0, screenSize.width() / zoom / moveFactor);
496 } else if (x > 0) {
497 xMove = std::max(1.0, screenSize.width() / zoom / moveFactor);
498 } else {
499 xMove = 0;
500 }
501
502 if (y < 0) {
503 yMove = -std::max(1.0, screenSize.height() / zoom / moveFactor);
504 } else if (y > 0) {
505 yMove = std::max(1.0, screenSize.height() / zoom / moveFactor);
506 } else {
507 yMove = 0;
508 }
509
510 timeline.start();
511}
512
513void ZoomEffect::moveZoomLeft()
514{
515 moveZoom(-1, 0);
516}
517
518void ZoomEffect::moveZoomRight()
519{
520 moveZoom(1, 0);
521}
522
523void ZoomEffect::moveZoomUp()
524{
525 moveZoom(0, -1);
526}
527
528void ZoomEffect::moveZoomDown()
529{
530 moveZoom(0, 1);
531}
532
533void ZoomEffect::moveMouseToFocus()
534{
535 QCursor::setPos(focusPoint.x(), focusPoint.y());
536}
537
538void ZoomEffect::moveMouseToCenter()
539{
540 const QRect r = effects->virtualScreenGeometry();
541 QCursor::setPos(r.x() + r.width() / 2, r.y() + r.height() / 2);
542}
543
544void ZoomEffect::slotMouseChanged(const QPointF &pos, const QPointF &old, Qt::MouseButtons,
545 Qt::MouseButtons, Qt::KeyboardModifiers, Qt::KeyboardModifiers)
546{
547 if (zoom == 1.0) {
548 return;
549 }
550 cursorPoint = pos.toPoint();
551 if (pos != old) {
552 lastMouseEvent = QTime::currentTime();
554 }
555}
556
557void ZoomEffect::slotWindowAdded(EffectWindow *w)
558{
559 connect(w, &EffectWindow::windowDamaged, this, &ZoomEffect::slotWindowDamaged);
560}
561
562void ZoomEffect::slotWindowDamaged()
563{
564 if (zoom != 1.0) {
566 }
567}
568
569void ZoomEffect::slotScreenRemoved(Output *screen)
570{
571 if (auto it = m_offscreenData.find(screen); it != m_offscreenData.end()) {
573 m_offscreenData.erase(it);
574 }
575}
576
577void ZoomEffect::moveFocus(const QPoint &point)
578{
579 if (zoom == 1.0) {
580 return;
581 }
582 focusPoint = point;
583 lastFocusEvent = QTime::currentTime();
585}
586
588{
589 return zoom != 1.0 || zoom != target_zoom;
590}
591
593{
594 return 10;
595}
596
598{
599 return zoomFactor;
600}
601
603{
604 return mousePointer;
605}
606
608{
609 return mouseTracking;
610}
611
613{
614 return focusDelay;
615}
616
618{
619 return moveFactor;
620}
621
623{
624 return target_zoom;
625}
626
627} // namespace
628
629#include "moc_zoom.cpp"
static const ColorDescription sRGB
Definition colorspace.h:132
Base class for all KWin effects.
Definition effect.h:535
Representation of a window used by/for Effect classes.
void windowDamaged(KWin::EffectWindow *w)
Display * waylandDisplay() const
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
void screenRemoved(KWin::Output *screen)
QList< EffectWindow * > stackingOrder
bool makeOpenGLContextCurrent()
Makes the OpenGL compositing context current.
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action)
Registers a global axis shortcut with the provided action.
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
bool isOpenGLCompositing() const
Whether the Compositor is OpenGL based (either GL 1 or 2).
void mouseChanged(const QPointF &pos, const QPointF &oldpos, Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons, Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers)
PlatformCursorImage cursorImage() const
KSharedConfigPtr config() const
void windowAdded(KWin::EffectWindow *w)
Q_SCRIPTABLE void addRepaintFull()
static GLFramebuffer * popFramebuffer()
static void pushFramebuffer(GLFramebuffer *fbo)
bool setColorspaceUniformsFromSRGB(const ColorDescription &dst)
Definition glshader.cpp:457
bool setUniform(const char *name, float value)
Definition glshader.cpp:301
static std::unique_ptr< GLTexture > allocate(GLenum internalFormat, const QSize &size, int levels=1)
static std::unique_ptr< GLTexture > upload(const QImage &image)
void render(const QSizeF &size)
QImage image() const
Definition globals.h:217
const ColorDescription & colorDescription() const
QMatrix4x4 projectionMatrix() const
QRectF renderRect() const
static ShaderManager * instance()
GLShader * pushShader(ShaderTraits traits)
void focusPointChanged(const QPoint &point)
~ZoomEffect() override
Definition zoom.cpp:133
qreal zoomFactor
Definition zoom.h:34
qreal configuredMoveFactor() const
Definition zoom.cpp:617
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen) override
Definition zoom.cpp:294
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override
Definition zoom.cpp:245
void reconfigure(ReconfigureFlags flags) override
Definition zoom.cpp:212
int focusDelay
Definition zoom.h:39
qreal targetZoom
Definition zoom.h:41
int configuredFocusDelay() const
Definition zoom.cpp:612
qreal moveFactor
Definition zoom.h:40
int configuredMousePointer() const
Definition zoom.cpp:602
int configuredMouseTracking() const
Definition zoom.cpp:607
int mousePointer
Definition zoom.h:35
int requestedEffectChainPosition() const override
Definition zoom.cpp:592
bool isActive() const override
Definition zoom.cpp:587
int mouseTracking
Definition zoom.h:36
void postPaintScreen() override
Definition zoom.cpp:417
bool isFocusTrackingEnabled() const
Definition zoom.cpp:142
bool isTextCaretTrackingEnabled() const
Definition zoom.cpp:151
qreal configuredZoomFactor() const
Definition zoom.cpp:597
static double animationTime(const KConfigGroup &cfg, const QString &key, int defaultTime)
Definition effect.cpp:483
@ ReconfigureAll
Definition effect.h:601
@ PointerAxisUp
Definition globals.h:105
@ PointerAxisDown
Definition globals.h:106
EffectsHandler * effects