Skip to content

Commit ad5a04b

Browse files
authored
[DYN-7840] Inaccurate popup placement for input nodes in collapsed groups - Follow-up (#16263)
1 parent e2a8ee6 commit ad5a04b

2 files changed

Lines changed: 26 additions & 5 deletions

File tree

src/DynamoCoreWpf/Controls/InPortContextMenu.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,13 @@
139139
<Path Grid.Column="1"
140140
HorizontalAlignment="Right"
141141
VerticalAlignment="Center"
142-
Data="M 12,10 L -1,5 -1,15 Z"
142+
Data="M 12,6 L -1,1 -1,11 Z"
143143
Fill="White"
144144
Stroke="#999999" />
145145
<Path Grid.Column="0"
146146
HorizontalAlignment="Right"
147147
VerticalAlignment="Center"
148-
Data="M 2,5 0,5 L0,10 L2,10 Z"
148+
Data="M 2,1 0,1 L0,6 L2,6 Z"
149149
Stretch="None"
150150
Fill="White"
151151
Stroke="White" />

src/DynamoCoreWpf/ViewModels/Core/PortViewModel.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,18 +375,20 @@ internal void SetupPortContextMenuPlacement(Popup popup)
375375
/// </summary>
376376
private void ConfigurePopupPlacement(Popup popup, double zoom)
377377
{
378+
var dpiScale = GetDpiScale();
379+
378380
popup.CustomPopupPlacementCallback = (popupSize, targetSize, offset) =>
379381
{
380382
double x;
381383
double y = (targetSize.Height - popupSize.Height) / 2;
382384

383385
if (this is InPortViewModel)
384386
{
385-
x = -popupSize.Width + proxyPortContextMenuOffset * zoom;
387+
x = -popupSize.Width + proxyPortContextMenuOffset * zoom * dpiScale;
386388
}
387389
else
388390
{
389-
x = targetSize.Width - proxyPortContextMenuOffset * zoom;
391+
x = targetSize.Width - proxyPortContextMenuOffset * zoom * dpiScale;
390392
}
391393

392394
return new[] { new CustomPopupPlacement(new Point(x, y), PopupPrimaryAxis.None) };
@@ -398,6 +400,7 @@ private CustomPopupPlacement[] PlacePortContextMenu(Size popupSize, Size targetS
398400
// The actual zoom here is confusing
399401
// What matters is the zoom factor measured from the scaled : unscaled node size
400402
var zoom = node.WorkspaceViewModel.Zoom;
403+
var dpiScale = GetDpiScale();
401404

402405
double x;
403406
var scaledWidth = autocompletePopupSpacing * targetSize.Width / node.ActualWidth;
@@ -421,13 +424,31 @@ private CustomPopupPlacement[] PlacePortContextMenu(Size popupSize, Size targetS
421424
var rowOffset = PortModel.Index * PortModel.Height * zoom;
422425
var customNodeOffset = NodeModel.CustomNodeTopBorderHeight * zoom;
423426

424-
var y = popupHeightOffset + headerHeightOffset + portHalfHeight + rowOffset + customNodeOffset;
427+
// popupSize.Height is already DPI-scaled (in screen pixels), so we do NOT apply dpiScale to it
428+
// All other layout values are in logical units and must be multiplied by dpiScale for correct placement
429+
var y = popupHeightOffset + (headerHeightOffset + portHalfHeight + rowOffset + customNodeOffset) * dpiScale;
425430

426431
var placement = new CustomPopupPlacement(new Point(x, y), PopupPrimaryAxis.None);
427432

428433
return new[] { placement };
429434
}
430435

436+
private static double GetDpiScale()
437+
{
438+
double dpiScale = 1.0;
439+
try
440+
{
441+
var source = PresentationSource.FromVisual(Application.Current.MainWindow);
442+
dpiScale = source?.CompositionTarget?.TransformToDevice.M22 ?? 1.0;
443+
}
444+
catch
445+
{
446+
// fallback to default DPI scale of 1.0 if anything fails
447+
}
448+
449+
return dpiScale;
450+
}
451+
431452
private void WorkspacePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
432453
{
433454
switch (e.PropertyName)

0 commit comments

Comments
 (0)