Skip to content

Commit

Permalink
WPF - Manually calculate GetScreenPoint
Browse files Browse the repository at this point in the history
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
  • Loading branch information
amaitland committed Jun 2, 2017
1 parent b78208b commit d168116
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions CefSharp.Wpf/ChromiumWebBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ public class ChromiumWebBrowser : ContentControl, IRenderWebBrowser, IWpfWebBrow
/// The dispose count
/// </summary>
private int disposeCount;
/// <summary>
/// <summary>
/// Location of the control on the screen, relative to Top/Left
/// Used to calculate GetScreenPoint
/// We're unable to call PointToScreen directly due to treading restrictions
/// and calling in a sync fashion on the UI thread was problematic.
/// </summary>
private Point browserScreenLocation;

/// <summary>
/// A flag that indicates whether or not the designer is active
/// NOTE: Needs to be static for OnApplicationExit
Expand Down Expand Up @@ -601,15 +610,18 @@ bool IRenderWebBrowser.GetScreenPoint(int viewX, int viewY, out int screenX, out
screenX = 0;
screenY = 0;

var point = new Point(viewX, viewY);

UiThreadRunSync(() =>
//We manually claculate the screen point as calling PointToScreen can only be called on the UI thread
// in a sync fashion and it's easy for users to get themselves into a deadlock.
if(DpiScaleFactor > 1)
{
screenX = (int)(browserScreenLocation.X + (viewX * DpiScaleFactor));
screenY = (int)(browserScreenLocation.Y + (viewY * DpiScaleFactor));
}
else
{
point = PointToScreen(point);
});

screenX = (int)point.X;
screenY = (int)point.Y;
screenX = (int)(browserScreenLocation.X + viewX);
screenY = (int)(browserScreenLocation.Y + viewY);
}

return true;
}
Expand Down Expand Up @@ -1533,6 +1545,7 @@ private void PresentationSourceChangedHandler(object sender, SourceChangedEventA
if(window != null)
{
window.StateChanged += WindowStateChanged;
window.LocationChanged += OnWindowLocationChanged;
}
}
}
Expand All @@ -1544,6 +1557,7 @@ private void PresentationSourceChangedHandler(object sender, SourceChangedEventA
if (window != null)
{
window.StateChanged -= WindowStateChanged;
window.LocationChanged -= OnWindowLocationChanged;
}
}
}
Expand Down Expand Up @@ -1574,6 +1588,13 @@ private void WindowStateChanged(object sender, EventArgs e)
}
}

private void OnWindowLocationChanged(object sender, EventArgs e)
{
//We maintain a manual reference to the controls screen location
//(relative to top/left of the screen)
browserScreenLocation = PointToScreen(new Point());
}

/// <summary>
/// Removes the source hook.
/// </summary>
Expand Down Expand Up @@ -1720,6 +1741,9 @@ private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
Dispatcher
);
tooltipTimer.IsEnabled = false;

//Initial value for screen location
browserScreenLocation = PointToScreen(new Point());
}

/// <summary>
Expand Down

0 comments on commit d168116

Please sign in to comment.