Merge pull request #4462 from synergy/pr-jpmcmu-tripple-click-fix
Double click breaks dragging and tripple click on Mac #3784
This commit is contained in:
commit
0008ad2778
|
@ -105,8 +105,8 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso
|
||||||
m_activeModifierHotKeyMask(0),
|
m_activeModifierHotKeyMask(0),
|
||||||
m_eventTapPort(nullptr),
|
m_eventTapPort(nullptr),
|
||||||
m_eventTapRLSR(nullptr),
|
m_eventTapRLSR(nullptr),
|
||||||
m_lastSingleClick(0),
|
m_lastClickTime(0),
|
||||||
m_lastDoubleClick(0),
|
m_clickState(1),
|
||||||
m_lastSingleClickXCursor(0),
|
m_lastSingleClickXCursor(0),
|
||||||
m_lastSingleClickYCursor(0),
|
m_lastSingleClickYCursor(0),
|
||||||
m_autoShowHideCursor(autoShowHideCursor),
|
m_autoShowHideCursor(autoShowHideCursor),
|
||||||
|
@ -524,6 +524,10 @@ OSXScreen::postMouseEvent(CGPoint& pos) const
|
||||||
}
|
}
|
||||||
|
|
||||||
CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, button);
|
CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, button);
|
||||||
|
|
||||||
|
// Dragging events also need the click state
|
||||||
|
CGEventSetIntegerValueField(event, kCGMouseEventClickState, m_clickState);
|
||||||
|
|
||||||
CGEventPost(kCGHIDEventTap, event);
|
CGEventPost(kCGHIDEventTap, event);
|
||||||
|
|
||||||
CFRelease(event);
|
CFRelease(event);
|
||||||
|
@ -532,20 +536,6 @@ OSXScreen::postMouseEvent(CGPoint& pos) const
|
||||||
void
|
void
|
||||||
OSXScreen::fakeMouseButton(ButtonID id, bool press)
|
OSXScreen::fakeMouseButton(ButtonID id, bool press)
|
||||||
{
|
{
|
||||||
NXEventHandle handle = NXOpenEventStatus();
|
|
||||||
double clickTime = NXClickTime(handle);
|
|
||||||
|
|
||||||
if ((ARCH->time() - m_lastDoubleClick) <= clickTime) {
|
|
||||||
// drop all down and up fakes immedately after a double click.
|
|
||||||
// TODO: perhaps there is a better way to do this, usually in
|
|
||||||
// finder, if you tripple click a folder, it will open it and
|
|
||||||
// then select a folder under the cursor -- and perhaps other
|
|
||||||
// strange behaviour might happen?
|
|
||||||
LOG((CLOG_DEBUG1 "dropping mouse button %s",
|
|
||||||
press ? "press" : "release"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buttons are indexed from one, but the button down array is indexed from zero
|
// Buttons are indexed from one, but the button down array is indexed from zero
|
||||||
UInt32 index = id - kButtonLeft;
|
UInt32 index = id - kButtonLeft;
|
||||||
if (index >= NumButtonIDs) {
|
if (index >= NumButtonIDs) {
|
||||||
|
@ -569,61 +559,47 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press)
|
||||||
// since we don't have double click distance in NX APIs
|
// since we don't have double click distance in NX APIs
|
||||||
// we define our own defaults.
|
// we define our own defaults.
|
||||||
const double maxDiff = sqrt(2) + 0.0001;
|
const double maxDiff = sqrt(2) + 0.0001;
|
||||||
|
|
||||||
if (press && (id == kButtonLeft) &&
|
|
||||||
((ARCH->time() - m_lastSingleClick) <= clickTime) &&
|
NXEventHandle handle = NXOpenEventStatus();
|
||||||
diff <= maxDiff) {
|
double clickTime = NXClickTime(handle);
|
||||||
|
|
||||||
LOG((CLOG_DEBUG1 "faking mouse left double click"));
|
// As long as the click is within the time window and distance window
|
||||||
|
// increase clickState (double click, triple click, etc)
|
||||||
// finder does not seem to detect double clicks from two separate
|
// This will allow for higher than triple click but the quartz documenation
|
||||||
// CGEventCreateMouseEvent calls. so, if we detect a double click we
|
// does not specify that this should be limited to triple click
|
||||||
// use CGEventSetIntegerValueField to tell the OS.
|
if(press) {
|
||||||
//
|
if((ARCH->time() - m_lastClickTime) <= clickTime && diff <= maxDiff){
|
||||||
// the caveat here is that findor will see this as a single click
|
m_clickState++;
|
||||||
// followed by a double click (even though there should be only a
|
}
|
||||||
// double click). this may cause weird behaviour in other apps.
|
else {
|
||||||
//
|
m_clickState = 1;
|
||||||
// for some reason using the old CGPostMouseEvent function, doesn't
|
}
|
||||||
// cause double clicks (though i'm sure it did work at some point).
|
|
||||||
|
m_lastClickTime = ARCH->time();
|
||||||
CGEventRef event = CGEventCreateMouseEvent(
|
}
|
||||||
NULL, kCGEventLeftMouseDown, pos, kCGMouseButtonLeft);
|
|
||||||
|
if(m_clickState == 1){
|
||||||
CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
|
m_lastSingleClickXCursor = m_xCursor;
|
||||||
m_buttonState.set(index, kMouseButtonDown);
|
m_lastSingleClickYCursor = m_yCursor;
|
||||||
CGEventPost(kCGHIDEventTap, event);
|
}
|
||||||
|
|
||||||
CGEventSetType(event, kCGEventLeftMouseUp);
|
EMouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp;
|
||||||
m_buttonState.set(index, kMouseButtonUp);
|
|
||||||
CGEventPost(kCGHIDEventTap, event);
|
LOG((CLOG_DEBUG1 "faking mouse button id: %d press: %s", id, press ? "pressed" : "released"));
|
||||||
|
|
||||||
CFRelease(event);
|
MouseButtonEventMapType thisButtonMap = MouseButtonEventMap[index];
|
||||||
|
CGEventType type = thisButtonMap[state];
|
||||||
m_lastDoubleClick = ARCH->time();
|
|
||||||
}
|
CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, index);
|
||||||
else {
|
|
||||||
|
CGEventSetIntegerValueField(event, kCGMouseEventClickState, m_clickState);
|
||||||
// ... otherwise, perform a single press or release as normal.
|
|
||||||
|
m_buttonState.set(index, state);
|
||||||
EMouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp;
|
CGEventPost(kCGHIDEventTap, event);
|
||||||
|
|
||||||
LOG((CLOG_DEBUG1 "faking mouse button id: %d press: %s", id, press ? "pressed" : "released"));
|
CFRelease(event);
|
||||||
|
|
||||||
MouseButtonEventMapType thisButtonMap = MouseButtonEventMap[index];
|
|
||||||
CGEventType type = thisButtonMap[state];
|
|
||||||
|
|
||||||
CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, index);
|
|
||||||
|
|
||||||
m_buttonState.set(index, state);
|
|
||||||
CGEventPost(kCGHIDEventTap, event);
|
|
||||||
|
|
||||||
CFRelease(event);
|
|
||||||
|
|
||||||
m_lastSingleClick = ARCH->time();
|
|
||||||
m_lastSingleClickXCursor = m_xCursor;
|
|
||||||
m_lastSingleClickYCursor = m_yCursor;
|
|
||||||
}
|
|
||||||
if (!press && (id == kButtonLeft)) {
|
if (!press && (id == kButtonLeft)) {
|
||||||
if (m_fakeDraggingStarted) {
|
if (m_fakeDraggingStarted) {
|
||||||
m_getDropTargetThread = new Thread(new TMethodJob<OSXScreen>(
|
m_getDropTargetThread = new Thread(new TMethodJob<OSXScreen>(
|
||||||
|
|
|
@ -335,8 +335,8 @@ private:
|
||||||
CFRunLoopSourceRef m_eventTapRLSR;
|
CFRunLoopSourceRef m_eventTapRLSR;
|
||||||
|
|
||||||
// for double click coalescing.
|
// for double click coalescing.
|
||||||
double m_lastSingleClick;
|
double m_lastClickTime;
|
||||||
double m_lastDoubleClick;
|
int m_clickState;
|
||||||
SInt32 m_lastSingleClickXCursor;
|
SInt32 m_lastSingleClickXCursor;
|
||||||
SInt32 m_lastSingleClickYCursor;
|
SInt32 m_lastSingleClickYCursor;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue