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

View File

@ -136,6 +136,10 @@ private:
void onMouseRelease(const XButtonEvent&); void onMouseRelease(const XButtonEvent&);
void onMouseMove(const XMotionEvent&); 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(); bool detectXI2();
#ifdef HAVE_XI2 #ifdef HAVE_XI2
void selectXIRawMotion(); void selectXIRawMotion();
@ -172,8 +176,15 @@ private:
// true if screen is being used as a primary screen, false otherwise // true if screen is being used as a primary screen, false otherwise
bool m_isPrimary; bool m_isPrimary;
// The size of a smallest supported scroll event, in points
int m_mouseScrollDelta; 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; Display* m_display;
Window m_root; Window m_root;
Window m_window; Window m_window;