Skip to content

Commit b26cb07

Browse files
authored
WPF - Fixed Html Dropdown positioning when near bottom of screen (Cleanup) (#4759)
* WPF - Popup Mouse Transform - Refactor and performance improvements - WPF Example - Enable popup transform by default Issue #2820
1 parent d606945 commit b26cb07

File tree

7 files changed

+74
-78
lines changed

7 files changed

+74
-78
lines changed

CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using CefSharp.Fluent;
1717
using CefSharp.Wpf.Example.Handlers;
1818
using CefSharp.Wpf.Example.ViewModels;
19+
using CefSharp.Wpf.Experimental;
1920
using CefSharp.Wpf.Experimental.Accessibility;
2021

2122
namespace CefSharp.Wpf.Example.Views
@@ -31,6 +32,8 @@ public BrowserTabView()
3132

3233
DataContextChanged += OnDataContextChanged;
3334

35+
browser.UsePopupMouseTransform();
36+
3437
//browser.BrowserSettings.BackgroundColor = Cef.ColorSetARGB(0, 255, 255, 255);
3538

3639
//Please remove the comments below to use the Experimental WpfImeKeyboardHandler.

CefSharp.Wpf/ChromiumWebBrowser.cs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,6 @@ public partial class ChromiumWebBrowser : Control, IRenderWebBrowser, IWpfWebBro
140140
/// </summary>
141141
private static bool DesignMode;
142142

143-
/// <summary>
144-
/// The class that coordinates the positioning of the dropdown if wanted.
145-
/// </summary>
146-
private IMouseAdjustor mouseAdjustor;
147-
148143
// https://github.com/chromiumembedded/cef/issues/3427
149144
private bool resizeHackIgnoreOnPaint;
150145
private Structs.Size? resizeHackSize;
@@ -155,6 +150,11 @@ public partial class ChromiumWebBrowser : Control, IRenderWebBrowser, IWpfWebBro
155150
/// </summary>
156151
private bool initialFocus;
157152

153+
/// <summary>
154+
/// The class that coordinates the positioning of the dropdown if wanted.
155+
/// </summary>
156+
internal IMousePositionTransform MousePositionTransform { get; set; }
157+
158158
/// <summary>
159159
/// When enabled the browser will resize by 1px when it becomes visible to workaround
160160
/// the upstream issue
@@ -489,14 +489,6 @@ public ChromiumWebBrowser()
489489
{
490490
NoInliningConstructor();
491491
}
492-
493-
bool adjust = true;
494-
495-
if (adjust)
496-
this.mouseAdjustor = new MouseAdjustor();
497-
498-
else
499-
this.mouseAdjustor = new NoMouseAdjustor();
500492
}
501493

502494
/// <summary>
@@ -626,6 +618,7 @@ private void NoInliningConstructor()
626618
PresentationSource.AddSourceChangedHandler(this, PresentationSourceChangedHandler);
627619

628620
MenuHandler = new ContextMenuHandler();
621+
MousePositionTransform = new NoOpMousePositionTransform();
629622

630623
UseLayoutRounding = true;
631624
}
@@ -1053,7 +1046,7 @@ protected virtual void OnPopupShow(bool isOpen)
10531046
UiThreadRunAsync(() =>
10541047
{
10551048
popupImage.Visibility = isOpen ? Visibility.Visible : Visibility.Hidden;
1056-
mouseAdjustor.OnPopupShow(isOpen);
1049+
MousePositionTransform.OnPopupShow(isOpen);
10571050
});
10581051
}
10591052

@@ -2125,7 +2118,7 @@ private void SetPopupSizeAndPositionImpl(Rect rect)
21252118
popupImage.Width = rect.Width;
21262119
popupImage.Height = rect.Height;
21272120

2128-
Point point = this.mouseAdjustor.UpdatePopupSizeAndPosition(rect, this.viewRect);
2121+
var point = MousePositionTransform.UpdatePopupSizeAndPosition(rect, viewRect);
21292122

21302123
Canvas.SetLeft(popupImage, point.X);
21312124
Canvas.SetTop(popupImage, point.Y);
@@ -2295,8 +2288,8 @@ protected override void OnMouseMove(MouseEventArgs e)
22952288
var point = e.GetPosition(this);
22962289
var modifiers = e.GetModifiers();
22972290

2298-
var adjustedPoint = mouseAdjustor.GetAdjustedMouseCoords(point);
2299-
browser.GetHost().SendMouseMoveEvent(adjustedPoint.X, adjustedPoint.Y, false, modifiers);
2291+
MousePositionTransform.TransformMousePoint(ref point);
2292+
browser.GetHost().SendMouseMoveEvent((int)point.X, (int)point.Y, false, modifiers);
23002293
}
23012294

23022295
base.OnMouseMove(e);
@@ -2313,11 +2306,11 @@ protected override void OnMouseWheel(MouseWheelEventArgs e)
23132306
var point = e.GetPosition(this);
23142307
var modifiers = e.GetModifiers();
23152308
var isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
2316-
var adjustedPoint = mouseAdjustor.GetAdjustedMouseCoords(point);
2309+
MousePositionTransform.TransformMousePoint(ref point);
23172310

23182311
browser.SendMouseWheelEvent(
2319-
adjustedPoint.X,
2320-
adjustedPoint.Y,
2312+
(int)point.X,
2313+
(int)point.Y,
23212314
deltaX: isShiftKeyDown ? e.Delta : 0,
23222315
deltaY: !isShiftKeyDown ? e.Delta : 0,
23232316
modifiers: modifiers);
@@ -2467,11 +2460,9 @@ private void OnMouseButton(MouseButtonEventArgs e)
24672460
{
24682461
clickCount = 1;
24692462
}
2470-
24712463

2472-
var adjustedPoint = mouseAdjustor.GetAdjustedMouseCoords(point);
2473-
browser.GetHost().SendMouseClickEvent(adjustedPoint.X, adjustedPoint.Y, (MouseButtonType)e.ChangedButton, mouseUp, clickCount, modifiers);
2474-
// browser.GetHost().SendMouseClickEvent(mouseTeleport.originalRect.X + mouseTeleport.originalRect.Width, (int)point.Y, (MouseButtonType)e.ChangedButton, mouseUp, clickCount, modifiers);
2464+
MousePositionTransform.TransformMousePoint(ref point);
2465+
browser.GetHost().SendMouseClickEvent((int)point.X, (int)point.Y, (MouseButtonType)e.ChangedButton, mouseUp, clickCount, modifiers);
24752466
}
24762467

24772468
e.Handled = true;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using CefSharp.Wpf.Internals;
2+
3+
namespace CefSharp.Wpf.Experimental
4+
{
5+
public static class ExperimentalExtensions
6+
{
7+
public static void UsePopupMouseTransform(this ChromiumWebBrowser chromiumWebBrowser)
8+
{
9+
chromiumWebBrowser.MousePositionTransform = new MousePositionTransform();
10+
}
11+
}
12+
}

CefSharp.Wpf/IMouseAdjustor.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using CefSharp.Structs;
2+
3+
namespace CefSharp.Wpf.Internals
4+
{
5+
/// <summary>
6+
/// Implement this interface to control transform the mouse position
7+
/// </summary>
8+
public interface IMousePositionTransform
9+
{
10+
System.Windows.Point UpdatePopupSizeAndPosition(Rect originalRect, Rect viewRect);
11+
void OnPopupShow(bool isOpen);
12+
void TransformMousePoint(ref System.Windows.Point point);
13+
}
14+
}

CefSharp.Wpf/Internals/MouseAdjustor.cs renamed to CefSharp.Wpf/Internals/MousePositionTransform.cs

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,7 @@
22

33
namespace CefSharp.Wpf.Internals
44
{
5-
public class NoMouseAdjustor : IMouseAdjustor
6-
{
7-
public virtual void Dispose()
8-
{
9-
}
10-
11-
public System.Windows.Point UpdatePopupSizeAndPosition(Rect originalRect, Rect viewRect)
12-
{
13-
return new System.Windows.Point(originalRect.X, originalRect.Y);
14-
}
15-
16-
public void OnPopupShow(bool isOpen)
17-
{
18-
}
19-
20-
public Point GetAdjustedMouseCoords(System.Windows.Point point)
21-
{
22-
return new Point((int)point.X, (int)point.Y);
23-
}
24-
}
25-
26-
public class MouseAdjustor : IMouseAdjustor
5+
public sealed class MousePositionTransform : IMousePositionTransform
276
{
287
/// <summary>
298
/// The x-offset.
@@ -50,20 +29,13 @@ public class MouseAdjustor : IMouseAdjustor
5029
/// </summary>
5130
private bool isOpen;
5231

53-
/// <summary>
54-
/// This method is required for the interface.
55-
/// </summary>
56-
public virtual void Dispose()
57-
{
58-
}
59-
6032
/// <summary>
6133
/// Updates the size and the position of the popup.
6234
/// </summary>
6335
/// <param name="originalRect"></param>
6436
/// <param name="viewRect"></param>
6537
/// <returns>The adjusted point.</returns>
66-
public System.Windows.Point UpdatePopupSizeAndPosition(Rect originalRect, Rect viewRect)
38+
System.Windows.Point IMousePositionTransform.UpdatePopupSizeAndPosition(Rect originalRect, Rect viewRect)
6739
{
6840
int x = originalRect.X,
6941
prevX = originalRect.X,
@@ -124,7 +96,7 @@ public System.Windows.Point UpdatePopupSizeAndPosition(Rect originalRect, Rect v
12496
/// Resets the offsets and original-rect.
12597
/// <param name="isOpen">If the popup is open or not.</param>
12698
/// </summary>
127-
public void OnPopupShow(bool isOpen)
99+
void IMousePositionTransform.OnPopupShow(bool isOpen)
128100
{
129101
if (!isOpen)
130102
{
@@ -142,16 +114,14 @@ public void OnPopupShow(bool isOpen)
142114
/// Adjusts the mouse-coordinates when the popup is visible.
143115
/// </summary>
144116
/// <param name="point">The original point.</param>
145-
/// <returns>The adjusted point if needed, else the original point.</returns>
146-
public Point GetAdjustedMouseCoords(System.Windows.Point point)
117+
/// <returns>The transformed point if needed, else the original point.</returns>
118+
void IMousePositionTransform.TransformMousePoint(ref System.Windows.Point point)
147119
{
148-
if (!this.isOpen)
149-
return new Point((int)point.X, (int)point.Y);
150-
151-
if (!this.IsInsideOriginalRect(point) && IsInsideAdjustedRect(point))
152-
return new Point((int)point.X + this.xOffset, (int)point.Y + this.yOffset);
120+
if (!isOpen)
121+
return;
153122

154-
return new Point((int)point.X, (int)point.Y);
123+
if (!IsInsideOriginalRect(point) && IsInsideAdjustedRect(point))
124+
point = new System.Windows.Point((int)point.X + this.xOffset, (int)point.Y + this.yOffset);
155125
}
156126

157127
/// <summary>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using CefSharp.Structs;
2+
3+
namespace CefSharp.Wpf.Internals
4+
{
5+
public sealed class NoOpMousePositionTransform : IMousePositionTransform
6+
{
7+
System.Windows.Point IMousePositionTransform.UpdatePopupSizeAndPosition(Rect originalRect, Rect viewRect)
8+
{
9+
return new System.Windows.Point(originalRect.X, originalRect.Y);
10+
}
11+
12+
void IMousePositionTransform.OnPopupShow(bool isOpen)
13+
{
14+
}
15+
16+
void IMousePositionTransform.TransformMousePoint(ref System.Windows.Point point)
17+
{
18+
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)