From 3d22f970263dfa230864efac4abe19aed8fae9c8 Mon Sep 17 00:00:00 2001 From: nathan Date: Sun, 21 Feb 2016 00:56:14 +0100 Subject: [PATCH] Added movement delta for hiding popup --- .../swing/SwingSystemTrayMenuPopup.java | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/dorkbox/systemTray/swing/SwingSystemTrayMenuPopup.java b/src/dorkbox/systemTray/swing/SwingSystemTrayMenuPopup.java index 43fb0e8f..be7b7b1f 100644 --- a/src/dorkbox/systemTray/swing/SwingSystemTrayMenuPopup.java +++ b/src/dorkbox/systemTray/swing/SwingSystemTrayMenuPopup.java @@ -16,8 +16,8 @@ package dorkbox.systemTray.swing; import dorkbox.util.DelayTimer; -import dorkbox.util.SwingUtil; import dorkbox.util.Property; +import dorkbox.util.SwingUtil; import javax.swing.JPopupMenu; import java.awt.Dimension; @@ -30,19 +30,28 @@ class SwingSystemTrayMenuPopup extends JPopupMenu { private static final long serialVersionUID = 1L; @Property - /** Allows you to customize the delay (for hiding the popup) when the cursor is "moused out" of the popup menu */ + /** Customize the delay (for hiding the popup) when the cursor is "moused out" of the popup menu */ public static long POPUP_HIDE_DELAY = 1000L; + @Property + /** Customize the minimum amount of movement needed to cause the popup-delay to hide the popup */ + public static int MOVEMENT_DELTA = 20; + private DelayTimer timer; + protected volatile Point previousLocation = null; + // protected boolean mouseStillOnMenu; // private JDialog hiddenDialog; SwingSystemTrayMenuPopup() { super(); setFocusable(true); +// setBorder(new BorderUIResource.EmptyBorderUIResource(0,0,0,0)); this.timer = new DelayTimer("PopupMenuHider", true, new Runnable() { + + @Override public void run() { @@ -51,15 +60,28 @@ class SwingSystemTrayMenuPopup extends JPopupMenu { public void run() { Point location = MouseInfo.getPointerInfo().getLocation(); - Point locationOnScreen = getLocationOnScreen(); + Point menuLocation = getLocationOnScreen(); Dimension size = getSize(); - if (location.x >= locationOnScreen.x && location.x < locationOnScreen.x + size.width && - location.y >= locationOnScreen.y && location.y < locationOnScreen.y + size.height) { + // is the mouse pointer still inside of the popup? + if (location.x >= menuLocation.x && location.x < menuLocation.x + size.width && + location.y >= menuLocation.y && location.y < menuLocation.y + size.height) { - SwingSystemTrayMenuPopup.this.timer.delay(SwingSystemTrayMenuPopup.this.timer.getDelay()); + // restart the timer + SwingSystemTrayMenuPopup.this.timer.delay(POPUP_HIDE_DELAY); } + + // has the mouse pointer moved > delta pixels from it's original location (when the tray icon was clicked)? + else if (previousLocation != null && + location.x >= previousLocation.x - MOVEMENT_DELTA && location.x < previousLocation.x + MOVEMENT_DELTA && + location.y >= previousLocation.y - MOVEMENT_DELTA && location.y < previousLocation.y + MOVEMENT_DELTA) { + + // restart the timer + SwingSystemTrayMenuPopup.this.timer.delay(POPUP_HIDE_DELAY); + } + else { + // else, we hide it setVisible(false); } } @@ -76,6 +98,7 @@ class SwingSystemTrayMenuPopup extends JPopupMenu { } }); + // Does not work correctly on linux. a window in the taskbar still shows up // Initialize the hidden dialog as a headless, titleless dialog window // this.hiddenDialog = new JDialog((Frame)null); @@ -100,6 +123,8 @@ class SwingSystemTrayMenuPopup extends JPopupMenu { this.timer.cancel(); if (makeVisible) { + previousLocation = MouseInfo.getPointerInfo().getLocation(); + // if the mouse isn't inside the popup in x seconds, close the popup this.timer.delay(POPUP_HIDE_DELAY); }