# How to script when a docked window loses focus?

**URL:** <https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491>\
**Category:** Ignition\
**Created:** [August 15, 2019, 7:41pm UTC](https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491 "2019-08-15T19:41:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![sbrannen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/sbrannen/32/3459_2.png) [@sbrannen](https://forum.inductiveautomation.com/u/sbrannen)\
**Post date:** [August 15, 2019, 7:41pm UTC](https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491/1 "2019-08-15T19:41:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![sbrannen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/sbrannen/32/3459_2.png) [@sbrannen](https://forum.inductiveautomation.com/u/sbrannen)\
**Post date:** [August 16, 2019, 1:15pm UTC](https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491/2 "2019-08-16T13:15:07Z")

</div>

Graciously bumping in hopes of an assist. 🙏

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [August 16, 2019, 2:29pm UTC](https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491/3 "2019-08-16T14:29:43Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sbrannen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/sbrannen/32/3459_2.png) [@sbrannen](https://forum.inductiveautomation.com/u/sbrannen)\
**Post date:** [August 21, 2019, 4:27pm UTC](https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491/4 "2019-08-21T16:27:20Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![raymond1982](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/raymond1982/32/6490_2.png) [@raymond1982](https://forum.inductiveautomation.com/u/raymond1982)\
**Post date:** [August 22, 2019, 2:30am UTC](https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491/5 "2019-08-22T02:30:55Z")

</div>

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.

```auto
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()
		

```

---

<div class="post-metadata">

**Author:** ![sbrannen](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/sbrannen/32/3459_2.png) [@sbrannen](https://forum.inductiveautomation.com/u/sbrannen)\
**Post date:** [August 22, 2019, 9:15am UTC](https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491/6 "2019-08-22T09:15:39Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![lachguerabdallah](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lachguerabdallah/32/25558_2.png) [@lachguerabdallah](https://forum.inductiveautomation.com/u/lachguerabdallah)\
**Post date:** [February 1, 2021, 4:45pm UTC](https://forum.inductiveautomation.com/t/how-to-script-when-a-docked-window-loses-focus/27491/7 "2021-02-01T16:45:03Z")

</div>

> [@raymond1982](#):
>
> 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()

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