44import static com .esotericsoftware .clippy .util .Util .*;
55import static com .esotericsoftware .minlog .Log .*;
66
7+ import com .esotericsoftware .clippy .tobii .EyeX ;
8+ import com .esotericsoftware .clippy .util .SharedLibraryLoader ;
9+
710import java .awt .Dimension ;
811import java .awt .Point ;
912import java .awt .Toolkit ;
1013import java .awt .event .InputEvent ;
1114import java .awt .event .KeyEvent ;
1215
13- import com .esotericsoftware .clippy .tobii .EyeX ;
14- import com .esotericsoftware .clippy .util .SharedLibraryLoader ;
15-
1616public class Tobii {
1717 static private final int mouseAnimationMillis = 100 ; // Zero disables animating mouse movement.
1818 static private final int screenLeft = 10 , screenTop = 10 ; // Margins to keep mouse on screen, useful for bottom and right.
@@ -34,7 +34,7 @@ public class Tobii {
3434 final Clippy clippy = Clippy .instance ;
3535 EyeX eyeX ;
3636 Dimension screen = Toolkit .getDefaultToolkit ().getScreenSize ();
37- boolean connected , hotkeyPressed , mouseControl , storeHeadAdjustment , ignoreNextHotkey ;
37+ boolean connected , hotkeyPressed , hotkeyLeftClick , hotkeyRightClick , mouseControl , storeHeadAdjustment , ignoreNextHotkey ;
3838
3939 double gazeX , gazeY , gazeStartX , gazeStartY , gazeSnappedX , gazeSnappedY ;
4040 final Buffer gazeJumpSamples = new Buffer (gazeJumpSampleCount * 2 );
@@ -44,7 +44,7 @@ public class Tobii {
4444 int headSamplesSkipped ;
4545
4646 final Point mouse = new Point ();
47- int mouseLastX , mouseLastY , mouseStartX , mouseStartY , mouseEndX , mouseEndY ;
47+ int mouseLastX , mouseLastY , mouseStartX , mouseStartY , mouseEndX , mouseEndY , mouseButtonPressed ;
4848 long mouseMoveLastTime , mouseDownTime ;
4949 double mouseMoveTime ;
5050 boolean mouseDrag ;
@@ -174,15 +174,19 @@ public synchronized void hotkeyPressed (final int vk, final boolean clickOnRelea
174174
175175 hotkeyPressed = true ;
176176 mouseControl = true ;
177+ hotkeyLeftClick = false ;
178+ hotkeyRightClick = false ;
177179 storeHeadAdjustment = true ;
178180 screen = Toolkit .getDefaultToolkit ().getScreenSize ();
179181
180182 mouseDrag = mouseDownTime > 0 ;
181183 mouseDownTime = 0 ;
182184 if (mouseDrag )
183185 setMousePosition (hotkeyReleaseX , hotkeyReleaseY , false );
184- else
186+ else {
187+ mouseButtonPressed = 0 ;
185188 setMouseToGaze ();
189+ }
186190
187191 threadPool .submit (new Runnable () {
188192 public void run () {
@@ -201,8 +205,8 @@ synchronized boolean hotkeyPressedTick (int vk, boolean clickOnRelease) {
201205 // Shift aborts without clicking.
202206 if (clippy .keyboard .isKeyDown (KeyEvent .VK_SHIFT )) return false ;
203207
204- // Click when hotkey is released.
205- if (!clippy .keyboard .isKeyDown (vk )) {
208+ // Click when hotkey is released or aborted .
209+ if (!hotkeyPressed || ! clippy .keyboard .isKeyDown (vk )) {
206210 if (clickOnRelease && System .currentTimeMillis () - hotkeyReleaseTime < doubleClickTime ) {
207211 // If a double click, use the same position as the mouse down.
208212 setMousePosition (hotkeyReleaseX , hotkeyReleaseY , false );
@@ -226,8 +230,11 @@ synchronized boolean hotkeyPressedTick (int vk, boolean clickOnRelease) {
226230 }
227231 setGridOffset (gazeStartX , gazeStartY , mouse .x - gazeStartX , mouse .y - gazeStartY );
228232 }
229- if (clickOnRelease ) {
230- robot .mousePress (InputEvent .BUTTON1_MASK );
233+ if (clickOnRelease || hotkeyLeftClick || hotkeyRightClick ) {
234+ if (hotkeyRightClick )
235+ robot .mousePress (mouseButtonPressed = InputEvent .BUTTON3_DOWN_MASK );
236+ else
237+ robot .mousePress (mouseButtonPressed = InputEvent .BUTTON1_DOWN_MASK );
231238 mouseDownTime = System .currentTimeMillis ();
232239 }
233240 }
@@ -259,7 +266,7 @@ void hotkeyReleased (int vk) {
259266 // Stop mouse control.
260267 boolean mouseDown ;
261268 synchronized (this ) {
262- if (mouseDrag ) robot .mouseRelease (InputEvent . BUTTON1_MASK );
269+ if (mouseDrag ) robot .mouseRelease (mouseButtonPressed );
263270 mouseDown = mouseDownTime > 0 ;
264271 mouseControl = false ;
265272 }
@@ -292,13 +299,36 @@ void hotkeyReleased (int vk) {
292299 sleep (Math .max (0 , doubleTapDragTime - (System .currentTimeMillis () - mouseDownTime )));
293300 synchronized (this ) {
294301 if (mouseDownTime > 0 ) {
302+ robot .mouseRelease (mouseButtonPressed );
295303 mouseDownTime = 0 ;
296- robot . mouseRelease ( InputEvent . BUTTON1_MASK ) ;
304+ mouseButtonPressed = 0 ;
297305 }
298306 }
299307 }
300308 }
301309
310+ synchronized void hotkeyLeftClick () {
311+ if (!connected ) return ;
312+ if (hotkeyPressed ) {
313+ hotkeyPressed = false ; // Abort existing movement.
314+ hotkeyLeftClick = true ;
315+ } else {
316+ robot .mousePress (InputEvent .BUTTON1_DOWN_MASK );
317+ robot .mouseRelease (InputEvent .BUTTON1_DOWN_MASK );
318+ }
319+ }
320+
321+ synchronized void hotkeyRightClick () {
322+ if (!connected ) return ;
323+ if (hotkeyPressed ) {
324+ hotkeyPressed = false ; // Abort existing movement.
325+ hotkeyRightClick = true ;
326+ } else {
327+ robot .mousePress (InputEvent .BUTTON3_DOWN_MASK );
328+ robot .mouseRelease (InputEvent .BUTTON3_DOWN_MASK );
329+ }
330+ }
331+
302332 void setMouseToGaze () {
303333 double x = gazeX , y = gazeY ;
304334 gazeStartX = x ;
0 commit comments