Fix zoom push mouse tracking on multi-monitor workspaces
Zoom push tracking now considers the layout of the user's monitors, accounting for situations where the monitor layout doesn't form a perfect rectangle. These changes help prevent the zoom area from being unable to reach certain areas of the workspace depending on which edge of which screen the user pushes against. One known issue is that, if the mouse moves too quickly, the zoom area can sometimes imperfectly track the movement. It will look the same as the original bug (areas of the screen will appear to be cut off/unreachable), but moving the mouse in the opposite direction a tiny bit snaps the zoom area back to where it should be. BUG: 467182 @teams/qa Heads-up that I'm very blind, and this is the first time I've ever contributed to a KDE project. I've tested the changes on my system and they fix the bug, but I want to make sure I didn't break anything in the process.
This commit is contained in:
parent
9e3e567592
commit
86f0d9914e
2 changed files with 39 additions and 13 deletions
|
@ -326,25 +326,42 @@ void ZoomEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewp
|
|||
break;
|
||||
case MouseTrackingPush: {
|
||||
// touching an edge of the screen moves the zoom-area in that direction.
|
||||
int x = cursorPoint.x() * zoom - prevPoint.x() * (zoom - 1.0);
|
||||
int y = cursorPoint.y() * zoom - prevPoint.y() * (zoom - 1.0);
|
||||
int threshold = 4;
|
||||
const int x = cursorPoint.x() * zoom - prevPoint.x() * (zoom - 1.0);
|
||||
const int y = cursorPoint.y() * zoom - prevPoint.y() * (zoom - 1.0);
|
||||
const int threshold = 4;
|
||||
const QRectF currScreen = effects->screenAt(QPoint(x, y))->geometry();
|
||||
|
||||
// bounds of the screen the cursor's on
|
||||
const int screenTop = currScreen.top();
|
||||
const int screenLeft = currScreen.left();
|
||||
const int screenRight = currScreen.right();
|
||||
const int screenBottom = currScreen.bottom();
|
||||
const int screenCenterX = currScreen.center().x();
|
||||
const int screenCenterY = currScreen.center().y();
|
||||
|
||||
// figure out whether we have adjacent displays in all 4 directions
|
||||
// We pan within the screen in directions where there are no adjacent screens.
|
||||
const bool adjacentLeft = screenExistsAt(QPoint(screenLeft - 1, screenCenterY));
|
||||
const bool adjacentRight = screenExistsAt(QPoint(screenRight + 1, screenCenterY));
|
||||
const bool adjacentTop = screenExistsAt(QPoint(screenCenterX, screenTop - 1));
|
||||
const bool adjacentBottom = screenExistsAt(QPoint(screenCenterX, screenBottom + 1));
|
||||
|
||||
xMove = yMove = 0;
|
||||
if (x < threshold) {
|
||||
xMove = (x - threshold) / zoom;
|
||||
} else if (x + threshold > screenSize.width()) {
|
||||
xMove = (x + threshold - screenSize.width()) / zoom;
|
||||
if (x < screenLeft + threshold && !adjacentLeft) {
|
||||
xMove = (x - threshold - screenLeft) / zoom;
|
||||
} else if (x > screenRight - threshold && !adjacentRight) {
|
||||
xMove = (x + threshold - screenRight) / zoom;
|
||||
}
|
||||
if (y < threshold) {
|
||||
yMove = (y - threshold) / zoom;
|
||||
} else if (y + threshold > screenSize.height()) {
|
||||
yMove = (y + threshold - screenSize.height()) / zoom;
|
||||
if (y < screenTop + threshold && !adjacentTop) {
|
||||
yMove = (y - threshold - screenTop) / zoom;
|
||||
} else if (y > screenBottom - threshold && !adjacentBottom) {
|
||||
yMove = (y + threshold - screenBottom) / zoom;
|
||||
}
|
||||
if (xMove) {
|
||||
prevPoint.setX(std::max(0, std::min(screenSize.width(), prevPoint.x() + xMove)));
|
||||
prevPoint.setX(prevPoint.x() + xMove);
|
||||
}
|
||||
if (yMove) {
|
||||
prevPoint.setY(std::max(0, std::min(screenSize.height(), prevPoint.y() + yMove)));
|
||||
prevPoint.setY(prevPoint.y() + yMove);
|
||||
}
|
||||
xTranslation = -int(prevPoint.x() * (zoom - 1.0));
|
||||
yTranslation = -int(prevPoint.y() * (zoom - 1.0));
|
||||
|
@ -624,6 +641,12 @@ qreal ZoomEffect::targetZoom() const
|
|||
return target_zoom;
|
||||
}
|
||||
|
||||
bool ZoomEffect::screenExistsAt(const QPoint &point) const
|
||||
{
|
||||
const Output *output = effects->screenAt(point);
|
||||
return output && output->geometry().contains(point);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "moc_zoom.cpp"
|
||||
|
|
|
@ -57,6 +57,9 @@ public:
|
|||
int configuredFocusDelay() const;
|
||||
qreal configuredMoveFactor() const;
|
||||
qreal targetZoom() const;
|
||||
|
||||
private:
|
||||
bool screenExistsAt(const QPoint &point) const;
|
||||
private Q_SLOTS:
|
||||
inline void zoomIn()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue