How to script when a docked window loses focus?

Hi,

I have a West docked window that expands/collapses based on mouse movement. Works great except for one small issue… it doesn’t always close. I have a script on the root container event ‘mouseExited’ which slides the window closed when the mouse exceeds the bounds of the docked container. However, if the mouse is moved really fast, then this event does not register and the window stays open until you move your mouse over the bounds again.

Question is: Is there a way to script when a root container loses focus? Or, is there another reliable way to assure the menu closes when the mouse is moved off it?

As you were,
Steve

Graciously bumping in hopes of an assist. :pray:

What if you put a script in the other window’s root container’s mouseEntered function to close the docked window. That might capture the event better, you might even have the script in both as extra insurance. Scripting on the window itself, not the root container, has the internalFrameDeactivated function that fires when a window loses focus, but I don’t think moving your mouse out the frame causes focus loss, you would have to click out of the frame.

1 Like

Thanks dkhayes, I appreciate the response. I had actually tried the mouseEntered method previously on a single screen. As expected it worked, but I was not a fan of this method as it would entail adding a script on about 150 screens. Ugh… So that is why I was wondering about the ‘focus lost’ scripting on a root container. When I get a chance to try the internalFrameDeactivated method on the internal window I will post back if successful.

Again, thanks!
Steve

1 Like

Here is some code where i did something close. Put this on the propertyChange of the rootContainer on the window you want to collapse/expand.

from javax.swing import SwingUtilities
from java.awt.event import AWTEventListener, MouseEvent
from java.awt import AWTEvent, Toolkit, MouseInfo
from java.awt import IllegalComponentStateException
from java.awt.dnd import DragSourceMotionListener, DragSource
from com.inductiveautomation.ignition.client.util.gui import IgnitionSwingUtilities 
from com.inductiveautomation.factorypmi.application import FPMIWindow


class GlobalMouseListener(AWTEventListener):
	
	
	def __init__(self, container):
		self.container = container
	
	def startup(self):
		Toolkit.getDefaultToolkit().addAWTEventListener(self, AWTEvent.MOUSE_EVENT_MASK)
		Toolkit.getDefaultToolkit().addAWTEventListener(self, AWTEvent.MOUSE_MOTION_EVENT_MASK)

	def shutdown(self):
		Toolkit.getDefaultToolkit().removeAWTEventListener(self)
	
	def isMousePointInPanel(self, point):
		x = point.x
		y = point.y
		location = self.container.getLocationOnScreen()
		cx = location.getX()
		cy = location.getY()
		cw = self.container.getWidth()
		ch = self.container.getHeight()
		return x <= cx + cw and x >= cx and y < cy + ch and y >= cy
	
	def handleEnterExit(self, point):
		if self.isMousePointInPanel(point):
			# here is where your expand logic goes
			print 'Mouse in Panel'
			pass
				
		else:
			# here is where the contract logic goes i would set a contracted flag here to save time.
			print 'Mouse not Panel'
			pass

	def eventDispatched(self, event):
		try:
			point = event.getLocationOnScreen()
			container_window = 	IgnitionSwingUtilities.getAncestorOfClass(FPMIWindow, self.container)
			if event.getID () == MouseEvent.MOUSE_MOVED:
				self.handleEnterExit(point)
						
		except IllegalComponentStateException:
			pass

			
if event.propertyName == 'componentRunning':
	if event.newValue:
		listener = GlobalMouseListener(event.source)
		listener.startup()
		event.source.putClientProperty('global_listener', listener)
	else:
		listener = event.source.getClientProperty('global_listener')
		listener.shutdown()
		
4 Likes

Hi raymond1982…

Thank you for the code!! It’s exactly what I was looking for, and works flawlessly. I really tried to trip it up with all kinds of mouse movement and could not. I really appreciate your time and expertise! Kudos!

Thank you!
Steve

hello. could you explain the code a bit, I want to do something similar. thanks.

1 Like