Accumulate scrolls less than supported scroll on XWindows

This fixes barrier case #67 and synergy case #5670.
This commit is contained in:
Povilas Kanapickas 2018-06-21 00:50:08 +03:00
parent 773a0081e3
commit 76c39aaf4e
2 changed files with 29 additions and 12 deletions

View File

@ -99,6 +99,7 @@ XWindowsScreen::XWindowsScreen(
IEventQueue* events) :
m_isPrimary(isPrimary),
m_mouseScrollDelta(mouseScrollDelta),
m_accumulatedScroll(0),
m_display(NULL),
m_root(None),
m_window(None),
@ -865,9 +866,11 @@ XWindowsScreen::fakeMouseWheel(SInt32, SInt32 yDelta) const
return;
}
int numEvents = accumulateMouseScroll(yDelta);
// choose button depending on rotation direction
const unsigned int xButton = mapButtonToX(static_cast<ButtonID>(
(yDelta >= 0) ? -1 : -2));
(numEvents >= 0) ? -1 : -2));
if (xButton == 0) {
// If we get here, then the XServer does not support the scroll
// wheel buttons, so send PageUp/PageDown keystrokes instead.
@ -886,20 +889,14 @@ XWindowsScreen::fakeMouseWheel(SInt32, SInt32 yDelta) const
return;
}
// now use absolute value of delta
if (yDelta < 0) {
yDelta = -yDelta;
}
if (yDelta < m_mouseScrollDelta) {
LOG((CLOG_WARN "Wheel scroll delta (%d) smaller than threshold (%d)", yDelta, m_mouseScrollDelta));
}
numEvents = std::abs(numEvents);
// send as many clicks as necessary
for (; yDelta >= m_mouseScrollDelta; yDelta -= m_mouseScrollDelta) {
for (; numEvents > 0; numEvents--) {
XTestFakeButtonEvent(m_display, xButton, True, CurrentTime);
XTestFakeButtonEvent(m_display, xButton, False, CurrentTime);
}
XFlush(m_display);
}
@ -1643,6 +1640,15 @@ XWindowsScreen::onMouseMove(const XMotionEvent& xmotion)
}
}
int
XWindowsScreen::accumulateMouseScroll(SInt32 yDelta) const
{
m_accumulatedScroll += yDelta;
int numEvents = m_accumulatedScroll / m_mouseScrollDelta;
m_accumulatedScroll -= numEvents * m_mouseScrollDelta;
return numEvents;
}
Cursor
XWindowsScreen::createBlankCursor() const
{

View File

@ -136,6 +136,10 @@ private:
void onMouseRelease(const XButtonEvent&);
void onMouseMove(const XMotionEvent&);
// Returns the number of scroll events needed after the current delta has
// been taken into account
int accumulateMouseScroll(SInt32 yDelta) const;
bool detectXI2();
#ifdef HAVE_XI2
void selectXIRawMotion();
@ -172,8 +176,15 @@ private:
// true if screen is being used as a primary screen, false otherwise
bool m_isPrimary;
// The size of a smallest supported scroll event, in points
int m_mouseScrollDelta;
// Accumulates scrolls of less than m_mouseScrollDelta across multiple
// scroll events. We dispatch a scroll event whenever the accumulated scroll
// becomes larger than m_mouseScrollDelta
mutable int m_accumulatedScroll;
Display* m_display;
Window m_root;
Window m_window;