Skip to content

Commit

Permalink
Fixes mouse scroll wheel events going into the wrong direction if Alt…
Browse files Browse the repository at this point in the history
… modifier was pressed at the same time

Signed-off-by: Christian Parpart <christian@parpart.family>
  • Loading branch information
christianparpart committed Jan 7, 2024
1 parent 5592672 commit 62460c5
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 51 deletions.
1 change: 1 addition & 0 deletions metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
<ul>
<li>Fixes `scripts/install-deps.sh` for openSuSE (Tumbleweed) to install the correct dependencies.</li>
<li>Fixes missing dependencies for release .deb packages (#1397).</li>
<li>Fixes mouse scroll wheel events going into the wrong direction if `Alt` modifier was pressed at the same time (#394).</li>
</ul>
</description>
</release>
Expand Down
112 changes: 61 additions & 51 deletions src/contour/helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,30 +118,43 @@ namespace
PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } };
}

int mouseWheelDelta(QWheelEvent* event) noexcept
QPoint transposed(QPoint p) noexcept
{
#if 1
// FIXME: Temporarily addressing a really bad Qt implementation detail
// as tracked here:
// https://github.com/contour-terminal/contour/issues/394
if (event->pixelDelta().y())
return event->pixelDelta().y();
if (event->angleDelta().y())
return event->angleDelta().y();

return 0;
#else
// switch (event->orientation())
// {
// case Qt::Orientation::Horizontal:
// return event->pixelDelta().x() ? event->pixelDelta().x()
// : event->angleDelta().x();
// case Qt::Orientation::Vertical:
// return event->pixelDelta().y() ? event->pixelDelta().y()
// : event->angleDelta().y();
// }
return event->angleDelta().y();
#endif
// NB: We cannot use QPoint::transposed(), because it is not available in older Qt versions.
return QPoint { p.y(), p.x() };
}

void sendWheelEventForDelta(QPoint const& delta,
PixelCoordinate const& position,
vtbackend::Modifiers modifiers,
TerminalSession& session)
{
using VTMouseButton = vtbackend::MouseButton;

session.addScrollX(delta.x());
session.addScrollY(delta.y());

inputLog()("[{}] Accumulate scroll with current value {}",
modifiers,
crispy::point { session.getScrollX(), session.getScrollY() });

if (std::abs(session.getScrollX()) > unbox<int>(session.terminal().cellPixelSize().width))
{
session.sendMousePressEvent(modifiers,
session.getScrollX() > 0 ? VTMouseButton::WheelRight
: VTMouseButton::WheelLeft,
position);
session.resetScrollX();
}

if (std::abs(session.getScrollY()) > unbox<int>(session.terminal().cellPixelSize().height))
{
session.sendMousePressEvent(modifiers,
session.getScrollY() > 0 ? VTMouseButton::WheelUp
: VTMouseButton::WheelDown,
position);
session.resetScrollY();
}
}

} // namespace
Expand Down Expand Up @@ -415,40 +428,37 @@ bool sendKeyEvent(QKeyEvent* event, vtbackend::KeyboardEventType eventType, Term
void sendWheelEvent(QWheelEvent* event, TerminalSession& session)
{
using VTMouseButton = vtbackend::MouseButton;
using vtbackend::Modifier;

auto const xDelta = event->angleDelta().x() > 0 ? 1 : event->angleDelta().x() < 0 ? -1 : 0;
if (xDelta)
{
session.addScrollX(xDelta);
inputLog()("Accumulate x scroll with current value {} ", session.getScrollX());
}
if (std::abs(session.getScrollX()) > unbox<int>(session.terminal().cellPixelSize().width))
{
auto const modifier = makeModifiers(event->modifiers());
auto const button = session.getScrollX() > 0 ? VTMouseButton::WheelRight : VTMouseButton::WheelLeft;
session.resetScrollX();
auto const pixelPosition =
makeMousePixelPosition(event, session.profile().margins, session.contentScale());
auto const modifiers = makeModifiers(event->modifiers());

session.sendMousePressEvent(modifier, button, pixelPosition);
event->accept();
}
// NOTE: Qt is playing some weird games with the mouse wheel events, i.e. if Alt is pressed
// it will send horizontal wheel events instead of vertical ones. We need to compensate
// for that here.

auto const pixelDelta =
(modifiers & Modifier::Alt) ? transposed(event->pixelDelta()) : event->pixelDelta();

auto const numDegrees =
((modifiers & Modifier::Alt) ? transposed(event->angleDelta()) : event->angleDelta()) / 8;

auto const yDelta = mouseWheelDelta(event);
if (yDelta)
auto const pixelPosition =
makeMousePixelPosition(event, session.profile().margins, session.contentScale());

if (!pixelDelta.isNull())
{
session.addScrollY(yDelta);
inputLog()("Accumulate y scroll with current value {} ", session.getScrollY());
sendWheelEventForDelta(pixelDelta, pixelPosition, modifiers, session);
event->accept();
}
if (std::abs(session.getScrollY()) > unbox<int>(session.terminal().cellPixelSize().height))
else if (!numDegrees.isNull())
{
auto const modifier = makeModifiers(event->modifiers());
auto const button = session.getScrollY() > 0 ? VTMouseButton::WheelUp : VTMouseButton::WheelDown;
session.resetScrollY();
auto const pixelPosition =
makeMousePixelPosition(event, session.profile().margins, session.contentScale());

session.sendMousePressEvent(modifier, button, pixelPosition);
auto const numSteps = numDegrees / 15;
auto const cellSize = session.terminal().cellPixelSize();
auto const scaledDelta = QPoint {
numSteps.x() * unbox<int>(cellSize.width),
numSteps.y() * unbox<int>(cellSize.height),
};
sendWheelEventForDelta(scaledDelta, pixelPosition, modifiers, session);
event->accept();
}
}
Expand Down

0 comments on commit 62460c5

Please sign in to comment.