# Move Popup Within Bounds of Client Window

**URL:** <https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865>\
**Category:** Ignition\
**Tags:** ignition81, vision, scripting\
**Created:** [March 25, 2024, 8:43pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865 "2024-03-25T20:43:52Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [March 25, 2024, 8:43pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/1 "2024-03-25T20:43:52Z")

</div>

I have a popup view that I'm opening via an onClick event and I'd like to open it in the relative mouse position.

I've achieved this, but now there's a case where the button is close enough to the edge of the client window that it opens partially off the screen.

I want to limit the max X and Y position based on the window size, but this is not so easy because there can be docked view (in this case, a docked north navigation view) that throws things off.

```auto
#x and y position for popup, relative to entire screen
xOpen, yOpen = system.gui.convertPointToScreen(event.x, event.y, event)

#open window
window = system.nav.openWindowInstance('Popups/PopUp')

#parent window
parentWindow = system.gui.getParentWindow(event)

#calculate where the end of the poup is
xEnd = xOpen + window.width
yEnd = yOpen + window.height

#how do I find x and y max (width and height of screen)??
#xMax = 1920
#yMax = 1080

#make sure end of popup is not off-screen
if xEnd > xMax:
	xOpen = xOpen - (xEnd - xMax)
	
if yEnd > yMax:
	yOpen = yOpen - (yEnd - yMax)

#set window location
window.setLocation(xOpen,yOpen)

```

How can I make sure the popup opens within the bounds of the window every time?

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [March 27, 2024, 12:39am UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/2 "2024-03-27T00:39:13Z")

</div>

Here is a script I developed some time ago for this purpose:

```auto
# Developed to be called from a popup window's internalFrameActivated event handler

# Import the necessary Javax Swing classes
from javax.swing import JFrame,SwingUtilities

# Get an unambiguous reference to the 'popupWindow' component from the event source
popupWindow = event.source

# Find the nearest ancestor JFrame of the 'popupWindow' component which will be the parent window that the popup was opened from
parentJFrame = SwingUtilities.getAncestorOfClass(JFrame, popupWindow)

# Set a margin value for positioning the 'popupWindow'
parentJFrameMargin = 100

# Try to get the mouse position relative to the 'parent' JFrame
try:
	popupWindowX = parentJFrame.getMousePosition(True).x
	popupWindowY = parentJFrame.getMousePosition(True).y
	
# If an exception occurs (e.g., mouse position not available), set default values of (0,0) [Upper left corner] plus the specified margin
except:
	popupWindowX = parentJFrameMargin
	popupWindowY = parentJFrameMargin
	
# Ensure that the 'popupWindow' is within the boundaries of the 'parent' JFrame
if popupWindowX < parentJFrameMargin:
	popupWindowX = parentJFrameMargin
elif popupWindowX + popupWindow.width > parentJFrame.width - parentJFrameMargin:
	popupWindowX = parentJFrame.width - popupWindow.width - parentJFrameMargin
if popupWindowY < parentJFrameMargin:
	popupWindowY = parentJFrameMargin
elif popupWindowY + popupWindow.height > parentJFrame.height - parentJFrameMargin:
	popupWindowY = parentJFrame.height - popupWindow.height - parentJFrameMargin 
	
# Set the new location of the 'popupWindow' based on the calculated positions
popupWindow.setLocation(popupWindowX, popupWindowY)

```

It finds the Jframe of the window the popup was launched from, and calculates if the window can be positioned at the mouse cursor without overlapping the side of the window. If it can't be done, it positions it as close as possible. It also has an adjustable margin parameter which is currently set to 100 pixels, so the window will actually be contained within a 100 pixels of the edge of the parent window.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [March 27, 2024, 12:53pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/3 "2024-03-27T12:53:05Z")

</div>

Thanks for the script! I'll try to adapt this for my use.

I have one call that opens the popup and another that repositions the popup, all within the `onActionPerformed` for a button, like so:

```auto
if event.source.parent.parent.clickable:
	window = Nav.popup1(event)
	Nav.moveWindowRelative(event, window)

```

```auto
def popup1(event):
	'''
		Calls pop with path defined on the root container
		
		Args:
			event (obj) :	event handler (typically mouse click or button action)
			
		Returns:
			window (obj) :	window that was opened
	'''
	
	#get component path from root container
	param1 = event.source.parent.parent.path
	
	#call popup with path
	window = system.nav.openWindowInstance('Popups/PopUp', {'path' : param1})
	system.nav.centerWindow(window)
	
	return window

```

If I use your code as-is

```auto
def moveWindowRelative(event, window):
	from javax.swing import JFrame,SwingUtilities
	# Get an unambiguous reference to the 'popupWindow' component from the event source
	popupWindow = event.source
	
	# Find the nearest ancestor JFrame of the 'popupWindow' component which will be the parent window that the popup was opened from
	parentJFrame = SwingUtilities.getAncestorOfClass(JFrame, popupWindow)
	
	# Set a margin value for positioning the 'popupWindow'
	parentJFrameMargin = 100
	
	# Try to get the mouse position relative to the 'parent' JFrame
	try:
		popupWindowX = parentJFrame.getMousePosition(True).x
		popupWindowY = parentJFrame.getMousePosition(True).y
	
	# If an exception occurs (e.g., mouse position not available), set default values of (0,0) [Upper left corner] plus the specified margin
	except:
		popupWindowX = parentJFrameMargin
		popupWindowY = parentJFrameMargin
	
	# Ensure that the 'popupWindow' is within the boundaries of the 'parent' JFrame
	if popupWindowX < parentJFrameMargin:
		popupWindowX = parentJFrameMargin
	elif popupWindowX + popupWindow.width > parentJFrame.width - parentJFrameMargin:
		popupWindowX = parentJFrame.width - popupWindow.width - parentJFrameMargin
	if popupWindowY < parentJFrameMargin:
		popupWindowY = parentJFrameMargin
	elif popupWindowY + popupWindow.height > parentJFrame.height - parentJFrameMargin:
		popupWindowY = parentJFrame.height - popupWindow.height - parentJFrameMargin 
	
	# Set the new location of the 'popupWindow' based on the calculated positions
	popupWindow.setLocation(popupWindowX, popupWindowY)

```

The window always just opens at 0,0.

If I replace the las popupWindow.setLocation with my window.setLocation it still opens off the screen.

I'll try and do some troubleshooting with the console.

\*edit: so, when I print the JFrame that is found it looks like this:

```auto
com.inductiveautomation.ignition.designer.IgnitionDesigner[frame1,1912,-8,1936x1056,invalid,layout=java.awt.BorderLayout,title=Grain_SCC - Ignition-LPTP134 - Ignition Designer,resizable,maximized,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,8,31,1920x1017,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@7071c1,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

```

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [March 27, 2024, 12:57pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/4 "2024-03-27T12:57:56Z")

</div>

If you're calling my script from the button that launches the popup, it won't work "as is".

My script was developed to be called from the pop-up window itself. Specifically, the internalFrameActivated event handler.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [March 27, 2024, 12:58pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/5 "2024-03-27T12:58:32Z")

</div>

Right, that's what I'm going to try and change. I just don't know enough about JFrames

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [March 27, 2024, 1:01pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/6 "2024-03-27T13:01:18Z")

</div>

Delete the `popupWindow = event.source` line, and rename your passed in `window` variable `popupWindow`, and the script will probably work.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [March 27, 2024, 1:03pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/7 "2024-03-27T13:03:50Z")

</div>

There we go! I replaced it in the `setLocation` call, but nowhere else. That's perfect.

```python
# Import the necessary Javax Swing classes
from javax.swing import JFrame,SwingUtilities

def moveWindowRelative(window):
	'''
		Moves a popup window to a position
	'''
	
	
	# Find the nearest ancestor JFrame of the window component which will be the parent window that the popup was opened from
	parentJFrame = SwingUtilities.getAncestorOfClass(JFrame, window)
	
	# Set a margin value for positioning the window
	parentJFrameMargin = 30
	#initially assume a window move is required
	moveRequired = True
	
	# Try to get the mouse position relative to the parent JFrame
	try:
	    windowX = parentJFrame.getMousePosition(True).x
	    windowY = parentJFrame.getMousePosition(True).y

	# If an exception occurs (e.g., mouse position not available), do not move the window
	except:
		moveRequired = False
		
	if moveRequired:
	
		# Ensure that the window is within the boundaries of the parent JFrame
		if windowX < parentJFrameMargin:
		    windowX = parentJFrameMargin
		elif windowX + window.width > parentJFrame.width - parentJFrameMargin:
		    windowX = parentJFrame.width - window.width - parentJFrameMargin
		if windowY < parentJFrameMargin:
		    windowY = parentJFrameMargin
		elif windowY + window.height > parentJFrame.height - parentJFrameMargin:
		    windowY = parentJFrame.height - window.height - parentJFrameMargin 
		
		# Set the new location of the window based on the calculated positions
		window.setLocation(windowX, windowY)

```

---

<div class="post-metadata">

**Author:** ![michael.flagler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/michael.flagler/32/26272_2.png) [@michael.flagler](https://forum.inductiveautomation.com/u/michael.flagler)\
**Post date:** [March 28, 2024, 7:24pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/8 "2024-03-28T19:24:31Z")

</div>

I needed just this for my popups, and determined that the best event handler on the popup is the visionWindowOpened event. Your script works perfectly otherwise, and helped me a ton!

When I used internalFrameActivated, if the user clicks off of the popup and back to it, the script triggers again causing the popup to jump to a new location based on where the user clicks on the popup.

You also can't use internalFrameOpened unless your cache policy on the popup is set to never, as any cached windows/popups will not run the script a second time and the popup will show in the last location.

I finally moved it to visionWindowOpened, and it works consistenly with or without caching and without jumping when clicking off and back on a popup.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [March 28, 2024, 9:36pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/9 "2024-03-28T21:36:27Z")

</div>

That makes sense. In my application, I close the pop-up with internal frame deactivated, so its counterpart _internal frame activated_ seemed appropriate for my initialization script. If I were leaving the popup open, I would definitely have to take your advice and change the way that part of the script is called.

---

<div class="post-metadata">

**Author:** ![Melvin\_Miclat](https://avatars.discourse-cdn.com/v4/letter/m/ba9def/32.png) [@Melvin\_Miclat](https://forum.inductiveautomation.com/u/Melvin_Miclat)\
**Post date:** [July 16, 2024, 11:11pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/10 "2024-07-16T23:11:37Z")

</div>

I get error on with this line. I think it needs an answer.

# If an exception occurs (e.g., mouse position not available), do not move the window

```
	moveRequired = False

```

---

<div class="post-metadata">

**Author:** ![michael.flagler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/michael.flagler/32/26272_2.png) [@michael.flagler](https://forum.inductiveautomation.com/u/michael.flagler)\
**Post date:** [July 16, 2024, 11:32pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/11 "2024-07-16T23:32:01Z")

</div>

What error are you getting? Most likely you didn't copy/paste the script exactly as written or modified it in some way that's breaking it. Could even be your indentation is off/wrong.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [July 17, 2024, 7:09am UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/12 "2024-07-17T07:09:24Z")

</div>

The indentation of the comment could be causing the issue. Make it match the line it's above.

```python
# If an exception occurs (e.g., mouse position not available), do not move the window
Move Required = False

```

---

<div class="post-metadata">

**Author:** ![Melvin\_Miclat](https://avatars.discourse-cdn.com/v4/letter/m/ba9def/32.png) [@Melvin\_Miclat](https://forum.inductiveautomation.com/u/Melvin_Miclat)\
**Post date:** [July 17, 2024, 1:09pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/13 "2024-07-17T13:09:14Z")

</div>

This is what I get for an error.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/7/0/7068ba984a583b41dce98207f144bcb571ab951d.png)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 17, 2024, 1:12pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/14 "2024-07-17T13:12:00Z")

</div>

You have an incomplete `try:` block above that point, that expects consistent indentation.

---

<div class="post-metadata">

**Author:** ![Melvin\_Miclat](https://avatars.discourse-cdn.com/v4/letter/m/ba9def/32.png) [@Melvin\_Miclat](https://forum.inductiveautomation.com/u/Melvin_Miclat)\
**Post date:** [July 17, 2024, 1:22pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/15 "2024-07-17T13:22:22Z")

</div>

do you have an idea what script I should put to that try: block you mentioned?

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [July 17, 2024, 1:24pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/16 "2024-07-17T13:24:00Z")

</div>

The `try` must be accompanied by an `except` clause like this:

```python
except:
		#if an exception occurs (e.g., mouse position not available), do not move the window 		 
		moveRequired = False

```

Somehow, it must have got omitted from his code example. For reference, it is included in his prior example a few posts up.

---

<div class="post-metadata">

**Author:** ![Melvin\_Miclat](https://avatars.discourse-cdn.com/v4/letter/m/ba9def/32.png) [@Melvin\_Miclat](https://forum.inductiveautomation.com/u/Melvin_Miclat)\
**Post date:** [July 17, 2024, 7:15pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/17 "2024-07-17T19:15:30Z")

</div>

Hi Amark did you get this work? I cant get it to work on my end. It seems like it is missing something after the moveRequired = False. I tried to add the except script on it and still did not work. Not sure what im doing wrong.

---

<div class="post-metadata">

**Author:** ![Melvin\_Miclat](https://avatars.discourse-cdn.com/v4/letter/m/ba9def/32.png) [@Melvin\_Miclat](https://forum.inductiveautomation.com/u/Melvin_Miclat)\
**Post date:** [July 17, 2024, 7:30pm UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/18 "2024-07-17T19:30:37Z")

</div>

Ok this works. but the script is still not positioning the popup inside the window.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [July 18, 2024, 5:24am UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/19 "2024-07-18T05:24:24Z")

</div>

> [@Melvin\_Miclat](#):
>
> the script is still not positioning the popup inside the window

How are you calling it? Where are you storing it? Alex's version is written for the project library.

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/8/e8fa0946ab8d993d0f8a9ba22b7c1c5d53a3c9dc.png)  
If the function were placed in a library script unimaginatively named `libararyScripts`, and the popup were being opened by a button, then the script would need to be called from the action performed event handler of the button in this way:

```python
# From the action performed event handler of the button that opens the popup

# Define needed parameters for the opening window
path = 'path/to/popup'
parameter = 'someParameter' # Optional
value = 3 # Optional

# Open the window and assign it to a passable variable
# ...(The system function returns the window instance)
window = system.nav.openWindowInstance(path , {parameter: value})

# Call the library script and pass in the event and the window,
# ...so the script can properly postion window before it is painted
libararyScripts.moveWindowRelative(event, window)

```

Alternatively, the script I originally posted could simply be placed in the popup's `visionWindowOpened` event handler, and it would just work with no need to do anything from the button or action that deploys the popup, but in my opinion, for generic stuff like this that will likely need to be reused throughout a project, it's a better practice to go the library script route because when the need arises to change the script in some way, it will be easier to find, and it will only need to be touched in one place.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [July 18, 2024, 11:50am UTC](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865/20 "2024-07-18T11:50:23Z")

</div>

I don't know how the `except` got omitted, considering I copy-pasted the code, but I've edited the code above to include the `except`.

This is designed as a library function and is called like so

> [@justinedwards.jle](#):
>
> ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/8/e8fa0946ab8d993d0f8a9ba22b7c1c5d53a3c9dc.png)  
> If the function were placed in a library script unimaginatively named `libararyScripts`, and the popup were being opened by a button, then the script would need to be called from the action performed event handler of the button in this way:
> 
> ```python
> # From the action performed event handler of the button that opens the popup
> 
> # Define needed parameters for the opening window
> path = 'path/to/popup'
> parameter = 'someParameter' # Optional
> value = 3 # Optional
> 
> # Open the window and assign it to a passable variable
> # ...(The system function returns the window instance)
> window = system.nav.openWindowInstance(path , {parameter: value})
> 
> # Call the library script and pass in the event and the window,
> # ...so the script can properly postion window before it is painted
> libararyScripts.moveWindowRelative(event, window)
> 
> ```

[Next page](https://forum.inductiveautomation.com/t/move-popup-within-bounds-of-client-window/87865.md?page=2)
