Does anyone have a workaround for rs.PopupMenu() popping up in the wrong position? By default it is supposed to popup under the cursor, but since V7 or earlier it always is way far away for me, most often in the lower right hand corner of the screen.
I have posted about this a long time ago, but nothing has been done. It may be that this phenomenon is due to display scaling? I just now tried to figure out how to get the cursor position and calculate myself in screen coordinates to feed to the method, but I failed miserably - I’m not very good with this stuff.
Partially (and hopefully correctly) answering my own question - the answer to it might be yes.
I tried scaling the X and Y coordinates of the cursor location according to the display scaling I have here - 225%:
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino, System
items=["A","B","C","D","None of the Above"]
ds=100/225 #display scaling factor
screen_point=System.Windows.Forms.Cursor.Position
screen_point.X*=ds
screen_point.Y*=ds
result=Rhino.UI.Dialogs.ShowContextMenu(items, screen_point, None)
print ("You chose {}".format(items[result]))
Running this on my laptop at 225% scaling, the menu then pops up pretty much where it’s supposed to, close to the location of the mouse cursor where one clicks, a little to the right and below.
@dale Well, I don’t know what to tell you - as the picture above attests to, PopupMenu() doesn’t work correctly here on either of my two computers/monitors with different dpi scaling. And this in Rhino 6, 7 and 8. Adding the correction (225 for my laptop and 150 for my desktop) via the script makes it position perfectly.
Windows 11 (10.0.26100 SR0.0) or greater (Physical RAM: 32GB)
.NET 7.0.0
Computer platform: LAPTOP - Plugged in [100% battery remaining]
Non-hybrid graphics configuration.
Primary display and OpenGL: NVIDIA GeForce RTX 4060 Laptop GPU (NVidia) Memory: 8GB, Driver date: 11-6-2024 (M-D-Y). OpenGL Ver: 4.6.0 NVIDIA 566.14
> Integrated accelerated graphics device with 4 adapter port(s)
- Windows Main Display is laptop’s integrated screen or built-in port
Primary OpenGL: NVIDIA GeForce RTX 4060 Laptop GPU (NVidia) Memory: 8GB, Driver date: 11-6-2024 (M-D-Y). OpenGL Ver: 4.6.0 NVIDIA 566.14
> Integrated accelerated graphics device with 4 adapter port(s)
- Windows Main Display is laptop’s integrated screen or built-in port
OpenGL Settings
Safe mode: Off
Use accelerated hardware modes: On
GPU Tessellation is: On
Redraw scene when viewports are exposed: On
Graphics level being used: OpenGL 4.6 (primary GPU’s maximum)
Anti-alias mode: 4x
Mip Map Filtering: Linear
Anisotropic Filtering Mode: High
Vendor Name: NVIDIA Corporation
Render version: 4.6
Shading Language: 4.60 NVIDIA
Driver Date: 11-6-2024
Driver Version: 32.0.15.6614
Maximum Texture size: 32768 x 32768
Z-Buffer depth: 24 bits
Maximum Viewport size: 32768 x 32768
Total Video Memory: 8188 MB
I get the exact same issue as you @Helvetosaur, and just as you mention this seems to be a problem for screens with higher resolutions. On a regular 1080p screen everything works, but on a 4k screen all forms pop up at a shifted location that corresponds to the scaling…
As an alternative solution to your question about querying the scaling locally, I’ve had some success using the “LogicalPixelSize” (see below) on the Rhino window. I then scale the form insertion point (that I base on the cursor position).
import Rhino as rc
scale_factor = rc.UI.RhinoEtoApp.MainWindow.LogicalPixelSize
A problem for me now is that I only have access to the insertion point for the “ShowContextMenu” from your example, not the other forms I need (like checkbox forms etc). One could do a fully manual eto form for this, but it’s nice to have the simple forms for less complicated things.
Bumping @dale in the hope this can be fixed since @Helvetosaur is not alone in getting this popup location bug for 4k screens.
Almost, divide by the size variable in your example rather than multiplying (like in the example @Measure gave).
Otherwise this is just what I have done to work around the bug for 4k screens.