cefsharp / CefSharp

.NET (WPF and Windows Forms) bindings for the Chromium Embedded Framework
http://cefsharp.github.io/
Other
9.76k stars 2.92k forks source link

WPF - Html dropdown goes off screen when near bottom of page #2820

Open Dumpen opened 5 years ago

Dumpen commented 5 years ago
amaitland commented 5 years ago

Additional checks to make sure the popup is within the bounds of the control will be required.

Currently the image that represents the drop down is just positioned relative to the canvas https://github.com/cefsharp/CefSharp/blob/cefsharp/73/CefSharp.Wpf/ChromiumWebBrowser.cs#L1962

A very quick look at the CEF source code, and it's doing some checks about the size https://github.com/chromiumembedded/cef/blob/8a055593d694b386f46530f81f53ed8b7c5ea284/tests/cefclient/browser/osr_renderer.cc#L247

We should do similar, pull requests welcome.

Dumpen commented 4 years ago

I changed the code to match the one in CEF which moves the popup but the underlying popup is still where it was before. Is there a method to "paint/refresh" the UI?

Heres a gif of the problem

     /// <summary>
        /// Sets the popup size and position implementation.
        /// </summary>
        /// <param name="rect">The popup rectangle (size and position).</param>
        private void SetPopupSizeAndPositionImpl(Rect rect)
        {
            popupImage.Width = rect.Width;
            popupImage.Height = rect.Height;

            int x = rect.X, y = rect.Y;

            // if x or y are negative, move them to 0.
            if (x < 0)
            {
                x = 0;
            }

            if (y < 0)
            {
                y = 0;
            }

            // if popup goes outside the view, try to reposition origin
            if (rect.X + rect.Width > viewRect.Width)
            {
               x = viewRect.Width - rect.Width;
            }

            if (rect.Y + rect.Height > viewRect.Height)
            {
                y = viewRect.Height - rect.Height;
            }

            // if x or y became negative, move them to 0 again.
            if (x < 0)
            {
                x = 0;
            }

            if (y < 0)
            {
                y = 0;
            }

            Canvas.SetLeft(popupImage, x);
            Canvas.SetTop(popupImage, y);
        }
amaitland commented 4 years ago

You'd have to debug cefclient to see what additional changes are required.

haavamoa commented 4 years ago

Hi guys! :)

We are experiencing the same bug. Is there any progress regarding this bug?

riksking commented 4 years ago

Hi all :) We are experiencing the same bug on version v79.1.360. Is there any progress?

CaptBli commented 4 years ago

This is quite the problem for us. Any progress? Just trying to ping. Right now we have to make our dropdowns become multi-row selects with only a couple of rows in order to make the dropdowns stay on screen.

amaitland commented 4 years ago

For anyone wishing to debug this problem you can download the source for the cefclient reference implementation from http://opensource.spotify.com/cefbuilds/index.html

Suggests on where to add some breakpoints

amaitland commented 4 years ago

It looks like cefclient is adjusting the mouse x,y values when over a dropdown.

Shankp commented 3 years ago

does anyone have a fix for this.?? we are facing this in version 85.3.130

amaitland commented 3 years ago

I'm not aware of anyone working on this currently, a pull request would be welcomed.

jaqueamo commented 3 years ago

I used a part of the code from @Dumpen and adjusted the mouse x,y values as described by @amaitland. Seems to work.

Select

Just one problem: I would position the popup over the select control. Currently thats just a fixed offset. Is there a way to get the height of the select control to determine the correct position for the popup ?

amaitland commented 3 years ago

Is there a way to get the height of the select control

I don't believe so. Have you checked the cefclient reference implementation to see how it works?

https://github.com/chromiumembedded/cef/blob/4430/tests/cefclient/browser/osr_renderer.cc#L247

jaqueamo commented 3 years ago

I think there the poup is repositioned to the border of the view like in the solution from @Dumpen.

amaitland commented 3 years ago

@jaqueamo can you push your changes to GitHub? Thanks

carrierdown commented 3 years ago

I've made a similar fix using the code from @Dumpen as a starting point. This code has been tested and fixes the issues we faced, though it is not perfect. For this reason, I'm reluctant to post a PR for this currently. Also, my fix is currently made to the 86.0.241-version, since that is the one we're currently using in our project, but the same changes could be trivially moved over to the latest release if desired. Anyways, my changes can be found here: https://github.com/carrierdown/CefSharp/commit/a843d3e8881c0597bf6a3d0052519dc23ff48569

carrierdown commented 3 years ago

Some notes about my implementation:

When a popup is active and needs to be adjusted, I keep track of the adjusted and original areas that the popup occupies (stored as Rects). This is handled by the new MouseTeleport class. When the mouse enters the adjusted popup area, the mouse position is offset so that it corresponds to the original popup area, since the underlying control is still in its original position as far as CEF is concerned.

However, there is a problem when moving the mouse over the original popup area, as this would also trigger the popup leading to confusing behaviour where moving the mouse under a dropdown would select the topmost item for instance. To work around this, mouse move messages are not sent when in the original popup-area (while the popup is open). However, since the user can click anywhere outside the popup to close it, this solution would make the popup fail to close when clicking underneath the adjusted popup. That's still better than letting the clicks through though, because that would mean that some random item in the list might get selected when clicking outside the control, which is definitely not what you want. I've solved the issue by offseting clicks one pixel away from the original popup in these cases. It's not perfect, but is not likely to cause any serious issues either.

Metritutus commented 2 years ago

Along with the issue of the positioning of the dropdown, there also appears to be an issue with the drop-down being clipped by the window boundary, which does not occur with other browser controls such as the stock WPF WebBrowser control or Microsoft's own WebView2 control.

Should the drop-down spill beyond the boundaries of the window, it should render outside of it.

amaitland commented 2 years ago

Along with the issue of the positioning of the dropdown, there also appears to be an issue with the drop-down being clipped by the window boundary

@Metritutus That is correct. It's by design at this point in time as the popup is hosted within a canvas.

Historically a Popup was used, this was problematic as WPF would frequently crash and there was no action from Microsoft in fixing the issues. That was some three years ago, I haven't tested using Popup since.

stock WPF WebBrowser control or Microsoft's own WebView2 control.

Both are HwndHost based implementations and are not native (for want of a better word) WPF controls. There is an equivalent version of CefSharp available https://github.com/cefsharp/CefSharp.Wpf.HwndHost

Pull requests are welcome. The cefclient implementation linked above can be used as a reference.

Metritutus commented 2 years ago

Along with the issue of the positioning of the dropdown, there also appears to be an issue with the drop-down being clipped by the window boundary

@Metritutus That is correct. It's by design at this point in time as the popup is hosted within a canvas.

Historically a Popup was used, this was problematic as WPF would frequently crash and there was no action from Microsoft in fixing the issues. That was some three years ago, I haven't tested using Popup since.

stock WPF WebBrowser control or Microsoft's own WebView2 control.

Both are HwndHost based implementations and are not native (for want of a better word) WPF controls. There is an equivalent version of CefSharp available https://github.com/cefsharp/CefSharp.Wpf.HwndHost

Pull requests are welcome. The cefclient implementation linked above can be used as a reference.

This is incredibly useful information, thanks! I confess I had no idea that CefSharp.Wpf.HwndHost existed. It isn't referenced from the main page or in the wiki. It appears to work as desired, and dropdowns are not clipped by the window when using the ChromiumWebBrowser from that repository.

With regards to your referring to pull requests, are you suggesting pull-requests for this (the CefSharp repository) would be welcome to try and resolve the clipping issue for the WPF version of the browser? I've had a look through the history regarding the popup crash issue you mentioned, but could only find #2239, which doesn't mention crashes.

dmitry-novoselov commented 2 years ago

Hey, @Metritutus

Have you proceeded with the pull request for fixing the issue in CefSharp.Wpf? Are there any chance you will submit it?

Metritutus commented 2 years ago

Hey, @Metritutus

Have you proceeded with the pull request for fixing the issue in CefSharp.Wpf? Are there any chance you will submit it?

I am afraid that I have not yet had the opportunity to do so.

There is a steep learning curve involved in order for me to understand how this project works, so for now I have made do with CefSharp.Wpf.HwndHost, which was linked earlier, which has been entirely satisfactory in addressing this issue for me for the time being.

EricPRHC commented 1 year ago

Along with the issue of the positioning of the dropdown, there also appears to be an issue with the drop-down being clipped by the window boundary, which does not occur with other browser controls such as the stock WPF WebBrowser control or Microsoft's own WebView2 control.

Should the drop-down spill beyond the boundaries of the window, it should render outside of it.

Since my issue #4382 has been marked as duplicate I'm particularly interested in developments in this area. Ofcourse if the popup could open to another direction that would also be sufficient, but that doesn't seem to be the current behaviour.

Any interesting developments in this regard?

amaitland commented 1 year ago

I'm not aware of any developments, happy to review a PR if someone would like to submit one.

DidiDerDenker commented 5 months ago

I submitted a PR (#4639) but it needs some testing. Could some of you test the behaviour and report back? Thank you!

amaitland commented 3 months ago

Thanks to @DidiDerDenker this is now available for testing in version v123.0.60. You can test it out using:

using CefSharp.Wpf.Experimental;

chromiumWebBrowser.UsePopupMouseTransform();

Please provide feedback. Once it's been sufficiently tested we can enable it by default.