chromiumembedded / java-cef

Java Chromium Embedded Framework (JCEF). A simple framework for embedding Chromium-based browsers in other applications using the Java programming language.
https://bitbucket.org/chromiumembedded/java-cef
Other
605 stars 135 forks source link

Scale factor on WIndows not always respected properly #438

Open ekpeters opened 1 year ago

ekpeters commented 1 year ago

Describe the bug On windows 10. The viewport for the browser does not match the Java UI itself in dimensions. Querying the device does report the correct dimensions, but a corrective scale factor is not applied.

To Reproduce Steps to reproduce the behavior:

  1. Have 2+ monitors.
  2. Configure them to different UI scales in the Windows Display control panel. "Scale and layout." -> "Change the size of text, apps, and other items". In my case, I set the primary display to 150% and the second display to 100%. It's important It's critical that these be different. If they are the same, the problem will not recreate.
  3. Open a basic JCEF browser (not sure what you example is, and I've spent myself trying to just get your code to compile just to patch this for myself. I can provide SSCCE)
  4. Drag the window between your different monitors.

Expected behavior Window and browser contents adjust in lock-step as the window is dragged between render contexts that apply different scaling. Or if not in lockstep, that adjust correctly after only a short delay not requiring user action.

Screenshots

WrongScale1 WrongScale2 correctScale

Versions (please complete the following information):

Additional context Does the problem reproduce with the JCEF simple or detailed sample application at the same version? Unknown - assumed so. Does the problem reproduce with the CEF cefclient or cefsimple sample application at the same version? Unknown. Does the problem reproduce with Google Chrome at the same version? Unknown - assumed not. Add any other context about the problem here. CefBrowserWr.java line 74 reads as: 'if (OS.isMacintosh() || OS.isLinux()) doUpdate();' My read of the behaviors, this class file, and that specific line in context suggests that making that doUpdate() call unconditional is necessary. You need to actively apply the scale factor for Mac, Linux, and Windows, which covers the gamut of OSs identified by org.cef.OS. I understand why you don't want to call doUpdate() unconditionally, but I don't have lots of good alternative suggestions for fixing this, except maybe suppressing no-change updates (which you might already do at some layer).

While I might be able to pre-seed the scale for jcef, I see no way to actually do that for this, other than the faint hope of the CefDisplayHandler, which appears to be hard coded to null for my situation.

Resizing the window programatically usually fixes the problem, but the resize kludge hasn't been working for me in the context of our application's dialogs. I've some ideas why resizing might fail specifically for dialogs, but I'd honestly prefer the scale problem just be fixed outright.

ekpeters commented 1 year ago

Simpe code example, using jcefmaven to prepare and and start the browser:

import java.awt.BorderLayout; import java.awt.DisplayMode; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Rectangle; import java.io.File;

import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.WindowConstants;

import org.cef.CefApp; import org.cef.CefClient; import org.cef.browser.CefBrowser; import org.cef.browser.CefMessageRouter;

import me.friwi.jcefmaven.CefAppBuilder; import me.friwi.jcefmaven.CefInitializationException; import me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler;

/**

ekpeters commented 1 year ago

A comment and an observation... 1- I'm only about 80% certain that invoking the mac/linux fix on windows will fix my issue. 2- You probably want CefBrowserWr.scaleFactor to be volatile, so that when accessed from multiple threads some threads do not get old values for it.

ekpeters commented 1 year ago

Apparently, my invoking doUpdate() does not work (tried reflectively). Yes - it's picking up the scaleFactor, ... eh, I've burned enough time already trying to get this browser to work usably for this scenario. Re-examining the screenshots, it's possible the scale is correct and the position is wrong.

One of the curious points is the 'grow-browser-by-2-pixels' resize fixes the problem for full-up JFrames, but does not fix it windows opened as modal dialogs (oauth popups).

Not sure it helps, but it is possible on the java side to sus out physical and logical screen dimensions in Java without access to a Graphics2D component, though what I use myself might actually be brittle (the wording on the api descriptions isn't helpful). That doesn't yield a scale-factor directly, but it could be useful regardless.

magreenblatt commented 1 year ago

Does the problem reproduce with the JCEF simple or detailed sample application at the same version? Unknown - assumed so.

Please test with the JCEF sample apps. They are easy to build/run with the JCEF binary distribution.

ekpeters commented 1 year ago

If you would like me to use said sample apps, please direct me to them.

I am not psychic, and while I have done some looking for such an app, I have not found any clear indicator that such apps even exists - aside from the request when posting a bug report to try said apps.

ekpeters commented 1 year ago

While you are at it - could you update the Readme.md to indicate where said apps live, and add a link to them in the bug reporting instructions.

magreenblatt commented 1 year ago

The JCEF main page includes build instructions at https://github.com/chromiumembedded/java-cef/#building-jcef

The jcefmaven project also links to a (different) sample app on their main page.

I am not psychic...

Please keep the conversation constructive.

ekpeters commented 1 year ago

Initial appearance of the sample app: image Dragged to Display 1: image Dragged back to Display 0: image

Monitor specs as derived from java.awt.GraphicsEnvironment: Screen("\Display0", Relative position: 0.0x0.0, logical size: 1728.0x3072.0, physical size: 2160x3840) Screen("\Display1", Relative position: 2160.0x504.0, logical size: 1280.0x1024.0, physical size: 1280x1024)

(Edit to fix 2nd image)

magreenblatt commented 1 year ago

Thanks for the updated details.

A similar issue was fixed in #343. It looks like you're using Java 11, so perhaps something more is now required with that version.

ekpeters commented 1 year ago

Correct, this is Java 11. Moving Java 17 is on the todo-list for us, but buried under a stack of other priorities,