Skip to content

Commit d168116

Browse files
committed
WPF - Manually calculate GetScreenPoint
Using PointToScreen(point) on the UI thread (had to be called in a sync fashion) made it easy for users to cause a deadlock Resolve #1915
1 parent b78208b commit d168116

File tree

1 file changed

+32
-8
lines changed

1 file changed

+32
-8
lines changed

CefSharp.Wpf/ChromiumWebBrowser.cs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ public class ChromiumWebBrowser : ContentControl, IRenderWebBrowser, IWpfWebBrow
8282
/// The dispose count
8383
/// </summary>
8484
private int disposeCount;
85+
/// <summary>
86+
/// <summary>
87+
/// Location of the control on the screen, relative to Top/Left
88+
/// Used to calculate GetScreenPoint
89+
/// We're unable to call PointToScreen directly due to treading restrictions
90+
/// and calling in a sync fashion on the UI thread was problematic.
91+
/// </summary>
92+
private Point browserScreenLocation;
93+
8594
/// <summary>
8695
/// A flag that indicates whether or not the designer is active
8796
/// NOTE: Needs to be static for OnApplicationExit
@@ -601,15 +610,18 @@ bool IRenderWebBrowser.GetScreenPoint(int viewX, int viewY, out int screenX, out
601610
screenX = 0;
602611
screenY = 0;
603612

604-
var point = new Point(viewX, viewY);
605-
606-
UiThreadRunSync(() =>
613+
//We manually claculate the screen point as calling PointToScreen can only be called on the UI thread
614+
// in a sync fashion and it's easy for users to get themselves into a deadlock.
615+
if(DpiScaleFactor > 1)
616+
{
617+
screenX = (int)(browserScreenLocation.X + (viewX * DpiScaleFactor));
618+
screenY = (int)(browserScreenLocation.Y + (viewY * DpiScaleFactor));
619+
}
620+
else
607621
{
608-
point = PointToScreen(point);
609-
});
610-
611-
screenX = (int)point.X;
612-
screenY = (int)point.Y;
622+
screenX = (int)(browserScreenLocation.X + viewX);
623+
screenY = (int)(browserScreenLocation.Y + viewY);
624+
}
613625

614626
return true;
615627
}
@@ -1533,6 +1545,7 @@ private void PresentationSourceChangedHandler(object sender, SourceChangedEventA
15331545
if(window != null)
15341546
{
15351547
window.StateChanged += WindowStateChanged;
1548+
window.LocationChanged += OnWindowLocationChanged;
15361549
}
15371550
}
15381551
}
@@ -1544,6 +1557,7 @@ private void PresentationSourceChangedHandler(object sender, SourceChangedEventA
15441557
if (window != null)
15451558
{
15461559
window.StateChanged -= WindowStateChanged;
1560+
window.LocationChanged -= OnWindowLocationChanged;
15471561
}
15481562
}
15491563
}
@@ -1574,6 +1588,13 @@ private void WindowStateChanged(object sender, EventArgs e)
15741588
}
15751589
}
15761590

1591+
private void OnWindowLocationChanged(object sender, EventArgs e)
1592+
{
1593+
//We maintain a manual reference to the controls screen location
1594+
//(relative to top/left of the screen)
1595+
browserScreenLocation = PointToScreen(new Point());
1596+
}
1597+
15771598
/// <summary>
15781599
/// Removes the source hook.
15791600
/// </summary>
@@ -1720,6 +1741,9 @@ private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
17201741
Dispatcher
17211742
);
17221743
tooltipTimer.IsEnabled = false;
1744+
1745+
//Initial value for screen location
1746+
browserScreenLocation = PointToScreen(new Point());
17231747
}
17241748

17251749
/// <summary>

0 commit comments

Comments
 (0)