Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion src/DynamoCoreWpf/Views/Core/WorkspaceView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public enum CursorState
private PortViewModel snappedPort;
private double currentNodeCascadeOffset;
private Point inCanvasSearchPosition;
private List<DependencyObject> hitResultsList = new List<DependencyObject>();
private Window ownerWindow;

static internal event Action<Window, ViewModelBase> RequestShowNodeAutoCompleteBar;
private double currentRenderScale = -1;
Expand Down Expand Up @@ -109,6 +109,8 @@ public WorkspaceView()
InitializeComponent();

DataContextChanged += OnWorkspaceViewDataContextChanged;
Loaded += WorkspaceView_Loaded;
Unloaded += WorkspaceView_Unloaded;

// view of items to drag
draggedSelectionTemplate = (DataTemplate)FindResource("DraggedSelectionTemplate");
Expand Down Expand Up @@ -912,6 +914,29 @@ private void OnCanvasMouseDown(object sender, MouseButtonEventArgs e)
ViewModel.RequestTogglePanMode();
}
}
private void WorkspaceView_Loaded(object sender, RoutedEventArgs e)
{
if (ownerWindow != null)
ownerWindow.Deactivated -= OwnerWindow_Deactivated;

ownerWindow = Window.GetWindow(this);
if (ownerWindow != null)
ownerWindow.Deactivated += OwnerWindow_Deactivated;
}

private void WorkspaceView_Unloaded(object sender, RoutedEventArgs e)
{
if (ownerWindow != null)
{
ownerWindow.Deactivated -= OwnerWindow_Deactivated;
ownerWindow = null;
}
}

private void OwnerWindow_Deactivated(object sender, EventArgs e)
{
DestroyPortContextMenu();
}

/// <summary>
/// Closes the port's context menu and sets its references to null.
Expand Down Expand Up @@ -1260,6 +1285,13 @@ public void Dispose()
{
RemoveViewModelsubscriptions(ViewModel);
DataContextChanged -= OnWorkspaceViewDataContextChanged;
Loaded -= WorkspaceView_Loaded;
Unloaded -= WorkspaceView_Unloaded;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing one bit of cleanup, unsubscribing to OwnerWindow_Deactivated.

Simple change. I'll add it and merge.

if (ownerWindow != null)
{
ownerWindow.Deactivated -= OwnerWindow_Deactivated;
ownerWindow = null;
}
}
}
}
39 changes: 39 additions & 0 deletions test/DynamoCoreWpfTests/CoreUITests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1504,5 +1504,44 @@ private void RightClick(IInputElement element)
//Wait 3 seconds until the Click Right context menu is opened
Task.WaitAll(new Task[] { Task.Delay(2000) });
}

[Test]
[Category("UnitTests")]
public void PortContextMenu_ClosesWhenOwnerWindowIsDeactivated()
{
// Open a new workspace.
ViewModel.NewHomeWorkspaceCommand.Execute(null);
DispatcherUtil.DoEvents();

// Grab the WorkspaceView of the new workspace (it must be loaded so it has
// subscribed to the owner window's Deactivated event).
var currentWs = View.ChildOfType<WorkspaceView>();
Assert.IsNotNull(currentWs, "DynamoView does not have any WorkspaceView");
DispatcherUtil.DoEvents();

// The port context menu should not be open on a fresh workspace.
Assert.IsFalse(currentWs.PortContextMenu.IsOpen, "Port context menu should not be open on a new workspace");

// Open the port context menu popup.
currentWs.PortContextMenu.IsOpen = true;
DispatcherUtil.DoEvents();
Assert.IsTrue(currentWs.PortContextMenu.IsOpen, "Port context menu popup was not opened");

// Simulate the Dynamo window losing focus (e.g. the user switching to another application).
var ownerWindow = Window.GetWindow(currentWs);
Assert.IsNotNull(ownerWindow, "WorkspaceView does not have an owner window");
RaiseDeactivatedEvent(ownerWindow);
DispatcherUtil.DoEvents();

// The port context menu popup must close so it is not left visible on top of other applications.
Assert.IsFalse(currentWs.PortContextMenu.IsOpen, "Port context menu should close when the owner window is deactivated");
}

private static void RaiseDeactivatedEvent(Window window)
{
System.Reflection.MethodInfo onDeactivated = typeof(Window).GetMethod("OnDeactivated",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
onDeactivated.Invoke(window, new object[] { EventArgs.Empty });
}
}
}
Loading