MacOSX Double / Triple Click Fix
This patch corrects issues with double click and adds triple click to MacOSX. Double click was functioning but double clicking and then dragging would not work.
This commit is contained in:
parent
ecd51d231b
commit
1bbd086a17
|
@ -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) {
|
||||||
|
@ -570,60 +560,46 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press)
|
||||||
// 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) &&
|
|
||||||
diff <= maxDiff) {
|
|
||||||
|
|
||||||
LOG((CLOG_DEBUG1 "faking mouse left double click"));
|
NXEventHandle handle = NXOpenEventStatus();
|
||||||
|
double clickTime = NXClickTime(handle);
|
||||||
|
|
||||||
// finder does not seem to detect double clicks from two separate
|
// As long as the click is within the time window and distance window
|
||||||
// CGEventCreateMouseEvent calls. so, if we detect a double click we
|
// increase clickState (double click, triple click, etc)
|
||||||
// use CGEventSetIntegerValueField to tell the OS.
|
// This will allow for higher than triple click but the quartz documenation
|
||||||
//
|
// does not specify that this should be limited to triple click
|
||||||
// the caveat here is that findor will see this as a single click
|
if(press) {
|
||||||
// followed by a double click (even though there should be only a
|
if((ARCH->time() - m_lastClickTime) <= clickTime && diff <= maxDiff){
|
||||||
// double click). this may cause weird behaviour in other apps.
|
m_clickState++;
|
||||||
//
|
}
|
||||||
// for some reason using the old CGPostMouseEvent function, doesn't
|
else {
|
||||||
// cause double clicks (though i'm sure it did work at some point).
|
m_clickState = 1;
|
||||||
|
}
|
||||||
|
|
||||||
CGEventRef event = CGEventCreateMouseEvent(
|
m_lastClickTime = ARCH->time();
|
||||||
NULL, kCGEventLeftMouseDown, pos, kCGMouseButtonLeft);
|
}
|
||||||
|
|
||||||
CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
|
if(m_clickState == 1){
|
||||||
m_buttonState.set(index, kMouseButtonDown);
|
m_lastSingleClickXCursor = m_xCursor;
|
||||||
CGEventPost(kCGHIDEventTap, event);
|
m_lastSingleClickYCursor = m_yCursor;
|
||||||
|
}
|
||||||
|
|
||||||
CGEventSetType(event, kCGEventLeftMouseUp);
|
EMouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp;
|
||||||
m_buttonState.set(index, kMouseButtonUp);
|
|
||||||
CGEventPost(kCGHIDEventTap, event);
|
|
||||||
|
|
||||||
CFRelease(event);
|
LOG((CLOG_DEBUG1 "faking mouse button id: %d press: %s", id, press ? "pressed" : "released"));
|
||||||
|
|
||||||
m_lastDoubleClick = ARCH->time();
|
MouseButtonEventMapType thisButtonMap = MouseButtonEventMap[index];
|
||||||
}
|
CGEventType type = thisButtonMap[state];
|
||||||
else {
|
|
||||||
|
|
||||||
// ... otherwise, perform a single press or release as normal.
|
CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, index);
|
||||||
|
|
||||||
EMouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp;
|
CGEventSetIntegerValueField(event, kCGMouseEventClickState, m_clickState);
|
||||||
|
|
||||||
LOG((CLOG_DEBUG1 "faking mouse button id: %d press: %s", id, press ? "pressed" : "released"));
|
m_buttonState.set(index, state);
|
||||||
|
CGEventPost(kCGHIDEventTap, event);
|
||||||
|
|
||||||
MouseButtonEventMapType thisButtonMap = MouseButtonEventMap[index];
|
CFRelease(event);
|
||||||
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