How to improve sensietivity of EventHandler to MouseDragged and MouseClicked events - wolfram-mathematica

Using EventHandler, I notice that sometimes it thinks I was dragging the mouse, even though I was just clicking it.
Here is a simple example
EventHandler[Graphics[Circle[{0, 0}, 1]],
"MouseClicked" :> Print["mouse clicked"],
"MouseDragged" :> Print["mouse being dragged"]
]
When I start clicking, even though I make sure the mouse is completely fixed and not moving, and I just keep clicking, and looking at the print messages, once in a while I see the dragging message come out.
I understand this can be sensitive to the mouse (but I have a good mouse), may be even the mouse pad, the OS, and any slight movement by hand, might cause this.
I wanted to ask if someone could try this and see if you notice this problem as well, and if someone knows some setting I can do in Mathematica to minimize this. I was looking for an option to EventHandler to set the time or delay as to when it decides the mouse being dragged, but see nothing.
Here is an example output of what I get on my system when I am just clicking after running the above code
mouse being dragged
mouse clicked
mouse clicked
mouse clicked
mouse clicked
mouse clicked
mouse clicked
mouse clicked
mouse clicked
mouse being dragged
mouse clicked
mouse clicked
This is on windows 7, Mathematica 8.0.1
Thanks

The following is not perfect, but seems to work better:
initMousePos = {-1, -1};
dragged = False;
EventHandler[
Dynamic#Graphics[Circle[{0, 0}, 1]],
"MouseDown" :>
(initMousePos = MousePosition["Graphics"]),
"MouseUp" :>
If[EuclideanDistance[MousePosition["Graphics"], initMousePos] < 2 10^-1,
Print["MouseClicked " <> ToString#MousePosition["Graphics"]],
Sequence ## {}],
"MouseDragged" :>
If[EuclideanDistance[MousePosition["Graphics"], initMousePos] > 2 10^-1,
Print["mouse being dragged " <>
ToString#MousePosition["Graphics"]], Sequence ## {}]]

Related

Change behavior of "control" and "shift" keys in OrbitControls

Using a scene with OrbitControls and as far as I can tell by default pressing the ctrl and shift key reverts the left and right mouse movements.
in my setup left mouse click rotatoes arounds the scene and right mouse clicks move around the 2d plain.
how can I disable the ctrl and shift key reversing that?
a hack I found is to edit the controls mouseButtons back when the keys are pressed:
this.controls.mouseButtons = {
LEFT: shouldSwitch ? 2 : 0,
MIDDLE: 1,
RIGHT: shouldSwitch ? 0 : 2,
};
using r141
OrbitControls does not allow disable the processing of "control", "shift" and "meta" keys. You would need a custom modification and remove the following two sections:
https://github.com/mrdoob/three.js/blob/f30599ed21818efbbffee6e923957616fd410016/examples/jsm/controls/OrbitControls.js#L905-L913
https://github.com/mrdoob/three.js/blob/f30599ed21818efbbffee6e923957616fd410016/examples/jsm/controls/OrbitControls.js#L927-L935
Changing the mouse button configuration (OrbitControls.mouseButtons) when one of the keys are pressed like suggested is also a valid solution.

How do I allow the Leap Motion to control my cursor in an OS X application?

So I have a game for Mac OS X built in cocos2D.
I'm using gestures to simulate keyboard commands to control my character and it works really well.
I submitted my game to the AirSpace store and it got rejected on the grounds that the Leap should be used to control my menus as well which is fair enough I guess.
Thing is for the life of me I cannot figure out how this is done. There are no examples out there to show me how to implement it and nothing in the SDK example that makes it clear either.
Does anyone have any examples they'd care to share, I only need it to hijack my cursor and allow a click when held over a button. I really didn't think something so complex would be needed on simply for basic menu navigation.
If this is a Mac only game you should have access to the Quartz event api. This is the easiest way to generate mouse events in OS X...
I would recommend simply tracking the palm (hand) position, and moving the cursor based on that.
This is how I do my palm tracking:
float handX = ([[hand palmPosition] x]);
float handY = (-[[hand palmPosition] y] + 150);
The "+ 150" is the number of millimetres above the Leap device, to use as the '0' location. From there you can move the cursor based on the hand offset from 0.
The function I use to move the cursor (using Quartz):
- (void)mouseEventWithType:(CGEventType)type loc:(CGPoint)loc deltaX:(float)dX deltaY:(float)dY
{
CGEventRef theEvent = CGEventCreateMouseEvent(NULL, type, loc, kCGMouseButtonLeft);
CGEventSetIntegerValueField(theEvent, kCGMouseEventDeltaX, dX);
CGEventSetIntegerValueField(theEvent, kCGMouseEventDeltaY, dY);
CGEventPost(kCGHIDEventTap, theEvent);
CFRelease(theEvent);
}
and an example function call:
[self mouseEventWithType:kCGEventMouseMoved loc:CGPointMake(newLocX, newLocY) deltaX:dX deltaY:dY];
This call will move the mouse. Basically you just pass the new location of the mouse, and the corresponding deltas, relative to the last cursor position.
I can provide more examples such as examples for getting mouse location, clicking the mouse, or even a full mouse moving program...
EDIT 1:
To handle click and drag with Quartz, you can call the same function as above only pass in kCGEventLeftMouseDown.
The catch is that in order to drag you cannot call the kCGEventMouseMoved you must instead pass kCGEventLeftMouseDragged while the drag is happening.
Once the drag is done you must pass a kCGEventLeftMouseUp.
To do a single click (no drag) you simply call mouse down and then up right after, without any drag...

Simulated MouseEvent not working properly OSX

Back in 2010, Pierre asked this question (his accepted answer doesn't work for me).
I'm having the same problem: I am able to successfully move the mouse around (and off!?!) the screen programmatically from my Cocoa Application, however bringing the mouse to the location of my dock doesn't show it (and some other applications aren't registering the mouse moved event, eg. games that remove the mouse)
The method I am using is thus:
void PostMouseEvent(CGMouseButton button, CGEventType type, const CGPoint point)
{
CGEventRef theEvent = CGEventCreateMouseEvent(NULL, type, point, button);
CGEventSetType(theEvent, type);
CGEventPost(kCGSessionEventTap, theEvent);
CFRelease(theEvent);
}
And then when I want to move the mouse I run:
PostMouseEvent(0, kCGEventMouseMoved, mouseLocation);
Note that this code DOES generate mouseover events for things such as links.
Now that's it's 2013, is it possible to fix this issue?
Thanks for your time!
I would both warp the cursor and generate the mouse-move event. I know from experience, for example, that warping the cursor, while it doesn't generate an event itself, modifies the subsequent mouse move event to include the moved distance in its mouse delta. I don't know if your synthesized move event will include the proper delta values on its own.
OK, so evidently MacOSX needs the mouse to be at exactly the edge of the screen for the dock to show!
Because I keep my dock on the left-side of the screen (due to many programs keeping vital buttons at the bottom of their windows), all I had to do was say
if (mouseLocation.x < 0)
{
mouseLocation.x = 0;
}
And it worked!
I am also using KenThomases' idea to warp the cursor as well.
(this answer is marked correct as it allows me to show the dock - however there are still some applications that are not responding to mouse input)

How to use AutoAction->True with LocatorPane with more than one Locator?

I am trying to have a LocatorPane with more than one Locator using LocatorAutoCreate option.
But I'd also like to set AutoAction->True, so that when the mouse is over a locator, it moves automatically with the mouse. i.e. works like dragging.
I am basically trying to just have the dragging feature of LocatorPane, and do not want the clicking feature of LocatorPane, as it complicate something else I am doing.
i.e. I just want to be able to just drag points across a locator pane. Clicking on the locatorPane should do nothing. One way to do that I found is by setting AutoAction->True. Is there a better way to disable Clicking effect on LocatorPane?
The problem is that, when I have more than one locator, Mathematica kernel crashes right away.
So, I am asking if there is a way to use AutoAction->True with LocatorPane with more LocatorAutoCreator at the same time. Or if there is a way to just allow dragging, and clicking should do nothing.
Here is an example
LocatorPane[{{0,0},{.4,.5}},
Graphics[{Gray,Disk[]}],
AutoAction->True,
LocatorAutoCreate->{1,5}]
Make sure you save your work before running the above, as it will crash Mathematica once the mouse is over the Pane.
Version 8.0.1, Windows 7.
Update:
FYI; I got a reply from WRI tech support on this today. The problem has been reproduced and send to Mathematica development team to investigate.
You may try:
LocatorPane[{{0, 0}, {.4, .5}, {.1, .1}},
Graphics[{Gray, Disk[]}],
AutoAction -> True, LocatorAutoCreate -> {All}]

Autohotkey Mousemove Wrong Monitor

I'm using mousegetpos to get the current mouse position. I click somewhere else. Then I try to restore the original postion with mousemove. The mouse moves to a different monitor. I tried the alternative method dllcall, with no success. How do I move the mouse back to the original monitor?
It's easier to help if you post your code - then people can see where you're going wrong.
This works fine for me when pressing the Ctrl-T hotkey:
CoordMode, Mouse, Screen
^t::
MouseGetPos, x, y
; Do Stuff Here.
MouseMove, x, y
return
The CoordMode, Mouse, Screen line sets the coordinates relative to the entire screen rather than the active window. I've tested this on my multiple monitor setup and the mouse goes back to the original location every time, even across monitors. Let me know if it's not working for you.
Also, just to make things a little smoother, you can set the mouse speed to '0' before moving the mouse with:
SetDefaultMouseSpeed, 0
This makes the mouse appear to move instantly which looks a little cleaner in most scripts.
I can confirm that Gary's answer works perfectly for anybody else out there having similar problems. Thanks, Gary!
I was myself having a problem like this with Breakaway Audio Enhancer...
For anybody that uses or knows Breakaway, you have to double-click on the toolbar (in the taskbar) to mute it. The way Breakaway works with the sound pipeline other standard AHK mute scripts won't work, so moving the mouse to the toolbar and double-clicking is really the only method of muting. I wanted Caps Lock to mute (or unmute) audio and preferably have the mouse return to where it originally was.
I've had countless problems trying to get this to work with multiple monitors until Gary's post, so here is my solution for anybody else having similar issues:
Capslock::
BlockInput On
CoordMode, Mouse, Screen
MouseGetPos, xpos, ypos
MouseClick, left, 42, 965, 2 ;change the co-ordinates to match your system
MouseMove, xpos, ypos
SetDefaultMouseSpeed, 0
BlockInput Off
Return

Resources