how to implement a double click? - algorithm

Let me explain what we are doing:
We have designed a frame of ir sensors/receivers that can be put around a screen, and basically it converts the screen into a touch-less screen. We are able to move the mouse cursor around when the user moves his finger inside the frame and we can also generate a right click, simply by seeing that if the user is holding his/her finger over the same coords for x amount of time then generate a right click.
The problem is double click. With a regular mouse a user simply double clicks the button and done. Any thoughts on how this can be achieved?
Thank you.

You would need to figure out if the finger is within the screen at all; once you've got a mechanism that tells you that - you can check for this sequence:
Time 0: (finger off screen)
Time 1: (finger touches P1)
Time 2: (finger off screen)
Time 3: (finger touches P2)
where P1 and P2 are close (up to a preset tolerance level) and Time 3 and Time 1 are close (up to a preset double-click sensitivity level).

A solution would be to use different timers for Right click and double click. When you place the finger over a clickable element, a circular progress bar appears at the position of the finger, when the progress reachs the end (the circle is complete) and the user moves the finger away a right click is detected. If the user doesn't move away the finger, a different progress bar appears, if that progress bar reachs 100%, then you have a double click.
In my opinion, a much better solution would be to NOT need a double click, or even a right click, check the XBox Kinect menu navigation interface for a good example.
Hope it helps.
Regards.

Related

XCrossingEvent and x_root, y_root

I am chasing a bug that I suspect is my own misunderstanding about X:
TL;DR - Sometimes XEnterNotify events give global mouse coordinates that don't correspond to the window being entered.
I'm modifying a tiling window manager (ratpoison). The screen is divided into frames, each of which may contain a mapped window. If a frame contains no window, I'd like to focus the frame. So I ask for EnterNotify events on the root window, cast the XEvent to an XCrossingEvent, and then look at x_root and y_root to figure out where the mouse is on the screen. I expect to get the global screen coordinates. The problem is that sometimes when I move the mouse over the empty frame, I get an EnterNotify event on the root window, but the (x_root, y_root) members of the event give a point in the frame I came from (i.e., not at an exposed part of the root window).
Any suggestions?
I think the answer is the following:
The mouse coordinates are not guaranteed to be in sync with anything in particular. The only thing that seems really to be guaranteed is that the mouse was at one point at these coordinates and that a later event will have a later mouse position. In order to know the true mouse position, I either need to listen to motion events on the root window (so that I will eventually get the information I want) or else call (probably) XQueryPointer().
Note that I am not 100% certain of this answer.

How to track mouse movements without limiting it to screen size?

I'm using WM_MOUSEMOVE to get changes in mouse position. When simulating "knobs" for example it's desired to let the user go up/down with mouse without any limits. In this cases I hide cursor and use SetCursorPos to change its position every time user moves with it and detect just the difference from the original position.
Unfortunately it doesn't seem to work - if I set the mouse position, it sometimes works, but sometimes is one or more pixels away, which is just wrong. And even bigger trouble is that after the call another WM_MOUSEMOVE seems to be delivered, which unfortunately does the same thing as it wants to move the cursor back to the original position again. So it ends up in an infinite cycle or settings mouse position and receiving messages until the user releases the mouse button.
What's the correct approach or what's the problem?
The raw input system can do this - it lets you register for raw mouse input that isn't clipped or confined to the screen boundaries.
Broadly speaking, you register for raw input using RegisterRawInputDevices(). Your window will then receive WM_INPUT messages, which you process using the GetRawInputData() function.
See Using Raw Input for an example.
I hide cursor and use SetCursorPos to change its position every time user moves with it and detect just the difference from the original position.
This is just plain wrong. Instead, use SetCapture() to capture the mouse. All movements will be reported as WM_MOUSEMOVE messages with coordinates that are relative to the specified window, even if the mouse is outside of that window, until you release the capture.
Asking the user to move the mouse continuously, even after the cursor hit the screen limit is a very bad idea in terms of User Interface, IMHO.
Some games have another approach: when the mouse hit the "limit", the game enter a special mode: things appears to function exactly as if the mouse was moving, even if the user don't move it. When the user wants to exit that mode, he just has to move the mouse of the limit.
Doing so requires a timer, armed when the mouse hit some limit, executing code periodically as if the mouse was moving. The timer is stopped when a real mouse movement makes it leaves the limit.
Ok folks, so I found a solution simple enough:
The main problem is that SetCursorPos may not set the coordinates accurately, I guess it's because of some high resolution processing, nevertheless it's probably a bug. Anyway if SetCursorPos doesn't set the coordinates correctly (but +-1 in x and/or y) it also sends WM_MOUSEMOVE to the target window. As a result the window performs the exact same operation as before and this goes on and on.
So the solution is to remove all WM_MOUSEMOVE messages right after SetCursorPos:
MSG msg;
while (::PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) { };
Then retrieving the current mouse cursor pos using ::GetCursorPos .
It's ugly but seems to fix the problem. It basically seems that in some position of the mouse, the system always adds or subtracts 1 in either coordinate, so this way you let system do the weird stuff and use the new coordinates without trying to persuade system that your coordinates are the correct ones :).

obtaining MOUSE_DX MOUSE_DY in winapi

I need obtain a MOUSE_DX and MOUSE_DY values where
MOUSE_DX is a difference between MOUSE_X and MOUSE_PREV_X
someone give stupid answer to my that i can hide cursor substract
succesive MOUSE_X between mouse move events, and when cursor
goes away from the centre of the sceen call ShowCursorPost to the
cantre of the screen - but this is a real hell : it is stupid perself also
calling ShowCursorPost generate fake mouse move events so
then I would need to filter out this fake movements then (It is hell)
Is there some more reasonable way of obtaining the MOUSE_DX
MOUSE_DY I need?
//EDIT (more explaining for questions )
I want to use mouse as a steering device - something like mowing yaw/pitch/roll of the camera
For this purpose I need to gest something like MOUSE_DELTA_X MOUSE_DELTA_Y
where such numbers are indeed the MOUSE_X-MOUSE_PREV_X where MOUSE_X/Y are
coordinates of the mouse cursor given to me by WM_MOUSEMOVE
allright - this works to some extent but not much:
I need the DX DY walues related to mouse movements but do not need
a mouse cursor at all, when mouse cursor hits the screen edge i will
not gest full DX but some cutted and then all zeros
To prevent this i call (as somebody advice me) SetCursorPos when
the cursor nears to the edge of the desktop (the window really becouse
I do not want him to exit my window) then I call SetCursorPos
to the centre of the client area (I also make cursor invisible, and
also clip it to the window size but it also brings a lot of
trouble, need to unclip the areo on alt+tab etc it is all tiresome
and it is all a complex workaround for such simple thing like obtaining
DX DY) I just do not need this f*cking invisible cursor moving on screen
at all here - but I need mouse DX DY only
but let assume that this machinery with invisible cursor is tiresomely
coded and debugged
the other trouble is that when I call SetCursorPos It also generates
fake mouse movement backward and it generates fake DX and DY then
(it is hard to filter - at least i do not know how to do it all
in a robust way)
(can this fake mouse move been easily filtered out?)
I did it all this invisible cursor clipping SetCursorPos and filtering
out the false DX DY but it is very ugly thing very error prone and
confusing - all this for simple obtaining (cursor independant/mouse
related)DX DY for every move - this is hell It made me a long hours to
debug this stuff so I am angry - this is coding hell - this is terribly
wrong so I am angry and need a good way of doing it
The WM_MOUSEMOVE event tells you the current position of the cursor. Well, it's actually the position of the cursor when the event was placed in the message queue, not quite the same thing. But the system does not keep track of the position of the cursor associated with the previous WM_MOUSEMOVE message. From this you can conclude that you will need to keep track of that.
So, do the following:
Declare variables to hold the previous cursor position.
Initialize those variables to the current cursor position.
Whenever you process WM_MOUSEMOVE you can compare the current position with the previous.
Once you have done that, update the previous cursor position to be equal to the current position, ready for the next WM_MOUSEMOVE message.
What you could try:
Use the ClipCursor function to confine the cursor inside your window, or a sub-rect.
When the mouse hit your "border", start a timer. Stop the timer when the mouse leaves the border.
On each timer tick, you could generate a fake DX or DY.
The idea is to have the behavior of many games: you move the mouse, hitting a border, and then all behave as if you were still moving the mouse.

Windows command script that moves mouse cursor N pixels?

I am trying to find out how to move the mouse cursor N pixels to some direction.... through a command script, since I cannot install anything on my computer.
I basically try to keep the screen active forever, until I kill the script.
(Yes, I've been searching high and low for a way to do it by a command script.... but could not find anything. I hope it's possible.)
The most straightforward way to manipulate mouse with batch file is with
rundll32 user32.dll,SetCursorPos
But this is not very useful - just sets the mouse to 0,0 position.
Check the mouse.bat - it is a self compiled C#/batch file and does not require external tools and the source is visible and editable.
Examples:
//clicks at the current position
call mouse click
//double clicks at the current position
call mouse doubleClick
//right clicks at the current position
call mouse rightClick
//returns the position of the cursor
call mouse position
//scrolls up the mouse wheel with 1500 units
call mouse scrollUp 150
//scrolls down with 100 postitions
call mouse scrollDown 100
//relatively(from the current position) moves the mouse with 100 horizontal and 100 vertial postitions
call mouse moveBy 100x100
//absolute positioning
call mouse moveTo 100x100
//relative drag (lefclick and move)
call mouse dragBy 300x200
//absolute drag
call mouse dragTo 500x500
Search for NirCmd, and install it in C:\windows, and do:
nircmd setcursor 100 50
nircmd movecursor 10 10
or another commands for clicks etc.
(Late answer but can still be useful for others)
If you just want to keep your computer from falling asleep, the software "Caffeine" does this quite well.
You could try installing AutoHotKey. It makes controlling mouse very simple. Example script:
#MaxThreadsPerHotkey 3
^g::
Toggle := !Toggle
Loop
{
If (!Toggle)
Break
Click
Sleep 1000 ; Make this number higher for slower clicks, lower for faster.
}
Return
After running script for this example press control+g and it will click every second to keep screen awake. ctrl+g again to stop.
install at: https://www.autohotkey.com/
found solution: https://autohotkey.com/boards/viewtopic.php?t=19846
try setting sleep mode to 'none', but if you want to move your mouse without even touching it, download memz clean and let the "random cursor movement" to be bluish. now enjoy. (if it doesn't work, the payloads must be disabled. try doing shift+esc to enable/disable payloads. try doing ctrl+shift+s to skip some time because in some minutes the mouse will shake more better.)

Why won't Gtk's button_press_event receive single left clicks?

I am trying to set up an add-tab button in a Gtk::Notebook (gtkmm). I am doing this by drawing a pixmap to a calculated position -- that works just fine. However, when trying to receive events for it, I cannot pick up a single left click. Single middle and single right give both press and release events, and double left gives just a press event, but single left doesn't register anything. How can I properly receive events?
Did you draw your image in a GtkEventBox?

Resources